• 締切済み

子プロセスのコマンド結果

pipe(),fork(),dup2()等を駆使し、子プロセスにコマンドを実行させる処理にて、 子プロセスの実行したコマンドが入力待ちか処理終了しているかを判定する方法ってありますで しょうか?

みんなの回答

  • muyoshid
  • ベストアンサー率72% (230/318)
回答No.2

こんにちわ。 fork() の復帰値 (子プロセスのID) を取り出しておいて、 kill(子プロセスID, 0) とすれば、指定したプロセスID の プロセスが生きているかどうか分かります。

  • a-kuma
  • ベストアンサー率50% (1122/2211)
回答No.1

子プロセスが終了したときには、親プロセスには SIGCHLD が飛んできますので、いつ終了したかは、それで分かります。 「入力待ちか?」というのは、親から write するハンドルに対して、read で ブロックされている常態か、他の処理が走っている最中かを調べたい、ということ でしょうか? それようの仕組みは、私が知る限りでは *無い* ので、別途、プロセス間で通信する必要があります。 通信といってもたいそうなことではなく、子プロセスが read に入った、read から抜けた、の 二つの状態が分かればよいだけであれば、SIGUSR1 と SIGUSR2 を使うだけで十分です。 他にも、SYSV のプロセス間通信の手段がありますが、pipe を使っているのですから 「子が待ちに入っているかどうか」を細かく知らなければいけない、というプログラムに すること自体が間違っている、と思います。

sting
質問者

補足

具体的には以下のようなソースを作成中であり、 以下であれば1件目の受信メールを任意ファイルに 保存されます。 しかし、メール有無の判定方法がわからないため No Mail For User と言うメッセージが出力されてしまいます。 コマンド実行の結果を標準出力させたくないのですが、 以下の方法だと出力されてしまい・・・。 メール有無は出力後のファイルサイズなどを調査するしかないでしょうか? /* パイプの作成 */ Rc = pipe(PipeFd) ; if (Rc) { return -1; } Rc = pipe(PipeStdOut) ; if (Rc) { return -1; } /* 子プロセスの生成 */ Pid = fork() ; if (Pid == -1) { close(PipeFd[1]) ; close(PipeFd[0]) ; return -1; } /* 子プロセスの処理 */ if (Pid == 0) { if (close(PipeFd[1])) { exit(1) ; } if (close(PipeStdOut[0])) { exit(1) ; } /* パイプを標準入力へ */ if (close(STDIN_FILENO)) { exit(1) ; } if (dup(PipeFd[0]) == -1) { exit(1) ; } if (close(PipeFd[0])) { exit(1) ; } /* メッセージを表示しない*/ if (close(STDOUT_FILENO)) { exit(1) ; } if (dup(PipeStdOut[1]) == -1) { exit(1) ; } if (close(PipeStdOut[1])) { exit(1) ; } /* メーラを実行 */ execlp("mailx","mailx",NULL) ; exit(1) ; } /* 親プロセスの処理 */ if (close(PipeFd[0])) { kill(Pid,SIGKILL) ; wait((int *)NULL) ; close(PipeFd[1]) ; return -1; } if (close(PipeStdOut[1])) { kill(Pid,SIGKILL) ; wait((int *)NULL) ; close(PipeFd[1]) ; return -1; } /* 標準入力へ指示する */ sprintf(Buf,"s %s\nq\n","/home/user/mbox") ; Length = strlen(Buf) ; if (write(PipeFd[1],(void *)Buf,Length) != Length) { if (errno != EPIPE) { kill(Pid,SIGKILL) ; wait((int *)NULL) ; close(PipeFd[1]) ; return -1; } } if (close(PipeFd[1])) { kill(Pid,SIGKILL) ; wait((int *)NULL) ; return -1; } /* 子プロの標準出力を捨てる*/ while( read(PipeStdOut[0], (void *)Buf,sizeof(Buf)) ) ; if (close(PipeStdOut[0])) { kill(Pid,SIGKILL) ; wait((int *)NULL) ; return -1; } Rc = (int)wait((int *)NULL) ; if (Rc == -1) { return -1; } return 0;