コンソールでの環境と通常のターミナルの環境
でPOPENやSIGNALについての影響に
何か違いがあるのか ご存知の方教えて下さい
宜しくお願いします。
--
>コンソールより立ち上げ、コンソールをクローズ
>したときのみ
>SIGHUPシグナルが発生し
>通常のターミナルから立ち上げるときは
>発生しません。
"Unix" の種類 (OS 名) や,版数,そして program/process たちの動作
timing についての情報が不足していますが,例えば,いわゆる SysV 系の
仕様の中に,「端末の制御 process (ある端末を open している process
がいなかった時に open() をかけた process)が消滅する時(その process
を leader とする "session"/"pgrp" に対して)SIGHUP を送る」という項目
があり,この条件に該当している可能性が(もし,その OS が SysV 系統なら)
あります.
その他,端末操作に関連して kernel が送ってくる signal については,
signal 関連のマニュアルか,端末関連のマニュアルに出ている可能性が
高いと思います.
なお,複数 processes の間の動作 timing については strace, truss,
ktrace など(その OS に標準添付されている/移植されている trace tool)
を使って調べる事ができますし,process が open しているファイル(端末等
の特殊ファイル含む)は,lsof という free software を使って調べる事が
可能です.
#なお,popen(3S) は普通「システムコール」ではなく厳密にはそう呼ばない
#はずです.(複数の system callsを使って実装される library 関数のはず)
--
橋本 剛 (HASHIMOTO, Tsuyoshi)
OS SunOS 5.6(solaris2.6)
test 環境 signal 発生ケース
SUN
サーバ COM ------ COM PC
pc上でCOMをオープンし 該当プログラムを バックグラウンドで起動
COMオープンしたターミナルを立ち上げたままにしておけば SIGNALは発生しな
い
*
但し、COMオープンしたターミナル(windows上teraterm)をクローズすると
SIGNALが発生する
SUN
サーバ
SUNサーバ上にネットワークログイン 仮想ターミナル上で 該当プログラムを
起動
立上げに使用した際のターミナルはクローズしてもSIGNALは発生しない
該当プログラムは ソケットを用いたサーバクライアント型の処理です
プログラム概要
メイン
sigset (SIGHUP, ハンドラ関数); (ちなみにハンドラ内ではプログラムをexitす
るような仕様になっています)
socket
bind
listen
accept <----------- connect (クライアント)
sigignore(SIGCHLD);
fork
(子)
receive
ディスク容量チェック処理
popen("df -k","r"); ------->このライブラリ関数がコール
された
時点でなぜかSIGHUPが発生す
るらしい
pclose
このデーモンは通常手動でネットワーク経由で上げていたので事象が発生していな
かったのですが
たまたまCOM経由で上げてCOMのターミナルをクローズした場合に サーバプロセス内
の
子プロセス内の popen 処理で SIGHUPがあがってしまっているようです。
端末の制御 process
(ある端末を open している process
がいなかった時に open() をかけた process)
が消滅する時
(その process を leader とする "session"/"pgrp" に対して)
SIGHUP を送る
上の表現はたいへんわかりずらいのですが
この場合 popen 内で コマンド実行用のsh が起動され 標準入出力が使用されま
すが
そのshが終了した時点でSIGHUPを上げているようなイメージでしょうか?
また 上記ハンドラ内で なぜかsigsetを使用しているのですが
sigactionなる関数に置き換えてテストもしてみたいと思います。
何かございましたら また よろしくお願いいたします。
"HASHIMOTO, Tsuyoshi" <t...@spp.hpc.fujitsu.co.jp> wrote in message
news:snmitbn...@indra.spp.hpc.fujitsu.co.jp...
In article <XkeP7.440$ob6....@news1.dion.ne.jp> "ma" <m...@www.com>
writes:
>Newsgroups: fj.unix
複数 Newsgroups に記事をポストする必要がある場合上のように「1つだけ
newsgroup を指定した記事を複数回ポストする(この方法はマルチポストと
呼ばれます)」のではなく,「複数の newsgroups を指定した記事を,1回
だけポストする(この方法はクロスポストと呼ばれます)」事を原則にして
下さい.クロスポストは,例えば次のように Newsgroups: 行に複数 groups
を 「,」で区切って書く事で実現できます.
Newsgroups: fj.unix,fj.questions.unix,fj.comp.lang.c
これは,NetNews の使い方についての一種のエチケットと見なされています.
理由としては,次のような事が挙げられます.
(1) 「同一の記事が複数 groups に現れている」事が,記事を読む側にきちん
と情報として伝わる.(これが,本質的です).
- このため(よく出来た News reader (program) を使っている場合)読む
人の都合に合わせて「別の newsgroup で一度読んだ記事は再表示しない」
などの指定ができる.(よって,読む人にとって,時間の節約になります).
- 複数の Newsgroups で別々に議論が進む事による「無駄」が避けられる.
(Followup 記事を書く人により,他の newsgroup での followup 記事が
ある事がそもそも分からないと,他の記事を参考する事ができない他,
(既に別の人が書いているので書く必要がない)同じ内容を書いてしまう
かも知れない).
(2) (主に News server にとって)Network 帯域や disk space を節約できる.
- NetNews の記事は,多くの場合,世界中のサーバに転送されていきます.
「チリも積もれば ...」で(多くの人が)上のエチケットを守った場合と
守らない場合では,(記事の1つ1つは大した大きさではなくても),
最終的には,差が出ます.
なお,(マルチポストはもちろんの事)クロスポストも濫用はつつしむ必要が
あります.また,クロスポストを使う場合は,できるだけ「Followup 記事の
投稿先(希望)Newsgroup」を(できれば1つ)指定しておく事が望ましいと
思います.なお,この時,記事のヘッダに Followup-To: という行を含めて,
そこに Followup 記事の投稿希望先 group 名を書いておくと,よく出来た
news reader を使っている場合,投稿先 group が,その group に自動設定
されるので, Followup 記事を書く側の人にとって,便利な場合が多いかと
思います.(例えば,次のような感じにヘッダ行を書くという話です.なお,
本当のヘッダ行の先頭には tab や space は(もちろん)ありません).
Newsgroups: fj.unix,fj.questions.unix,fj.comp.lang.c
Followup-To: fj.unix
さて,本題の続きも(少しだけですが ^^;)書きます.
>OS SunOS 5.6(solaris2.6)
>test 環境 signal 発生ケース
> SUN
> サーバ COM ------ COM PC
> pc上でCOMをオープンし 該当プログラムを バックグラウンドで起動
...
> 但し、COMオープンしたターミナル(windows上teraterm)をクローズすると
>SIGNALが発生する
これは,man termio すると出てくる,下記の説明に該当します.
Ioctl Requests termio(7I)
...
Modem Disconnect
When a modem disconnect is detected, a SIGHUP signal is sent
to the terminal's controlling process. Unless other arrange-
ments have been made, these signals cause the process to
terminate. If SIGHUP is ignored or caught, any subsequent
read returns with an end-of-file indication until the termi-
nal is closed.
"Modem" という言葉が使われていますが,これは単に「COM port の先」と
いう意味にとって構いません.
NEWS関連のご忠告ありがとうございます。
下記 termio ですが
> If SIGHUP is ignored or caught, any subsequent
> read returns with an end-of-file indication until the termi-
> nal is closed.
この部分が私の能力ではよくわかりません。
噛み砕くとどういうことを言っているのでしょうか?
確かにコンソールのクローズのSIGNALに関係ありそうですが
該当プロセスはバッググラウンドで動作していています。
バッググラウンドでもコンソールのSIGNALを受けてしまうのでしょうか?
仮に そのSIGNALだとしても デーモンが死ぬまでに
タイムラグがあり、popen ライブラリが呼ばれるまでは
デーモンは生きているように思われます。
また 端末の属性を、コンソールではデフォルトが sun になっており
stty -a としましたところ hupcl になっておりましたので
-hupcl にしてから デーモンの立上げを行ってみましたが
状況はあまりかわりませんでした。
(仮想ターミナルでは vt100 で -hupcl がデフォルトでした)
何かヒントになることがございましたら
よろしくお願い致します。
"HASHIMOTO, Tsuyoshi" <t...@spp.hpc.fujitsu.co.jp> wrote in message
news:snmg06p...@indra.spp.hpc.fujitsu.co.jp...
> 下記 termio ですが
> > If SIGHUP is ignored or caught, any subsequent
> > read returns with an end-of-file indication until the termi-
> > nal is closed.
>
> この部分が私の能力ではよくわかりません。
> 噛み砕くとどういうことを言っているのでしょうか?
% program &
上のようにバックグランドで起動した programは一般にデーモンでは
ありません。単にバックグランドで動いているだけです。
ですから制御端末が落ちれば所属するプロセスグループすべてに
SIGHUPが発行されます。
バックグランドで動いている programはシェルがNOHUPジョブとして
設定してくれているので、SIGHUPを無視しますが、programの子プロセスの
popen()で呼び出した dfはSIGHUPを受け付けてしまいます。
この問題の簡単な解決方法は 制御端末を切り離すなどの処理をして
正しくデーモンとして programを作ることでしょう。
LinuxやFreeBSDだとdaemon()と言う自プロセスをデーモン化する
便利な関数があるのですが、Solarisにはないようですね。
簡単にdaemon()のクローンを書いてみました。
mainの最初のほうで 以下のdaemon() 関数を呼べば正しいデーモンに
なると思います。
数分で書いたコードなので間違いがあるかもしれません。
SunOS5.7で動作確認しました。
でかいの企画 佐々木茂彦
ssa...@dekaino.net
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
void daemon(void) {
int fd;
switch (fork()) {
case -1:
perror("fork()");
exit(1);
case 0:
break;
default:
exit(0);
}
if (setsid() == -1) {
perror("setsid()");
exit(1);
}
chdir("/");
fd = open("/dev/null", O_RDWR);
if (fd != -1) {
dup2(fd, 0);
dup2(fd, 1);
dup2(fd, 2);
}
}
デーモンについてもう少し詳しく勉強してみます。
わかりやすいご説明ありがとうございました。
また何かございましたら宜しくお願い致します。
"Shigehiko SASAKI" <ssa...@dekaino.net> wrote in message
news:rmk7w0z...@emma.dekaino.net...
"ma" <m...@www.com> wrote
in message news:WZCP7.493$ob6....@news1.dion.ne.jp...
>
> また 端末の属性を、コンソールではデフォルトが sun になっており
> stty -a としましたところ hupcl になっておりましたので
> -hupcl にしてから デーモンの立上げを行ってみましたが
> 状況はあまりかわりませんでした。
> (仮想ターミナルでは vt100 で -hupcl がデフォルトでした)
該当箇所を
poepn("stty -hupcl;df -k","r")
... とすればどうですか?
あるいは foo を動かすときに
$ (stty -hupcl;foo )&
とするとか。
$ nohup foo &
としてみるという手も在ります。
foo がバックグラウンドで動作するなら
特に問題にはならないと思います。
下記 ご説明でいままでの現象がきれいに説明できると
思うのですが、通常のネットワーク経由でログインした
ターミナルから上げた場合は 該当プログラムが
デーモンとして 作られていなくても
落ちないのはなぜでしょうか?
popen の子プロセスまで -nohup の環境が引き継がれるということでしょうか?
よろしくお願い致します。
"Shigehiko SASAKI" <ssa...@dekaino.net> wrote in message
news:rmk7w0z...@emma.dekaino.net...
"Iwao Watanabe" <iw...@DSL.gr.jp> wrote in message
news:9un1lc$kpp$1...@sv.dsl.gr.jp...
> 端末ドライバーのHUPシグナルの設定の差異による現象のようですね。
>
> "ma" <m...@www.com> wrote
> in message news:WZCP7.493$ob6....@news1.dion.ne.jp...
>
> >
> > また 端末の属性を、コンソールではデフォルトが sun になっており
> > stty -a としましたところ hupcl になっておりましたので
> > -hupcl にしてから デーモンの立上げを行ってみましたが
> > 状況はあまりかわりませんでした。
> > (仮想ターミナルでは vt100 で -hupcl がデフォルトでした)
>
> 該当箇所を
>
> poepn("stty -hupcl;df -k","r")
>
> ... とすればどうですか?
特に動作上は変わり映えしないようでした。
こちらでももう少し勉強してみます。
なにかございましたら 宜しくお願い致します。
In article <_OEP7.497$ob6....@news1.dion.ne.jp> "ma" <m...@www.com>
writes:
>思うのですが、通常のネットワーク経由でログインした
>ターミナルから上げた場合は 該当プログラムが
「通常のネットワーク」は COM port と違って,Modem と見なされないために
<snmg06p...@indra.spp.hpc.fujitsu.co.jp> で引用したマニュアルの記述
は当てはまらず,SIGHUP が送られない ... という事ではないでしょうか?
#実際に何がおきているかは,例えば truss というコマンドを使って,
# truss -aelf -vall command arg1 arg2 ... & などとしてみれば,分かる
#かと思います.truss の各 option の意味はマニュアルを見て下さい.なお,
#truss で既に起動済みの (backgrond) process をトレースする事も -p を
#指定すれば出来ます.truss は,こうした問題の調査に非常に役立ちます.
ちなみに,現象発生は「SIGHUP が送られるか送られないか」により決まって
いますが,「SIGHUP が送られた後で,その「端末ファイル」をアクセスする
時に何が起こるか?」というのは,また別の話です.以下の部分はその点に
ついてです.
>> > > If SIGHUP is ignored or caught, any subsequent
>> > > read returns with an end-of-file indication until the termi-
>> > > nal is closed.
>> > この部分が私の能力ではよくわかりません。
>> > 噛み砕くとどういうことを言っているのでしょうか?
「この部分」が(文字通り)上の3行を指すなら,ここに書いてある内容は,
(SIGHUP が無視 (ignored) または handler が設定されている (caught) 場合
には process が消滅しないので,「端末ファイル」に対するアクセス,特に
read アクセスを続ける場合がありえますから,その場合)「read に対しては
必ず EOF が返る」そして「その状態は,その「端末ファイル」を close する
まで変わらない (until ... closed) 」という事を言っています.ところで,
>> LinuxやFreeBSDだとdaemon()と言う自プロセスをデーモン化する
>> 便利な関数があるのですが、Solarisにはないようですね。
この通りですが,最近 SUN は Linux の API を(free software 移植性を
上げるため)Solaris に採り入れようとしているようなので,ひょっとして,
Solaris 9 (あるいは,その後の版で)追加される可能性はあるかも???
マニュアルに書かれていないので,いつまで残る機能かは分かりませんが,
/usr/bin/setpgrp というコマンドは,「制御端末を切り離す」処理をして,
指定されたコマンドを(引数もつけて)実行するようです.i.e. 使い方は,
/usr/bin/setpgrp command arg1 arg2 ... &
という形なのでしょう(マニュアルもない非公開機能で,「無保証」ですし,
truss で見ると,setsid() ではなく(「廃止予定」の)setpgrp() を使う点
からして,「見るからに古そう」なコマンドですから,お勧めはできません.^^;
似たようなコマンドを自分で作って使う事は比較的容易なので,その方が堅実
と思います).
# 2.5 ないしそれ以前の古い版の Solaris の rc script のどれかで,上記
#コマンドが使われていたような気がします.2.6 では rc script は使って
#いないと思いますが,setpgrp コマンドは,まだ残っているようです.
プログラム自体をデーモン化するのが
一番きれいなのでしょうが
時間がありませんものですから
下記コマンドで 試してみましたところ
シグナルを受け取らなくなりました。
とりあえずは 表面上
思うように動作するようになっているように見られます。
質問ですが
下記コマンドを使用する上で 注意点など ご存知でしょうか?
よろしくお願い致します。
>下記コマンドを使用する上で 注意点など ご存知でしょうか?
「既に <snmelm8...@indra.spp.hpc.fujitsu.co.jp> で書いた事が全て」
です.(マニュアルすらなく,非公開/無保証で,将来の OS 改版に際しては
なくなるかも知れません.中で何をしているかは,truss の結果を見て比較的
容易に推測がつくはずと思います.もし推測ができないようなら「無保証かつ
ソースを見ることのできないコマンド」を「自分自身でリスクを負って使う」
という立場に身をおくのは気が重いと思いますから,より正統的な「daemon
を daemon らしくする」ないし,せめて同様のコマンドを自作しての解決策に
移行する事を考えるのが「堅実」な考え方と思います).
/usr/bin/setpgrp 同様のコマンドは setsid() + fork() + execvp() を順に
呼び出せば実装可能のはずです.なお,daemon になる処理の sample コード
として,Stevens の「UNIX ネットワークプログラミング」という本の sample
コード (stevens.netprog.tar.Z という名前で,あちこちのサイトにある tar
archive の中に daemon.c という名で入っています) も (古い System V の
system call setpgrp() は setsid() で置き換える方が良い点を除き) 使える
と思いますし,Rago の「詳解 UNIX ネットワークプログラミング」という本
の sample (こちらは rago.netprog.tar.Z) の ex2.4.16.c は,Solaris 2.x,
7, 8 では,そのまま使えるはずです.これらは,stevens.advprog.tar.Z と
共に,いろいろな system call や library 関数の使用例を調べるのに役立つ
と思いますから,今回使うかどうかは別として,get しておくとよいかも?
ところで,また NetNews の話ですが,「クロスポスト」については,かなり
「特別な状況で慎重に使うもの」と考えられていますので,単に「自分の質問
に確実に気がついて欲しい」という理由では使わないで下さい.議論が続いて
いる途中で話の内容が変わってきて group を移動する途中に使うなど,複数
の group に現れる事の「客観的な利益」が後述の「group を絞る利益」より
大きい」と信じる「客観的な理由」がある場合に限って使うべきと思います.
#例えば,http://www.tcn.ne.jp/~kisimoto/aruki/qa-a03.txt なども参照.
NetNews の記事は,後から「公共の記録」として参照されるものでもあるので,
その場合できるだけ少ない(できれば1つだけの十分適切な) group にだけ
現れる方が記録として価値が高まります.この価値を減らす代償は「投稿の際
に記事を見る/議論に参加する人の多くにとっての利益」以外では不十分です.
今回の話題だと,fj.questions.unix と fj.unix で最初迷うのは一応分かり
ますが実は一方で十分ですし,fj.comp.lang.c は「OS 依存性が強い」と指摘
が出る話題と分かった時点で,外してよい/外すべきだったと思います.
#実は,この記事自体のクロスポスト先も,ずいぶん迷って決めました,