aboutsummaryrefslogtreecommitdiff
path: root/winsup/cygwin
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2024-08-18 21:40:51 +0200
committerCorinna Vinschen <corinna@vinschen.de>2024-08-18 21:40:51 +0200
commit7f3c22532577ae0a926e8eb8ad63787c9841abbf (patch)
treebafa7012f987bf3f23cc4e77c8fbde1046281303 /winsup/cygwin
parentb2e05e03df85ba84f11e10445663fb23ebd21e23 (diff)
downloadnewlib-7f3c22532577ae0a926e8eb8ad63787c9841abbf.zip
newlib-7f3c22532577ae0a926e8eb8ad63787c9841abbf.tar.gz
newlib-7f3c22532577ae0a926e8eb8ad63787c9841abbf.tar.bz2
Cygwin: pipe: handle signals explicitely in raw_write
The simple cygwait call in fhandler_pipe_fifo::raw_write doesn't take the SA_RESTART setting into account. Move handling the signal into raw_write. Fixes: 4b25687ea3ee2 ("Cygwin: fhandler_pipe: add raw_read and raw_write") Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
Diffstat (limited to 'winsup/cygwin')
-rw-r--r--winsup/cygwin/fhandler/pipe.cc15
1 files changed, 12 insertions, 3 deletions
diff --git a/winsup/cygwin/fhandler/pipe.cc b/winsup/cygwin/fhandler/pipe.cc
index ae43cbc..ce6099d 100644
--- a/winsup/cygwin/fhandler/pipe.cc
+++ b/winsup/cygwin/fhandler/pipe.cc
@@ -498,9 +498,16 @@ fhandler_pipe_fifo::raw_write (const void *ptr, size_t len)
(PVOID) ptr, len1, NULL, NULL);
if (status == STATUS_PENDING)
{
- while (WAIT_TIMEOUT ==
- (waitret = cygwait (evt, (DWORD) 0, cw_cancel | cw_sig)))
+ do
{
+ /* To allow constant reader_closed() checking even if the
+ signal has been set up with SA_RESTART, we're handling
+ the signal here --> cw_sig_eintr. */
+ waitret = cygwait (evt, (DWORD) 0, cw_cancel | cw_sig_eintr);
+ /* Break out if no SA_RESTART. */
+ if (waitret == WAIT_SIGNALED
+ && !_my_tls.call_signal_handler ())
+ break;
if (reader_closed ())
{
CancelIo (get_handle ());
@@ -509,8 +516,10 @@ fhandler_pipe_fifo::raw_write (const void *ptr, size_t len)
goto out;
}
else
- cygwait (select_sem, 10);
+ cygwait (select_sem, 10, cw_cancel);
}
+ /* Loop in case of blocking write or SA_RESTART */
+ while (waitret == WAIT_TIMEOUT || waitret == WAIT_SIGNALED);
/* If io.Status is STATUS_CANCELLED after CancelIo, IO has
actually been cancelled and io.Information contains the
number of bytes processed so far.