Index: configure.in =================================================================== RCS file: /cvsroot/python/python/dist/src/configure.in,v retrieving revision 1.485 diff -u -b -B -u -r1.485 configure.in --- configure.in 2 Jun 2005 13:09:24 -0000 1.485 +++ configure.in 1 Aug 2005 22:21:06 -0000 @@ -2107,7 +2107,7 @@ setlocale setregid setreuid setsid setpgid setpgrp setuid setvbuf snprintf \ sigaction siginterrupt sigrelse strftime \ sysconf tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \ - truncate uname unsetenv utimes waitpid wcscoll _getpty) + truncate uname unsetenv utimes waitpid wait4 wcscoll _getpty) # For some functions, having a definition is not sufficient, since # we want to take their address. Index: Doc/lib/libos.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libos.tex,v retrieving revision 1.164 diff -u -b -B -u -r1.164 libos.tex --- Doc/lib/libos.tex 18 Jul 2005 08:16:33 -0000 1.164 +++ Doc/lib/libos.tex 1 Aug 2005 22:21:07 -0000 @@ -1693,6 +1693,15 @@ return suitable process handles. \end{funcdesc} +\begin{funcdesc}{wait4}{pid, options} +Similar to waitpid, except a 3 element tuple, containing the child's +process id, exit status indication, and resource usage information +is returned. Refer to \function{getrusage()} for details on resource +usage information. The arguments to \function{wait4()} are the same as +those provided to \function{waitpid()}. +Availability: \UNIX, ? +\end{funcdesc} + \begin{datadesc}{WNOHANG} The option for \function{waitpid()} to return immediately if no child process status is available immediately. The function returns Index: Modules/posixmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/posixmodule.c,v retrieving revision 2.337 diff -u -b -B -u -r2.337 posixmodule.c --- Modules/posixmodule.c 5 Jul 2005 15:21:58 -0000 2.337 +++ Modules/posixmodule.c 1 Aug 2005 22:21:07 -0000 @@ -136,6 +136,10 @@ #endif /* ! __WATCOMC__ || __QNX__ */ #endif /* ! __IBMC__ */ +#ifdef HAVE_WAIT4 +#include "resourcemodule.h" +#endif + #ifndef _MSC_VER #if defined(__sgi)&&_COMPILER_VERSION>=700 @@ -4881,6 +4885,70 @@ } #endif /* HAVE_SETGROUPS */ +#ifdef HAVE_WAIT4 +PyDoc_STRVAR(posix_wait4__doc__, +"wait4(pid, options) -> (pid, status, rusage)\n\n\ +Wait for completion of a given child process - BSD style."); + +static PyObject * +posix_wait4(PyObject *self, PyObject *args) +{ + int pid, options; + + struct rusage ru; + PyObject *result; + +#ifdef UNION_WAIT + union wait status; +#define status_i (status.w_status) +#else + int status; +#define status_i status +#endif + status_i = 0; + + if (PyResourceModule_ImportModuleAndAPI()) + return NULL; + if (!PyArg_ParseTuple(args, "ii:wait4", &pid, &options)) + return NULL; + Py_BEGIN_ALLOW_THREADS + pid = wait4(pid, &status, options, &ru); + Py_END_ALLOW_THREADS + if (pid == -1) + return posix_error(); + else { + result = PyStructSequence_New(PyResourceModule.StructRUsageType); + if (!result) + return NULL; + PyStructSequence_SET_ITEM(result, 0, + PyFloat_FromDouble(doubletime(ru.ru_utime))); + PyStructSequence_SET_ITEM(result, 1, + PyFloat_FromDouble(doubletime(ru.ru_stime))); + PyStructSequence_SET_ITEM(result, 2, PyInt_FromLong(ru.ru_maxrss)); + PyStructSequence_SET_ITEM(result, 3, PyInt_FromLong(ru.ru_ixrss)); + PyStructSequence_SET_ITEM(result, 4, PyInt_FromLong(ru.ru_idrss)); + PyStructSequence_SET_ITEM(result, 5, PyInt_FromLong(ru.ru_isrss)); + PyStructSequence_SET_ITEM(result, 6, PyInt_FromLong(ru.ru_minflt)); + PyStructSequence_SET_ITEM(result, 7, PyInt_FromLong(ru.ru_majflt)); + PyStructSequence_SET_ITEM(result, 8, PyInt_FromLong(ru.ru_nswap)); + PyStructSequence_SET_ITEM(result, 9, PyInt_FromLong(ru.ru_inblock)); + PyStructSequence_SET_ITEM(result, 10, PyInt_FromLong(ru.ru_oublock)); + PyStructSequence_SET_ITEM(result, 11, PyInt_FromLong(ru.ru_msgsnd)); + PyStructSequence_SET_ITEM(result, 12, PyInt_FromLong(ru.ru_msgrcv)); + PyStructSequence_SET_ITEM(result, 13, PyInt_FromLong(ru.ru_nsignals)); + PyStructSequence_SET_ITEM(result, 14, PyInt_FromLong(ru.ru_nvcsw)); + PyStructSequence_SET_ITEM(result, 15, PyInt_FromLong(ru.ru_nivcsw)); + + if (PyErr_Occurred()) { + Py_DECREF(result); + return NULL; + } + + return Py_BuildValue("iiO", pid, status, result); + } +} +#endif /* HAVE_WAIT4 */ + #ifdef HAVE_WAITPID PyDoc_STRVAR(posix_waitpid__doc__, "waitpid(pid, options) -> (pid, status)\n\n\ @@ -7466,6 +7534,9 @@ #ifdef HAVE_WAIT {"wait", posix_wait, METH_NOARGS, posix_wait__doc__}, #endif /* HAVE_WAIT */ +#if defined(HAVE_WAIT4) + {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__}, +#endif /* HAVE_WAIT4 */ #if defined(HAVE_WAITPID) || defined(HAVE_CWAIT) {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__}, #endif /* HAVE_WAITPID */ Index: Modules/resource.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/resource.c,v retrieving revision 2.32 diff -u -b -B -u -r2.32 resource.c --- Modules/resource.c 12 Aug 2004 13:26:56 -0000 2.32 +++ Modules/resource.c 1 Aug 2005 22:21:07 -0000 @@ -10,6 +10,9 @@ #include #endif +#define RESOURCE_MODULE +#include "resourcemodule.h" + /* On some systems, these aren't in any header file. On others they are, with inconsistent prototypes. We declare the (default) return type, to shut up gcc -Wall; @@ -17,8 +20,6 @@ when the header files declare it different. Worse, on some Linuxes, getpagesize() returns a size_t... */ -#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001) - static PyObject *ResourceError; PyDoc_STRVAR(struct_rusage__doc__, @@ -57,6 +58,11 @@ static PyTypeObject StructRUsageType; +static +PyResourceModule_APIObject PyResourceModuleAPI = { + &StructRUsageType +}; + static PyObject * resource_getrusage(PyObject *self, PyObject *args) { @@ -246,6 +252,11 @@ PyModule_AddObject(m, "struct_rusage", (PyObject*) &StructRUsageType); + /* Export C API */ + if (PyModule_AddObject(m, PyResource_CAPI_NAME, + PyCObject_FromVoidPtr((void *)&PyResourceModuleAPI, NULL)) != 0) + return; + /* insert constants */ #ifdef RLIMIT_CPU PyModule_AddIntConstant(m, "RLIMIT_CPU", RLIMIT_CPU);