Минималистичный пример программы, которая
- читает символ за символом через 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
.