Когда я пробую ваш код в моей среде, результат у вас тот же. Я проверяю состояние процесса сына после Ctrl + Z ,
До Ctrl + Z
ps -aux | grep sleep
16586 0.0 0.0 2016 412 pts/1 S+ 10:42 0:00 /bin/sleep 10
После Ctrl + Z
ps -aux | grep sleep
16586 0.0 0.0 2016 412 pts/1 T+ 10:42 0:00 /bin/sleep 10
Состояние процесса сына изменилось с S - > T. Это означает, что родительский процесс успешно отправил сигнал дочернему процессу.
Но дочерний процесс не завершается, поэтому ваш waitpid (-1, & status, 0) не может вернуться.
Option1: send сигнал kill для процесса son, и waitpid получит одно возвращение.
void send_signal(int signum)
{
if (pid)
{
printf("kill %d, signum %d\n", pid, signum);
//kill(pid, signum);
kill(pid, SIGKILL );
}
}
Option2: API-интерфейс waitpid имеет одну опцию, которая может ожидать состояние остановки:
void handler()
{
pid_t pid;
int status;
while ((pid = waitpid(-1, &status, WSTOPPED)) > 0) {
printf("pid: %d has been reaped\n", pid);
break;
}
}
Пожалуйста, проверьте ниже версию sw , он работает на моей рабочей станции.
int pid = 0;
void handler()
{
pid_t pid;
int status;
while ((pid = waitpid(-1, &status, WSTOPPED)) > 0) {
printf("pid: %d has been reaped\n", pid);
break;
}
}
void send_signal(int signum)
{
if (pid)
{
printf("kill %d, signum %d\n", pid, signum);
kill(pid, signum);
//kill(pid, SIGKILL );
}
}
void init_signals()
{
signal(SIGCHLD, handler);
signal(SIGTSTP, send_signal);
}
void start_foreground_job(char** argv)
{
pid = fork();
if (pid == 0) {
signal(SIGTSTP, SIG_DFL);
if ((execve(argv[0], argv, NULL)) < 0) { //envp
fprintf(stderr, "%s: Command not found.\n", argv[0]);
exit(0);
}
}
printf("son process pid is %d\n", pid);
pause();
return;
}
int main()
{
init_signals();
char* argv[] = {"/bin/sleep", "10", NULL};
start_foreground_job(argv);
printf("This line is what I expected after pressing CTRL-Z\n");
return 0;
}
Ниже приведен мой результат теста:
./temp
son process pid is 29249
^Zkill 29249, signum 20
pid: 29249 has been reaped
This line is what I expected after pressing CTRL-Z