1

これは、コマンドを実行するための私のコードのライト バージョンです。

void close_all_nonestandard_fds()
{
    struct rlimit fds_limit;
    int max_fd = 1024;
    if (getrlimit(RLIMIT_NOFILE, &fds_limit) == 0) max_fd = fds_limit.rlim_cur;
    for(int i = 0; i <= max_fd; ++i) {
        if(i != STDERR_FILENO && i != STDOUT_FILENO && i != STDIN_FILENO) close(i);
    }
}

void exec_command(char* command, char*const* args)
{
    pid_t pid = fork();
    if(pid != 0)
    {
        if(pid == -1) throw_error("Failed to fork: %s", strerror(errno));
        // Parent
    }
    else
    {
        // Child
        close_all_nonestandard_fds();
        if(execv(command, args) == -1) throw_error("Failed to execv: %s", trerror(errno));
    }
}

このexec_commandメソッドは、サーバー側アプリケーションで、デーモン プロセスを含むさまざまな種類のプロセスを実行するために使用されます。しかし、ここで問題に気づきました:

サーバーが子デーモン プロセスを実行すると、それ (サーバー) が強制終了またはクラッシュすると、子はサーバーがリッスンしていたポートをリッスンし始めます。

では、コマンドを実行して、サーバーの終了 (クラッシュ、死) 後にサーバーのポートがビジー状態にならないようにするにはどうすればよいでしょうか?

4

1 に答える 1

1

すべてのサーバーソケットを保存して追跡し、fork()ing後にそれらをclose()子にします。

それらはlisten()ing ソケットとaccept()ed ソケットです。


アップデート:

また、渡されたソケットsetsockopt()にオプションを設定するために使用したい場合がありますSO_REUSEADDRbind()

SO_REUSEADDR

bind(2) 呼び出しで提供されたアドレスの検証に使用される規則が、ローカル アドレスの再利用を許可する必要があることを示します。AF_INET ソケットの場合、これは、アドレスにバインドされたアクティブなリスニング ソケットがある場合を除き、ソケットがバインドできることを意味します。リスニング ソケットが特定のポートで INADDR_ANY にバインドされている場合、どのローカル アドレスでもこのポートにバインドすることはできません。引数は整数ブール値フラグです。

于 2012-10-29T16:47:06.727 に答える