From e5888a1ffdae813d7575f5fb02275c6bb07e5199 Mon Sep 17 00:00:00 2001 From: Taru Karttunen Date: Wed, 30 Mar 2011 15:46:40 +0300 Subject: Import sources from 2011-03-30 iso image --- sys/src/ape/lib/ap/plan9/wait.c | 150 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100755 sys/src/ape/lib/ap/plan9/wait.c (limited to 'sys/src/ape/lib/ap/plan9/wait.c') diff --git a/sys/src/ape/lib/ap/plan9/wait.c b/sys/src/ape/lib/ap/plan9/wait.c new file mode 100755 index 000000000..ac1ab13da --- /dev/null +++ b/sys/src/ape/lib/ap/plan9/wait.c @@ -0,0 +1,150 @@ +#include "lib.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "sys9.h" +#include "dir.h" + +/* + * status not yet collected for processes that have exited + */ +typedef struct Waited Waited; +struct Waited { + Waitmsg* msg; + Waited* next; +}; +static Waited *wd; + +static Waitmsg * +lookpid(int pid) +{ + Waited **wl, *w; + Waitmsg *msg; + + for(wl = &wd; (w = *wl) != nil; wl = &w->next) + if(pid <= 0 || w->msg->pid == pid){ + msg = w->msg; + *wl = w->next; + free(w); + return msg; + } + return 0; +} + +static void +addpid(Waitmsg *msg) +{ + Waited *w; + + w = malloc(sizeof(*w)); + if(w == nil){ + /* lost it; what can we do? */ + free(msg); + return; + } + w->msg = msg; + w->next = wd; + wd = w; +} + +static int +waitstatus(Waitmsg *w) +{ + int r, t; + char *bp, *ep; + + r = 0; + t = 0; + if(w->msg[0]){ + /* message is 'prog pid:string' */ + bp = w->msg; + while(*bp){ + if(*bp++ == ':') + break; + } + if(*bp == 0) + bp = w->msg; + r = strtol(bp, &ep, 10); + if(*ep == 0){ + if(r < 0 || r >= 256) + r = 1; + }else{ + t = _stringsig(bp); + if(t == 0) + r = 1; + } + } + return (r<<8) | t; +} + +static void +waitresource(struct rusage *ru, Waitmsg *w) +{ + memset(ru, 0, sizeof(*ru)); + ru->ru_utime.tv_sec = w->time[0]/1000; + ru->ru_utime.tv_usec = (w->time[0]%1000)*1000; + ru->ru_stime.tv_sec = w->time[1]/1000; + ru->ru_stime.tv_usec = (w->time[1]%1000)*1000; +} + +pid_t +wait(int *status) +{ + return wait4(-1, status, 0, nil); +} + +pid_t +waitpid(pid_t wpid, int *status, int options) +{ + return wait4(wpid, status, options, nil); +} + +pid_t +wait3(int *status, int options, struct rusage *res) +{ + return wait4(-1, status, options, res); +} + +pid_t +wait4(pid_t wpid, int *status, int options, struct rusage *res) +{ + char pname[50]; + Dir *d; + Waitmsg *w; + + w = lookpid(wpid); + if(w == nil){ + if(options & WNOHANG){ + snprintf(pname, sizeof(pname), "/proc/%d/wait", getpid()); + d = _dirstat(pname); + if(d != nil && d->length == 0){ + free(d); + return 0; + } + free(d); + } + for(;;){ + w = _WAIT(); + if(w == nil){ + _syserrno(); + return -1; + } + if(wpid <= 0 || w->pid == wpid) + break; + addpid(w); + } + } + if(res != nil) + waitresource(res, w); + if(status != nil) + *status = waitstatus(w); + wpid = w->pid; + free(w); + return wpid; +} -- cgit v1.2.3