diff options
author | Brad King <brad.king@kitware.com> | 2017-12-22 20:24:33 -0500 |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2018-01-08 12:55:00 -0500 |
commit | 4ffb0f8b45a5abd51a04a399461c9096019a87f8 (patch) | |
tree | 59eba1a3356d9a2fdb0beb587fe00589e41d6f57 /Utilities | |
parent | f7f34a46e674fcf0326b0dbbc6dbb35c9e3c022f (diff) | |
download | cmake-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')
-rw-r--r-- | Utilities/cmlibuv/src/unix/signal.c | 7 |
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)) |