9fans - fans of the OS Plan 9 from Bell Labs
 help / color / mirror / Atom feed
From: lucio@proxima.alt.za
To: 9fans@cse.psu.edu
Subject: Re: [9fans] waitpid()
Date: Fri, 16 Apr 2004 18:47:00 +0200	[thread overview]
Message-ID: <f050e9670cf38f611b373308f56733df@proxima.alt.za> (raw)
In-Reply-To: <03be01c423aa$85426530$57d87d50@SOMA>

[-- Attachment #1: Type: text/plain, Size: 1164 bytes --]

> 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

[-- Attachment #2: pidwait.c --]
[-- Type: text/plain, Size: 3069 bytes --]

#include "lib.h"
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#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);
	}
}

  reply	other threads:[~2004-04-16 16:47 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-04-16  8:04 lucio
2004-04-16  8:54 ` Fco.J.Ballesteros
2004-04-16  9:03   ` lucio
2004-04-16 11:10     ` Fco.J.Ballesteros
2004-04-16  9:07   ` lucio
2004-04-16  9:12     ` lucio
2004-04-16 11:36 ` boyd, rounin
2004-04-16 11:46   ` lucio
2004-04-16 12:01     ` boyd, rounin
2004-04-16 16:47       ` lucio [this message]
2004-04-16 17:10         ` boyd, rounin
2004-04-19  6:30           ` lucio

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=f050e9670cf38f611b373308f56733df@proxima.alt.za \
    --to=lucio@proxima.alt.za \
    --cc=9fans@cse.psu.edu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).