From patchwork Tue Oct 3 18:58:14 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Brendan Shanks X-Patchwork-Id: 148031 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:612c:2a8e:b0:403:3b70:6f57 with SMTP id in14csp2291531vqb; Tue, 3 Oct 2023 12:04:52 -0700 (PDT) X-Google-Smtp-Source: AGHT+IE8PkkwsTwYBcOkmIyXpGSDLFQKnCmGnDswARg77DCZOoujpYaA+CTkd82B8Wbbk/f0EUL6 X-Received: by 2002:a17:906:209a:b0:9ae:3f69:9b89 with SMTP id 26-20020a170906209a00b009ae3f699b89mr69417ejq.7.1696359892062; Tue, 03 Oct 2023 12:04:52 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1696359892; cv=none; d=google.com; s=arc-20160816; b=Y5mjyvJ/twJ3etQyqLjOt9F+BnzSIerAtbWWipw94WcZHxFLDDsMZ1Txtmk994T+CR t0+1/j8mXrrx5ndu2WlLVnRWuBeeNX1VMnNkWsQEp7gnkTBJNBB21eYsJkWXmFyNqD9B 8n19Q4WEYdkm0ugqF/rPdpoJJoq/gqlqVx1Tx3CI4kI84jlSSGYJSDt5Gj+1UHT+M5D5 lzfMtqAFoHx72iJO7gjEVtC+fnJugL8aa5a/7ODW+D1bXvmaa6ghtie2QwlkLeXQT4S4 NtZ4DTYy70wVLqLaGANCkPAIAfEXhGATkH0ggMHZRAFRZFHWI8WD38aO45CO4Fc0IaXf DTbg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:message-id:date:subject:cc:to:from:dkim-signature :dmarc-filter:delivered-to; bh=HDYLfc4EWSF0m6WeSdSGLXqjH12/FXvnBCNYNJOCG3g=; fh=QiogErZPgyLKS8sr17tmBJKC6nJZFHjteHo56ry6e5g=; b=j2hea0LsO2TBkn5wiyBuVq6Tpl6lT74pwFxXiC39jr/iZVkGUVTFkDACCUi8vgUbMf vF51K40x5n6SZegDc2zZu/Y/SWvO6uRHQNShuvkcN01pscKsaQKu4u3NFpC6Ic2uUb9v /HpeUpN9MEmTup6oB8eobddfTGZrJKVBCcGqPO8O6ylvA0/PuRxD4/U3kBwRcGoTqrgw +VUV+uaRV6LXszvOiRA8Z3je+w6UP8sjEbKKR3NfpUoqsgRfmokzgjwbjRCt1xScZzkY QebGsRfSlvDwX+k9ZrWEWtKRXQZ9NMph0c1ClOCjEZ7CUUkBXhIsgaHFAM0xuZHaIZOo sKCg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@codeweavers.com header.s=s1 header.b=odkaxeZj; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=codeweavers.com Received: from server2.sourceware.org (ip-8-43-85-97.sourceware.org. [8.43.85.97]) by mx.google.com with ESMTPS id i26-20020a1709064eda00b0099233867740si924834ejv.144.2023.10.03.12.04.51 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 03 Oct 2023 12:04:52 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) client-ip=8.43.85.97; Authentication-Results: mx.google.com; dkim=pass header.i=@codeweavers.com header.s=s1 header.b=odkaxeZj; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=codeweavers.com Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 52F0A385772B for ; Tue, 3 Oct 2023 19:04:45 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail.codeweavers.com (mail.codeweavers.com [4.36.192.163]) by sourceware.org (Postfix) with ESMTPS id AC75F3858D39 for ; Tue, 3 Oct 2023 19:04:21 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org AC75F3858D39 Authentication-Results: sourceware.org; dmarc=pass (p=reject dis=none) header.from=codeweavers.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=codeweavers.com DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=codeweavers.com; s=s1; h=Message-ID:Date:Subject:Cc:To:From:Sender; bh=HDYLfc4EWSF0m6WeSdSGLXqjH12/FXvnBCNYNJOCG3g=; b=odkaxeZj0G2zkny+up2gu9uat1 HoUR09nccyAXu9VEAzF88JyV5PRzyd7uBh67zRlSlOog5WHmxxL43E2ilOD1ZdFki56xjx1ahzDks HfSvFqan9f5fYAI4RDuoSMnTsqiKHO8ccM5qLdbxLJPwXHg1mZeCV7G9ZccbegrPQ58sRVRN2CFwQ rK23tWCMYxAizwwIwQR7P+nozyO+3Djeb8gMkxXARqUPzTZB/eB9ZSRL500ekFiaseWQwWY+hjQ0k UOJBv2DkY1mPdqbYxG8KMqsrtrixo0AP30xANPIeZH4Yl+W4R+njjek8C26aFQGewIa7hvxa0lSUb 8h5BG77A==; Received: from ip72-203-125-151.oc.oc.cox.net ([72.203.125.151] helo=zen.bslabs.net) by mail.codeweavers.com with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1qnkgt-0025ja-UH; Tue, 03 Oct 2023 14:04:20 -0500 From: Brendan Shanks To: gcc-patches@gcc.gnu.org Cc: Brendan Shanks Subject: [PATCH v2] libiberty: Use posix_spawn in pex-unix when available. Date: Tue, 3 Oct 2023 11:58:14 -0700 Message-ID: <20231003190414.23822-1-bshanks@codeweavers.com> X-Mailer: git-send-email 2.41.0 MIME-Version: 1.0 X-Spam-Status: No, score=-12.4 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, SPF_HELO_PASS, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1778762270140461487 X-GMAIL-MSGID: 1778762270140461487 Hi, This patch implements pex_unix_exec_child using posix_spawn when available. This should especially benefit recent macOS (where vfork just calls fork), but should have equivalent or faster performance on all platforms. In addition, the implementation is substantially simpler than the vfork+exec code path. Tested on x86_64-linux. v2: Fix error handling (previously the function would be run twice in case of error), and don't use a macro that changes control flow. libiberty/ * configure.ac (AC_CHECK_HEADERS): Add spawn.h. (checkfuncs): Add posix_spawn, posix_spawnp. (AC_CHECK_FUNCS): Add posix_spawn, posix_spawnp. * configure, config.in: Rebuild. * pex-unix.c [HAVE_POSIX_SPAWN] (pex_unix_exec_child): New function. Signed-off-by: Brendan Shanks --- libiberty/configure.ac | 8 ++-- libiberty/pex-unix.c | 93 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+), 3 deletions(-) diff --git a/libiberty/configure.ac b/libiberty/configure.ac index 0748c592704..2488b031bc8 100644 --- a/libiberty/configure.ac +++ b/libiberty/configure.ac @@ -289,7 +289,7 @@ AC_SUBST_FILE(host_makefile_frag) # It's OK to check for header files. Although the compiler may not be # able to link anything, it had better be able to at least compile # something. -AC_CHECK_HEADERS(sys/file.h sys/param.h limits.h stdlib.h malloc.h string.h unistd.h strings.h sys/time.h time.h sys/resource.h sys/stat.h sys/mman.h fcntl.h alloca.h sys/pstat.h sys/sysmp.h sys/sysinfo.h machine/hal_sysinfo.h sys/table.h sys/sysctl.h sys/systemcfg.h stdint.h stdio_ext.h process.h sys/prctl.h) +AC_CHECK_HEADERS(sys/file.h sys/param.h limits.h stdlib.h malloc.h string.h unistd.h strings.h sys/time.h time.h sys/resource.h sys/stat.h sys/mman.h fcntl.h alloca.h sys/pstat.h sys/sysmp.h sys/sysinfo.h machine/hal_sysinfo.h sys/table.h sys/sysctl.h sys/systemcfg.h stdint.h stdio_ext.h process.h sys/prctl.h spawn.h) AC_HEADER_SYS_WAIT AC_HEADER_TIME @@ -412,7 +412,8 @@ funcs="$funcs setproctitle" vars="sys_errlist sys_nerr sys_siglist" checkfuncs="__fsetlocking canonicalize_file_name dup3 getrlimit getrusage \ - getsysinfo gettimeofday on_exit pipe2 psignal pstat_getdynamic pstat_getstatic \ + getsysinfo gettimeofday on_exit pipe2 posix_spawn posix_spawnp psignal \ + pstat_getdynamic pstat_getstatic \ realpath setrlimit spawnve spawnvpe strerror strsignal sysconf sysctl \ sysmp table times wait3 wait4" @@ -435,7 +436,8 @@ if test "x" = "y"; then index insque \ memchr memcmp memcpy memmem memmove memset mkstemps \ on_exit \ - pipe2 psignal pstat_getdynamic pstat_getstatic putenv \ + pipe2 posix_spawn posix_spawnp psignal \ + pstat_getdynamic pstat_getstatic putenv \ random realpath rename rindex \ sbrk setenv setproctitle setrlimit sigsetmask snprintf spawnve spawnvpe \ stpcpy stpncpy strcasecmp strchr strdup \ diff --git a/libiberty/pex-unix.c b/libiberty/pex-unix.c index 33b5bce31c2..5e5ac529ad2 100644 --- a/libiberty/pex-unix.c +++ b/libiberty/pex-unix.c @@ -58,6 +58,9 @@ extern int errno; #ifdef HAVE_PROCESS_H #include #endif +#ifdef HAVE_SPAWN_H +#include +#endif #ifdef vfork /* Autoconf may define this to fork for us. */ # define VFORK_STRING "fork" @@ -559,6 +562,96 @@ pex_unix_exec_child (struct pex_obj *obj ATTRIBUTE_UNUSED, return (pid_t) -1; } +#elif defined(HAVE_POSIX_SPAWN) && defined(HAVE_POSIX_SPAWNP) +/* Implementation of pex->exec_child using posix_spawn. */ + +static pid_t +pex_unix_exec_child (struct pex_obj *obj ATTRIBUTE_UNUSED, + int flags, const char *executable, + char * const * argv, char * const * env, + int in, int out, int errdes, + int toclose, const char **errmsg, int *err) +{ + int ret; + pid_t pid = -1; + posix_spawnattr_t attr; + posix_spawn_file_actions_t actions; + int attr_initialized = 0, actions_initialized = 0; + + ret = posix_spawnattr_init (&attr); + if (ret) { *err = ret; *errmsg = "posix_spawnattr_init"; goto exit; } + attr_initialized = 1; + + /* Use vfork() on glibc <=2.24. */ +#ifdef POSIX_SPAWN_USEVFORK + ret = posix_spawnattr_setflags (&attr, POSIX_SPAWN_USEVFORK); + if (ret) { *err = ret; *errmsg = "posix_spawnattr_setflags"; goto exit; } +#endif + + ret = posix_spawn_file_actions_init (&actions); + if (ret) { *err = ret; *errmsg = "posix_spawn_file_actions_init"; goto exit; } + actions_initialized = 1; + + if (in != STDIN_FILE_NO) + { + ret = posix_spawn_file_actions_adddup2 (&actions, in, STDIN_FILE_NO); + if (ret) { *err = ret; *errmsg = "posix_spawn_file_actions_adddup2"; goto exit; } + + ret = posix_spawn_file_actions_addclose (&actions, in); + if (ret) { *err = ret; *errmsg = "posix_spawn_file_actions_addclose"; goto exit; } + } + if (out != STDOUT_FILE_NO) + { + ret = posix_spawn_file_actions_adddup2 (&actions, out, STDOUT_FILE_NO); + if (ret) { *err = ret; *errmsg = "posix_spawn_file_actions_adddup2"; goto exit; } + + ret = posix_spawn_file_actions_addclose (&actions, out); + if (ret) { *err = ret; *errmsg = "posix_spawn_file_actions_addclose"; goto exit; } + } + if (errdes != STDERR_FILE_NO) + { + ret = posix_spawn_file_actions_adddup2 (&actions, errdes, STDERR_FILE_NO); + if (ret) { *err = ret; *errmsg = "posix_spawn_file_actions_adddup2"; goto exit; } + + ret = posix_spawn_file_actions_addclose (&actions, errdes); + if (ret) { *err = ret; *errmsg = "posix_spawn_file_actions_addclose"; goto exit; } + } + if (toclose >= 0) + { + ret = posix_spawn_file_actions_addclose (&actions, toclose); + if (ret) { *err = ret; *errmsg = "posix_spawn_file_actions_addclose"; goto exit; } + } + if ((flags & PEX_STDERR_TO_STDOUT) != 0) + { + ret = posix_spawn_file_actions_adddup2 (&actions, STDOUT_FILE_NO, STDERR_FILE_NO); + if (ret) { *err = ret; *errmsg = "posix_spawn_file_actions_adddup2"; goto exit; } + } + + if ((flags & PEX_SEARCH) != 0) + { + ret = posix_spawnp (&pid, executable, &actions, &attr, argv, env ? env : environ); + if (ret) { *err = ret; *errmsg = "posix_spawnp"; goto exit; } + } + else + { + ret = posix_spawn (&pid, executable, &actions, &attr, argv, env ? env : environ); + if (ret) { *err = ret; *errmsg = "posix_spawn"; goto exit; } + } + +exit: + if (in != STDIN_FILE_NO) + close (in); + if (out != STDOUT_FILE_NO) + close (out); + if (errdes != STDERR_FILE_NO) + close (errdes); + + if (actions_initialized) + posix_spawn_file_actions_destroy (&actions); + if (attr_initialized) + posix_spawnattr_destroy (&attr); + return pid; +} #else /* Implementation of pex->exec_child using standard vfork + exec. */