2

私は、fork(2)とexecl(3)を使用してポート転送の目的でsshを実行するCプログラムを作成しました。sshはバックグラウンドで-fオプションで実行されます。

Cプログラムが終了したら、それが生成したsshインスタンスにSIGTERMを送信するようにします。

私が試してみました

// creating the ssh process
ssh_pid = fork();
if (ssh_pid == 0)
    execl("/usr/bin/ssh", "/usr/bin/ssh", "-f", other options, NULL)

// ...

printf("Killing %d\n", ssh_pid); // <--- output the PID
kill(ssh_pid, 15);
sleep(1); // give it a chance to exit properly
if (kill(ssh_pid, 0) == 0)
    kill(ssh_pid, 9); // the "shotgun" approach

ただし、これは機能しません(SIGKILLを使用しても)。

プログラムが終了する前にpsを実行した場合

ps aux | grep ssh | grep -v sshd | grep -v grep

私はこのようなものを見ます:

user      27825  0.2  0.0      0     0 pts/0    Z+   18:23   0:00 [ssh] <defunct>
user      27834  0.0  0.0  41452  1176 ?        Ss   18:23   0:00 /usr/bin/ssh -f [other options]

プログラムが強制終了しているPIDを出力すると、次のように表示されます。

Killing 27825

続いてpsを繰り返すと、次のようになります。

user      27834  0.0  0.0  41452  1176 ?        Ss   18:23   0:00 /usr/bin/ssh -f [other options]

元のsshは、バックグラウンドプロセスになるために分岐したようです。

そこで、kill(2)の呼び出しを変更して、元のsshによって生成されたすべてのプロセスを強制終了しようとしました。

kill(-ssh_pid, 15);

しかし、これは効果がないようです。元のsshが背景のsshの親ではなくなったためだと思います。

では、どうすればバックグラウンドのsshを安全に強制終了できますか?それも可能ですか?

4

1 に答える 1

1

私が見つけた解決策は、-fオプションをまったく使用せず、sshを自分でバックグラウンドにすることです。

ssh_pid = fork();
if (ssh_pid == 0)
{
    freopen("/dev/null", "r", stdin);
    freopen("/dev/null", "w", stdout);
    freopen("/dev/null", "w", stderr);
    execl("/usr/bin/ssh", "/usr/bin/ssh", other options, NULL);
}

sshが-fオプションを取得すると子が作成され、親に送信されたシグナルは子に渡されないためです。

于 2013-02-15T10:47:27.360 に答える