Comprendre l’appel système Unix dup2?

Je joue avec la fonction dup2() pour essayer de mieux le comprendre.

En regardant le manuel, il faut deux parameters. Le premier est le descripteur de fichier existant et le deuxième paramètre est le descripteur de fichier copié.

J’ai décidé d’essayer de redirect stdout vers mon extrémité d’écriture du tube.

À en juger par le manuel, je pensais que le code devrait être …

  if ((dup2(STDOUT_FILENO, fd[1])) <= 0) { printf("error on dup \n"); } write(STDOUT_FILENO, "Hi \n", 5); 

Comme stdout serait maintenant dupliqué dans fd [1]. Par conséquent, si nous écrivions à stdout, nous devrions écrire pour écrire la fin du tube. Cependant, cela imprime toujours à l’écran. J’ai donc supposé que ce devrait être fd [1] suivi de stdout. Donc, cela signifie que stdout est maintenant une copie de fd [1] et c’est pourquoi cela fonctionne.

Enfin, si je voulais réécrire à l’écran … comment ferais-je cela dans le même processus?

Le prototype de dup2 est: int dup2 (int oldfd, int newfd);

Donc votre visage:

 dup2(STDOUT_FILENO, fd[1]) 

copie le stream associé à STDOUT_FILENO (qui normalement sera 1) au descripteur dans fd [1]. Supposons que vous ayez mis la valeur du descripteur 4 dans fd [1], puis à la fin, 1 et 4 indiqueront tous deux le “stream de sortie standard” qui est généralement le terminal tty / pty.

Après l’appel (s’il réussit), fd [1] ne fait plus référence à un canal. On dirait que vous confondez la fonctionnalité dup / dup2 avec pipe. pipe() crée une paire de descripteurs avec une fin de lecture et d’écriture. Si vous faites ensuite un bifurcation, vous pouvez connecter deux processus avec le tube, puis un processus fils avec un tube peut tromper son canal vers STDIN_FILENO ou STDOUT_FILENO, de telle sorte que les routines standard lisent / écrivent au terminal.

La seule chose qui fait que 0, 1, 2 spécial est qu’ils sont initialement ouverts à un terminal, et que les routines de la bibliothèque y font référence par leur numéro (ou macro SDTIN_FILENO, etc.). et lier le descripteur sous-jacent à l’emplacement d’origine.

On dirait que ce que vous voulez faire est de passer fd [1] dans le premier argument et de le piéger dans STDOUT_FILENO afin de connecter votre pipe à un stream standard.