1 /***********************************************************
2 Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
7 Permission to use, copy, modify, and distribute this software and its
8 documentation for any purpose and without fee is hereby granted,
9 provided that the above copyright notice appear in all copies and that
10 both that copyright notice and this permission notice appear in
11 supporting documentation, and that the names of Stichting Mathematisch
12 Centrum or CWI or Corporation for National Research Initiatives or
13 CNRI not be used in advertising or publicity pertaining to
14 distribution of the software without specific, written prior
17 While CWI is the initial source for this software, a modified version
18 is made available by the Corporation for National Research Initiatives
19 (CNRI) at the Internet address ftp://ftp.python.org.
21 STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22 REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23 MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24 CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26 PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27 TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28 PERFORMANCE OF THIS SOFTWARE.
30 ******************************************************************/
33 #include "mytime.h" /* needed for SunOS4.1 */
34 #include <sys/resource.h>
40 /* 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... */
51 #define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
53 static PyObject
*ResourceError
;
56 resource_getrusage(self
, args
)
63 if (!PyArg_ParseTuple(args
, "i", &who
))
66 if (getrusage(who
, &ru
) == -1) {
67 if (errno
== EINVAL
) {
68 PyErr_SetString(PyExc_ValueError
,
69 "invalid who parameter");
72 PyErr_SetFromErrno(ResourceError
);
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'.
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 */
103 resource_getrlimit(self
, args
)
110 if (!PyArg_ParseTuple(args
, "i", &resource
))
113 if (resource
< 0 || resource
>= RLIM_NLIMITS
) {
114 PyErr_SetString(PyExc_ValueError
,
115 "invalid resource specified");
119 if (getrlimit(resource
, &rl
) == -1) {
120 PyErr_SetFromErrno(ResourceError
);
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
);
131 return Py_BuildValue("ii", (long) rl
.rlim_cur
, (long) rl
.rlim_max
);
135 resource_setrlimit(self
, args
)
141 PyObject
*curobj
, *maxobj
;
143 if (!PyArg_ParseTuple(args
, "i(OO)", &resource
, &curobj
, &maxobj
))
146 if (resource
< 0 || resource
>= RLIM_NLIMITS
) {
147 PyErr_SetString(PyExc_ValueError
,
148 "invalid resource specified");
152 #if !defined(HAVE_LARGEFILE_SUPPORT)
153 rl
.rlim_cur
= PyInt_AsLong(curobj
);
154 rl
.rlim_max
= PyInt_AsLong(maxobj
);
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
);
163 rl
.rlim_cur
= rl
.rlim_cur
& RLIM_INFINITY
;
164 rl
.rlim_max
= rl
.rlim_max
& RLIM_INFINITY
;
165 if (setrlimit(resource
, &rl
) == -1) {
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");
173 PyErr_SetFromErrno(ResourceError
);
181 resource_getpagesize(self
, args
)
185 if (!PyArg_ParseTuple(args
, ""))
187 return Py_BuildValue("i", getpagesize());
190 /* List of functions */
192 static struct PyMethodDef
193 resource_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 */
202 /* Module initialization */
205 ins(PyObject
*dict
, char *name
, int value
)
207 PyObject
*v
= PyInt_FromLong((long) value
);
209 PyDict_SetItemString(dict
, name
, v
);
212 /* errors will be checked by initresource() */
219 /* Create the module and add the functions */
220 m
= Py_InitModule("resource", resource_methods
);
222 /* Add some symbolic constants to the module */
223 d
= PyModule_GetDict(m
);
224 ResourceError
= PyErr_NewException("resource.error", NULL
, NULL
);
225 PyDict_SetItemString(d
, "error", ResourceError
);
227 /* insert constants */
229 ins(d
, "RLIMIT_CPU", RLIMIT_CPU
);
233 ins(d
, "RLIMIT_FSIZE", RLIMIT_FSIZE
);
237 ins(d
, "RLIMIT_DATA", RLIMIT_DATA
);
241 ins(d
, "RLIMIT_STACK", RLIMIT_STACK
);
245 ins(d
, "RLIMIT_CORE", RLIMIT_CORE
);
249 ins(d
, "RLIMIT_NOFILE", RLIMIT_NOFILE
);
253 ins(d
, "RLIMIT_OFILE", RLIMIT_OFILE
);
257 ins(d
, "RLIMIT_VMEM", RLIMIT_VMEM
);
261 ins(d
, "RLIMIT_AS", RLIMIT_AS
);
265 ins(d
, "RLIMIT_RSS", RLIMIT_RSS
);
269 ins(d
, "RLIMIT_NPROC", RLIMIT_NPROC
);
272 #ifdef RLIMIT_MEMLOCK
273 ins(d
, "RLIMIT_MEMLOCK", RLIMIT_MEMLOCK
);
277 ins(d
, "RUSAGE_SELF", RUSAGE_SELF
);
280 #ifdef RUSAGE_CHILDREN
281 ins(d
, "RUSAGE_CHILDREN", RUSAGE_CHILDREN
);
285 ins(d
, "RUSAGE_BOTH", RUSAGE_BOTH
);