mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 05:31:20 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			287 lines
		
	
	
	
		
			7.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			287 lines
		
	
	
	
		
			7.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /***********************************************************
 | |
| Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
 | |
| The Netherlands.
 | |
| 
 | |
|                         All Rights Reserved
 | |
| 
 | |
| Permission to use, copy, modify, and distribute this software and its
 | |
| documentation for any purpose and without fee is hereby granted,
 | |
| provided that the above copyright notice appear in all copies and that
 | |
| both that copyright notice and this permission notice appear in
 | |
| supporting documentation, and that the names of Stichting Mathematisch
 | |
| Centrum or CWI or Corporation for National Research Initiatives or
 | |
| CNRI not be used in advertising or publicity pertaining to
 | |
| distribution of the software without specific, written prior
 | |
| permission.
 | |
| 
 | |
| While CWI is the initial source for this software, a modified version
 | |
| is made available by the Corporation for National Research Initiatives
 | |
| (CNRI) at the Internet address ftp://ftp.python.org.
 | |
| 
 | |
| STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
 | |
| REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
 | |
| MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
 | |
| CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
 | |
| DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
 | |
| PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 | |
| TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 | |
| PERFORMANCE OF THIS SOFTWARE.
 | |
| 
 | |
| ******************************************************************/
 | |
| 
 | |
| #include "Python.h"
 | |
| #include "mytime.h" /* needed for SunOS4.1 */
 | |
| #include <sys/resource.h>
 | |
| #include <sys/time.h>
 | |
| #include <unistd.h>
 | |
| #include <string.h>
 | |
| #include <errno.h>
 | |
| 
 | |
| /* On some systems, these aren't in any header file.
 | |
|    On others they are, with inconsistent prototypes.
 | |
|    We declare the (default) return type, to shut up gcc -Wall;
 | |
|    but we can't declare the prototype, to avoid errors
 | |
|    when the header files declare it different.
 | |
|    Worse, on some Linuxes, getpagesize() returns a size_t... */
 | |
| #ifndef linux
 | |
| int getrusage();
 | |
| int getpagesize();
 | |
| #endif
 | |
| 
 | |
| #define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
 | |
| 
 | |
| static PyObject *ResourceError;
 | |
| 
 | |
| static PyObject *
 | |
| resource_getrusage(self, args)
 | |
| 	PyObject *self;
 | |
| 	PyObject *args;
 | |
| {
 | |
| 	int who;
 | |
| 	struct rusage ru;
 | |
| 
 | |
| 	if (!PyArg_ParseTuple(args, "i", &who))
 | |
| 		return NULL;
 | |
| 
 | |
| 	if (getrusage(who, &ru) == -1) {
 | |
| 		if (errno == EINVAL) {
 | |
| 			PyErr_SetString(PyExc_ValueError,
 | |
| 					"invalid who parameter");
 | |
| 			return NULL;
 | |
| 		} 
 | |
| 		PyErr_SetFromErrno(ResourceError);
 | |
| 		return NULL;
 | |
| 	}
 | |
| 
 | |
| 	/* Yeah, this 16-tuple is way ugly. It's probably a lot less
 | |
| 	   ugly than a dictionary with keys (or object attributes)
 | |
| 	   named things like 'ixrss'. 
 | |
| 	   */
 | |
| 	return Py_BuildValue(
 | |
| 		"ddiiiiiiiiiiiiii",
 | |
| 		doubletime(ru.ru_utime),     /* user time used */
 | |
| 		doubletime(ru.ru_stime),     /* system time used */
 | |
| 		ru.ru_maxrss,		     /* max. resident set size */
 | |
| 		ru.ru_ixrss,		     /* shared memory size */
 | |
| 		ru.ru_idrss,		     /* unshared memory size */
 | |
| 		ru.ru_isrss,		     /* unshared stack size */
 | |
| 		ru.ru_minflt,		     /* page faults not requiring I/O*/
 | |
| 		ru.ru_majflt,		     /* page faults requiring I/O */
 | |
| 		ru.ru_nswap,		     /* number of swap outs */
 | |
| 		ru.ru_inblock,		     /* block input operations */
 | |
| 		ru.ru_oublock,		     /* block output operations */
 | |
| 		ru.ru_msgsnd,		     /* messages sent */
 | |
| 		ru.ru_msgrcv,		     /* messages received */
 | |
| 		ru.ru_nsignals,		     /* signals received */
 | |
| 		ru.ru_nvcsw,		     /* voluntary context switchs */
 | |
| 		ru.ru_nivcsw		     /* involuntary context switchs */
 | |
| 		);
 | |
| }
 | |
