diff options
Diffstat (limited to 'otherlibs/unix/wait.c')
-rw-r--r-- | otherlibs/unix/wait.c | 76 |
1 files changed, 57 insertions, 19 deletions
diff --git a/otherlibs/unix/wait.c b/otherlibs/unix/wait.c index 12579ddac..fa7f77404 100644 --- a/otherlibs/unix/wait.c +++ b/otherlibs/unix/wait.c @@ -16,33 +16,71 @@ #include <memory.h> #include "unix.h" -value unix_wait() /* ML */ +#include <sys/types.h> +#include <sys/wait.h> + +#ifndef WIFEXITED +#define WIFEXITED(status) ((status) & 0xFF == 0) +#define WEXITSTATUS(status) (((status) >> 8) & 0xFF) +#define WIFSTOPPED(status) ((status) & 0xFF == 0xFF) +#define WSTOPSIG(status) (((status) >> 8) & 0xFF) +#define WTERMSIG(status) ((status) & 0x3F) +#endif + +static value alloc_process_status(pid, status) + int pid, status; { - value res; - int pid, status; + value st, res; Push_roots(r, 1); -#define st r[0] - pid = wait(&status); - if (pid == -1) uerror("wait", Nothing); - switch (status & 0xFF) { - case 0: + + if (WIFEXITED(status)) { st = alloc(1, 0); - Field(st, 0) = Val_int((status >> 8) & 0xFF); - break; - case 0177: + Field(st, 0) = Val_int(WEXITSTATUS(status)); + } + else if (WIFSTOPPED(status)) { st = alloc(1, 2); - Field(st, 0) = Val_int((status >> 8) & 0xFF); - break; - default: - st = alloc(2, 1); - Field(st, 0) = Val_int(status & 0x3F); - Field(st, 1) = status & 0200 ? Val_true : Val_false; - break; + Field(st, 0) = Val_int(WSTOPSIG(status)); + } + else { + st = alloc(1, 1); + Field(st, 0) = Val_int(WTERMSIG(status)); } + r[0] = st; res = alloc_tuple(2); Field(res, 0) = Val_int(pid); - Field(res, 1) = st; + Field(res, 1) = r[0]; Pop_roots(); return res; } +value unix_wait() /* ML */ +{ + int pid, status; + Push_roots(r, 1); + pid = wait(&status); + if (pid == -1) uerror("wait", Nothing); + return alloc_process_status(pid, status); +} + +#ifdef HAS_WAITPID + +static int wait_flag_table[] = { + WNOHANG, WUNTRACED +}; + +value unix_waitpid(flags, pid_req) + value flags, pid_req; +{ + int pid, status; + + pid = waitpid(Int_val(pid_req), &status, + convert_flag_list(flags, wait_flag_table)); + if (pid == -1) uerror("waitpid", Nothing); + return alloc_process_status(pid, status); +} + +#else + +value unix_waitpid() { invalid_argument("waitpid not implemented"); } + +#endif |