diff options
Diffstat (limited to 'source/kit/process.posix.c')
-rw-r--r-- | source/kit/process.posix.c | 319 |
1 files changed, 0 insertions, 319 deletions
diff --git a/source/kit/process.posix.c b/source/kit/process.posix.c deleted file mode 100644 index 961f058..0000000 --- a/source/kit/process.posix.c +++ /dev/null @@ -1,319 +0,0 @@ -#include "process.h" - -#if !defined(_WIN32) || defined(__CYGWIN__) -# include "status.h" - -# include <assert.h> -# include <fcntl.h> -# include <signal.h> -# include <sys/wait.h> - -static char *kit_process_argv_null_[] = { "", NULL }; -static char *kit_process_env_null_[] = { NULL }; - -static char *kit_process_str_(kit_str_t s) { - // FIXME - // - - return BS(s); -} - -static char **kit_init_argv_(kit_process_args_t args, u32 flags) { - // TODO - // - - if ((flags & KIT_PROCESS_NO_ARGUMENTS) != 0) - return kit_process_argv_null_; - - return NULL; -} - -static char **kit_init_envp_(kit_process_env_t env, u32 flags) { - // TODO - // - - if ((flags & KIT_PROCESS_NO_ENVIRONMENT) != 0) - return kit_process_env_null_; - - return NULL; -} - -s32 kit_process_init(kit_process_t *p, kit_process_info_t info) { - assert(p != NULL); - assert(info.working_directory.size == 0 || - info.working_directory.values != NULL); - - if (p == NULL || (info.working_directory.size != 0 && - info.working_directory.values == NULL)) - return KIT_ERROR_INVALID_ARGUMENT; - - memset(p, 0, sizeof *p); - - p->_stdin = -1; - p->_stdout = -1; - p->_stderr = -1; - - signal(SIGCHLD, SIG_IGN); - signal(SIGALRM, SIG_IGN); // pipes - - i32 pipe_in[2]; - i32 pipe_out[2]; - i32 pipe_err[2]; - - if ((info.flags & KIT_PROCESS_NO_PIPES) == 0) { - if (pipe(pipe_in) == -1) { - assert(0); - return KIT_ERROR_PIPE_FAILED; - } - - if (pipe(pipe_out) == -1) { - assert(0); - close(pipe_in[0]); - close(pipe_in[1]); - return KIT_ERROR_PIPE_FAILED; - } - - if (pipe(pipe_err) == -1) { - assert(0); - close(pipe_in[0]); - close(pipe_in[1]); - close(pipe_out[0]); - close(pipe_out[1]); - return KIT_ERROR_PIPE_FAILED; - } - - // non-blocking writing for stdout, stderr - if (fcntl(pipe_out[1], F_SETFL, O_NONBLOCK) == -1 || - fcntl(pipe_err[1], F_SETFL, O_NONBLOCK) == -1) { - assert(0); - close(pipe_in[0]); - close(pipe_in[1]); - close(pipe_out[0]); - close(pipe_out[1]); - close(pipe_err[0]); - close(pipe_err[1]); - return KIT_ERROR_PIPE_FAILED; - } - } - - pid_t id = fork(); - - switch (id) { - case -1: return KIT_ERROR_FORK_FAILED; - - case 0: - // Child process - // - - p->status = KIT_OK; - p->current_is_forked = 1; - - if ((info.flags & KIT_PROCESS_NO_PIPES) == 0) { - // Redirect IO - if (dup2(pipe_in[0], STDIN_FILENO) == -1 || - dup2(pipe_out[1], STDOUT_FILENO) == -1 || - dup2(pipe_err[1], STDERR_FILENO) == -1) { - assert(0); - close(pipe_in[0]); - close(pipe_in[1]); - close(pipe_out[0]); - close(pipe_out[1]); - close(pipe_err[0]); - close(pipe_err[1]); - return KIT_ERROR_DUP2_FAILED; - } - - // Close pipes - close(pipe_in[0]); - close(pipe_in[1]); - close(pipe_out[0]); - close(pipe_out[1]); - close(pipe_err[0]); - close(pipe_err[1]); - } - - // Change working directory - if (info.working_directory.size != 0 && - chdir(kit_process_str_(info.working_directory)) == -1) { - assert(0); - return KIT_ERROR_CHDIR_FAILED; - } - - if ((info.flags & KIT_PROCESS_FORK) == 0) { - execve(kit_process_str_(info.file_name), - kit_init_argv_(info.command_line, info.flags), - kit_init_envp_(info.environment, info.flags)); - // Doesn't return on success - - return KIT_ERROR_EXECVE_FAILED; - } - - return KIT_OK; - - default: - // Parent process - // - - p->status = KIT_OK; - p->current_is_forked = 0; - p->_ready = 1; - p->_running = 1; - p->_id = id; - - if ((info.flags & KIT_PROCESS_NO_PIPES) == 0) { - p->_stdin = pipe_in[1]; - p->_stdout = pipe_out[0]; - p->_stderr = pipe_err[0]; - - // Close unused pipes - close(pipe_in[0]); - close(pipe_out[1]); - close(pipe_err[1]); - } - } - - return KIT_OK; -} - -void kit_process_cleanup(kit_process_t *p) { - assert(p != NULL); - assert(p->_ready); - - if (p == NULL || !p->_ready) - return; - - if (p->_stdin != -1) - close(p->_stdin); - if (p->_stdout != -1) - close(p->_stdout); - if (p->_stderr != -1) - close(p->_stderr); - - memset(p, 0, sizeof *p); -} - -i64 kit_process_write_stdin(kit_process_t *p, kit_str_t in_data) { - assert(p != NULL && (in_data.size == 0 || in_data.values != NULL) && - p->_running); - - if (p == NULL || (in_data.size != 0 && in_data.values == NULL)) - return KIT_ERROR_INVALID_ARGUMENT; - if (in_data.size == 0 || !p->_running || p->_stdin == -1) - return 0; - - i64 n = write(p->_stdin, in_data.values, in_data.size); - - assert(n >= 0); - if (n < 0) - return 0; - - return n; -} - -i64 kit_process_read_stdout(kit_process_t *p, kit_str_t out_data) { - assert(p != NULL && - (out_data.size == 0 || out_data.values != NULL) && - p->_ready); - - if (p == NULL || (out_data.size != 0 && out_data.values == NULL)) - return KIT_ERROR_INVALID_ARGUMENT; - if (out_data.size == 0 || !p->_ready || p->_stdout == -1) - return 0; - - i64 n = read(p->_stdout, out_data.values, out_data.size); - - assert(n >= 0); - if (n < 0) - return 0; - - return n; -} - -i64 kit_process_read_stderr(kit_process_t *p, kit_str_t out_data) { - assert(p != NULL && - (out_data.size == 0 || out_data.values != NULL) && - p->_ready); - - if (p == NULL || (out_data.size != 0 && out_data.values == NULL)) - return KIT_ERROR_INVALID_ARGUMENT; - if (out_data.size == 0 || !p->_ready || p->_stderr == -1) - return 0; - - i64 n = read(p->_stderr, out_data.values, out_data.size); - - assert(n >= 0); - if (n < 0) - return 0; - - return n; -} - -s32 kit_process_terminate(kit_process_t *p) { - assert(p != NULL && p->_running); - if (p == NULL || !p->_running) - return KIT_ERROR_INVALID_ARGUMENT; - - if (kill(p->_id, SIGTERM) == -1) - return KIT_ERROR_KILL_FAILED; - - return KIT_OK; -} - -b8 kit_process_alive(kit_process_t *p) { - assert(p != NULL); - if (p == NULL || p->status != KIT_OK) - return 0; - - if (!p->_running) - return 0; - - int status; - - pid_t id = waitpid(p->_id, &status, WNOHANG); - - if (id == -1) { - p->status = KIT_ERROR_WAITPID_FAILED; - return 0; - } - - if (id == 0) - return 1; - - if (WIFEXITED(status)) { - p->exit_code = WEXITSTATUS(status); - p->_running = 0; - return 0; - } - - return 1; -} - -s32 kit_process_wait(kit_process_t *p) { - assert(p != NULL); - if (p == NULL) - return KIT_ERROR_INVALID_ARGUMENT; - - if (p->status != KIT_OK) - return p->status; - if (!p->_running) - return KIT_OK; - - for (;;) { - int status; - - pid_t id = waitpid(p->_id, &status, 0); - - if (id == -1) - return KIT_ERROR_WAITPID_FAILED; - - if (WIFEXITED(status)) { - p->exit_code = WEXITSTATUS(status); - p->_running = 0; - break; - } - } - - return KIT_OK; -} - -#endif |