blob: ab3f6761b9dcce03fe99ac6837654243bae43432 [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"
Guido van Rossum86aeb901997-10-31 16:55:51 +000033#include "mytime.h" /* needed for SunOS4.1 */
Guido van Rossum2e631391996-12-18 18:37:27 +000034#include <sys/resource.h>
35#include <sys/time.h>
36#include <unistd.h>
37#include <string.h>
38#include <errno.h>
39
Guido van Rossum607b33a1997-08-17 16:24:30 +000040/* On some systems, these aren't in any header file.
41 On others they are, with inconsistent prototypes.
42 We declare the (default) return type, to shut up gcc -Wall;
43 but we can't declare the prototype, to avoid errors
44 when the header files declare it different.
45 Worse, on some Linuxes, getpagesize() returns a size_t... */
46#ifndef linux
47int getrusage();
48int getpagesize();
Guido van Rossum668e4411997-08-05 02:24:57 +000049#endif
Guido van Rossum2e631391996-12-18 18:37:27 +000050
51#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
52
53static PyObject *ResourceError;
54
55static PyObject *
56resource_getrusage(self, args)
57 PyObject *self;
58 PyObject *args;
59{
60 int who;
61 struct rusage ru;
62
63 if (!PyArg_ParseTuple(args, "i", &who))
64 return NULL;
65
66 if (getrusage(who, &ru) == -1) {
67 if (errno == EINVAL) {
68 PyErr_SetString(PyExc_ValueError,
69 "invalid who parameter");
70 return NULL;
71 }
72 PyErr_SetFromErrno(ResourceError);
73 return NULL;
74 }
75
76 /* Yeah, this 16-tuple is way ugly. It's probably a lot less
77 ugly than a dictionary with keys (or object attributes)
78 named things like 'ixrss'.
79 */
80 return Py_BuildValue(
81 "ddiiiiiiiiiiiiii",
82 doubletime(ru.ru_utime), /* user time used */
83 doubletime(ru.ru_stime), /* system time used */
84 ru.ru_maxrss, /* max. resident set size */
85 ru.ru_ixrss, /* shared memory size */
86 ru.ru_idrss, /* unshared memory size */
87 ru.ru_isrss, /* unshared stack size */
88 ru.ru_minflt, /* page faults not requiring I/O*/
89 ru.ru_majflt, /* page faults requiring I/O */
90 ru.ru_nswap, /* number of swap outs */
91 ru.ru_inblock, /* block input operations */
92 ru.ru_oublock, /* block output operations */
93 ru.ru_msgsnd, /* messages sent */
94 ru.ru_msgrcv, /* messages received */
95 ru.ru_nsignals, /* signals received */
96 ru.ru_nvcsw, /* voluntary context switchs */
97 ru.ru_nivcsw /* involuntary context switchs */
98 );
99}
100
101
102static PyObject *
103resource_getrlimit(self, args)
104 PyObject *self;
105 PyObject *args;
106{
107 struct rlimit rl;
108 int resource;
Guido van Rossum2e631391996-12-18 18:37:27 +0000109
110 if (!PyArg_ParseTuple(args, "i", &resource))
111 return NULL;
112
113 if (resource < 0 || resource >= RLIM_NLIMITS) {
114 PyErr_SetString(PyExc_ValueError,
115 "invalid resource specified");
116 return NULL;
117 }
118
119 if (getrlimit(resource, &rl) == -1) {
120 PyErr_SetFromErrno(ResourceError);
121 return NULL;
122 }
123 return Py_BuildValue("ii", rl.rlim_cur, rl.rlim_max);
124}
125
126static PyObject *
127resource_setrlimit(self, args)
128 PyObject *self;
129 PyObject *args;
130{
131 struct rlimit rl;
132 int resource;
Guido van Rossum2e631391996-12-18 18:37:27 +0000133
134 if (!PyArg_ParseTuple(args, "i(ii)", &resource, &rl.rlim_cur,
135 &rl.rlim_max))
136 return NULL;
137
138 if (resource < 0 || resource >= RLIM_NLIMITS) {
139 PyErr_SetString(PyExc_ValueError,
140 "invalid resource specified");
141 return NULL;
142 }
143
144 rl.rlim_cur = rl.rlim_cur & RLIM_INFINITY;
145 rl.rlim_max = rl.rlim_max & RLIM_INFINITY;
146 if (setrlimit(resource, &rl) == -1) {
147 if (errno == EINVAL)
148 PyErr_SetString(PyExc_ValueError,
149 "current limit exceeds maximum limit");
150 else if (errno == EPERM)
151 PyErr_SetString(PyExc_ValueError,
152 "not allowed to raise maximum limit");
153 else
154 PyErr_SetFromErrno(ResourceError);
155 return NULL;
156 }
157 Py_INCREF(Py_None);
158 return Py_None;
159}
160
161static PyObject *
162resource_getpagesize(self, args)
163 PyObject *self;
164 PyObject *args;
165{
166 if (!PyArg_ParseTuple(args, ""))
167 return NULL;
168 return Py_BuildValue("i", getpagesize());
169}
170
171/* List of functions */
172
173static struct PyMethodDef
174resource_methods[] = {
175 {"getrusage", resource_getrusage, 1},
176 {"getrlimit", resource_getrlimit, 1},
177 {"setrlimit", resource_setrlimit, 1},
178 {"getpagesize", resource_getpagesize, 1},
179 {NULL, NULL} /* sentinel */
180};
181
182
183/* Module initialization */
184
185static void
186ins(PyObject *dict, char *name, int value)
187{
188 PyObject *v = PyInt_FromLong((long) value);
189 if (v) {
190 PyDict_SetItemString(dict, name, v);
191 Py_DECREF(v);
192 }
193 /* errors will be checked by initresource() */
194}
195
196void initresource()
197{
198 PyObject *m, *d;
199
200 /* Create the module and add the functions */
201 m = Py_InitModule("resource", resource_methods);
202
203 /* Add some symbolic constants to the module */
204 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +0000205 ResourceError = PyErr_NewException("resource.error", NULL, NULL);
Guido van Rossum2e631391996-12-18 18:37:27 +0000206 PyDict_SetItemString(d, "error", ResourceError);
207
208 /* insert constants */
209#ifdef RLIMIT_CPU
210 ins(d, "RLIMIT_CPU", RLIMIT_CPU);
211#endif
212
213#ifdef RLIMIT_FSIZE
214 ins(d, "RLIMIT_FSIZE", RLIMIT_FSIZE);
215#endif
216
217#ifdef RLIMIT_DATA
218 ins(d, "RLIMIT_DATA", RLIMIT_DATA);
219#endif
220
221#ifdef RLIMIT_STACK
222 ins(d, "RLIMIT_STACK", RLIMIT_STACK);
223#endif
224
225#ifdef RLIMIT_CORE
226 ins(d, "RLIMIT_CORE", RLIMIT_CORE);
227#endif
228
229#ifdef RLIMIT_NOFILE
230 ins(d, "RLIMIT_NOFILE", RLIMIT_NOFILE);
231#endif
232
233#ifdef RLIMIT_OFILE
234 ins(d, "RLIMIT_OFILE", RLIMIT_OFILE);
235#endif
236
237#ifdef RLIMIT_VMEM
238 ins(d, "RLIMIT_VMEM", RLIMIT_VMEM);
239#endif
240
241#ifdef RLIMIT_AS
242 ins(d, "RLIMIT_AS", RLIMIT_AS);
243#endif
244
245#ifdef RLIMIT_RSS
246 ins(d, "RLIMIT_RSS", RLIMIT_RSS);
247#endif
248
249#ifdef RLIMIT_NPROC
250 ins(d, "RLIMIT_NPROC", RLIMIT_NPROC);
251#endif
252
253#ifdef RLIMIT_MEMLOCK
254 ins(d, "RLIMIT_MEMLOCK", RLIMIT_MEMLOCK);
255#endif
256
257#ifdef RUSAGE_SELF
258 ins(d, "RUSAGE_SELF", RUSAGE_SELF);
259#endif
260
Guido van Rossumebd05eb1997-12-09 19:35:48 +0000261#ifdef RUSAGE_CHILDREN
Guido van Rossum2e631391996-12-18 18:37:27 +0000262 ins(d, "RUSAGE_CHILDREN", RUSAGE_CHILDREN);
263#endif
264
265#ifdef RUSAGE_BOTH
266 ins(d, "RUSAGE_BOTH", RUSAGE_BOTH);
267#endif
Guido van Rossum2e631391996-12-18 18:37:27 +0000268}