exemples pratiques utilisent dup ou dup2
-
19-09-2019 - |
Question
Je sais ce que dup
/ dup2
fait, mais je aucune idée quand il serait utilisé.
Les exemples pratiques?
Merci.
La solution
Un exemple utiliser serait redirection E / S. Pour cela, vous bifurquez un processus enfant et de fermer les descripteurs de fichiers stdin ou stdout (0 et 1), puis vous faites un dup () sur un autre FileDescriptor de votre choix qui va maintenant être mis en correspondance avec le plus bas descripteur de fichier disponible, ce qui est dans ce cas 0 ou 1.
En utilisant cela, vous pouvez maintenant exec tout processus enfant qui est peut-être pas au courant de votre demande et à chaque fois que l'enfant écrit sur le stdout (ou STDIN, tout ce que vous configuré) les données est écrite sur la condition FileDescriptor à la place.
Coquilles utiliser cette fonction pour mettre en oeuvre des commandes avec des tuyaux, par exemple /bin/ls | more
en connectant la sortie standard d'un processus à l'entrée standard de l'autre.
Autres conseils
Le meilleur scénario pour comprendre dup et dup2 est redirection.
La première chose que nous devons savoir est que le système dispose de 3 ids de fichiers par défaut (ou variables indiquant les sources de sortie ou d'entrée) qui traite de l'entrée et de sortie. Ils sont stdin
, stdout
, stderr
, en nombres entiers ils sont 0
, 1
, 2
. La plupart des fonctions telles que fprintf
ou cout
sont directement sortie stdout
.
Si nous voulons rediriger la sortie, d'une façon est de donner, par exemple, la fonction fprintf
plus d'arguments indiquant in
et out
.
Cependant, il y a une façon plus élégante: on peut remplacer les ids de fichier par défaut pour les faire pointer vers le fichier que nous voulons recevoir la sortie. dup
et dup2
fonctionne exactement dans cette situation.
Commençons par un exemple simple maintenant: supposons que nous voulons rediriger la sortie de fprintf
vers un fichier txt nommé « chinaisbetter.txt ». Tout d'abord, nous devons ouvrir ce fichier
int fw=open("chinaisbetter.txt", O_APPEND|O_WRONLY);
Ensuite, nous voulons stdout
pour pointer sur "chinaisbetter.txt" en utilisant la fonction dup:
dup2(fw,1);
stdout (1) pointe vers le descripteur de « chinaisbetter.txt », même si elle est encore 1, mais la sortie est maintenant redirigé.
Ensuite, vous pouvez utiliser printf
comme d'habitude, mais les résultats seront dans le fichier txt au lieu d'afficher directement sur l'écran:
printf("Are you kidding me? \n");
PS :
-
Cela donne juste une explication intuitive, vous devrez peut-être vérifier la page de manuel ou des informations détaillées. En fait, nous disons "copie" ici, ils ne sont pas tout copier.
-
L'identifiant de fichier se réfère ici au gestionnaire du fichier. Le descripteur de fichier mentionné ci-dessus est un struct de l'information du fichier des enregistrements.
Lorsque vous êtes curieux de connaître les fonctions POSIX, en particulier ceux qui semblent se reproduire, il est généralement bon de vérifier la norme elle-même . Au fond, vous habituellement voir des exemples, ainsi que le raisonnement derrière la mise en œuvre (et existence) des deux.
Dans ce cas:
Les sections suivantes sont informatives.
Exemples
Réorientation la sortie standard dans un fichier
L'exemple suivant ferme la sortie standard pour les processus actuels, réaffecte la sortie standard pour aller au fichier référencé par pfd
et ferme le descripteur de fichier original à nettoyer.
#include <unistd.h>
...
int pfd;
...
close(1);
dup(pfd);
close(pfd);
...
Rediriger Messages d'erreur
L'exemple suivant redirige automatiquement les messages stderr
à stdout
.
#include <unistd.h>
...
dup2(2, 1); // 2-stderr; 1-stdout
...
Application Usage
Aucun.
Justification
Les fonctions de dup()
et dup2()
sont redondants. Leurs services sont également fournis par la fonction fcntl()
. Ils ont été inclus dans ce volume de la norme IEEE Std 1003.1-2001 principalement pour des raisons historiques, car de nombreuses applications existantes les utiliser.
Alors que le bref segment de code affiché est très similaire dans le comportement à dup2()
, une mise en œuvre conforme à base d'autres fonctions définies dans ce volume de la norme IEEE Std 1003.1-2001 est beaucoup plus complexe. Moins évident est l'effet possible d'une fonction de gestionnaire de signal qui pourrait être invoqué entre les étapes et allouer ou descripteurs de fichiers désaffecter. Cela pourrait être évité en bloquant les signaux.
La fonction dup2()
n'est pas marqué obsolescent, car il présente une version de type sécurisé des fonctionnalités fournies dans une version de type dangereux par fcntl()
. Il est utilisé dans l'Ada POSIX obligatoire.
La fonction dup2()
n'a pas été conçu pour être utilisé dans des régions critiques comme un mécanisme de synchronisation.
Dans la description de [EBADF], le cas de Fildes étant hors de portée est couvert par le cas donné Fildes ne pas être valide. Les descriptions de fildes
et fildes2
sont différents parce que le seul type d'invalidité qui est pertinente pour fildes2
est de savoir s'il est hors de portée; qui est, peu importe si fildes2
fait référence à un fichier ouvert lorsque l'appel est fait dup2()
.
Orientations futures
Aucun.
Voir aussi
close()
, fcntl()
, open()
, le volume des définitions de base de la norme IEEE 1003,1 à 2001, <unistd.h>
Historique des modifications
D'abord publié dans le numéro 1. Dérivé du numéro 1 du SVID.
Un exemple pratique réoriente les messages de sortie à un autre flux comme un fichier journal. Voici un exemple de code pour la redirection d'E / S.
S'il vous plaît se référer à la publication dorigine
#include <stdio.h>
main()
{
int fd;
fpos_t pos;
printf("stdout, ");
fflush(stdout);
fgetpos(stdout, &pos);
fd = dup(fileno(stdout));
freopen("stdout.out", "w", stdout);
f();
fflush(stdout);
dup2(fd, fileno(stdout));
close(fd);
clearerr(stdout);
fsetpos(stdout, &pos); /* for C9X */
printf("stdout again\n");
}
f()
{
printf("stdout in f()");
}
redirection d'E / S dans la coquille serait très probablement mis en œuvre en utilisant les appels système dup2 / de fcnlt.
On peut facilement imiter le type de $program 2>&1 > logfile.log
de redirection en utilisant la fonction dup2.
Le programme ci-dessous réoriente à la fois stdout et stderr .i.e émule le comportement de $program 2>&1 > output
en utilisant le dup2.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
int
main(void){
int close_this_fd;
dup2(close_this_fd = open("output", O_WRONLY), 1);
dup2(1,2);
close(close_this_fd);
fprintf(stdout, "standard output\n");
fprintf(stderr, "standard error\n");
fflush(stdout);
sleep(100); //sleep to examine the filedes in /proc/pid/fd level.
return;
}
vagrant@precise64:/vagrant/advC$ ./a.out
^Z
[2]+ Stopped ./a.out
vagrant@precise64:/vagrant/advC$ cat output
standard error
standard output
vagrant@precise64:/vagrant/advC$ ll /proc/2761/fd
total 0
dr-x------ 2 vagrant vagrant 0 Jun 20 22:07 ./
dr-xr-xr-x 8 vagrant vagrant 0 Jun 20 22:07 ../
lrwx------ 1 vagrant vagrant 64 Jun 20 22:07 0 -> /dev/pts/0
l-wx------ 1 vagrant vagrant 64 Jun 20 22:07 1 -> /vagrant/advC/output
l-wx------ 1 vagrant vagrant 64 Jun 20 22:07 2 -> /vagrant/advC/output