2010-02-03 10 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; 
} 

Si doy un argumento de línea de comando como "ls grep .c" debería obtener todos los archivos ".c" mostrados.Tubería de implemento ("|") usando C .. (horquilla utilizada)

pseudocódigo: - "ls" Mi proceso hijo se ejecutará & proceso padre se ejecutará ".c grep" .. proceso padre espera hasta que el proceso hijo termine de manera que niño escribe a la tubería. plazo

prueba: -

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

¿Por qué está sucediendo?

+0

Ok. Obtuve la respuesta yo mismo. Usé "execl()" en el proceso secundario que no busca el nombre de archivo usando la variable de entorno $ PATH .... Si cambio a execlp(), el programa se ejecuta como se esperaba. –

+2

Probablemente tampoco quiera ese "wait (y childpid);" (o su comentario inexacto) allí. No espera hasta que los datos provengan del niño, espera hasta que el estado del proceso secundario cambie, p. salida. Si el proceso de su hijo escribe más de los datos de una tubería (tal vez 8k) se colgará esperando a que el padre lo lea, mientras el padre aún espera que salga. – jmb

+0

entonces, ¿qué debería hacer para que el padre se ejecute después de que el niño haya ejecutado ...? –

Respuesta

8

Un simple error: su llamada execl en realidad debería ser execlp. Además, puede deshacerse de las declaraciones wait y close. Luego debe verificar el código de error execlp.

+0

+1 para publicar respuesta ~ 1 hora antes de que OP obtenga su propia respuesta – jschmier

+0

No es necesario que pruebe el estado de devolución de 'exec *() 'funciones; si la función regresa, falló. Pero está en lo correcto de que debería haber algún tipo de manejo de error para una función 'exec *()' fallida. –

1

Una cosa más, el close(0) y el close(1) son innecesarios, la función dup2() lo hace automáticamente por usted.

+0

Tienes razón. El 'close (0)' y 'close (1)' serían relevantes si el código usa 'dup()' en lugar de 'dup2()'. –

Cuestiones relacionadas