From 7e03fc35f528c7776dac0b4dc0b6814ca012986b Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Tue, 18 Apr 2023 23:47:28 +0200 Subject: Add posix_spawn_file_actions_add{f}chdir_np MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These are defined as _np functions and available in glibc, musl, macOS, FreeBSD, Solaris ≥ 11.3 They are likely to be standardized without the _np suffix as a result of Austin Group issue 1208. if so, both names will be kept as aliases. Introduce HAVE_CHDIR and HAVE_FCHDIR to allow building on systems not providing these calls. Signed-off-by: Corinna Vinschen --- newlib/libc/posix/posix_spawn.c | 89 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 87 insertions(+), 2 deletions(-) (limited to 'newlib/libc/posix') diff --git a/newlib/libc/posix/posix_spawn.c b/newlib/libc/posix/posix_spawn.c index 85bfa64..3506b0f 100644 --- a/newlib/libc/posix/posix_spawn.c +++ b/newlib/libc/posix/posix_spawn.c @@ -123,7 +123,13 @@ struct __posix_spawn_file_actions { typedef struct __posix_spawn_file_actions_entry { STAILQ_ENTRY(__posix_spawn_file_actions_entry) fae_list; - enum { FAE_OPEN, FAE_DUP2, FAE_CLOSE } fae_action; + enum { + FAE_OPEN, + FAE_DUP2, + FAE_CLOSE, + FAE_CHDIR, + FAE_FCHDIR + } fae_action; int fae_fildes; union { @@ -139,6 +145,10 @@ typedef struct __posix_spawn_file_actions_entry { int newfildes; #define fae_newfildes fae_data.dup2.newfildes } dup2; + char *dir; +#define fae_dir fae_data.dir + int dirfd; +#define fae_dirfd fae_data.dirfd } fae_data; } posix_spawn_file_actions_entry_t; @@ -235,7 +245,21 @@ process_file_actions_entry(posix_spawn_file_actions_entry_t *fae) /* Perform a close(), do not fail if already closed */ (void)_close(fae->fae_fildes); break; +#ifdef HAVE_CHDIR + case FAE_CHDIR: + /* Perform a chdir. */ + if (chdir (fae->fae_dir) == -1) + return (errno); + break; +#endif +#ifdef HAVE_FCHDIR + case FAE_FCHDIR: + /* Perform a chdir. */ + if (fchdir (fae->fae_dirfd) == -1) + return (errno); + break; } +#endif return (0); } @@ -407,8 +431,18 @@ posix_spawn_file_actions_destroy (posix_spawn_file_actions_t *fa) STAILQ_REMOVE_HEAD(&(*fa)->fa_list, fae_list); /* Deallocate file action entry */ - if (fae->fae_action == FAE_OPEN) + switch (fae->fae_action) { + case FAE_OPEN: free(fae->fae_path); + break; +#ifdef HAVE_CHDIR + case FAE_CHDIR: + free(fae->fae_dir); + break; +#endif + default: + break; + } free(fae); } @@ -496,6 +530,57 @@ posix_spawn_file_actions_addclose (posix_spawn_file_actions_t *fa, return (0); } +#ifdef HAVE_CHDIR +int +posix_spawn_file_actions_addchdir_np ( + posix_spawn_file_actions_t * __restrict fa, + const char * __restrict path) +{ + posix_spawn_file_actions_entry_t *fae; + int error; + + /* Allocate object */ + fae = malloc(sizeof(posix_spawn_file_actions_entry_t)); + if (fae == NULL) + return (errno); + + /* Set values and store in queue */ + fae->fae_action = FAE_CHDIR; + fae->fae_dir = strdup(path); + if (fae->fae_dir == NULL) { + error = errno; + free(fae); + return (error); + } + + STAILQ_INSERT_TAIL(&(*fa)->fa_list, fae, fae_list); + return (0); +} +#endif + +#ifdef HAVE_FCHDIR +int +posix_spawn_file_actions_addfchdir_np ( + posix_spawn_file_actions_t * __restrict fa, + int fd) +{ + posix_spawn_file_actions_entry_t *fae; + int error; + + /* Allocate object */ + fae = malloc(sizeof(posix_spawn_file_actions_entry_t)); + if (fae == NULL) + return (errno); + + /* Set values and store in queue */ + fae->fae_action = FAE_FCHDIR; + fae->fae_dirfd = fd; + + STAILQ_INSERT_TAIL(&(*fa)->fa_list, fae, fae_list); + return (0); +} +#endif + /* * Spawn attributes */ -- cgit v1.1