C言語でCGIを製作していています。(環境:Linux + APACHE + gcc)

malloc()などで動的に確保したメモリ内容を標準出力に表示している時に
出力先(閲覧者ですね)側から受信停止されたら、その後の処理はどうな
るのでしょうか?
その時の例外処理は、コンソールでのターミネイト処理と同じでいいので
しょうか。

試しにAPACHEのログを見てみますと、出力は最後まで行われていないよ
うです。本来そのCGIは120Kbyteの転送量が書き出されますが、受信停止
と思われる30kbyte程度で収まっています。

OS側でうまくやってくれれば、それにこしたことが無いのですが。

どうぞよろしくお願い致します。

このQ&Aに関連する最新のQ&A

A 回答 (1件)

 UN*X系のOS(Linuxもそう)で、webサーバがApacheであれば、ブラウザ側で中断されると、CGIで起こされたプロセスにはSIGTERMが送られます。

SIGTERMを受け取ったプロセスのデフォルトの処理は「強制終了」で、使っていたリソース(メモリとか、ファイルハンドルとか)は、OSによってシステムに回収され、後始末されます。

 もちろん、SIGTERMを受けるシグナルハンドラを定義して、自前で終了処理を行ってもかまいません。
    • good
    • 0
この回答へのお礼

CGIの場合もFree()しなくても、大抵はOS側でやってくれるのですね。

ありがとうございました。

お礼日時:2001/07/06 12:42

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aと関連する良く見られている質問

QCGIの中で出力するテキスト内容をhtml側で表示する方法。

htmlからCGIファイルを呼び出すと、そのCGIは動作はしているようですが、
print等でhtml形式で文字出力させている部分は、ブラウザ内に表示されません。
今やって失敗している方法です。どのようにするのが良いか教えて頂ければ幸いです。

1.CGIスクリプト(Perlで記述)を用意... test.cgi
-----------------------------------------------------
#!/usr/bin/perl
print "Content-type:text/html; charset=shift_jis\n\n";
print <<__EOD;
<html lang="ja">
<head>
<title>TITLE</title>
</head>
<div align=center>
<a>テスト1</a><br>
<a>テスト2</a><br>
</div><br>
</body></html>
__EOD

open(OUT,">a.tmp") || die "$!";
print OUT "aaaaa\n";
close(OUT);
-----------------------------------------------------


2.htmlを用意 ... test.html
-----------------------------------------------------
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<title>HTML TEST</title>
</head>
<body>
<script src="http://xxx/CGI/test.cgi"></script>
</body>
</html>
-----------------------------------------------------

上記のとき、動作として、

