dup2(2)
Appel système
Fait d'un descripteur de fichier une copie d'un autre. C'est l'appel qui redirige la sortie standard vers un fichier ou un pipe avant un exec.
#include <unistd.h>
int dup2(int oldfd, int newfd);Description
dup2(oldfd, newfd) fait pointer le descripteur newfd vers le même fichier ouvert que oldfd. Si newfd était déjà ouvert, il est d'abord fermé, sans signaler d'erreur. Après l'appel, les deux numéros désignent le même fichier et partagent sa position et ses options d'ouverture ; seul le drapeau « close-on-exec » reste propre à chacun.
L'usage le plus courant est la redirection. Les descripteurs 0, 1 et 2 sont l'entrée standard, la sortie standard et la sortie d'erreur (STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO). dup2(fd, STDOUT_FILENO) envoie tout ce que le processus écrit sur sa sortie standard dans fd, un fichier ou l'extrémité d'écriture d'un pipe. Comme les descripteurs survivent à execvp, un programme lancé ensuite écrit lui aussi au nouvel endroit, sans le savoir.
Valeur de retour
Le nouveau descripteur, donc newfd. -1 en cas d'erreur, avec errno : EBADF si oldfd n'est pas ouvert (dans ce cas newfd n'est pas fermé), EINTR si un signal a interrompu l'appel. Si oldfd et newfd sont égaux, dup2 ne fait rien et renvoie newfd.
Pièges
Après
dup2(fd, STDOUT_FILENO), fermefd: il ne sert plus, et un descripteur de pipe resté ouvert empêche le lecteur de voir la fin du flux.L'ordre des arguments est celui de
cp: la source d'abord, la destination ensuite.dup2(STDOUT_FILENO, fd)fait l'inverse de ce qu'on voulait.La redirection ne touche pas le tampon de
printf. Du texte écrit avantdup2et pas encore vidé partira au nouvel endroit. Appellefflush(stdout)avant de rediriger.
Exemple
#include <fcntl.h>#include <stdio.h>#include <unistd.h>
int main(void){ printf("à l'écran\n"); fflush(stdout);
int fd = open("sortie.txt", O_WRONLY | O_CREAT | O_TRUNC, 0644); if (fd == -1) { perror("open"); return 1; } dup2(fd, STDOUT_FILENO); close(fd); printf("dans le fichier\n"); return 0;}$ gcc -Wall -Wextra redirige.c -o redirige$ ./redirigeà l'écran$ cat sortie.txtdans le fichierLe second printf n'a pas changé : c'est le descripteur 1 qui mène désormais au fichier.
process_stream_open
Écris process_stream_open, qui lance une commande dans un enfant et branche sa sortie ou son entrée standard sur un pipe dont tu renvoies l'autre extrémité.