diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2024-08-18 21:40:51 +0200 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2024-08-18 21:40:51 +0200 |
commit | 7f3c22532577ae0a926e8eb8ad63787c9841abbf (patch) | |
tree | bafa7012f987bf3f23cc4e77c8fbde1046281303 /winsup/cygwin | |
parent | b2e05e03df85ba84f11e10445663fb23ebd21e23 (diff) | |
download | newlib-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.cc | 15 |
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. |