SIGCHLD вызывает EOF в родительском процессе - PullRequest
0 голосов
/ 23 ноября 2018

Минималистичный пример программы, которая

  • читает символ за символом через getchar, пока EOF
  • не запустит дочерний процесс при обнаружении "a".

Любопытно, что установка обработчика сигнала заставляет getchar возвращать EOF каждый раз, когда выходит ребенок.Довольно нежелательный побочный эффект.

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>

void handler() {
    // 
}

void action() {
    if (fork() == 0) {
        printf("(action)\n");
        sleep(1);
        exit(0);
    }
}

int main(int argc, char** argv) {
    char c;
    signal(SIGCHLD, handler);                // signal
    while (EOF != (c = getchar())) {
        if (c == 'a') action();
    }
    printf("End Of Data\n");
}

Проблема исчезает, когда сигнальная строка закомментирована.Может кто-нибудь объяснить, почему это происходит?

Кажется, та же проблема, что и Обработка SIGCHLD вернет EOF отцу, почему? , который не имеет четкого ответа о том, почему и как этого избежать.


РЕДАКТИРОВАТЬ 1: Мне было непонятно, не значит ли это много (вечер пятницы ...)

  • Причина в том, что системный вызов под getchar()был прерван, что привело к его возврату EOF (как написано на странице руководства).
  • (Ad hoc) Решение: проверьте errno для EINTR.

Вкл.этот пример

 while (EOF != (c = getchar()) || errno == EINTR) {

РЕДАКТИРОВАТЬ 2: проверка errno работает с getchar(), но не делает вас из леса с getline().

Реальное решение - забыть об устаревшем signal() и использовать sigaction() с флагом SA_RESTART.

...