double() - なぜですか?

double() - なぜですか?

ソースコードで次の関数を見つけました。猫の目(ミニマリストウィンドウマネージャ):

void spawn(const Arg arg) {
    if(fork() == 0) {
        if(fork() == 0) {
            if(dis)
                close(ConnectionNumber(dis));

            setsid();
            execvp((char*)arg.com[0],(char**)arg.com);
        }
        exit(0);
    }
}

githubで見る)

なぜ単にそうでないのか理解できません。

void spawn(const Arg arg) {
    if(fork() == 0) {
        if(dis)
            close(ConnectionNumber(dis));

        setsid();
        execvp((char*)arg.com[0],(char**)arg.com);
    }
}

?ここでdoubleを使用すると、どのような利点がありますかfork()

答え1

次の節は、StevensとRagoの記事を引用したものです。UNIX環境の高度なプログラミング、デーモンを作成するための6つのコーディング規則のうち2つを説明します。特に、参照したい場合に備えて、図13.1にリストされている単一の関数daemonizeでこれを実装しました。

  1. フォークを呼び出し、親が終了するようにします。ここにはいくつかあります。まず、デーモンが単純なシェルコマンドで始まる場合、親プロセスを終了させると、シェルはコマンドが完了したと考えます。第二に、子プロセスは親プロセスのプロセスグループIDを継承しますが、新しいプロセスIDを取得するので、子プロセスがプロセスグループリーダーではないことを確認できます。これは後のsetid呼び出しの前提条件です。
  2. 新しいセッションを作成するには、setidを呼び出します。セクション9.5にリストされている3つのステップが発生します。プロセスは(a)新しいセッションのリーダーになり、(b)新しいプロセスグループのリーダーになり、(c)制御端末から切断されます。
    • System V ベースのシステムでは、一部のユーザーはこの時点で fork を呼び出して親プロセスを終了し、子プロセスでデーモンを実行し続けることをお勧めします。これにより、デーモンはセッションリーダーではなく、System Vの規則(9.6節)に従って制御端末を取得できなくなります。または、制御端末のインポートを防ぐには、端末装置を開くときにO_NOCTTYを指定する必要があります。

変更したコードでは、親コードはexit()呼び出し後に実行され続けます。spawn()正確な動作は、spawn()呼び出し後の内容によって異なります。

関連情報