Date: Thu, 8 Mar 2007 12:30:13 GMT From: Bruce Evans <bde@zeta.org.au> To: freebsd-bugs@FreeBSD.org Subject: Re: bin/107171: systat(1) doesn't die when it's xterm is killed while it's running Message-ID: <200703081230.l28CUDWP001936@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
The following reply was made to PR bin/107171; it has been noted by GNATS. From: Bruce Evans <bde@zeta.org.au> To: Nate Eldredge <nge@cs.hmc.edu> 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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200703081230.l28CUDWP001936>