home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / py2s152.zip / Modules / resource.c < prev    next >
C/C++ Source or Header  |  1999-06-27  |  8KB  |  288 lines

  1. /***********************************************************
  2. Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
  3. The Netherlands.
  4.  
  5.                         All Rights Reserved
  6.  
  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
  15. permission.
  16.  
  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.
  20.  
  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.
  29.  
  30. ******************************************************************/
  31.  
  32. #include "Python.h"
  33. #include "mytime.h" /* needed for SunOS4.1 */
  34. #include <sys/resource.h>
  35. #include <sys/time.h>
  36. #include <unistd.h>
  37. #include <string.h>
  38. #include <errno.h>
  39.  
  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... */
  46. #ifndef linux
  47. int getrusage();
  48. int getpagesize();
  49. #endif
  50.  
  51. #define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
  52.  
  53. static PyObject *ResourceError;
  54.  
  55. static PyObject *
  56. resource_getrusage(self, args)
  57.     PyObject *self;
  58.     PyObject *args;
  59. {
  60.     int who;
  61.     struct rusage ru;
  62.  
  63.     if (!PyArg_ParseTuple(args, "i", &who))
  64.         return NULL;
  65.  
  66.     if (getrusage(who, &ru) == -1) {
  67.         if (errno == EINVAL) {
  68.             PyErr_SetString(PyExc_ValueError,
  69.                     "invalid who parameter");
  70.             return NULL;
  71.         } 
  72.         PyErr_SetFromErrno(ResourceError);
  73.         return NULL;
  74.     }
  75.  
  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'. 
  79.        */
  80.     return Py_BuildValue(
  81.         "ddiiiiiiiiiiiiii",
  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 */
  98.         );
  99. }
  100.  
  101.  
  102. static PyObject *
  103. resource_getrlimit(self, args)
  104.     PyObject *self;
  105.     PyObject *args;
  106. {
  107.     struct rlimit rl;
  108.     int resource;
  109.  
  110.     if (!PyArg_ParseTuple(args, "i", &resource)) 
  111.         return NULL;
  112.  
  113.     if (resource < 0 || resource >= RLIM_NLIMITS) {
  114.         PyErr_SetString(PyExc_ValueError,
  115.                 "invalid resource specified");
  116.         return NULL;
  117.     }
  118.  
  119.     if (getrlimit(resource, &rl) == -1) {
  120.         PyErr_SetFromErrno(ResourceError);
  121.         return NULL;
  122.     }
  123.  
  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);
  129.     }
  130. #endif
  131.     return Py_BuildValue("ii", (long) rl.rlim_cur, (long) rl.rlim_max);
  132. }
  133.  
  134. static PyObject *
  135. resource_setrlimit(self, args)
  136.     PyObject *self;
  137.     PyObject *args;
  138. {
  139.     struct rlimit rl;
  140.     int resource;
  141.     PyObject *curobj, *maxobj;
  142.  
  143.     if (!PyArg_ParseTuple(args, "i(OO)", &resource, &curobj, &maxobj))
  144.         return NULL;
  145.  
  146.     if (resource < 0 || resource >= RLIM_NLIMITS) {
  147.         PyErr_SetString(PyExc_ValueError,
  148.                 "invalid resource specified");
  149.         return NULL;
  150.     }
  151.  
  152. #if !defined(HAVE_LARGEFILE_SUPPORT)
  153.     rl.rlim_cur = PyInt_AsLong(curobj);
  154.     rl.rlim_max = PyInt_AsLong(maxobj);
  155. #else
  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);
  161. #endif
  162.  
  163.     rl.rlim_cur = rl.rlim_cur & RLIM_INFINITY;
  164.     rl.rlim_max = rl.rlim_max & RLIM_INFINITY;
  165.     if (setrlimit(resource, &rl) == -1) {
  166.         if (errno == EINVAL) 
  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");
  172.         else
  173.             PyErr_SetFromErrno(ResourceError);
  174.         return NULL;
  175.     }
  176.     Py_INCREF(Py_None);
  177.     return Py_None;
  178. }
  179.  
  180. static PyObject *
  181. resource_getpagesize(self, args)
  182.     PyObject *self;
  183.     PyObject *args;
  184. {
  185.     if (!PyArg_ParseTuple(args, ""))
  186.         return NULL;
  187.     return Py_BuildValue("i", getpagesize());
  188. }
  189.  
  190. /* List of functions */
  191.  
  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 */
  199. };
  200.  
  201.  
  202. /* Module initialization */
  203.  
  204. static void
  205. ins(PyObject *dict, char *name, int value)
  206. {
  207.     PyObject *v = PyInt_FromLong((long) value);
  208.     if (v) {
  209.         PyDict_SetItemString(dict, name, v);
  210.         Py_DECREF(v);
  211.     }
  212.     /* errors will be checked by initresource() */
  213. }
  214.  
  215. void initresource()
  216. {
  217.     PyObject *m, *d;
  218.  
  219.     /* Create the module and add the functions */
  220.     m = Py_InitModule("resource", resource_methods);
  221.  
  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);
  226.  
  227.     /* insert constants */
  228. #ifdef RLIMIT_CPU
  229.     ins(d, "RLIMIT_CPU", RLIMIT_CPU);
  230. #endif
  231.  
  232. #ifdef RLIMIT_FSIZE
  233.     ins(d, "RLIMIT_FSIZE", RLIMIT_FSIZE);
  234. #endif
  235.  
  236. #ifdef RLIMIT_DATA
  237.     ins(d, "RLIMIT_DATA", RLIMIT_DATA);
  238. #endif
  239.  
  240. #ifdef RLIMIT_STACK
  241.     ins(d, "RLIMIT_STACK", RLIMIT_STACK);
  242. #endif
  243.  
  244. #ifdef RLIMIT_CORE
  245.     ins(d, "RLIMIT_CORE", RLIMIT_CORE);
  246. #endif
  247.  
  248. #ifdef RLIMIT_NOFILE
  249.     ins(d, "RLIMIT_NOFILE", RLIMIT_NOFILE);
  250. #endif
  251.  
  252. #ifdef RLIMIT_OFILE
  253.     ins(d, "RLIMIT_OFILE", RLIMIT_OFILE);
  254. #endif
  255.  
  256. #ifdef RLIMIT_VMEM
  257.     ins(d, "RLIMIT_VMEM", RLIMIT_VMEM);
  258. #endif
  259.  
  260. #ifdef RLIMIT_AS
  261.     ins(d, "RLIMIT_AS", RLIMIT_AS);
  262. #endif
  263.  
  264. #ifdef RLIMIT_RSS
  265.     ins(d, "RLIMIT_RSS", RLIMIT_RSS);
  266. #endif
  267.  
  268. #ifdef RLIMIT_NPROC
  269.     ins(d, "RLIMIT_NPROC", RLIMIT_NPROC);
  270. #endif
  271.  
  272. #ifdef RLIMIT_MEMLOCK
  273.     ins(d, "RLIMIT_MEMLOCK", RLIMIT_MEMLOCK);
  274. #endif
  275.  
  276. #ifdef RUSAGE_SELF
  277.     ins(d, "RUSAGE_SELF", RUSAGE_SELF);
  278. #endif
  279.  
  280. #ifdef RUSAGE_CHILDREN
  281.     ins(d, "RUSAGE_CHILDREN", RUSAGE_CHILDREN);
  282. #endif
  283.  
  284. #ifdef RUSAGE_BOTH
  285.     ins(d, "RUSAGE_BOTH", RUSAGE_BOTH);
  286. #endif
  287. }
  288.