9fans - fans of the OS Plan 9 from Bell Labs
 help / color / mirror / Atom feed
* [9fans] waitpid()
@ 2004-04-16  8:04 lucio
  2004-04-16  8:54 ` Fco.J.Ballesteros
  2004-04-16 11:36 ` boyd, rounin
  0 siblings, 2 replies; 12+ messages in thread
From: lucio @ 2004-04-16  8:04 UTC (permalink / raw)
  To: 9fans

Posix waitpid() seemingly can select the PID to wait for.  Unlike P9
waitpid(2) which merely returns the PID.

It has always baffled me that originally Unix allowed one to wait for
a child to complete without providing a mechanism to select _which_
child.  In other words, I side with Posix on this issue but I would be
curious to know why what seems obvious to me (in hindsight of course)
was not the design in the first place.

Of some importance is the fact that the current APE implementation has
an understandably faulty waitpid(): it removes PIDs it does not (yet)
care about while looking from the requested one.  When one later goes
looking for one of these discarded PIDs, it naturally does not get
found.

It is unmanageable to cache PIDs somehow within APE wait model,
because it is difficult (unless I miss something) if not impossible to
track PID as children terminate, so they can be added to the cache by
the time a process comes looking for them.

So the big question is whether it is entirely out of the question to
enhance the kernel "wait" functionality so that something resembling
Posix waitpid() can return the termination information for a chosen
PID.

I have not looked at the kernel myself, but until the historical
reasons have been shown to be insignificant, I'm not the best person
to investigate this.

++L




^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [9fans] waitpid()
  2004-04-16  8:04 [9fans] waitpid() lucio
@ 2004-04-16  8:54 ` Fco.J.Ballesteros
  2004-04-16  9:03   ` lucio
  2004-04-16  9:07   ` lucio
  2004-04-16 11:36 ` boyd, rounin
  1 sibling, 2 replies; 12+ messages in thread
From: Fco.J.Ballesteros @ 2004-04-16  8:54 UTC (permalink / raw)
  To: 9fans

> Posix waitpid() seemingly can select the PID to wait for.  Unlike P9
> waitpid(2) which merely returns the PID.

My question is, what does posix say regarding the pids
you don't want. I mean, does it say something like

"when waitpid finds an unwanted pid it guarantees that such
information is not dropped" or the opposite, or just nothing about.
Perhaps rsc knows.

Regarding what should be done, I think that all waitpid() variants
should be dropped. The regular wait one is the one that should
be there IMHO. If you just happen to be looking for a particular
pid, then put your wait() in a lopp. If you also happen to want to
keep the unwanted ones around (should you want to wait for them
in the future), record them in a list.

The plan9 waitpid is a convenience for the case when you look for
a pid but don't care about others. Thus, I wouldn't vote for changing
the native interface; I'd just change ape, but only if posix says so.
Otherwise I'd fix the program using ape.



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [9fans] waitpid()
  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
  1 sibling, 1 reply; 12+ messages in thread
From: lucio @ 2004-04-16  9:03 UTC (permalink / raw)
  To: 9fans

> The plan9 waitpid is a convenience for the case when you look for
> a pid but don't care about others. Thus, I wouldn't vote for changing
> the native interface; I'd just change ape, but only if posix says so.
> Otherwise I'd fix the program using ape.

I hope I'm not reading it wrong: P9 waitpid(2) is a stripped down
version of wait(2) that returns only the "current" PID, no other
details.  It has nothing in common with Posix waitpid().

++L



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [9fans] waitpid()
  2004-04-16  8:54 ` Fco.J.Ballesteros
  2004-04-16  9:03   ` lucio
@ 2004-04-16  9:07   ` lucio
  2004-04-16  9:12     ` lucio
  1 sibling, 1 reply; 12+ messages in thread
From: lucio @ 2004-04-16  9:07 UTC (permalink / raw)
  To: 9fans

> My question is, what does posix say regarding the pids
> you don't want. I mean, does it say something like
> 
> "when waitpid finds an unwanted pid it guarantees that such
> information is not dropped" or the opposite, or just nothing about.

