From 8c33c921b485f4c07d2f5943a7dd64b9375ecafc Mon Sep 17 00:00:00 2001 From: Giacomo Tesio Date: Mon, 1 May 2017 23:57:05 +0200 Subject: [PATCH] libposix: draft waitpid (still broken) --- sys/include/posix.h | 1 + sys/src/lib/posix/initlib.c | 9 +++- sys/src/lib/posix/processes.c | 80 ++++++++++++++++++++++++++++++++++- 3 files changed, 88 insertions(+), 2 deletions(-) diff --git a/sys/include/posix.h b/sys/include/posix.h index 589932d..e5a2a7a 100644 --- a/sys/include/posix.h +++ b/sys/include/posix.h @@ -51,6 +51,7 @@ extern int POSIX_stat(int *errnop, const char *file, void *stat); extern clock_t POSIX_times(int *errnop, void *tms); extern int POSIX_unlink(int *errnop, const char *name); extern int POSIX_wait(int *errnop, int *status); +extern int POSIX_waitpid(int *errnop, int pid, int *status, int options); extern long POSIX_write(int *errnop, int fd, const void *buf, size_t len); extern int POSIX_gettimeofday(int *errnop, void *timeval, void *timezone); extern char* POSIX_getenv(int *errnop, const char *name); diff --git a/sys/src/lib/posix/initlib.c b/sys/src/lib/posix/initlib.c index f720b70..817858f 100644 --- a/sys/src/lib/posix/initlib.c +++ b/sys/src/lib/posix/initlib.c @@ -21,6 +21,7 @@ #include "internal.h" extern int *__libposix_errors_codes; +extern WaitList **__libposix_wait_list; static int __initialized; static void @@ -35,14 +36,20 @@ void libposix_init(int argc, char *argv[], PosixInit init) { extern int main(int, char**); - int error_codes[ERRNO_LAST-ERRNO_FIRST]; + WaitList *wait_list; int status; + int error_codes[ERRNO_LAST-ERRNO_FIRST]; + assert(__initialized == 0); /* initialize PosixErrors map */ memset(error_codes, 0, sizeof(error_codes)); __libposix_errors_codes=error_codes; + + /* initialize wait_list; see also POSIX_fork and POSIX_exit */ + wait_list = nil; + __libposix_wait_list = &wait_list; if(!atnotify(__libposix_note_handler, 1)) sysfatal("libposix: atnotify"); diff --git a/sys/src/lib/posix/processes.c b/sys/src/lib/posix/processes.c index c68e3ce..2d84602 100644 --- a/sys/src/lib/posix/processes.c +++ b/sys/src/lib/posix/processes.c @@ -22,6 +22,15 @@ extern char **environ; +typedef struct WaitList WaitList; +struct WaitList +{ + int pid; + int status; + WaitList *next; +}; + +WaitList **__libposix_wait_list; static PosixSignalTrampoline __libposix_signal_trampoline; static PosixExitStatusTranslator __libposix_exit_status_translator; @@ -31,6 +40,20 @@ void POSIX_exit(int code) { char buf[64], *s; + WaitList *wl, c; + + /* free the wait list as the memory is shared */ + wl = *__libposix_wait_list; + if(wl != nil){ + *__libposix_wait_list = nil; + do + { + c = wl; + wl = c->next; + free(c); + } + while (wl != nil) + } if(__libposix_exit_status_translator != nil &&(s = __libposix_exit_status_translator(code)) != nil){ @@ -75,9 +98,19 @@ int POSIX_wait(int *errnop, int *status) { Waitmsg *w; + WaitList *l; char *s; int ret = 0, pid; + l = *__libposix_wait_list; + if(l != nil){ + *__libposix_wait_list = l->next; + *status = l->status; + pid = l->pid; + free(l); + return pid; + } + w = wait(); if(w == nil){ *errnop = __libposix_get_errno(PosixECHILD); @@ -100,6 +133,45 @@ POSIX_wait(int *errnop, int *status) return pid; } +int +POSIX_waitpid(int *errnop, int pid, int *status, int options) +{ + Waitmsg *w; + WaitList *c, **nl; + char *s; + int ret = 0, pid; + + nl = __libposix_wait_list; + l = *nl' + while(l != nil){ + } + if(l != nil){ + + } + + w = wait(); + if(w == nil){ + *errnop = __libposix_get_errno(PosixECHILD); + return -1; + } + pid = w->pid; + if(w->msg[0] != 0){ + s = strstr(w->msg, __POSIX_EXIT_PREFIX); + if(s){ + s += (sizeof(__POSIX_EXIT_PREFIX)/sizeof(char) - 1); + ret = atoi(s); + } else { + /* TODO: setup configurable interpretations */ + ret = 127; + } + } + if(status != nil) + *status = ret; + free(w); + return pid; + +} + static int note_all_writable_processes(int *errnop, char *note) { @@ -162,7 +234,13 @@ POSIX_getppid(int *errnop) int POSIX_fork(int *errnop) { - return fork(); + int pid = fork(); + + if(pid == 0){ + /* reset wait list for the child */ + *__libposix_wait_list = nil; + } + return pid; } static int