execl에 의해 시작된 프로세스 종료

execl에 의해 시작된 프로세스 종료

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은 완료하는 데 오랜 시간이 걸리며 세 프로세스를 모두 종료하려면 kill 2339셸에서 실행하면 됩니다. 이후 2339, 2335, 2334가 모두 HTOP 모니터에서 사라졌습니다.

내가 원하는 것은 C 프로그램에서 kill(2339, ...)을 실행하고 쉘에서 할 수 있는 것처럼 모든 것을 종료하는 것입니다. 내 질문은 PID 2339를 얻는 방법입니다. 이 예에서 내 childPID는 2334입니다.

답변1

sh -c첫째, 중간 프로세스 중 하나를 제거하여 문제를 단순화할 수 있습니다. 이를 사용하여 프로세스를 시작할 이유가 없습니다 . 실제로 실제 명령줄이 동적으로 구축되면 보안이 덜할 수 있습니다. 바꾸다:

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이제 프로세스 와 프로세스 두 개만 있습니다 nmap. 상위 프로세스( )의 프로세스 ID는 알고 있지만 하위 프로세스( )의 프로세스 ID는 sudo알 수 없습니다 . nmap그러나 다음 기능을 사용할 수 있으므로 중요하지 않습니다 sudo. 부모를 죽이면( 를 사용하여 SIGTERM) 신호가 자식에게 전달됩니다.

마지막 남은 질문은 귀하가 요청한 질문과 직접적인 관련이 없지만 어쨌든 이러한 프로세스를 종료할 권한은 없을 것입니다! 그 목적은 권한을 높이는 것이기 때문에 sudo애초에 해당 신호나 해당 하위 신호를 보낼 권한이 없을 수도 있습니다.

답변2

sudo kill한 가지 방법은 권한이 부여된 경우 상위 프로세스에서 하위 프로세스로 이동하는 것입니다 .pidsudoers

#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);
}

관련 정보