2016-04-11 4 views
-1
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <fcntl.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <errno.h> 


int main(void) { 


    if(mkfifo("fifo", S_IRWXU) < 0 && errno != EEXIST) { 
     perror("Fifo error"); 
     exit(EXIT_FAILURE); 
    } 

    pid_t pid = fork(); 

    if(pid == 0) /*dziecko*/ 
    { 
     int fifo_write_end = open("fifo", O_WRONLY); 

     if(fifo_write_end < 0) 
     { 
      perror("fifo_write_end error"); 
      exit(EXIT_FAILURE); 
     } 

     if(dup2(fifo_write_end, STDOUT_FILENO) < 0) 
     { 
      perror("dup2 fifo_write_end error"); 
      exit(EXIT_FAILURE); 
     } 

     if(execlp("/bin/ls", "ls", "-al", NULL) < 0) 
     { 
      perror("execlp error"); 
      exit(EXIT_FAILURE); 
     } 

    } 


    if(pid > 0) /*rodzic*/ 
    { 
     int fifo_read_end = open("fifo", O_RDONLY); 

     if(fifo_read_end < 0) 
     { 
      perror("fifo_read_end error"); 
      exit(EXIT_FAILURE); 
     } 
     if(dup2(fifo_read_end, STDOUT_FILENO) < 0) 
     { 
      perror("dup2 fifo_read_end error"); 
      exit(EXIT_FAILURE); 
     } 

     int atxt = open("a.txt", O_WRONLY|O_CREAT, S_IRWXU); 

     if(atxt < 0) 
     { 
      perror("a.txt open error"); 
      exit(EXIT_FAILURE); 
     } 

     if(dup2(atxt,STDOUT_FILENO) < 0) 
     { 
      perror("dup2 atxt error"); 
      exit(EXIT_FAILURE); 
     } 

     if(execlp("/usr/bin/tr", "tr", "a-z", "A-Z", NULL) < 0) 
     { 
      perror("tr exec error"); 
      exit(EXIT_FAILURE); 
     } 

    } 

    if(pid < 0) 
    { 
     perror("Fork error"); 
     exit(EXIT_FAILURE); 
    } 


    return 0; 
} 

プログラムは停止しません。なぜ私は考えていない。 ls -al |を実行する必要があります。 tr a-z A-Zを作成し、ファイルa.txtに書き込みます。C - mkfifo、ls - 停止しない

誰かができる場合は、私に説明する方法を教えてください。ls-al | tr a-z A-Z | tr A-Z a-z> a.txtである。別のtrのために、私は2番目のmkfifoの権利が必要ですか?私はそれがどのように動作しているのか分からず、ここで記述子を書き込んだり読んだりするとどうなるでしょうか。 「パイプ」ではそれは昔ながらのものでした。

ありがとうございました!

答えて

1

パイプの読み取り側は、パイプが閉じられるまでEOFを報告しません。 すべてまでパイプは閉じられていません。それを参照する記述子は閉じられています。 dup2に電話をかけた後、元のFDとそれを欺いたディスクリプタの両方によってパイプが参照されます。元のFDを閉じる必要があります。

if(dup2(fifo_write_end, STDOUT_FILENO) < 0) 
    { 
     perror("dup2 fifo_write_end error"); 
     exit(EXIT_FAILURE); 
    } 
    close(fifo_write_end); 
    if(execlp("/bin/ls", "ls", "-al", NULL) < 0) 
    { 
     perror("execlp error"); 
     exit(EXIT_FAILURE); 
    } 

もう一つの問題は、trを実行しているプロセスがstdin、ないstdoutにFIFOをDUPする必要があるということです。だから、

if(dup2(fifo_read_end, STDOUT_FILENO) < 0) 
    { 
     perror("dup2 fifo_read_end error"); 
     exit(EXIT_FAILURE); 
    } 

if(dup2(fifo_read_end, STDIN_FILENO) < 0) 
    { 
     perror("dup2 fifo_read_end error"); 
     exit(EXIT_FAILURE); 
    } 
+0

おかげである必要があり、それが近いリード後に動作しますが、何秒TRと。私は2番目のmkfifoが必要ですか? – Gwiazdek

+1

はい、各パイプにFIFOが必要です。なぜ、 'pipe()'を呼び出す代わりにFIFOを使用していますか? – Barmar

+0

これは私の研究の課題です。はっきりするためには、第2のfifoはどこにあるべきですか? 「孫」を作るためには、まず子どもの上と上のような2つのフォークがありますか? – Gwiazdek

関連する問題