From owner-freebsd-current@FreeBSD.ORG Mon Aug 14 13:13:03 2006 Return-Path: X-Original-To: current@freebsd.org Delivered-To: freebsd-current@FreeBSD.ORG Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 3AA8316A4DA for ; Mon, 14 Aug 2006 13:13:03 +0000 (UTC) (envelope-from b.candler@pobox.com) Received: from proof.pobox.com (proof.pobox.com [207.106.133.28]) by mx1.FreeBSD.org (Postfix) with ESMTP id 0D68A43D62 for ; Mon, 14 Aug 2006 13:12:56 +0000 (GMT) (envelope-from b.candler@pobox.com) Received: from proof (localhost [127.0.0.1]) by proof.pobox.com (Postfix) with ESMTP id 3CAF928D87; Mon, 14 Aug 2006 09:13:18 -0400 (EDT) Received: from mappit.local.linnet.org (212-74-113-67.static.dsl.as9105.com [212.74.113.67]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by proof.sasl.smtp.pobox.com (Postfix) with ESMTP id D062B6708C; Mon, 14 Aug 2006 09:13:15 -0400 (EDT) Received: from lists by mappit.local.linnet.org with local (Exim 4.61 (FreeBSD)) (envelope-from ) id 1GCcFP-000MKD-RE; Mon, 14 Aug 2006 14:12:52 +0100 Date: Mon, 14 Aug 2006 14:12:51 +0100 From: Brian Candler To: Julian Elischer Message-ID: <20060814131251.GB85695@uk.tiscali.com> References: <44DD4510.5070002@elischer.org> <20060812033607.GB80768@gothmog.pc> <44DD50FF.5040406@elischer.org> <20060812041535.GA82669@gothmog.pc> <44DD5992.5080409@elischer.org> <20060812045622.GA84354@gothmog.pc> <44DD6CBC.9030309@elischer.org> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <44DD6CBC.9030309@elischer.org> User-Agent: Mutt/1.4.2.1i Cc: Giorgos Keramidas , current@freebsd.org Subject: Re: suggested addition to 'date' X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 14 Aug 2006 13:13:03 -0000 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 #include #include #include #include #include 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; }