mirror of
				https://github.com/python/cpython.git
				synced 2025-11-03 23:21:29 +00:00 
			
		
		
		
	
		
			
	
	
		
			239 lines
		
	
	
	
		
			5.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			239 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");
							 | 
						||
| 
								 | 
							
								}
							 |