2010-02-03 15 views
9
#include<stdio.h> 
#include<unistd.h> 
#include<stdlib.h> 

int main(int argc,char **argv) 
{ 
    int fd[2]; 
    pid_t childpid; 
    pipe(fd); 
    childpid=fork(); 
    if (childpid == -1) 
    { 
     perror("Error forking..."); 
     exit(1); 
    } 
    if (childpid) /*parent proces*/ //grep .c 
    { 
     wait(&childpid);  //waits till the child send output to pipe 
     close(fd[1]); 
     close(0);  //stdin closed 
     dup2(fd[0],0); 
     execlp(argv[2],argv[2],argv[3],NULL); 

    } 
    if (childpid==0) //ls 
    { 
     close(fd[0]); /*Closes read side of pipe*/ 
     close(1);  //STDOUT closed 
     dup2(fd[1],1); 
     execl(argv[1],NULL); 
    } 
    return 0; 
} 

Se fornisco l'argomento della riga di comando come "ls grep .c", dovrei ottenere tutti i file ".c" visualizzati.Implementare le tubazioni ("|") utilizzando C .. (fork utilizzato)

Pseudocodice: - mio processo figlio verrà eseguito "ls" & processo padre verrà eseguito "grep .c" .. processo genitore aspetta finché il processo figlio viene completata in modo che bambino scrive al tubo. run

prova: -

bash-3.1$ ls | grep .c 
1.c 
hello.c 
bash-3.1$ ./a.out ls grep .c 
bash-3.1$ 

Perché che succede?

+0

Ok. Ho ricevuto la risposta da solo. Ho usato "execl()" nel processo figlio che non cerca il nomefile usando la variabile d'ambiente $ PATH .... Se cambio in execlp(), il programma funziona come previsto. –

+2

Probabilmente anche tu non vuoi "wait (& childpid);" (o il suo commento inaccurato) lì. Non attende che i dati arrivino dal bambino, attende fino a quando lo stato del processo secondario cambia - ad es. Uscita. Se il processo figlio scrive più di una pipe di dati (forse 8k), si bloccherà in attesa che il genitore legga, mentre il genitore attende ancora che esca. – jmb

+0

quindi, cosa dovrei fare in modo che il genitore venga eseguito dopo che il bambino ha eseguito ...? –

risposta

8

Un semplice errore: la tua chiamata execl dovrebbe essere in realtà execlp. Inoltre, è possibile eliminare le dichiarazioni wait e close. Quindi dovresti controllare il codice di errore di execlp.

+0

+1 per postare risposta ~ 1 ora prima che OP abbia la propria risposta – jschmier

+0

Non è necessario testare lo stato di ritorno di exec *() 'funzioni; se la funzione ritorna, non è riuscita. Ma hai ragione che dovrebbe esserci una sorta di gestione degli errori per una funzione fallita di exec *(). –

1

Un'ultima cosa, il close(0) e close(1) non sono necessari, la funzione dup2() lo fa automaticamente per te.

+0

Hai ragione. 'Close (0)' e 'close (1)' sarebbero rilevanti se il codice usasse 'dup()' piuttosto che 'dup2()'. –