chicken-hackers
[Top][All Lists]
Advanced

[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

Attachment: 0001-After-calling-getc-and-getting-back-EOF-properly-che.patch
Description: Text document


reply via email to

[Prev in Thread] Current Thread [Next in Thread]