On Fri, Aug 11, 2006 at 10:53:00PM -0700, Julian Elischer wrote: > I tried making the signal handler just set a variable that makes the > main loop quit, flush and exit, > but believe it or not, fgets() doesn't return from a signal. so you hit > ^C but it doesn't notice the flag that is set until > you then hit CR. Try using sigaction() instead of signal(), and don't set the SA_RESTART flag. fgets() should then return with EINTR in that case. OTOH, maybe stdio catches EINTR and retries itself. Quick check... no, it doesn't, so it should work in the way you want. The attached program demonstrates this. Regards, Brian. ----- 8< ----------------------------------------------------------------- #include <sys/types.h> #include <stdio.h> #include <unistd.h> #include <string.h> #include <stdlib.h> #include <signal.h> static int abortflag=0; static void parent(int wfd, pid_t cpid) { if (write(wfd, "abc", 3) != 3) { perror("write"); exit(1); } sleep(1); if (kill(cpid, SIGTERM) < 0) { perror("kill"); exit(1); } sleep(4); close(wfd); } static void setabort(int sig) { abortflag=1; } static void child(int rfd) { char buf[256]; struct sigaction act, oact; FILE *f = fdopen(rfd, "r"); if (!f) { perror("fdopen"); exit(1); } memset(&act, 0, sizeof(act)); act.sa_handler = setabort; sigaction(SIGTERM, &act, &oact); fprintf(stderr, "child: OK\n"); while(fgets(buf, sizeof(buf), f)) { fprintf(stderr, "child: Abort flag = %d\n", abortflag); fprintf(stderr, "child: Got %d bytes: '%s'\n", strlen(buf), buf); if (abortflag) break; } fclose(f); fprintf(stderr, "child: done\n"); } int main(void) { int pid; int fds[2]; if (pipe(fds) < 0) { perror("pipe"); return 1; } pid = fork(); if (pid < 0) { perror("fork"); return 1; } if (pid > 0) parent(fds[1], pid); else child(fds[0]); return 0; }Received on Mon Aug 14 2006 - 11:13:03 UTC
This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:38:59 UTC