◆ブラウザからCGIのパス(http://svr1/CGI/test.cgi)に直接アクセスした場合、
「テスト1」「テスト2」の文字が表示され、a.tmpファイルも作成されている。

◆ブラウザからhtml(http://svr1/test.html)にアクセスした場合、ブラウザ画面は何も表示されない
(真っ白となる)が、a.tmpファイルは作成されている。

のようになってしまいます。

後者のようにして、htmlからCGIファイルを呼び出すと、そのCGIは動作はしているようですが、
print等でhtml形式で文字出力させている部分は、ブラウザ内に表示されません。

以上、よろしくお願い致します。

htmlからCGIファイルを呼び出すと、そのCGIは動作はしているようですが、
print等でhtml形式で文字出力させている部分は、ブラウザ内に表示されません。
今やって失敗している方法です。どのようにするのが良いか教えて頂ければ幸いです。

1.CGIスクリプト(Perlで記述)を用意... test.cgi
-----------------------------------------------------
#!/usr/bin/perl
print "Content-type:text/html; charset=shift_jis\n\n";
print <<__EOD;
<html lang="ja">
<head>
<title>TITLE</title>
</head>...続きを読む

Aベストアンサー

<script src="http://xxx/CGI/test.cgi"></script>としているなら
perlで出力するヘッダーは
print "Content-Type: application/x-javascript\n\n";
としないとならないでしょう。

perlではjavaScript構文を出力します。

例えばhtmlでは・・
<BODY>
<SCRIPT TYPE="Text/Javascript" LANGUAGE="Javascript">
<!--
document.write ("<SCRIPT TYPE=\"text/JavaScript\" SRC=\"test.cgi\"></SCRIPT>");
// -->
</SCRIPT>
</BODY>

として、perlでは

#!/usr/bin/perl
print "Content-Type: application/x-javascript\n\n";
print "document.write('<A HREF=\"other.html\">てすと</A>');";

てな感じです。

<script src="http://xxx/CGI/test.cgi"></script>としているなら
perlで出力するヘッダーは
print "Content-Type: application/x-javascript\n\n";
としないとならないでしょう。

perlではjavaScript構文を出力します。

例えばhtmlでは・・
<BODY>
<SCRIPT TYPE="Text/Javascript" LANGUAGE="Javascript">
<!--
document.write ("<SCRIPT TYPE=\"text/JavaScript\" SRC=\"test.cgi\"></SCRIPT>");
// -->
</SCRIPT>
</BODY>

として、perlでは

#!/usr/bin/perl
print "Content-Type: appli...続きを読む

Qapacheでcgiがうまく動かない。cgiが認識されていない?

すいません、多分基本的な所なのですが、
どうしても分からないので質問させてください。
■環境------------------------------
・windowsXP sp2
・apache1.3.33C:\Program Files\Apache Group\Apache
 現在の状態:html表示可能。httpd.confを変更
・perl5.6.1c:\perl
 現在の状態:PPMにてimagemagick,DBI,DBD-MySql(だっけ)をインストールしている
・php5.0.4c:\php
・mysql4.02C:\mysql
■httpd.confの変更箇所--------------------------------
337
Options Indexes FollowSymLinks MultiViews

Options Indexes FollowSymLinks ExecCGI MultiViews

538
#!c:/program files/perl/perl

#!C:/Perl/bin/perl

720以降に追加
AddType application/x-httpd-cgi .cgi
AddType application/x-httpd-cgi .pl

825以降に追加
AddHandler cgi-script .cgi
AddHandler cgi-script .pl
■printenv.plの内容--------------------------------
#!C:/Perl/bin/perl
##
## printenv -- demo CGI program which just prints its environment
##

print "Content-type: text/plain\n\n";
foreach $var (sort(keys(%ENV))) {
$val = $ENV{$var};
$val =~ s|\n|\\n|g;
$val =~ s|"|\\"|g;
print "${var}=\"${val}\"\n";
}
--------------------------------------------------
上記のような環境で、いまPERLの動作確認を行っています。

http://localhost/cgi-bin/printenv.pl
http://localhost/cgi-bin/printenv.pl

PLファイルを指定しても実行されず、ダウンロードされてしまいます。
cgiに拡張子を変えても同じでした。

エラーというわけでもない為、エラーログにも何もかかれません。
何が問題なのでしょうか?

すいません、多分基本的な所なのですが、
どうしても分からないので質問させてください。
■環境------------------------------
・windowsXP sp2
・apache1.3.33C:\Program Files\Apache Group\Apache
 現在の状態:html表示可能。httpd.confを変更
・perl5.6.1c:\perl
 現在の状態:PPMにてimagemagick,DBI,DBD-MySql(だっけ)をインストールしている
・php5.0.4c:\php
・mysql4.02C:\mysql
■httpd.confの変更箇所--------------------------------
337
Options Indexes FollowSymLinks MultiViews
...続きを読む

Aベストアンサー

1.
htdocsではなく、cgi-binでの実行のようなので
ScriptAlias のコメントアウトははずしました?

2.
http://127.0.0.1/cgi-bin/printenv.pl
ではどうでしょう
Windowsでしたら、たまにIISが関係してくるようですよ

QCGIで他のCGIの出力を取り込む方法について。

CGIで他のCGIを呼び出し、同じページの一部として出力したいと考えています。
例えば、親のCGIが簡単な機能のCGIをページの一部として出力し、
そのパラメーターを子のCGIに受け渡し呼び出すようなしかけです。
なんかうまい方法ありますか??
あまり急いでいませんが、宜しくお願いします。

Aベストアンサー

use Socket;

ソケット通信を行えば、
パラメータの受け渡し等含めてやりとりできます。
(postでの受け渡しも可能ですし)

ただ、少々実装が面倒かもしれません。

#LWP(lib-www-perl)なども使えるかと思います。
#詳細は参考文献にて。

参考URL:http://member.nifty.ne.jp/hippo2000/perltips/LWP.html

QCGIの処理中に次の処理が出来る?

perlで書いたCGIの処理時間が非常に長いのです。
処理は数百名に対してメールを配信するもので、テキストで書かれた数百のメールアドレス配列に対してループ文で一人ずつメールを配信しています。これが約4分くらいかかります。
質問は2つあって、
(1)まずこのメール配信の処理を早くする方法はないでしょうか?
 配信アドレスは自動的に追加されたり削除されたりするので固定のML
 を使う事ができませんので、個別にメールを送る方法を取っていま  す。
(2)メール配信をバックグランドで実行させて、メインのプログラムは
 復帰させる、という方法が出来るでしょうか?
 今は、メインCGIが画面の表示やメールの配信などほとんどを実行し
 ています。
 このような場合、メール配信中はそのメインCGIが実行権を握った
 状態になる為、他のユーザはこのメインCGIを実行出来ないと思って
 いるのですが、間違った認識でしょうか?
 もしそうだとすると、早くメインCGIの実行権を他のユーザに明け渡 さなければならないと思うので、メール配信を別CGIで実行させたほ うが良いのかな?と思った次第です。

 よろしくご教示下さい。

perlで書いたCGIの処理時間が非常に長いのです。
処理は数百名に対してメールを配信するもので、テキストで書かれた数百のメールアドレス配列に対してループ文で一人ずつメールを配信しています。これが約4分くらいかかります。
質問は2つあって、
(1)まずこのメール配信の処理を早くする方法はないでしょうか?
 配信アドレスは自動的に追加されたり削除されたりするので固定のML
 を使う事ができませんので、個別にメールを送る方法を取っていま  す。
(2)メール配信をバックグランドで実行させて、...続きを読む

Aベストアンサー

がると申します。
1番については「処理次第」としか言いようがないのですが。#1さんの補足質問のコードを見てる限りですと「普通はこんなもん」だと思うです。
ここから速度アップを考えると、smtp関連で結構突っ込んだコードになってくるので、「業務的に必須」とか「やる気が両手からあふれかえっている」とかでなければ、このままでよいように思うです。
ちなみに、$mailfile を読み込む際の
flock(OUT,8);
は不要です。
# flockの解除は「しない」癖をつけたほうが安全です。

んで。
私は「まとめて送信」には比較的懐疑的です。
一つには、ユーザ的に「メールヘッダのToが自分のアドレスである」ほうが好感度が高いのが一つ。
もう一つが、まとめて送るときはSMTP的に「RCPT TO」とうコマンドを列挙するのですが、これには数量限界がありまして。RFC的にもさほど多くない上に(ちょっと記憶に浅いのですが、たしか100~200程度)、実装上ではさらに低い上限(たしか10~20くらい)もありまして。そのあたりから考えるに、まとめての送信はちょっと微妙です。

2番についてですが。
forkなどで別プロセスをたたき起こすことによって「バックグラウンドでの実行」は可能です。ただ、厳密にはforkで作った子プロセスには2パターンの挙動がありまして。さらにHTTPdの挙動も微妙で。
まずforkの子プロセス周りですが。「子プロセスが実行中に親プロセスが終了。子プロセス君、君はどうする?」と質問すると、「んじゃぁ親プロセスのもう一つ上(大抵はプロセスID 0のプロセス)と親子関係結びなおしてそのまま実行」という独立心旺盛な場合と「親が死んだんだもの、僕も一緒に~」という情愛豊かに終了してしまう場合とがあります。
次にHTTPdですが「親プロセスしか監視しない」タイプと「そこから派生した全てのプロセスをチェック」するタイプがやはり存在します。
ですので、可能か不可能かは「環境次第」になってしまいます。
環境に依存しないためには、
・CGIで「メール送信依頼」をどこか(ファイルまたはDB)に設定する
・cronで定期的に送信依頼をチェック、依頼があれば遂行する
というほうがより安全です。

ちなみに「メール配信中はそのメインCGIが実行権を握った状態になる為、他のユーザはこのメインCGIを実行出来ない」ってのは明確に誤りです。
細かく書くと長くなるので省略しますが、基本的にプログラムは「あちこちから呼ばれてパラレルに動くことが可能」です。そのあたりはプロセスとかその辺を勉強すると色々わかると思います。

以上、なにか参考にでもなれば幸いです。

がると申します。
1番については「処理次第」としか言いようがないのですが。#1さんの補足質問のコードを見てる限りですと「普通はこんなもん」だと思うです。
ここから速度アップを考えると、smtp関連で結構突っ込んだコードになってくるので、「業務的に必須」とか「やる気が両手からあふれかえっている」とかでなければ、このままでよいように思うです。
ちなみに、$mailfile を読み込む際の
flock(OUT,8);
は不要です。
# flockの解除は「しない」癖をつけたほうが安全です。

んで。
私は「まとめ...続きを読む

QapacheのCGI設定

 pc9821にFreeBSD(98)をいれapache1.3を起動させています。cgiはlight.cgiというソフトをつかっています。なかなかcgiがうまくいきません。参考ページには
public_html / index.html (トップページ)
|
+-- bbs / light.cgi [755]
| admin.cgi [755]
・・・・(省略)
+-- lock [777] /
|
+-- past [777] / 0001.cgi [666]
とかかれていますが、実際に私のサーバーにはpublic_htmlというフォルダは存在していなくて
/usr/local/www/cgi-binにbbsというフォルダをつくり
あとは上のようにしています。またindex.htmlは/usr/local/www/dataのなかにいれて表示してWebサーバーとしてはたらいています。またapacheの/usr/local/etc/apacheのhttpd.confは
関係ありそうな行だけあげると
ServerRoot "/usr/local"
DocumentRoot "/usr/local/www/cgi-bin"
<Directory "/usr/local/www/cgi-bin/bbs">
Options Indexes FollowSymLinks MultiViews
<location "/cgi-bin/">
Options ExecCGI
AllowOverride AuthConfig Limit
Order allow ,deny
Allow from all
</Location>
<IfModule mod_mime.c>
TypesConfig /usr/local/etc/apache/mime.types
ADDHandler cgi-script .cgi
</IfModule>
ScriptAlias /cgi-bin/ "/usr/local/www/cgi-bin/"
<Directory "/usr/local/www/cgi-bin/bbs">
AllowOverride None
Options ExecCGI
Order allow,deny
Allow from all
</Directory>
AddHandler cgi-script .cgi
どこがおかしいのかおしえていただけないでしょうか?

 pc9821にFreeBSD(98)をいれapache1.3を起動させています。cgiはlight.cgiというソフトをつかっています。なかなかcgiがうまくいきません。参考ページには
public_html / index.html (トップページ)
|
+-- bbs / light.cgi [755]
| admin.cgi [755]
・・・・(省略)
+-- lock [777] /
|
+-- past [777] / 0001.cgi [666]
とかかれていますが、実際に私のサーバーにはpublic_htmlというフォルダは存在していなくて
/usr/local/www/cgi...続きを読む

Aベストアンサー

PC9821にApacheをインストールしたことはないので外しているかもしれませんが・・・

> とかかれていますが、実際に私のサーバーにはpublic_htmlというフォルダは存在していなくて
Apacheインストール直後では、
ディレクトリ htdocs が public_html に該当します。
CGIファイルは cgi-bin に置くことでデフォルトで動作します。

httpd.confにはデフォルトで ScriptAlias の記述がありますが、
この記述があると cgi-bin に置いたファイルしかCGIとして認識しなくなります。
ですので、ディレクティブごとコメントアウトしてみてください。


このカテゴリの人気Q&Aランキング

おすすめ情報