Re: posix_spawn_file_actions_addchdir/addfchdir

Stuart Henderson <[email protected]>
Newsgroups gmane.os.openbsd.tech
Message-ID <[email protected]>
updated for daniel@'s feedback

Index: include/spawn.h
===================================================================
RCS file: /cvs/src/include/spawn.h,v
diff -u -p -r1.3 spawn.h
--- include/spawn.h	20 May 2015 22:50:07 -0000	1.3
+++ include/spawn.h	28 Aug 2026 09:17:56 -0000
@@ -69,6 +69,11 @@ int posix_spawn_file_actions_addopen(pos
     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 __POSIX_VISIBLE >= 202405
+int posix_spawn_file_actions_addchdir(posix_spawn_file_actions_t *__restrict,
+    const char *__restrict);
+int posix_spawn_file_actions_addfchdir(posix_spawn_file_actions_t *, int);
+#endif
 
 /*
  * Spawn attributes
Index: lib/libc/Symbols.list
===================================================================
RCS file: /cvs/src/lib/libc/Symbols.list,v
diff -u -p -r1.95 Symbols.list
--- lib/libc/Symbols.list	24 Oct 2025 11:30:06 -0000	1.95
+++ lib/libc/Symbols.list	28 Aug 2026 09:17:56 -0000
@@ -725,8 +725,10 @@ pause
 pclose
 popen
 posix_spawn
+posix_spawn_file_actions_addchdir
 posix_spawn_file_actions_addclose
 posix_spawn_file_actions_adddup2
+posix_spawn_file_actions_addfchdir
 posix_spawn_file_actions_addopen
 posix_spawn_file_actions_destroy
 posix_spawn_file_actions_init
Index: lib/libc/gen/posix_spawn.3
===================================================================
RCS file: /cvs/src/lib/libc/gen/posix_spawn.3,v
diff -u -p -r1.11 posix_spawn.3
--- lib/libc/gen/posix_spawn.3	26 Jun 2023 15:28:52 -0000	1.11
+++ lib/libc/gen/posix_spawn.3	28 Aug 2026 09:17:56 -0000
@@ -73,8 +73,10 @@ with
 Otherwise, file descriptors in the child process
 are altered according to
 .Xr posix_spawn_file_actions_init 3 ,
+.Xr posix_spawn_file_actions_addchdir 3 ,
 .Xr posix_spawn_file_actions_addclose 3 ,
 .Xr posix_spawn_file_actions_adddup2 3 ,
+.Xr posix_spawn_file_actions_addfchdir 3 ,
 and
 .Xr posix_spawn_file_actions_addopen 3 .
 .Pp
Index: lib/libc/gen/posix_spawn.c
===================================================================
RCS file: /cvs/src/lib/libc/gen/posix_spawn.c,v
diff -u -p -r1.10 posix_spawn.c
--- lib/libc/gen/posix_spawn.c	28 Jun 2019 13:32:41 -0000	1.10
+++ lib/libc/gen/posix_spawn.c	28 Aug 2026 09:17:56 -0000
@@ -51,7 +51,7 @@ struct __posix_spawn_file_actions {
 
 typedef struct __posix_spawn_file_actions_entry {
 	SIMPLEQ_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 {
@@ -171,6 +171,14 @@ process_file_actions_entry(posix_spawn_f
 		/* Perform a close(), do not fail if already closed */
 		(void)close(fae->fae_fildes);
 		break;
+	case FAE_CHDIR:
+		if (chdir(fae->fae_path) == -1)
+			return (errno);
+		break;
+	case FAE_FCHDIR:
+		if (fchdir(fae->fae_fildes) == -1)
+			return (errno);
+		break;
 	}
 	return (0);
 }
@@ -273,7 +281,8 @@ posix_spawn_file_actions_destroy(posix_s
 		SIMPLEQ_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);
 	}
@@ -352,6 +361,53 @@ posix_spawn_file_actions_addclose(posix_
 
 	/* Set values and store in queue */
 	fae->fae_action = FAE_CLOSE;
+	fae->fae_fildes = fildes;
+
+	SIMPLEQ_INSERT_TAIL(&(*fa)->fa_list, fae, fae_list);
+	return (0);
+}
+
+int
+posix_spawn_file_actions_addchdir(posix_spawn_file_actions_t *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_path = strdup(path);
+	if (fae->fae_path == NULL) {
+		error = errno;
+		free(fae);
+		return (error);
+	}
+
+	SIMPLEQ_INSERT_TAIL(&(*fa)->fa_list, fae, fae_list);
+	return (0);
+}
+
+int
+posix_spawn_file_actions_addfchdir(posix_spawn_file_actions_t *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);
+
+	/* Set values and store in queue */
+	fae->fae_action = FAE_FCHDIR;
 	fae->fae_fildes = fildes;
 
 	SIMPLEQ_INSERT_TAIL(&(*fa)->fa_list, fae, fae_list);
