blob: 2c825c7b7276c90dfb268cdef227dd1a5629eeed [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
Guido van Rossum43713e52000-02-29 13:59:29 +000063 if (!PyArg_ParseTuple(args, "i:getrusage", &who))
Guido van Rossum2e631391996-12-18 18:37:27 +000064 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
Guido van Rossum43713e52000-02-29 13:59:29 +0000110 if (!PyArg_ParseTuple(args, "i:getrlimit", &resource))
Guido van Rossum2e631391996-12-18 18:37:27 +0000111 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 }
Guido van Rossum763737b1999-01-06 18:44:57 +0000123
124#if defined(HAVE_LONG_LONG)
125 if (sizeof(rl.rlim_cur) > sizeof(long)) {
126 return Py_BuildValue("LL",
127 (LONG_LONG) rl.rlim_cur,
128 (LONG_LONG) rl.rlim_max);
129 }
130#endif
131 return Py_BuildValue("ii", (long) rl.rlim_cur, (long) rl.rlim_max);
Guido van Rossum2e631391996-12-18 18:37:27 +0000132}
133
134static PyObject *
135resource_setrlimit(self, args)
136 PyObject *self;
137 PyObject *args;
138{
139 struct rlimit rl;
140 int resource;
Guido van Rossum763737b1999-01-06 18:44:57 +0000141 PyObject *curobj, *maxobj;
Guido van Rossum2e631391996-12-18 18:37:27 +0000142
Guido van Rossum43713e52000-02-29 13:59:29 +0000143 if (!PyArg_ParseTuple(args, "i(OO):setrlimit", &resource, &curobj, &maxobj))
Guido van Rossum2e631391996-12-18 18:37:27 +0000144 return NULL;
145
146 if (resource < 0 || resource >= RLIM_NLIMITS) {
147 PyErr_SetString(PyExc_ValueError,
148 "invalid resource specified");
149 return NULL;
150 }
151
Guido van Rossum763737b1999-01-06 18:44:57 +0000152#if !defined(HAVE_LARGEFILE_SUPPORT)
153 rl.rlim_cur = PyInt_AsLong(curobj);
154 rl.rlim_max = PyInt_AsLong(maxobj);
155#else
156 /* The limits are probably bigger than a long */
157 rl.rlim_cur = PyLong_Check(curobj) ?
158 PyLong_AsLongLong(curobj) : PyInt_AsLong(curobj);
159 rl.rlim_max = PyLong_Check(maxobj) ?
160 PyLong_AsLongLong(maxobj) : PyInt_AsLong(maxobj);
161#endif
162
Guido van Rossum2e631391996-12-18 18:37:27 +0000163 rl.rlim_cur = rl.rlim_cur & RLIM_INFINITY;
164 rl.rlim_max = rl.rlim_max & RLIM_INFINITY;
165 if (setrlimit(resource, &rl) == -1) {
166 if (errno == EINVAL)
167 PyErr_SetString(PyExc_ValueError,
168 "current limit exceeds maximum limit");
169 else if (errno == EPERM)
170 PyErr_SetString(PyExc_ValueError,
171 "not allowed to raise maximum limit");
172 else
173 PyErr_SetFromErrno(ResourceError);
174 return NULL;
175 }
176 Py_INCREF(Py_None);
177 return Py_None;
178}
179
180static PyObject *
181resource_getpagesize(self, args)
182 PyObject *self;
183 PyObject *args;
184{
Guido van Rossum43713e52000-02-29 13:59:29 +0000185 if (!PyArg_ParseTuple(args, ":getpagesize"))
Guido van Rossum2e631391996-12-18 18:37:27 +0000186 return NULL;
187 return Py_BuildValue("i", getpagesize());
188}
189
190/* List of functions */
191
192static struct PyMethodDef
193resource_methods[] = {
194 {"getrusage", resource_getrusage, 1},
195 {"getrlimit", resource_getrlimit, 1},
196 {"setrlimit", resource_setrlimit, 1},
197 {"getpagesize", resource_getpagesize, 1},
198 {NULL, NULL} /* sentinel */
199};
200
201
202/* Module initialization */
203
204static void
205ins(PyObject *dict, char *name, int value)
206{
207 PyObject *v = PyInt_FromLong((long) value);
208 if (v) {
209 PyDict_SetItemString(dict, name, v);
210 Py_DECREF(v);
211 }
212 /* errors will be checked by initresource() */
213}
214
215void initresource()
216{
217 PyObject *m, *d;
218
219 /* Create the module and add the functions */
220 m = Py_InitModule("resource", resource_methods);
221
222 /* Add some symbolic constants to the module */
223 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +0000224 ResourceError = PyErr_NewException("resource.error", NULL, NULL);
Guido van Rossum2e631391996-12-18 18:37:27 +0000225 PyDict_SetItemString(d, "error", ResourceError);
226
227 /* insert constants */
228#ifdef RLIMIT_CPU
229 ins(d, "RLIMIT_CPU", RLIMIT_CPU);
230#endif
231
232#ifdef RLIMIT_FSIZE
233 ins(d, "RLIMIT_FSIZE", RLIMIT_FSIZE);
234#endif
235
236#ifdef RLIMIT_DATA
237 ins(d, "RLIMIT_DATA", RLIMIT_DATA);
238#endif
239
240#ifdef RLIMIT_STACK
241 ins(d, "RLIMIT_STACK", RLIMIT_STACK);
242#endif
243
244#ifdef RLIMIT_CORE
245 ins(d, "RLIMIT_CORE", RLIMIT_CORE);
246#endif
247
248#ifdef RLIMIT_NOFILE
249 ins(d, "RLIMIT_NOFILE", RLIMIT_NOFILE);
250#endif
251
252#ifdef RLIMIT_OFILE
253 ins(d, "RLIMIT_OFILE", RLIMIT_OFILE);
254#endif
255
256#ifdef RLIMIT_VMEM
257 ins(d, "RLIMIT_VMEM", RLIMIT_VMEM);
258#endif
259
260#ifdef RLIMIT_AS
261 ins(d, "RLIMIT_AS", RLIMIT_AS);
262#endif
263
264#ifdef RLIMIT_RSS
265 ins(d, "RLIMIT_RSS", RLIMIT_RSS);
266#endif
267
268#ifdef RLIMIT_NPROC
269 ins(d, "RLIMIT_NPROC", RLIMIT_NPROC);
270#endif
271
272#ifdef RLIMIT_MEMLOCK
273 ins(d, "RLIMIT_MEMLOCK", RLIMIT_MEMLOCK);
274#endif
275
276#ifdef RUSAGE_SELF
277 ins(d, "RUSAGE_SELF", RUSAGE_SELF);
278#endif
279
Guido van Rossumebd05eb1997-12-09 19:35:48 +0000280#ifdef RUSAGE_CHILDREN
Guido van Rossum2e631391996-12-18 18:37:27 +0000281 ins(d, "RUSAGE_CHILDREN", RUSAGE_CHILDREN);
282#endif
283
284#ifdef RUSAGE_BOTH
285 ins(d, "RUSAGE_BOTH", RUSAGE_BOTH);
286#endif
Guido van Rossum2e631391996-12-18 18:37:27 +0000287}