WEB相談室

Webページ作成に関しての何でも掲示板です。

タイトル:CGIの動作について

0:[投稿] 29歳からのPerl [2002/10/01 22:47 ][環境:WIN+IE UNIX系+Perl]

長らく解決してない問題の一つなのですが。
スクリプトの動作中に、(Web)クライアント側にレスポンスを開始・終了できないのでしょうか?

よくあるのは、以下のような形です。
画像データを出力して、その後は統計処理のみをするような処理です。

#前処理
print("Content-type: image/gif\n");
print("Content-length: $size\n\n");
print($image);
# この時点で、レスポンスを完了にしたい
# この後は、計算してdb処理だけして終了

標準出力を閉じたらなど試してみたのですが、
うまくいきませんでした。

よろしくお願いします。


1:[回答] TOM neko [2002/10/02 07:53 ]

close(STDOUT);でいいと思うのですが、うまくいかないのは変ですね。サーバが違うのかな。Apacheでは出来ましたが。


2:[回答] B-Cus [2002/10/02 09:30 ]

なんでそんな難しい例から始めるんでしょうか。問題の切り分けが
難しくなるだけなのに。やるのなら↓この程度では?

print "Content-type: text/plain\n\n";
print "test";
close(STDOUT)
sleep 10;


3:[回答] Mr.X [2002/10/02 12:50 ]

> close(STDOUT);
これをやる前にシグナルハンドラを登録しておかないと
終了シグナルを受けて CGI プロセスが終了してしまう罠。

CGI が無限ループに陥ってたりすると困るので
クライアントへのデータ転送が終ると
httpd は CGI プロセスを終了させようとします。
(少なくとも UNIX の apache は SIGTERM を送ってきます)

質問者の「うまくいかない」が
「その後の動作を継続できない」ならそういうことかと。

# lynx で書き込もうとしたら蹴られた (ぉ


4:[回答] TOM neko [2002/10/02 16:20 ]

>>3
うちのUNIX(Mac OS X)のApache/1.3.26 では下記が成功しましたが。何が違うんでしょうね?

print "Content-type: text/plain\n\n";
print "test";
close(STDOUT);
sleep 10;
open FILE, ">test.txt";
print FILE "HOGE\n";
close FILE;


5:[回答] TOM neko [2002/10/02 17:26 ]

>>4
違いが分かりました。suexecが有効だとプロセスが止まりませんが、suexecが無ければプロセスが止まります。OS XのデフォルトのApacheだと止まりますね。


6:[完了] 29歳からのPerl [2002/10/02 23:08 ]

みなさん、ありがとうございます。
取り急ぎテストしたところ、うまくいってます。
説明の中で環境を書かなければと思いながら、忘れてました。

完了としますが、これを見られた方がいたら、もう少し質問させてください。
特に二番目はWEBに関係ないので申し訳ないです。

1)今回の手法なのですが、需要がありそうな気がするのですが見た事がありません。
稼動サーバー(お客さんの)で取り入れたいのですが、その前にもう少し情報が欲しいのです。
公開されていて、よく使われてそうなCGIはないでしょうか?

2)このも長らくの疑問なのですが、Unixに触れだした頃に、
$ cat install.log | head
とすると、install.logが何万行あっても10行しか処理されない。
という説明を不思議に思ってました。
これは、誰かからシグナルでも来て、
誰かが、止めるのでしょうか?
シェルの特定が必要な場合は、shでも(もちろん他でも)。

よろしくお願いします。


7:[完了] Malic [2002/10/03 11:22 ]

2番のほうは・・・

head が頭10行を表示する命令だから。ちなみに、オプション付ければ行数変えられます。

head -100 なら100行になります

cat ファイル名 でファイルの中身を表示し、 head 命令で中身のうちの頭10行を表示してます。


8:[完了] Mr.X [2002/10/03 23:22 ]

> これは、誰かからシグナルでも来て、誰かが、止めるのでしょうか?
/usr/include/sys/signal.h にこうあります。
#define SIGPIPE 13 /* write on a pipe with no one to read it */
つまりパイプに書き込んだ時にそれを読み出すプロセスがいなければ
書き込んだプロセスが SIGPIPE を受け取るわけです。
あと NULL アドレスにアクセスした時に Segmentation Fault で死ぬのも
シグナルです (SIGSEGV)。
この辺はカーネルが直接発行して、シェルは介在してないと思います。

# しかし、suexec 環境だと SIGTERM が来ないんだ……
# suexec されてると httpd の uid と CGI の uid が違うんだから
# 考えてみれば、当然か。他人のプロセスは止められないからなぁ。
# そういう環境で無限ループっちゃったりデッドロックっちゃったりする CGI を
# ユーザが動かしちゃったら、やっぱサーバ管理者が面倒見るしかないのかしらん。


9:[完了] 29歳からのPerl [2002/10/08 22:17 ]

ありがとうございます。
これで、長年の疑問の一つが解けそうです。
時間に余裕があった時にでも、テストしてみたいと思います。

回答(必須): 状態:

お名前(必須):

e-mail:

URL:




[戻る]

ChaichanPAPA's World