[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Chicken-hackers] [PATCH] Handle EINTR properly in getc()
From: |
Peter Bex |
Subject: |
[Chicken-hackers] [PATCH] Handle EINTR properly in getc() |
Date: |
Wed, 3 Oct 2012 21:10:09 +0200 |
User-agent: |
Mutt/1.4.2.3i |
Hi all,
I got some strange results when registering a signal handler for sigchld,
as I documented here:
http://lists.nongnu.org/archive/html/chicken-users/2012-10/msg00009.html
It turns out that this is caused by faulty EINTR handling. On Linux and
OpenBSD this apparently is not an issue, but on NetBSD registering sigchld
causes the program in my message to return from the child before reading
has finished (but only about 9 times out of 10). This causes SIGCHLD to
be delivered, which means the read action gets interrupted with EINTR.
As the NetBSD manual page for getc() says:
"If successful, these routines return the next requested object from the
stream. If the stream is at end-of-file or a read error occurs, the rou-
tines return EOF. The routines feof(3) and ferror(3) must be used to
distinguish between end-of-file and error. If an error occurs, the
global variable errno is set to indicate the error."
It turns out that errno is *not* cleared in between calls, which means
we get stuck in an endless loop; fast_read_line_from_file() returns -13
the first time (which indicates 12 bytes were read), then the port's
read-line procedure loops and calls fast_read_line_from_file() again,
which from then on keeps returning -1 because we're at the end of the
file but errno is still EINTR. This just keeps going, and going, and
going...
Possibly this could be another cause of some spiffy hangs we've been
seeing. Since EINTR is relatively rare (especially on Linux, apparently)
this happens only occasionally.
Attached is a patch to fix this behavior. It also fixes a second bug in
the EINTR handling code in read-line: the negative number was assigned
to 'n', but this was never used, which means the bytes read up until we
got interrupted by a signal was simply ignored.
I wasn't sure whether to add a test for this because it's a little
over-specific and can only semi-reliably be triggered on NetBSD.
Cheers,
Peter
--
http://sjamaan.ath.cx
--
"The process of preparing programs for a digital computer
is especially attractive, not only because it can be economically
and scientifically rewarding, but also because it can be an aesthetic
experience much like composing poetry or music."
-- Donald Knuth
0001-After-calling-getc-and-getting-back-EOF-properly-che.patch
Description: Text document