blob: cca6d823fe607db9c7f1920480d8eb4cdb5236bd [file] [log] [blame]
Guido van Rossumf84a5391997-08-15 00:04:24 +00001/***********************************************************
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00002Copyright (c) 2000, BeOpen.com.
3Copyright (c) 1995-2000, Corporation for National Research Initiatives.
4Copyright (c) 1990-1995, Stichting Mathematisch Centrum.
5All rights reserved.
Guido van Rossumf84a5391997-08-15 00:04:24 +00006
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00007See the file "Misc/COPYRIGHT" for information on usage and
8redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
Guido van Rossumf84a5391997-08-15 00:04:24 +00009******************************************************************/
10
Guido van Rossum2e631391996-12-18 18:37:27 +000011#include "Python.h"
12#include <sys/resource.h>
13#include <sys/time.h>
14#include <unistd.h>
15#include <string.h>
16#include <errno.h>
17
Guido van Rossum607b33a1997-08-17 16:24:30 +000018/* On some systems, these aren't in any header file.
19 On others they are, with inconsistent prototypes.
20 We declare the (default) return type, to shut up gcc -Wall;
21 but we can't declare the prototype, to avoid errors
22 when the header files declare it different.
23 Worse, on some Linuxes, getpagesize() returns a size_t... */
Guido van Rossum2e631391996-12-18 18:37:27 +000024
25#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
26
27static PyObject *ResourceError;
28
29static PyObject *
Peter Schneider-Kamp416d4132000-07-10 12:15:54 +000030resource_getrusage(PyObject *self, PyObject *args)
Guido van Rossum2e631391996-12-18 18:37:27 +000031{
32 int who;
33 struct rusage ru;
34
Guido van Rossum43713e52000-02-29 13:59:29 +000035 if (!PyArg_ParseTuple(args, "i:getrusage", &who))
Guido van Rossum2e631391996-12-18 18:37:27 +000036 return NULL;
37
38 if (getrusage(who, &ru) == -1) {
39 if (errno == EINVAL) {
40 PyErr_SetString(PyExc_ValueError,
41 "invalid who parameter");
42 return NULL;
43 }
44 PyErr_SetFromErrno(ResourceError);
45 return NULL;
46 }
47
48 /* Yeah, this 16-tuple is way ugly. It's probably a lot less
49 ugly than a dictionary with keys (or object attributes)
50 named things like 'ixrss'.
51 */
52 return Py_BuildValue(
53 "ddiiiiiiiiiiiiii",
54 doubletime(ru.ru_utime), /* user time used */
55 doubletime(ru.ru_stime), /* system time used */
56 ru.ru_maxrss, /* max. resident set size */
57 ru.ru_ixrss, /* shared memory size */
58 ru.ru_idrss, /* unshared memory size */
59 ru.ru_isrss, /* unshared stack size */
60 ru.ru_minflt, /* page faults not requiring I/O*/
61 ru.ru_majflt, /* page faults requiring I/O */
62 ru.ru_nswap, /* number of swap outs */
63 ru.ru_inblock, /* block input operations */
64 ru.ru_oublock, /* block output operations */
65 ru.ru_msgsnd, /* messages sent */
66 ru.ru_msgrcv, /* messages received */
67 ru.ru_nsignals, /* signals received */
Thomas Wouters7e474022000-07-16 12:04:32 +000068 ru.ru_nvcsw, /* voluntary context switches */
69 ru.ru_nivcsw /* involuntary context switches */
Guido van Rossum2e631391996-12-18 18:37:27 +000070 );
71}
72
73
74static PyObject *
Peter Schneider-Kamp416d4132000-07-10 12:15:54 +000075resource_getrlimit(PyObject *self, PyObject *args)
Guido van Rossum2e631391996-12-18 18:37:27 +000076{
77 struct rlimit rl;
78 int resource;
Guido van Rossum2e631391996-12-18 18:37:27 +000079
Guido van Rossum43713e52000-02-29 13:59:29 +000080 if (!PyArg_ParseTuple(args, "i:getrlimit", &resource))
Guido van Rossum2e631391996-12-18 18:37:27 +000081 return NULL;
82
83 if (resource < 0 || resource >= RLIM_NLIMITS) {
84 PyErr_SetString(PyExc_ValueError,
85 "invalid resource specified");
86 return NULL;
87 }
88
89 if (getrlimit(resource, &rl) == -1) {
90 PyErr_SetFromErrno(ResourceError);
91 return NULL;
92 }
Guido van Rossum763737b1999-01-06 18:44:57 +000093
94#if defined(HAVE_LONG_LONG)
95 if (sizeof(rl.rlim_cur) > sizeof(long)) {
96 return Py_BuildValue("LL",
97 (LONG_LONG) rl.rlim_cur,
98 (LONG_LONG) rl.rlim_max);
99 }
100#endif
101 return Py_BuildValue("ii", (long) rl.rlim_cur, (long) rl.rlim_max);
Guido van Rossum2e631391996-12-18 18:37:27 +0000102}
103
104static PyObject *
Peter Schneider-Kamp416d4132000-07-10 12:15:54 +0000105resource_setrlimit(PyObject *self, PyObject *args)
Guido van Rossum2e631391996-12-18 18:37:27 +0000106{
107 struct rlimit rl;
108 int resource;
Guido van Rossum763737b1999-01-06 18:44:57 +0000109 PyObject *curobj, *maxobj;
Guido van Rossum2e631391996-12-18 18:37:27 +0000110
Guido van Rossum43713e52000-02-29 13:59:29 +0000111 if (!PyArg_ParseTuple(args, "i(OO):setrlimit", &resource, &curobj, &maxobj))
Guido van Rossum2e631391996-12-18 18:37:27 +0000112 return NULL;
113
114 if (resource < 0 || resource >= RLIM_NLIMITS) {
115 PyErr_SetString(PyExc_ValueError,
116 "invalid resource specified");
117 return NULL;
118 }
119
Guido van Rossum763737b1999-01-06 18:44:57 +0000120#if !defined(HAVE_LARGEFILE_SUPPORT)
121 rl.rlim_cur = PyInt_AsLong(curobj);
122 rl.rlim_max = PyInt_AsLong(maxobj);
123#else
124 /* The limits are probably bigger than a long */
125 rl.rlim_cur = PyLong_Check(curobj) ?
126 PyLong_AsLongLong(curobj) : PyInt_AsLong(curobj);
127 rl.rlim_max = PyLong_Check(maxobj) ?
128 PyLong_AsLongLong(maxobj) : PyInt_AsLong(maxobj);
129#endif
130
Guido van Rossum2e631391996-12-18 18:37:27 +0000131 rl.rlim_cur = rl.rlim_cur & RLIM_INFINITY;
132 rl.rlim_max = rl.rlim_max & RLIM_INFINITY;
133 if (setrlimit(resource, &rl) == -1) {
134 if (errno == EINVAL)
135 PyErr_SetString(PyExc_ValueError,
136 "current limit exceeds maximum limit");
137 else if (errno == EPERM)
138 PyErr_SetString(PyExc_ValueError,
139 "not allowed to raise maximum limit");
140 else
141 PyErr_SetFromErrno(ResourceError);
142 return NULL;
143 }
144 Py_INCREF(Py_None);
145 return Py_None;
146}
147
148static PyObject *
Peter Schneider-Kamp416d4132000-07-10 12:15:54 +0000149resource_getpagesize(PyObject *self, PyObject *args)
Guido van Rossum2e631391996-12-18 18:37:27 +0000150{
Guido van Rossum43713e52000-02-29 13:59:29 +0000151 if (!PyArg_ParseTuple(args, ":getpagesize"))
Guido van Rossum2e631391996-12-18 18:37:27 +0000152 return NULL;
153 return Py_BuildValue("i", getpagesize());
154}
155
156/* List of functions */
157
158static struct PyMethodDef
159resource_methods[] = {
160 {"getrusage", resource_getrusage, 1},
161 {"getrlimit", resource_getrlimit, 1},
162 {"setrlimit", resource_setrlimit, 1},
163 {"getpagesize", resource_getpagesize, 1},
164 {NULL, NULL} /* sentinel */
165};
166
167
168/* Module initialization */
169
170static void
171ins(PyObject *dict, char *name, int value)
172{
173 PyObject *v = PyInt_FromLong((long) value);
174 if (v) {
175 PyDict_SetItemString(dict, name, v);
176 Py_DECREF(v);
177 }
178 /* errors will be checked by initresource() */
179}
180
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000181void initresource(void)
Guido van Rossum2e631391996-12-18 18:37:27 +0000182{
183 PyObject *m, *d;
184
185 /* Create the module and add the functions */
186 m = Py_InitModule("resource", resource_methods);
187
188 /* Add some symbolic constants to the module */
189 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +0000190 ResourceError = PyErr_NewException("resource.error", NULL, NULL);
Guido van Rossum2e631391996-12-18 18:37:27 +0000191 PyDict_SetItemString(d, "error", ResourceError);
192
193 /* insert constants */
194#ifdef RLIMIT_CPU
195 ins(d, "RLIMIT_CPU", RLIMIT_CPU);
196#endif
197
198#ifdef RLIMIT_FSIZE
199 ins(d, "RLIMIT_FSIZE", RLIMIT_FSIZE);
200#endif
201
202#ifdef RLIMIT_DATA
203 ins(d, "RLIMIT_DATA", RLIMIT_DATA);
204#endif
205
206#ifdef RLIMIT_STACK
207 ins(d, "RLIMIT_STACK", RLIMIT_STACK);
208#endif
209
210#ifdef RLIMIT_CORE
211 ins(d, "RLIMIT_CORE", RLIMIT_CORE);
212#endif
213
214#ifdef RLIMIT_NOFILE
215 ins(d, "RLIMIT_NOFILE", RLIMIT_NOFILE);
216#endif
217
218#ifdef RLIMIT_OFILE
219 ins(d, "RLIMIT_OFILE", RLIMIT_OFILE);
220#endif
221
222#ifdef RLIMIT_VMEM
223 ins(d, "RLIMIT_VMEM", RLIMIT_VMEM);
224#endif
225
226#ifdef RLIMIT_AS
227 ins(d, "RLIMIT_AS", RLIMIT_AS);
228#endif
229
230#ifdef RLIMIT_RSS
231 ins(d, "RLIMIT_RSS", RLIMIT_RSS);
232#endif
233
234#ifdef RLIMIT_NPROC
235 ins(d, "RLIMIT_NPROC", RLIMIT_NPROC);
236#endif
237
238#ifdef RLIMIT_MEMLOCK
239 ins(d, "RLIMIT_MEMLOCK", RLIMIT_MEMLOCK);
240#endif
241
242#ifdef RUSAGE_SELF
243 ins(d, "RUSAGE_SELF", RUSAGE_SELF);
244#endif
245
Guido van Rossumebd05eb1997-12-09 19:35:48 +0000246#ifdef RUSAGE_CHILDREN
Guido van Rossum2e631391996-12-18 18:37:27 +0000247 ins(d, "RUSAGE_CHILDREN", RUSAGE_CHILDREN);
248#endif
249
250#ifdef RUSAGE_BOTH
251 ins(d, "RUSAGE_BOTH", RUSAGE_BOTH);
252#endif
Guido van Rossum2e631391996-12-18 18:37:27 +0000253}