From mboxrd@z Thu Jan 1 00:00:00 1970 Message-ID: To: 9fans@cse.psu.edu Subject: Re: [9fans] waitpid() From: lucio@proxima.alt.za In-Reply-To: <03be01c423aa$85426530$57d87d50@SOMA> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="upas-gqsuhdebffrzuokhpurranldze" Date: Fri, 16 Apr 2004 18:47:00 +0200 Topicbox-Message-UUID: 5dd7eb86-eacd-11e9-9e20-41e7f4b1d025 This is a multi-part message in MIME format. --upas-gqsuhdebffrzuokhpurranldze Content-Disposition: inline Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit > well i thought i'd coded it before. > > look at pipe.c: Thanks, Boyd, for the guidelines and also to Nemo for suggesting a similar tack in previous private mail. I have no idea whether this is adequate, but it matches some superficial expectations, at least. I'm including my efforts here because I'm going away for the weekend and somebody may have the opportunity in the meantime to look at the code and use it, but more specially to inspect it and hopefully make suggestions on how to improve it (other than in code layout, I have a great deal of trouble omitting spaces as seems to be the norm in Plan 9 sources, sorry about that). I'll be grateful for all and any feedback, please be alerted that the code is designed for use in the APE environment, modelled on the NetBSD wait(2) man page I mentioned earlier. It is intended to replace /sys/src/ape/lib/ap/plan9/wait.c in its entirety, but I have not checked this to any degree. The module compiles and runs with $ pcc -D_PLAN9_SOURCE -D_POSIX_SOURCE -I/sys/src/ape/lib/ap/plan9 -c pidwait.c $ 8l -o pidwait pidwait.8 $ pidwait from my home directory. ++L --upas-gqsuhdebffrzuokhpurranldze Content-Disposition: attachment; filename=pidwait.c Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit #include "lib.h" #include #include #include #include #include #include #include "sys9.h" pid_t wait(int *status); pid_t waitpid(pid_t wpid, int *status, int options); pid_t wait3(int *status, int options, Waitmsg *waitmsg); pid_t wait4(pid_t wpid, int *status, int options, Waitmsg *waitmsg); /* ** PID cache */ typedef struct wdesc wdesc; struct wdesc { pid_t w_pid; Waitmsg *w_msg; wdesc *w_next; }; static wdesc *wd = 0; static Waitmsg * lookpid (pid_t pid) { wdesc **wp0 = &wd, *wp; Waitmsg *msg; printf ("PID+ %d ", pid); if (pid == -1) { if (wd == 0) return 0; pid = wd->w_pid; } for (wp = wd; wp; wp = wp->w_next) { printf ("looking: %d.", wp->w_pid); if (wp->w_pid == pid) { msg = wp->w_msg; *wp0 = wp->w_next; printf (" yes\n"); free (wp); return msg; } wp0 = &(wp->w_next); } printf (" no\n"); return 0; } static void addpid (Waitmsg *msg) { wdesc **wp0 = &wd, *wp = malloc (sizeof (wdesc)); printf ("ADD: %d\n", msg->pid); wp->w_msg = msg; wp->w_pid = msg->pid; wp->w_next = wd; wd = wp; } pid_t wait (int *status) { return wait4(-1, status, 0, 0); } pid_t waitpid (pid_t wpid, int *status, int options) { return wait4(wpid, status, options, 0); } pid_t wait3 (int *status, int options, Waitmsg *waitmsg) { return wait4(-1, status, options, waitmsg); } pid_t wait4 (pid_t wpid, int *status, int options, Waitmsg *waitmsg) { Waitmsg *w; if (options & WNOHANG) { char pname[128]; int i; struct stat buf; snprintf (pname, sizeof (pname), "/proc/%d/wait", getpid()); i = stat (pname, &buf); if (i >= 0 && buf.st_size == 0) return 0; } if (w = lookpid (wpid)) { waitmsg = w; wpid = w->pid; return wpid; } w = _WAIT(); while (w) { if (wpid <= 0) { waitmsg = w; wpid = w->pid; return wpid; } if (w->pid == wpid) { if (status) { int r = 0; int t = 0; char *bp, *ep; 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; } } *status = (r << 8) | t; } waitmsg = w; wpid = w->pid; return wpid; } else { addpid (w); } w = _WAIT(); } if (w == 0) { _syserrno (); } } #define N (5) main () { int x, status; pid_t p, pid[N]; Waitmsg waitmsg; for (x = 0; x < N; x++) { switch (pid[x] = fork()) { case 0: sleep (5); exit (0); case -1: _syserrno (); break; default: sleep (3); break; } printf ("ID[%d]: %d\n", x, pid[x]); } for (x = 0; x < N; x++) { if (p = wait4 (pid[x], &status, 0, &waitmsg)) printf ("PID[%d]: %d\n", x, p); } } --upas-gqsuhdebffrzuokhpurranldze--