Использование `kill` для запуска родительского` waitpid` - PullRequest
0 голосов
/ 06 февраля 2019

Я использую sigaction(SIGTSTP, &ctrlz_signal, NULL);, чтобы убедиться, что я могу поймать Ctrl-Z.

void ctrlz_signal(int sigNo) {
    printf("Caught Ctrl-Z  |  curr_chld=%d\n", CURR_CHILD);
    if(CURR_CHILD != 0) kill(CURR_CHILD, SIGTSTP);
}

CURR_CHILD настроен путем разветвления:

    sigaction(SIGTSTP, &ctrlz_signal, NULL);

    int         status;
    CURR_CHILD = fork();


    if (CURR_CHILD < 0) {
        // ...

    } else if (CURR_CHILD == 0) {  // child
        // exec(...)

    } else {  // back in parent
        waitpid(CURR_CHILD, &status, 0);  // wait for child to finish
        // ...
    }

Кажется, что это успешноостанавливает дочерний процесс, но затем не запускает родительский waitpid.Я бы подумал, что будет родительский сигнал, когда я буду использовать эту функцию kill, но похоже, что это не так, поскольку моя "оболочка" застревает на этой строке waitpid.

Как мне сделать так, чтобы после нажатия Ctrl-Z процесс, выполняющий команду exec (которая на тот момент была дочерней), был помещен в фоновый режим (остановлен), а затем родительскийпроцесс должен получить контроль над потоком программы?

1 Ответ

0 голосов
/ 06 февраля 2019

printf не является функцией для защиты от асинхронных сигналов (поскольку она не является входящей) и поэтому не должна использоваться в обработчике сигналов.Использование таких функций приведет к неопределенному поведению.

Если вы хотите, чтобы дочерний процесс, который не отслеживается с помощью ptrace, возвращался, вы должны указать параметр WUNTRACED при использовании waitpid.

В качестве альтернативы вы можете использовать ptrace с параметром PTRACE_TRACEME, чтобы он предоставил статус для дочернего процесса, даже если параметр WUNTRACED неуказанный в waitpid вызове.

...