>  > Q: Is there another way to wait without hanging?
>  > 
>  >    I tryied to install a signal handler on SIGCHLD. But for some reasons, I
>  >    don't wait for all children, because some signals get lost, or even worse
>  >    I get into a state, where I don't get any SIGCHLD signal anymore. After a
>  >    while my process can't fork anymore because there are too many unwaited
>  >    children (on irix 6.0.1) :-(.
>  There's undocumented special code in signalmodule.c which requires
>  your handler to re-instate the signal handler for this signal, because
>  otherwise the two-stage way of handling signals in Python would cause
>  infinite recursion given the way this signal is generated (if there's
>  still a child waiting when you return from the C signal handler, the
>  signal is sent again by the OS).  I don't know if this code works
>  correctly -- in fact I don't know what the guaranteed and actual
>  semantics of SIGCHLD are in Posix and other Unix versions.
It was me who brought up the problem with the SIGCHLD :-). In the meantime I
read in the 'UNIX Network Programming' bible [UNIX Network Programming';
W. Richard Stevens; Prentice Hall; 1990]. Stevens points out, that SIGCLD under
System V has a special semantics: if SIGCLD is set to SIG_IGN, then exited
children do not become zombies. To emulate the same under 4.3BSD based UNIX he
suggests the following handler:
	#include <sys/wait.h>
	#include <signal.h>
	/* Beware that the calling process may get an interupted system call
	 * when we return, so the had better handle that.
	*/
	sig_child()
	{
	#ifdef BSD
		 int pid;
		 union wait status;
		 while ( pid = wait3(&status, WNOHANG, (struct rusage*) 0 )) > 0)
			 ;
	#endif /* BSD */
	}
       
Later he uses this in the following way:
  ...
	#ifdef SIGTSTP
		 signal(SIGCLD, sig_child); /* BSD */
	#else
		 signal(SIGCLD, SIG_IGN);  /* System V */
	#endif
Well, using SIGTSTP as indicator for BSD seems to be a funny trick...
>From which I would conclude the following python code:
	def is_BSD():
		try:
			# funny way to find out if this is SYS V 
			from signal import SIGTSTP
			return 1
		except ImportError:
			return 0
	
	def sig_child():
		import posix
		while 1:
			# wait all dead children...
			pid,status=posix.waitpid(-1,posix.WNOHANG)
			if not pid:
				# done
				return
	def ignore_children():
		import signal
		if is_BSD():
			signal.signal(signal.SIGCHLD,sig_child)
		else:
			signal.signal(signal.SIGCHLD,signal.SIG_IGN)
	
Ok, I'm not sure if this is_BSD() is a good idea or not. One could
just always install the sig_chld() handler since you patched the signal module
anyway ...
>  > Q: Would it make sense to export WNOHANG from the posix module?
>    Yes.  It's not in the current beta of 1.2 and I would prefer to add as
>  few things as possible.  However if you come up with a clean patch for
>  posixmodule.c that adds these wait-related symbols, I might be
>  convinced to add them.  (Something similar has already been done with
>  socket related symbols.)
Here's a patch based on the newest posixmodule.c -- I hope it's clean enough
Michael :-)
--- posixmodule.c.~1~	Tue Mar 21 16:55:00 1995
+++ posixmodule.c	Tue Mar 21 17:23:03 1995
@@ -1468,6 +1468,24 @@
 	{NULL,		NULL}		 /* Sentinel */
 };
 
+#ifdef HAVE_WAITPID
+/* Convenience routine to export an integer value.
+   For simplicity, errors (which are unlikely anyway) are ignored. */
+
+static void
+BUILD_FUNC_DEF_3(insint,PyObject *,d,char *,name,int,value)
+{
+	PyObject *v = PyInt_FromLong((long) value);
+	if (v == NULL) {
+		/* Don't bother reporting this error */
+		PyErr_Clear();
+	}
+	else {
+		PyDict_SetItemString(d, name, v);
+		Py_DECREF(v);
+	}
+}
+#endif /* HAVE_WAITPID */
 
 #ifdef NT
 void
@@ -1484,6 +1502,12 @@
 		fatal("can't define nt.environ");
 	DECREF(v);
 	
+#ifdef HAVE_WAITPID
+#  ifdef WNOHANG /* let's be shure :-) */
+	insint(d, "WNOHANG", WNOHANG);
+#  endif /* WNOHANG */
+#endif /* HAVE_WAITPID */
+	
 	/* Initialize nt.error exception */
 	PosixError = newstringobject("nt.error");
 	if (PosixError == NULL || dictinsert(d, "error", PosixError) != 0)
@@ -1503,6 +1527,12 @@
 	if (v == NULL || dictinsert(d, "environ", v) != 0)
 		fatal("can't define posix.environ");
 	DECREF(v);
+
+#ifdef HAVE_WAITPID
+#  ifdef WNOHANG /* let's be shure :-) */
+	insint(d, "WNOHANG", WNOHANG);
+#  endif /* WNOHANG */
+#endif /* HAVE_WAITPID */
 	
 	/* Initialize posix.error exception */
 	PosixError = newstringobject("posix.error");
-- ___ _ _ ___ _ | __) | \/ | | ) | | Michael Scharf | _) | | | -< | |_ EMail: scharf@EMBL-Heidelberg.de |___) |_||_| |___) |___) http://www.EMBL-Heidelberg.de/~scharf/