どうやってinetdサービスに制御を移す、以下は私の理解です
- inetdは、
/etc/inetd.conf
- クライアントがinetdがリッスンしているポートの1つにリクエストを送信した場合、inetdはそのリクエストの制御をサービスに渡し、子プロセスとして起動します。
/etc/inetd.conf
- マルチプレクサとして機能します。
私の疑問は以下の通りです
- リクエストはどのようにして子プロセス (それぞれのサービス デーモン) に引き渡されるのでしょうか?
- すでに inetd によってポートに接続が行われているため、inetd がそのポートを解放するまで、子プロセスはそのポートを再度使用できません。inetd がそのポートを解放すると、既存のクライアント接続が切断されます (私の理解が間違っている場合は、ご指摘ください)。
答え1
inetd
ポートをリッスンし、それを処理するサービスの stdin、stdout、stderr に接続します。
どうやってそれをするのか
- 接続が完了すると
accept
、そのノードの 1 つにソケットが作成されますfd
。 - 次に、、、 を反復
dup
します。fd
0
1
2
- その後、
fork
何らかのアクションを実行してファイル記述子を閉じるまで、すべてのファイル記述子は開いたままになります (つまり、0、1、および 2 は開いたままになります)。 - 子プロセスは を呼び出しますが
exec
、fd
はまだ開いたままです。 - サービスは、リモート クライアントが stdin (0)、stdout (1)、stderr (2) に接続された状態で実行されています。
- サービスは、クライアントがこれらのファイル記述子上にあることを認識するだけでよく、
listen
独自の処理を実行する必要はありません。
inetd
(調べてみたのですが、サービス プログラムに によって呼び出されたことを伝える方法がわかりませんinetd
。コマンド ライン引数があるはずです。)
答え2
次のようなアクションを検討してください。
[親]
sfd = socket(), listen(), connect(), fork();
子プロセスに継承されるべきではない、
close()
または以前にFD_CLOEXEC;
afterに設定された他の記述子についてはfork
、親はこのsfdを閉じることができます。
[子供]
execve();
接続されたソケット記述子のコピーが継承され、クライアントI/Oに使用できます。
答え3
それは、Que-Linux-ソケットプログラミングセクションの下The Design Parameters of inetd Servers