GNU bug report logs - #13018
fport_fill_input should handle EINTR

Previous Next

Package: guile;

Reported by: Aidan Gauland <aidalgol <at> no8wireless.co.nz>

Date: Wed, 28 Nov 2012 08:22:01 UTC

Severity: normal

Done: Mark H Weaver <mhw <at> netris.org>

Bug is archived. No further changes may be made.

Full log


Message #20 received at 13018 <at> debbugs.gnu.org (full text, mbox):

From: Mark H Weaver <mhw <at> netris.org>
To: Aidan Gauland <aidalgol <at> no8wireless.co.nz>,  13018 <at> debbugs.gnu.org
Subject: Re: bug#13018: fport_fill_input should handle EINTR
Date: Wed, 03 Jul 2013 15:14:10 -0400
We now finally understand the cause of this bug.  See below.

Andy Wingo <wingo <at> pobox.com> writes:
> On Thu 29 Nov 2012 21:19, ludo <at> gnu.org (Ludovic Courtès) writes:
>
>> Aidan Gauland <aidalgol <at> no8wireless.co.nz> skribis:
>>
>>> <mark_weaver> fport_fill_input should handle an EINTR error from 'read',
>>>               and restart the read if that happens.
>>>
>>> <mark_weaver> by default on some systems, signals cause 'read', 'write',
>>>               and many other system calls to abort and return an EINTR
>>>               error.
>>>
>>> <mark_weaver> basically, at the POSIX level, every call to 'read' has to
>>>               be within a little loop that takes care of the EINTR
>>>               problem.
>>
>> ‘fport_fill_input’ does this:
>>
>>   SCM_SYSCALL (count = read (fp->fdes, pt->read_buf, pt->read_buf_size));
>>
>> and SCM_SYSCALL does that:
>>
>>   # ifdef EINTR
>>   #  if (EINTR > 0)
>>   #   define SCM_SYSCALL(line)                    \
>>     do                                            \
>>       {                                           \
>>         errno = 0;                                \
>>         line;                                     \
>>         if (errno == EINTR)                       \
>>           {                                       \
>>             SCM_ASYNC_TICK;                       \
>>             continue;                             \
>>           }                                       \
>>       }                                           \
>>     while(0)
>>   #  endif /*  (EINTR > 0) */
>>   # endif /* def EINTR */
>
> I get the feeling the EINTR is coming from somewhere else [...]

As Ludovic finally realized, the 'continue' above always exits the loop,
because 'continue' jumps to the test, rather than unconditionally
jumping to the top of the loop body.  This bug was introduced in Guile
2.0.0.  We are now discussing how to proceed on guile-devel:

http://lists.gnu.org/archive/html/guile-devel/2013-06/msg00050.html
http://lists.gnu.org/archive/html/guile-devel/2013-07/msg00002.html

    Thanks,
      Mark




This bug report was last modified 11 years and 346 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.