Убейте sh -c и все его подпроцессы в c с помощью системных вызовов linux

#c #linux

Вопрос:

Я работаю над этой программой строки состояния, которая должна разветвлять и выполнять сценарии bash с помощью управления заданиями. Затем он передает выходные данные в строку и отображает их. В настоящее время я реализую эту функцию тайм-аута, которая запускает таймер, а затем убивает запущенный процесс, если выход занимает слишком много времени.

Процессы запускаются следующим образом :

 if (pipe2(pipefd, O_CLOEXEC) == -1)                                     
    return -1;                                                               int pid;                                                                
if ((pid = fork()) == -1)                                               
    return -1;                                                      
if (pid == 0) {                                                         
        close(STDIN_FILENO);                                            
        close(STDERR_FILENO);                                           
        dup2(pipefd[1], STDOUT_FILENO);                                 
        setpgid(0, 0);                                                  
        execl("/bin/sh", "sh", "-c", cmd, NULL);                        
        _exit(127);                                                     
}                                                                       
return pid;
 

И убили вот так :

 kill(cpid, SIGKILL);
 

Однако этот код не убьет подпроцессы sh, и это большая проблема. Чтобы добавить к этому, он создает множество несуществующих sh-процессов, даже если я использую waitpid.

Комментарии:

1. Это одна из вещей, для которой предназначены группы процессов. Видите killpg , и gnu.org/software/libc/manual/html_node/…

2. Кстати, использование SIGKILL-плохая идея, особенно если вы даже не пробовали сначала SIGTERM. Когда вы жестко убиваете программу, у нее нет возможности очистить свои буферы, поэтому вы можете получить вывод, который она пыталась распечатать, но еще не сбросила, просто потеряв его.

Ответ №1:

Убейте всю группу процессов, используя негатив лидера группы процессов:

 kill(-cpid, SIGKILL);
 

Комментарии:

1. Поэтому pid должен быть отрицательным. Большое спасибо

2. @WilliamBoulanger, отрицательное значение-это то, как вы указываете, что передаете номер группы процессов, а не идентификационный номер процесса. Вы не можете использовать произвольный идентификационный номер процесса, как если бы это была группа процессов; вам необходимо передать, в частности , номер группы процессов (который совпадает с идентификатором процесса лидера этой группы процессов, если ваша ОС Linux).

3. Теперь он убивает все подпроцессы, за исключением самого процесса sh, который становится несуществующим или зомби-процессом.

4. @WilliamBoulanger, если это зомби, это значит, что вы не wait() готовились к этому. Буквально, запись в таблице процессов, ожидающая прочтения и удаления waitpid() вызовом, — это то, что такое зомби .

5. @WilliamBoulanger Это тоже должно было произойти с исходным кодом.