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

Komut satırı argümanını "ls grep .c" olarak verirseniz, tüm ".c" dosyalarının görüntülenmesi gerekir.Boruları ("|") kullanarak C .. (kullanılan çatal)

yalancı kod: - çocuk bunu çocuk borusuna yazar böylece tamamlar kadar Çocuğum süreci çalışacaktır "ls" & ebeveyn süreci "grep .c" çalışacak .. Veli süreci bekler.

test çalışması: - Neden oluyor ki

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

?

+0

Tamam. Cevabı kendim aldım. $ PATH ortam değişkenini kullanarak dosya adını aramayan çocuk işleminde "execl()" kullandım. execlp() 'e değiştirirseniz, program beklendiği gibi çalışır. –

+2

Muhtemelen bunu istemiyorsunuz "bekle (& childpid);" (ya da onun yanlış yorum) orada. Veriler çocuktan gelene kadar beklemez, çocuk süreç durumu değişene kadar bekler - örn. çıkış. Çocuğunuz bir borudan daha fazla veri yazıyorsa (belki 8k), ebeveynin okumaya devam etmesi beklenirken, ebeveyn hala çıkmasını bekler. – jmb

+0

Yani, aslında ebeveynin çocuk çalıştırdıktan sonra yürütmesi için ne yapmalıyım? Ebeveyn ucundan –

cevap

8

Basit bir hata: execl aramanız aslında execlp olmalıdır. Ayrıca, wait ve close ifadelerinden de kurtulabilirsiniz. Daha sonra execlp hata kodunu kontrol etmelisiniz.

+0

+1, OP'nin kendi cevabını almadan önce ~ 1 saat cevap yazdırabilmek için – jschmier

+0

'exec 'i ​​geri döndürme durumunu test etmeniz gerekmez. *() 'fonksiyonları; işlev döndüğünde, başarısız oldu. Ancak, hatalı bir 'exec *()' işlevi için bir çeşit hata işleme olması gerektiği konusunda haklısınız. –

1

Bir şey daha, close(0) ve close(1) gereksizdir, dup2() işlevi sizin için otomatik olarak yapar.

+0

Haklısınız. 'Close (0)' ve 'close (1)', eğer kod 'dup2()' yerine 'dup()' kullanılırsa uygun olur. –