2016-11-20 5 views
0

私は現在fork()を使って子プロセスを作成するプログラムを書いています。この子プロセスはシェルコマンド "uniq"を "-d"オプションで実行し、stdinから読み込みます。実行コマンドの後、 "uniq"プログラムのパイプ上でstdinとして文字列を送りたい。だから私はお互いの背後に同じ文字列を送信した後、文字列はstdoutに出力されるはずです(uniqのmanページ:https://linux.die.net/man/1/uniq参照)。しかし、何も印刷されていません。ここで子プロセスがuniq -dを実行すると、stdin上のパイプによって渡された重複が表示されないのはなぜですか?

は、これまでの私のコードです:

void execute_uniq_process() 
{ 
    //create pipe 
    int pipefd[2]; 
    if(pipe(pipefd)<0) 
    { 
     //error handling 
    } 

    //create argv for command: 
    char *argv[] = {"uniq","-d",(char *)0}; 

    //create child process 
    pid_t pid = fork(); 
    int status; 

    switch(pid) 
    { 
     case -1: 
     //error handling 
     break; 

     case 0: 
      //child process 
      //close writing end in pipe 
      close(pipefd[1]); 

      //duplicate stdin 
      dup2(pipefd[0],STDIN_FILENO); 
      close(pipefd[0]); 

      execvp("uniq",argv); 
      exit(errno); 
     break; 

     default: 
      //parent process 
      //close reading end in pipe 
      close(pipefd[0]); 

      //write all commands to pipe 
      write(pipefd[1],"test1",5); 
      write(pipefd[1],"test1",5); 
      write(pipefd[1],"test2",5); 
      //edited: 
      close(pipefd[1]); 

      //waits till child is finished 
      wait(&status); 

      if(WEXITSTATUS(status) != EXIT_SUCCESS) 
      { 
       //error handling 
      } 
     break; 
    } 
} 

だから私は、印刷された「TEST1」はシェルであることを期待します。私はまた、uniqプロセスをきれいに終了させる方法を知っています。私はおそらく書くことに問題があると思うので、パイプに書き込むすべての文字列の後に "入力"をシミュレートする必要があります。

+1

'uniq'が終了するのを待つ前にパイプを閉じる必要があります。パイプを閉じるまでEOFがあることを知らないからです。そして、あなたは 'uniq'の標準入力に1行も書いていません。 'write()'システムコールはあなたが書いたことをあなたが書いたものを書き出し、確かにそれ自身の意志の改行を追加しません。 –

+0

ありがとうございます。私は自分の投稿を編集し、uniqプロセスを待つ前にパイプを閉じました。今度は終了します。しかし、私はuniqの標準に何も書かれていない今まで理解していません。子供の読み終わりは標準入力に向かいました。親はパイプに書き込む。申し訳ありませんが、私はこのトピックに新しいです。 – hiaslosch17

+0

あなたは 'uniq'への入力行全体を書いていません。あなたが書くものには改行がないので、重複はありません( 'uniq'は' test1test1test2'に改行なし)。私の答えを見てください。 –

答えて

0

uniqが終了するのを待つ前に、パイプを閉じる必要があります。これは、パイプを閉じるまでEOFがあることを知らないためです。 uniqの標準入力には、書き込まれたデータに改行がないため、1行も書いていません。 write()システムコールは、あなたが書き込むように指示したものだけを書き込みます。それは確かにそれ自体の意志の改行を追加しません。

これらの変更、および雑貨トリビア、につながる:それが実行されると、これがtest1を出力

#include <errno.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <sys/wait.h> 
#include <unistd.h> 

int main(void) 
{ 
    int pipefd[2]; 
    if (pipe(pipefd) < 0) 
    { 
     fprintf(stderr, "Failed to create pipe\n"); 
     return 1; 
    } 

    char *argv[] = {"uniq", "-d", (char *)0}; 

    pid_t pid = fork(); 

    switch (pid) 
    { 
    case -1: 
     fprintf(stderr, "Failed to fork\n"); 
     return 1; 

    case 0: 
     close(pipefd[1]); 
     dup2(pipefd[0], STDIN_FILENO); 
     close(pipefd[0]); 
     execvp(argv[0], argv); 
     fprintf(stderr, "Failed to exec %s\n", argv[0]); 
     exit(errno); 

    default: 
     close(pipefd[0]); 
     write(pipefd[1], "test1\n", 6); 
     write(pipefd[1], "test1\n", 6); 
     write(pipefd[1], "test2\n", 6); 
     close(pipefd[1]); 
     int status; 
     int corpse = wait(&status); 

     if (WEXITSTATUS(status) != EXIT_SUCCESS) 
     { 
      fprintf(stderr, "Child (%s) exited (PID %d, status 0x%.4X)\n", argv[0], corpse, status); 
     } 
     break; 
    } 
    return 0; 
} 

関連する問題