From patchwork Mon Mar 30 08:18:39 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lucas Chollet X-Patchwork-Id: 132437 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from vm01.sourceware.org (localhost [127.0.0.1]) by sourceware.org (Postfix) with ESMTP id 00F8A4B920C4 for ; Mon, 30 Mar 2026 08:20:10 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 00F8A4B920C4 Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=free.fr header.i=@free.fr header.a=rsa-sha256 header.s=smtp-20201208 header.b=bh0u1RjS X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from smtp5-g21.free.fr (smtp5-g21.free.fr [IPv6:2a01:e0c:1:1599::14]) by sourceware.org (Postfix) with ESMTPS id 66AEE4BA2E3E for ; Mon, 30 Mar 2026 08:18:55 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 66AEE4BA2E3E Authentication-Results: sourceware.org; dmarc=pass (p=quarantine dis=none) header.from=free.fr Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=free.fr ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 66AEE4BA2E3E Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2a01:e0c:1:1599::14 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1774858735; cv=none; b=sg5XHferf1ZqqWJXKgoNXogenOg9nSQ7Tis30UlVwfwePCHwjCJZZz2n4GZpRVibdJB5o67vjR9vGMxWss0JrviZ70RRbo0Nr61MWBiK65IokIQDnl9+5iuzbw3WD9+FBNe2mhVbjKZB8TZzi5e7Q4goAYzgtfd1vxi/Nfr364s= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1774858735; c=relaxed/simple; bh=BRWmO1/TaSunW+1XZx07L855iXiV/MeIfd/gRZvpXY4=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=twBqcxgM4+35XGd9AWM3TVuOK0Bn17AJULpumz9e9J7h79DZQL1976x0DrgkmrJ+f30BxLpTZMBv2zjTtlQNjAPWljlKR355vIHG2sIfzUwJg9fLCoH8GU2K3ur8JVFCjGiXzZkjXvAkyvROE6HTVIWLjV/2bzQ+oYLU6yk3AeA= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 66AEE4BA2E3E Received: from itxub.fritz.box (unknown [84.254.90.136]) (Authenticated sender: lucas.chollet@free.fr) by smtp5-g21.free.fr (Postfix) with ESMTPSA id EE5A960141; Mon, 30 Mar 2026 10:18:51 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=free.fr; s=smtp-20201208; t=1774858734; bh=BRWmO1/TaSunW+1XZx07L855iXiV/MeIfd/gRZvpXY4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=bh0u1RjSW+miHo8yUtkZTtNs3m+vPDRe6Y8/2QCqHD2LwRlLtU3CM0NA8TYa11u88 xabK4yJwsS2OauxUBgZBorVWpvgJtnCTKvR9WPHoRCj1IXyGY5YABovShBJGD0ygA/ mKvTaUATSa/Q+f3CzQBb76QMpnnjLW11skggpBBac5D5huyoV+EKFIxtXHFXAq7JKe sdwxs/fFZoPdgMgh8MKvP5z5Y+ES4Zu7gUkDnWXarM+u9YwkWmHSd5NQLrzBEA/XaZ zvQkkTlBJXQZ30TiQm1DLw44tJcZhzq9XKTgGjbOM+8TCdW15Cia5nDorycglzVvHk LqV91QTHrzvcA== From: Lucas Chollet To: libc-alpha@sourceware.org Cc: Lucas Chollet Subject: [PATCH 1/1] posix: Add POSIX aliases to some spawn functions Date: Mon, 30 Mar 2026 10:18:39 +0200 Message-ID: <20260330081840.878377-2-lucas.chollet@free.fr> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20260330081840.878377-1-lucas.chollet@free.fr> References: <20260330081840.878377-1-lucas.chollet@free.fr> MIME-Version: 1.0 X-Spam-Status: No, score=-11.9 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_DNSWL_BLOCKED, 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 sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libc-alpha-bounces~patchwork=sourceware.org@sourceware.org Both `posix_spawn_file_actions_add{,f}chdir` functions are now fully defined by POSIX-2024, this patch adds both functions as aliases of the already existing `posix_spawn_file_actions_add{,f}chdir_np` GNU extensions. This makes glibc more compliant in regards to POSIX-2024. Signed-off-by: Lucas Chollet --- conform/data/spawn.h-data | 4 + posix/Versions | 4 + posix/spawn.h | 20 ++ posix/spawn_faction_addchdir.c | 3 + posix/spawn_faction_addfchdir.c | 3 + posix/tst-spawn-chdir.c | 222 ++++++++++-------- .../unix/sysv/linux/x86_64/64/libc.abilist | 2 + 7 files changed, 154 insertions(+), 104 deletions(-) diff --git a/conform/data/spawn.h-data b/conform/data/spawn.h-data index 43aa9cb8ae..1f332324c2 100644 --- a/conform/data/spawn.h-data +++ b/conform/data/spawn.h-data @@ -29,6 +29,10 @@ function int posix_spawnattr_setpgroup (posix_spawnattr_t*, pid_t) function int posix_spawnattr_setschedparam (posix_spawnattr_t*, const struct sched_param*) function int posix_spawnattr_setschedpolicy (posix_spawnattr_t*, int) function int posix_spawnattr_setsigmask (posix_spawnattr_t*, const sigset_t*) +#if defined XOPEN2K24 || defined POSIX2024 +function int posix_spawn_file_actions_addchdir (posix_spawn_file_actions_t*, const char *) +function int posix_spawn_file_actions_addfchdir (posix_spawn_file_actions_t*, int) +#endif function int posix_spawn_file_actions_addclose (posix_spawn_file_actions_t*, int) function int posix_spawn_file_actions_adddup2 (posix_spawn_file_actions_t*, int, int) function int posix_spawn_file_actions_addopen (posix_spawn_file_actions_t*, int, const char *, int, mode_t) diff --git a/posix/Versions b/posix/Versions index 0624d24bcc..3c15dbb50c 100644 --- a/posix/Versions +++ b/posix/Versions @@ -159,6 +159,10 @@ libc { GLIBC_2.35 { posix_spawn_file_actions_addtcsetpgrp_np; } + GLIBC_2.44 { + posix_spawn_file_actions_addchdir; + posix_spawn_file_actions_addfchdir; + } GLIBC_PRIVATE { __libc_fork; __libc_pread; __libc_pwrite; __nanosleep_nocancel; __pause_nocancel; diff --git a/posix/spawn.h b/posix/spawn.h index 5e68752a66..1fc300ed13 100644 --- a/posix/spawn.h +++ b/posix/spawn.h @@ -200,6 +200,26 @@ extern int posix_spawn_file_actions_adddup2 (posix_spawn_file_actions_t * int __fd, int __newfd) __THROW __nonnull ((1)); +#ifdef __USE_XOPEN2K24XSI + +/* Add an action changing the directory to PATH during spawn. This + affects the subsequent file actions. + Alias of posix_spawn_file_actions_addchdir_np. */ +extern int posix_spawn_file_actions_addchdir (posix_spawn_file_actions_t * + __restrict __actions, + const char *__restrict __path) + __THROW __nonnull ((1, 2)); + +/* Add an action changing the directory to FD during spawn. This + affects the subsequent file actions. FD is not duplicated and must + be open when the file action is executed. + Alias of posix_spawn_file_actions_addfchdir_np. */ +extern int posix_spawn_file_actions_addfchdir (posix_spawn_file_actions_t *, + int __fd) + __THROW __nonnull ((1)); + +#endif /* __USE_XOPEN2K24XSI */ + #ifdef __USE_MISC /* Add an action changing the directory to PATH during spawn. This affects the subsequent file actions. */ diff --git a/posix/spawn_faction_addchdir.c b/posix/spawn_faction_addchdir.c index 02f8ce27ee..dadb8a27e0 100644 --- a/posix/spawn_faction_addchdir.c +++ b/posix/spawn_faction_addchdir.c @@ -51,3 +51,6 @@ posix_spawn_file_actions_addchdir_np (posix_spawn_file_actions_t *file_actions, return 0; } + +strong_alias (posix_spawn_file_actions_addchdir_np, + posix_spawn_file_actions_addchdir) diff --git a/posix/spawn_faction_addfchdir.c b/posix/spawn_faction_addfchdir.c index a3df6df489..7056993d62 100644 --- a/posix/spawn_faction_addfchdir.c +++ b/posix/spawn_faction_addfchdir.c @@ -44,3 +44,6 @@ posix_spawn_file_actions_addfchdir_np (posix_spawn_file_actions_t *actions, return 0; } + +strong_alias (posix_spawn_file_actions_addfchdir_np, + posix_spawn_file_actions_addfchdir) diff --git a/posix/tst-spawn-chdir.c b/posix/tst-spawn-chdir.c index a3478d61f6..c85465c973 100644 --- a/posix/tst-spawn-chdir.c +++ b/posix/tst-spawn-chdir.c @@ -72,18 +72,31 @@ get_pwd_program (void) the open function and TMPFD to emulate chdir using fchdir. */ static void add_chdir (posix_spawn_file_actions_t *actions, const char *path, - bool do_fchdir, int tmpfd) + bool do_fchdir, bool do_posix, int tmpfd) { if (do_fchdir) { TEST_COMPARE (posix_spawn_file_actions_addopen (actions, tmpfd, path, O_DIRECTORY | O_RDONLY, 0), 0); - TEST_COMPARE (posix_spawn_file_actions_addfchdir_np - (actions, tmpfd), 0); + if (do_posix) + { + TEST_COMPARE (posix_spawn_file_actions_addfchdir + (actions, tmpfd), 0); + } + else + { + TEST_COMPARE (posix_spawn_file_actions_addfchdir_np + (actions, tmpfd), 0); + } TEST_COMPARE (posix_spawn_file_actions_addclose (actions, tmpfd), 0); } else - TEST_COMPARE (posix_spawn_file_actions_addchdir_np (actions, path), 0); + { + if (do_posix) + TEST_COMPARE (posix_spawn_file_actions_addchdir (actions, path), 0); + else + TEST_COMPARE (posix_spawn_file_actions_addchdir_np (actions, path), 0); + } } static int @@ -110,109 +123,110 @@ do_test (void) for (int do_spawnp = 0; do_spawnp < 2; ++do_spawnp) for (int do_overwrite = 0; do_overwrite < 2; ++do_overwrite) for (int do_fchdir = 0; do_fchdir < 2; ++do_fchdir) - { - /* This subtest does not make sense for fchdir. */ - if (do_overwrite && do_fchdir) - continue; - - ++iteration; - if (test_verbose > 0) - printf ("info: iteration=%d do_spawnp=%d do_overwrite=%d" - " do_fchdir=%d\n", - iteration, do_spawnp, do_overwrite, do_fchdir); - - /* The "pwd" program runs in this directory. */ - char *iteration_directory = xasprintf ("%s/%d", directory, iteration); - add_temp_file (iteration_directory); - xmkdir (iteration_directory, 0777); - - /* This file receives output from "pwd". */ - char *output_file_path - = xasprintf ("%s/output-file", iteration_directory); - add_temp_file (output_file_path); - - /* This subdirectory is used for chdir ordering checks. */ - char *subdir_path = xasprintf ("%s/subdir", iteration_directory); - add_temp_file (subdir_path); - xmkdir (subdir_path, 0777); - - /* Also used for checking the order of actions. */ - char *probe_file_path - = xasprintf ("%s/subdir/probe-file", iteration_directory); - add_temp_file (probe_file_path); - TEST_COMPARE (access (probe_file_path, F_OK), -1); - TEST_COMPARE (errno, ENOENT); - - /* This symbolic link is used in a relative path with - posix_spawn. */ - char *pwd_symlink_path - = xasprintf ("%s/subdir/pwd-symlink", iteration_directory); - xsymlink (get_pwd_program (), pwd_symlink_path); - add_temp_file (pwd_symlink_path); - - posix_spawn_file_actions_t actions; - TEST_COMPARE (posix_spawn_file_actions_init (&actions), 0); - add_chdir (&actions, subdir_path, do_fchdir, 4); - TEST_COMPARE (posix_spawn_file_actions_addopen - (&actions, 3, /* Arbitrary unused descriptor. */ - "probe-file", - O_WRONLY | O_CREAT | O_EXCL, 0666), 0); - TEST_COMPARE (posix_spawn_file_actions_addclose (&actions, 3), 0); - /* Run the actual in iteration_directory. */ - add_chdir (&actions, "..", do_fchdir, 5); - TEST_COMPARE (posix_spawn_file_actions_addopen - (&actions, STDOUT_FILENO, "output-file", - O_WRONLY | O_CREAT | O_EXCL, 0666), 0); - - /* Check that posix_spawn_file_actions_addchdir_np made a copy - of the path. */ - if (do_overwrite) - subdir_path[0] = '\0'; - - char *const argv[] = { (char *) "pwd", NULL }; - char *const envp[] = { NULL } ; - PID_T_TYPE pid; - if (do_spawnp) - TEST_COMPARE (POSIX_SPAWNP (&pid, "pwd", &actions, - NULL, argv, envp), 0); - else - TEST_COMPARE (POSIX_SPAWN (&pid, "subdir/pwd-symlink", &actions, - NULL, argv, envp), 0); - TEST_VERIFY (pid > 0); - siginfo_t sinfo; - TEST_COMPARE (WAITID (P_ALL, 0, &sinfo, WEXITED), 0); - TEST_COMPARE (sinfo.si_code, CLD_EXITED); - TEST_COMPARE (sinfo.si_status, 0); - - /* Check that the current directory did not change. */ - { - char *cwd = get_current_dir_name (); - if (cwd == NULL) - FAIL_EXIT1 ("get_current_dir_name: %m"); - TEST_COMPARE_BLOB (original_cwd, strlen (original_cwd), - cwd, strlen (cwd)); - free (cwd); - } - - - /* Check the output from "pwd". */ + for (int do_posix = 0; do_posix < 2; ++do_posix) { - char *pwd = read_one_line (output_file_path); - TEST_COMPARE_BLOB (iteration_directory, strlen (iteration_directory), - pwd, strlen (pwd)); - free (pwd); + /* This subtest does not make sense for fchdir. */ + if (do_overwrite && do_fchdir) + continue; + + ++iteration; + if (test_verbose > 0) + printf ("info: iteration=%d do_spawnp=%d do_overwrite=%d" + " do_fchdir=%d do_posix=%d\n", + iteration, do_spawnp, do_overwrite, do_fchdir, do_posix); + + /* The "pwd" program runs in this directory. */ + char *iteration_directory = xasprintf ("%s/%d", directory, iteration); + add_temp_file (iteration_directory); + xmkdir (iteration_directory, 0777); + + /* This file receives output from "pwd". */ + char *output_file_path + = xasprintf ("%s/output-file", iteration_directory); + add_temp_file (output_file_path); + + /* This subdirectory is used for chdir ordering checks. */ + char *subdir_path = xasprintf ("%s/subdir", iteration_directory); + add_temp_file (subdir_path); + xmkdir (subdir_path, 0777); + + /* Also used for checking the order of actions. */ + char *probe_file_path + = xasprintf ("%s/subdir/probe-file", iteration_directory); + add_temp_file (probe_file_path); + TEST_COMPARE (access (probe_file_path, F_OK), -1); + TEST_COMPARE (errno, ENOENT); + + /* This symbolic link is used in a relative path with + posix_spawn. */ + char *pwd_symlink_path + = xasprintf ("%s/subdir/pwd-symlink", iteration_directory); + xsymlink (get_pwd_program (), pwd_symlink_path); + add_temp_file (pwd_symlink_path); + + posix_spawn_file_actions_t actions; + TEST_COMPARE (posix_spawn_file_actions_init (&actions), 0); + add_chdir (&actions, subdir_path, do_fchdir, do_posix, 4); + TEST_COMPARE (posix_spawn_file_actions_addopen + (&actions, 3, /* Arbitrary unused descriptor. */ + "probe-file", + O_WRONLY | O_CREAT | O_EXCL, 0666), 0); + TEST_COMPARE (posix_spawn_file_actions_addclose (&actions, 3), 0); + /* Run the actual in iteration_directory. */ + add_chdir (&actions, "..", do_fchdir, do_posix, 5); + TEST_COMPARE (posix_spawn_file_actions_addopen + (&actions, STDOUT_FILENO, "output-file", + O_WRONLY | O_CREAT | O_EXCL, 0666), 0); + + /* Check that posix_spawn_file_actions_addchdir_np made a copy + of the path. */ + if (do_overwrite) + subdir_path[0] = '\0'; + + char *const argv[] = { (char *) "pwd", NULL }; + char *const envp[] = { NULL } ; + PID_T_TYPE pid; + if (do_spawnp) + TEST_COMPARE (POSIX_SPAWNP (&pid, "pwd", &actions, + NULL, argv, envp), 0); + else + TEST_COMPARE (POSIX_SPAWN (&pid, "subdir/pwd-symlink", &actions, + NULL, argv, envp), 0); + TEST_VERIFY (pid > 0); + siginfo_t sinfo; + TEST_COMPARE (WAITID (P_ALL, 0, &sinfo, WEXITED), 0); + TEST_COMPARE (sinfo.si_code, CLD_EXITED); + TEST_COMPARE (sinfo.si_status, 0); + + /* Check that the current directory did not change. */ + { + char *cwd = get_current_dir_name (); + if (cwd == NULL) + FAIL_EXIT1 ("get_current_dir_name: %m"); + TEST_COMPARE_BLOB (original_cwd, strlen (original_cwd), + cwd, strlen (cwd)); + free (cwd); + } + + + /* Check the output from "pwd". */ + { + char *pwd = read_one_line (output_file_path); + TEST_COMPARE_BLOB (iteration_directory, strlen (iteration_directory), + pwd, strlen (pwd)); + free (pwd); + } + + /* This file must now exist. */ + TEST_COMPARE (access (probe_file_path, F_OK), 0); + + TEST_COMPARE (posix_spawn_file_actions_destroy (&actions), 0); + free (pwd_symlink_path); + free (probe_file_path); + free (subdir_path); + free (output_file_path); } - /* This file must now exist. */ - TEST_COMPARE (access (probe_file_path, F_OK), 0); - - TEST_COMPARE (posix_spawn_file_actions_destroy (&actions), 0); - free (pwd_symlink_path); - free (probe_file_path); - free (subdir_path); - free (output_file_path); - } - free (directory); return 0; diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist index 306cd627fd..3c42d9526d 100644 --- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist @@ -2771,6 +2771,8 @@ GLIBC_2.43 memset_explicit F GLIBC_2.43 mseal F GLIBC_2.43 openat2 F GLIBC_2.43 umaxabs F +GLIBC_2.44 posix_spawn_file_actions_addchdir F +GLIBC_2.44 posix_spawn_file_actions_addfchdir F GLIBC_2.5 __readlinkat_chk F GLIBC_2.5 inet6_opt_append F GLIBC_2.5 inet6_opt_find F