unix: use SA_RESTART when setting our sighandler

BSD `signal(2)` semantics make some system calls (e.g. for `write`)
restartable when interrupted by a signal handler.  Use `SA_RESTART` to
enable these semantics everywhere that supports them.

This was done by libev back when we used it.  In addition to being
common practice, this is required by C++ stream libraries that interpret
`EINTR` as any other error, set `badbit`, and stop writing.  I've
observed this with `libstdc++` during a `std::cout.flush()` call
interrupted by `SIGCHLD`.

PR-URL: https://github.com/libuv/libuv/pull/1696
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com>
This commit is contained in:
Brad King 2018-01-09 10:36:51 -05:00 committed by Santiago Gimeno
parent a468257e5d
commit 52b8b9a8b9
No known key found for this signature in database
GPG Key ID: F28C3C8DA33C03BE

View File

@ -28,6 +28,9 @@
#include <string.h>
#include <unistd.h>
#ifndef SA_RESTART
# define SA_RESTART 0
#endif
typedef struct {
uv_signal_t* handle;
@ -216,7 +219,9 @@ static int uv__signal_register_handler(int signum, int oneshot) {
if (sigfillset(&sa.sa_mask))
abort();
sa.sa_handler = uv__signal_handler;
sa.sa_flags = oneshot ? SA_RESETHAND : 0;
sa.sa_flags = SA_RESTART;
if (oneshot)
sa.sa_flags |= SA_RESETHAND;
/* XXX save old action so we can restore it later on? */
if (sigaction(signum, &sa, NULL))