From 4ffb0f8b45a5abd51a04a399461c9096019a87f8 Mon Sep 17 00:00:00 2001 From: Brad King Date: Fri, 22 Dec 2017 20:24:33 -0500 Subject: libuv: unix: restart syscalls interrupted by our signal handler 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 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`. --- Utilities/cmlibuv/src/unix/signal.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Utilities/cmlibuv/src/unix/signal.c b/Utilities/cmlibuv/src/unix/signal.c index cb09ead..3759778 100644 --- a/Utilities/cmlibuv/src/unix/signal.c +++ b/Utilities/cmlibuv/src/unix/signal.c @@ -28,6 +28,9 @@ #include #include +#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)) -- cgit v0.12