blob: cc81337efe403d33f1b267c13364cf20d07c75f3 [file] [log] [blame]
Guido van Rossumf84a5391997-08-15 00:04:24 +00001/***********************************************************
2Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
4
5 All Rights Reserved
6
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the names of Stichting Mathematisch
12Centrum or CWI or Corporation for National Research Initiatives or
13CNRI not be used in advertising or publicity pertaining to
14distribution of the software without specific, written prior
15permission.
16
17While CWI is the initial source for this software, a modified version
18is made available by the Corporation for National Research Initiatives
19(CNRI) at the Internet address ftp://ftp.python.org.
20
21STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28PERFORMANCE OF THIS SOFTWARE.
29
30******************************************************************/
31
Guido van Rossum2e631391996-12-18 18:37:27 +000032#include "Python.h"
33#include <sys/resource.h>
34#include <sys/time.h>
35#include <unistd.h>
36#include <string.h>
37#include <errno.h>
38
39/* don't know why this isn't defined in a header file */
40#ifndef getrusage
41int getrusage(int who, struct rusage *rusage);
42#endif
43
44#ifndef getpagesize
Guido van Rossum668e4411997-08-05 02:24:57 +000045#ifdef linux
46extern size_t getpagesize(void);
47#else
Guido van Rossum2e631391996-12-18 18:37:27 +000048int getpagesize(void);
49#endif
Guido van Rossum668e4411997-08-05 02:24:57 +000050#endif
Guido van Rossum2e631391996-12-18 18:37:27 +000051
52#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
53
54static PyObject *ResourceError;
55
56static PyObject *
57resource_getrusage(self, args)
58 PyObject *self;
59 PyObject *args;
60{
61 int who;
62 struct rusage ru;
63
64 if (!PyArg_ParseTuple(args, "i", &who))
65 return NULL;
66
67 if (getrusage(who, &ru) == -1) {
68 if (errno == EINVAL) {
69 PyErr_SetString(PyExc_ValueError,
70 "invalid who parameter");
71 return NULL;
72 }
73 PyErr_SetFromErrno(ResourceError);
74 return NULL;
75 }
76
77 /* Yeah, this 16-tuple is way ugly. It's probably a lot less
78 ugly than a dictionary with keys (or object attributes)
79 named things like 'ixrss'.
80 */
81 return Py_BuildValue(
82 "ddiiiiiiiiiiiiii",
83 doubletime(ru.ru_utime), /* user time used */
84 doubletime(ru.ru_stime), /* system time used */
85 ru.ru_maxrss, /* max. resident set size */
86 ru.ru_ixrss, /* shared memory size */
87 ru.ru_idrss, /* unshared memory size */
88 ru.ru_isrss, /* unshared stack size */
89 ru.ru_minflt, /* page faults not requiring I/O*/
90 ru.ru_majflt, /* page faults requiring I/O */
91 ru.ru_nswap, /* number of swap outs */
92 ru.ru_inblock, /* block input operations */
93 ru.ru_oublock, /* block output operations */
94 ru.ru_msgsnd, /* messages sent */
95 ru.ru_msgrcv, /* messages received */
96 ru.ru_nsignals, /* signals received */
97 ru.ru_nvcsw, /* voluntary context switchs */
98 ru.ru_nivcsw /* involuntary context switchs */
99 );
100}
101
102
103static PyObject *
104resource_getrlimit(self, args)
105 PyObject *self;
106 PyObject *args;
107{
108 struct rlimit rl;
109 int resource;
Guido van Rossum2e631391996-12-18 18:37:27 +0000110
111 if (!PyArg_ParseTuple(args, "i", &resource))
112 return NULL;
113
114 if (resource < 0 || resource >= RLIM_NLIMITS) {
115 PyErr_SetString(PyExc_ValueError,
116 "invalid resource specified");
117 return NULL;
118 }
119
120 if (getrlimit(resource, &rl) == -1) {
121 PyErr_SetFromErrno(ResourceError);
122 return NULL;
123 }
124 return Py_BuildValue("ii", rl.rlim_cur, rl.rlim_max);
125}
126
127static PyObject *
128resource_setrlimit(self, args)
129 PyObject *self;
130 PyObject *args;
131{
132 struct rlimit rl;
133 int resource;
Guido van Rossum2e631391996-12-18 18:37:27 +0000134
135 if (!PyArg_ParseTuple(args, "i(ii)", &resource, &rl.rlim_cur,
136 &rl.rlim_max))
137 return NULL;
138
139 if (resource < 0 || resource >= RLIM_NLIMITS) {
140 PyErr_SetString(PyExc_ValueError,
141 "invalid resource specified");
142 return NULL;
143 }
144
145 rl.rlim_cur = rl.rlim_cur & RLIM_INFINITY;
146 rl.rlim_max = rl.rlim_max & RLIM_INFINITY;
147 if (setrlimit(resource, &rl) == -1) {
148 if (errno == EINVAL)
149 PyErr_SetString(PyExc_ValueError,
150 "current limit exceeds maximum limit");
151 else if (errno == EPERM)
152 PyErr_SetString(PyExc_ValueError,
153 "not allowed to raise maximum limit");
154 else
155 PyErr_SetFromErrno(ResourceError);
156 return NULL;
157 }
158 Py_INCREF(Py_None);
159 return Py_None;
160}
161
162static PyObject *
163resource_getpagesize(self, args)
164 PyObject *self;
165 PyObject *args;
166{
167 if (!PyArg_ParseTuple(args, ""))
168 return NULL;
169 return Py_BuildValue("i", getpagesize());
170}
171
172/* List of functions */
173
174static struct PyMethodDef
175resource_methods[] = {
176 {"getrusage", resource_getrusage, 1},
177 {"getrlimit", resource_getrlimit, 1},
178 {"setrlimit", resource_setrlimit, 1},
179 {"getpagesize", resource_getpagesize, 1},
180 {NULL, NULL} /* sentinel */
181};
182
183
184/* Module initialization */
185
186static void
187ins(PyObject *dict, char *name, int value)
188{
189 PyObject *v = PyInt_FromLong((long) value);
190 if (v) {
191 PyDict_SetItemString(dict, name, v);
192 Py_DECREF(v);
193 }
194 /* errors will be checked by initresource() */
195}
196
197void initresource()
198{
199 PyObject *m, *d;
200
201 /* Create the module and add the functions */
202 m = Py_InitModule("resource", resource_methods);
203
204 /* Add some symbolic constants to the module */
205 d = PyModule_GetDict(m);
206 ResourceError = PyString_FromString("resource.error");
207 PyDict_SetItemString(d, "error", ResourceError);
208
209 /* insert constants */
210#ifdef RLIMIT_CPU
211 ins(d, "RLIMIT_CPU", RLIMIT_CPU);
212#endif
213
214#ifdef RLIMIT_FSIZE
215 ins(d, "RLIMIT_FSIZE", RLIMIT_FSIZE);
216#endif
217
218#ifdef RLIMIT_DATA
219 ins(d, "RLIMIT_DATA", RLIMIT_DATA);
220#endif
221
222#ifdef RLIMIT_STACK
223 ins(d, "RLIMIT_STACK", RLIMIT_STACK);
224#endif
225
226#ifdef RLIMIT_CORE
227 ins(d, "RLIMIT_CORE", RLIMIT_CORE);
228#endif
229
230#ifdef RLIMIT_NOFILE
231 ins(d, "RLIMIT_NOFILE", RLIMIT_NOFILE);
232#endif
233
234#ifdef RLIMIT_OFILE
235 ins(d, "RLIMIT_OFILE", RLIMIT_OFILE);
236#endif
237
238#ifdef RLIMIT_VMEM
239 ins(d, "RLIMIT_VMEM", RLIMIT_VMEM);
240#endif
241
242#ifdef RLIMIT_AS
243 ins(d, "RLIMIT_AS", RLIMIT_AS);
244#endif
245
246#ifdef RLIMIT_RSS
247 ins(d, "RLIMIT_RSS", RLIMIT_RSS);
248#endif
249
250#ifdef RLIMIT_NPROC
251 ins(d, "RLIMIT_NPROC", RLIMIT_NPROC);
252#endif
253
254#ifdef RLIMIT_MEMLOCK
255 ins(d, "RLIMIT_MEMLOCK", RLIMIT_MEMLOCK);
256#endif
257
258#ifdef RUSAGE_SELF
259 ins(d, "RUSAGE_SELF", RUSAGE_SELF);
260#endif
261
262#ifdef RUSAGE_CHILDERN
263 ins(d, "RUSAGE_CHILDREN", RUSAGE_CHILDREN);
264#endif
265
266#ifdef RUSAGE_BOTH
267 ins(d, "RUSAGE_BOTH", RUSAGE_BOTH);
268#endif
269
270 /* Check for errors */
271 if (PyErr_Occurred())
272 Py_FatalError("can't initialize module resource");
273}