diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 32d87e080..57a82167a 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,9 @@ +2013-01-11 Christopher Faylor + + * DevNotes: Add entry cgf-000021. + * select.cc (select): Unconditionally return when a signal is detected. + (select_stuff::wait): Ditto. + 2013-01-11 Corinna Vinschen * syscalls.cc (rename): Drop handling paths > 32757 chars, emit EINVAL diff --git a/winsup/cygwin/DevNotes b/winsup/cygwin/DevNotes index 0884579f5..cff8a2789 100644 --- a/winsup/cygwin/DevNotes +++ b/winsup/cygwin/DevNotes @@ -1,3 +1,12 @@ +2013-01-11 cgf-000021 + +Apparently I got the signal handling semantics of select() wrong again +even though I would have sworn that I tested this on Linux and Windows. + +select() is apparently *always* interrupted by a signal and *never* +restarts. Hopefully, between the comment added to the code and this +note, I'll not make this mistake again. + 2013-01-02 cgf-000020 (This entry should have been checked in with the changes but... I forgot) diff --git a/winsup/cygwin/globals.cc b/winsup/cygwin/globals.cc index 19a65b16a..581aecb60 100644 --- a/winsup/cygwin/globals.cc +++ b/winsup/cygwin/globals.cc @@ -1,7 +1,7 @@ /* globals.cc - Define global variables here. Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, - 2006, 2007, 2008, 2009, 2010, 2011, 2012 Red Hat, Inc. + 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Red Hat, Inc. This file is part of Cygwin. diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc index 143e8c4e7..4286c1543 100644 --- a/winsup/cygwin/select.cc +++ b/winsup/cygwin/select.cc @@ -1,7 +1,7 @@ /* select.cc Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, - 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Red Hat, Inc. + 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Red Hat, Inc. This file is part of Cygwin. @@ -165,13 +165,12 @@ select (int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, { case WAIT_SIGNALED: select_printf ("signal received"); - if (_my_tls.call_signal_handler ()) - res = select_stuff::select_loop; /* Emulate linux behavior */ - else - { - set_sig_errno (EINTR); - res = select_stuff::select_error; - } + /* select() is always interrupted by a signal so set EINTR, + unconditionally, ignoring any SA_RESTART detection by + call_signal_handler(). */ + _my_tls.call_signal_handler (); + set_sig_errno (EINTR); + res = select_stuff::select_signalled; break; case WAIT_CANCELED: sel.destroy (); @@ -404,13 +403,12 @@ next_while:; be assured that a signal handler won't jump out of select entirely. */ cleanup (); destroy (); - if (_my_tls.call_signal_handler ()) - res = select_loop; - else - { - set_sig_errno (EINTR); - res = select_signalled; /* Cause loop exit in cygwin_select */ - } + /* select() is always interrupted by a signal so set EINTR, + unconditionally, ignoring any SA_RESTART detection by + call_signal_handler(). */ + _my_tls.call_signal_handler (); + set_sig_errno (EINTR); + res = select_signalled; /* Cause loop exit in cygwin_select */ break; case WAIT_FAILED: system_printf ("WaitForMultipleObjects failed, %E");