Я только что проверил свое предложение в комментариях, и оно сработало! Это код в моем magic_tool.c
:
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
int main (int argc, char *argv[])
{
pid_t pid;
printf("Executing %s to wrap %s.\n", argv[0], argv[1]);
pid = fork();
if (pid == -1)
return -1;
if (pid == 0) {
raise(SIGSTOP);
execl(argv[1], "", NULL);
} else {
printf("PID == %d\n", pid);
}
return 0;
}
Я написал другую тестовую программу target.c
:
#include <stdio.h>
int main ()
{
puts("It works!\n");
return 0;
}
Запустив ./magic_tool ./target
, напечатал PID и вернулся в оболочку. Только после запуска kill -SIGCONT <printed_pid>
был напечатан It works!
. Возможно, вы захотите сохранить PID в другом месте, а также выполнить некоторые проверки в magic_tool
, но я думаю, что это, тем не менее, хорошее подтверждение концепции.
РЕДАКТИРОВАТЬ:
Я немного поиграл с этим, и по какой-то причине это не всегда работало (см. Почему ниже). Решение простое - просто следуйте правильному расколу и умрите образец чуть более точно в magic_tool.c
:
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
int main (int argc, char *argv[])
{
pid_t pid;
printf("Executing %s to wrap %s.\n", argv[0], argv[1]);
pid = fork();
if (pid == -1)
return -1;
if (pid == 0) {
setsid();
pid = fork();
if (pid == -1)
return -1;
if (pid == 0) {
raise(SIGSTOP);
if (execl(argv[1], "", NULL))
return -1;
}
printf("PID == %d\n", pid);
}
return 0;
}
Я нашел объяснение в этом ответе :
Когда вы запускаете корневой процесс из своей оболочки, он является лидером группы процессов, а его потомки являются членами этой группы. Когда этот лидер заканчивается, группа процессов становится сиротой. Когда система обнаруживает вновь осиротевшую группу процессов, в которой остановлен какой-либо участник, каждому участнику группы процессов отправляется SIGHUP, за которым следует SIGCONT.
Итак, некоторые из ваших дочерних процессов по-прежнему останавливаются, когдалидер заканчивается, и, таким образом, каждый получает SIGHUP, за которым следует SIGCONT, что в практических целях означает, что они умирают от SIGHUP.
Точно, какие потомки все еще остановлены (или даже просто весело продвигаются к выходу ())гонка по времени.
Ответ также связан с IEEE Std 1003.1-2017 _Выходная запись , которая содержит более подробную информацию по этому вопросу.