Skip to content

Commit 2e63139

Browse files
committed
Added Jeremy's resource module.
1 parent 3c7b2dc commit 2e63139

3 files changed

Lines changed: 242 additions & 0 deletions

File tree

Modules/Makefile.pre.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ posixmodule.o: posixmodule.c
185185
pwdmodule.o: pwdmodule.c
186186
regexmodule.o: regexmodule.c
187187
regexpr.o: regexpr.c
188+
resource.o: resource.c
188189
rgbimgmodule.o: rgbimgmodule.c
189190
rotormodule.o: rotormodule.c
190191
selectmodule.o: selectmodule.c

Modules/Setup.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ errno errnomodule.c # posix (UNIX) errno values
140140
#nis nismodule.c # Sun yellow pages -- not everywhere
141141
#termios termios.c # Steen Lumholt's termios module
142142
#_xdr _xdrmodule.c # -lnsl # Helper for xdrlib.py
143+
#resource resource.c # Jeremy Hylton's rlimit interface
143144

144145

145146
# Multimedia modules -- on by default.

Modules/resource.c

Lines changed: 240 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,240 @@
1+
#include "Python.h"
2+
#include <sys/resource.h>
3+
#include <sys/time.h>
4+
#include <unistd.h>
5+
#include <string.h>
6+
#include <errno.h>
7+
8+
/* don't know why this isn't defined in a header file */
9+
#ifndef getrusage
10+
int getrusage(int who, struct rusage *rusage);
11+
#endif
12+
13+
#ifndef getpagesize
14+
int getpagesize(void);
15+
#endif
16+
17+
#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
18+
19+
static PyObject *ResourceError;
20+
21+
static PyObject *
22+
resource_getrusage(self, args)
23+
PyObject *self;
24+
PyObject *args;
25+
{
26+
int who;
27+
struct rusage ru;
28+
29+
if (!PyArg_ParseTuple(args, "i", &who))
30+
return NULL;
31+
32+
if (getrusage(who, &ru) == -1) {
33+
if (errno == EINVAL) {
34+
PyErr_SetString(PyExc_ValueError,
35+
"invalid who parameter");
36+
return NULL;
37+
}
38+
PyErr_SetFromErrno(ResourceError);
39+
return NULL;
40+
}
41+
42+
/* Yeah, this 16-tuple is way ugly. It's probably a lot less
43+
ugly than a dictionary with keys (or object attributes)
44+
named things like 'ixrss'.
45+
*/
46+
return Py_BuildValue(
47+
"ddiiiiiiiiiiiiii",
48+
doubletime(ru.ru_utime), /* user time used */
49+
doubletime(ru.ru_stime), /* system time used */
50+
ru.ru_maxrss, /* max. resident set size */
51+
ru.ru_ixrss, /* shared memory size */
52+
ru.ru_idrss, /* unshared memory size */
53+
ru.ru_isrss, /* unshared stack size */
54+
ru.ru_minflt, /* page faults not requiring I/O*/
55+
ru.ru_majflt, /* page faults requiring I/O */
56+
ru.ru_nswap, /* number of swap outs */
57+
ru.ru_inblock, /* block input operations */
58+
ru.ru_oublock, /* block output operations */
59+
ru.ru_msgsnd, /* messages sent */
60+
ru.ru_msgrcv, /* messages received */
61+
ru.ru_nsignals, /* signals received */
62+
ru.ru_nvcsw, /* voluntary context switchs */
63+
ru.ru_nivcsw /* involuntary context switchs */
64+
);
65+
}
66+
67+
68+
static PyObject *
69+
resource_getrlimit(self, args)
70+
PyObject *self;
71+
PyObject *args;
72+
{
73+
struct rlimit rl;
74+
int resource;
75+
char *errstr;
76+
77+
if (!PyArg_ParseTuple(args, "i", &resource))
78+
return NULL;
79+
80+
if (resource < 0 || resource >= RLIM_NLIMITS) {
81+
PyErr_SetString(PyExc_ValueError,
82+
"invalid resource specified");
83+
return NULL;
84+
}
85+
86+
if (getrlimit(resource, &rl) == -1) {
87+
PyErr_SetFromErrno(ResourceError);
88+
return NULL;
89+
}
90+
return Py_BuildValue("ii", rl.rlim_cur, rl.rlim_max);
91+
}
92+
93+
static PyObject *
94+
resource_setrlimit(self, args)
95+
PyObject *self;
96+
PyObject *args;
97+
{
98+
struct rlimit rl;
99+
int resource;
100+
char *errstr;
101+
102+
if (!PyArg_ParseTuple(args, "i(ii)", &resource, &rl.rlim_cur,
103+
&rl.rlim_max))
104+
return NULL;
105+
106+
if (resource < 0 || resource >= RLIM_NLIMITS) {
107+
PyErr_SetString(PyExc_ValueError,
108+
"invalid resource specified");
109+
return NULL;
110+
}
111+
112+
rl.rlim_cur = rl.rlim_cur & RLIM_INFINITY;
113+
rl.rlim_max = rl.rlim_max & RLIM_INFINITY;
114+
if (setrlimit(resource, &rl) == -1) {
115+
if (errno == EINVAL)
116+
PyErr_SetString(PyExc_ValueError,
117+
"current limit exceeds maximum limit");
118+
else if (errno == EPERM)
119+
PyErr_SetString(PyExc_ValueError,
120+
"not allowed to raise maximum limit");
121+
else
122+
PyErr_SetFromErrno(ResourceError);
123+
return NULL;
124+
}
125+
Py_INCREF(Py_None);
126+
return Py_None;
127+
}
128+
129+
static PyObject *
130+
resource_getpagesize(self, args)
131+
PyObject *self;
132+
PyObject *args;
133+
{
134+
if (!PyArg_ParseTuple(args, ""))
135+
return NULL;
136+
return Py_BuildValue("i", getpagesize());
137+
}
138+
139+
/* List of functions */
140+
141+
static struct PyMethodDef
142+
resource_methods[] = {
143+
{"getrusage", resource_getrusage, 1},
144+
{"getrlimit", resource_getrlimit, 1},
145+
{"setrlimit", resource_setrlimit, 1},
146+
{"getpagesize", resource_getpagesize, 1},
147+
{NULL, NULL} /* sentinel */
148+
};
149+
150+
151+
/* Module initialization */
152+
153+
static void
154+
ins(PyObject *dict, char *name, int value)
155+
{
156+
PyObject *v = PyInt_FromLong((long) value);
157+
if (v) {
158+
PyDict_SetItemString(dict, name, v);
159+
Py_DECREF(v);
160+
}
161+
/* errors will be checked by initresource() */
162+
}
163+
164+
void initresource()
165+
{
166+
PyObject *m, *d;
167+
168+
/* Create the module and add the functions */
169+
m = Py_InitModule("resource", resource_methods);
170+
171+
/* Add some symbolic constants to the module */
172+
d = PyModule_GetDict(m);
173+
ResourceError = PyString_FromString("resource.error");
174+
PyDict_SetItemString(d, "error", ResourceError);
175+
176+
/* insert constants */
177+
#ifdef RLIMIT_CPU
178+
ins(d, "RLIMIT_CPU", RLIMIT_CPU);
179+
#endif
180+
181+
#ifdef RLIMIT_FSIZE
182+
ins(d, "RLIMIT_FSIZE", RLIMIT_FSIZE);
183+
#endif
184+
185+
#ifdef RLIMIT_DATA
186+
ins(d, "RLIMIT_DATA", RLIMIT_DATA);
187+
#endif
188+
189+
#ifdef RLIMIT_STACK
190+
ins(d, "RLIMIT_STACK", RLIMIT_STACK);
191+
#endif
192+
193+
#ifdef RLIMIT_CORE
194+
ins(d, "RLIMIT_CORE", RLIMIT_CORE);
195+
#endif
196+
197+
#ifdef RLIMIT_NOFILE
198+
ins(d, "RLIMIT_NOFILE", RLIMIT_NOFILE);
199+
#endif
200+
201+
#ifdef RLIMIT_OFILE
202+
ins(d, "RLIMIT_OFILE", RLIMIT_OFILE);
203+
#endif
204+
205+
#ifdef RLIMIT_VMEM
206+
ins(d, "RLIMIT_VMEM", RLIMIT_VMEM);
207+
#endif
208+
209+
#ifdef RLIMIT_AS
210+
ins(d, "RLIMIT_AS", RLIMIT_AS);
211+
#endif
212+
213+
#ifdef RLIMIT_RSS
214+
ins(d, "RLIMIT_RSS", RLIMIT_RSS);
215+
#endif
216+
217+
#ifdef RLIMIT_NPROC
218+
ins(d, "RLIMIT_NPROC", RLIMIT_NPROC);
219+
#endif
220+
221+
#ifdef RLIMIT_MEMLOCK
222+
ins(d, "RLIMIT_MEMLOCK", RLIMIT_MEMLOCK);
223+
#endif
224+
225+
#ifdef RUSAGE_SELF
226+
ins(d, "RUSAGE_SELF", RUSAGE_SELF);
227+
#endif
228+
229+
#ifdef RUSAGE_CHILDERN
230+
ins(d, "RUSAGE_CHILDREN", RUSAGE_CHILDREN);
231+
#endif
232+
233+
#ifdef RUSAGE_BOTH
234+
ins(d, "RUSAGE_BOTH", RUSAGE_BOTH);
235+
#endif
236+
237+
/* Check for errors */
238+
if (PyErr_Occurred())
239+
Py_FatalError("can't initialize module resource");
240+
}

0 commit comments

Comments
 (0)