From patchwork Fri Sep 29 19:16:55 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Brendan Shanks X-Patchwork-Id: 146732 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:6359:6f87:b0:13f:353d:d1ed with SMTP id tl7csp3513002rwb; Fri, 29 Sep 2023 12:18:53 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEbVW4IpIM/80CEIBPl/Xz+F9vpOsbVf8nwTjfnX50u0/cKFx5OocDo//zEuIJgOhx282L6 X-Received: by 2002:a17:907:778e:b0:9ae:6196:a4d1 with SMTP id ky14-20020a170907778e00b009ae6196a4d1mr4507160ejc.68.1696015133470; Fri, 29 Sep 2023 12:18:53 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1696015133; cv=none; d=google.com; s=arc-20160816; b=LaF0rwIO24dCZZ1jvdvwM5KIuQ9FtS+Cs5G0NFrBiHNdRogidk9a5XlAbIkR9wgntY v2/eoiElsuWxxvEEWran2JN/y8jAlRx45PHlqkl432xEtZkvG1cC1fmRZbXK2e0ZhPXP MQ5NfY50xWXRawUv41afiOPXTc/AFm08/UFVYGyxCmauxmArUt3dHy4v08IDUK73HT7d KCZJ9jnmURqPKFCskVo/RB8u8y92WYcWBJE32cLANPZimox1MR8/vy7+KVop0BFkYhQV lkONgjOrIufxO7ZkLvo9Sp70EkAPgX0vgl0ka4eluwCSgne6Ix8ShGvyj6TE2cCOR1dz e+SA== 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=cNRdu5LI/tJuURvCSCjv2LFRgSEnsE8RlxPkNF/O/JU=; fh=QiogErZPgyLKS8sr17tmBJKC6nJZFHjteHo56ry6e5g=; b=DZ4Dp5LQkNY7SgQTfXw+Hid57YMXyxFpWql+r4jfICwxqmLp67ql2TkkuMJYY9Dbmp jnx9lxs2HmBFd9CCXv8ifmMCjDbVULktY08O/AQl4EnsPGy1jWeCvlpnJUeEmgKimsi/ aLLEa46OnmNQPYcdz5vcpqznR3hRUnYjitmsynjhndVMfs7uYF29DuSMp67iRnzphJML t+4TOLhHQqfhnv5npmhGT9ZytcAcT8zU5OToWmJzDGARNtDYOD9HRtZrn3niiwC9olIc ltC4263J88NpUkGdh3DuM+ha3Q4Rdlpg295tcn9WDhihE8zUI1V6QHvdHT3SY+PWJVaB A+LA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@codeweavers.com header.s=s1 header.b=lx1re0iB; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c 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 (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id b18-20020a170906d11200b009936afb1e23si16846710ejz.130.2023.09.29.12.18.53 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 29 Sep 2023 12:18:53 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) client-ip=2620:52:3:1:0:246e:9693:128c; Authentication-Results: mx.google.com; dkim=pass header.i=@codeweavers.com header.s=s1 header.b=lx1re0iB; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c 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 235F538323F8 for ; Fri, 29 Sep 2023 19:18:46 +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 660C53875DD7 for ; Fri, 29 Sep 2023 19:18:21 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 660C53875DD7 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=cNRdu5LI/tJuURvCSCjv2LFRgSEnsE8RlxPkNF/O/JU=; b=lx1re0iBNHTJ8bLWd1kwy36kEh c/DTwW2izJmIeFoPqL4X5NulBzLEBz10N7pXyxSSzdFZsg1ML50BJ/iZaQvjG9LwAfJKT6+1R/NAg A2FRqZ5xmh9GZ1/q8IeGP4/7eOTpfZ6xHv7rIMXhHeELnwywQmgwMXzrDV9W5KeaOYvtd0iYOFpPA aRPzniVqHEUOyVmpsvv3gtK7m1kqcI5sDL2Ix5jPHGL31sCi3gwIiJ9LFxE/Lneznrc78AXT7I55X LGREieBYOCjh8oO42O6iCe6nZcIomV+ZU4q1kZJIND0ndRqP5CWa0vOzmHeAsS++3a5bzc5Qkct1W IVs9SUDg==; 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 1qmJ0F-00FZhi-RW; Fri, 29 Sep 2023 14:18:20 -0500 From: Brendan Shanks To: gcc-patches@gcc.gnu.org Cc: Brendan Shanks Subject: [PATCH] libiberty: Use posix_spawn in pex-unix when available. Date: Fri, 29 Sep 2023 12:16:55 -0700 Message-ID: <20230929191806.27169-1-bshanks@codeweavers.com> X-Mailer: git-send-email 2.41.0 MIME-Version: 1.0 X-Spam-Status: No, score=-11.7 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: 1778400764581575537 X-GMAIL-MSGID: 1778400764581575537 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. 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 | 72 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 77 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..d299852b7de 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,75 @@ 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) +{ + pid_t pid = -1; + posix_spawnattr_t attr; + posix_spawn_file_actions_t actions; + int attr_initialized = 0, actions_initialized = 0; + + #define ERR_ON_FAILURE(ret, func) \ + do { if (ret) { *err = ret; *errmsg = func; goto exit; } else {} } while (0) + + ERR_ON_FAILURE (posix_spawnattr_init (&attr), "posix_spawnattr_init"); + attr_initialized = 1; + + /* Use vfork() on glibc <=2.24. */ +#ifdef POSIX_SPAWN_USEVFORK + ERR_ON_FAILURE (posix_spawnattr_setflags (&attr, POSIX_SPAWN_USEVFORK), "posix_spawnattr_setflags"); +#endif + + ERR_ON_FAILURE (posix_spawn_file_actions_init (&actions), "posix_spawn_file_actions_init"); + actions_initialized = 1; + + if (in != STDIN_FILE_NO) + { + ERR_ON_FAILURE (posix_spawn_file_actions_adddup2 (&actions, in, STDIN_FILE_NO), "posix_spawn_file_actions_adddup2"); + ERR_ON_FAILURE (posix_spawn_file_actions_addclose (&actions, in), "posix_spawn_file_actions_addclose"); + } + if (out != STDOUT_FILE_NO) + { + ERR_ON_FAILURE (posix_spawn_file_actions_adddup2 (&actions, out, STDOUT_FILE_NO), "posix_spawn_file_actions_adddup2"); + ERR_ON_FAILURE (posix_spawn_file_actions_addclose (&actions, out), "posix_spawn_file_actions_addclose"); + } + if (errdes != STDERR_FILE_NO) + { + ERR_ON_FAILURE (posix_spawn_file_actions_adddup2 (&actions, errdes, STDERR_FILE_NO), "posix_spawn_file_actions_adddup2"); + ERR_ON_FAILURE (posix_spawn_file_actions_addclose (&actions, errdes), "posix_spawn_file_actions_addclose"); + } + if (toclose >= 0) + ERR_ON_FAILURE (posix_spawn_file_actions_addclose (&actions, toclose), "posix_spawn_file_actions_addclose"); + if ((flags & PEX_STDERR_TO_STDOUT) != 0) + ERR_ON_FAILURE (posix_spawn_file_actions_adddup2 (&actions, STDOUT_FILE_NO, STDERR_FILE_NO), "posix_spawn_file_actions_adddup2"); + + if ((flags & PEX_SEARCH) != 0) + ERR_ON_FAILURE (posix_spawnp (&pid, executable, &actions, &attr, argv, env ? env : environ), "posix_spawnp"); + else + ERR_ON_FAILURE (posix_spawn (&pid, executable, &actions, &attr, argv, env ? env : environ), "posix_spawn"); + +#undef ERR_ON_FAILURE +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. */