2010-04-17 4 views
8

J'essaie de mettre en œuvre une coque Linux qui prend en charge la tuyauterie. J'ai déjà fait des commandes simples, des commandes fonctionnant en arrière-plan, des redirections, mais le piping est toujours manquant.Mise en œuvre de la canalisation

J'ai déjà lu à ce sujet et vu quelques extraits de code, mais je n'ai toujours pas été en mesure de résoudre une solution de travail.

Ce que j'ai jusqu'à présent:

int fd[2]; 

pipe(fd); 

pid_t pid = fork(); 

if (pid == -1) 
    return -1; 

if (pid == 0) 
{ 
    close(fd[1]); //close write to pipe, in child 
    execlp("cat", "cat", "names.txt", NULL); 
} 

else 
{ 
    close(fd[0]); //close read from pipe, in parent 
    execlp("sort", "sort", NULL); 
} 

Je suis un programmeur débutant, comme vous pouvez le dire, et je ne sais pas quand je programmais quelque chose de beaucoup au sujet, ce qui est évidemment le cas, je Je voudrais commencer par quelque chose de vraiment simple et concret, puis construire à partir de là. Donc, avant de pouvoir implémenter trois commandes différentes et plus en pipeline, j'aimerais pouvoir calculer "ls names.txt | sort" ou quelque chose de similaire, dans lequel names.txt est un fichier de noms alfabétiquement non ordonné.

Code mis à jour, mais ne fonctionne toujours pas.

Merci.

Répondre

9

Vous devez remplacer un stdout de l'enfant avec l'extrémité d'écriture de la pipe, et stdin de l'autre enfant avec l'extrémité de lecture:

if (pid == 0) 
{ 
    close(fd[1]); //close write to pipe, in child 
    dup2(fd[0], STDIN_FILENO); // Replace stdin with the read end of the pipe 
    close(fd[0]); // Don't need another copy of the pipe read end hanging about 
    execlp("cat", "cat", "names.txt", NULL); 
} 
else 
{ 
    close(fd[0]); //close read from pipe, in parent 
    dup2(fd[1], STDOUT_FILENO); // Replace stdout with the write end of the pipe 
    close(fd[1]); // Don't need another copy of the pipe write end hanging about 
    execlp("sort", "sort", NULL); 
} 
4

Examinez l'appel de bibliothèque standard pipe(). Ceci est utilisé pour créer un tuyau. Vous devez bien sûr faire une partie du travail avant vous fork(), afin que le processus fils hérite correctement du descripteur de fichier.

Notez également l'ordre des arguments à dup2():

int dup2(int oldfd, int newfd); 

dup2() transforme newfd la copie de oldfd, fermeture newfd d'abord si nécessaire

+0

Je le savais déjà, j'ai juste oublié d'ajouter l'instruction pipe au code. Que suggérez-vous maintenant? Merci. – nunos

+0

Je pensais que dup2 (0, fd [0]) copiait ce qui était censé aller à stdout à fd [0], qui est l'entrée du processus. Je suppose que ce que je veux, non? – nunos

+0

@nunos: dup2() ne fait pas la copie, il copie * des descripteurs de fichier *. Puisque fd [0] est le fd d'une extrémité de votre nouveau tube, cela n'a pas beaucoup de sens de le fermer, comme le fera dup2(). – unwind