私はシェルを書こうとしています。フォアグラウンド プロセスが実行されると、フォークされたプロセス パイプラインに独自のプロセス グループ ID が与えられます。次に、端末はこのプロセス グループ ID に引き渡され (tcsetpgrp を使用)、シェルはプロセス グループ ID が終了するのを待ってから、再び端末制御を渡します。これは完全に正常に機能します。
発生する問題は、バックグラウンド プロセスを実行しようとしたときに発生します。ここでも、パイプライン内のすべてのプロセスに 1 つのプロセス グループ ID を与えますが、今回はこのグループに端末制御を与えません。実行すると、特定のバックグラウンド コマンドの出力が (実行が終了する前に) 端末に出力され、端末は同時にユーザーにプロンプトを返します。端末に書き込もうとする子プロセスが SIGTTOU を取得して停止するはずですが、これは明らかに起こりません。フォークされたプロセスがすべて同じプロセス グループ ID を持ち、この ID がシェルのものとは異なることを確認しました。
(ctrl-c を使用して) シェルを終了し、それを実行した標準の bash シェルに戻ると、シェルの終了時にバックグラウンド プロセスを取得しなかったため、バックグラウンド プロセスは引き続き実行されます (これは例外です)。奇妙なのは、このプロセスがフォアグラウンド プロセスではないにもかかわらず、bash シェルに出力を書き続けていることです。これにより、このバックグラウンド プロセスが POSIX のバグが原因で SIGTTOU を取得していない (可能性は低い)、SIGTTOU を処理している (停止のデフォルト アクションが無視される)、またはバックグラウンド プロセスが SIGTTOU を無視していると結論付けることができます。
フォークされたプロセスを実行する前に、SIGTTOU を受信したときに停止することを確認する方法はありますか (exec バイナリが何も変更しないと仮定して)。