mirror of
				https://github.com/python/cpython.git
				synced 2025-11-04 07:31:38 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			238 lines
		
	
	
	
		
			5.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			238 lines
		
	
	
	
		
			5.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
#include "Python.h"
 | 
						|
#include <sys/resource.h>
 | 
						|
#include <sys/time.h>
 | 
						|
#include <unistd.h>
 | 
						|
#include <string.h>
 | 
						|
#include <errno.h>
 | 
						|
 | 
						|
/* don't know why this isn't defined in a header file */
 | 
						|
#ifndef getrusage
 | 
						|
int getrusage(int who, struct rusage *rusage);
 | 
						|
#endif
 | 
						|
 | 
						|
#ifndef getpagesize
 | 
						|
int getpagesize(void);
 | 
						|
#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;
 | 
						|
	}
 | 
						|
	return Py_BuildValue("ii", rl.rlim_cur, rl.rlim_max);
 | 
						|
}
 | 
						|
 | 
						|
static PyObject *
 | 
						|
resource_setrlimit(self, args)
 | 
						|
	PyObject *self;
 | 
						|
	PyObject *args;
 | 
						|
{
 | 
						|
	struct rlimit rl;
 | 
						|
	int resource;
 | 
						|
 | 
						|
	if (!PyArg_ParseTuple(args, "i(ii)", &resource, &rl.rlim_cur, 
 | 
						|
			      &rl.rlim_max)) 
 | 
						|
		return NULL;
 | 
						|
 | 
						|
	if (resource < 0 || resource >= RLIM_NLIMITS) {
 | 
						|
		PyErr_SetString(PyExc_ValueError,
 | 
						|
				"invalid resource specified");
 | 
						|
		return NULL;
 | 
						|
	}
 | 
						|
 | 
						|
	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 = PyString_FromString("resource.error");
 | 
						|
	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_CHILDERN
 | 
						|
	ins(d, "RUSAGE_CHILDREN", RUSAGE_CHILDREN);
 | 
						|
#endif
 | 
						|
 | 
						|
#ifdef RUSAGE_BOTH
 | 
						|
	ins(d, "RUSAGE_BOTH", RUSAGE_BOTH);
 | 
						|
#endif
 | 
						|
 | 
						|
	/* Check for errors */
 | 
						|
	if (PyErr_Occurred())
 | 
						|
		Py_FatalError("can't initialize module resource");
 | 
						|
}
 |