Je sais que dup, dup2, dup3 " crée une copie du descripteur de fichier oldfd " (à partir des pages de manuel). Cependant je ne peux pas le digérer.
Comme je le sais, les descripteurs de fichier ne sont que nombres pour garder une trace des emplacements des fichiers et de leur direction (entrée/sortie). Ne serait-il pas plus facile de simplement
fd=fd2;
Chaque fois que nous voulons dupliquer un descripteur de fichier?
Et quelque chose d'autre..
dup () utilise le descripteur inutilisé avec le plus petit numéro pour le nouveau descripteur.
Cela signifie-t-il qu'il peut également prendre pour valeur stdin , stdout ou stderr si nous supposons que nous avons close () - ed l'un de ces?
Je voulais juste me répondre à la deuxième question après avoir essayé un peu.
La réponse estOUI. Un descripteur de fichier que vous créez peut prendre les valeurs 0, 1, 2 si stdin, stdout ou stderr sont fermés.
Exemple:
close(1); //closing stdout
newfd=dup(1); //newfd takes value of least available fd number
Où cela arrive aux descripteurs de fichiers:
0 stdin .--------------. 0 stdin .--------------. 0 stdin
1 stdout =| close(1) :=> 2 stderr =| newfd=dup(1) :=> 1 newfd
2 stderr '--------------' '--------------' 2 stderr
Un descripteur de fichier est un peu plus qu'un nombre. Il porte également divers états semi-cachés (qu'il soit ouvert ou non, à quelle description de fichier il fait référence, ainsi que certains drapeaux). dup
duplique ces informations, vous pouvez par exemple fermez les deux descripteurs indépendamment. fd=fd2
ne le fait pas.
La chose la plus importante à propos de dup () est qu’elle renvoie le plus petit entier disponible pour un nouveau descripteur de fichier. C'est la base de la redirection:
int fd_redirect_to = open("file", O_CREAT);
close(1); /* stdout */
int fd_to_redirect = dup(fd_redirect_to); /* magically returns 1: stdout */
close(fd_redirect_to); /* we don't need this */
Après cela, quoi que ce soit écrit dans le descripteur de fichier 1 (stdout), passe par magie dans "fichier".
Supposons que vous écriviez un programme Shell et que vous souhaitiez rediriger stdin et stdout dans un programme que vous souhaitez exécuter. Cela pourrait ressembler à quelque chose comme ça:
fdin = open(infile, O_RDONLY);
fdout = open(outfile, O_WRONLY);
// Check for errors, send messages to stdout.
...
int pid = fork(0);
if(pid == 0) {
close(0);
dup(fdin);
close(fdin);
close(1);
dup(fdout);
close(fdout);
execvp(program, argv);
}
// Parent process cleans up, maybe waits for child.
...
dup2 () est un moyen un peu plus pratique de le faire. close () dup () peut être remplacé par:
dup2(fdin, 0);
dup2(fdout, 1);
La raison pour laquelle vous souhaitez procéder est que vous souhaitez signaler les erreurs à stdout (ou stderr) afin que vous ne puissiez pas les fermer et ouvrir un nouveau fichier dans le processus enfant. Deuxièmement, ce serait une perte de temps si l'un des appels à open () renvoyait une erreur.
voir cette page , stdout peut être alias dup(1)
...
appel système de dup () et dup2 ()
• L'appel système dup () duplique un descripteur de fichier ouvert et renvoie le nouveau descripteur de fichier.
• Le nouveau descripteur de fichier a les propriétés suivantes en commun avec le descripteur de fichier d'origine: 1. fait référence au même fichier ou canal ouvert. 2. a le même pointeur de fichier - c'est-à-dire que les deux descripteurs de fichier partagent un pointeur de fichier. 3. a le même mode d'accès, qu'il soit en lecture, en écriture ou en lecture et écriture.
• Dup () est sûr de renvoyer un descripteur de fichier avec la valeur entière la plus basse disponible. C'est en raison de cette fonction de retour du descripteur de fichier non utilisé disponible que les processus effectuent la redirection des E/S.
int dup (descripteur de fichier)
int dup2 (file_descriptor1, file_descriptor2)
Juste un conseil sur " dupliquer la sortie standard ".
Sur certains systèmes Unix (mais pas GNU/Linux)
fd = open("/dev/fd/1", O_WRONLY);
c'est équivalent à:
fd = dup(1);
Exemple:
close(1); //closing stdout newfd=dup(1); //newfd takes value of least available fd number
Où cela arrive aux descripteurs de fichiers:
0 stdin .--------------. 0 stdin .--------------. 0 stdin 1 stdout =| close(1) :=> 2 stderr =| newfd=dup(1) :=> 1 newfd 2 stderr '--------------' '--------------' 2 stderr
Une question se pose à nouveau: comment puis-je
dup()
un descripteur de fichier que j'ai déjà fermé?
Je doute que vous ayez conduit l'expérience ci-dessus avec le résultat indiqué, car cela ne serait pas conforme à la norme - cf. dup :
Le dupLa fonction () échouera si:
- [EBADF]
- Le fildes L'argument n'est pas un descripteur de fichier ouvert valide.
Ainsi, après la séquence de code affichée, newfd
ne doit pas être 1
, mais plutôt -1
et errno
EBADF
.