• 締切済み

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

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

  • sting
  • お礼率12% (35/274)

みんなの回答

  • 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;

関連するQ&A

  • コマンド実行結果のエラー標準出力制御について

    unix-cにて子プロセスにてexecvp()を使用しmailxコマンドを実行し、親プロセスにてmailxコマンドの実行結果に出力処理をしたいのですが、 どんなことがあろうと(パスが違うなど)標準出力させたくありません。 現在、fork(),pipe()を駆使して正常系は上手くできるようになったのですが、エラー時の標準出力(親、子とも)を防ぐことが できません。何か良い方法はないでしょうか?

  • fork()で作られた子プロセスから親プロセスの生存を知る方法は?

    タイトルの通りなのですが、プロセスAから fork()で子プロセスBを作り、Bには無限ループで処理をさせます。 Aはユーザからの入力を受け、処理を行います。 Aが終了要求をされプロセスを終了するときに、 Bも同時に終了したいのですが、BからAの生存を判定して Aのプロセスが切れていたBも終了する、ということは可能でしょうか? Bの無限ループ処理では、ファイルの書き換えを行っているので AからBのPIDを指定してKillする、ということはせずに B自身で判定して終了するようにしたいのですが。。

  • パイプのプログラム

    ここまでプログラムはできているのですが、親プロセスと子プロセスのところが分かりません。どなたかお願いします! XXX%a.out a|b のように入力して、コマンドaとコマンドbを、並列処理するプログラムを作っています。 なお、コマンドの実行は execl("/bin/コマンド名",コマンド名,NULL) というシステムコールを利用します。 パイプの生成およびファイル記述子の複製は、 pipe(pipefd)、 dup(pipefd[0])またはdup(pipefd[1]) のシステムコールを用います。 プログラム #include<stdio.h> #include<string.h> main(int argc,char *argv[]) { int pipefd[2],pid; char cmd_a[20]="/bin/"; if(pipe(pipefd)==-1) { perror("pipe error"); exit(1); } if((pid=fork())==-1){ perror("fork error"); exit(1); } if(pid!=0){ /*親プロセス*/ strcat(cmd_a,argv[1]); /*子プロセス*/

  • 子プロセスの管理

    forkした後の子プロセス管理で、終了をsignalで管理しようと思ってるんですが、forkを2回行なえばゾンビ化を防げると書いてありました。この二つの方法に違いはあるんですか?メリット・デメリットがよくわかりません。ちなみに子プロセスからの結果や終了を待つ様なプログラムではなく、ただexec関数での別処理を行なうために子プロセスを作成するだけです。 宜しくお願いします。

  • 子プロセスのデータを親プロセスに渡す方法ってありますか。

    こんにちは。 C言語内でfork()関数を使い親と子を分け、子プロセス間で生成されたデータを親プロセス側に渡して処理したいと考えています。要は、プロセス間でデータのやり取りをpipe()関数かなにかで行いたいと思っています。 子プロセスがデータをテキストファイルでどこかに出力して、それを親プロセスが参照する、というテキストファイルを橋渡しにする原始的な方法があるにはあるのですがこれは最終手段にしたいと考えています。他に良いやり方があればご教授いただけないでしょうか。 以下はサンプルコードです。 #include<stdio.h> #include<stdlib.h> #include<string.h> #include<unistd.h> #include<errno.h> #include<signal.h> #include<sys/types.h> int main(){ FILE *fp,*fp2; int fd[2],a,i = 0; pid_t pid; pipe(fd); char buff[1024]; pid = fork(); sigignore(SIGCLD); //ちゃんと子が死ぬようにする if(pid == 0){ close(STDOUT_FILENO); //画面に出力されないようにする dup2(fd[1],STDOUT_FILENO); close(fd[0]); fp = popen("tcpdump","tcpdump","tcp[13] & 255 == 2",NULL); } else{ sleep(1); //一秒だけ子プロセスを起動 kill(pid,SIGTERM); wait(); //完全に子プロセスを殺す fp2 = popen("wc -l fpのファイルデータ","r"); for(i=0;i<3;i++){ a = fgetc(fp2); putc(a,stdout); }printf("\n"); return 0; } } プログラムの内容は、 tcpdumpで処理(子プロセス)した内容を、wc -l で「行数」のみ取得する(親プロセス)というものです。あくまで目標ですが・・。^^; お手数でしょうが、どうぞよろしくお願いします。

  • プロセスが起動中かどうかを判定するコマンドはありますか?

    あるプログラムを起動したとします。 psコマンドで起動中のプロセス番号を知ることができるのはわかりますが、 プログラム起動中かどうかを判定するコマンドとかあるでしょうか。 たとえば、 >あるコマンド プロセスID のようにプロセスIDを引数として実行すると、プロセス起動中かどうか判定できるような。。。 ご存知な方ご教授おねがいします。

  • 子プロセスと親プロセス

    ある本を読んでいると、以下のような問いにぶち当たり、プログラムの仕方がよくわからないのです。 自分でもいろいろ調べたのですが、わからないので質問させていただきます。 自分のプロセスIDと親のプロセスIDのプロセスIDを表示するコマンドshowpidを作り、showpidを子プロセスとして10回実行するプログラムを作りなさい。ただし、execを用いてshowpidを10回実行すること。 というものなのですが、自分のプロセスIDと親のプロセスIDの表示方法はわかったのですが、それをコマンドとして作り、子プロセスとして10回実行する方法がわからなくて困っております。。。 言語はc言語を使ってもらいたいです。以下に自分のプロセスIDと親のプロセスIDを表示するプログラムを付けときます。 #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> int main(){ pid_t pid; int status; if((pid=fork())==0) printf("I am a child with pid=%d. My parent pid is %d.\n",getpid(),getppid()); else{ wait(&status); exit(EXIT_SUCCESS); }

  • 2つのプロセスを実行するCGI

    1つのCGIで2つのプロセスを実行することを考えています。 1つは、数分かかるような処理を行い、もう1つはユーザにその処理が”実行中”であるといったメッセージを表示しようと思っています。 CGIはC&C++で作成しようと考えており、forkして子プロセスで、数分かかる処理を実行し、親プロセスでメッセージ画面表示といった流れを考えています。 で、質問ですが、この場合、メッセージ画面で子プロセスが実行している間、砂時計が表示され続けますが、これを消す方法がありますでしょうか? また、1つのCGIで、このように2つのプロセスを実行する場合に、何か良い方法はありますでしょうか?

    • 締切済み
    • CGI
  • プロセスの生成

    #include<stdio.h> #include <unistd.h> main(){ int i; printf("\t(%s)プロセスID.....%d\n","元",getpid()); printf("\t(%s)親プロセスID...%d\n","元",getppid()); if((i=fork())==0) { //子プロセスで実行する部分 printf("\t子プロセスでのfork()の値 : %d\n",i); printf("\t(%s)プロセスID.............%d\n","子",getpid()); printf("\t(%s)親プロセスID...........%d\n","子",getppid()); printf("子プロセスを終了します\n"); } else{//親プロセスで実行する部分 printf("\t親プロセスでのfork()の値 : %d\n",i); printf("\t(%s)プロセスID.............%d\n","親",getpid()); printf("\t(%s)親プロセスID...........%d\n","親",getppid()); printf("親プロセスを終了します\n"); } } fork関数の振る舞いについてです。 上記のプログラムをgccでコンパイルして実行した場合出力結果が /_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ (元)プロセスID.....375 (元)親プロセスID...246 親プロセスでのfork()の値 : 376 子プロセスでのfork()の値 : 0 (子)プロセスID.............376 (子)親プロセスID...........375 子プロセスを終了します (親)プロセスID.............375 (親)親プロセスID...........246 親プロセスを終了します _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ という感じで出力されました。 fork関数がプロセスの複製を行っていることと、戻り値が0と376の2つであることはわかりました。 また子プロセスには0を親プロセスには376を返すこともわかりました。 感覚的にはif文の真である子プロセス側の記述文と偽である親プロセス側 の記述文が同時に実行されているのではないかと考えましたが 同時に実行されているのに printf("\t子プロセスでのfork()の値 : %d\n",i); printf("\t親プロセスでのfork()の値 : %d\n",i); で表示される値が違うのはなぜでしょうか。 i=fork()によって代入されているのはわかるのですが、 同時に実行されつつ何故2つの違う値をiは出力できるのかがわかりません。 また出力結果が _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ (元)プロセスID.....377 (元)親プロセスID...246 親プロセスでのfork()の値 : 378 (親)プロセスID.............377 (親)親プロセスID...........246 親プロセスを終了します 子プロセスでのfork()の値 : 0 (子)プロセスID.............378 (子)親プロセスID...........1 子プロセスを終了します _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ 子プロセスから見たときの親プロセスが1となっているのは何故でしょうか? 本来ならば377ではないでしょうか? わかりにくい説明ですいません。 よろしくお願いします。

  • Unixの親プロセスと子プロセスの関係について

    はじめまして。 親プロセスが終了するとそのプロセスから呼ばれた 子プロセスも停止するという認識は正しいでしょうか? というのも、あるシェルスクリプトを"kill -9"コマンドで強制終了させたのですが、そのシェルスクリプト内のコマンド(sleepコマンドです)は終了せずに残っていたので(psで確認しました)、??という感じでした。 さらにそのsleepコマンドの親プロセスが1(init?)になっていました。 色々とWEB上で調べてみたのですが、この動作について の記述を見つけることができませんでした。 どなたかご存知でしたら是非ご教授下さい。よろしくお願いします。

専門家に質問してみよう