From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTPS id 7695A385841B for ; Mon, 24 Jan 2022 21:52:41 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 7695A385841B Received: from mail-il1-f199.google.com (mail-il1-f199.google.com [209.85.166.199]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-391-G9uGF3j_O4e8eX4pyRtEZQ-1; Mon, 24 Jan 2022 16:52:24 -0500 X-MC-Unique: G9uGF3j_O4e8eX4pyRtEZQ-1 Received: by mail-il1-f199.google.com with SMTP id x6-20020a056e021ca600b002b7e8b542e6so10424086ill.21 for ; Mon, 24 Jan 2022 13:52:24 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:date:mime-version:user-agent:subject :content-language:to:references:from:organization:in-reply-to :content-transfer-encoding; bh=Am/PUgKxGqZogTk9otLZn8yYYknkflLaM0EdV6llT2Q=; b=jqPlQgvOKFs5yS21Zj3Re0eS5fNdA17G7C5FPJYvRPbbv+ynVf/SLXbxv8inTM0biN N93Xo5oXxHomGLYip+QGwj8ZqDZSkmEPoW+NoORU1CoO1mBrZ06xLHAb/J9sx4um0D/y O4GVFD/fHDt3bEhh81YoGTzKwBFSTlj1jx4DhxKKquJRGU2Y8tvxRGhk7O7OTUXsyQvX +N+Xh6Nq5IQaJvQL/ee+ke1yqB5PTZ3haPzVsA1HC2IcoVdSHST54G3WQM/X3GioEoW7 pq2fCQhdh7Z1TkEU226bpF9lH8RPF8scIpZ/RLOf0u6yORryoWazRpJlnpBEVAHbPvC/ 0idQ== X-Gm-Message-State: AOAM533cM73ugWWjYKL0fUM3DqWqsufhBEO8+YqxWixTv6zA7mm9zTDt BX2b7uHtB2UIb3Nv+nAUsPoG7ima04KXItlQPJh8VNy9ejsOC83ui2JdZdvQUVRgCceWlYV2uAb Ux4S0puSTXUevQonlNycU X-Received: by 2002:a05:6638:63b:: with SMTP id h27mr4534303jar.146.1643061142628; Mon, 24 Jan 2022 13:52:22 -0800 (PST) X-Google-Smtp-Source: ABdhPJz5qi68+TceqZCDdwKTy/xn2eqGMIV5smGfHTMZq6uaWRK3Q4SmFwMy5RktiL4+60DWvbHVhQ== X-Received: by 2002:a05:6638:63b:: with SMTP id h27mr4534297jar.146.1643061142166; Mon, 24 Jan 2022 13:52:22 -0800 (PST) Received: from [192.168.0.241] (135-23-175-80.cpe.pppoe.ca. [135.23.175.80]) by smtp.gmail.com with ESMTPSA id u8sm7767205ilk.65.2022.01.24.13.52.21 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 24 Jan 2022 13:52:21 -0800 (PST) Message-ID: Date: Mon, 24 Jan 2022 16:52:20 -0500 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.4.0 Subject: Re: [PATCH v7] posix: Add terminal control setting support for posix_spawn To: Adhemerval Zanella , libc-alpha@sourceware.org References: <20220124181026.835706-1-adhemerval.zanella@linaro.org> From: Carlos O'Donell Organization: Red Hat In-Reply-To: <20220124181026.835706-1-adhemerval.zanella@linaro.org> X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Language: en-US Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-12.1 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, NICE_REPLY_A, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 24 Jan 2022 21:52:46 -0000 On 1/24/22 13:10, Adhemerval Zanella wrote: > Currently there is no proper way to set the controlling terminal through > posix_spawn in race free manner [1]. This forces shell implementations > to keep using fork+exec when launching background process groups, > even when using posix_spawn yields better performance. > > This patch adds a new GNU extension so the creating process can > configure the created process terminal group. This is done with a new > flag, POSIX_SPAWN_TCSETPGROUP, along with two new attribute functions: > posix_spawnattr_tcsetpgrp_np, and posix_spawnattr_tcgetpgrp_np. > The function sets a new attribute, spawn-tcgroupfd, that references to > the controlling terminal. > > The controlling terminal is set after the spawn-pgroup attribute, and > uses the spawn-tcgroupfd along with current creating process group > (so it is composable with POSIX_SPAWN_SETPGROUP). > > To create a process and set the controlling terminal, one can use the > following sequence: > > posix_spawnattr_t attr; > posix_spawnattr_init (&attr); > posix_spawnattr_setflags (&attr, POSIX_SPAWN_TCSETPGROUP); > posix_spawnattr_tcsetpgrp_np (&attr, tcfd); > > If the idea is also to create a new process groups: > > posix_spawnattr_t attr; > posix_spawnattr_init (&attr); > posix_spawnattr_setflags (&attr, POSIX_SPAWN_TCSETPGROUP > | POSIX_SPAWN_SETPGROUP); > posix_spawnattr_tcsetpgrp_np (&attr, tcfd); > posix_spawnattr_setpgroup (&attr, 0); > > The controlling terminal file descriptor is ignored if the new flag is > not set. > > This interface is slight different than the one provided by QNX [2], > which only provides the POSIX_SPAWN_TCSETPGROUP flag. The QNX > documentation does not specify how the controlling terminal is obtained > nor how it iteracts with POSIX_SPAWN_SETPGROUP. Since a glibc > implementation is library based, it is more straightforward and avoid > requires additional file descriptor operations to request the caller > to setup the controlling terminal file descriptor (and it also allows > a bit less error handling by posix_spawn). > > Checked on x86_64-linux-gnu and i686-linux-gnu. OK for glibc 2.35. Tested on x86_64 and i686 without regressions. Reviewed-by: Carlos O'Donell Tested-by: Carlos O'Donell > [1] https://github.com/ksh93/ksh/issues/79 > [2] https://www.qnx.com/developers/docs/7.0.0/index.html#com.qnx.doc.neutrino.lib_ref/topic/p/posix_spawn.html > --- > v7: Fixed copyright years, NEWS, reviewers comments. > v6: Rebased against master and added or1k abilist. > v5: Rebased against master. > v3: Properly added posix/tst-spawn6 on tests. > v4: Rebased against master. > --- > NEWS | 5 + > include/unistd.h | 2 + > posix/Makefile | 4 +- > posix/Versions | 4 + > posix/spawn.h | 16 +- > posix/spawnattr_setflags.c | 3 +- > posix/spawnattr_tcgetpgrp.c | 26 +++ > posix/spawnattr_tcsetpgrp.c | 26 +++ > posix/tst-spawn6.c | 175 ++++++++++++++++++ > sysdeps/mach/hurd/spawni.c | 13 ++ > sysdeps/unix/bsd/tcsetpgrp.c | 4 +- > sysdeps/unix/sysv/linux/aarch64/libc.abilist | 2 + > sysdeps/unix/sysv/linux/alpha/libc.abilist | 2 + > sysdeps/unix/sysv/linux/arc/libc.abilist | 2 + > sysdeps/unix/sysv/linux/arm/be/libc.abilist | 2 + > sysdeps/unix/sysv/linux/arm/le/libc.abilist | 2 + > sysdeps/unix/sysv/linux/csky/libc.abilist | 2 + > sysdeps/unix/sysv/linux/hppa/libc.abilist | 2 + > sysdeps/unix/sysv/linux/i386/libc.abilist | 2 + > sysdeps/unix/sysv/linux/ia64/libc.abilist | 2 + > .../sysv/linux/m68k/coldfire/libc.abilist | 2 + > .../unix/sysv/linux/m68k/m680x0/libc.abilist | 2 + > .../sysv/linux/microblaze/be/libc.abilist | 2 + > .../sysv/linux/microblaze/le/libc.abilist | 2 + > .../sysv/linux/mips/mips32/fpu/libc.abilist | 2 + > .../sysv/linux/mips/mips32/nofpu/libc.abilist | 2 + > .../sysv/linux/mips/mips64/n32/libc.abilist | 2 + > .../sysv/linux/mips/mips64/n64/libc.abilist | 2 + > sysdeps/unix/sysv/linux/nios2/libc.abilist | 2 + > sysdeps/unix/sysv/linux/or1k/libc.abilist | 2 + > .../linux/powerpc/powerpc32/fpu/libc.abilist | 2 + > .../powerpc/powerpc32/nofpu/libc.abilist | 2 + > .../linux/powerpc/powerpc64/be/libc.abilist | 2 + > .../linux/powerpc/powerpc64/le/libc.abilist | 2 + > .../unix/sysv/linux/riscv/rv32/libc.abilist | 2 + > .../unix/sysv/linux/riscv/rv64/libc.abilist | 2 + > .../unix/sysv/linux/s390/s390-32/libc.abilist | 2 + > .../unix/sysv/linux/s390/s390-64/libc.abilist | 2 + > sysdeps/unix/sysv/linux/sh/be/libc.abilist | 2 + > sysdeps/unix/sysv/linux/sh/le/libc.abilist | 2 + > .../sysv/linux/sparc/sparc32/libc.abilist | 2 + > .../sysv/linux/sparc/sparc64/libc.abilist | 2 + > sysdeps/unix/sysv/linux/spawni.c | 11 ++ > .../unix/sysv/linux/x86_64/64/libc.abilist | 2 + > .../unix/sysv/linux/x86_64/x32/libc.abilist | 2 + > termios/tcsetpgrp.c | 5 +- > 46 files changed, 354 insertions(+), 6 deletions(-) > create mode 100644 posix/spawnattr_tcgetpgrp.c > create mode 100644 posix/spawnattr_tcsetpgrp.c > create mode 100644 posix/tst-spawn6.c > > diff --git a/NEWS b/NEWS > index 07e9eac52d..a9f25d3225 100644 > --- a/NEWS > +++ b/NEWS > @@ -129,6 +129,11 @@ Major new features: > * On Linux, the epoll_pwait2 function has been added. It is similar to > epoll_wait with the difference the timeout has nanoseconds resolution. > > +* The functions posix_spawnattr_tcsetpgrp_np and posix_spawnattr_tcgetpgrp_np > + have been added, enabling posix_spawn and posix_spawnp to set the > + controlling terminal in the new process in a race free manner. These > + functions are GNU extensions. > + > Deprecated and removed features, and other changes affecting compatibility: > > * On x86-64, the LD_PREFER_MAP_32BIT_EXEC environment variable support > diff --git a/include/unistd.h b/include/unistd.h > index 2bcdd494e1..7090169601 100644 > --- a/include/unistd.h > +++ b/include/unistd.h > @@ -183,6 +183,8 @@ extern int __truncate (const char *path, __off_t __length); > extern void *__sbrk (intptr_t __delta); > libc_hidden_proto (__sbrk) > > +extern int __tcsetpgrp (int fd, __pid_t pgrp); > +libc_hidden_proto (__tcsetpgrp) OK. Fixes Florian's comment. > > /* This variable is set nonzero at startup if the process's effective > IDs differ from its real IDs, or it is otherwise indicated that > diff --git a/posix/Makefile b/posix/Makefile > index 24d8bfd303..35be22095e 100644 > --- a/posix/Makefile > +++ b/posix/Makefile > @@ -64,6 +64,7 @@ routines := \ > spawnattr_getpgroup spawnattr_setpgroup spawn spawnp spawni \ > spawnattr_getsigmask spawnattr_getschedpolicy spawnattr_getschedparam \ > spawnattr_setsigmask spawnattr_setschedpolicy spawnattr_setschedparam \ > + spawnattr_tcgetpgrp spawnattr_tcsetpgrp \ > posix_madvise \ > get_child_max sched_cpucount sched_cpualloc sched_cpufree \ > streams-compat \ > @@ -108,7 +109,7 @@ tests := test-errno tstgetopt testfnm runtests runptests \ > tst-glob-tilde test-ssize-max tst-spawn4 bug-regex37 \ > bug-regex38 tst-regcomp-truncated tst-spawn-chdir \ > tst-wordexp-nocmd tst-execveat tst-spawn5 \ > - tst-sched_getaffinity > + tst-sched_getaffinity tst-spawn6 > > # Test for the glob symbol version that was replaced in glibc 2.27. > ifeq ($(have-GLIBC_2.26)$(build-shared),yesyes) > @@ -289,6 +290,7 @@ tst-execvpe5-ARGS = -- $(host-test-program-cmd) > tst-spawn-ARGS = -- $(host-test-program-cmd) > tst-spawn-static-ARGS = $(tst-spawn-ARGS) > tst-spawn5-ARGS = -- $(host-test-program-cmd) > +tst-spawn6-ARGS = -- $(host-test-program-cmd) > tst-dir-ARGS = `pwd` `cd $(common-objdir)/$(subdir); pwd` `cd $(common-objdir); pwd` $(objpfx)tst-dir > tst-chmod-ARGS = $(objdir) > tst-vfork3-ARGS = --test-dir=$(objpfx) > diff --git a/posix/Versions b/posix/Versions > index a78792135f..e4f4f649b0 100644 > --- a/posix/Versions > +++ b/posix/Versions > @@ -156,6 +156,10 @@ libc { > execveat; > posix_spawn_file_actions_addclosefrom_np; > } > + GLIBC_2.35 { > + posix_spawnattr_tcgetpgrp_np; > + posix_spawnattr_tcsetpgrp_np; > + } > GLIBC_PRIVATE { > __libc_fork; __libc_pread; __libc_pwrite; > __nanosleep_nocancel; __pause_nocancel; > diff --git a/posix/spawn.h b/posix/spawn.h > index 58f17d1277..7779020250 100644 > --- a/posix/spawn.h > +++ b/posix/spawn.h > @@ -34,7 +34,8 @@ typedef struct > sigset_t __ss; > struct sched_param __sp; > int __policy; > - int __pad[16]; > + int __ctty_fd; > + int __pad[15]; > } posix_spawnattr_t; > > > @@ -59,6 +60,7 @@ typedef struct > #ifdef __USE_GNU > # define POSIX_SPAWN_USEVFORK 0x40 > # define POSIX_SPAWN_SETSID 0x80 > +# define POSIX_SPAWN_TCSETPGROUP 0x100 > #endif > > > @@ -166,6 +168,18 @@ extern int posix_spawnattr_setschedparam (posix_spawnattr_t *__restrict __attr, > __restrict __schedparam) > __THROW __nonnull ((1, 2)); > > +#ifdef __USE_GNU > +/* Make the spawned process the foreground process group on the terminal > + associated with FD (which must be a controlling terminal, and still be > + associated with its session). */ > +extern int posix_spawnattr_tcsetpgrp_np (posix_spawnattr_t *__attr, int fd) > + __THROW __nonnull ((1)); > + > +/* Return the associated terminal FD in the attribute structure. */ > +extern int posix_spawnattr_tcgetpgrp_np (const posix_spawnattr_t * > + __restrict __attr, int *fd) > + __THROW __nonnull ((1, 2)); > +#endif > > /* Initialize data structure for file attribute for `spawn' call. */ > extern int posix_spawn_file_actions_init (posix_spawn_file_actions_t * > diff --git a/posix/spawnattr_setflags.c b/posix/spawnattr_setflags.c > index 3e6fe4ef03..603bfcf911 100644 > --- a/posix/spawnattr_setflags.c > +++ b/posix/spawnattr_setflags.c > @@ -26,7 +26,8 @@ > | POSIX_SPAWN_SETSCHEDPARAM \ > | POSIX_SPAWN_SETSCHEDULER \ > | POSIX_SPAWN_SETSID \ > - | POSIX_SPAWN_USEVFORK) > + | POSIX_SPAWN_USEVFORK \ > + | POSIX_SPAWN_TCSETPGROUP) > > /* Store flags in the attribute structure. */ > int > diff --git a/posix/spawnattr_tcgetpgrp.c b/posix/spawnattr_tcgetpgrp.c > new file mode 100644 > index 0000000000..8db33e4474 > --- /dev/null > +++ b/posix/spawnattr_tcgetpgrp.c > @@ -0,0 +1,26 @@ > +/* Get the controlling terminal option. > + Copyright (C) 2022 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 > + > +int > +posix_spawnattr_tcgetpgrp_np (const posix_spawnattr_t *attr, int *fd) > +{ > + *fd = attr->__ctty_fd; > + return 0; > +} > diff --git a/posix/spawnattr_tcsetpgrp.c b/posix/spawnattr_tcsetpgrp.c > new file mode 100644 > index 0000000000..c3b2ea2718 > --- /dev/null > +++ b/posix/spawnattr_tcsetpgrp.c > @@ -0,0 +1,26 @@ > +/* Set the controlling terminal option. > + Copyright (C) 2022 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 > + > +int > +posix_spawnattr_tcsetpgrp_np (posix_spawnattr_t *attr, int fd) > +{ > + attr->__ctty_fd = fd; > + return 0; > +} > diff --git a/posix/tst-spawn6.c b/posix/tst-spawn6.c > new file mode 100644 > index 0000000000..5f95bd1938 > --- /dev/null > +++ b/posix/tst-spawn6.c > @@ -0,0 +1,175 @@ > +/* Check posix_spawn set controlling terminal extension. > + Copyright (C) 2022 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 > +#include > +#include > +#include > +#include > + > +static int > +handle_restart (const char *argv1) > +{ > + int fd = xopen (_PATH_TTY, O_RDONLY, 0600); > + > + /* If process group is not changed (POSIX_SPAWN_SETPGROUP), then check > + the creating process one, otherwise check against the process group > + itself. */ > + pid_t pgrp; > + if (strcmp (argv1, "setgrpr") != 0) > + TEST_COMPARE (sscanf (argv1, "%d", &pgrp), 1); > + else > + { > + pgrp = getpgrp (); > + /* Check if a new process group was actually created. */ > + pid_t ppid = getppid (); > + pid_t pgid = getpgid (ppid); > + TEST_VERIFY (pgid != pgrp); > + } > + > + TEST_COMPARE (tcgetpgrp (fd), pgrp); > + > + xclose (fd); > + return 0; > +} > + > +static int restart; > +#define CMDLINE_OPTIONS \ > + { "restart", no_argument, &restart, 1 }, > + > +static void > +run_subprogram (int argc, char *argv[], const posix_spawnattr_t *attr, > + int exp_err) > +{ > + short int flags; > + TEST_COMPARE (posix_spawnattr_getflags (attr, &flags), 0); > + bool setpgrp = flags & POSIX_SPAWN_SETPGROUP; > + > + char *spargv[9]; > + char pgrp[INT_STRLEN_BOUND (pid_t)]; > + > + int i = 0; > + for (; i < argc - 1; i++) > + spargv[i] = argv[i + 1]; > + spargv[i++] = (char *) "--direct"; > + spargv[i++] = (char *) "--restart"; > + if (setpgrp) > + spargv[i++] = (char *) "setgrpr"; > + else > + { > + snprintf (pgrp, sizeof pgrp, "%d", getpgrp ()); > + spargv[i++] = pgrp; > + } > + spargv[i] = NULL; > + TEST_VERIFY_EXIT (i < array_length (spargv)); OK. Added extra check. > + > + pid_t pid; > + TEST_COMPARE (posix_spawn (&pid, argv[1], NULL, attr, spargv, environ), > + exp_err); > + if (exp_err != 0) > + return; > + > + int status; > + TEST_COMPARE (xwaitpid (pid, &status, WUNTRACED), pid); > + TEST_VERIFY (WIFEXITED (status)); > + TEST_VERIFY (!WIFSTOPPED (status)); > + TEST_VERIFY (!WIFSIGNALED (status)); > + TEST_COMPARE (WEXITSTATUS (status), 0); > +} > + > +static int > +do_test (int argc, char *argv[]) > +{ > + /* We must have either: > + - four parameters left if called initially: > + + path to ld.so optional > + + "--library-path" optional > + + the library path optional > + + the application name > + - six parameters left if called through re-execution: > + + --setgrpr optional > + */ > + > + if (restart) > + return handle_restart (argv[1]); > + > + int tcfd = xopen (_PATH_TTY, O_RDONLY, 0600); > + > + /* Check getters and setters. */ > + { > + posix_spawnattr_t attr; > + TEST_COMPARE (posix_spawnattr_init (&attr), 0); > + TEST_COMPARE (posix_spawnattr_tcsetpgrp_np (&attr, tcfd), 0); > + > + int fd; > + TEST_COMPARE (posix_spawnattr_tcgetpgrp_np (&attr, &fd), 0); > + TEST_COMPARE (tcfd, fd); > + } > + > + /* Check setting the controlling terminal without changing the group. */ > + { > + posix_spawnattr_t attr; > + TEST_COMPARE (posix_spawnattr_init (&attr), 0); > + TEST_COMPARE (posix_spawnattr_setflags (&attr, POSIX_SPAWN_TCSETPGROUP), > + 0); > + TEST_COMPARE (posix_spawnattr_tcsetpgrp_np (&attr, tcfd), 0); > + > + run_subprogram (argc, argv, &attr, 0); > + } > + > + /* Check setting both the controlling terminal and the create a new process > + group. */ > + { > + posix_spawnattr_t attr; > + TEST_COMPARE (posix_spawnattr_init (&attr), 0); > + TEST_COMPARE (posix_spawnattr_setflags (&attr, POSIX_SPAWN_TCSETPGROUP > + | POSIX_SPAWN_SETPGROUP), > + 0); > + TEST_COMPARE (posix_spawnattr_setpgroup (&attr, 0), 0); > + TEST_COMPARE (posix_spawnattr_tcsetpgrp_np (&attr, tcfd), 0); > + > + run_subprogram (argc, argv, &attr, 0); > + } > + > + /* Trying to set the controlling terminal after a setsid incurs in a ENOTTY > + from tcsetpgrp. */ > + { > + posix_spawnattr_t attr; > + TEST_COMPARE (posix_spawnattr_init (&attr), 0); > + TEST_COMPARE (posix_spawnattr_setflags (&attr, POSIX_SPAWN_TCSETPGROUP > + | POSIX_SPAWN_SETSID), 0); > + TEST_COMPARE (posix_spawnattr_tcsetpgrp_np (&attr, tcfd), 0); > + > + run_subprogram (argc, argv, &attr, ENOTTY); > + } > + > + xclose (tcfd); > + > + return 0; > +} > + > +#define TEST_FUNCTION_ARGV do_test > +#include > diff --git a/sysdeps/mach/hurd/spawni.c b/sysdeps/mach/hurd/spawni.c > index ebf2b5e27f..bccdd013bf 100644 > --- a/sysdeps/mach/hurd/spawni.c > +++ b/sysdeps/mach/hurd/spawni.c > @@ -390,6 +390,19 @@ retry: > if (!err && (flags & POSIX_SPAWN_SETPGROUP) != 0) > err = __proc_setpgrp (proc, new_pid, attrp->__pgrp); > > + /* Set the controlling terminal. */ > + if (!err && (flags & POSIX_SPAWN_TCSETPGROUP) != 0) > + { > + pid_t pgrp; > + /* Check if it is possible to avoid an extra syscall. */ > + if ((attrp->__flags & POSIX_SPAWN_SETPGROUP) != 0 && attrp->__pgrp != 0) > + pgrp = attrp->__pgrp; > + else > + err = __proc_getpgrp (proc, new_pid, &pgrp); > + if (!err) > + err = __tcsetpgrp (attrp->__ctty_fd, pgrp); > + } > + > /* Set the effective user and group IDs. */ > if (!err && (flags & POSIX_SPAWN_RESETIDS) != 0) > { > diff --git a/sysdeps/unix/bsd/tcsetpgrp.c b/sysdeps/unix/bsd/tcsetpgrp.c > index a7c34ae8d5..272f207c3d 100644 > --- a/sysdeps/unix/bsd/tcsetpgrp.c > +++ b/sysdeps/unix/bsd/tcsetpgrp.c > @@ -22,7 +22,9 @@ > > /* Set the foreground process group ID of FD set PGRP_ID. */ > int > -tcsetpgrp (int fd, pid_t pgrp_id) > +__tcsetpgrp (int fd, pid_t pgrp_id) > { > return __ioctl (fd, TIOCSPGRP, &pgrp_id); > } > +weak_alias (__tcsetpgrp, tcsetpgrp) > +libc_hidden_def (__tcsetpgrp) > diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist > index c1a5ee90e6..9dd574d9e2 100644 > --- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist > +++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist > @@ -2615,3 +2615,5 @@ GLIBC_2.34 tss_set F > GLIBC_2.35 __memcmpeq F > GLIBC_2.35 _dl_find_object F > GLIBC_2.35 epoll_pwait2 F > +GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F > +GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F > diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist > index 1a30d0666b..f66704877e 100644 > --- a/sysdeps/unix/sysv/linux/alpha/libc.abilist > +++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist > @@ -2712,6 +2712,8 @@ GLIBC_2.34 tss_set F > GLIBC_2.35 __memcmpeq F > GLIBC_2.35 _dl_find_object F > GLIBC_2.35 epoll_pwait2 F > +GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F > +GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F > GLIBC_2.4 _IO_fprintf F > GLIBC_2.4 _IO_printf F > GLIBC_2.4 _IO_sprintf F > diff --git a/sysdeps/unix/sysv/linux/arc/libc.abilist b/sysdeps/unix/sysv/linux/arc/libc.abilist > index e5dfdab357..97aa3da1ad 100644 > --- a/sysdeps/unix/sysv/linux/arc/libc.abilist > +++ b/sysdeps/unix/sysv/linux/arc/libc.abilist > @@ -2376,3 +2376,5 @@ GLIBC_2.34 tss_set F > GLIBC_2.35 __memcmpeq F > GLIBC_2.35 _dl_find_object F > GLIBC_2.35 epoll_pwait2 F > +GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F > +GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F > diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist > index 4d3fd87278..18f4364856 100644 > --- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist > +++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist > @@ -495,6 +495,8 @@ GLIBC_2.35 __epoll_pwait2_time64 F > GLIBC_2.35 __memcmpeq F > GLIBC_2.35 _dl_find_object F > GLIBC_2.35 epoll_pwait2 F > +GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F > +GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F > GLIBC_2.4 _Exit F > GLIBC_2.4 _IO_2_1_stderr_ D 0xa0 > GLIBC_2.4 _IO_2_1_stdin_ D 0xa0 > diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist > index 009dc9da14..2c12c020b1 100644 > --- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist > +++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist > @@ -492,6 +492,8 @@ GLIBC_2.35 __epoll_pwait2_time64 F > GLIBC_2.35 __memcmpeq F > GLIBC_2.35 _dl_find_object F > GLIBC_2.35 epoll_pwait2 F > +GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F > +GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F > GLIBC_2.4 _Exit F > GLIBC_2.4 _IO_2_1_stderr_ D 0xa0 > GLIBC_2.4 _IO_2_1_stdin_ D 0xa0 > diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist > index df8da506cd..7f28516feb 100644 > --- a/sysdeps/unix/sysv/linux/csky/libc.abilist > +++ b/sysdeps/unix/sysv/linux/csky/libc.abilist > @@ -2651,3 +2651,5 @@ GLIBC_2.35 __epoll_pwait2_time64 F > GLIBC_2.35 __memcmpeq F > GLIBC_2.35 _dl_find_object F > GLIBC_2.35 epoll_pwait2 F > +GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F > +GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F > diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist > index 7ea1b017d0..9776f20763 100644 > --- a/sysdeps/unix/sysv/linux/hppa/libc.abilist > +++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist > @@ -2600,6 +2600,8 @@ GLIBC_2.35 __epoll_pwait2_time64 F > GLIBC_2.35 __memcmpeq F > GLIBC_2.35 _dl_find_object F > GLIBC_2.35 epoll_pwait2 F > +GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F > +GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F > GLIBC_2.4 __confstr_chk F > GLIBC_2.4 __fgets_chk F > GLIBC_2.4 __fgets_unlocked_chk F > diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist > index 99ccf354b3..96b50d0a9b 100644 > --- a/sysdeps/unix/sysv/linux/i386/libc.abilist > +++ b/sysdeps/unix/sysv/linux/i386/libc.abilist > @@ -2784,6 +2784,8 @@ GLIBC_2.35 __epoll_pwait2_time64 F > GLIBC_2.35 __memcmpeq F > GLIBC_2.35 _dl_find_object F > GLIBC_2.35 epoll_pwait2 F > +GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F > +GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F > GLIBC_2.4 __confstr_chk F > GLIBC_2.4 __fgets_chk F > GLIBC_2.4 __fgets_unlocked_chk F > diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist > index 201542d1e7..9b2eebfbf1 100644 > --- a/sysdeps/unix/sysv/linux/ia64/libc.abilist > +++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist > @@ -2550,6 +2550,8 @@ GLIBC_2.34 tss_set F > GLIBC_2.35 __memcmpeq F > GLIBC_2.35 _dl_find_object F > GLIBC_2.35 epoll_pwait2 F > +GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F > +GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F > GLIBC_2.4 __confstr_chk F > GLIBC_2.4 __fgets_chk F > GLIBC_2.4 __fgets_unlocked_chk F > diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist > index 32fd72a78d..71cd35488e 100644 > --- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist > +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist > @@ -496,6 +496,8 @@ GLIBC_2.35 __epoll_pwait2_time64 F > GLIBC_2.35 __memcmpeq F > GLIBC_2.35 _dl_find_object F > GLIBC_2.35 epoll_pwait2 F > +GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F > +GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F > GLIBC_2.4 _Exit F > GLIBC_2.4 _IO_2_1_stderr_ D 0x98 > GLIBC_2.4 _IO_2_1_stdin_ D 0x98 > diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist > index d26f0ae6c2..ced01a501d 100644 > --- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist > +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist > @@ -2727,6 +2727,8 @@ GLIBC_2.35 __epoll_pwait2_time64 F > GLIBC_2.35 __memcmpeq F > GLIBC_2.35 _dl_find_object F > GLIBC_2.35 epoll_pwait2 F > +GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F > +GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F > GLIBC_2.4 __confstr_chk F > GLIBC_2.4 __fgets_chk F > GLIBC_2.4 __fgets_unlocked_chk F > diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist > index 520ca0882d..5406c01f1d 100644 > --- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist > +++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist > @@ -2700,3 +2700,5 @@ GLIBC_2.35 __epoll_pwait2_time64 F > GLIBC_2.35 __memcmpeq F > GLIBC_2.35 _dl_find_object F > GLIBC_2.35 epoll_pwait2 F > +GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F > +GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F > diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist > index 9162c31396..53b8ade4c3 100644 > --- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist > +++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist > @@ -2697,3 +2697,5 @@ GLIBC_2.35 __epoll_pwait2_time64 F > GLIBC_2.35 __memcmpeq F > GLIBC_2.35 _dl_find_object F > GLIBC_2.35 epoll_pwait2 F > +GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F > +GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F > diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist > index 656fdbdcaa..919973ea46 100644 > --- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist > +++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist > @@ -2692,6 +2692,8 @@ GLIBC_2.35 __epoll_pwait2_time64 F > GLIBC_2.35 __memcmpeq F > GLIBC_2.35 _dl_find_object F > GLIBC_2.35 epoll_pwait2 F > +GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F > +GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F > GLIBC_2.4 __confstr_chk F > GLIBC_2.4 __fgets_chk F > GLIBC_2.4 __fgets_unlocked_chk F > diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist > index 5f0b90d318..cf5a8dc120 100644 > --- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist > +++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist > @@ -2690,6 +2690,8 @@ GLIBC_2.35 __epoll_pwait2_time64 F > GLIBC_2.35 __memcmpeq F > GLIBC_2.35 _dl_find_object F > GLIBC_2.35 epoll_pwait2 F > +GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F > +GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F > GLIBC_2.4 __confstr_chk F > GLIBC_2.4 __fgets_chk F > GLIBC_2.4 __fgets_unlocked_chk F > diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist > index 9f4891fc08..003c3bd0a6 100644 > --- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist > +++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist > @@ -2698,6 +2698,8 @@ GLIBC_2.35 __epoll_pwait2_time64 F > GLIBC_2.35 __memcmpeq F > GLIBC_2.35 _dl_find_object F > GLIBC_2.35 epoll_pwait2 F > +GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F > +GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F > GLIBC_2.4 __confstr_chk F > GLIBC_2.4 __fgets_chk F > GLIBC_2.4 __fgets_unlocked_chk F > diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist > index f1b0644bc3..73629c2f21 100644 > --- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist > +++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist > @@ -2601,6 +2601,8 @@ GLIBC_2.34 tss_set F > GLIBC_2.35 __memcmpeq F > GLIBC_2.35 _dl_find_object F > GLIBC_2.35 epoll_pwait2 F > +GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F > +GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F > GLIBC_2.4 __confstr_chk F > GLIBC_2.4 __fgets_chk F > GLIBC_2.4 __fgets_unlocked_chk F > diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist > index 1cf88e38b9..9e8645ebc0 100644 > --- a/sysdeps/unix/sysv/linux/nios2/libc.abilist > +++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist > @@ -2739,3 +2739,5 @@ GLIBC_2.35 __epoll_pwait2_time64 F > GLIBC_2.35 __memcmpeq F > GLIBC_2.35 _dl_find_object F > GLIBC_2.35 epoll_pwait2 F > +GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F > +GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F > diff --git a/sysdeps/unix/sysv/linux/or1k/libc.abilist b/sysdeps/unix/sysv/linux/or1k/libc.abilist > index ac2a8284ce..7ed49ee71e 100644 > --- a/sysdeps/unix/sysv/linux/or1k/libc.abilist > +++ b/sysdeps/unix/sysv/linux/or1k/libc.abilist > @@ -1395,6 +1395,8 @@ GLIBC_2.35 posix_spawnattr_setschedparam F > GLIBC_2.35 posix_spawnattr_setschedpolicy F > GLIBC_2.35 posix_spawnattr_setsigdefault F > GLIBC_2.35 posix_spawnattr_setsigmask F > +GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F > +GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F > GLIBC_2.35 posix_spawnp F > GLIBC_2.35 ppoll F > GLIBC_2.35 prctl F > diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist > index 9692335d10..3d1ba9887c 100644 > --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist > +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist > @@ -2754,6 +2754,8 @@ GLIBC_2.35 __epoll_pwait2_time64 F > GLIBC_2.35 __memcmpeq F > GLIBC_2.35 _dl_find_object F > GLIBC_2.35 epoll_pwait2 F > +GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F > +GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F > GLIBC_2.4 _IO_fprintf F > GLIBC_2.4 _IO_printf F > GLIBC_2.4 _IO_sprintf F > diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist > index 7da0ed59f2..d979a3b93b 100644 > --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist > +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist > @@ -2787,6 +2787,8 @@ GLIBC_2.35 __epoll_pwait2_time64 F > GLIBC_2.35 __memcmpeq F > GLIBC_2.35 _dl_find_object F > GLIBC_2.35 epoll_pwait2 F > +GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F > +GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F > GLIBC_2.4 _IO_fprintf F > GLIBC_2.4 _IO_printf F > GLIBC_2.4 _IO_sprintf F > diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist > index 72cf685198..44688e52cf 100644 > --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist > +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist > @@ -2509,6 +2509,8 @@ GLIBC_2.34 tss_set F > GLIBC_2.35 __memcmpeq F > GLIBC_2.35 _dl_find_object F > GLIBC_2.35 epoll_pwait2 F > +GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F > +GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F > GLIBC_2.4 _IO_fprintf F > GLIBC_2.4 _IO_printf F > GLIBC_2.4 _IO_sprintf F > diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist > index ee7f67f4d0..40682711eb 100644 > --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist > +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist > @@ -2811,3 +2811,5 @@ GLIBC_2.34 tss_set F > GLIBC_2.35 __memcmpeq F > GLIBC_2.35 _dl_find_object F > GLIBC_2.35 epoll_pwait2 F > +GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F > +GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F > diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist > index b8c0854508..e239d626b3 100644 > --- a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist > +++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist > @@ -2378,3 +2378,5 @@ GLIBC_2.34 tss_set F > GLIBC_2.35 __memcmpeq F > GLIBC_2.35 _dl_find_object F > GLIBC_2.35 epoll_pwait2 F > +GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F > +GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F > diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist > index 90f331fc0b..ab0c4e7092 100644 > --- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist > +++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist > @@ -2578,3 +2578,5 @@ GLIBC_2.34 tss_set F > GLIBC_2.35 __memcmpeq F > GLIBC_2.35 _dl_find_object F > GLIBC_2.35 epoll_pwait2 F > +GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F > +GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F > diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist > index ded5e3c0ce..74e3a4651f 100644 > --- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist > +++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist > @@ -2752,6 +2752,8 @@ GLIBC_2.35 __epoll_pwait2_time64 F > GLIBC_2.35 __memcmpeq F > GLIBC_2.35 _dl_find_object F > GLIBC_2.35 epoll_pwait2 F > +GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F > +GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F > GLIBC_2.4 _IO_fprintf F > GLIBC_2.4 _IO_printf F > GLIBC_2.4 _IO_sprintf F > diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist > index 4b26299254..e5553f06b2 100644 > --- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist > +++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist > @@ -2546,6 +2546,8 @@ GLIBC_2.34 tss_set F > GLIBC_2.35 __memcmpeq F > GLIBC_2.35 _dl_find_object F > GLIBC_2.35 epoll_pwait2 F > +GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F > +GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F > GLIBC_2.4 _IO_fprintf F > GLIBC_2.4 _IO_printf F > GLIBC_2.4 _IO_sprintf F > diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist > index 8bfd716fd2..9662041cd4 100644 > --- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist > +++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist > @@ -2607,6 +2607,8 @@ GLIBC_2.35 __epoll_pwait2_time64 F > GLIBC_2.35 __memcmpeq F > GLIBC_2.35 _dl_find_object F > GLIBC_2.35 epoll_pwait2 F > +GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F > +GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F > GLIBC_2.4 __confstr_chk F > GLIBC_2.4 __fgets_chk F > GLIBC_2.4 __fgets_unlocked_chk F > diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist > index 47fd204d84..bf90e924a6 100644 > --- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist > +++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist > @@ -2604,6 +2604,8 @@ GLIBC_2.35 __epoll_pwait2_time64 F > GLIBC_2.35 __memcmpeq F > GLIBC_2.35 _dl_find_object F > GLIBC_2.35 epoll_pwait2 F > +GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F > +GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F > GLIBC_2.4 __confstr_chk F > GLIBC_2.4 __fgets_chk F > GLIBC_2.4 __fgets_unlocked_chk F > diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist > index 9b82f15109..ddb0d0621f 100644 > --- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist > +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist > @@ -2747,6 +2747,8 @@ GLIBC_2.35 __epoll_pwait2_time64 F > GLIBC_2.35 __memcmpeq F > GLIBC_2.35 _dl_find_object F > GLIBC_2.35 epoll_pwait2 F > +GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F > +GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F > GLIBC_2.4 _IO_fprintf F > GLIBC_2.4 _IO_printf F > GLIBC_2.4 _IO_sprintf F > diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist > index 94caf012a7..ca14224cb7 100644 > --- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist > +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist > @@ -2573,6 +2573,8 @@ GLIBC_2.34 tss_set F > GLIBC_2.35 __memcmpeq F > GLIBC_2.35 _dl_find_object F > GLIBC_2.35 epoll_pwait2 F > +GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F > +GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F > GLIBC_2.4 __confstr_chk F > GLIBC_2.4 __fgets_chk F > GLIBC_2.4 __fgets_unlocked_chk F > diff --git a/sysdeps/unix/sysv/linux/spawni.c b/sysdeps/unix/sysv/linux/spawni.c > index 4c2d4195cd..93359c708b 100644 > --- a/sysdeps/unix/sysv/linux/spawni.c > +++ b/sysdeps/unix/sysv/linux/spawni.c > @@ -164,6 +164,17 @@ __spawni_child (void *arguments) > && __setpgid (0, attr->__pgrp) != 0) > goto fail; > > + /* Set the controlling terminal. */ > + if ((attr->__flags & POSIX_SPAWN_TCSETPGROUP) != 0) > + { > + /* Check if it is possible to avoid an extra syscall. */ > + pid_t pgrp = (attr->__flags & POSIX_SPAWN_SETPGROUP) != 0 > + && attr->__pgrp != 0 > + ? attr->__pgrp : __getpgid (0); > + if (__tcsetpgrp (attr->__ctty_fd, pgrp) != 0) > + goto fail; > + } > + > /* Set the effective user and group IDs. */ > if ((attr->__flags & POSIX_SPAWN_RESETIDS) != 0 > && (local_seteuid (__getuid ()) != 0 > diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist > index 140e9e8c1c..661d928adf 100644 > --- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist > +++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist > @@ -2524,6 +2524,8 @@ GLIBC_2.34 tss_set F > GLIBC_2.35 __memcmpeq F > GLIBC_2.35 _dl_find_object F > GLIBC_2.35 epoll_pwait2 F > +GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F > +GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F > GLIBC_2.4 __confstr_chk F > GLIBC_2.4 __fgets_chk F > GLIBC_2.4 __fgets_unlocked_chk F > diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist > index 04d13ce27e..bb8058dfa4 100644 > --- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist > +++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist > @@ -2630,3 +2630,5 @@ GLIBC_2.34 tss_set F > GLIBC_2.35 __memcmpeq F > GLIBC_2.35 _dl_find_object F > GLIBC_2.35 epoll_pwait2 F > +GLIBC_2.35 posix_spawnattr_tcgetpgrp_np F > +GLIBC_2.35 posix_spawnattr_tcsetpgrp_np F > diff --git a/termios/tcsetpgrp.c b/termios/tcsetpgrp.c > index 581328b12a..1e4ff0987d 100644 > --- a/termios/tcsetpgrp.c > +++ b/termios/tcsetpgrp.c > @@ -21,7 +21,7 @@ > > /* Set the foreground process group ID of FD set PGRP_ID. */ > int > -tcsetpgrp (int fd, pid_t pgrp_id) > +__tcsetpgrp (int fd, pid_t pgrp_id) > { > if (fd < 0) > { > @@ -32,6 +32,7 @@ tcsetpgrp (int fd, pid_t pgrp_id) > __set_errno (ENOSYS); > return -1; > } > - > +weak_alias (__tcsetpgrp, tcsetpgrp); > +libc_hidden_def (__tcsetpgrp) > > stub_warning (tcsetpgrp) -- Cheers, Carlos.