From owner-freebsd-bugs@FreeBSD.ORG Thu Mar 8 12:30:13 2007 Return-Path: X-Original-To: freebsd-bugs@hub.freebsd.org Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id B796216A409 for ; Thu, 8 Mar 2007 12:30:13 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [69.147.83.40]) by mx1.freebsd.org (Postfix) with ESMTP id 6105013C441 for ; Thu, 8 Mar 2007 12:30:13 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.13.4/8.13.4) with ESMTP id l28CUDBs001937 for ; Thu, 8 Mar 2007 12:30:13 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.13.4/8.13.4/Submit) id l28CUDWP001936; Thu, 8 Mar 2007 12:30:13 GMT (envelope-from gnats) Date: Thu, 8 Mar 2007 12:30:13 GMT Message-Id: <200703081230.l28CUDWP001936@freefall.freebsd.org> To: freebsd-bugs@FreeBSD.org From: Bruce Evans Cc: Subject: Re: bin/107171: systat(1) doesn't die when it's xterm is killed while it's running X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: Bruce Evans List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 08 Mar 2007 12:30:13 -0000 The following reply was made to PR bin/107171; it has been noted by GNATS. From: Bruce Evans To: Nate Eldredge Cc: freebsd-gnats-submit@FreeBSD.org Subject: Re: bin/107171: systat(1) doesn't die when it's xterm is killed while it's running Date: Thu, 8 Mar 2007 23:20:56 +1100 (EST) On Thu, 8 Mar 2007, Nate Eldredge wrote: > I presume the retry is to cope with the case where getch() was interrupted > by a signal. So probably it should only retry if errno = EINTR. This is > essentially what top does. Also, ferror(stdin) is a bogus test; getch() > does not go through stdio and so ferror(stdin) will never be set, and the > clearerr() is bogus too. > > EINTR is probably moot for FreeBSD anyway since it appears our ncurses > handles that transparently, but it doesn't hurt to check. ncurses has code to actively hide it, but this doesn't seem to be configured in FreeBSD (option HIDE_EINTR). Thus getch()'s man page may be wrong in claiming that the ncurses implementation never returns EINTR. In fact, it is a bug for getch() to never return EINTR, and a worse bug to loop in an input function when read() returns EINTR. Most unthreaded applications that use signal handlers need to change the BSD default of restarting syscalls after a signal, so that their signal handlers can just set a flag and depend on their main loop checking the flag promptly. Restarting syscalls prevents the flag being checked promptly by looping calling read() (or another syscall) in the kernel, and HIDE_EINTR would prevent the flag being checked promptly by looping calling read() in the library. However, EINTR is probably irrelevant for the current bug. systat doesn't catch SIGHUP in order to clean up up unsafely like it does for SIGINT, so any SIGHUP that gives EOF on the terminal would either: - kill the process uncleanly, or - not be delivered to the process because it is masked (no EINTR since it is not caught), or - not be delivered to the process because of job control stuff. So systat just needs a simple check for EOF from getch() and the remainly problem is that getch(), like getc(), unimproves on read() by not having any way to distinguish the non-error of EOF from errors. Bruce