home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 15 / AACD15.ISO / AACD / Programming / Python2 / Python20_source / Modules / resource.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-10-25  |  5.7 KB  |  245 lines

  1.  
  2. #include "Python.h"
  3. #include <sys/resource.h>
  4. #include <sys/time.h>
  5. #include <unistd.h>
  6. #include <string.h>
  7. #include <errno.h>
  8.  
  9. /* On some systems, these aren't in any header file.
  10.    On others they are, with inconsistent prototypes.
  11.    We declare the (default) return type, to shut up gcc -Wall;
  12.    but we can't declare the prototype, to avoid errors
  13.    when the header files declare it different.
  14.    Worse, on some Linuxes, getpagesize() returns a size_t... */
  15.  
  16. #define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
  17.  
  18. static PyObject *ResourceError;
  19.  
  20. static PyObject *
  21. resource_getrusage(PyObject *self, PyObject *args)
  22. {
  23.     int who;
  24.     struct rusage ru;
  25.  
  26.     if (!PyArg_ParseTuple(args, "i:getrusage", &who))
  27.         return NULL;
  28.  
  29.     if (getrusage(who, &ru) == -1) {
  30.         if (errno == EINVAL) {
  31.             PyErr_SetString(PyExc_ValueError,
  32.                     "invalid who parameter");
  33.             return NULL;
  34.         } 
  35.         PyErr_SetFromErrno(ResourceError);
  36.         return NULL;
  37.     }
  38.  
  39.     /* Yeah, this 16-tuple is way ugly. It's probably a lot less
  40.        ugly than a dictionary with keys (or object attributes)
  41.        named things like 'ixrss'. 
  42.        */
  43.     return Py_BuildValue(
  44.         "ddiiiiiiiiiiiiii",
  45.         doubletime(ru.ru_utime),     /* user time used */
  46.         doubletime(ru.ru_stime),     /* system time used */
  47.         ru.ru_maxrss,             /* max. resident set size */
  48.         ru.ru_ixrss,             /* shared memory size */
  49.         ru.ru_idrss,             /* unshared memory size */
  50.         ru.ru_isrss,             /* unshared stack size */
  51.         ru.ru_minflt,             /* page faults not requiring I/O*/
  52.         ru.ru_majflt,             /* page faults requiring I/O */
  53.         ru.ru_nswap,             /* number of swap outs */
  54.         ru.ru_inblock,             /* block input operations */
  55.         ru.ru_oublock,             /* block output operations */
  56.         ru.ru_msgsnd,             /* messages sent */
  57.         ru.ru_msgrcv,             /* messages received */
  58.         ru.ru_nsignals,             /* signals received */
  59.         ru.ru_nvcsw,             /* voluntary context switches */
  60.         ru.ru_nivcsw             /* involuntary context switches */
  61.         );
  62. }
  63.  
  64.  
  65. static PyObject *
  66. resource_getrlimit(PyObject *self, PyObject *args)
  67. {
  68.     struct rlimit rl;
  69.     int resource;
  70.  
  71.     if (!PyArg_ParseTuple(args, "i:getrlimit", &resource)) 
  72.         return NULL;
  73.  
  74.     if (resource < 0 || resource >= RLIM_NLIMITS) {
  75.         PyErr_SetString(PyExc_ValueError,
  76.                 "invalid resource specified");
  77.         return NULL;
  78.     }
  79.  
  80.     if (getrlimit(resource, &rl) == -1) {
  81.         PyErr_SetFromErrno(ResourceError);
  82.         return NULL;
  83.     }
  84.  
  85. #if defined(HAVE_LONG_LONG)
  86.     if (sizeof(rl.rlim_cur) > sizeof(long)) {
  87.         return Py_BuildValue("LL",
  88.                      (LONG_LONG) rl.rlim_cur,
  89.                      (LONG_LONG) rl.rlim_max);
  90.     }
  91. #endif
  92.     return Py_BuildValue("ii", (long) rl.rlim_cur, (long) rl.rlim_max);
  93. }
  94.  
  95. static PyObject *
  96. resource_setrlimit(PyObject *self, PyObject *args)
  97. {
  98.     struct rlimit rl;
  99.     int resource;
  100.     PyObject *curobj, *maxobj;
  101.  
  102.     if (!PyArg_ParseTuple(args, "i(OO):setrlimit", &resource, &curobj, &maxobj))
  103.         return NULL;
  104.  
  105.     if (resource < 0 || resource >= RLIM_NLIMITS) {
  106.         PyErr_SetString(PyExc_ValueError,
  107.                 "invalid resource specified");
  108.         return NULL;
  109.     }
  110.  
  111. #if !defined(HAVE_LARGEFILE_SUPPORT)
  112.     rl.rlim_cur = PyInt_AsLong(curobj);
  113.     rl.rlim_max = PyInt_AsLong(maxobj);
  114. #else
  115.     /* The limits are probably bigger than a long */
  116.     rl.rlim_cur = PyLong_Check(curobj) ?
  117.         PyLong_AsLongLong(curobj) : PyInt_AsLong(curobj);
  118.     rl.rlim_max = PyLong_Check(maxobj) ?
  119.         PyLong_AsLongLong(maxobj) : PyInt_AsLong(maxobj);
  120. #endif
  121.  
  122.     rl.rlim_cur = rl.rlim_cur & RLIM_INFINITY;
  123.     rl.rlim_max = rl.rlim_max & RLIM_INFINITY;
  124.     if (setrlimit(resource, &rl) == -1) {
  125.         if (errno == EINVAL) 
  126.             PyErr_SetString(PyExc_ValueError,
  127.                     "current limit exceeds maximum limit");
  128.         else if (errno == EPERM)
  129.             PyErr_SetString(PyExc_ValueError,
  130.                     "not allowed to raise maximum limit");
  131.         else
  132.             PyErr_SetFromErrno(ResourceError);
  133.         return NULL;
  134.     }
  135.     Py_INCREF(Py_None);
  136.     return Py_None;
  137. }
  138.  
  139. static PyObject *
  140. resource_getpagesize(PyObject *self, PyObject *args)
  141. {
  142.     if (!PyArg_ParseTuple(args, ":getpagesize"))
  143.         return NULL;
  144.     return Py_BuildValue("i", getpagesize());
  145. }
  146.  
  147. /* List of functions */
  148.  
  149. static struct PyMethodDef
  150. resource_methods[] = {
  151.     {"getrusage",    resource_getrusage,   1},
  152.     {"getrlimit",    resource_getrlimit,   1},
  153.     {"setrlimit",    resource_setrlimit,   1},
  154.     {"getpagesize",  resource_getpagesize, 1},
  155.     {NULL, NULL}                 /* sentinel */
  156. };
  157.  
  158.  
  159. /* Module initialization */
  160.  
  161. static void
  162. ins(PyObject *dict, char *name, int value)
  163. {
  164.     PyObject *v = PyInt_FromLong((long) value);
  165.     if (v) {
  166.         PyDict_SetItemString(dict, name, v);
  167.         Py_DECREF(v);
  168.     }
  169.     /* errors will be checked by initresource() */
  170. }
  171.  
  172. void initresource(void)
  173. {
  174.     PyObject *m, *d;
  175.  
  176.     /* Create the module and add the functions */
  177.     m = Py_InitModule("resource", resource_methods);
  178.  
  179.     /* Add some symbolic constants to the module */
  180.     d = PyModule_GetDict(m);
  181.     ResourceError = PyErr_NewException("resource.error", NULL, NULL);
  182.     PyDict_SetItemString(d, "error", ResourceError);
  183.  
  184.     /* insert constants */
  185. #ifdef RLIMIT_CPU
  186.     ins(d, "RLIMIT_CPU", RLIMIT_CPU);
  187. #endif
  188.  
  189. #ifdef RLIMIT_FSIZE
  190.     ins(d, "RLIMIT_FSIZE", RLIMIT_FSIZE);
  191. #endif
  192.  
  193. #ifdef RLIMIT_DATA
  194.     ins(d, "RLIMIT_DATA", RLIMIT_DATA);
  195. #endif
  196.  
  197. #ifdef RLIMIT_STACK
  198.     ins(d, "RLIMIT_STACK", RLIMIT_STACK);
  199. #endif
  200.  
  201. #ifdef RLIMIT_CORE
  202.     ins(d, "RLIMIT_CORE", RLIMIT_CORE);
  203. #endif
  204.  
  205. #ifdef RLIMIT_NOFILE
  206.     ins(d, "RLIMIT_NOFILE", RLIMIT_NOFILE);
  207. #endif
  208.  
  209. #ifdef RLIMIT_OFILE
  210.     ins(d, "RLIMIT_OFILE", RLIMIT_OFILE);
  211. #endif
  212.  
  213. #ifdef RLIMIT_VMEM
  214.     ins(d, "RLIMIT_VMEM", RLIMIT_VMEM);
  215. #endif
  216.  
  217. #ifdef RLIMIT_AS
  218.     ins(d, "RLIMIT_AS", RLIMIT_AS);
  219. #endif
  220.  
  221. #ifdef RLIMIT_RSS
  222.     ins(d, "RLIMIT_RSS", RLIMIT_RSS);
  223. #endif
  224.  
  225. #ifdef RLIMIT_NPROC
  226.     ins(d, "RLIMIT_NPROC", RLIMIT_NPROC);
  227. #endif
  228.  
  229. #ifdef RLIMIT_MEMLOCK
  230.     ins(d, "RLIMIT_MEMLOCK", RLIMIT_MEMLOCK);
  231. #endif
  232.  
  233. #ifdef RUSAGE_SELF
  234.     ins(d, "RUSAGE_SELF", RUSAGE_SELF);
  235. #endif
  236.  
  237. #ifdef RUSAGE_CHILDREN
  238.     ins(d, "RUSAGE_CHILDREN", RUSAGE_CHILDREN);
  239. #endif
  240.  
  241. #ifdef RUSAGE_BOTH
  242.     ins(d, "RUSAGE_BOTH", RUSAGE_BOTH);
  243. #endif
  244. }
  245.