diff --git a/libc/calls/sigprocmask.c b/libc/calls/sigprocmask.c index 9941de4c4..c59a64ce9 100644 --- a/libc/calls/sigprocmask.c +++ b/libc/calls/sigprocmask.c @@ -43,6 +43,8 @@ * @param set is the new mask content (optional) * @param oldset will receive the old mask (optional) and can't overlap * @return 0 on success, or -1 w/ errno + * @raise EFAULT if `set` or `oldset` is bad memory + * @raise EINVAL if `how` is invalid * @asyncsignalsafe * @restartable * @vforksafe diff --git a/libc/isystem/spawn.h b/libc/isystem/spawn.h index 679428a19..638126051 100644 --- a/libc/isystem/spawn.h +++ b/libc/isystem/spawn.h @@ -1,5 +1,5 @@ #ifndef COSMOPOLITAN_LIBC_ISYSTEM_SPAWN_H_ #define COSMOPOLITAN_LIBC_ISYSTEM_SPAWN_H_ #include "libc/calls/weirdtypes.h" -#include "libc/stdio/spawn.h" +#include "libc/stdio/posix_spawn.h" #endif /* COSMOPOLITAN_LIBC_ISYSTEM_SPAWN_H_ */ diff --git a/libc/log/oncrash.c b/libc/log/oncrash.c index da017092b..d6ae1a992 100644 --- a/libc/log/oncrash.c +++ b/libc/log/oncrash.c @@ -278,7 +278,6 @@ static wontreturn relegated noinstrument void __minicrash(int sig, * @vforksafe */ relegated void __oncrash(int sig, struct siginfo *si, ucontext_t *ctx) { - kprintf("oncrash\n"); intptr_t rip; int me, owner; int gdbpid, err; diff --git a/libc/stdio/popen.c b/libc/stdio/popen.c index 2a3e62a64..dcf912835 100644 --- a/libc/stdio/popen.c +++ b/libc/stdio/popen.c @@ -54,7 +54,7 @@ FILE *popen(const char *cmdline, const char *mode) { switch ((pid = fork())) { case 0: _unassert(dup2(pipefds[!dir], !dir) == !dir); - // we can't rely on cloexec because cocmd builtins don't execev + // we can't rely on cloexec because cocmd builtins don't execve if (pipefds[0] != !dir) _unassert(!close(pipefds[0])); if (pipefds[1] != !dir) _unassert(!close(pipefds[1])); _Exit(cocmd(3, (char *[]){"popen", "-c", cmdline, 0})); diff --git a/libc/stdio/spawn.c b/libc/stdio/posix_spawn.c similarity index 55% rename from libc/stdio/spawn.c rename to libc/stdio/posix_spawn.c index 904a750a5..705e7558b 100644 --- a/libc/stdio/spawn.c +++ b/libc/stdio/posix_spawn.c @@ -16,94 +16,95 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/assert.h" #include "libc/calls/calls.h" -#include "libc/calls/struct/sched_param.h" #include "libc/calls/struct/sigaction.h" +#include "libc/calls/struct/sigset.h" #include "libc/errno.h" -#include "libc/fmt/fmt.h" -#include "libc/intrin/kprintf.h" #include "libc/runtime/runtime.h" -#include "libc/stdio/spawn.h" -#include "libc/stdio/spawna.internal.h" -#include "libc/str/str.h" +#include "libc/stdio/posix_spawn.h" +#include "libc/stdio/posix_spawn.internal.h" + +static int RunFileActions(struct _posix_faction *a) { + int t; + if (!a) return 0; + if (RunFileActions(a->next) == -1) return -1; + switch (a->action) { + case _POSIX_SPAWN_CLOSE: + return close(a->fildes); + case _POSIX_SPAWN_DUP2: + return dup2(a->fildes, a->newfildes); + case _POSIX_SPAWN_OPEN: + if ((t = open(a->path, a->oflag, a->mode)) == -1) return -1; + if (t != a->fildes) { + if (dup2(t, a->fildes) == -1) { + close(t); + return -1; + } + if (close(t) == -1) { + return -1; + } + } + return 0; + default: + unreachable; + } +} /** * Spawns process the POSIX way. * - * @param pid is non-NULL and will be set to child pid in parent - * @param path of executable that is not PATH searched + * @param pid if non-null shall be set to child pid on success + * @param path is resolved path of program which is not `$PATH` searched + * @param file_actions specifies close(), dup2(), and open() operations + * @param attrp specifies signal masks, user ids, scheduling, etc. + * @param envp is environment variables, or `environ` if null * @return 0 on success or error number on failure + * @see posix_spawnp() for `$PATH` searching */ int posix_spawn(int *pid, const char *path, const posix_spawn_file_actions_t *file_actions, const posix_spawnattr_t *attrp, char *const argv[], char *const envp[]) { - unsigned mode; + int s, child; sigset_t allsigs; struct sigaction dfl; - char *p, *q, opath[PATH_MAX]; - int s, fd, newfd, oflag, tempfd; - if (!(*pid = vfork())) { - if (attrp) { - if (attrp->posix_attr_flags & POSIX_SPAWN_SETPGROUP) { - if (setpgid(0, attrp->posix_attr_pgroup)) _Exit(127); + if (!(child = vfork())) { + if (attrp && *attrp) { + if ((*attrp)->flags & POSIX_SPAWN_SETPGROUP) { + if (setpgid(0, (*attrp)->pgroup)) _Exit(127); } - if (attrp->posix_attr_flags & POSIX_SPAWN_SETSIGMASK) { - sigprocmask(SIG_SETMASK, &attrp->posix_attr_sigmask, 0); + if ((*attrp)->flags & POSIX_SPAWN_SETSIGMASK) { + sigprocmask(SIG_SETMASK, &(*attrp)->sigmask, 0); } - if (attrp->posix_attr_flags & POSIX_SPAWN_RESETIDS) { + if ((*attrp)->flags & POSIX_SPAWN_RESETIDS) { setuid(getuid()); setgid(getgid()); } - if (attrp->posix_attr_flags & POSIX_SPAWN_SETSIGDEF) { + if ((*attrp)->flags & POSIX_SPAWN_SETSIGDEF) { dfl.sa_handler = SIG_DFL; dfl.sa_flags = 0; sigfillset(&allsigs); for (s = 0; sigismember(&allsigs, s); s++) { - if (sigismember(&attrp->posix_attr_sigdefault, s)) { + if (sigismember(&(*attrp)->sigdefault, s)) { if (sigaction(s, &dfl, 0) == -1) _Exit(127); } } } } if (file_actions) { - for (p = *file_actions; *p; p = strchr(p, ')') + 1) { - if (!strncmp(p, "close(", 6)) { - if (sscanf(p + 6, "%d)", &fd) != 1) _Exit(127); - if (close(fd) == -1) _Exit(127); - } else if (!strncmp(p, "dup2(", 5)) { - if (sscanf(p + 5, "%d,%d)", &fd, &newfd) != 2) _Exit(127); - if (dup2(fd, newfd) == -1) _Exit(127); - } else if (!strncmp(p, "open(", 5)) { - if (sscanf(p + 5, "%d,", &fd) != 1) _Exit(127); - p = strchr(p, ',') + 1; - q = strchr(p, '*'); - if (!q || q - p >= PATH_MAX) _Exit(127); - strncpy(opath, p, q - p); - opath[q - p] = '\0'; - if (sscanf(q + 1, "%o,%o)", &oflag, &mode) != 2) _Exit(127); - if (close(fd) == -1 && errno != EBADF) _Exit(127); - tempfd = open(opath, oflag, mode); - if (tempfd == -1) _Exit(127); - if (tempfd != fd) { - if (dup2(tempfd, fd) == -1) _Exit(127); - if (close(tempfd) == -1) _Exit(127); - } - } else { - _Exit(127); - } + if (RunFileActions(*file_actions) == -1) { + _Exit(127); } } - if (attrp) { - if (attrp->posix_attr_flags & POSIX_SPAWN_SETSCHEDULER) { - if (sched_setscheduler(0, attrp->posix_attr_schedpolicy, - &attrp->posix_attr_schedparam) == -1) { + if (attrp && *attrp) { + if ((*attrp)->flags & POSIX_SPAWN_SETSCHEDULER) { + if (sched_setscheduler(0, (*attrp)->schedpolicy, + &(*attrp)->schedparam) == -1) { if (errno != ENOSYS) _Exit(127); } } - if (attrp->posix_attr_flags & POSIX_SPAWN_SETSCHEDPARAM) { - if (sched_setparam(0, &attrp->posix_attr_schedparam) == -1) { + if ((*attrp)->flags & POSIX_SPAWN_SETSCHEDPARAM) { + if (sched_setparam(0, &(*attrp)->schedparam) == -1) { if (errno != ENOSYS) _Exit(127); } } @@ -111,8 +112,10 @@ int posix_spawn(int *pid, const char *path, if (!envp) envp = environ; execve(path, argv, envp); _Exit(127); - } else { - if (*pid == -1) return errno; + } else if (child != -1) { + if (pid) *pid = child; return 0; + } else { + return errno; } } diff --git a/libc/stdio/spawn.h b/libc/stdio/posix_spawn.h similarity index 95% rename from libc/stdio/spawn.h rename to libc/stdio/posix_spawn.h index 58c99474a..8f177d854 100644 --- a/libc/stdio/spawn.h +++ b/libc/stdio/posix_spawn.h @@ -13,8 +13,8 @@ #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ -typedef char *posix_spawn_file_actions_t; -typedef struct _posix_spawnattr posix_spawnattr_t; +typedef struct _posix_spawna *posix_spawnattr_t; +typedef struct _posix_faction *posix_spawn_file_actions_t; int posix_spawn(int *, const char *, const posix_spawn_file_actions_t *, const posix_spawnattr_t *, char *const[], char *const[]); diff --git a/libc/stdio/posix_spawn.internal.h b/libc/stdio/posix_spawn.internal.h new file mode 100644 index 000000000..dc274275a --- /dev/null +++ b/libc/stdio/posix_spawn.internal.h @@ -0,0 +1,41 @@ +#ifndef COSMOPOLITAN_LIBC_STDIO_SPAWNA_INTERNAL_H_ +#define COSMOPOLITAN_LIBC_STDIO_SPAWNA_INTERNAL_H_ +#include "libc/calls/struct/sched_param.h" +#include "libc/calls/struct/sigset.h" + +#define _POSIX_SPAWN_CLOSE 1 +#define _POSIX_SPAWN_DUP2 2 +#define _POSIX_SPAWN_OPEN 3 + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct _posix_spawna { + char flags; + bool schedparam_isset; + bool schedpolicy_isset; + bool sigmask_isset; + int pgroup; + int schedpolicy; + struct sched_param schedparam; + sigset_t sigmask; + sigset_t sigdefault; +}; + +struct _posix_faction { + struct _posix_faction *next; + int action; + union { + int fildes; + int oflag; + }; + union { + int newfildes; + unsigned mode; + }; + const char *path; +}; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_STDIO_SPAWNA_INTERNAL_H_ */ diff --git a/libc/stdio/spawnf.c b/libc/stdio/posix_spawn_file_actions.c similarity index 53% rename from libc/stdio/spawnf.c rename to libc/stdio/posix_spawn_file_actions.c index acced624d..914a0a12c 100644 --- a/libc/stdio/spawnf.c +++ b/libc/stdio/posix_spawn_file_actions.c @@ -19,67 +19,98 @@ #include "libc/errno.h" #include "libc/fmt/fmt.h" #include "libc/mem/mem.h" -#include "libc/stdio/spawn.h" +#include "libc/stdio/posix_spawn.h" +#include "libc/stdio/posix_spawn.internal.h" #include "libc/str/str.h" +static int AddFileAction(posix_spawn_file_actions_t *l, + struct _posix_faction a) { + struct _posix_faction *ap; + if (!(ap = malloc(sizeof(*ap)))) return ENOMEM; + a.next = *l; + *ap = a; + *l = ap; + return 0; +} + /** - * Creates object with no actions. + * Initializes posix_spawn() file actions list. + * + * @param file_actions will need posix_spawn_file_actions_destroy() + * @return 0 on success, or errno on error */ int posix_spawn_file_actions_init(posix_spawn_file_actions_t *file_actions) { - *file_actions = malloc(sizeof(char)); - if (!*file_actions) return ENOMEM; - strcpy(*file_actions, ""); + *file_actions = 0; return 0; } /** - * Frees object storage and make invalid. + * Destroys posix_spawn() file actions list. + * + * This function is safe to call multiple times. + * + * @param file_actions was initialized by posix_spawn_file_actions_init() + * @return 0 on success, or errno on error */ int posix_spawn_file_actions_destroy(posix_spawn_file_actions_t *file_actions) { - free(*file_actions); - *file_actions = NULL; - return 0; -} - -/** - * Adds new action string to object. - */ -static int add_to_file_actions(posix_spawn_file_actions_t *file_actions, - char *new_action) { - *file_actions = - realloc(*file_actions, strlen(*file_actions) + strlen(new_action) + 1); - if (!*file_actions) return ENOMEM; - strcat(*file_actions, new_action); + if (*file_actions) { + posix_spawn_file_actions_destroy(&(*file_actions)->next); + free((*file_actions)->path); + free(*file_actions); + *file_actions = 0; + } return 0; } /** * Add a close action to object. + * + * @param file_actions was initialized by posix_spawn_file_actions_init() + * @return 0 on success, or errno on error + * @raise ENOMEM if we require more vespene gas */ int posix_spawn_file_actions_addclose(posix_spawn_file_actions_t *file_actions, int fildes) { - char temp[100]; - (sprintf)(temp, "close(%d)", fildes); - return add_to_file_actions(file_actions, temp); + return AddFileAction(file_actions, (struct _posix_faction){ + .action = _POSIX_SPAWN_CLOSE, + .fildes = fildes, + }); } /** * Add a dup2 action to object. + * + * @param file_actions was initialized by posix_spawn_file_actions_init() + * @return 0 on success, or errno on error + * @raise ENOMEM if we require more vespene gas */ int posix_spawn_file_actions_adddup2(posix_spawn_file_actions_t *file_actions, int fildes, int newfildes) { - char temp[100]; - (sprintf)(temp, "dup2(%d,%d)", fildes, newfildes); - return add_to_file_actions(file_actions, temp); + return AddFileAction(file_actions, (struct _posix_faction){ + .action = _POSIX_SPAWN_DUP2, + .fildes = fildes, + .newfildes = newfildes, + }); } /** * Add an open action to object. + * + * @param file_actions was initialized by posix_spawn_file_actions_init() + * @param filedes is what open() result gets duplicated to + * @param path will be safely copied + * @return 0 on success, or errno on error + * @raise ENOMEM if we require more vespene gas */ int posix_spawn_file_actions_addopen(posix_spawn_file_actions_t *file_actions, int fildes, const char *path, int oflag, unsigned mode) { - char temp[100]; - (sprintf)(temp, "open(%d,%s*%o,%o)", fildes, path, oflag, mode); - return add_to_file_actions(file_actions, temp); + if (!(path = strdup(path))) return ENOMEM; + return AddFileAction(file_actions, (struct _posix_faction){ + .action = _POSIX_SPAWN_OPEN, + .fildes = fildes, + .path = path, + .oflag = oflag, + .mode = mode, + }); } diff --git a/libc/stdio/posix_spawnattr.c b/libc/stdio/posix_spawnattr.c new file mode 100644 index 000000000..44a8c29ad --- /dev/null +++ b/libc/stdio/posix_spawnattr.c @@ -0,0 +1,213 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2021 Justine Alexandra Roberts Tunney │ +│ │ +│ Permission to use, copy, modify, and/or distribute this software for │ +│ any purpose with or without fee is hereby granted, provided that the │ +│ above copyright notice and this permission notice appear in all copies. │ +│ │ +│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ +│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ +│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ +│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ +│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ +│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ +│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ +│ PERFORMANCE OF THIS SOFTWARE. │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/struct/sigset.h" +#include "libc/errno.h" +#include "libc/mem/mem.h" +#include "libc/stdio/posix_spawn.h" +#include "libc/stdio/posix_spawn.internal.h" +#include "libc/sysv/consts/sig.h" + +/** + * Initialize posix_spawn() attributes object with default values. + * + * @param attr needs to be passed to posix_spawnattr_destroy() later + * @return 0 on success, or errno on error + * @raise ENOMEM if we require more vespene gas + */ +int posix_spawnattr_init(posix_spawnattr_t *attr) { + int e, rc; + struct _posix_spawna *a; + e = errno; + errno = 0; + if ((a = calloc(1, sizeof(*a)))) { + a->flags = 0; + a->pgroup = 0; + sigemptyset(&a->sigdefault); + a->schedpolicy = sched_getscheduler(0); + sched_getparam(0, &a->schedparam); + } + rc = errno; + errno = e; + return rc; +} + +/** + * Destroys posix_spawn() attributes object. + * + * This function is safe to call multiple times. + * + * @param attr was initialized by posix_spawnattr_init() + * @return 0 on success, or errno on error + */ +int posix_spawnattr_destroy(posix_spawnattr_t *attr) { + if (*attr) { + free(*attr); + *attr = 0; + } + return 0; +} + +/** + * Gets posix_spawn() flags. + * + * @param attr was initialized by posix_spawnattr_init() + * @return 0 on success, or errno on error + */ +int posix_spawnattr_getflags(const posix_spawnattr_t *attr, short *flags) { + *flags = (*attr)->flags; + return 0; +} + +/** + * Sets posix_spawn() flags. + * + * Setting these flags is needed in order for the other setters in this + * function to take effect. + * + * @param attr was initialized by posix_spawnattr_init() + * @param flags may have any of the following + * - `POSIX_SPAWN_RESETIDS` + * - `POSIX_SPAWN_SETPGROUP` + * - `POSIX_SPAWN_SETSIGDEF` + * - `POSIX_SPAWN_SETSIGMASK` + * - `POSIX_SPAWN_SETSCHEDPARAM` + * - `POSIX_SPAWN_SETSCHEDULER` + * @return 0 on success, or errno on error + * @raise EINVAL if `flags` has invalid bits + */ +int posix_spawnattr_setflags(posix_spawnattr_t *attr, short flags) { + if (flags & ~(POSIX_SPAWN_RESETIDS | POSIX_SPAWN_SETPGROUP | + POSIX_SPAWN_SETSIGDEF | POSIX_SPAWN_SETSIGMASK | + POSIX_SPAWN_SETSCHEDPARAM | POSIX_SPAWN_SETSCHEDULER)) { + return EINVAL; + } + (*attr)->flags = flags; + return 0; +} + +int posix_spawnattr_getpgroup(const posix_spawnattr_t *attr, int *pgroup) { + *pgroup = (*attr)->pgroup; + return 0; +} + +int posix_spawnattr_setpgroup(posix_spawnattr_t *attr, int pgroup) { + (*attr)->pgroup = pgroup; + return 0; +} + +/** + * Gets scheduler policy that'll be used for spawned process. + * + * If the setter wasn't called then this function will return the + * scheduling policy of the current process. + * + * @param attr was initialized by posix_spawnattr_init() + * @param schedpolicy receives the result + * @return 0 on success, or errno on error + */ +int posix_spawnattr_getschedpolicy(const posix_spawnattr_t *attr, + int *schedpolicy) { + if (!(*attr)->schedpolicy_isset) { + (*attr)->schedpolicy = sched_getscheduler(0); + (*attr)->schedpolicy_isset = true; + } + *schedpolicy = (*attr)->schedpolicy; + return 0; +} + +/** + * Specifies scheduler policy override for spawned process. + * + * Scheduling policies are inherited by default. Use this to change it. + * + * @param attr was initialized by posix_spawnattr_init() + * @param schedpolicy receives the result + * @return 0 on success, or errno on error + */ +int posix_spawnattr_setschedpolicy(posix_spawnattr_t *attr, int schedpolicy) { + (*attr)->schedpolicy = schedpolicy; + (*attr)->schedpolicy_isset = true; + return 0; +} + +/** + * Gets scheduler parameter that'll be used for spawned process. + * + * If the setter wasn't called then this function will return the + * scheduling parameter of the current process. + * + * @param attr was initialized by posix_spawnattr_init() + * @param schedparam receives the result + * @return 0 on success, or errno on error + */ +int posix_spawnattr_getschedparam(const posix_spawnattr_t *attr, + struct sched_param *schedparam) { + if (!(*attr)->schedparam_isset) { + sched_getparam(0, &(*attr)->schedparam); + (*attr)->schedparam_isset = true; + } + *schedparam = (*attr)->schedparam; + return 0; +} + +/** + * Specifies scheduler parameter override for spawned process. + * + * Scheduling parameters are inherited by default. Use this to change it. + * + * @param attr was initialized by posix_spawnattr_init() + * @param schedparam receives the result + * @return 0 on success, or errno on error + */ +int posix_spawnattr_setschedparam(posix_spawnattr_t *attr, + const struct sched_param *schedparam) { + (*attr)->schedparam = *schedparam; + (*attr)->schedparam_isset = true; + return 0; +} + +int posix_spawnattr_getsigmask(const posix_spawnattr_t *attr, + sigset_t *sigmask) { + if (!(*attr)->sigmask_isset) { + sigprocmask(SIG_SETMASK, 0, &(*attr)->sigmask); + (*attr)->sigmask_isset = true; + } + *sigmask = (*attr)->sigmask; + return 0; +} + +int posix_spawnattr_setsigmask(posix_spawnattr_t *attr, + const sigset_t *sigmask) { + (*attr)->sigmask = *sigmask; + (*attr)->sigmask_isset = true; + return 0; +} + +int posix_spawnattr_getsigdefault(const posix_spawnattr_t *attr, + sigset_t *sigdefault) { + *sigdefault = (*attr)->sigdefault; + return 0; +} + +int posix_spawnattr_setsigdefault(posix_spawnattr_t *attr, + const sigset_t *sigdefault) { + (*attr)->sigdefault = *sigdefault; + return 0; +} diff --git a/libc/stdio/spawnp.c b/libc/stdio/posix_spawnp.c similarity index 98% rename from libc/stdio/spawnp.c rename to libc/stdio/posix_spawnp.c index 67b9d0d67..3ca42ab6a 100644 --- a/libc/stdio/spawnp.c +++ b/libc/stdio/posix_spawnp.c @@ -18,7 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" #include "libc/errno.h" -#include "libc/stdio/spawn.h" +#include "libc/stdio/posix_spawn.h" /** * Spawns process the POSIX way w/ PATH search. diff --git a/libc/stdio/spawna.c b/libc/stdio/spawna.c deleted file mode 100644 index 9a923f94c..000000000 --- a/libc/stdio/spawna.c +++ /dev/null @@ -1,105 +0,0 @@ -/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ -│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ -╞══════════════════════════════════════════════════════════════════════════════╡ -│ Copyright 2021 Justine Alexandra Roberts Tunney │ -│ │ -│ Permission to use, copy, modify, and/or distribute this software for │ -│ any purpose with or without fee is hereby granted, provided that the │ -│ above copyright notice and this permission notice appear in all copies. │ -│ │ -│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ -│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ -│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ -│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ -│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ -│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ -│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ -│ PERFORMANCE OF THIS SOFTWARE. │ -╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/calls/calls.h" -#include "libc/stdio/spawn.h" -#include "libc/stdio/spawna.internal.h" - -/** - * Initialize object with default values. - */ -int posix_spawnattr_init(posix_spawnattr_t *attr) { - attr->posix_attr_flags = 0; - attr->posix_attr_pgroup = 0; - sigprocmask(0, NULL, &attr->posix_attr_sigmask); - sigemptyset(&attr->posix_attr_sigdefault); - attr->posix_attr_schedpolicy = sched_getscheduler(0); - sched_getparam(0, &attr->posix_attr_schedparam); - return 0; -} - -int posix_spawnattr_destroy(posix_spawnattr_t *attr) { - return 0; -} - -int posix_spawnattr_getflags(const posix_spawnattr_t *attr, short *flags) { - *flags = attr->posix_attr_flags; - return 0; -} - -int posix_spawnattr_setflags(posix_spawnattr_t *attr, short flags) { - attr->posix_attr_flags = flags; - return 0; -} - -int posix_spawnattr_getpgroup(const posix_spawnattr_t *attr, int *pgroup) { - *pgroup = attr->posix_attr_pgroup; - return 0; -} - -int posix_spawnattr_setpgroup(posix_spawnattr_t *attr, int pgroup) { - attr->posix_attr_pgroup = pgroup; - return 0; -} - -int posix_spawnattr_getschedpolicy(const posix_spawnattr_t *attr, - int *schedpolicy) { - *schedpolicy = attr->posix_attr_schedpolicy; - return 0; -} - -int posix_spawnattr_setschedpolicy(posix_spawnattr_t *attr, int schedpolicy) { - attr->posix_attr_schedpolicy = schedpolicy; - return 0; -} - -int posix_spawnattr_getschedparam(const posix_spawnattr_t *attr, - struct sched_param *schedparam) { - *schedparam = attr->posix_attr_schedparam; - return 0; -} - -int posix_spawnattr_setschedparam(posix_spawnattr_t *attr, - const struct sched_param *schedparam) { - attr->posix_attr_schedparam = *schedparam; - return 0; -} - -int posix_spawnattr_getsigmask(const posix_spawnattr_t *attr, - sigset_t *sigmask) { - *sigmask = attr->posix_attr_sigmask; - return 0; -} - -int posix_spawnattr_setsigmask(posix_spawnattr_t *attr, - const sigset_t *sigmask) { - attr->posix_attr_sigmask = *sigmask; - return 0; -} - -int posix_spawnattr_getsigdefault(const posix_spawnattr_t *attr, - sigset_t *sigdefault) { - *sigdefault = attr->posix_attr_sigdefault; - return 0; -} - -int posix_spawnattr_setsigdefault(posix_spawnattr_t *attr, - const sigset_t *sigdefault) { - attr->posix_attr_sigdefault = *sigdefault; - return 0; -} diff --git a/libc/stdio/spawna.internal.h b/libc/stdio/spawna.internal.h deleted file mode 100644 index 2635aca1f..000000000 --- a/libc/stdio/spawna.internal.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef COSMOPOLITAN_LIBC_STDIO_SPAWNA_INTERNAL_H_ -#define COSMOPOLITAN_LIBC_STDIO_SPAWNA_INTERNAL_H_ -#include "libc/calls/struct/sched_param.h" -#include "libc/calls/struct/sigset.h" -#if !(__ASSEMBLER__ + __LINKER__ + 0) -COSMOPOLITAN_C_START_ - -struct _posix_spawnattr { - int16_t posix_attr_flags; - int32_t posix_attr_pgroup; - sigset_t posix_attr_sigmask; - sigset_t posix_attr_sigdefault; - int32_t posix_attr_schedpolicy; - struct sched_param posix_attr_schedparam; -}; - -COSMOPOLITAN_C_END_ -#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ -#endif /* COSMOPOLITAN_LIBC_STDIO_SPAWNA_INTERNAL_H_ */ diff --git a/libc/stdio/stdio.mk b/libc/stdio/stdio.mk index 94b395fde..3157a33e9 100644 --- a/libc/stdio/stdio.mk +++ b/libc/stdio/stdio.mk @@ -57,6 +57,8 @@ o//libc/stdio/appendw.o: private \ OVERRIDE_CFLAGS += \ -Os +o/$(MODE)/libc/stdio/posix_spawnattr.o \ +o/$(MODE)/libc/stdio/posix_spawn_file_actions.o \ o/$(MODE)/libc/stdio/mt19937.o: private \ OVERRIDE_CFLAGS += \ -ffunction-sections diff --git a/test/libc/calls/sched_getaffinity_test.c b/test/libc/calls/sched_getaffinity_test.c index 055d91fe4..950bdbdc7 100644 --- a/test/libc/calls/sched_getaffinity_test.c +++ b/test/libc/calls/sched_getaffinity_test.c @@ -23,7 +23,7 @@ #include "libc/intrin/popcnt.h" #include "libc/intrin/safemacros.internal.h" #include "libc/runtime/runtime.h" -#include "libc/stdio/spawn.h" +#include "libc/stdio/posix_spawn.h" #include "libc/testlib/subprocess.h" #include "libc/testlib/testlib.h" #include "libc/thread/thread.h" diff --git a/test/libc/stdio/spawn_test.c b/test/libc/stdio/spawn_test.c index 95fabe42a..9ec4da203 100644 --- a/test/libc/stdio/spawn_test.c +++ b/test/libc/stdio/spawn_test.c @@ -19,10 +19,11 @@ #include "libc/calls/calls.h" #include "libc/dce.h" #include "libc/fmt/conv.h" +#include "libc/intrin/kprintf.h" #include "libc/intrin/safemacros.internal.h" #include "libc/runtime/internal.h" #include "libc/runtime/runtime.h" -#include "libc/stdio/spawn.h" +#include "libc/stdio/posix_spawn.h" #include "libc/stdio/stdio.h" #include "libc/sysv/consts/auxv.h" #include "libc/sysv/consts/o.h"