私はCプログラムでnmapを実行するためにexeclを使用しています。
execl("/bin/sh","sh","-c","sudo nmap -sS -A 192.168.0.1/24",NULL);
別のシェルウィンドウでHTOPを実行し、execl
起動PIDを確認します。
2339 for command "nmap -sS .."
2335 for command "sudo nmap -sS .."
2334 for command "sh .."
子プロセスPIDは2334です。 Nmapは完了するのに長い時間がかかり、3つのプロセスをすべて終了するにはkill 2339
シェルで実行できます。その後、2339、2335、2334はすべてHTOPモニターから消えました。
私が望むのは、Cプログラムでkill(2339、...)を実行し、シェルでできるようにすべてを終了することです。私の質問はPID 2339を取得する方法です。この例では、私のchildPIDは2334です。
答え1
sh -c
まず、中間プロセスの1つを削除して問題を簡素化できます。これを使用してプロセスを開始する理由はありません。実際、実際のコマンドラインが動的に構築されていると、セキュリティが低下する可能性があります。変える:
execl("/bin/sh","sh","-c","sudo nmap -sS -A 192.168.0.1/24",NULL);
以下を行う必要があります。
execlp("sudo", "sudo", "nmap", "-sS", "-A", "192.168.0.1/24", NULL);
sudo
これで、プロセスとプロセスは2つしかありませんnmap
。親プロセス()のプロセスIDはわかっていますが、子プロセス()のプロセスIDはsudo
不明です。nmap
ただし、次の機能が利用可能であるため重要ではありませんsudo
。親を殺すと(を使用してSIGTERM
)シグナルが子に渡されます。
最後の残りの質問は、あなたが要求した質問と直接関連していませんが、とにかくこれらのプロセスを終了する権限はありません!その目的は特権を高めることであるため、sudo
当初はそのシグナルまたはそのサブシグナルを送信する権限がない可能性があります。
答え2
sudo kill
1つの方法は、権限が付与されている場合は親プロセスから子プロセスに移動することです。pid
sudoers
#include <err.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void sudokill(pid_t tokill);
int main(void)
{
pid_t pid;
pid = fork();
switch (pid) {
case -1:
err(1, "fork() failed");
case 0:
execlp("sudo", "sudo", "sleep", "999", (char *) NULL);
err(1, "execlp() failed");
default:
sleep(7);
sudokill(pid);
}
exit(EXIT_SUCCESS);
}
void sudokill(pid_t tokill)
{
char *killstr;
int status;
pid_t pid;
if (asprintf(&killstr, "%d", tokill) < 0)
err(1, "asprintf() failed");
pid = fork();
switch (pid) {
case -1:
err(1, "fork() failed");
case 0:
execlp("sudo", "sudo", "kill", killstr, (char *) NULL);
err(1, "execlp() failed");
default:
wait(&status);
}
free(killstr);
}