- 締切済み
forkの失敗???
C++(UNIX)です。 以下のようなprogramをくみました。 comは自作のCシェルです。 ------------------- : pid_t ch_pid = fork(); cout << "ch_pid = " << ch_pid<< endl; int shell_ret = 0; int execl_ret = 0; int status = 0; if( ch_pid == 0) { cout << "execl(shell)" << endl; execl_ret = execl(com, com, NULL); cout << "execl ret = " << execl_ret << endl; } else if(ch_pid < 0) { cout << "fail to fork" << endl; cout << "errno = " << errno << endl; return 0; } waitpid(ch_pid, &shell_ret, 0); : ------------------ 実行したところ、 成功する[シェルが実行される]場合と、失敗する[シェルが実行されない]場合があります。 シェルが失敗するときはそれ以上先に進まず、固まってしまいます。(waitpidのせいだと思いますが。) 成功する場合のログ --------------- ch_pid = 12885 ch_pid = 0 execl(shell) : --------------- 失敗する場合のログ --------------- ch_pid = 12885 : --------------- forkに失敗していたら、"fail to fork"と表示されると思うので forkには失敗していないと思うのですが・・・。 なぜ、execlは実行されないのでしょうか。
- みんなの回答 (3)
- 専門家の回答
みんなの回答
- terra5
- ベストアンサー率34% (574/1662)
このソースだとexecl()が失敗した場合, waitpid()を実行してしまい、ハングするでしょうね。 return errnoあたりが適切でしょうか。 あとは、情報不足なのでわかりません。 fork()やexecl()の失敗時のerrnoは必ずわかるようにしておきましょう。 -1がわかってもうれしくないです(^^; execl()が失敗する可能性も無いとは言えないかなぁ。
- pikacchu
- ベストアンサー率44% (11/25)
C++は少しかじったくらいなのではっきり言えませんが、なぜエラーになるのかの判断として、errnoを見てみるのはどうですか? 通常ですとerrno.hをインクルードして変数errnoを見ればエラーの種類がわかります。例えば、メモリが足りないとか・・・ただし、errnoはintの整数ですが、ヘッダの中を見ればエラーの種類はわかりますよ。
お礼
ありがとうございます。 errnoは使っていました。 が、manで調べていたので、エラーの種類がわからなかったんです。 ヘッダの中を見て、ようやく分かりました。ありがとうございました。
- ranx
- ベストアンサー率24% (357/1463)
このような質問をされる際の一般原則ですが、お使いの環境(OSの種類など)について 書いておいて頂いた方が、的確な回答を得やすいと思います。 プログラムを拝見しましたが、この範囲では、特に問題のありそうな個所は見当たらない ように思います。恐らく、fork()が失敗したわけでもexecl()が失敗したわけでもない ...となると、残るはcomの内部ですね。(ch_pid =0;execl(shell)が表示されないのは、 恐らくバッファリングされて、出力されていないためでしょう。) 試みに、ハングアップした状態で、psコマンドで状況を確認してみて下さい。 ・子プロセス(csh)が動いていなければ、上のプログラムに問題があります。 ・子プロセスが起動されながら動いていなければ、comが何かのリソース待ちです。 ・子プロセスが動きつづけていれば、恐らくcomが何かのバグで、無限ループに陥っています。
お礼
回答ありがとうございました。 ここでは記載していなかったのですが、 この関数がスレッドだったためfork()ではなく、fork1()を使うほうが良かったようです。 また、fork()とexecl()の間にログを吐くマクロ(自作)を入れていたのですが、それが大きな原因だったようです。
お礼
回答ありがとうございます。 execl()の失敗等のエラー処理も追加しました。