summaryrefslogtreecommitdiff
path: root/Utilities/cmlibuv
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2017-12-22 20:24:33 -0500
committerBrad King <brad.king@kitware.com>2018-01-08 12:55:00 -0500
commit4ffb0f8b45a5abd51a04a399461c9096019a87f8 (patch)
tree59eba1a3356d9a2fdb0beb587fe00589e41d6f57 /Utilities/cmlibuv
parentf7f34a46e674fcf0326b0dbbc6dbb35c9e3c022f (diff)
downloadcmake-4ffb0f8b45a5abd51a04a399461c9096019a87f8.tar.gz
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`.
Diffstat (limited to 'Utilities/cmlibuv')
-rw-r--r--Utilities/cmlibuv/src/unix/signal.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/Utilities/cmlibuv/src/unix/signal.c b/Utilities/cmlibuv/src/unix/signal.c
index cb09ead50a..3759778011 100644
--- a/Utilities/cmlibuv/src/unix/signal.c
+++ b/Utilities/cmlibuv/src/unix/signal.c
@@ -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))