diff options
| author | Konstantin Belousov <kib@FreeBSD.org> | 2026-01-24 22:06:36 +0000 |
|---|---|---|
| committer | Konstantin Belousov <kib@FreeBSD.org> | 2026-01-25 17:19:53 +0000 |
| commit | 3f0aea09689f6c10740de78011469355208a19a5 (patch) | |
| tree | 65a669d21ef19876a4515d4dbbf1a9b8ba39f2b7 | |
| parent | d185e9fae91a48041363e36a6ee4a2a9c567fc16 (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.h | 7 | ||||
| -rw-r--r-- | lib/libc/gen/Symbol.map | 5 | ||||
| -rw-r--r-- | lib/libc/gen/posix_spawn.c | 22 |
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); +} |
