summaryrefslogtreecommitdiff
path: root/process-posix.c
diff options
context:
space:
mode:
Diffstat (limited to 'process-posix.c')
-rw-r--r--process-posix.c88
1 files changed, 31 insertions, 57 deletions
diff --git a/process-posix.c b/process-posix.c
index 53363b6..d683abe 100644
--- a/process-posix.c
+++ b/process-posix.c
@@ -6,40 +6,11 @@
struct Process {
pid_t pid;
int pipe;
- bool stopped;
- int exit_status; // INT_MAX if process was terminated
+ char error[64];
};
-static char process_error[64];
-static Process *processes;
-
-static void process_sigaction_sigchld(int signal, siginfo_t *info, void *context) {
- (void)context;
- if (signal == SIGCHLD) {
- pid_t pid = info->si_pid;
- arr_foreach_ptr(processes, Process, process) {
- if (process->pid == pid) {
- process->stopped = true;
- if (info->si_code == CLD_EXITED)
- process->exit_status = info->si_status;
- else
- process->exit_status = INT_MAX;
- }
- }
- }
-}
-
-void process_init(void) {
- struct sigaction act = {0};
- act.sa_sigaction = process_sigaction_sigchld;
- act.sa_flags = SA_SIGINFO | SA_NOCLDSTOP;
- sigaction(SIGCHLD, &act, NULL);
-}
-
-
-
-Process *process_exec(char const *program, char **argv) {
- Process *proc = NULL;
+bool process_exec(Process *proc, char const *program, char **argv) {
+ bool success = false;
int pipefd[2];
if (pipe(pipefd) == 0) {
@@ -56,21 +27,21 @@ Process *process_exec(char const *program, char **argv) {
exit(127);
}
} else if (pid > 0) {
- proc = arr_addp(processes);
// parent process
close(pipefd[1]);
fcntl(pipefd[0], F_SETFL, fcntl(pipefd[0], F_GETFL) | O_NONBLOCK); // set pipe to non-blocking
proc->pid = pid;
proc->pipe = pipefd[0];
+ success = true;
}
} else {
- strbuf_printf(process_error, "%s", strerror(errno));
+ strbuf_printf(proc->error, "%s", strerror(errno));
}
- return proc;
+ return success;
}
-char const *process_geterr(void) {
- return *process_error ? process_error : NULL;
+char const *process_geterr(Process *p) {
+ return p->error;
}
long long process_read(Process *proc, char *data, size_t size) {
@@ -81,7 +52,7 @@ long long process_read(Process *proc, char *data, size_t size) {
} else if (errno == EAGAIN) {
return -1;
} else {
- strbuf_printf(process_error, "%s", strerror(errno));
+ strbuf_printf(proc->error, "%s", strerror(errno));
return -2;
}
@@ -89,31 +60,34 @@ long long process_read(Process *proc, char *data, size_t size) {
void process_stop(Process *proc) {
kill(proc->pid, SIGKILL);
- // get rid of zombie process
- waitpid(proc->pid, NULL, 0);
close(proc->pipe);
- for (u32 i = 0; i < arr_len(processes); ++i)
- if (processes[i].pid == proc->pid)
- arr_remove(processes, i);
+ proc->pid = 0;
+ proc->pipe = 0;
}
-#include <sys/resource.h>
-int process_check_status(Process *proc, char *message, size_t message_size) {
- if (proc->stopped) {
- int status = proc->exit_status;
- process_stop(proc);
- switch (status) {
- case 0:
- if (message) str_printf(message, message_size, "exited successfully");
- return +1;
- case INT_MAX:
- if (message) str_printf(message, message_size, "terminated by a signal");
- return -1;
- default:
- if (message) str_printf(message, message_size, "exited with code %d", status);
+int process_check_status(Process *proc, char *message, size_t message_size) {
+ int wait_status = 0;
+ if (waitpid(proc->pid, &wait_status, WNOHANG) >= 0) {
+ if (WIFEXITED(wait_status)) {
+ int code = WEXITSTATUS(wait_status);
+ if (code == 0) {
+ str_printf(message, message_size, "exited successfully");
+ return +1;
+ } else {
+ str_printf(message, message_size, "exited with code %d", code);
+ return -1;
+ }
+ } else if (WIFSIGNALED(wait_status)) {
+ str_printf(message, message_size, "terminated by signal %d", WTERMSIG(wait_status));
return -1;
}
+ return 0;
+ } else if (errno == ECHILD) {
+ // this process is gone or something?
+ str_printf(message, message_size, "process ended unexpectedly");
+ return -1;
} else {
+ // probably shouldn't happen
return 0;
}
}