Patch #512005: getrusage() returns struct-like object.
diff --git a/Modules/resource.c b/Modules/resource.c
index ecd992e..4d8d4fa 100644
--- a/Modules/resource.c
+++ b/Modules/resource.c
@@ -1,5 +1,6 @@
#include "Python.h"
+#include "structseq.h"
#include <sys/resource.h>
#include <sys/time.h>
#include <string.h>
@@ -16,11 +17,48 @@
static PyObject *ResourceError;
+static char 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.\n";
+
+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;
+
static PyObject *
resource_getrusage(PyObject *self, PyObject *args)
{
int who;
struct rusage ru;
+ PyObject *result;
if (!PyArg_ParseTuple(args, "i:getrusage", &who))
return NULL;
@@ -35,29 +73,35 @@
return NULL;
}
- /* Yeah, this 16-tuple is way ugly. It's probably a lot less
- ugly than a dictionary with keys (or object attributes)
- named things like 'ixrss'.
- */
- return Py_BuildValue(
- "ddiiiiiiiiiiiiii",
- doubletime(ru.ru_utime), /* user time used */
- doubletime(ru.ru_stime), /* system time used */
- ru.ru_maxrss, /* max. resident set size */
- ru.ru_ixrss, /* shared memory size */
- ru.ru_idrss, /* unshared memory size */
- ru.ru_isrss, /* unshared stack size */
- ru.ru_minflt, /* page faults not requiring I/O*/
- ru.ru_majflt, /* page faults requiring I/O */
- ru.ru_nswap, /* number of swap outs */
- ru.ru_inblock, /* block input operations */
- ru.ru_oublock, /* block output operations */
- ru.ru_msgsnd, /* messages sent */
- ru.ru_msgrcv, /* messages received */
- ru.ru_nsignals, /* signals received */
- ru.ru_nvcsw, /* voluntary context switches */
- ru.ru_nivcsw /* involuntary context switches */
- );
+ 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 result;
}
@@ -172,6 +216,9 @@
}
Py_INCREF(ResourceError);
PyModule_AddObject(m, "error", ResourceError);
+ PyStructSequence_InitType(&StructRUsageType, &struct_rusage_desc);
+ PyModule_AddObject(m, "struct_rusage",
+ (PyObject*) &StructRUsageType);
/* insert constants */
#ifdef RLIMIT_CPU