From patchwork Wed Jul 31 18:31:35 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 170206 Delivered-To: patch@linaro.org Received: by 2002:ac9:2daa:0:0:0:0:0 with SMTP id g42csp6295000oce; Wed, 31 Jul 2019 11:32:12 -0700 (PDT) X-Google-Smtp-Source: APXvYqwdx23yoi0qNy9O86xbFI1r3BoiXYgbtvd+ZFZXCaL08sJcKpvgfb8ELlkkLA2G/K07pjTr X-Received: by 2002:a17:902:f01:: with SMTP id 1mr121416500ply.170.1564597932920; Wed, 31 Jul 2019 11:32:12 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1564597932; cv=none; d=google.com; s=arc-20160816; b=k98KhyrEnlbUzD5k/g6yr/+oVbRNg3I/4ocvNWaqBJWwvvr6ryvj+XXzPyJTBAssFZ 16Lz/XmqAPY8zuJYFDrlMdllIA577sMrqC76zjQTeiL6efbk7HYKgYj654mrg1q4LsaO Igek6qaNuMtfUHozvrN+fKSRj2FG5SbhzGP2KcHIcoSqYsMLLsGYnbSNV8BGjqyvKTDO a7dt29LT2Fvx9HHr7XF0jPI0y5Hs2pXd6BKnkm0ZZs1xb1PLRY927EpunPF1J46YfMb5 JdnI3Zb/GL5d6B7inrJMp9YjbPEnpsxdlQgho4YH6R2YgmfZYP4/jwqrCtjxmnPSJpye shBw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:to:from :dkim-signature:delivered-to:sender:list-help:list-post:list-archive :list-subscribe:list-unsubscribe:list-id:precedence:mailing-list :dkim-signature:domainkey-signature; bh=dsIklHcmbonLRctveIVB5yxaOgCqI9ZpW46MYXiXOkg=; b=OvQSM01AtvpsXp+JclabSDueVcwq5qsOe4F66UiMLks4AOA4bs0XALe2QJZYgGJl9R 7WSHIBUOXHpJr6U1xMIk92UmrCJri7QQmy6APfdlhQNyv+dSIAVfHlz9zIkdzisM9jSC Azh1iXXaW3D5hLRRMeH4/DlFo7SwCSVdp/w/trY+ws9yu1WI3bBNtw8AXFFLpn45trmB TnB+siCRD/KjDmdx+MllR0T8PwIb3Cq6Odn8VgnleBIPa/LJ75ytYfLeif93NUda/zeL ZZQMJ8I6FgRPyfkb7gjcjLCguyudvdZc2kc0RT8764l/A8PV8ayWDZUVVbfLepfL94qB eglA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=KWgap257; dkim=pass header.i=@linaro.org header.s=google header.b=rcch0DeC; spf=pass (google.com: domain of libc-alpha-return-104075-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom="libc-alpha-return-104075-patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id c12si2900856pgl.252.2019.07.31.11.32.12 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 31 Jul 2019 11:32:12 -0700 (PDT) Received-SPF: pass (google.com: domain of libc-alpha-return-104075-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=KWgap257; dkim=pass header.i=@linaro.org header.s=google header.b=rcch0DeC; spf=pass (google.com: domain of libc-alpha-return-104075-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom="libc-alpha-return-104075-patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id:in-reply-to :references; q=dns; s=default; b=F3Bg2i515qQD/0gAvditAnUSerMpqzx 6ojrONhwqtX0j8N60pljwbbe14xSNGGolFkNy1MqjuJ9jeF2n+lRfdPfw+H/+/Fs Z9GTjtciqw5Cvo4udFBLaBcZn0N/jwlTfRdcztBgSIqKeqGMmcuE3KnnwzJz2jSo D4tF0w7i8BVs= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id:in-reply-to :references; s=default; bh=GKmb/0ptq8fkf3k6VXcHwxoIgH8=; b=KWgap 257phPdR9ArBbT6Qlmhm54HNclVA143+VPbY9GwVFgYoMIzYLcVW/30zG5pzf66v oIZYnd0nZRpgt0WehxJR2u/Cq4dVhbWXdLmCmCRZYK+O36w6ayoPl5kYX8UkyLmj NafFL+pwWzUlvsNvBGcvSrs5MYZSurxsvrQMYM= Received: (qmail 122997 invoked by alias); 31 Jul 2019 18:31:51 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 122900 invoked by uid 89); 31 Jul 2019 18:31:51 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-15.8 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.1 spammy=Plus, disposition, *restrict X-HELO: mail-qk1-f196.google.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:subject:date:message-id:in-reply-to:references; bh=dsIklHcmbonLRctveIVB5yxaOgCqI9ZpW46MYXiXOkg=; b=rcch0DeCyb4nDxyOfO4TUdlONPbqCbTGBQYdA1cN4dVO5HFCIxNT5QWh4Pclkn/LhX 4LS3JAVFsDGOqQaRsxsbVhV6bJjkQpTSO5xQOZaTGp39/kLQSuSVgE+7OphVW+Ub/Y4M //KB4DkjwZ91eDvrDgZqskjshBps6MHJdHN8HrxEn+3AbUw7WS3swla9nX6nzFkl7kB1 2luCiWOUmK8wmnYfq/yALIr+VGl/C2RMORxjDxTGfhg+XeWRiK5Bb7MoKGD2T9XzIUjg EOLVavxr/kbsxFTtF3d0SB/oWMFDw/14smDEJDVCB9mx6aE/TUALpPKatmYM9ebQD1LQ +AxQ== Return-Path: From: Adhemerval Zanella To: libc-alpha@sourceware.org Subject: [PATCH 4/5] linux: Optimize posix_spawn spurious sigaction calls Date: Wed, 31 Jul 2019 15:31:35 -0300 Message-Id: <20190731183136.21545-4-adhemerval.zanella@linaro.org> In-Reply-To: <20190731183136.21545-1-adhemerval.zanella@linaro.org> References: <20190731183136.21545-1-adhemerval.zanella@linaro.org> The child helper process on Linux posix_spawn child must ensure that no signal handler are enabled, so the signal disposition must be either SIG_DFL or SIG_IGN. However, it requires a sigprocmask to obtain the current signal mask and at least _NSIG sigaction calls to reset the signal handlers for each posix_spawn call. This patch optimizes it by tracking on sigaction implementation when a signal action is set different than SIG_DFL or SIG_IGN. It allows remove a sigprocmask call and isse sigaction to reset the disposition only the signals that has non-default actions set. It might incur in false positive, since it not easy to remove bits from the mask without race conditions, but it does not allow false negative since the mask is updated atomically prior the syscall. The false positive incur in just extra sigactions on posix_spawn. Checked on x86_64 and i686. * include/atomic.h (atomic_fetch_or_seq_cst, atomic_fetch_or_seq_cst): New macros. * posix/Makefile (tests): Add tst-spawn6. * posix/tst-spawn6.c: New file. * sysdeps/generic/sigsetops.h (__sigorset_atomic): New macro. * sysdeps/unix/sysv/linux/internal-signals.h (__get_sighandler_set): New prototype. * sysdeps/unix/sysv/linux/sigaction.c (__get_sighandler_set): New function. (__libc_sigaction): Set the internal handler_set for a new action. * sysdeps/unix/sysv/linux/sigsetops.h (__sigorset_atomic, __sigaddset_atomic): New macros. * sysdeps/unix/sysv/linux/spawni.c (spawni_child): Replace __sigprocmask with __get_sighandler_set. --- include/atomic.h | 10 + posix/Makefile | 4 +- posix/tst-spawn6.c | 220 +++++++++++++++++++++ sysdeps/generic/sigsetops.h | 7 + sysdeps/unix/sysv/linux/internal-signals.h | 3 + sysdeps/unix/sysv/linux/sigaction.c | 17 ++ sysdeps/unix/sysv/linux/sigsetops.h | 15 ++ sysdeps/unix/sysv/linux/spawni.c | 9 +- 8 files changed, 278 insertions(+), 7 deletions(-) create mode 100644 posix/tst-spawn6.c -- 2.17.1 diff --git a/include/atomic.h b/include/atomic.h index ee1978eb3b..72609efde9 100644 --- a/include/atomic.h +++ b/include/atomic.h @@ -646,6 +646,9 @@ void __atomic_link_error (void); # define atomic_fetch_or_release(mem, operand) \ ({ __atomic_check_size((mem)); \ __atomic_fetch_or ((mem), (operand), __ATOMIC_RELEASE); }) +# define atomic_fetch_or_seq_cst(mem, operand) \ + ({ __atomic_check_size((mem)); \ + __atomic_fetch_or ((mem), (operand), __ATOMIC_SEQ_CST); }) # define atomic_fetch_xor_release(mem, operand) \ ({ __atomic_check_size((mem)); \ @@ -791,6 +794,13 @@ void __atomic_link_error (void); ({ atomic_thread_fence_release (); \ atomic_fetch_or_acquire ((mem), (operand)); }) # endif +# ifndef atomic_fetch_or_seq_cst +# define atomic_fetch_or_seq_cst(mem, operand) \ + ({ atomic_thread_fence_acquire (); \ + atomic_fetch_or_relaxed ((mem), (operand)); \ + atomic_thread_fence_release (); }) +# endif + # ifndef atomic_fetch_xor_release /* Failing the atomic_compare_exchange_weak_release reloads the value in diff --git a/posix/Makefile b/posix/Makefile index 1ac41ad85a..131ae052fd 100644 --- a/posix/Makefile +++ b/posix/Makefile @@ -102,7 +102,8 @@ tests := test-errno tstgetopt testfnm runtests runptests \ tst-sysconf-empty-chroot tst-glob_symlinks tst-fexecve \ tst-glob-tilde test-ssize-max tst-spawn4 bug-regex37 \ bug-regex38 tst-regcomp-truncated tst-spawn-chdir \ - tst-spawn5 + tst-spawn5 \ + tst-spawn6 tests-internal := bug-regex5 bug-regex20 bug-regex33 \ tst-rfc3484 tst-rfc3484-2 tst-rfc3484-3 \ tst-glob_lstat_compat tst-spawn4-compat @@ -255,6 +256,7 @@ tst-exec-ARGS = -- $(host-test-program-cmd) tst-exec-static-ARGS = $(tst-exec-ARGS) tst-execvpe5-ARGS = -- $(host-test-program-cmd) tst-spawn-ARGS = -- $(host-test-program-cmd) +tst-spawn6-ARGS = -- $(host-test-program-cmd) tst-spawn-static-ARGS = $(tst-spawn-ARGS) tst-spawn5-ARGS = -- $(host-test-program-cmd) tst-dir-ARGS = `pwd` `cd $(common-objdir)/$(subdir); pwd` `cd $(common-objdir); pwd` $(objpfx)tst-dir diff --git a/posix/tst-spawn6.c b/posix/tst-spawn6.c new file mode 100644 index 0000000000..466e66f104 --- /dev/null +++ b/posix/tst-spawn6.c @@ -0,0 +1,220 @@ +/* Tests for posix_spawn signal handling. + Copyright (C) 2019 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +/* Nonzero if the program gets called via `exec'. */ +static int restart; +#define CMDLINE_OPTIONS \ + { "restart", no_argument, &restart, 1 }, + +enum spawn_test_t +{ + SPAWN_SETSIGMASK, + SPAWN_SETSIGDEF +}; + +static int signal_to_check[] = +{ + SIGHUP, SIGINT, SIGALRM, SIGUSR2 +}; + +/* Called on process re-execution. */ +static int +handle_restart (enum spawn_test_t test) +{ + switch (test) + { + case SPAWN_SETSIGMASK: + { + sigset_t mask; + sigprocmask (SIG_BLOCK, NULL, &mask); + for (int i = 0; i < array_length (signal_to_check); i++) + if (sigismember (&mask, signal_to_check[i]) != 1) + exit (EXIT_FAILURE); + } + break; + case SPAWN_SETSIGDEF: + { + for (int i = 0; i < array_length (signal_to_check); i++) + { + struct sigaction act; + if (sigaction (signal_to_check[i], NULL, &act) != 0) + exit (EXIT_FAILURE); + if (act.sa_handler != SIG_DFL) + exit (EXIT_FAILURE); + } + } + break; + } + + return 0; +} + +/* Common argument used for process re-execution. */ +static char *initial_spargv[5]; +static size_t initial_spargv_size; + +/* Re-execute the test process with both '--direct', '--restart', and the + TEST (as integer value) as arguments. */ +static void +reexecute (enum spawn_test_t test, const posix_spawnattr_t *attrp) +{ + char *spargv[8]; + int i; + + for (i = 0; i < initial_spargv_size; i++) + spargv[i] = initial_spargv[i]; + /* Three digits per byte plus null terminator. */ + char teststr[3 * sizeof (test) + 1]; + snprintf (teststr, array_length (teststr), "%d", test); + spargv[i++] = teststr; + spargv[i] = NULL; + TEST_VERIFY (i < 8); + + pid_t pid; + int status; + + TEST_COMPARE (posix_spawn (&pid, spargv[0], NULL, attrp, spargv, environ), + 0); + TEST_COMPARE (xwaitpid (pid, &status, 0), pid); + TEST_VERIFY (WIFEXITED (status)); + TEST_VERIFY (!WIFSIGNALED (status)); + TEST_COMPARE (WEXITSTATUS (status), 0); +} + +/* Test if POSIX_SPAWN_SETSIGMASK change the spawn process signal mask to + the value blocked signals defined by SIGNAL_TO_CHECK signals. */ +static void +do_test_setsigmask (void) +{ + posix_spawnattr_t attr; + /* posix_spawnattr_init does not fail. */ + posix_spawnattr_init (&attr); + + { + sigset_t mask; + TEST_COMPARE (sigemptyset (&mask), 0); + for (int i = 0; i < array_length (signal_to_check); i++) + TEST_COMPARE (sigaddset (&mask, signal_to_check[i]), 0); + TEST_COMPARE (posix_spawnattr_setsigmask (&attr, &mask), 0); + TEST_COMPARE (posix_spawnattr_setflags (&attr, POSIX_SPAWN_SETSIGMASK), 0); + } + + /* Change current mask to be different than the one asked for spawned + process. */ + { + sigset_t empty_mask, current_mask; + TEST_COMPARE (sigemptyset (&empty_mask), 0); + TEST_COMPARE (sigprocmask (SIG_BLOCK, &empty_mask, ¤t_mask), 0); + + reexecute (SPAWN_SETSIGMASK, &attr); + + TEST_COMPARE (sigprocmask (SIG_SETMASK, ¤t_mask, NULL), 0); + } +} + +/* Test if POSIX_SPAWN_SETSIGDEF change the spawn process signal actions + defined by SIGNAL_TO_CHECK signals to default actions. */ +static void +do_test_setsigdef (void) +{ + posix_spawnattr_t attr; + /* posix_spawnattr_init does not fail. */ + posix_spawnattr_init (&attr); + + { + sigset_t mask; + TEST_COMPARE (sigemptyset (&mask), 0); + for (int i = 0; i < array_length (signal_to_check); i++) + TEST_COMPARE (sigaddset (&mask, signal_to_check[i]), 0); + TEST_COMPARE (posix_spawnattr_setsigdefault (&attr, &mask), 0); + TEST_COMPARE (posix_spawnattr_setflags (&attr, POSIX_SPAWN_SETSIGDEF), 0); + } + + /* Change current signal disposition to be different than the one asked for + spawned process. */ + struct sigaction default_act[array_length (signal_to_check)]; + { + sigset_t empty_mask; + TEST_COMPARE (sigemptyset (&empty_mask), 0); + for (int i = 0; i < array_length (signal_to_check); i++) + TEST_COMPARE (sigaction (signal_to_check[i], + &((struct sigaction) { .sa_handler = SIG_IGN, + .sa_mask = empty_mask, + .sa_flags = 0 }), + &default_act[i]), + 0); + } + + reexecute (SPAWN_SETSIGDEF, &attr); + + /* Restore signal dispositions. */ + for (int i = 0; i < array_length (signal_to_check); i++) + TEST_COMPARE (sigaction (signal_to_check[i], &default_act[i], NULL), 0); +} + +static int +do_test (int argc, char *argv[]) +{ + /* We must have one or four parameters left if called initially: + + path for ld.so optional + + "--library-path" optional + + the library path optional + + the application name + + Plus one parameter to indicate which test to execute through + re-execution. + + So for default usage without --enable-hardcoded-path-in-tests, it + will be called initially with 5 arguments and later with 2. For + --enable-hardcoded-path-in-tests it will be called with 2 arguments + regardless. */ + + if (argc != (restart ? 2 : 5) && argc != 2) + FAIL_EXIT1 ("wrong number of arguments (%d)", argc); + + if (restart) + return handle_restart (atoi (argv[1])); + + { + int i; + for (i = 0; i < (argc == 5 ? 4 : 1); i++) + initial_spargv[i] = argv[i + 1]; + initial_spargv[i++] = (char *) "--direct"; + initial_spargv[i++] = (char *) "--restart"; + initial_spargv_size = i; + } + + do_test_setsigmask (); + do_test_setsigdef (); + + return 0; +} + +#define TEST_FUNCTION_ARGV do_test +#include diff --git a/sysdeps/generic/sigsetops.h b/sysdeps/generic/sigsetops.h index ddeeb0b0d5..9cae11771b 100644 --- a/sysdeps/generic/sigsetops.h +++ b/sysdeps/generic/sigsetops.h @@ -66,6 +66,13 @@ 0; \ })) +# define __sigorset_atomic(set) \ + (__extension__ ({ \ + __sigset_t __mask = __sigmask (sig); \ + atomic_fetch_or_seq_cst (set, mask); \ + 0; \ + })) + # define __sigdelset(set, sig) \ (__extension__ ({ \ __sigset_t __mask = __sigmask (sig); \ diff --git a/sysdeps/unix/sysv/linux/internal-signals.h b/sysdeps/unix/sysv/linux/internal-signals.h index 3562011d21..385442f81e 100644 --- a/sysdeps/unix/sysv/linux/internal-signals.h +++ b/sysdeps/unix/sysv/linux/internal-signals.h @@ -88,4 +88,7 @@ __libc_signal_restore_set (const sigset_t *set) /* Used to communicate with signal handler. */ extern struct xid_command *__xidcmd attribute_hidden; +/* Used to obtained the modified signal handlers. */ +extern void __get_sighandler_set (sigset_t *set) attribute_hidden; + #endif diff --git a/sysdeps/unix/sysv/linux/sigaction.c b/sysdeps/unix/sysv/linux/sigaction.c index 52722b08ae..3bcf3946ab 100644 --- a/sysdeps/unix/sysv/linux/sigaction.c +++ b/sysdeps/unix/sysv/linux/sigaction.c @@ -20,6 +20,7 @@ #include #include +#include #include /* New ports should not define the obsolete SA_RESTORER, however some @@ -36,6 +37,13 @@ # define STUB(act, sigsetsize) (sigsetsize) #endif +static sigset_t handler_set; + +void __get_sighandler_set (sigset_t *set) +{ + *set = handler_set; +} + /* If ACT is not NULL, change the action for SIG to *ACT. If OACT is not NULL, put the old action for SIG in *OACT. */ int @@ -47,6 +55,15 @@ __libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) if (act) { + /* Tracks which signal had a signal handler set different from default + (SIG_DFL/SIG_IGN). It allows optimize posix_spawn to reset only + those signals. It might incur in false positive, since it not easy + to remove bits from the mask without race conditions, but it does not + allow false negative since the mask is updated atomically prior the + syscall. The false positive incur in just extra sigactions on + posix_spawn. */ + if (act->sa_handler != SIG_DFL && act->sa_handler != SIG_IGN) + __sigaddset_atomic (&handler_set, sig); kact.k_sa_handler = act->sa_handler; memcpy (&kact.sa_mask, &act->sa_mask, sizeof (sigset_t)); kact.sa_flags = act->sa_flags; diff --git a/sysdeps/unix/sysv/linux/sigsetops.h b/sysdeps/unix/sysv/linux/sigsetops.h index 713d4840d8..6c98c83e42 100644 --- a/sysdeps/unix/sysv/linux/sigsetops.h +++ b/sysdeps/unix/sysv/linux/sigsetops.h @@ -20,6 +20,7 @@ #define _SIGSETOPS_H 1 #include +#include /* Return a mask that includes the bit for SIG only. */ # define __sigmask(sig) \ @@ -80,6 +81,12 @@ (void)0; \ })) +# define __sigorset_atomic(dest, left, right) \ + (__extension__ ({ \ + atomic_fetch_or_seq_cst (dest, left, right); \ + 0; \ + })) + /* These macros needn't check for a bogus signal number; error checking is done in the non-__ versions. */ # define __sigismember(set, sig) \ @@ -97,6 +104,14 @@ (void)0; \ })) +# define __sigaddset_atomic(set, sig) \ + (__extension__ ({ \ + unsigned long int __mask = __sigmask (sig); \ + unsigned long int __word = __sigword (sig); \ + atomic_fetch_or_seq_cst (&((set)->__val[__word]), __mask); \ + (void)0; \ + })) + # define __sigdelset(set, sig) \ (__extension__ ({ \ unsigned long int __mask = __sigmask (sig); \ diff --git a/sysdeps/unix/sysv/linux/spawni.c b/sysdeps/unix/sysv/linux/spawni.c index 0f7a8ca5df..264edd09c6 100644 --- a/sysdeps/unix/sysv/linux/spawni.c +++ b/sysdeps/unix/sysv/linux/spawni.c @@ -132,17 +132,14 @@ spawni_child (void *arguments) const posix_spawnattr_t *restrict attr = args->attr; const posix_spawn_file_actions_t *file_actions = args->fa; - /* The child must ensure that no signal handler are enabled because it shared + /* The child must ensure that no signal handler are enabled because it share memory with parent, so the signal disposition must be either SIG_DFL or - SIG_IGN. It does by iterating over all signals and although it could - possibly be more optimized (by tracking which signal potentially have a - signal handler), it might requires system specific solutions (since the - sigset_t data type can be very different on different architectures). */ + SIG_IGN. */ struct sigaction sa; memset (&sa, '\0', sizeof (sa)); sigset_t hset; - __sigprocmask (SIG_BLOCK, 0, &hset); + __get_sighandler_set (&hset); for (int sig = 1; sig < _NSIG; ++sig) { if ((attr->__flags & POSIX_SPAWN_SETSIGDEF)