The branch main has been updated by kib:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=25cda42a498101612687b32005856cd8b14f2f7a

commit 25cda42a498101612687b32005856cd8b14f2f7a
Author:     Konstantin Belousov <[email protected]>
AuthorDate: 2021-11-27 22:49:03 +0000
Commit:     Konstantin Belousov <[email protected]>
CommitDate: 2021-11-30 01:43:54 +0000

    posix_spawn: add chdir-related non-portable actions
    
    Namely posix_spawn_file_actions_addchdir_np and
    posix_spawn_file_actions_addfchdir_np.
    
    Reviewed by:    kevans, ngie (previous version)
    Sponsored by:   The FreeBSD Foundation
    MFC after:      1 week
    Differential revision:  https://reviews.freebsd.org/D33143
---
 include/spawn.h            |  7 ++++++
 lib/libc/gen/Symbol.map    |  2 ++
 lib/libc/gen/posix_spawn.c | 57 +++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 65 insertions(+), 1 deletion(-)

diff --git a/include/spawn.h b/include/spawn.h
index 79753bba0510..4ba3998a3e90 100644
--- a/include/spawn.h
+++ b/include/spawn.h
@@ -87,6 +87,13 @@ int 
posix_spawn_file_actions_addopen(posix_spawn_file_actions_t * __restrict,
 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 __BSD_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 *,
+    int);
+#endif
+
 /*
  * Spawn attributes
  */
diff --git a/lib/libc/gen/Symbol.map b/lib/libc/gen/Symbol.map
index b6c3c252be7c..bae2463d99d4 100644
--- a/lib/libc/gen/Symbol.map
+++ b/lib/libc/gen/Symbol.map
@@ -436,6 +436,8 @@ FBSD_1.6 {
 };
 
 FBSD_1.7 {
+        posix_spawn_file_actions_addchdir_np;
+        posix_spawn_file_actions_addfchdir_np;
         sched_getaffinity;
         sched_setaffinity;
         sched_getcpu;
diff --git a/lib/libc/gen/posix_spawn.c b/lib/libc/gen/posix_spawn.c
index 03283cfcfb04..00d1724a6515 100644
--- a/lib/libc/gen/posix_spawn.c
+++ b/lib/libc/gen/posix_spawn.c
@@ -66,6 +66,8 @@ typedef struct __posix_spawn_file_actions_entry {
                FAE_OPEN,
                FAE_DUP2,
                FAE_CLOSE,
+               FAE_CHDIR,
+               FAE_FCHDIR,
        } fae_action;
 
        int fae_fildes;
@@ -180,6 +182,14 @@ 
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;
+       case FAE_CHDIR:
+               if (chdir(fae->fae_path) != 0)
+                       return (errno);
+               break;
+       case FAE_FCHDIR:
+               if (fchdir(fae->fae_fildes) != 0)
+                       return (errno);
+               break;
        }
        return (0);
 }
@@ -393,7 +403,8 @@ 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)
+               if (fae->fae_action == FAE_OPEN ||
+                   fae->fae_action == FAE_CHDIR)
                        free(fae->fae_path);
                free(fae);
        }
@@ -478,6 +489,50 @@ 
posix_spawn_file_actions_addclose(posix_spawn_file_actions_t *fa,
        return (0);
 }
 
+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;
+
+       fae = malloc(sizeof(posix_spawn_file_actions_entry_t));
+       if (fae == NULL)
+               return (errno);
+
+       fae->fae_action = FAE_CHDIR;
+       fae->fae_path = strdup(path);
+       if (fae->fae_path == NULL) {
+               error = errno;
+               free(fae);
+               return (error);
+       }
+
+       STAILQ_INSERT_TAIL(&(*fa)->fa_list, fae, fae_list);
+       return (0);
+}
+
+int
+posix_spawn_file_actions_addfchdir_np(posix_spawn_file_actions_t *__restrict 
fa,
+    int fildes)
+{
+       posix_spawn_file_actions_entry_t *fae;
+
+       if (fildes < 0)
+               return (EBADF);
+
+       /* Allocate object */
+       fae = malloc(sizeof(posix_spawn_file_actions_entry_t));
+       if (fae == NULL)
+               return (errno);
+
+       fae->fae_action = FAE_FCHDIR;
+       fae->fae_fildes = fildes;
+
+       STAILQ_INSERT_TAIL(&(*fa)->fa_list, fae, fae_list);
+       return (0);
+}
+
 /*
  * Spawn attributes
  */

Reply via email to