- ベストアンサー
execlしない・・・
下記のようなクライアントから要求を受けてサーバはそれを実行して結果をクライアントに返す仕様のプログラムを書きました。 すると、画面にdup OKまでは表示されるのですが、execl OKが出ません。 もちろん、そのあとのsendもしないので、クライアント側に結果が届きません。 execlが出来ていないのかと思い、cgi.outを開くと、中に、CGIの実行結果(画面にHTMLの文書を表示させるというものですが、その文書)が書き込まれているので、実行はしてるみたいなんです。 なので、どの状況でとまっているのかわからず、困っています。 教えてください(><)
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
わざわざファイルを中継させる必要はないですよ。 dup2()を使って pid=fork(); if(pid==0){ dup2(ns,1); execl(execfile, ....); //↑ //execfile は結果をstdoutに吐く } close(ns); こう書けます。 親プロセスはその後ノータッチでOK。 もし,ファイルを中継し,親プロセス側で処理したいなら,wait()で子の終了を待つ必要があるんじゃないかな? # 疑問形なのはexec先の挙動がわからないため。
その他の回答 (3)
- ranx
- ベストアンサー率24% (357/1463)
No.2です。一言書き落としました。 別のプログラムを現行プロセスの置き換えではなく 「別プロセス」として実行する場合は、execl()の前に fork()を実行して下さい。これは、実行中のプログラムを コピーする関数で、親プロセスには子プロセスのIDが、 子プロセスにはゼロが返ります。一般的にこんなプログラムに なります。 int pid; pid = fork(); if (pid < 0) { /*エラー処理*/ } else if (pid == 0) { /*子プロセス - プログラム実行*/ execl(・・・); } else { /*親プロセスの処理 - wait等*/ }
補足
返答ありがとうございます。 すいません。組んだプログラムの抜粋部分にはないんですが、下のプログラムでpid2となっているのは、その前でforkして、子プロセスを作ったからなんです。 ということは、これはexeclでcgiを実行したあと、子プロセスを閉じて、親プロセスでcgi.outの中身をsendする、というふうに書き換えればよいのでしょうか?
- ranx
- ベストアンサー率24% (357/1463)
execl()は正常に実行されると、戻ってきません。 exit()の親類だと思って下さい。 実行中のプログラムを別のものに置き換える関数ですので。
- piyoco
- ベストアンサー率0% (0/1)
ouka_sです。 800文字以内だってので貼れなかったので、友人にログインしてもらって貼ってもらいます。 こんなプログラムを書きました。 (略) else if(pid2 == 0){ printf("%s\n",filename); strcat(str5, filename); fd = open("cgi.out", O_WRONLY|O_CREAT, 0644); printf("%s\n",str5); close(1); dup(fd); fprintf(stderr,"dup OK\n"); execl(str5, filename ,NULL); fprintf(stderr,"execl OK\n") if((execl(str5,filename,NULL))<0){ perror("execl"); strcat(str3,str2); send(ns, str3, strlen(str3), 0); fp3 = fopen(filename2,"r"); while(fgets(filedata,strlen(filedata), fp3) != NULL){ send(ns, filedata, strlen(filedata), 0); } exit(1); } /*send to client*/ else if{ fpcgi = fopen("cgi.out","r"); while((fgets(filedata,sizeof(filedata), fpcgi)) != NULL){ send(ns, filedata, strlen(filedata), 0); } fclose(fpcgi); } } (以下略) ※str5 = "/home/(中略)/cgi-bin/\0" filename = "hello.cgi\0" が入っています。
お礼
ありがとうございます! ソケットに直接送るという、onosukeさんの方法で、うまく走らせることができました! execlすると、そのあとの操作はされないんですね。 wait関数はつかったことないんですが、それも勉強しようと思います。