| 
 | |
| 
 | |
| static PyObject *
 | |
| resource_getrlimit(self, args)
 | |
| 	PyObject *self;
 | |
| 	PyObject *args;
 | |
| {
 | |
| 	struct rlimit rl;
 | |
| 	int resource;
 | |
| 
 | |
| 	if (!PyArg_ParseTuple(args, "i", &resource)) 
 | |
| 		return NULL;
 | |
| 
 | |
| 	if (resource < 0 || resource >= RLIM_NLIMITS) {
 | |
| 		PyErr_SetString(PyExc_ValueError,
 | |
| 				"invalid resource specified");
 | |
| 		return NULL;
 | |
| 	}
 | |
| 
 | |
| 	if (getrlimit(resource, &rl) == -1) {
 | |
| 		PyErr_SetFromErrno(ResourceError);
 | |
| 		return NULL;
 | |
| 	}
 | |
| 
 | |
| #if defined(HAVE_LONG_LONG)
 | |
| 	if (sizeof(rl.rlim_cur) > sizeof(long)) {
 | |
| 		return Py_BuildValue("LL",
 | |
| 				     (LONG_LONG) rl.rlim_cur,
 | |
| 				     (LONG_LONG) rl.rlim_max);
 | |
| 	}
 | |
| #endif
 | |
| 	return Py_BuildValue("ii", (long) rl.rlim_cur, (long) rl.rlim_max);
 | |
| }
 | |
| 
 | |
| static PyObject *
 | |
| resource_setrlimit(self, args)
 | |
| 	PyObject *self;
 | |
| 	PyObject *args;
 | |
| {
 | |
| 	struct rlimit rl;
 | |
| 	int resource;
 | |
| 	PyObject *curobj, *maxobj;
 | |
| 
 | |
| 	if (!PyArg_ParseTuple(args, "i(OO)", &resource, &curobj, &maxobj))
 | |
| 		return NULL;
 | |
| 
 | |
| 	if (resource < 0 || resource >= RLIM_NLIMITS) {
 | |
| 		PyErr_SetString(PyExc_ValueError,
 | |
| 				"invalid resource specified");
 | |
| 		return NULL;
 | |
| 	}
 | |
| 
 | |
| #if !defined(HAVE_LARGEFILE_SUPPORT)
 | |
| 	rl.rlim_cur = PyInt_AsLong(curobj);
 | |
| 	rl.rlim_max = PyInt_AsLong(maxobj);
 | |
| #else
 | |
| 	/* The limits are probably bigger than a long */
 | |
| 	rl.rlim_cur = PyLong_Check(curobj) ?
 | |
| 		PyLong_AsLongLong(curobj) : PyInt_AsLong(curobj);
 | |
| 	rl.rlim_max = PyLong_Check(maxobj) ?
 | |
| 		PyLong_AsLongLong(maxobj) : PyInt_AsLong(maxobj);
 | |
| #endif
 | |
| 
 | |
| 	rl.rlim_cur = rl.rlim_cur & RLIM_INFINITY;
 | |
| 	rl.rlim_max = rl.rlim_max & RLIM_INFINITY;
 | |
| 	if (setrlimit(resource, &rl) == -1) {
 | |
| 		if (errno == EINVAL) 
 | |
| 			PyErr_SetString(PyExc_ValueError,
 | |
| 					"current limit exceeds maximum limit");
 | |
| 		else if (errno == EPERM)
 | |
| 			PyErr_SetString(PyExc_ValueError,
 | |
| 					"not allowed to raise maximum limit");
 | |
| 		else
 | |
| 			PyErr_SetFromErrno(ResourceError);
 | |
| 		return NULL;
 | |
| 	}
 | |
| 	Py_INCREF(Py_None);
 | |
| 	return Py_None;
 | |
| }
 | |
| 
 | |
| static PyObject *
 | |
| resource_getpagesize(self, args)
 | |
| 	PyObject *self;
 | |
| 	PyObject *args;
 | |
| {
 | |
| 	if (!PyArg_ParseTuple(args, ""))
 | |
| 		return NULL;
 | |
| 	return Py_BuildValue("i", getpagesize());
 | |
| }
 | |
| 
 | |
| /* List of functions */
 | |
