The branch main has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=3f0aea09689f6c10740de78011469355208a19a5
commit 3f0aea09689f6c10740de78011469355208a19a5 Author: Konstantin Belousov <[email protected]> AuthorDate: 2026-01-24 22:06:36 +0000 Commit: Konstantin Belousov <[email protected]> CommitDate: 2026-01-25 17:19:53 +0000 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 --- include/spawn.h | 7 +++++++ lib/libc/gen/Symbol.map | 5 +++++ lib/libc/gen/posix_spawn.c | 22 +++++++++++++++++++++- 3 files changed, 33 insertions(+), 1 deletion(-) 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; @@ -639,6 +643,14 @@ posix_spawnattr_getsigmask(const posix_spawnattr_t * __restrict sa, return (0); } +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) { @@ -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); +}
