17db96d56Sopenharmony_ci
27db96d56Sopenharmony_ci#include "Python.h"
37db96d56Sopenharmony_ci#include <sys/resource.h>
47db96d56Sopenharmony_ci#include <sys/time.h>
57db96d56Sopenharmony_ci#include <string.h>
67db96d56Sopenharmony_ci#include <errno.h>
77db96d56Sopenharmony_ci#include <unistd.h>
87db96d56Sopenharmony_ci
97db96d56Sopenharmony_ci/* On some systems, these aren't in any header file.
107db96d56Sopenharmony_ci   On others they are, with inconsistent prototypes.
117db96d56Sopenharmony_ci   We declare the (default) return type, to shut up gcc -Wall;
127db96d56Sopenharmony_ci   but we can't declare the prototype, to avoid errors
137db96d56Sopenharmony_ci   when the header files declare it different.
147db96d56Sopenharmony_ci   Worse, on some Linuxes, getpagesize() returns a size_t... */
157db96d56Sopenharmony_ci
167db96d56Sopenharmony_ci#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
177db96d56Sopenharmony_ci
187db96d56Sopenharmony_ci/*[clinic input]
197db96d56Sopenharmony_cimodule resource
207db96d56Sopenharmony_ci[clinic start generated code]*/
217db96d56Sopenharmony_ci/*[clinic end generated code: output=da39a3ee5e6b4b0d input=e89d38ed52609d7c]*/
227db96d56Sopenharmony_ci
237db96d56Sopenharmony_ci/*[python input]
247db96d56Sopenharmony_ciclass pid_t_converter(CConverter):
257db96d56Sopenharmony_ci    type = 'pid_t'
267db96d56Sopenharmony_ci    format_unit = '" _Py_PARSE_PID "'
277db96d56Sopenharmony_ci[python start generated code]*/
287db96d56Sopenharmony_ci/*[python end generated code: output=da39a3ee5e6b4b0d input=0c1d19f640d57e48]*/
297db96d56Sopenharmony_ci
307db96d56Sopenharmony_ci#include "clinic/resource.c.h"
317db96d56Sopenharmony_ci
327db96d56Sopenharmony_ciPyDoc_STRVAR(struct_rusage__doc__,
337db96d56Sopenharmony_ci"struct_rusage: Result from getrusage.\n\n"
347db96d56Sopenharmony_ci"This object may be accessed either as a tuple of\n"
357db96d56Sopenharmony_ci"    (utime,stime,maxrss,ixrss,idrss,isrss,minflt,majflt,\n"
367db96d56Sopenharmony_ci"    nswap,inblock,oublock,msgsnd,msgrcv,nsignals,nvcsw,nivcsw)\n"
377db96d56Sopenharmony_ci"or via the attributes ru_utime, ru_stime, ru_maxrss, and so on.");
387db96d56Sopenharmony_ci
397db96d56Sopenharmony_cistatic PyStructSequence_Field struct_rusage_fields[] = {
407db96d56Sopenharmony_ci    {"ru_utime",        "user time used"},
417db96d56Sopenharmony_ci    {"ru_stime",        "system time used"},
427db96d56Sopenharmony_ci    {"ru_maxrss",       "max. resident set size"},
437db96d56Sopenharmony_ci    {"ru_ixrss",        "shared memory size"},
447db96d56Sopenharmony_ci    {"ru_idrss",        "unshared data size"},
457db96d56Sopenharmony_ci    {"ru_isrss",        "unshared stack size"},
467db96d56Sopenharmony_ci    {"ru_minflt",       "page faults not requiring I/O"},
477db96d56Sopenharmony_ci    {"ru_majflt",       "page faults requiring I/O"},
487db96d56Sopenharmony_ci    {"ru_nswap",        "number of swap outs"},
497db96d56Sopenharmony_ci    {"ru_inblock",      "block input operations"},
507db96d56Sopenharmony_ci    {"ru_oublock",      "block output operations"},
517db96d56Sopenharmony_ci    {"ru_msgsnd",       "IPC messages sent"},
527db96d56Sopenharmony_ci    {"ru_msgrcv",       "IPC messages received"},
537db96d56Sopenharmony_ci    {"ru_nsignals",     "signals received"},
547db96d56Sopenharmony_ci    {"ru_nvcsw",        "voluntary context switches"},
557db96d56Sopenharmony_ci    {"ru_nivcsw",       "involuntary context switches"},
567db96d56Sopenharmony_ci    {0}
577db96d56Sopenharmony_ci};
587db96d56Sopenharmony_ci
597db96d56Sopenharmony_cistatic PyStructSequence_Desc struct_rusage_desc = {
607db96d56Sopenharmony_ci    "resource.struct_rusage",           /* name */
617db96d56Sopenharmony_ci    struct_rusage__doc__,       /* doc */
627db96d56Sopenharmony_ci    struct_rusage_fields,       /* fields */
637db96d56Sopenharmony_ci    16          /* n_in_sequence */
647db96d56Sopenharmony_ci};
657db96d56Sopenharmony_ci
667db96d56Sopenharmony_citypedef struct {
677db96d56Sopenharmony_ci  PyTypeObject *StructRUsageType;
687db96d56Sopenharmony_ci} resourcemodulestate;
697db96d56Sopenharmony_ci
707db96d56Sopenharmony_ci
717db96d56Sopenharmony_cistatic inline resourcemodulestate*
727db96d56Sopenharmony_ciget_resource_state(PyObject *module)
737db96d56Sopenharmony_ci{
747db96d56Sopenharmony_ci    void *state = PyModule_GetState(module);
757db96d56Sopenharmony_ci    assert(state != NULL);
767db96d56Sopenharmony_ci    return (resourcemodulestate *)state;
777db96d56Sopenharmony_ci}
787db96d56Sopenharmony_ci
797db96d56Sopenharmony_cistatic struct PyModuleDef resourcemodule;
807db96d56Sopenharmony_ci
817db96d56Sopenharmony_ci#ifdef HAVE_GETRUSAGE
827db96d56Sopenharmony_ci/*[clinic input]
837db96d56Sopenharmony_ciresource.getrusage
847db96d56Sopenharmony_ci
857db96d56Sopenharmony_ci    who: int
867db96d56Sopenharmony_ci    /
877db96d56Sopenharmony_ci
887db96d56Sopenharmony_ci[clinic start generated code]*/
897db96d56Sopenharmony_ci
907db96d56Sopenharmony_cistatic PyObject *
917db96d56Sopenharmony_ciresource_getrusage_impl(PyObject *module, int who)
927db96d56Sopenharmony_ci/*[clinic end generated code: output=8fad2880ba6a9843 input=5c857bcc5b9ccb1b]*/
937db96d56Sopenharmony_ci{
947db96d56Sopenharmony_ci    struct rusage ru;
957db96d56Sopenharmony_ci    PyObject *result;
967db96d56Sopenharmony_ci
977db96d56Sopenharmony_ci    if (getrusage(who, &ru) == -1) {
987db96d56Sopenharmony_ci        if (errno == EINVAL) {
997db96d56Sopenharmony_ci            PyErr_SetString(PyExc_ValueError,
1007db96d56Sopenharmony_ci                            "invalid who parameter");
1017db96d56Sopenharmony_ci            return NULL;
1027db96d56Sopenharmony_ci        }
1037db96d56Sopenharmony_ci        PyErr_SetFromErrno(PyExc_OSError);
1047db96d56Sopenharmony_ci        return NULL;
1057db96d56Sopenharmony_ci    }
1067db96d56Sopenharmony_ci
1077db96d56Sopenharmony_ci    result = PyStructSequence_New(
1087db96d56Sopenharmony_ci        get_resource_state(module)->StructRUsageType);
1097db96d56Sopenharmony_ci    if (!result)
1107db96d56Sopenharmony_ci        return NULL;
1117db96d56Sopenharmony_ci
1127db96d56Sopenharmony_ci    PyStructSequence_SET_ITEM(result, 0,
1137db96d56Sopenharmony_ci                    PyFloat_FromDouble(doubletime(ru.ru_utime)));
1147db96d56Sopenharmony_ci    PyStructSequence_SET_ITEM(result, 1,
1157db96d56Sopenharmony_ci                    PyFloat_FromDouble(doubletime(ru.ru_stime)));
1167db96d56Sopenharmony_ci    PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong(ru.ru_maxrss));
1177db96d56Sopenharmony_ci    PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong(ru.ru_ixrss));
1187db96d56Sopenharmony_ci    PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong(ru.ru_idrss));
1197db96d56Sopenharmony_ci    PyStructSequence_SET_ITEM(result, 5, PyLong_FromLong(ru.ru_isrss));
1207db96d56Sopenharmony_ci    PyStructSequence_SET_ITEM(result, 6, PyLong_FromLong(ru.ru_minflt));
1217db96d56Sopenharmony_ci    PyStructSequence_SET_ITEM(result, 7, PyLong_FromLong(ru.ru_majflt));
1227db96d56Sopenharmony_ci    PyStructSequence_SET_ITEM(result, 8, PyLong_FromLong(ru.ru_nswap));
1237db96d56Sopenharmony_ci    PyStructSequence_SET_ITEM(result, 9, PyLong_FromLong(ru.ru_inblock));
1247db96d56Sopenharmony_ci    PyStructSequence_SET_ITEM(result, 10, PyLong_FromLong(ru.ru_oublock));
1257db96d56Sopenharmony_ci    PyStructSequence_SET_ITEM(result, 11, PyLong_FromLong(ru.ru_msgsnd));
1267db96d56Sopenharmony_ci    PyStructSequence_SET_ITEM(result, 12, PyLong_FromLong(ru.ru_msgrcv));
1277db96d56Sopenharmony_ci    PyStructSequence_SET_ITEM(result, 13, PyLong_FromLong(ru.ru_nsignals));
1287db96d56Sopenharmony_ci    PyStructSequence_SET_ITEM(result, 14, PyLong_FromLong(ru.ru_nvcsw));
1297db96d56Sopenharmony_ci    PyStructSequence_SET_ITEM(result, 15, PyLong_FromLong(ru.ru_nivcsw));
1307db96d56Sopenharmony_ci
1317db96d56Sopenharmony_ci    if (PyErr_Occurred()) {
1327db96d56Sopenharmony_ci        Py_DECREF(result);
1337db96d56Sopenharmony_ci        return NULL;
1347db96d56Sopenharmony_ci    }
1357db96d56Sopenharmony_ci
1367db96d56Sopenharmony_ci    return result;
1377db96d56Sopenharmony_ci}
1387db96d56Sopenharmony_ci#endif
1397db96d56Sopenharmony_ci
1407db96d56Sopenharmony_cistatic int
1417db96d56Sopenharmony_cipy2rlimit(PyObject *limits, struct rlimit *rl_out)
1427db96d56Sopenharmony_ci{
1437db96d56Sopenharmony_ci    PyObject *curobj, *maxobj;
1447db96d56Sopenharmony_ci    limits = PySequence_Tuple(limits);
1457db96d56Sopenharmony_ci    if (!limits)
1467db96d56Sopenharmony_ci        /* Here limits is a borrowed reference */
1477db96d56Sopenharmony_ci        return -1;
1487db96d56Sopenharmony_ci
1497db96d56Sopenharmony_ci    if (PyTuple_GET_SIZE(limits) != 2) {
1507db96d56Sopenharmony_ci        PyErr_SetString(PyExc_ValueError,
1517db96d56Sopenharmony_ci                        "expected a tuple of 2 integers");
1527db96d56Sopenharmony_ci        goto error;
1537db96d56Sopenharmony_ci    }
1547db96d56Sopenharmony_ci    curobj = PyTuple_GET_ITEM(limits, 0);
1557db96d56Sopenharmony_ci    maxobj = PyTuple_GET_ITEM(limits, 1);
1567db96d56Sopenharmony_ci#if !defined(HAVE_LARGEFILE_SUPPORT)
1577db96d56Sopenharmony_ci    rl_out->rlim_cur = PyLong_AsLong(curobj);
1587db96d56Sopenharmony_ci    if (rl_out->rlim_cur == (rlim_t)-1 && PyErr_Occurred())
1597db96d56Sopenharmony_ci        goto error;
1607db96d56Sopenharmony_ci    rl_out->rlim_max = PyLong_AsLong(maxobj);
1617db96d56Sopenharmony_ci    if (rl_out->rlim_max == (rlim_t)-1 && PyErr_Occurred())
1627db96d56Sopenharmony_ci        goto error;
1637db96d56Sopenharmony_ci#else
1647db96d56Sopenharmony_ci    /* The limits are probably bigger than a long */
1657db96d56Sopenharmony_ci    rl_out->rlim_cur = PyLong_AsLongLong(curobj);
1667db96d56Sopenharmony_ci    if (rl_out->rlim_cur == (rlim_t)-1 && PyErr_Occurred())
1677db96d56Sopenharmony_ci        goto error;
1687db96d56Sopenharmony_ci    rl_out->rlim_max = PyLong_AsLongLong(maxobj);
1697db96d56Sopenharmony_ci    if (rl_out->rlim_max == (rlim_t)-1 && PyErr_Occurred())
1707db96d56Sopenharmony_ci        goto error;
1717db96d56Sopenharmony_ci#endif
1727db96d56Sopenharmony_ci
1737db96d56Sopenharmony_ci    Py_DECREF(limits);
1747db96d56Sopenharmony_ci    rl_out->rlim_cur = rl_out->rlim_cur & RLIM_INFINITY;
1757db96d56Sopenharmony_ci    rl_out->rlim_max = rl_out->rlim_max & RLIM_INFINITY;
1767db96d56Sopenharmony_ci    return 0;
1777db96d56Sopenharmony_ci
1787db96d56Sopenharmony_cierror:
1797db96d56Sopenharmony_ci    Py_DECREF(limits);
1807db96d56Sopenharmony_ci    return -1;
1817db96d56Sopenharmony_ci}
1827db96d56Sopenharmony_ci
1837db96d56Sopenharmony_cistatic PyObject*
1847db96d56Sopenharmony_cirlimit2py(struct rlimit rl)
1857db96d56Sopenharmony_ci{
1867db96d56Sopenharmony_ci    if (sizeof(rl.rlim_cur) > sizeof(long)) {
1877db96d56Sopenharmony_ci        return Py_BuildValue("LL",
1887db96d56Sopenharmony_ci                             (long long) rl.rlim_cur,
1897db96d56Sopenharmony_ci                             (long long) rl.rlim_max);
1907db96d56Sopenharmony_ci    }
1917db96d56Sopenharmony_ci    return Py_BuildValue("ll", (long) rl.rlim_cur, (long) rl.rlim_max);
1927db96d56Sopenharmony_ci}
1937db96d56Sopenharmony_ci
1947db96d56Sopenharmony_ci/*[clinic input]
1957db96d56Sopenharmony_ciresource.getrlimit
1967db96d56Sopenharmony_ci
1977db96d56Sopenharmony_ci    resource: int
1987db96d56Sopenharmony_ci    /
1997db96d56Sopenharmony_ci
2007db96d56Sopenharmony_ci[clinic start generated code]*/
2017db96d56Sopenharmony_ci
2027db96d56Sopenharmony_cistatic PyObject *
2037db96d56Sopenharmony_ciresource_getrlimit_impl(PyObject *module, int resource)
2047db96d56Sopenharmony_ci/*[clinic end generated code: output=98327b25061ffe39 input=a697cb0004cb3c36]*/
2057db96d56Sopenharmony_ci{
2067db96d56Sopenharmony_ci    struct rlimit rl;
2077db96d56Sopenharmony_ci
2087db96d56Sopenharmony_ci    if (resource < 0 || resource >= RLIM_NLIMITS) {
2097db96d56Sopenharmony_ci        PyErr_SetString(PyExc_ValueError,
2107db96d56Sopenharmony_ci                        "invalid resource specified");
2117db96d56Sopenharmony_ci        return NULL;
2127db96d56Sopenharmony_ci    }
2137db96d56Sopenharmony_ci
2147db96d56Sopenharmony_ci    if (getrlimit(resource, &rl) == -1) {
2157db96d56Sopenharmony_ci        PyErr_SetFromErrno(PyExc_OSError);
2167db96d56Sopenharmony_ci        return NULL;
2177db96d56Sopenharmony_ci    }
2187db96d56Sopenharmony_ci    return rlimit2py(rl);
2197db96d56Sopenharmony_ci}
2207db96d56Sopenharmony_ci
2217db96d56Sopenharmony_ci/*[clinic input]
2227db96d56Sopenharmony_ciresource.setrlimit
2237db96d56Sopenharmony_ci
2247db96d56Sopenharmony_ci    resource: int
2257db96d56Sopenharmony_ci    limits: object
2267db96d56Sopenharmony_ci    /
2277db96d56Sopenharmony_ci
2287db96d56Sopenharmony_ci[clinic start generated code]*/
2297db96d56Sopenharmony_ci
2307db96d56Sopenharmony_cistatic PyObject *
2317db96d56Sopenharmony_ciresource_setrlimit_impl(PyObject *module, int resource, PyObject *limits)
2327db96d56Sopenharmony_ci/*[clinic end generated code: output=4e82ec3f34d013d1 input=6235a6ce23b4ca75]*/
2337db96d56Sopenharmony_ci{
2347db96d56Sopenharmony_ci    struct rlimit rl;
2357db96d56Sopenharmony_ci
2367db96d56Sopenharmony_ci    if (resource < 0 || resource >= RLIM_NLIMITS) {
2377db96d56Sopenharmony_ci        PyErr_SetString(PyExc_ValueError,
2387db96d56Sopenharmony_ci                        "invalid resource specified");
2397db96d56Sopenharmony_ci        return NULL;
2407db96d56Sopenharmony_ci    }
2417db96d56Sopenharmony_ci
2427db96d56Sopenharmony_ci    if (PySys_Audit("resource.setrlimit", "iO", resource,
2437db96d56Sopenharmony_ci                    limits ? limits : Py_None) < 0) {
2447db96d56Sopenharmony_ci        return NULL;
2457db96d56Sopenharmony_ci    }
2467db96d56Sopenharmony_ci
2477db96d56Sopenharmony_ci    if (py2rlimit(limits, &rl) < 0) {
2487db96d56Sopenharmony_ci        return NULL;
2497db96d56Sopenharmony_ci    }
2507db96d56Sopenharmony_ci
2517db96d56Sopenharmony_ci    if (setrlimit(resource, &rl) == -1) {
2527db96d56Sopenharmony_ci        if (errno == EINVAL)
2537db96d56Sopenharmony_ci            PyErr_SetString(PyExc_ValueError,
2547db96d56Sopenharmony_ci                            "current limit exceeds maximum limit");
2557db96d56Sopenharmony_ci        else if (errno == EPERM)
2567db96d56Sopenharmony_ci            PyErr_SetString(PyExc_ValueError,
2577db96d56Sopenharmony_ci                            "not allowed to raise maximum limit");
2587db96d56Sopenharmony_ci        else
2597db96d56Sopenharmony_ci            PyErr_SetFromErrno(PyExc_OSError);
2607db96d56Sopenharmony_ci        return NULL;
2617db96d56Sopenharmony_ci    }
2627db96d56Sopenharmony_ci    Py_RETURN_NONE;
2637db96d56Sopenharmony_ci}
2647db96d56Sopenharmony_ci
2657db96d56Sopenharmony_ci#ifdef HAVE_PRLIMIT
2667db96d56Sopenharmony_ci/*[clinic input]
2677db96d56Sopenharmony_ciresource.prlimit
2687db96d56Sopenharmony_ci
2697db96d56Sopenharmony_ci    pid: pid_t
2707db96d56Sopenharmony_ci    resource: int
2717db96d56Sopenharmony_ci    [
2727db96d56Sopenharmony_ci    limits: object
2737db96d56Sopenharmony_ci    ]
2747db96d56Sopenharmony_ci    /
2757db96d56Sopenharmony_ci
2767db96d56Sopenharmony_ci[clinic start generated code]*/
2777db96d56Sopenharmony_ci
2787db96d56Sopenharmony_cistatic PyObject *
2797db96d56Sopenharmony_ciresource_prlimit_impl(PyObject *module, pid_t pid, int resource,
2807db96d56Sopenharmony_ci                      int group_right_1, PyObject *limits)
2817db96d56Sopenharmony_ci/*[clinic end generated code: output=ee976b393187a7a3 input=b77743bdccc83564]*/
2827db96d56Sopenharmony_ci{
2837db96d56Sopenharmony_ci    struct rlimit old_limit, new_limit;
2847db96d56Sopenharmony_ci    int retval;
2857db96d56Sopenharmony_ci
2867db96d56Sopenharmony_ci    if (resource < 0 || resource >= RLIM_NLIMITS) {
2877db96d56Sopenharmony_ci        PyErr_SetString(PyExc_ValueError,
2887db96d56Sopenharmony_ci                        "invalid resource specified");
2897db96d56Sopenharmony_ci        return NULL;
2907db96d56Sopenharmony_ci    }
2917db96d56Sopenharmony_ci
2927db96d56Sopenharmony_ci    if (PySys_Audit("resource.prlimit", "iiO", pid, resource,
2937db96d56Sopenharmony_ci                    limits ? limits : Py_None) < 0) {
2947db96d56Sopenharmony_ci        return NULL;
2957db96d56Sopenharmony_ci    }
2967db96d56Sopenharmony_ci
2977db96d56Sopenharmony_ci    if (group_right_1) {
2987db96d56Sopenharmony_ci        if (py2rlimit(limits, &new_limit) < 0) {
2997db96d56Sopenharmony_ci            return NULL;
3007db96d56Sopenharmony_ci        }
3017db96d56Sopenharmony_ci        retval = prlimit(pid, resource, &new_limit, &old_limit);
3027db96d56Sopenharmony_ci    }
3037db96d56Sopenharmony_ci    else {
3047db96d56Sopenharmony_ci        retval = prlimit(pid, resource, NULL, &old_limit);
3057db96d56Sopenharmony_ci    }
3067db96d56Sopenharmony_ci
3077db96d56Sopenharmony_ci    if (retval == -1) {
3087db96d56Sopenharmony_ci        if (errno == EINVAL) {
3097db96d56Sopenharmony_ci            PyErr_SetString(PyExc_ValueError,
3107db96d56Sopenharmony_ci                            "current limit exceeds maximum limit");
3117db96d56Sopenharmony_ci        } else {
3127db96d56Sopenharmony_ci            PyErr_SetFromErrno(PyExc_OSError);
3137db96d56Sopenharmony_ci        }
3147db96d56Sopenharmony_ci        return NULL;
3157db96d56Sopenharmony_ci    }
3167db96d56Sopenharmony_ci    return rlimit2py(old_limit);
3177db96d56Sopenharmony_ci}
3187db96d56Sopenharmony_ci#endif /* HAVE_PRLIMIT */
3197db96d56Sopenharmony_ci
3207db96d56Sopenharmony_ci/*[clinic input]
3217db96d56Sopenharmony_ciresource.getpagesize -> int
3227db96d56Sopenharmony_ci[clinic start generated code]*/
3237db96d56Sopenharmony_ci
3247db96d56Sopenharmony_cistatic int
3257db96d56Sopenharmony_ciresource_getpagesize_impl(PyObject *module)
3267db96d56Sopenharmony_ci/*[clinic end generated code: output=9ba93eb0f3d6c3a9 input=546545e8c1f42085]*/
3277db96d56Sopenharmony_ci{
3287db96d56Sopenharmony_ci    long pagesize = 0;
3297db96d56Sopenharmony_ci#if defined(HAVE_GETPAGESIZE)
3307db96d56Sopenharmony_ci    pagesize = getpagesize();
3317db96d56Sopenharmony_ci#elif defined(HAVE_SYSCONF) && defined(_SC_PAGE_SIZE)
3327db96d56Sopenharmony_ci    pagesize = sysconf(_SC_PAGE_SIZE);
3337db96d56Sopenharmony_ci#else
3347db96d56Sopenharmony_ci#   error "unsupported platform: resource.getpagesize()"
3357db96d56Sopenharmony_ci#endif
3367db96d56Sopenharmony_ci    return pagesize;
3377db96d56Sopenharmony_ci}
3387db96d56Sopenharmony_ci
3397db96d56Sopenharmony_ci/* List of functions */
3407db96d56Sopenharmony_ci
3417db96d56Sopenharmony_cistatic struct PyMethodDef
3427db96d56Sopenharmony_ciresource_methods[] = {
3437db96d56Sopenharmony_ci    RESOURCE_GETRUSAGE_METHODDEF
3447db96d56Sopenharmony_ci    RESOURCE_GETRLIMIT_METHODDEF
3457db96d56Sopenharmony_ci    RESOURCE_PRLIMIT_METHODDEF
3467db96d56Sopenharmony_ci    RESOURCE_SETRLIMIT_METHODDEF
3477db96d56Sopenharmony_ci    RESOURCE_GETPAGESIZE_METHODDEF
3487db96d56Sopenharmony_ci    {NULL, NULL}                             /* sentinel */
3497db96d56Sopenharmony_ci};
3507db96d56Sopenharmony_ci
3517db96d56Sopenharmony_ci
3527db96d56Sopenharmony_ci/* Module initialization */
3537db96d56Sopenharmony_ci
3547db96d56Sopenharmony_cistatic int
3557db96d56Sopenharmony_ciresource_exec(PyObject *module)
3567db96d56Sopenharmony_ci{
3577db96d56Sopenharmony_ci    resourcemodulestate *state = get_resource_state(module);
3587db96d56Sopenharmony_ci#define ADD_INT(module, value)                                    \
3597db96d56Sopenharmony_ci    do {                                                          \
3607db96d56Sopenharmony_ci        if (PyModule_AddIntConstant(module, #value, value) < 0) { \
3617db96d56Sopenharmony_ci            return -1;                                            \
3627db96d56Sopenharmony_ci        }                                                         \
3637db96d56Sopenharmony_ci    } while (0)
3647db96d56Sopenharmony_ci
3657db96d56Sopenharmony_ci    /* Add some symbolic constants to the module */
3667db96d56Sopenharmony_ci    Py_INCREF(PyExc_OSError);
3677db96d56Sopenharmony_ci    if (PyModule_AddObject(module, "error", PyExc_OSError) < 0) {
3687db96d56Sopenharmony_ci        Py_DECREF(PyExc_OSError);
3697db96d56Sopenharmony_ci        return -1;
3707db96d56Sopenharmony_ci    }
3717db96d56Sopenharmony_ci
3727db96d56Sopenharmony_ci    state->StructRUsageType = PyStructSequence_NewType(&struct_rusage_desc);
3737db96d56Sopenharmony_ci    if (state->StructRUsageType == NULL) {
3747db96d56Sopenharmony_ci        return -1;
3757db96d56Sopenharmony_ci    }
3767db96d56Sopenharmony_ci    if (PyModule_AddType(module, state->StructRUsageType) < 0) {
3777db96d56Sopenharmony_ci        return -1;
3787db96d56Sopenharmony_ci    }
3797db96d56Sopenharmony_ci
3807db96d56Sopenharmony_ci    /* insert constants */
3817db96d56Sopenharmony_ci#ifdef RLIMIT_CPU
3827db96d56Sopenharmony_ci    ADD_INT(module, RLIMIT_CPU);
3837db96d56Sopenharmony_ci#endif
3847db96d56Sopenharmony_ci
3857db96d56Sopenharmony_ci#ifdef RLIMIT_FSIZE
3867db96d56Sopenharmony_ci    ADD_INT(module, RLIMIT_FSIZE);
3877db96d56Sopenharmony_ci#endif
3887db96d56Sopenharmony_ci
3897db96d56Sopenharmony_ci#ifdef RLIMIT_DATA
3907db96d56Sopenharmony_ci    ADD_INT(module, RLIMIT_DATA);
3917db96d56Sopenharmony_ci#endif
3927db96d56Sopenharmony_ci
3937db96d56Sopenharmony_ci#ifdef RLIMIT_STACK
3947db96d56Sopenharmony_ci    ADD_INT(module, RLIMIT_STACK);
3957db96d56Sopenharmony_ci#endif
3967db96d56Sopenharmony_ci
3977db96d56Sopenharmony_ci#ifdef RLIMIT_CORE
3987db96d56Sopenharmony_ci    ADD_INT(module, RLIMIT_CORE);
3997db96d56Sopenharmony_ci#endif
4007db96d56Sopenharmony_ci
4017db96d56Sopenharmony_ci#ifdef RLIMIT_NOFILE
4027db96d56Sopenharmony_ci    ADD_INT(module, RLIMIT_NOFILE);
4037db96d56Sopenharmony_ci#endif
4047db96d56Sopenharmony_ci
4057db96d56Sopenharmony_ci#ifdef RLIMIT_OFILE
4067db96d56Sopenharmony_ci    ADD_INT(module, RLIMIT_OFILE);
4077db96d56Sopenharmony_ci#endif
4087db96d56Sopenharmony_ci
4097db96d56Sopenharmony_ci#ifdef RLIMIT_VMEM
4107db96d56Sopenharmony_ci    ADD_INT(module, RLIMIT_VMEM);
4117db96d56Sopenharmony_ci#endif
4127db96d56Sopenharmony_ci
4137db96d56Sopenharmony_ci#ifdef RLIMIT_AS
4147db96d56Sopenharmony_ci    ADD_INT(module, RLIMIT_AS);
4157db96d56Sopenharmony_ci#endif
4167db96d56Sopenharmony_ci
4177db96d56Sopenharmony_ci#ifdef RLIMIT_RSS
4187db96d56Sopenharmony_ci    ADD_INT(module, RLIMIT_RSS);
4197db96d56Sopenharmony_ci#endif
4207db96d56Sopenharmony_ci
4217db96d56Sopenharmony_ci#ifdef RLIMIT_NPROC
4227db96d56Sopenharmony_ci    ADD_INT(module, RLIMIT_NPROC);
4237db96d56Sopenharmony_ci#endif
4247db96d56Sopenharmony_ci
4257db96d56Sopenharmony_ci#ifdef RLIMIT_MEMLOCK
4267db96d56Sopenharmony_ci    ADD_INT(module, RLIMIT_MEMLOCK);
4277db96d56Sopenharmony_ci#endif
4287db96d56Sopenharmony_ci
4297db96d56Sopenharmony_ci#ifdef RLIMIT_SBSIZE
4307db96d56Sopenharmony_ci    ADD_INT(module, RLIMIT_SBSIZE);
4317db96d56Sopenharmony_ci#endif
4327db96d56Sopenharmony_ci
4337db96d56Sopenharmony_ci/* Linux specific */
4347db96d56Sopenharmony_ci#ifdef RLIMIT_MSGQUEUE
4357db96d56Sopenharmony_ci    ADD_INT(module, RLIMIT_MSGQUEUE);
4367db96d56Sopenharmony_ci#endif
4377db96d56Sopenharmony_ci
4387db96d56Sopenharmony_ci#ifdef RLIMIT_NICE
4397db96d56Sopenharmony_ci    ADD_INT(module, RLIMIT_NICE);
4407db96d56Sopenharmony_ci#endif
4417db96d56Sopenharmony_ci
4427db96d56Sopenharmony_ci#ifdef RLIMIT_RTPRIO
4437db96d56Sopenharmony_ci    ADD_INT(module, RLIMIT_RTPRIO);
4447db96d56Sopenharmony_ci#endif
4457db96d56Sopenharmony_ci
4467db96d56Sopenharmony_ci#ifdef RLIMIT_RTTIME
4477db96d56Sopenharmony_ci    ADD_INT(module, RLIMIT_RTTIME);
4487db96d56Sopenharmony_ci#endif
4497db96d56Sopenharmony_ci
4507db96d56Sopenharmony_ci#ifdef RLIMIT_SIGPENDING
4517db96d56Sopenharmony_ci    ADD_INT(module, RLIMIT_SIGPENDING);
4527db96d56Sopenharmony_ci#endif
4537db96d56Sopenharmony_ci
4547db96d56Sopenharmony_ci/* target */
4557db96d56Sopenharmony_ci#ifdef RUSAGE_SELF
4567db96d56Sopenharmony_ci    ADD_INT(module, RUSAGE_SELF);
4577db96d56Sopenharmony_ci#endif
4587db96d56Sopenharmony_ci
4597db96d56Sopenharmony_ci#ifdef RUSAGE_CHILDREN
4607db96d56Sopenharmony_ci    ADD_INT(module, RUSAGE_CHILDREN);
4617db96d56Sopenharmony_ci#endif
4627db96d56Sopenharmony_ci
4637db96d56Sopenharmony_ci#ifdef RUSAGE_BOTH
4647db96d56Sopenharmony_ci    ADD_INT(module, RUSAGE_BOTH);
4657db96d56Sopenharmony_ci#endif
4667db96d56Sopenharmony_ci
4677db96d56Sopenharmony_ci#ifdef RUSAGE_THREAD
4687db96d56Sopenharmony_ci    ADD_INT(module, RUSAGE_THREAD);
4697db96d56Sopenharmony_ci#endif
4707db96d56Sopenharmony_ci
4717db96d56Sopenharmony_ci/* FreeBSD specific */
4727db96d56Sopenharmony_ci
4737db96d56Sopenharmony_ci#ifdef RLIMIT_SWAP
4747db96d56Sopenharmony_ci    ADD_INT(module, RLIMIT_SWAP);
4757db96d56Sopenharmony_ci#endif
4767db96d56Sopenharmony_ci
4777db96d56Sopenharmony_ci#ifdef RLIMIT_SBSIZE
4787db96d56Sopenharmony_ci    ADD_INT(module, RLIMIT_SBSIZE);
4797db96d56Sopenharmony_ci#endif
4807db96d56Sopenharmony_ci
4817db96d56Sopenharmony_ci#ifdef RLIMIT_NPTS
4827db96d56Sopenharmony_ci    ADD_INT(module, RLIMIT_NPTS);
4837db96d56Sopenharmony_ci#endif
4847db96d56Sopenharmony_ci
4857db96d56Sopenharmony_ci#ifdef RLIMIT_KQUEUES
4867db96d56Sopenharmony_ci    ADD_INT(module, RLIMIT_KQUEUES);
4877db96d56Sopenharmony_ci#endif
4887db96d56Sopenharmony_ci
4897db96d56Sopenharmony_ci    PyObject *v;
4907db96d56Sopenharmony_ci    if (sizeof(RLIM_INFINITY) > sizeof(long)) {
4917db96d56Sopenharmony_ci        v = PyLong_FromLongLong((long long) RLIM_INFINITY);
4927db96d56Sopenharmony_ci    } else
4937db96d56Sopenharmony_ci    {
4947db96d56Sopenharmony_ci        v = PyLong_FromLong((long) RLIM_INFINITY);
4957db96d56Sopenharmony_ci    }
4967db96d56Sopenharmony_ci    if (!v) {
4977db96d56Sopenharmony_ci        return -1;
4987db96d56Sopenharmony_ci    }
4997db96d56Sopenharmony_ci
5007db96d56Sopenharmony_ci    if (PyModule_AddObject(module, "RLIM_INFINITY", v) < 0) {
5017db96d56Sopenharmony_ci        Py_DECREF(v);
5027db96d56Sopenharmony_ci        return -1;
5037db96d56Sopenharmony_ci    }
5047db96d56Sopenharmony_ci    return 0;
5057db96d56Sopenharmony_ci
5067db96d56Sopenharmony_ci#undef ADD_INT
5077db96d56Sopenharmony_ci}
5087db96d56Sopenharmony_ci
5097db96d56Sopenharmony_cistatic struct PyModuleDef_Slot resource_slots[] = {
5107db96d56Sopenharmony_ci    {Py_mod_exec, resource_exec},
5117db96d56Sopenharmony_ci    {0, NULL}
5127db96d56Sopenharmony_ci};
5137db96d56Sopenharmony_ci
5147db96d56Sopenharmony_cistatic int
5157db96d56Sopenharmony_ciresourcemodule_traverse(PyObject *m, visitproc visit, void *arg) {
5167db96d56Sopenharmony_ci    Py_VISIT(get_resource_state(m)->StructRUsageType);
5177db96d56Sopenharmony_ci    return 0;
5187db96d56Sopenharmony_ci}
5197db96d56Sopenharmony_ci
5207db96d56Sopenharmony_cistatic int
5217db96d56Sopenharmony_ciresourcemodule_clear(PyObject *m) {
5227db96d56Sopenharmony_ci    Py_CLEAR(get_resource_state(m)->StructRUsageType);
5237db96d56Sopenharmony_ci    return 0;
5247db96d56Sopenharmony_ci}
5257db96d56Sopenharmony_ci
5267db96d56Sopenharmony_cistatic void
5277db96d56Sopenharmony_ciresourcemodule_free(void *m) {
5287db96d56Sopenharmony_ci    resourcemodule_clear((PyObject *)m);
5297db96d56Sopenharmony_ci}
5307db96d56Sopenharmony_ci
5317db96d56Sopenharmony_cistatic struct PyModuleDef resourcemodule = {
5327db96d56Sopenharmony_ci    PyModuleDef_HEAD_INIT,
5337db96d56Sopenharmony_ci    .m_name = "resource",
5347db96d56Sopenharmony_ci    .m_size = sizeof(resourcemodulestate),
5357db96d56Sopenharmony_ci    .m_methods = resource_methods,
5367db96d56Sopenharmony_ci    .m_slots = resource_slots,
5377db96d56Sopenharmony_ci    .m_traverse = resourcemodule_traverse,
5387db96d56Sopenharmony_ci    .m_clear = resourcemodule_clear,
5397db96d56Sopenharmony_ci    .m_free = resourcemodule_free,
5407db96d56Sopenharmony_ci};
5417db96d56Sopenharmony_ci
5427db96d56Sopenharmony_ciPyMODINIT_FUNC
5437db96d56Sopenharmony_ciPyInit_resource(void)
5447db96d56Sopenharmony_ci{
5457db96d56Sopenharmony_ci    return PyModuleDef_Init(&resourcemodule);
5467db96d56Sopenharmony_ci}
547