aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2026-01-24 22:06:36 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2026-01-25 17:19:53 +0000
commit3f0aea09689f6c10740de78011469355208a19a5 (patch)
tree65a669d21ef19876a4515d4dbbf1a9b8ba39f2b7
parentd185e9fae91a48041363e36a6ee4a2a9c567fc16 (diff)
libc: add posix_spawnattr_{get,set}execfd_np(3)
If execfd is set, the fexecve(2) is used by posix_spawn() instead of the provided path. Reviewed by: markj Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D54862
-rw-r--r--include/spawn.h7
-rw-r--r--lib/libc/gen/Symbol.map5
-rw-r--r--lib/libc/gen/posix_spawn.c22
3 files changed, 33 insertions, 1 deletions
diff --git a/include/spawn.h b/include/spawn.h
index a93315930954..a8f40e49dce0 100644
--- a/include/spawn.h
+++ b/include/spawn.h
@@ -123,6 +123,13 @@ int posix_spawnattr_setsigdefault(posix_spawnattr_t * __restrict,
const sigset_t * __restrict);
int posix_spawnattr_setsigmask(posix_spawnattr_t * __restrict,
const sigset_t * __restrict);
+
+#if __BSD_VISIBLE
+int posix_spawnattr_setexecfd_np(posix_spawnattr_t * __restrict, int);
+int posix_spawnattr_getexecfd_np(const posix_spawnattr_t * __restrict,
+ int * __restrict);
+#endif
+
__END_DECLS
#endif /* !_SPAWN_H_ */
diff --git a/lib/libc/gen/Symbol.map b/lib/libc/gen/Symbol.map
index 494b65bc5cc1..19170768ef7c 100644
--- a/lib/libc/gen/Symbol.map
+++ b/lib/libc/gen/Symbol.map
@@ -474,6 +474,11 @@ FBSD_1.8 {
str2sig;
};
+FBSD_1.9 {
+ posix_spawnattr_getexecfd_np;
+ posix_spawnattr_setexecfd_np;
+};
+
FBSDprivate_1.0 {
/* needed by thread libraries */
__thr_jtable;
diff --git a/lib/libc/gen/posix_spawn.c b/lib/libc/gen/posix_spawn.c
index a5b732696b8c..fc327e15bbf0 100644
--- a/lib/libc/gen/posix_spawn.c
+++ b/lib/libc/gen/posix_spawn.c
@@ -50,6 +50,7 @@ struct __posix_spawnattr {
int sa_schedpolicy;
sigset_t sa_sigdefault;
sigset_t sa_sigmask;
+ int sa_execfd;
};
struct __posix_spawn_file_actions {
@@ -260,7 +261,9 @@ _posix_spawn_thr(void *data)
_exit(127);
}
envp = psa->envp != NULL ? psa->envp : environ;
- if (psa->use_env_path)
+ if (psa->sa != NULL && (*(psa->sa))->sa_execfd != -1)
+ fexecve((*(psa->sa))->sa_execfd, psa->argv, envp);
+ else if (psa->use_env_path)
__libc_execvpe(psa->path, psa->argv, envp);
else
_execve(psa->path, psa->argv, envp);
@@ -578,6 +581,7 @@ posix_spawnattr_init(posix_spawnattr_t *ret)
sa = calloc(1, sizeof(struct __posix_spawnattr));
if (sa == NULL)
return (errno);
+ sa->sa_execfd = -1;
/* Set defaults as specified by POSIX, cleared above */
*ret = sa;
@@ -640,6 +644,14 @@ posix_spawnattr_getsigmask(const posix_spawnattr_t * __restrict sa,
}
int
+posix_spawnattr_getexecfd_np(const posix_spawnattr_t * __restrict sa,
+ int * __restrict fdp)
+{
+ *fdp = (*sa)->sa_execfd;
+ return (0);
+}
+
+int
posix_spawnattr_setflags(posix_spawnattr_t *sa, short flags)
{
if ((flags & ~(POSIX_SPAWN_RESETIDS | POSIX_SPAWN_SETPGROUP |
@@ -688,3 +700,11 @@ posix_spawnattr_setsigmask(posix_spawnattr_t * __restrict sa,
(*sa)->sa_sigmask = *sigmask;
return (0);
}
+
+int
+posix_spawnattr_setexecfd_np(posix_spawnattr_t * __restrict sa,
+ int execfd)
+{
+ (*sa)->sa_execfd = execfd;
+ return (0);
+}