diff options
author | Nico Weber <thakis@chromium.org> | 2020-06-19 10:46:45 -0400 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-06-19 22:11:38 +0200 |
commit | 7ffcc5a8b262a1a83de74483ad0a4634f177e011 (patch) | |
tree | f5438d2f0b69bb6a01024eb39cfc116fc1da5deb /Libraries/LibC | |
parent | 68f281c864aea9d6530a31f45b6a06fcb8545038 (diff) | |
download | serenity-7ffcc5a8b262a1a83de74483ad0a4634f177e011.zip |
LibC: Implement file actions for posix_spawn
Diffstat (limited to 'Libraries/LibC')
-rw-r--r-- | Libraries/LibC/spawn.cpp | 57 | ||||
-rw-r--r-- | Libraries/LibC/spawn.h | 9 |
2 files changed, 44 insertions, 22 deletions
diff --git a/Libraries/LibC/spawn.cpp b/Libraries/LibC/spawn.cpp index 774af16d02..62b778105e 100644 --- a/Libraries/LibC/spawn.cpp +++ b/Libraries/LibC/spawn.cpp @@ -34,18 +34,23 @@ #include <spawn.h> -#include <assert.h> +#include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <AK/Function.h> +#include <AK/Vector.h> + +struct posix_spawn_file_actions_state { + Vector<Function<int()>, 4> actions; +}; extern "C" { [[noreturn]] static void posix_spawn_child(const char* path, const posix_spawn_file_actions_t* file_actions, const posix_spawnattr_t* attr, char* const argv[], char* const envp[], int (*exec)(const char*, char* const[], char* const[])) { - if (file_actions) { - // FIXME - } if (attr) { short flags = attr->flags; if (flags & POSIX_SPAWN_RESETIDS) { @@ -94,6 +99,15 @@ extern "C" { // FIXME: POSIX_SPAWN_SETSCHEDULER } + if (file_actions) { + for (const auto& action : file_actions->state->actions) { + if (action() < 0) { + perror("posix_spawn file action"); + exit(127); + } + } + } + exec(path, argv, envp); perror("posix_spawn exec"); exit(127); @@ -127,33 +141,42 @@ int posix_spawnp(pid_t* out_pid, const char* path, const posix_spawn_file_action posix_spawn_child(path, file_actions, attr, argv, envp, execvpe); } - -#if 0 -// FIXME -int posix_spawn_file_actions_addclose(posix_spawn_file_actions_t*, - int) +int posix_spawn_file_actions_addclose(posix_spawn_file_actions_t* actions, int fd) { + actions->state->actions.append([fd]() { return close(fd); }); + return 0; } -int posix_spawn_file_actions_adddup2(posix_spawn_file_actions_t*, - int, int) +int posix_spawn_file_actions_adddup2(posix_spawn_file_actions_t* actions, int old_fd, int new_fd) { + actions->state->actions.append([old_fd, new_fd]() { return dup2(old_fd, new_fd); }); + return 0; } -int posix_spawn_file_actions_addopen(posix_spawn_file_actions_t*, - int, const char*, int, mode_t) +int posix_spawn_file_actions_addopen(posix_spawn_file_actions_t* actions, int want_fd, const char* path, int flags, mode_t mode) { + actions->state->actions.append([want_fd, path, flags, mode]() { + int opened_fd = open(path, flags, mode); + if (opened_fd < 0 || opened_fd == want_fd) + return opened_fd; + if (int rc = dup2(opened_fd, want_fd); rc < 0) + return rc; + return close(opened_fd); + }); + return 0; } -int posix_spawn_file_actions_destroy(posix_spawn_file_actions_t*) +int posix_spawn_file_actions_destroy(posix_spawn_file_actions_t* actions) { + delete actions->state; + return 0; } -int posix_spawn_file_actions_init(posix_spawn_file_actions_t*) +int posix_spawn_file_actions_init(posix_spawn_file_actions_t* actions) { + actions->state = new posix_spawn_file_actions_state; + return 0; } -#endif - int posix_spawnattr_destroy(posix_spawnattr_t*) { diff --git a/Libraries/LibC/spawn.h b/Libraries/LibC/spawn.h index 1fc1289f7f..03bd4c1899 100644 --- a/Libraries/LibC/spawn.h +++ b/Libraries/LibC/spawn.h @@ -52,8 +52,9 @@ enum { POSIX_SPAWN_SETSIGMASK = 1 << 5, }; +struct posix_spawn_file_actions_state; typedef struct { - // FIXME + struct posix_spawn_file_actions_state* state; } posix_spawn_file_actions_t; typedef struct { @@ -68,13 +69,11 @@ typedef struct { int posix_spawn(pid_t*, const char*, const posix_spawn_file_actions_t*, const posix_spawnattr_t*, char* const[], char* const[]); int posix_spawnp(pid_t*, const char*, const posix_spawn_file_actions_t*, const posix_spawnattr_t*, char* const[], char* const[]); -#if 0 int posix_spawn_file_actions_addclose(posix_spawn_file_actions_t*, int); -int posix_spawn_file_actions_adddup2(posix_spawn_file_actions_t*, int, int); -int posix_spawn_file_actions_addopen(posix_spawn_file_actions_t*, int, const char*, int, mode_t); +int posix_spawn_file_actions_adddup2(posix_spawn_file_actions_t*, int old_fd, int new_fd); +int posix_spawn_file_actions_addopen(posix_spawn_file_actions_t*, int fd, const char*, int flags, mode_t); int posix_spawn_file_actions_destroy(posix_spawn_file_actions_t*); int posix_spawn_file_actions_init(posix_spawn_file_actions_t*); -#endif int posix_spawnattr_destroy(posix_spawnattr_t*); int posix_spawnattr_getflags(const posix_spawnattr_t*, short*); |