GNU bug report logs -
#30368
‘select’ returns non-empty sets upon EINTR or EAGAIN
Previous Next
Reported by: ludo <at> gnu.org (Ludovic Courtès)
Date: Tue, 6 Feb 2018 10:40:02 UTC
Severity: important
Done: ludo <at> gnu.org (Ludovic Courtès)
Bug is archived. No further changes may be made.
To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 30368 in the body.
You can then email your comments to 30368 AT debbugs.gnu.org in the normal way.
Toggle the display of automated, internal messages from the tracker.
Report forwarded
to
bug-guile <at> gnu.org
:
bug#30368
; Package
guile
.
(Tue, 06 Feb 2018 10:40:02 GMT)
Full text and
rfc822 format available.
Acknowledgement sent
to
ludo <at> gnu.org (Ludovic Courtès)
:
New bug report received and forwarded. Copy sent to
bug-guile <at> gnu.org
.
(Tue, 06 Feb 2018 10:40:02 GMT)
Full text and
rfc822 format available.
Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):
[Message part 1 (text/plain, inline)]
Hello,
As of Guile 2.2.3, the Scheme-level ‘select’ can return non-empty sets
when the C-level ‘select’ returns EINTR or EAGAIN. The program below
illustrates this:
--8<---------------cut here---------------start------------->8---
(use-modules (ice-9 match))
(sigaction SIGINT (lambda args
(pk 'signal! args)))
(let ((target (getpid)))
(match (primitive-fork)
((? zero?)
(sleep 4)
(kill target SIGINT)
(primitive-exit 0))
(_ #t)))
(match (select (list (current-input-port)) '() '())
(((port) () ())
(pk 'reading-from port)
(read-char port))
(lst
(pk 'done lst)))
--8<---------------cut here---------------end--------------->8---
On 2.2.3, it prints:
--8<---------------cut here---------------start------------->8---
$ guile select.scm
;;; (signal! (2))
;;; (reading-from #<input: file /dev/pts/9>)
--8<---------------cut here---------------end--------------->8---
From there on it’s stuck in a read(0, …) call.
The attached patch fixes it by clearing the returned FD sets on
EINTR/EAGAIN.
(Besides it seems that select(2) never returns EAGAIN.)
I’m not sure how to write a test for this; the one above is
timing-sensitive, which wouldn’t be great.
Thoughts?
Ludo’.
[Message part 2 (text/x-patch, inline)]
diff --git a/libguile/filesys.c b/libguile/filesys.c
index e39dc4a0d..05dd2bd16 100644
--- a/libguile/filesys.c
+++ b/libguile/filesys.c
@@ -1,5 +1,5 @@
/* Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2004, 2006,
- * 2009, 2010, 2011, 2012, 2013, 2014, 2016, 2017 Free Software Foundation, Inc.
+ * 2009, 2010, 2011, 2012, 2013, 2014, 2016, 2017, 2018 Free Software Foundation, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
@@ -900,10 +900,20 @@ SCM_DEFINE (scm_select, "select", 3, 2, 0,
int rv = scm_std_select (max_fd + 1,
&read_set, &write_set, &except_set,
time_ptr);
- /* Let EINTR / EAGAIN cause a return to the user and let them loop
- to run any asyncs that might be pending. */
- if (rv < 0 && errno != EINTR && errno != EAGAIN)
- SCM_SYSERROR;
+ if (rv < 0)
+ {
+ /* Let EINTR / EAGAIN cause a return to the user and let them
+ loop to run any asyncs that might be pending. */
+ if (errno != EINTR && errno != EAGAIN)
+ SCM_SYSERROR;
+ else
+ {
+ /* Return empty sets. */
+ FD_ZERO (&read_set);
+ FD_ZERO (&write_set);
+ FD_ZERO (&except_set);
+ }
+ }
}
return scm_list_3 (retrieve_select_type (&read_set, read_ports_ready, reads),
Severity set to 'important' from 'normal'
Request was from
ludo <at> gnu.org (Ludovic Courtès)
to
control <at> debbugs.gnu.org
.
(Wed, 07 Feb 2018 13:31:01 GMT)
Full text and
rfc822 format available.
Information forwarded
to
bug-guile <at> gnu.org
:
bug#30368
; Package
guile
.
(Wed, 07 Feb 2018 13:35:01 GMT)
Full text and
rfc822 format available.
Message #10 received at 30368 <at> debbugs.gnu.org (full text, mbox):
ludo <at> gnu.org (Ludovic Courtès) skribis:
> On 2.2.3, it prints:
>
> $ guile select.scm
>
>
> ;;; (signal! (2))
> ;;; (reading-from #<input: file /dev/pts/9>)
>
>>From there on it’s stuck in a read(0, …) call.
>
> The attached patch fixes it by clearing the returned FD sets on
> EINTR/EAGAIN.
There’s a case where we can get a “fake” EINTR that doesn’t come from
the underlying select(2) call: when the ‘scm_i_prepare_to_wait_on_fd’
call in ‘scm_std_select’ returns 1, which happens when new asyncs have
been queued.
Ludo’.
Reply sent
to
ludo <at> gnu.org (Ludovic Courtès)
:
You have taken responsibility.
(Fri, 16 Feb 2018 14:34:02 GMT)
Full text and
rfc822 format available.
Notification sent
to
ludo <at> gnu.org (Ludovic Courtès)
:
bug acknowledged by developer.
(Fri, 16 Feb 2018 14:34:02 GMT)
Full text and
rfc822 format available.
Message #15 received at 30368-done <at> debbugs.gnu.org (full text, mbox):
ludo <at> gnu.org (Ludovic Courtès) skribis:
> The attached patch fixes it by clearing the returned FD sets on
> EINTR/EAGAIN.
Pushed as f390afa0cc84eb84ed2cb3e03f542b991d4bb080.
Ludo’.
bug archived.
Request was from
Debbugs Internal Request <help-debbugs <at> gnu.org>
to
internal_control <at> debbugs.gnu.org
.
(Sat, 17 Mar 2018 11:24:06 GMT)
Full text and
rfc822 format available.
This bug report was last modified 6 years and 40 days ago.
Previous Next
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.