LCOV - code coverage report
Current view: | top level - Modules - resource.c (source / functions) |  |  | Hit | Total | Coverage
Test: | CPython 3.12 LCOV report [commit 5e6661bce9] |  | Lines: | 50 | 151 | 33.1 %
Date: | 2023-03-20 08:15:36 |  | Functions: | 8 | 13 | 61.5 %
|  |  | Branches: | 31 | 112 | 27.7 %

               Branch data     Line data    Source code
           1                 :            :
           2                 :            : #include "Python.h"
           3                 :            : #include <sys/resource.h>
           4                 :            : #include <sys/time.h>
           5                 :            : #include <string.h>
           6                 :            : #include <errno.h>
           7                 :            : #include <unistd.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                 :            : /*[clinic input]
          19                 :            : module resource
          20                 :            : [clinic start generated code]*/
          21                 :            : /*[clinic end generated code: output=da39a3ee5e6b4b0d input=e89d38ed52609d7c]*/
          22                 :            :
          23                 :            : /*[python input]
          24                 :            : class pid_t_converter(CConverter):
          25                 :            :     type = 'pid_t'
          26                 :            :     format_unit = '" _Py_PARSE_PID "'
          27                 :            :
          28                 :            :     def parse_arg(self, argname, displayname):
          29                 :            :         return """
          30                 :            :             {paramname} = PyLong_AsPid({argname});
          31                 :            :             if ({paramname} == -1 && PyErr_Occurred()) {{{{
          32                 :            :                 goto exit;
          33                 :            :             }}}}
          34                 :            :             """.format(argname=argname, paramname=self.parser_name)
          35                 :            : [python start generated code]*/
          36                 :            : /*[python end generated code: output=da39a3ee5e6b4b0d input=5af1c116d56cbb5a]*/
          37                 :            :
          38                 :            : #include "clinic/resource.c.h"
          39                 :            :
          40                 :            : PyDoc_STRVAR(struct_rusage__doc__,
          41                 :            : "struct_rusage: Result from getrusage.\n\n"
          42                 :            : "This object may be accessed either as a tuple of\n"
          43                 :            : "    (utime,stime,maxrss,ixrss,idrss,isrss,minflt,majflt,\n"
          44                 :            : "    nswap,inblock,oublock,msgsnd,msgrcv,nsignals,nvcsw,nivcsw)\n"
          45                 :            : "or via the attributes ru_utime, ru_stime, ru_maxrss, and so on.");
          46                 :            :
          47                 :            : static PyStructSequence_Field struct_rusage_fields[] = {
          48                 :            :     {"ru_utime",        "user time used"},
          49                 :            :     {"ru_stime",        "system time used"},
          50                 :            :     {"ru_maxrss",       "max. resident set size"},
          51                 :            :     {"ru_ixrss",        "shared memory size"},
          52                 :            :     {"ru_idrss",        "unshared data size"},
          53                 :            :     {"ru_isrss",        "unshared stack size"},
          54                 :            :     {"ru_minflt",       "page faults not requiring I/O"},
          55                 :            :     {"ru_majflt",       "page faults requiring I/O"},
          56                 :            :     {"ru_nswap",        "number of swap outs"},
          57                 :            :     {"ru_inblock",      "block input operations"},
          58                 :            :     {"ru_oublock",      "block output operations"},
          59                 :            :     {"ru_msgsnd",       "IPC messages sent"},
          60                 :            :     {"ru_msgrcv",       "IPC messages received"},
          61                 :            :     {"ru_nsignals",     "signals received"},
          62                 :            :     {"ru_nvcsw",        "voluntary context switches"},
          63                 :            :     {"ru_nivcsw",       "involuntary context switches"},
          64                 :            :     {0}
          65                 :            : };
          66                 :            :
          67                 :            : static PyStructSequence_Desc struct_rusage_desc = {
          68                 :            :     "resource.struct_rusage",           /* name */
          69                 :            :     struct_rusage__doc__,       /* doc */
          70                 :            :     struct_rusage_fields,       /* fields */
          71                 :            :     16          /* n_in_sequence */
          72                 :            : };
          73                 :            :
          74                 :            : typedef struct {
          75                 :            :   PyTypeObject *StructRUsageType;
          76                 :            : } resourcemodulestate;
          77                 :            :
          78                 :            :
          79                 :            : static inline resourcemodulestate*
          80                 :         74 : get_resource_state(PyObject *module)
          81                 :            : {
          82                 :         74 :     void *state = PyModule_GetState(module);
          83                 :            :     assert(state != NULL);
          84                 :         74 :     return (resourcemodulestate *)state;
          85                 :            : }
          86                 :            :
          87                 :            : static struct PyModuleDef resourcemodule;
          88                 :            :
          89                 :            : #ifdef HAVE_GETRUSAGE
          90                 :            : /*[clinic input]
          91                 :            : resource.getrusage
          92                 :            :
          93                 :            :     who: int
          94                 :            :     /
          95                 :            :
          96                 :            : [clinic start generated code]*/
          97                 :            :
          98                 :            : static PyObject *
          99                 :          0 : resource_getrusage_impl(PyObject *module, int who)
         100                 :            : /*[clinic end generated code: output=8fad2880ba6a9843 input=5c857bcc5b9ccb1b]*/
         101                 :            : {
         102                 :            :     struct rusage ru;
         103                 :            :     PyObject *result;
         104                 :            :
         105         [ #  # ]:          0 :     if (getrusage(who, &ru) == -1) {
         106         [ #  # ]:          0 :         if (errno == EINVAL) {
         107                 :          0 :             PyErr_SetString(PyExc_ValueError,
         108                 :            :                             "invalid who parameter");
         109                 :          0 :             return NULL;
         110                 :            :         }
         111                 :          0 :         PyErr_SetFromErrno(PyExc_OSError);
         112                 :          0 :         return NULL;
         113                 :            :     }
         114                 :            :
         115                 :          0 :     result = PyStructSequence_New(
         116                 :          0 :         get_resource_state(module)->StructRUsageType);
         117         [ #  # ]:          0 :     if (!result)
         118                 :          0 :         return NULL;
         119                 :            :
         120                 :          0 :     PyStructSequence_SET_ITEM(result, 0,
         121                 :            :                     PyFloat_FromDouble(doubletime(ru.ru_utime)));
         122                 :          0 :     PyStructSequence_SET_ITEM(result, 1,
         123                 :            :                     PyFloat_FromDouble(doubletime(ru.ru_stime)));
         124                 :          0 :     PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong(ru.ru_maxrss));
         125                 :          0 :     PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong(ru.ru_ixrss));
         126                 :          0 :     PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong(ru.ru_idrss));
         127                 :          0 :     PyStructSequence_SET_ITEM(result, 5, PyLong_FromLong(ru.ru_isrss));
         128                 :          0 :     PyStructSequence_SET_ITEM(result, 6, PyLong_FromLong(ru.ru_minflt));
         129                 :          0 :     PyStructSequence_SET_ITEM(result, 7, PyLong_FromLong(ru.ru_majflt));
         130                 :          0 :     PyStructSequence_SET_ITEM(result, 8, PyLong_FromLong(ru.ru_nswap));
         131                 :          0 :     PyStructSequence_SET_ITEM(result, 9, PyLong_FromLong(ru.ru_inblock));
         132                 :          0 :     PyStructSequence_SET_ITEM(result, 10, PyLong_FromLong(ru.ru_oublock));
         133                 :          0 :     PyStructSequence_SET_ITEM(result, 11, PyLong_FromLong(ru.ru_msgsnd));
         134                 :          0 :     PyStructSequence_SET_ITEM(result, 12, PyLong_FromLong(ru.ru_msgrcv));
         135                 :          0 :     PyStructSequence_SET_ITEM(result, 13, PyLong_FromLong(ru.ru_nsignals));
         136                 :          0 :     PyStructSequence_SET_ITEM(result, 14, PyLong_FromLong(ru.ru_nvcsw));
         137                 :          0 :     PyStructSequence_SET_ITEM(result, 15, PyLong_FromLong(ru.ru_nivcsw));
         138                 :            :
         139         [ #  # ]:          0 :     if (PyErr_Occurred()) {
         140                 :          0 :         Py_DECREF(result);
         141                 :          0 :         return NULL;
         142                 :            :     }
         143                 :            :
         144                 :          0 :     return result;
         145                 :            : }
         146                 :            : #endif
         147                 :            :
         148                 :            : static int
         149                 :          0 : py2rlimit(PyObject *limits, struct rlimit *rl_out)
         150                 :            : {
         151                 :            :     PyObject *curobj, *maxobj;
         152                 :          0 :     limits = PySequence_Tuple(limits);
         153         [ #  # ]:          0 :     if (!limits)
         154                 :            :         /* Here limits is a borrowed reference */
         155                 :          0 :         return -1;
         156                 :            :
         157         [ #  # ]:          0 :     if (PyTuple_GET_SIZE(limits) != 2) {
         158                 :          0 :         PyErr_SetString(PyExc_ValueError,
         159                 :            :                         "expected a tuple of 2 integers");
         160                 :          0 :         goto error;
         161                 :            :     }
         162                 :          0 :     curobj = PyTuple_GET_ITEM(limits, 0);
         163                 :          0 :     maxobj = PyTuple_GET_ITEM(limits, 1);
         164                 :            : #if !defined(HAVE_LARGEFILE_SUPPORT)
         165                 :          0 :     rl_out->rlim_cur = PyLong_AsLong(curobj);
         166   [ #  #  #  # ]:          0 :     if (rl_out->rlim_cur == (rlim_t)-1 && PyErr_Occurred())
         167                 :          0 :         goto error;
         168                 :          0 :     rl_out->rlim_max = PyLong_AsLong(maxobj);
         169   [ #  #  #  # ]:          0 :     if (rl_out->rlim_max == (rlim_t)-1 && PyErr_Occurred())
         170                 :          0 :         goto error;
         171                 :            : #else
         172                 :            :     /* The limits are probably bigger than a long */
         173                 :            :     rl_out->rlim_cur = PyLong_AsLongLong(curobj);
         174                 :            :     if (rl_out->rlim_cur == (rlim_t)-1 && PyErr_Occurred())
         175                 :            :         goto error;
         176                 :            :     rl_out->rlim_max = PyLong_AsLongLong(maxobj);
         177                 :            :     if (rl_out->rlim_max == (rlim_t)-1 && PyErr_Occurred())
         178                 :            :         goto error;
         179                 :            : #endif
         180                 :            :
         181                 :          0 :     Py_DECREF(limits);
         182                 :          0 :     rl_out->rlim_cur = rl_out->rlim_cur & RLIM_INFINITY;
         183                 :          0 :     rl_out->rlim_max = rl_out->rlim_max & RLIM_INFINITY;
         184                 :          0 :     return 0;
         185                 :            :
         186                 :          0 : error:
         187                 :          0 :     Py_DECREF(limits);
         188                 :          0 :     return -1;
         189                 :            : }
         190                 :            :
         191                 :            : static PyObject*
         192                 :          1 : rlimit2py(struct rlimit rl)
         193                 :            : {
         194                 :            :     if (sizeof(rl.rlim_cur) > sizeof(long)) {
         195                 :            :         return Py_BuildValue("LL",
         196                 :            :                              (long long) rl.rlim_cur,
         197                 :            :                              (long long) rl.rlim_max);
         198                 :            :     }
         199                 :          1 :     return Py_BuildValue("ll", (long) rl.rlim_cur, (long) rl.rlim_max);
         200                 :            : }
         201                 :            :
         202                 :            : /*[clinic input]
         203                 :            : resource.getrlimit
         204                 :            :
         205                 :            :     resource: int
         206                 :            :     /
         207                 :            :
         208                 :            : [clinic start generated code]*/
         209                 :            :
         210                 :            : static PyObject *
         211                 :          1 : resource_getrlimit_impl(PyObject *module, int resource)
         212                 :            : /*[clinic end generated code: output=98327b25061ffe39 input=a697cb0004cb3c36]*/
         213                 :            : {
         214                 :            :     struct rlimit rl;
         215                 :            :
         216   [ +  -  -  + ]:          1 :     if (resource < 0 || resource >= RLIM_NLIMITS) {
         217                 :          0 :         PyErr_SetString(PyExc_ValueError,
         218                 :            :                         "invalid resource specified");
         219                 :          0 :         return NULL;
         220                 :            :     }
         221                 :            :
         222         [ -  + ]:          1 :     if (getrlimit(resource, &rl) == -1) {
         223                 :          0 :         PyErr_SetFromErrno(PyExc_OSError);
         224                 :          0 :         return NULL;
         225                 :            :     }
         226                 :          1 :     return rlimit2py(rl);
         227                 :            : }
         228                 :            :
         229                 :            : /*[clinic input]
         230                 :            : resource.setrlimit
         231                 :            :
         232                 :            :     resource: int
         233                 :            :     limits: object
         234                 :            :     /
         235                 :            :
         236                 :            : [clinic start generated code]*/
         237                 :            :
         238                 :            : static PyObject *
         239                 :          0 : resource_setrlimit_impl(PyObject *module, int resource, PyObject *limits)
         240                 :            : /*[clinic end generated code: output=4e82ec3f34d013d1 input=6235a6ce23b4ca75]*/
         241                 :            : {
         242                 :            :     struct rlimit rl;
         243                 :            :
         244   [ #  #  #  # ]:          0 :     if (resource < 0 || resource >= RLIM_NLIMITS) {
         245                 :          0 :         PyErr_SetString(PyExc_ValueError,
         246                 :            :                         "invalid resource specified");
         247                 :          0 :         return NULL;
         248                 :            :     }
         249                 :            :
         250   [ #  #  #  # ]:          0 :     if (PySys_Audit("resource.setrlimit", "iO", resource,
         251                 :            :                     limits ? limits : Py_None) < 0) {
         252                 :          0 :         return NULL;
         253                 :            :     }
         254                 :            :
         255         [ #  # ]:          0 :     if (py2rlimit(limits, &rl) < 0) {
         256                 :          0 :         return NULL;
         257                 :            :     }
         258                 :            :
         259         [ #  # ]:          0 :     if (setrlimit(resource, &rl) == -1) {
         260         [ #  # ]:          0 :         if (errno == EINVAL)
         261                 :          0 :             PyErr_SetString(PyExc_ValueError,
         262                 :            :                             "current limit exceeds maximum limit");
         263         [ #  # ]:          0 :         else if (errno == EPERM)
         264                 :          0 :             PyErr_SetString(PyExc_ValueError,
         265                 :            :                             "not allowed to raise maximum limit");
         266                 :            :         else
         267                 :          0 :             PyErr_SetFromErrno(PyExc_OSError);
         268                 :          0 :         return NULL;
         269                 :            :     }
         270                 :          0 :     Py_RETURN_NONE;
         271                 :            : }
         272                 :            :
         273                 :            : #ifdef HAVE_PRLIMIT
         274                 :            : /*[clinic input]
         275                 :            : resource.prlimit
         276                 :            :
         277                 :            :     pid: pid_t
         278                 :            :     resource: int
         279                 :            :     limits: object = None
         280                 :            :     /
         281                 :            :
         282                 :            : [clinic start generated code]*/
         283                 :            :
         284                 :            : static PyObject *
         285                 :          0 : resource_prlimit_impl(PyObject *module, pid_t pid, int resource,
         286                 :            :                       PyObject *limits)
         287                 :            : /*[clinic end generated code: output=6ebc49ff8c3a816e input=54bb69c9585e33bf]*/
         288                 :            : {
         289                 :            :     struct rlimit old_limit, new_limit;
         290                 :            :     int retval;
         291                 :            :
         292   [ #  #  #  # ]:          0 :     if (resource < 0 || resource >= RLIM_NLIMITS) {
         293                 :          0 :         PyErr_SetString(PyExc_ValueError,
         294                 :            :                         "invalid resource specified");
         295                 :          0 :         return NULL;
         296                 :            :     }
         297                 :            :
         298   [ #  #  #  # ]:          0 :     if (PySys_Audit("resource.prlimit", "iiO", pid, resource,
         299                 :            :                     limits ? limits : Py_None) < 0) {
         300                 :          0 :         return NULL;
         301                 :            :     }
         302                 :            :
         303         [ #  # ]:          0 :     if (limits != Py_None) {
         304         [ #  # ]:          0 :         if (py2rlimit(limits, &new_limit) < 0) {
         305                 :          0 :             return NULL;
         306                 :            :         }
         307                 :          0 :         retval = prlimit(pid, resource, &new_limit, &old_limit);
         308                 :            :     }
         309                 :            :     else {
         310                 :          0 :         retval = prlimit(pid, resource, NULL, &old_limit);
         311                 :            :     }
         312                 :            :
         313         [ #  # ]:          0 :     if (retval == -1) {
         314         [ #  # ]:          0 :         if (errno == EINVAL) {
         315                 :          0 :             PyErr_SetString(PyExc_ValueError,
         316                 :            :                             "current limit exceeds maximum limit");
         317                 :            :         } else {
         318                 :          0 :             PyErr_SetFromErrno(PyExc_OSError);
         319                 :            :         }
         320                 :          0 :         return NULL;
         321                 :            :     }
         322                 :          0 :     return rlimit2py(old_limit);
         323                 :            : }
         324                 :            : #endif /* HAVE_PRLIMIT */
         325                 :            :
         326                 :            : /*[clinic input]
         327                 :            : resource.getpagesize -> int
         328                 :            : [clinic start generated code]*/
         329                 :            :
         330                 :            : static int
         331                 :          0 : resource_getpagesize_impl(PyObject *module)
         332                 :            : /*[clinic end generated code: output=9ba93eb0f3d6c3a9 input=546545e8c1f42085]*/
         333                 :            : {
         334                 :          0 :     long pagesize = 0;
         335                 :            : #if defined(HAVE_GETPAGESIZE)
         336                 :          0 :     pagesize = getpagesize();
         337                 :            : #elif defined(HAVE_SYSCONF) && defined(_SC_PAGE_SIZE)
         338                 :            :     pagesize = sysconf(_SC_PAGE_SIZE);
         339                 :            : #else
         340                 :            : #   error "unsupported platform: resource.getpagesize()"
         341                 :            : #endif
         342                 :          0 :     return pagesize;
         343                 :            : }
         344                 :            :
         345                 :            : /* List of functions */
         346                 :            :
         347                 :            : static struct PyMethodDef
         348                 :            : resource_methods[] = {
         349                 :            :     RESOURCE_GETRUSAGE_METHODDEF
         350                 :            :     RESOURCE_GETRLIMIT_METHODDEF
         351                 :            :     RESOURCE_PRLIMIT_METHODDEF
         352                 :            :     RESOURCE_SETRLIMIT_METHODDEF
         353                 :            :     RESOURCE_GETPAGESIZE_METHODDEF
         354                 :            :     {NULL, NULL}                             /* sentinel */
         355                 :            : };
         356                 :            :
         357                 :            :
         358                 :            : /* Module initialization */
         359                 :            :
         360                 :            : static int
         361                 :          2 : resource_exec(PyObject *module)
         362                 :            : {
         363                 :          2 :     resourcemodulestate *state = get_resource_state(module);
         364                 :            : #define ADD_INT(module, value)                                    \
         365                 :            :     do {                                                          \
         366                 :            :         if (PyModule_AddIntConstant(module, #value, value) < 0) { \
         367                 :            :             return -1;                                            \
         368                 :            :         }                                                         \
         369                 :            :     } while (0)
         370                 :            :
         371                 :            :     /* Add some symbolic constants to the module */
         372                 :          2 :     Py_INCREF(PyExc_OSError);
         373         [ -  + ]:          2 :     if (PyModule_AddObject(module, "error", PyExc_OSError) < 0) {
         374                 :          0 :         Py_DECREF(PyExc_OSError);
         375                 :          0 :         return -1;
         376                 :            :     }
         377                 :            :
         378                 :          2 :     state->StructRUsageType = PyStructSequence_NewType(&struct_rusage_desc);
         379         [ -  + ]:          2 :     if (state->StructRUsageType == NULL) {
         380                 :          0 :         return -1;
         381                 :            :     }
         382         [ -  + ]:          2 :     if (PyModule_AddType(module, state->StructRUsageType) < 0) {
         383                 :          0 :         return -1;
         384                 :            :     }
         385                 :            :
         386                 :            :     /* insert constants */
         387                 :            : #ifdef RLIMIT_CPU
         388         [ -  + ]:          2 :     ADD_INT(module, RLIMIT_CPU);
         389                 :            : #endif
         390                 :            :
         391                 :            : #ifdef RLIMIT_FSIZE
         392         [ -  + ]:          2 :     ADD_INT(module, RLIMIT_FSIZE);
         393                 :            : #endif
         394                 :            :
         395                 :            : #ifdef RLIMIT_DATA
         396         [ -  + ]:          2 :     ADD_INT(module, RLIMIT_DATA);
         397                 :            : #endif
         398                 :            :
         399                 :            : #ifdef RLIMIT_STACK
         400         [ -  + ]:          2 :     ADD_INT(module, RLIMIT_STACK);
         401                 :            : #endif
         402                 :            :
         403                 :            : #ifdef RLIMIT_CORE
         404         [ -  + ]:          2 :     ADD_INT(module, RLIMIT_CORE);
         405                 :            : #endif
         406                 :            :
         407                 :            : #ifdef RLIMIT_NOFILE
         408         [ -  + ]:          2 :     ADD_INT(module, RLIMIT_NOFILE);
         409                 :            : #endif
         410                 :            :
         411                 :            : #ifdef RLIMIT_OFILE
         412         [ -  + ]:          2 :     ADD_INT(module, RLIMIT_OFILE);
         413                 :            : #endif
         414                 :            :
         415                 :            : #ifdef RLIMIT_VMEM
         416                 :            :     ADD_INT(module, RLIMIT_VMEM);
         417                 :            : #endif
         418                 :            :
         419                 :            : #ifdef RLIMIT_AS
         420         [ -  + ]:          2 :     ADD_INT(module, RLIMIT_AS);
         421                 :            : #endif
         422                 :            :
         423                 :            : #ifdef RLIMIT_RSS
         424         [ -  + ]:          2 :     ADD_INT(module, RLIMIT_RSS);
         425                 :            : #endif
         426                 :            :
         427                 :            : #ifdef RLIMIT_NPROC
         428         [ -  + ]:          2 :     ADD_INT(module, RLIMIT_NPROC);
         429                 :            : #endif
         430                 :            :
         431                 :            : #ifdef RLIMIT_MEMLOCK
         432         [ -  + ]:          2 :     ADD_INT(module, RLIMIT_MEMLOCK);
         433                 :            : #endif
         434                 :            :
         435                 :            : #ifdef RLIMIT_SBSIZE
         436                 :            :     ADD_INT(module, RLIMIT_SBSIZE);
         437                 :            : #endif
         438                 :            :
         439                 :            : /* Linux specific */
         440                 :            : #ifdef RLIMIT_MSGQUEUE
         441         [ -  + ]:          2 :     ADD_INT(module, RLIMIT_MSGQUEUE);
         442                 :            : #endif
         443                 :            :
         444                 :            : #ifdef RLIMIT_NICE
         445         [ -  + ]:          2 :     ADD_INT(module, RLIMIT_NICE);
         446                 :            : #endif
         447                 :            :
         448                 :            : #ifdef RLIMIT_RTPRIO
         449         [ -  + ]:          2 :     ADD_INT(module, RLIMIT_RTPRIO);
         450                 :            : #endif
         451                 :            :
         452                 :            : #ifdef RLIMIT_RTTIME
         453         [ -  + ]:          2 :     ADD_INT(module, RLIMIT_RTTIME);
         454                 :            : #endif
         455                 :            :
         456                 :            : #ifdef RLIMIT_SIGPENDING
         457         [ -  + ]:          2 :     ADD_INT(module, RLIMIT_SIGPENDING);
         458                 :            : #endif
         459                 :            :
         460                 :            : /* target */
         461                 :            : #ifdef RUSAGE_SELF
         462         [ -  + ]:          2 :     ADD_INT(module, RUSAGE_SELF);
         463                 :            : #endif
         464                 :            :
         465                 :            : #ifdef RUSAGE_CHILDREN
         466         [ -  + ]:          2 :     ADD_INT(module, RUSAGE_CHILDREN);
         467                 :            : #endif
         468                 :            :
         469                 :            : #ifdef RUSAGE_BOTH
         470                 :            :     ADD_INT(module, RUSAGE_BOTH);
         471                 :            : #endif
         472                 :            :
         473                 :            : #ifdef RUSAGE_THREAD
         474         [ -  + ]:          2 :     ADD_INT(module, RUSAGE_THREAD);
         475                 :            : #endif
         476                 :            :
         477                 :            : /* FreeBSD specific */
         478                 :            :
         479                 :            : #ifdef RLIMIT_SWAP
         480                 :            :     ADD_INT(module, RLIMIT_SWAP);
         481                 :            : #endif
         482                 :            :
         483                 :            : #ifdef RLIMIT_SBSIZE
         484                 :            :     ADD_INT(module, RLIMIT_SBSIZE);
         485                 :            : #endif
         486                 :            :
         487                 :            : #ifdef RLIMIT_NPTS
         488                 :            :     ADD_INT(module, RLIMIT_NPTS);
         489                 :            : #endif
         490                 :            :
         491                 :            : #ifdef RLIMIT_KQUEUES
         492                 :            :     ADD_INT(module, RLIMIT_KQUEUES);
         493                 :            : #endif
         494                 :            :
         495                 :            :     PyObject *v;
         496                 :            :     if (sizeof(RLIM_INFINITY) > sizeof(long)) {
         497                 :            :         v = PyLong_FromLongLong((long long) RLIM_INFINITY);
         498                 :            :     } else
         499                 :            :     {
         500                 :          2 :         v = PyLong_FromLong((long) RLIM_INFINITY);
         501                 :            :     }
         502         [ -  + ]:          2 :     if (!v) {
         503                 :          0 :         return -1;
         504                 :            :     }
         505                 :            :
         506         [ -  + ]:          2 :     if (PyModule_AddObject(module, "RLIM_INFINITY", v) < 0) {
         507                 :          0 :         Py_DECREF(v);
         508                 :          0 :         return -1;
         509                 :            :     }
         510                 :          2 :     return 0;
         511                 :            :
         512                 :            : #undef ADD_INT
         513                 :            : }
         514                 :            :
         515                 :            : static struct PyModuleDef_Slot resource_slots[] = {
         516                 :            :     {Py_mod_exec, resource_exec},
         517                 :            :     {0, NULL}
         518                 :            : };
         519                 :            :
         520                 :            : static int
         521                 :         34 : resourcemodule_traverse(PyObject *m, visitproc visit, void *arg) {
         522   [ +  -  -  + ]:         34 :     Py_VISIT(get_resource_state(m)->StructRUsageType);
         523                 :         34 :     return 0;
         524                 :            : }
         525                 :            :
         526                 :            : static int
         527                 :          4 : resourcemodule_clear(PyObject *m) {
         528         [ +  + ]:          4 :     Py_CLEAR(get_resource_state(m)->StructRUsageType);
         529                 :          4 :     return 0;
         530                 :            : }
         531                 :            :
         532                 :            : static void
         533                 :          2 : resourcemodule_free(void *m) {
         534                 :          2 :     resourcemodule_clear((PyObject *)m);
         535                 :          2 : }
         536                 :            :
         537                 :            : static struct PyModuleDef resourcemodule = {
         538                 :            :     PyModuleDef_HEAD_INIT,
         539                 :            :     .m_name = "resource",
         540                 :            :     .m_size = sizeof(resourcemodulestate),
         541                 :            :     .m_methods = resource_methods,
         542                 :            :     .m_slots = resource_slots,
         543                 :            :     .m_traverse = resourcemodule_traverse,
         544                 :            :     .m_clear = resourcemodule_clear,
         545                 :            :     .m_free = resourcemodule_free,
         546                 :            : };
         547                 :            :
         548                 :            : PyMODINIT_FUNC
         549                 :          2 : PyInit_resource(void)
         550                 :            : {
         551                 :          2 :     return PyModuleDef_Init(&resourcemodule);
         552                 :            : }

Generated by: LCOV version 1.14