Re: suggested addition to 'date'

From: Brian Candler <B.Candler_at_pobox.com>
Date: Mon, 14 Aug 2006 14:12:51 +0100
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