2016-11-07 2 views
1

Je ne connais pas encore les processus, les canaux et le dup2, par conséquent, j'aimerais que quelqu'un m'aide à comprendre ce qui ne va pas avec un programme que j'ai créé. Ce programme est censé fonctionner ls | wc. Jusqu'à présent, la sortie que je reçois est:Utilisation de processus pour exécuter des commandes avec des canaux

wc : standard input : Bad file descriptor 
     0   0   0 
ls : write error : Bad file descriptor 

Après avoir reçu cette sortie, le terminal accepte toujours les entrées. C'est comme si wc est toujours en cours d'exécution, bien que si je mets d'abord des commandes comme ls (sans aucune autre entrée), il les exécute et s'arrête. J'ai essayé d'exécuter ps avant/après et pendant que le programme était encore en cours d'exécution et il n'a montré aucun processus ouvert en dehors de bash et ps. (Je suis en cours d'exécution de ce programme dans le terminal Linux)

Voici mon code:

#include<stdio.h> 
#include<unistd.h> 
#include<sys/types.h> 
#include<stdlib.h> 
#include<string.h> 
#include<sys/wait.h> 
#include<errno.h> 

int main(int argc, char* argv[]){ 
     pid_t pid; 
     int fd[2]; 
     char com1[1024] = ("ls"); 
     char com2[1024] = ("wc"); 
     pipe(fd); 
     pid = fork(); 
     if(pid == 0){ 
      open(fd[1]); 
      dup2(fd[0],STDOUT_FILENO); 
      close(fd[0]); 
      execlp(com1, com1, NULL); 
        } 
     else { 
      pid = fork(); 
      if (pid == 0){ 
        open(fd[0]); 
        dup2(fd[1],STDIN_FILENO); 
        close(fd[1]); 
        execlp(com2, com2, NULL); 
         } 
      } 
return 0; 
} 

Gardez à l'esprit que je connais si les commandes de contrôle sont nécessaires (comme if(pid<0)exit(0);) mais j'ai essayé de simplifier mon code autant que possible afin de voir s'il y a une erreur due à la négligence. Merci d'avance!

+0

Est-ce que le code même compilation? Cela devrait à tout le moins amener le compilateur à vous crier des avertissements. L'appel 'open (fd [0])' (et bien sûr 'open (fd [1])') n'est pas valide et devrait être supprimé. –

+0

En ce qui concerne votre problème, je vous suggère de lire [la page de manuel 'pipe'] (http://man7.org/linux/man-pages/man2/pipe.2.html). Portez une attention particulière aux descripteurs qui sont l'extrémité de lecture et d'écriture du tube. –

+0

Ce code compile sans aucune erreur jusqu'à présent, j'ai supprimé les commandes open() et j'ai la même sortie –

Répondre

0

Selon the pipe manual page:

pipefd[0] se réfère à l'extrémité lecture du tube. pipefd[1] fait référence à l'extrémité d'écriture du tuyau.

Maintenant prenez cette ligne dès le premier enfant, le processus qui appelle la commande ls:

dup2(fd[0],STDOUT_FILENO); 

Ici vous dupliquez le lu extrémité du tuyau à STDOUT_FILENO, à savoir où la production est écrite. Si vous vous arrêtez et que vous y réfléchissez un peu, comment écririez-vous dans un descripteur de fichier en lecture seule comme fd[0]?

Même avec l'autre processus enfant, où vous faites écrire fin de l'entrée standard de tuyau.

La solution est simple: permutez les emplacements des descripteurs que vous dupliquez. Utilisez fd[1] pour le premier processus enfant et fd[0] pour le deuxième processus enfant.

Dans le premier processus où vous appelez la commande ls:

dup2(fd[1],STDOUT_FILENO); 
close(fd[1]); 
execlp(com1, com1, NULL); 

Et dans le second processus enfant où vous appelez la commande wc:

dup2(fd[0],STDIN_FILENO); 
close(fd[0]); 
execlp(com2, com2, NULL);