Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2023-04-19 00:47:28 +0300
committerCorinna Vinschen <corinna@vinschen.de>2023-04-19 00:47:28 +0300
commit7e03fc35f528c7776dac0b4dc0b6814ca012986b (patch)
treec7585083c8d34559b8f8fb5ec8125afa06d6a996
parentd30a5917a9c40aec18c2243dfc2848c616dca77a (diff)
Add posix_spawn_file_actions_add{f}chdir_np
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 <corinna@vinschen.de>
-rw-r--r--newlib/configure.host2
-rw-r--r--newlib/libc/include/spawn.h7
-rw-r--r--newlib/libc/posix/posix_spawn.c89
3 files changed, 95 insertions, 3 deletions
diff --git a/newlib/configure.host b/newlib/configure.host
index 0a1ba282a..5f427526d 100644
--- a/newlib/configure.host
+++ b/newlib/configure.host
@@ -587,7 +587,7 @@ case "${host}" in
default_newlib_io_long_double="yes"
default_newlib_io_pos_args="yes"
CC="${CC} -I${cygwin_srcdir}/include"
- newlib_cflags="${newlib_cflags} -DHAVE_OPENDIR -DHAVE_RENAME -DGETREENT_PROVIDED -DSIGNAL_PROVIDED -DHAVE_BLKSIZE -DHAVE_FCNTL -DMALLOC_PROVIDED"
+ newlib_cflags="${newlib_cflags} -DHAVE_OPENDIR -DHAVE_RENAME -DGETREENT_PROVIDED -DSIGNAL_PROVIDED -DHAVE_BLKSIZE -DHAVE_FCNTL -DMALLOC_PROVIDED -DHAVE_CHDIR -DHAVE_FCHDIR"
syscall_dir=syscalls
;;
# RTEMS supplies its own versions of some routines:
diff --git a/newlib/libc/include/spawn.h b/newlib/libc/include/spawn.h
index d172177b1..d6ae992db 100644
--- a/newlib/libc/include/spawn.h
+++ b/newlib/libc/include/spawn.h
@@ -70,6 +70,13 @@ int posix_spawn_file_actions_addopen (posix_spawn_file_actions_t * __restrict,
int, const char * __restrict, int, mode_t);
int posix_spawn_file_actions_adddup2 (posix_spawn_file_actions_t *, int, int);
int posix_spawn_file_actions_addclose (posix_spawn_file_actions_t *, int);
+#if __MISC_VISIBLE || __GNU_VISIBLE
+int posix_spawn_file_actions_addchdir_np (posix_spawn_file_actions_t *__restrict
+,
+ const char *__restrict);
+int posix_spawn_file_actions_addfchdir_np (posix_spawn_file_actions_t *__restrict,
+ int);
+#endif
/*
* Spawn attributes
diff --git a/newlib/libc/posix/posix_spawn.c b/newlib/libc/posix/posix_spawn.c
index 85bfa6477..3506b0f8b 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
*/