2011-02-02 24 views
9

私はLinuxデーモンに取り組んでおり、stdin/stdoutに関するいくつかの問題があります。通常、デーモンの性質上、標準入力や標準出力はありません。しかし、デーモンが正常に動作するために必要なさまざまなパラメーターを指定するためにデーモンが初めて実行されたときに呼び出されるデーモンには関数があります。この関数が呼び出されると、ターミナルは非常に遅くなって別のシェルを起動し、応答の速いプロンプトを得るためにデーモンを一番上に置かなければなりません。今私はこれがstdin/stdoutを閉じるフォークプロセスと関係があると考えていますが、私はこれを回避する方法についてはあまりよく分かりません。もしあなたが、状況に少しでも光を当てれば、それは最も高く評価されるでしょう。ありがとう。LinuxデーモンとSTDIN/STDOUT

編集:

int main(argc, char *argv[]) { 

/* setup signal handling */ 

/* check command line arguments */ 

pid_t pid, sid; 

pid = fork(); 

if (pid < 0) { 
exit(EXIT_FAILURE); 
} 

if(pid > 0){ 
exit(EXIT_SUCCESS); 
} 

sid = setsid(); 

if(sid < 0) { 
exit(EXIT_FAILURE); 
} 

umask(027); 

/* set syslogging */ 

/* do some logic to determine wether we are running the daemon for the first time and if we are call the one time function which uses fgets() to recieve some input */ 

while(1) { 

/* do required work */ 

} 

/* do some clean up procedures and exit */ 

return 0; 
} 

君たちは設定ファイルを使用して言及します。これは、入力を介して受け取ったパラメータを格納するために行うものです。しかし、私はまだ最初にstdinを介してユーザーからこれらを取得する必要があります。最初に実行しているかどうかを判断するロジックは、configファイルの存在に基づいています。

+1

いくつかのコードを見ずにはわかりません。しかし、それはあなたが間違っているように聞こえる。あなたはデーモンがstdin/stdoutを取ることができるようにしたいと言っていますか?ソケットや何かの上にそれらを配管する必要があります。 – Falmarri

+0

はいファルマーリですが、その特定の関数が呼び出されたときに限り、私は言ったように一度のことです。私のコードでは、私はfork()の後にこの関数を呼び出します。新しいプロセス。 – Error1f1f

+2

なぜ設定ファイルを使用しないのですか? –

答えて

3

皆さんは設定ファイルを使用して言及しています。これは、入力を介して受け取ったパラメータを格納するために行うものです。しかし、私はまだ最初にstdinを介してユーザーからこれらを取得する必要があります。最初に実行しているかどうかを判断するロジックは、configファイルの存在に基づいています。

代わりの STDINを読んで、ユーザーは設定が自分自身をファイル書き込み持ちます。その存在がの前に確認し、フォークしていなければエラーで終了してください。デーモンにサンプルの設定ファイルを含め、デーモンのマンページにそのフォーマットを書いてください。あなたにマンページありますか?あなたの設定ファイルです、はい?

また、デーモン化ロジックには重要なステップがありません。フォーク後、ただしsetsidを呼び出す前に、fds 0,1、および2を閉じてから/dev/nullに再度開く必要があります(fclosefopenとしてください)。それはあなたの遅いターミナルの問題を解決するはずです。

+0

あなたは設定ファイルを書くためにユーザーに依存していますか?また、フォークプロセスの前にI/Oを実行しようとしましたが、私はまだ不機嫌な端末で同じ問題を抱えています。 – Error1f1f

+0

はい、絶対に、ユーザーに設定ファイルを書き込むよう依頼してください。それがこれがUnixで行われる方法です。遅い端末を再起動し、編集を参照してください。 – zwol

+0

"これを' fclose'と 'fopen'で行いません。"なぜそう、そしてどうやってこれをしようとするべきですか? –

1

デザインが間違っています。デーモンプロセスはstdin経由で入力を受け取ったり、出力をstdout/stderrに渡したりしてはいけません。デーモン化フェーズの一環として、これらの記述子を閉じます。デーモンは、コマンド行、構成ファイル、またはその両方から構成パラメーターを取る必要があります。ランタイム入力が必要な場合は、ファイルを読み込んでソケットなどを開く必要がありますが、デーモンのポイントは、ユーザーがコンソールにいなくても実行できることです。

+3

これはinetdによって実行されるデーモンでない限り:-) – mateusza

14

通常、デーモンの標準入力は/dev/nullに接続する必要があります。標準入力から何かが読み込まれるとすぐにEOFが得られます。通常、標準出力はファイル(ログファイルまたは/dev/null)に接続する必要があります。後者はすべての書き込みが成功することを意味しますが、情報は保存されません。同様に、標準エラーは/dev/nullまたはログファイルに接続する必要があります。

デーモンを含むすべてのプログラムは、stdin、stdout、およびstderrが適切にオープンされたファイルストリームであると仮定することができます。

通常、デーモンは、入力の出入りを制御することが適切です。入力が/dev/null以外から来ることはめったにありません。コードが標準出力または標準エラーなしに生き残るように書かれている場合(例えば、標準ログチャネルを開き、おそらくsyslog(3)を使用する場合)、stdoutおよびstderrを閉じることが適切な場合があります。それ以外の場合は、メッセージをログファイルに記録しながら、それらを/dev/nullにリダイレクトすることはおそらく適切です。また、stdoutとstderrの両方をログファイルにリダイレクトすることもできます。

応答時間が遅くなる可能性があるのは、プログラムが読み取りループ内のEOFに注意を払っていないためです。/dev/nullへのユーザー入力を促し、/ dev/nullからの応答を読み込み、 'y'または 'n'を戻さないようにするには、システムをひどく噛んでしまいます。もちろん、コードにはEOFを処理せず、無効な応答が得られた回数を数え、妥当な試行回数(16,32,64)後にばかげて停止することには欠陥があります。意味のある入力を期待し、それを得ることができなければ、プログラムは安全かつ安全に店を閉じなければなりません。

1

設定ファイルを使用します。 STDINまたはSTDOUTをデーモンと一緒に使用しないでください。デーモンはの背景で実行され、ユーザーの操作はありません。

1

デーモンを起動するためにstdin/keyboard入力を使用することを主張している場合(例:あなたがファイルに保存したくない魔法のパスフレーズを得るために)の前にすべてfork()を処理してください。

+0

まあ私はそれを考えて、それを確認しようとしましたが、やはり遅い端末で同じ問題が発生します。それは私にとってかなり不愉快です。 – Error1f1f

+0

コードスニペットはそうでないことを示唆しているようです。問題を解決したい場合は、実際のコードを共有してください。 – mvds

関連する問題