A python wait4 implementation

chads lamote1 at netscape.net
Tue Jul 27 14:39:43 EDT 2004


I was wondering if there is a current implementation or plan to implement
the wait4 function (BSD style) into Python.  If not, how do I go about
requesting consideration for inclusion in the future?

I slapped one together, using code from the current posixmodule.c and
resource.c files, for python-2.3.4.  I'm not sure how complete
or correct it is, but it's working for me on a Linux and FreeBSD box.

wait4(pid, options) -> (pid, status, rusage)

A posixmodule.c diff follows.

Thank you.
Chad


--- posixmodule.c       2004-05-04 03:07:49.000000000 -0500
+++ posixmodule.c.new   2004-07-26 13:48:14.000000000 -0500
@@ -4790,6 +4790,109 @@ posix_setgroups(PyObject *self, PyObject
 }
 #endif /* HAVE_SETGROUPS */
  
+
+/* NEW_WAIT4 */
+#ifdef HAVE_WAIT4
+#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
+static PyObject *ResourceError;
+
+PyDoc_STRVAR(struct_rusage__doc__,
+"struct_rusage: Result from getrusage.\n\n"
+"This object may be accessed either as a tuple of\n"
+"    (utime,stime,maxrss,ixrss,idrss,isrss,minflt,majflt,\n"
+"    nswap,inblock,oublock,msgsnd,msgrcv,nsignals,nvcsw,nivcsw)\n"
+"or via the attributes ru_utime, ru_stime, ru_maxrss, and so on.");
+
+static PyStructSequence_Field struct_rusage_fields[] = {
+       {"ru_utime",    "user time used"},
+       {"ru_stime",    "system time used"},
+       {"ru_maxrss",   "max. resident set size"},
+       {"ru_ixrss",    "shared memory size"},
+       {"ru_idrss",    "unshared data size"},
+       {"ru_isrss",    "unshared stack size"},
+       {"ru_minflt",   "page faults not requiring I/O"},
+       {"ru_majflt",   "page faults requiring I/O"},
+       {"ru_nswap",    "number of swap outs"},
+       {"ru_inblock",  "block input operations"},
+       {"ru_oublock",  "block output operations"},
+       {"ru_msgsnd",   "IPC messages sent"},
+       {"ru_msgrcv",   "IPC messages received"},
+       {"ru_nsignals", "signals received"},
+       {"ru_nvcsw",    "voluntary context switches"},
+       {"ru_nivcsw",   "involuntary context switches"},
+       {0}
+};
+
+static PyStructSequence_Desc struct_rusage_desc = {
+       "resource.struct_rusage",       /* name */
+       struct_rusage__doc__,   /* doc */
+       struct_rusage_fields,   /* fields */
+       16      /* n_in_sequence */
+};
+
+static PyTypeObject StructRUsageType;
+
+PyDoc_STRVAR(posix_wait4__doc__,
+"wait4(pid, options) -> (pid, status, rusage)\n\n\
+Wait for completion of a given child process.");
+
+static PyObject *
+posix_wait4(PyObject *self, PyObject *args)
+{
+   int pid, options;
+#ifdef UNION_WAIT
+   union wait status;
+#define status_i (status.w_status)
+#else
+   int status;
+#define status_i status
+#endif
+   status_i = 0;
+
+   struct rusage ru;
+   PyObject *result;
+
+   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(&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 */
+/* NEW_WAIT4 */
+
 #ifdef HAVE_WAITPID
 PyDoc_STRVAR(posix_waitpid__doc__,
 "waitpid(pid, options) -> (pid, status)\n\n\
@@ -7280,6 +7383,11 @@ static PyMethodDef posix_methods[] = {
 #ifdef HAVE_WAIT
        {"wait",        posix_wait, METH_NOARGS, posix_wait__doc__},
 #endif /* HAVE_WAIT */
+/* NEW_WAIT4 */
+#if defined(HAVE_WAIT4)
+       {"wait4",       posix_wait4, METH_VARARGS, posix_wait4__doc__},
+#endif /* HAVE_WAIT4 */
+/* NEW_WAIT4 */
 #if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
        {"waitpid",     posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
 #endif /* HAVE_WAITPID */
@@ -7723,6 +7831,12 @@ INITFUNC(void)
        Py_INCREF((PyObject*) &StatResultType);
        PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
  
+        /* NEW_WAIT4 */
+        PyStructSequence_InitType(&StructRUsageType, &struct_rusage_desc);
+       PyModule_AddObject(m, "struct_rusage",
+                          (PyObject*) &StructRUsageType);
+        /* NEW_WAIT4 */
+
        statvfs_result_desc.name = MODNAME ".statvfs_result";
        PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
        Py_INCREF((PyObject*) &StatVFSResultType);



More information about the Python-list mailing list