The NetBSD man page is a bit ambiguous, but I think waitpid() and
wait4() specifically wait for the given PID and no other.  Remember
that the child need not have terminated yet, so you may not want to
return at all and carry on waiting even though other children have
terminated (don't ask!).

++L



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [9fans] waitpid()
  2004-04-16  9:07   ` lucio
@ 2004-04-16  9:12     ` lucio
  0 siblings, 0 replies; 12+ messages in thread
From: lucio @ 2004-04-16  9:12 UTC (permalink / raw)
  To: 9fans

> The NetBSD man page is a bit ambiguous, but I think waitpid() and

This might help:

	http://netbsd.gw.com/cgi-bin/man-cgi?wait+2+NetBSD-current

++L



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [9fans] waitpid()
  2004-04-16  9:03   ` lucio
@ 2004-04-16 11:10     ` Fco.J.Ballesteros
  0 siblings, 0 replies; 12+ messages in thread
From: Fco.J.Ballesteros @ 2004-04-16 11:10 UTC (permalink / raw)
  To: 9fans

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

Sorry. I meant the bsd waitpid and not the plan 9 waitpid.

[-- Attachment #2: Type: message/rfc822, Size: 2416 bytes --]

From: lucio@proxima.alt.za
To: 9fans@cse.psu.edu
Subject: Re: [9fans] waitpid()
Date: Fri, 16 Apr 2004 11:03:16 +0200
Message-ID: <098cc449668fabc366ee4852e9cfbaff@proxima.alt.za>

> The plan9 waitpid is a convenience for the case when you look for
> a pid but don't care about others. Thus, I wouldn't vote for changing
> the native interface; I'd just change ape, but only if posix says so.
> Otherwise I'd fix the program using ape.

I hope I'm not reading it wrong: P9 waitpid(2) is a stripped down
version of wait(2) that returns only the "current" PID, no other
details.  It has nothing in common with Posix waitpid().

++L

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [9fans] waitpid()
  2004-04-16  8:04 [9fans] waitpid() lucio
  2004-04-16  8:54 ` Fco.J.Ballesteros
@ 2004-04-16 11:36 ` boyd, rounin
  2004-04-16 11:46   ` lucio
  1 sibling, 1 reply; 12+ messages in thread
From: boyd, rounin @ 2004-04-16 11:36 UTC (permalink / raw)
  To: 9fans

> So the big question is whether it is entirely out of the question to
> enhance the kernel "wait" functionality so that something resembling
> Posix waitpid() can return the termination information for a chosen
> PID.

don't do it in kernel mode.  do it in user mode.  just record the
pid + Waitmsg of the ones that wait has returned and search
this first and if not found go into a wait loop, recording the
pid + Waitmsg as wait returns if it's not the one you want,
otherwise return.

    The Waitmsg structure is allocated by malloc(2) and
    should be freed after use. For programs that only need
    the pid of the exiting program, waitpid returns just the
    pid and discards the rest of the information.

http://plan9.bell-labs.com/magic/man2html/2/wait



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [9fans] waitpid()
  2004-04-16 11:36 ` boyd, rounin
@ 2004-04-16 11:46   ` lucio
  2004-04-16 12:01     ` boyd, rounin
  0 siblings, 1 reply; 12+ messages in thread
From: lucio @ 2004-04-16 11:46 UTC (permalink / raw)
  To: 9fans

> don't do it in kernel mode.  do it in user mode.  just record the
> pid + Waitmsg of the ones that wait has returned and search
> this first and if not found go into a wait loop, recording the
> pid + Waitmsg as wait returns if it's not the one you want,
> otherwise return.

Hm, I thought it couldn't be done, but the above makes sense.  Now if
I just had rob's skills with linked lists...

I'll report back.

++L



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [9fans] waitpid()
  2004-04-16 11:46   ` lucio
@ 2004-04-16 12:01     ` boyd, rounin
  2004-04-16 16:47       ` lucio
  0 siblings, 1 reply; 12+ messages in thread
From: boyd, rounin @ 2004-04-16 12:01 UTC (permalink / raw)
  To: 9fans

> Hm, I thought it couldn't be done, but the above makes sense.  Now if

well i thought i'd coded it before.

look at pipe.c:

    http://www.insultant.net/repo/plan9/mace.bundle

1st Ed, 2 day rush job port done in 1994.



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [9fans] waitpid()
  2004-04-16 12:01     ` boyd, rounin
@ 2004-04-16 16:47       ` lucio
  2004-04-16 17:10         ` boyd, rounin
  0 siblings, 1 reply; 12+ messages in thread
From: lucio @ 2004-04-16 16:47 UTC (permalink / raw)
  To: 9fans

[-- 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);
	}
}

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [9fans] waitpid()
  2004-04-16 16:47       ` lucio
@ 2004-04-16 17:10         ` boyd, rounin
  2004-04-19  6:30           ` lucio
  0 siblings, 1 reply; 12+ messages in thread
From: boyd, rounin @ 2004-04-16 17:10 UTC (permalink / raw)
  To: 9fans

> Thanks, Boyd, for the guidelines and also to Nemo for suggesting a
> similar tack in previous private mail.

i could of used a list but NOFILE was small when i wrote the original,
so an array more than sufficed.

wait4() -- therein lies madness.



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [9fans] waitpid()
  2004-04-16 17:10         ` boyd, rounin
@ 2004-04-19  6:30           ` lucio
  0 siblings, 0 replies; 12+ messages in thread
From: lucio @ 2004-04-19  6:30 UTC (permalink / raw)
  To: 9fans

> wait4() -- therein lies madness.

Probably, but it is merely a generalisation.  I doubt it is used much
directly and it does not defeat the original intentions.  Pity about
the name, really.

++L



^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2004-04-19  6:30 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-04-16  8:04 [9fans] waitpid() 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
2004-04-16 17:10         ` boyd, rounin
2004-04-19  6:30           ` lucio

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).