| 
 | |
| static struct PyMethodDef
 | |
| resource_methods[] = {
 | |
| 	{"getrusage",    resource_getrusage,   1},
 | |
| 	{"getrlimit",    resource_getrlimit,   1},
 | |
| 	{"setrlimit",    resource_setrlimit,   1},
 | |
| 	{"getpagesize",  resource_getpagesize, 1},
 | |
| 	{NULL, NULL}			     /* sentinel */
 | |
| };
 | |
| 
 | |
| 
 | |
| /* Module initialization */
 | |
| 
 | |
| static void
 | |
| ins(PyObject *dict, char *name, int value)
 | |
| {
 | |
| 	PyObject *v = PyInt_FromLong((long) value);
 | |
| 	if (v) {
 | |
| 		PyDict_SetItemString(dict, name, v);
 | |
| 		Py_DECREF(v);
 | |
| 	}
 | |
| 	/* errors will be checked by initresource() */
 | |
| }
 | |
| 
 | |
| void initresource()
 | |
| {
 | |
| 	PyObject *m, *d;
 | |
| 
 | |
| 	/* Create the module and add the functions */
 | |
| 	m = Py_InitModule("resource", resource_methods);
 | |
| 
 | |
| 	/* Add some symbolic constants to the module */
 | |
| 	d = PyModule_GetDict(m);
 | |
| 	ResourceError = PyErr_NewException("resource.error", NULL, NULL);
 | |
| 	PyDict_SetItemString(d, "error", ResourceError);
 | |
| 
 | |
| 	/* insert constants */
 | |
| #ifdef RLIMIT_CPU
 | |
| 	ins(d, "RLIMIT_CPU", RLIMIT_CPU);
 | |
| #endif
 | |
| 
 | |
| #ifdef RLIMIT_FSIZE
 | |
| 	ins(d, "RLIMIT_FSIZE", RLIMIT_FSIZE);
 | |
| #endif
 | |
| 
 | |
| #ifdef RLIMIT_DATA
 | |
| 	ins(d, "RLIMIT_DATA", RLIMIT_DATA);
 | |
| #endif
 | |
| 
 | |
| #ifdef RLIMIT_STACK
 | |
| 	ins(d, "RLIMIT_STACK", RLIMIT_STACK);
 | |
| #endif
 | |
| 
 | |
| #ifdef RLIMIT_CORE
 | |
| 	ins(d, "RLIMIT_CORE", RLIMIT_CORE);
 | |
| #endif
 | |
| 
 | |
| #ifdef RLIMIT_NOFILE
 | |
| 	ins(d, "RLIMIT_NOFILE", RLIMIT_NOFILE);
 | |
| #endif
 | |
| 
 | |
| #ifdef RLIMIT_OFILE
 | |
| 	ins(d, "RLIMIT_OFILE", RLIMIT_OFILE);
 | |
| #endif
 | |
| 
 | |
| #ifdef RLIMIT_VMEM
 | |
| 	ins(d, "RLIMIT_VMEM", RLIMIT_VMEM);
 | |
| #endif
 | |
| 
 | |
| #ifdef RLIMIT_AS
 | |
| 	ins(d, "RLIMIT_AS", RLIMIT_AS);
 | |
| #endif
 | |
| 
 | |
| #ifdef RLIMIT_RSS
 | |
| 	ins(d, "RLIMIT_RSS", RLIMIT_RSS);
 | |
| #endif
 | |
| 
 | |
| #ifdef RLIMIT_NPROC
 | |
| 	ins(d, "RLIMIT_NPROC", RLIMIT_NPROC);
 | |
| #endif
 | |
| 
 | |
| #ifdef RLIMIT_MEMLOCK
 | |
| 	ins(d, "RLIMIT_MEMLOCK", RLIMIT_MEMLOCK);
 | |
| #endif
 | |
| 
 | |
| #ifdef RUSAGE_SELF
 | |
| 	ins(d, "RUSAGE_SELF", RUSAGE_SELF);
 | |
| #endif
 | |
| 
 | |
| #ifdef RUSAGE_CHILDREN
 | |
| 	ins(d, "RUSAGE_CHILDREN", RUSAGE_CHILDREN);
 | |
| #endif
 | |
| 
 | |
| #ifdef RUSAGE_BOTH
 | |
| 	ins(d, "RUSAGE_BOTH", RUSAGE_BOTH);
 | |
| #endif
 | |
| }
 | 