Index: lib/libc/gen/posix_spawn_file_actions_addopen.3
===================================================================
RCS file: /cvs/src/lib/libc/gen/posix_spawn_file_actions_addopen.3,v
diff -u -p -r1.9 posix_spawn_file_actions_addopen.3
--- lib/libc/gen/posix_spawn_file_actions_addopen.3	29 Mar 2022 18:15:52 -0000	1.9
+++ lib/libc/gen/posix_spawn_file_actions_addopen.3	28 Aug 2026 09:17:56 -0000
@@ -18,22 +18,31 @@
 .Dt POSIX_SPAWN_FILE_ACTIONS_ADDOPEN 3
 .Os
 .Sh NAME
+.Nm posix_spawn_file_actions_addchdir ,
 .Nm posix_spawn_file_actions_addclose ,
 .Nm posix_spawn_file_actions_adddup2 ,
+.Nm posix_spawn_file_actions_addfchdir ,
 .Nm posix_spawn_file_actions_addopen
-.Nd add action to close, dup2 or open file descriptor to file actions object
+.Nd add action to change directory, close, dup2 or open file descriptor
+to file actions object
 .Sh SYNOPSIS
 .In spawn.h
 .Ft int
+.Fn posix_spawn_file_actions_addchdir "posix_spawn_file_actions_t *file_actions" "const char *restrict path"
+.Ft int
 .Fn posix_spawn_file_actions_addclose "posix_spawn_file_actions_t *file_actions" "int fildes"
 .Ft int
 .Fn posix_spawn_file_actions_adddup2 "posix_spawn_file_actions_t *file_actions" "int fildes" "int newfildes"
 .Ft int
+.Fn posix_spawn_file_actions_addfchdir "posix_spawn_file_actions_t *file_actions" "int fildes"
+.Ft int
 .Fn posix_spawn_file_actions_addopen "posix_spawn_file_actions_t *file_actions" "int fildes" "const char *restrict path" "int oflag" "mode_t mode"
 .Sh DESCRIPTION
-These function add an action to
+These functions add an action to
+.Xr chdir 2 ,
 .Xr close 2 ,
 .Xr dup2 2 ,
+.Xr fchdir 2 ,
 or
 .Xr open 2
 a file descriptor
@@ -45,6 +54,15 @@ Actions are executed in order in the chi
 .Bl -dash
 .It
 The
+.Fn posix_spawn_file_actions_addchdir
+function adds an action that causes
+.Bd -literal -offset indent
+chdir(path);
+.Ed
+.Pp
+to be called.
+.It
+The
 .Fn posix_spawn_file_actions_addclose
 function adds an action that causes
 .Bd -literal -offset indent
@@ -69,6 +87,15 @@ equals
 .Fa fildes .
 .It
 The
+.Fn posix_spawn_file_actions_addfchdir
+function adds an action that causes
+.Bd -literal -offset indent
+fchdir(fildes);
+.Ed
+.Pp
+to be called.
+.It
+The
 .Fn posix_spawn_file_actions_addopen
 function adds an action that causes
 .Bd -literal -offset indent
@@ -91,7 +118,7 @@ argument.
 .Sh RETURN VALUES
 Upon successful completion, these functions return zero.
 Otherwise they may return
-.Er EINVAL
+.Er EBADF
 for negative file descriptors, or
 .Er ENOMEM
 if they run out of memory.
@@ -101,6 +128,6 @@ if they run out of memory.
 .Xr posix_spawnp 3
 .Sh STANDARDS
 These functions conform to
-.St -p1003.1-2001 .
+.St -p1003.1-2024 .
 .Sh AUTHORS
 .An \&Ed Schouten Aq Mt [email protected]
Index: lib/libc/hidden/spawn.h
===================================================================
RCS file: /cvs/src/lib/libc/hidden/spawn.h,v
diff -u -p -r1.1 spawn.h
--- lib/libc/hidden/spawn.h	4 Oct 2015 07:57:21 -0000	1.1
+++ lib/libc/hidden/spawn.h	28 Aug 2026 09:17:56 -0000
@@ -21,8 +21,10 @@
 #include_next <spawn.h>
 
 PROTO_DEPRECATED(posix_spawn);
+PROTO_DEPRECATED(posix_spawn_file_actions_addchdir);
 PROTO_DEPRECATED(posix_spawn_file_actions_addclose);
 PROTO_DEPRECATED(posix_spawn_file_actions_adddup2);
+PROTO_DEPRECATED(posix_spawn_file_actions_addfchdir);
 PROTO_DEPRECATED(posix_spawn_file_actions_addopen);
 PROTO_DEPRECATED(posix_spawn_file_actions_destroy);
 PROTO_DEPRECATED(posix_spawn_file_actions_init);
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.