3 #include <sys/resource.h>
9 /* On some systems, these aren't in any header file.
10 On others they are, with inconsistent prototypes.
11 We declare the (default) return type, to shut up gcc -Wall;
12 but we can't declare the prototype, to avoid errors
13 when the header files declare it different.
14 Worse, on some Linuxes, getpagesize() returns a size_t... */
16 #define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
18 static PyObject
*ResourceError
;
21 resource_getrusage(PyObject
*self
, PyObject
*args
)
26 if (!PyArg_ParseTuple(args
, "i:getrusage", &who
))
29 if (getrusage(who
, &ru
) == -1) {
30 if (errno
== EINVAL
) {
31 PyErr_SetString(PyExc_ValueError
,
32 "invalid who parameter");
35 PyErr_SetFromErrno(ResourceError
);
39 /* Yeah, this 16-tuple is way ugly. It's probably a lot less
40 ugly than a dictionary with keys (or object attributes)
41 named things like 'ixrss'.
45 doubletime(ru
.ru_utime
), /* user time used */
46 doubletime(ru
.ru_stime
), /* system time used */
47 ru
.ru_maxrss
, /* max. resident set size */
48 ru
.ru_ixrss
, /* shared memory size */
49 ru
.ru_idrss
, /* unshared memory size */
50 ru
.ru_isrss
, /* unshared stack size */
51 ru
.ru_minflt
, /* page faults not requiring I/O*/
52 ru
.ru_majflt
, /* page faults requiring I/O */
53 ru
.ru_nswap
, /* number of swap outs */
54 ru
.ru_inblock
, /* block input operations */
55 ru
.ru_oublock
, /* block output operations */
56 ru
.ru_msgsnd
, /* messages sent */
57 ru
.ru_msgrcv
, /* messages received */
58 ru
.ru_nsignals
, /* signals received */
59 ru
.ru_nvcsw
, /* voluntary context switches */
60 ru
.ru_nivcsw
/* involuntary context switches */
66 resource_getrlimit(PyObject
*self
, PyObject
*args
)
71 if (!PyArg_ParseTuple(args
, "i:getrlimit", &resource
))
74 if (resource
< 0 || resource
>= RLIM_NLIMITS
) {
75 PyErr_SetString(PyExc_ValueError
,
76 "invalid resource specified");
80 if (getrlimit(resource
, &rl
) == -1) {
81 PyErr_SetFromErrno(ResourceError
);
85 #if defined(HAVE_LONG_LONG)
86 if (sizeof(rl
.rlim_cur
) > sizeof(long)) {
87 return Py_BuildValue("LL",
88 (LONG_LONG
) rl
.rlim_cur
,
89 (LONG_LONG
) rl
.rlim_max
);
92 return Py_BuildValue("ii", (long) rl
.rlim_cur
, (long) rl
.rlim_max
);
96 resource_setrlimit(PyObject
*self
, PyObject
*args
)
100 PyObject
*curobj
, *maxobj
;
102 if (!PyArg_ParseTuple(args
, "i(OO):setrlimit", &resource
, &curobj
, &maxobj
))
105 if (resource
< 0 || resource
>= RLIM_NLIMITS
) {
106 PyErr_SetString(PyExc_ValueError
,
107 "invalid resource specified");
111 #if !defined(HAVE_LARGEFILE_SUPPORT)
112 rl
.rlim_cur
= PyInt_AsLong(curobj
);
113 rl
.rlim_max
= PyInt_AsLong(maxobj
);
115 /* The limits are probably bigger than a long */
116 rl
.rlim_cur
= PyLong_Check(curobj
) ?
117 PyLong_AsLongLong(curobj
) : PyInt_AsLong(curobj
);
118 rl
.rlim_max
= PyLong_Check(maxobj
) ?
119 PyLong_AsLongLong(maxobj
) : PyInt_AsLong(maxobj
);
122 rl
.rlim_cur
= rl
.rlim_cur
& RLIM_INFINITY
;
123 rl
.rlim_max
= rl
.rlim_max
& RLIM_INFINITY
;
124 if (setrlimit(resource
, &rl
) == -1) {
126 PyErr_SetString(PyExc_ValueError
,
127 "current limit exceeds maximum limit");
128 else if (errno
== EPERM
)
129 PyErr_SetString(PyExc_ValueError
,
130 "not allowed to raise maximum limit");
132 PyErr_SetFromErrno(ResourceError
);
140 resource_getpagesize(PyObject
*self
, PyObject
*args
)
142 if (!PyArg_ParseTuple(args
, ":getpagesize"))
144 return Py_BuildValue("i", getpagesize());
147 /* List of functions */
149 static struct PyMethodDef
150 resource_methods
[] = {
151 {"getrusage", resource_getrusage
, 1},
152 {"getrlimit", resource_getrlimit
, 1},
153 {"setrlimit", resource_setrlimit
, 1},
154 {"getpagesize", resource_getpagesize
, 1},
155 {NULL
, NULL
} /* sentinel */
159 /* Module initialization */
162 ins(PyObject
*dict
, char *name
, int value
)
164 PyObject
*v
= PyInt_FromLong((long) value
);
166 PyDict_SetItemString(dict
, name
, v
);
169 /* errors will be checked by initresource() */
172 void initresource(void)
176 /* Create the module and add the functions */
177 m
= Py_InitModule("resource", resource_methods
);
179 /* Add some symbolic constants to the module */
180 d
= PyModule_GetDict(m
);
181 ResourceError
= PyErr_NewException("resource.error", NULL
, NULL
);
182 PyDict_SetItemString(d
, "error", ResourceError
);
184 /* insert constants */
186 ins(d
, "RLIMIT_CPU", RLIMIT_CPU
);
190 ins(d
, "RLIMIT_FSIZE", RLIMIT_FSIZE
);
194 ins(d
, "RLIMIT_DATA", RLIMIT_DATA
);
198 ins(d
, "RLIMIT_STACK", RLIMIT_STACK
);
202 ins(d
, "RLIMIT_CORE", RLIMIT_CORE
);
206 ins(d
, "RLIMIT_NOFILE", RLIMIT_NOFILE
);
210 ins(d
, "RLIMIT_OFILE", RLIMIT_OFILE
);
214 ins(d
, "RLIMIT_VMEM", RLIMIT_VMEM
);
218 ins(d
, "RLIMIT_AS", RLIMIT_AS
);
222 ins(d
, "RLIMIT_RSS", RLIMIT_RSS
);
226 ins(d
, "RLIMIT_NPROC", RLIMIT_NPROC
);
229 #ifdef RLIMIT_MEMLOCK
230 ins(d
, "RLIMIT_MEMLOCK", RLIMIT_MEMLOCK
);
234 ins(d
, "RUSAGE_SELF", RUSAGE_SELF
);
237 #ifdef RUSAGE_CHILDREN
238 ins(d
, "RUSAGE_CHILDREN", RUSAGE_CHILDREN
);
242 ins(d
, "RUSAGE_BOTH", RUSAGE_BOTH
);