forkfd: Make sure we handle SIGPIPE too
We can't depend on the application/library ignoring the signal for us, so we do it. O_NOSIGPIPE exists on the BSDs and I'll add it to Linux. If it isn't supported, then we need to ignore SIGPIPE globally. Change-Id: I25d85d86649448d5b2b3fffd1450f6afeaea8b18 Reviewed-by: Ralf Nolden <nolden@kde.org> Reviewed-by: Rafael Roquetto <rafael.roquetto@kdab.com>
This commit is contained in:
parent
3cae115d6d
commit
cf6a2e9617
39
src/3rdparty/forkfd/forkfd.c
vendored
39
src/3rdparty/forkfd/forkfd.c
vendored
@ -410,6 +410,26 @@ chain_handler:
|
||||
old_sigaction.sa_handler(signum);
|
||||
}
|
||||
|
||||
static void ignore_sigpipe()
|
||||
{
|
||||
#ifdef O_NOSIGPIPE
|
||||
static ffd_atomic_int done = FFD_ATOMIC_INIT(0);
|
||||
if (ffd_atomic_load(&done, FFD_ATOMIC_RELAXED))
|
||||
return;
|
||||
#endif
|
||||
|
||||
struct sigaction action;
|
||||
memset(&action, 0, sizeof action);
|
||||
sigemptyset(&action.sa_mask);
|
||||
action.sa_handler = SIG_IGN;
|
||||
action.sa_flags = 0;
|
||||
sigaction(SIGPIPE, &action, NULL);
|
||||
|
||||
#ifdef O_NOSIGPIPE
|
||||
ffd_atomic_store(&done, 1, FFD_ATOMIC_RELAXED);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void forkfd_initialize()
|
||||
{
|
||||
#if defined(HAVE_BROKEN_WAITID)
|
||||
@ -446,6 +466,11 @@ static void forkfd_initialize()
|
||||
*/
|
||||
sigaction(SIGCHLD, &action, &old_sigaction);
|
||||
|
||||
#ifndef O_NOSIGPIPE
|
||||
/* disable SIGPIPE too */
|
||||
ignore_sigpipe();
|
||||
#endif
|
||||
|
||||
#ifndef __GNUC__
|
||||
atexit(cleanup);
|
||||
#endif
|
||||
@ -486,13 +511,23 @@ static void cleanup()
|
||||
|
||||
static int create_pipe(int filedes[], int flags)
|
||||
{
|
||||
int ret;
|
||||
int ret = -1;
|
||||
#ifdef HAVE_PIPE2
|
||||
/* use pipe2(2) whenever possible, since it can thread-safely create a
|
||||
* cloexec pair of pipes. Without it, we have a race condition setting
|
||||
* FD_CLOEXEC
|
||||
*/
|
||||
ret = pipe2(filedes, O_CLOEXEC);
|
||||
|
||||
# ifdef O_NOSIGPIPE
|
||||
/* try first with O_NOSIGPIPE */
|
||||
ret = pipe2(filedes, O_CLOEXEC | O_NOSIGPIPE);
|
||||
if (ret == -1) {
|
||||
/* O_NOSIGPIPE not supported, ignore SIGPIPE */
|
||||
ignore_sigpipe();
|
||||
}
|
||||
# endif
|
||||
if (ret == -1)
|
||||
ret = pipe2(filedes, O_CLOEXEC);
|
||||
if (ret == -1)
|
||||
return ret;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user