LCOV - code coverage report
Current view: | top level - Modules - fcntlmodule.c (source / functions) |  |  | Hit | Total | Coverage
Test: | CPython 3.12 LCOV report [commit 5e6661bce9] |  | Lines: | 61 | 195 | 31.3 %
Date: | 2023-03-20 08:15:36 |  | Functions: | 3 | 7 | 42.9 %
|  |  | Branches: | 55 | 220 | 25.0 %

               Branch data     Line data    Source code
           1                 :            :
           2                 :            : /* fcntl module */
           3                 :            :
           4                 :            : #define PY_SSIZE_T_CLEAN
           5                 :            :
           6                 :            : #include "Python.h"
           7                 :            :
           8                 :            : #ifdef HAVE_SYS_FILE_H
           9                 :            : #include <sys/file.h>
          10                 :            : #endif
          11                 :            : #ifdef HAVE_LINUX_FS_H
          12                 :            : #include <linux/fs.h>
          13                 :            : #endif
          14                 :            :
          15                 :            : #include <sys/ioctl.h>
          16                 :            : #include <fcntl.h>
          17                 :            : #ifdef HAVE_STROPTS_H
          18                 :            : #include <stropts.h>
          19                 :            : #endif
          20                 :            :
          21                 :            : /*[clinic input]
          22                 :            : module fcntl
          23                 :            : [clinic start generated code]*/
          24                 :            : /*[clinic end generated code: output=da39a3ee5e6b4b0d input=124b58387c158179]*/
          25                 :            :
          26                 :            : #include "clinic/fcntlmodule.c.h"
          27                 :            :
          28                 :            : /*[clinic input]
          29                 :            : fcntl.fcntl
          30                 :            :
          31                 :            :     fd: fildes
          32                 :            :     cmd as code: int
          33                 :            :     arg: object(c_default='NULL') = 0
          34                 :            :     /
          35                 :            :
          36                 :            : Perform the operation `cmd` on file descriptor fd.
          37                 :            :
          38                 :            : The values used for `cmd` are operating system dependent, and are available
          39                 :            : as constants in the fcntl module, using the same names as used in
          40                 :            : the relevant C header files.  The argument arg is optional, and
          41                 :            : defaults to 0; it may be an int or a string.  If arg is given as a string,
          42                 :            : the return value of fcntl is a string of that length, containing the
          43                 :            : resulting value put in the arg buffer by the operating system.  The length
          44                 :            : of the arg string is not allowed to exceed 1024 bytes.  If the arg given
          45                 :            : is an integer or if none is specified, the result value is an integer
          46                 :            : corresponding to the return value of the fcntl call in the C code.
          47                 :            : [clinic start generated code]*/
          48                 :            :
          49                 :            : static PyObject *
          50                 :          0 : fcntl_fcntl_impl(PyObject *module, int fd, int code, PyObject *arg)
          51                 :            : /*[clinic end generated code: output=888fc93b51c295bd input=7955340198e5f334]*/
          52                 :            : {
          53                 :          0 :     unsigned int int_arg = 0;
          54                 :            :     int ret;
          55                 :            :     char *str;
          56                 :            :     Py_ssize_t len;
          57                 :            :     char buf[1024];
          58                 :          0 :     int async_err = 0;
          59                 :            :
          60   [ #  #  #  # ]:          0 :     if (PySys_Audit("fcntl.fcntl", "iiO", fd, code, arg ? arg : Py_None) < 0) {
          61                 :          0 :         return NULL;
          62                 :            :     }
          63                 :            :
          64         [ #  # ]:          0 :     if (arg != NULL) {
          65                 :            :         int parse_result;
          66                 :            :
          67         [ #  # ]:          0 :         if (PyArg_Parse(arg, "s#", &str, &len)) {
          68         [ #  # ]:          0 :             if ((size_t)len > sizeof buf) {
          69                 :          0 :                 PyErr_SetString(PyExc_ValueError,
          70                 :            :                                 "fcntl string arg too long");
          71                 :          0 :                 return NULL;
          72                 :            :             }
          73                 :          0 :             memcpy(buf, str, len);
          74                 :            :             do {
          75                 :          0 :                 Py_BEGIN_ALLOW_THREADS
          76                 :          0 :                 ret = fcntl(fd, code, buf);
          77                 :          0 :                 Py_END_ALLOW_THREADS
          78   [ #  #  #  #  :          0 :             } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
                       #  # ]
          79         [ #  # ]:          0 :             if (ret < 0) {
          80         [ #  # ]:          0 :                 return !async_err ? PyErr_SetFromErrno(PyExc_OSError) : NULL;
          81                 :            :             }
          82                 :          0 :             return PyBytes_FromStringAndSize(buf, len);
          83                 :            :         }
          84                 :            :
          85                 :          0 :         PyErr_Clear();
          86                 :          0 :         parse_result = PyArg_Parse(arg,
          87                 :            :             "I;fcntl requires a file or file descriptor,"
          88                 :            :             " an integer and optionally a third integer or a string",
          89                 :            :             &int_arg);
          90         [ #  # ]:          0 :         if (!parse_result) {
          91                 :          0 :           return NULL;
          92                 :            :         }
          93                 :            :     }
          94                 :            :
          95                 :            :     do {
          96                 :          0 :         Py_BEGIN_ALLOW_THREADS
          97                 :          0 :         ret = fcntl(fd, code, (int)int_arg);
          98                 :          0 :         Py_END_ALLOW_THREADS
          99   [ #  #  #  #  :          0 :     } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
                       #  # ]
         100         [ #  # ]:          0 :     if (ret < 0) {
         101         [ #  # ]:          0 :         return !async_err ? PyErr_SetFromErrno(PyExc_OSError) : NULL;
         102                 :            :     }
         103                 :          0 :     return PyLong_FromLong((long)ret);
         104                 :            : }
         105                 :            :
         106                 :            :
         107                 :            : /*[clinic input]
         108                 :            : fcntl.ioctl
         109                 :            :
         110                 :            :     fd: fildes
         111                 :            :     request as code: unsigned_int(bitwise=True)
         112                 :            :     arg as ob_arg: object(c_default='NULL') = 0
         113                 :            :     mutate_flag as mutate_arg: bool = True
         114                 :            :     /
         115                 :            :
         116                 :            : Perform the operation `request` on file descriptor `fd`.
         117                 :            :
         118                 :            : The values used for `request` are operating system dependent, and are available
         119                 :            : as constants in the fcntl or termios library modules, using the same names as
         120                 :            : used in the relevant C header files.
         121                 :            :
         122                 :            : The argument `arg` is optional, and defaults to 0; it may be an int or a
         123                 :            : buffer containing character data (most likely a string or an array).
         124                 :            :
         125                 :            : If the argument is a mutable buffer (such as an array) and if the
         126                 :            : mutate_flag argument (which is only allowed in this case) is true then the
         127                 :            : buffer is (in effect) passed to the operating system and changes made by
         128                 :            : the OS will be reflected in the contents of the buffer after the call has
         129                 :            : returned.  The return value is the integer returned by the ioctl system
         130                 :            : call.
         131                 :            :
         132                 :            : If the argument is a mutable buffer and the mutable_flag argument is false,
         133                 :            : the behavior is as if a string had been passed.
         134                 :            :
         135                 :            : If the argument is an immutable buffer (most likely a string) then a copy
         136                 :            : of the buffer is passed to the operating system and the return value is a
         137                 :            : string of the same length containing whatever the operating system put in
         138                 :            : the buffer.  The length of the arg buffer in this case is not allowed to
         139                 :            : exceed 1024 bytes.
         140                 :            :
         141                 :            : If the arg given is an integer or if none is specified, the result value is
         142                 :            : an integer corresponding to the return value of the ioctl call in the C
         143                 :            : code.
         144                 :            : [clinic start generated code]*/
         145                 :            :
         146                 :            : static PyObject *
         147                 :          0 : fcntl_ioctl_impl(PyObject *module, int fd, unsigned int code,
         148                 :            :                  PyObject *ob_arg, int mutate_arg)
         149                 :            : /*[clinic end generated code: output=7f7f5840c65991be input=967b4a4cbeceb0a8]*/
         150                 :            : {
         151                 :            : #define IOCTL_BUFSZ 1024
         152                 :            :     /* We use the unsigned non-checked 'I' format for the 'code' parameter
         153                 :            :        because the system expects it to be a 32bit bit field value
         154                 :            :        regardless of it being passed as an int or unsigned long on
         155                 :            :        various platforms.  See the termios.TIOCSWINSZ constant across
         156                 :            :        platforms for an example of this.
         157                 :            :
         158                 :            :        If any of the 64bit platforms ever decide to use more than 32bits
         159                 :            :        in their unsigned long ioctl codes this will break and need
         160                 :            :        special casing based on the platform being built on.
         161                 :            :      */
         162                 :          0 :     int arg = 0;
         163                 :            :     int ret;
         164                 :            :     Py_buffer pstr;
         165                 :            :     char *str;
         166                 :            :     Py_ssize_t len;
         167                 :            :     char buf[IOCTL_BUFSZ+1];  /* argument plus NUL byte */
         168                 :            :
         169   [ #  #  #  # ]:          0 :     if (PySys_Audit("fcntl.ioctl", "iIO", fd, code,
         170                 :            :                     ob_arg ? ob_arg : Py_None) < 0) {
         171                 :          0 :         return NULL;
         172                 :            :     }
         173                 :            :
         174         [ #  # ]:          0 :     if (ob_arg != NULL) {
         175         [ #  # ]:          0 :         if (PyArg_Parse(ob_arg, "w*:ioctl", &pstr)) {
         176                 :            :             char *arg;
         177                 :          0 :             str = pstr.buf;
         178                 :          0 :             len = pstr.len;
         179                 :            :
         180         [ #  # ]:          0 :             if (mutate_arg) {
         181         [ #  # ]:          0 :                 if (len <= IOCTL_BUFSZ) {
         182                 :          0 :                     memcpy(buf, str, len);
         183                 :          0 :                     buf[len] = '\0';
         184                 :          0 :                     arg = buf;
         185                 :            :                 }
         186                 :            :                 else {
         187                 :          0 :                     arg = str;
         188                 :            :                 }
         189                 :            :             }
         190                 :            :             else {
         191         [ #  # ]:          0 :                 if (len > IOCTL_BUFSZ) {
         192                 :          0 :                     PyBuffer_Release(&pstr);
         193                 :          0 :                     PyErr_SetString(PyExc_ValueError,
         194                 :            :                         "ioctl string arg too long");
         195                 :          0 :                     return NULL;
         196                 :            :                 }
         197                 :            :                 else {
         198                 :          0 :                     memcpy(buf, str, len);
         199                 :          0 :                     buf[len] = '\0';
         200                 :          0 :                     arg = buf;
         201                 :            :                 }
         202                 :            :             }
         203         [ #  # ]:          0 :             if (buf == arg) {
         204                 :          0 :                 Py_BEGIN_ALLOW_THREADS /* think array.resize() */
         205                 :          0 :                 ret = ioctl(fd, code, arg);
         206                 :          0 :                 Py_END_ALLOW_THREADS
         207                 :            :             }
         208                 :            :             else {
         209                 :          0 :                 ret = ioctl(fd, code, arg);
         210                 :            :             }
         211   [ #  #  #  # ]:          0 :             if (mutate_arg && (len <= IOCTL_BUFSZ)) {
         212                 :          0 :                 memcpy(str, buf, len);
         213                 :            :             }
         214                 :          0 :             PyBuffer_Release(&pstr); /* No further access to str below this point */
         215         [ #  # ]:          0 :             if (ret < 0) {
         216                 :          0 :                 PyErr_SetFromErrno(PyExc_OSError);
         217                 :          0 :                 return NULL;
         218                 :            :             }
         219         [ #  # ]:          0 :             if (mutate_arg) {
         220                 :          0 :                 return PyLong_FromLong(ret);
         221                 :            :             }
         222                 :            :             else {
         223                 :          0 :                 return PyBytes_FromStringAndSize(buf, len);
         224                 :            :             }
         225                 :            :         }
         226                 :            :
         227                 :          0 :         PyErr_Clear();
         228         [ #  # ]:          0 :         if (PyArg_Parse(ob_arg, "s*:ioctl", &pstr)) {
         229                 :          0 :             str = pstr.buf;
         230                 :          0 :             len = pstr.len;
         231         [ #  # ]:          0 :             if (len > IOCTL_BUFSZ) {
         232                 :          0 :                 PyBuffer_Release(&pstr);
         233                 :          0 :                 PyErr_SetString(PyExc_ValueError,
         234                 :            :                                 "ioctl string arg too long");
         235                 :          0 :                 return NULL;
         236                 :            :             }
         237                 :          0 :             memcpy(buf, str, len);
         238                 :          0 :             buf[len] = '\0';
         239                 :          0 :             Py_BEGIN_ALLOW_THREADS
         240                 :          0 :             ret = ioctl(fd, code, buf);
         241                 :          0 :             Py_END_ALLOW_THREADS
         242         [ #  # ]:          0 :             if (ret < 0) {
         243                 :          0 :                 PyBuffer_Release(&pstr);
         244                 :          0 :                 PyErr_SetFromErrno(PyExc_OSError);
         245                 :          0 :                 return NULL;
         246                 :            :             }
         247                 :          0 :             PyBuffer_Release(&pstr);
         248                 :          0 :             return PyBytes_FromStringAndSize(buf, len);
         249                 :            :         }
         250                 :            :
         251                 :          0 :         PyErr_Clear();
         252         [ #  # ]:          0 :         if (!PyArg_Parse(ob_arg,
         253                 :            :              "i;ioctl requires a file or file descriptor,"
         254                 :            :              " an integer and optionally an integer or buffer argument",
         255                 :            :              &arg)) {
         256                 :          0 :           return NULL;
         257                 :            :         }
         258                 :            :         // Fall-through to outside the 'if' statement.
         259                 :            :     }
         260                 :          0 :     Py_BEGIN_ALLOW_THREADS
         261                 :          0 :     ret = ioctl(fd, code, arg);
         262                 :          0 :     Py_END_ALLOW_THREADS
         263         [ #  # ]:          0 :     if (ret < 0) {
         264                 :          0 :         PyErr_SetFromErrno(PyExc_OSError);
         265                 :          0 :         return NULL;
         266                 :            :     }
         267                 :          0 :     return PyLong_FromLong((long)ret);
         268                 :            : #undef IOCTL_BUFSZ
         269                 :            : }
         270                 :            :
         271                 :            : /*[clinic input]
         272                 :            : fcntl.flock
         273                 :            :
         274                 :            :     fd: fildes
         275                 :            :     operation as code: int
         276                 :            :     /
         277                 :            :
         278                 :            : Perform the lock operation `operation` on file descriptor `fd`.
         279                 :            :
         280                 :            : See the Unix manual page for flock(2) for details (On some systems, this
         281                 :            : function is emulated using fcntl()).
         282                 :            : [clinic start generated code]*/
         283                 :            :
         284                 :            : static PyObject *
         285                 :          0 : fcntl_flock_impl(PyObject *module, int fd, int code)
         286                 :            : /*[clinic end generated code: output=84059e2b37d2fc64 input=0bfc00f795953452]*/
         287                 :            : {
         288                 :            :     int ret;
         289                 :          0 :     int async_err = 0;
         290                 :            :
         291         [ #  # ]:          0 :     if (PySys_Audit("fcntl.flock", "ii", fd, code) < 0) {
         292                 :          0 :         return NULL;
         293                 :            :     }
         294                 :            :
         295                 :            : #ifdef HAVE_FLOCK
         296                 :            :     do {
         297                 :          0 :         Py_BEGIN_ALLOW_THREADS
         298                 :          0 :         ret = flock(fd, code);
         299                 :          0 :         Py_END_ALLOW_THREADS
         300   [ #  #  #  #  :          0 :     } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
                       #  # ]
         301                 :            : #else
         302                 :            :
         303                 :            : #ifndef LOCK_SH
         304                 :            : #define LOCK_SH         1       /* shared lock */
         305                 :            : #define LOCK_EX         2       /* exclusive lock */
         306                 :            : #define LOCK_NB         4       /* don't block when locking */
         307                 :            : #define LOCK_UN         8       /* unlock */
         308                 :            : #endif
         309                 :            :     {
         310                 :            :         struct flock l;
         311                 :            :         if (code == LOCK_UN)
         312                 :            :             l.l_type = F_UNLCK;
         313                 :            :         else if (code & LOCK_SH)
         314                 :            :             l.l_type = F_RDLCK;
         315                 :            :         else if (code & LOCK_EX)
         316                 :            :             l.l_type = F_WRLCK;
         317                 :            :         else {
         318                 :            :             PyErr_SetString(PyExc_ValueError,
         319                 :            :                             "unrecognized flock argument");
         320                 :            :             return NULL;
         321                 :            :         }
         322                 :            :         l.l_whence = l.l_start = l.l_len = 0;
         323                 :            :         do {
         324                 :            :             Py_BEGIN_ALLOW_THREADS
         325                 :            :             ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
         326                 :            :             Py_END_ALLOW_THREADS
         327                 :            :         } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
         328                 :            :     }
         329                 :            : #endif /* HAVE_FLOCK */
         330         [ #  # ]:          0 :     if (ret < 0) {
         331         [ #  # ]:          0 :         return !async_err ? PyErr_SetFromErrno(PyExc_OSError) : NULL;
         332                 :            :     }
         333                 :          0 :     Py_RETURN_NONE;
         334                 :            : }
         335                 :            :
         336                 :            :
         337                 :            : /*[clinic input]
         338                 :            : fcntl.lockf
         339                 :            :
         340                 :            :     fd: fildes
         341                 :            :     cmd as code: int
         342                 :            :     len as lenobj: object(c_default='NULL') = 0
         343                 :            :     start as startobj: object(c_default='NULL') = 0
         344                 :            :     whence: int = 0
         345                 :            :     /
         346                 :            :
         347                 :            : A wrapper around the fcntl() locking calls.
         348                 :            :
         349                 :            : `fd` is the file descriptor of the file to lock or unlock, and operation is one
         350                 :            : of the following values:
         351                 :            :
         352                 :            :     LOCK_UN - unlock
         353                 :            :     LOCK_SH - acquire a shared lock
         354                 :            :     LOCK_EX - acquire an exclusive lock
         355                 :            :
         356                 :            : When operation is LOCK_SH or LOCK_EX, it can also be bitwise ORed with
         357                 :            : LOCK_NB to avoid blocking on lock acquisition.  If LOCK_NB is used and the
         358                 :            : lock cannot be acquired, an OSError will be raised and the exception will
         359                 :            : have an errno attribute set to EACCES or EAGAIN (depending on the operating
         360                 :            : system -- for portability, check for either value).
         361                 :            :
         362                 :            : `len` is the number of bytes to lock, with the default meaning to lock to
         363                 :            : EOF.  `start` is the byte offset, relative to `whence`, to that the lock
         364                 :            : starts.  `whence` is as with fileobj.seek(), specifically:
         365                 :            :
         366                 :            :     0 - relative to the start of the file (SEEK_SET)
         367                 :            :     1 - relative to the current buffer position (SEEK_CUR)
         368                 :            :     2 - relative to the end of the file (SEEK_END)
         369                 :            : [clinic start generated code]*/
         370                 :            :
         371                 :            : static PyObject *
         372                 :          0 : fcntl_lockf_impl(PyObject *module, int fd, int code, PyObject *lenobj,
         373                 :            :                  PyObject *startobj, int whence)
         374                 :            : /*[clinic end generated code: output=4985e7a172e7461a input=5480479fc63a04b8]*/
         375                 :            : {
         376                 :            :     int ret;
         377                 :          0 :     int async_err = 0;
         378                 :            :
         379   [ #  #  #  #  :          0 :     if (PySys_Audit("fcntl.lockf", "iiOOi", fd, code, lenobj ? lenobj : Py_None,
                       #  # ]
         380                 :            :                     startobj ? startobj : Py_None, whence) < 0) {
         381                 :          0 :         return NULL;
         382                 :            :     }
         383                 :            :
         384                 :            : #ifndef LOCK_SH
         385                 :            : #define LOCK_SH         1       /* shared lock */
         386                 :            : #define LOCK_EX         2       /* exclusive lock */
         387                 :            : #define LOCK_NB         4       /* don't block when locking */
         388                 :            : #define LOCK_UN         8       /* unlock */
         389                 :            : #endif  /* LOCK_SH */
         390                 :            :     {
         391                 :            :         struct flock l;
         392         [ #  # ]:          0 :         if (code == LOCK_UN)
         393                 :          0 :             l.l_type = F_UNLCK;
         394         [ #  # ]:          0 :         else if (code & LOCK_SH)
         395                 :          0 :             l.l_type = F_RDLCK;
         396         [ #  # ]:          0 :         else if (code & LOCK_EX)
         397                 :          0 :             l.l_type = F_WRLCK;
         398                 :            :         else {
         399                 :          0 :             PyErr_SetString(PyExc_ValueError,
         400                 :            :                             "unrecognized lockf argument");
         401                 :          0 :             return NULL;
         402                 :            :         }
         403                 :          0 :         l.l_start = l.l_len = 0;
         404         [ #  # ]:          0 :         if (startobj != NULL) {
         405                 :            : #if !defined(HAVE_LARGEFILE_SUPPORT)
         406                 :          0 :             l.l_start = PyLong_AsLong(startobj);
         407                 :            : #else
         408                 :            :             l.l_start = PyLong_Check(startobj) ?
         409                 :            :                             PyLong_AsLongLong(startobj) :
         410                 :            :                     PyLong_AsLong(startobj);
         411                 :            : #endif
         412         [ #  # ]:          0 :             if (PyErr_Occurred())
         413                 :          0 :                 return NULL;
         414                 :            :         }
         415         [ #  # ]:          0 :         if (lenobj != NULL) {
         416                 :            : #if !defined(HAVE_LARGEFILE_SUPPORT)
         417                 :          0 :             l.l_len = PyLong_AsLong(lenobj);
         418                 :            : #else
         419                 :            :             l.l_len = PyLong_Check(lenobj) ?
         420                 :            :                             PyLong_AsLongLong(lenobj) :
         421                 :            :                     PyLong_AsLong(lenobj);
         422                 :            : #endif
         423         [ #  # ]:          0 :             if (PyErr_Occurred())
         424                 :          0 :                 return NULL;
         425                 :            :         }
         426                 :          0 :         l.l_whence = whence;
         427                 :            :         do {
         428                 :          0 :             Py_BEGIN_ALLOW_THREADS
         429         [ #  # ]:          0 :             ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
         430                 :          0 :             Py_END_ALLOW_THREADS
         431   [ #  #  #  #  :          0 :         } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
                       #  # ]
         432                 :            :     }
         433         [ #  # ]:          0 :     if (ret < 0) {
         434         [ #  # ]:          0 :         return !async_err ? PyErr_SetFromErrno(PyExc_OSError) : NULL;
         435                 :            :     }
         436                 :          0 :     Py_RETURN_NONE;
         437                 :            : }
         438                 :            :
         439                 :            : /* List of functions */
         440                 :            :
         441                 :            : static PyMethodDef fcntl_methods[] = {
         442                 :            :     FCNTL_FCNTL_METHODDEF
         443                 :            :     FCNTL_IOCTL_METHODDEF
         444                 :            :     FCNTL_FLOCK_METHODDEF
         445                 :            :     FCNTL_LOCKF_METHODDEF
         446                 :            :     {NULL, NULL}  /* sentinel */
         447                 :            : };
         448                 :            :
         449                 :            :
         450                 :            : PyDoc_STRVAR(module_doc,
         451                 :            : "This module performs file control and I/O control on file\n\
         452                 :            : descriptors.  It is an interface to the fcntl() and ioctl() Unix\n\
         453                 :            : routines.  File descriptors can be obtained with the fileno() method of\n\
         454                 :            : a file or socket object.");
         455                 :            :
         456                 :            : /* Module initialisation */
         457                 :            :
         458                 :            :
         459                 :            : static int
         460                 :          2 : all_ins(PyObject* m)
         461                 :            : {
         462         [ -  + ]:          2 :     if (PyModule_AddIntMacro(m, LOCK_SH)) return -1;
         463         [ -  + ]:          2 :     if (PyModule_AddIntMacro(m, LOCK_EX)) return -1;
         464         [ -  + ]:          2 :     if (PyModule_AddIntMacro(m, LOCK_NB)) return -1;
         465         [ -  + ]:          2 :     if (PyModule_AddIntMacro(m, LOCK_UN)) return -1;
         466                 :            : /* GNU extensions, as of glibc 2.2.4 */
         467                 :            : #ifdef LOCK_MAND
         468         [ -  + ]:          2 :     if (PyModule_AddIntMacro(m, LOCK_MAND)) return -1;
         469                 :            : #endif
         470                 :            : #ifdef LOCK_READ
         471         [ -  + ]:          2 :     if (PyModule_AddIntMacro(m, LOCK_READ)) return -1;
         472                 :            : #endif
         473                 :            : #ifdef LOCK_WRITE
         474         [ -  + ]:          2 :     if (PyModule_AddIntMacro(m, LOCK_WRITE)) return -1;
         475                 :            : #endif
         476                 :            : #ifdef LOCK_RW
         477         [ -  + ]:          2 :     if (PyModule_AddIntMacro(m, LOCK_RW)) return -1;
         478                 :            : #endif
         479                 :            :
         480                 :            : #ifdef F_DUPFD
         481         [ -  + ]:          2 :     if (PyModule_AddIntMacro(m, F_DUPFD)) return -1;
         482                 :            : #endif
         483                 :            : #ifdef F_DUPFD_CLOEXEC
         484         [ -  + ]:          2 :     if (PyModule_AddIntMacro(m, F_DUPFD_CLOEXEC)) return -1;
         485                 :            : #endif
         486                 :            : #ifdef F_GETFD
         487         [ -  + ]:          2 :     if (PyModule_AddIntMacro(m, F_GETFD)) return -1;
         488                 :            : #endif
         489                 :            : #ifdef F_SETFD
         490         [ -  + ]:          2 :     if (PyModule_AddIntMacro(m, F_SETFD)) return -1;
         491                 :            : #endif
         492                 :            : #ifdef F_GETFL
         493         [ -  + ]:          2 :     if (PyModule_AddIntMacro(m, F_GETFL)) return -1;
         494                 :            : #endif
         495                 :            : #ifdef F_SETFL
         496         [ -  + ]:          2 :     if (PyModule_AddIntMacro(m, F_SETFL)) return -1;
         497                 :            : #endif
         498                 :            : #ifdef F_GETLK
         499         [ -  + ]:          2 :     if (PyModule_AddIntMacro(m, F_GETLK)) return -1;
         500                 :            : #endif
         501                 :            : #ifdef F_SETLK
         502         [ -  + ]:          2 :     if (PyModule_AddIntMacro(m, F_SETLK)) return -1;
         503                 :            : #endif
         504                 :            : #ifdef F_SETLKW
         505         [ -  + ]:          2 :     if (PyModule_AddIntMacro(m, F_SETLKW)) return -1;
         506                 :            : #endif
         507                 :            : #ifdef F_OFD_GETLK
         508         [ -  + ]:          2 :     if (PyModule_AddIntMacro(m, F_OFD_GETLK)) return -1;
         509                 :            : #endif
         510                 :            : #ifdef F_OFD_SETLK
         511         [ -  + ]:          2 :     if (PyModule_AddIntMacro(m, F_OFD_SETLK)) return -1;
         512                 :            : #endif
         513                 :            : #ifdef F_OFD_SETLKW
         514         [ -  + ]:          2 :     if (PyModule_AddIntMacro(m, F_OFD_SETLKW)) return -1;
         515                 :            : #endif
         516                 :            : #ifdef F_GETOWN
         517         [ -  + ]:          2 :     if (PyModule_AddIntMacro(m, F_GETOWN)) return -1;
         518                 :            : #endif
         519                 :            : #ifdef F_SETOWN
         520         [ -  + ]:          2 :     if (PyModule_AddIntMacro(m, F_SETOWN)) return -1;
         521                 :            : #endif
         522                 :            : #ifdef F_GETPATH
         523                 :            :     if (PyModule_AddIntMacro(m, F_GETPATH)) return -1;
         524                 :            : #endif
         525                 :            : #ifdef F_GETSIG
         526         [ -  + ]:          2 :     if (PyModule_AddIntMacro(m, F_GETSIG)) return -1;
         527                 :            : #endif
         528                 :            : #ifdef F_SETSIG
         529         [ -  + ]:          2 :     if (PyModule_AddIntMacro(m, F_SETSIG)) return -1;
         530                 :            : #endif
         531                 :            : #ifdef F_RDLCK
         532         [ -  + ]:          2 :     if (PyModule_AddIntMacro(m, F_RDLCK)) return -1;
         533                 :            : #endif
         534                 :            : #ifdef F_WRLCK
         535         [ -  + ]:          2 :     if (PyModule_AddIntMacro(m, F_WRLCK)) return -1;
         536                 :            : #endif
         537                 :            : #ifdef F_UNLCK
         538         [ -  + ]:          2 :     if (PyModule_AddIntMacro(m, F_UNLCK)) return -1;
         539                 :            : #endif
         540                 :            : /* LFS constants */
         541                 :            : #ifdef F_GETLK64
         542         [ -  + ]:          2 :     if (PyModule_AddIntMacro(m, F_GETLK64)) return -1;
         543                 :            : #endif
         544                 :            : #ifdef F_SETLK64
         545         [ -  + ]:          2 :     if (PyModule_AddIntMacro(m, F_SETLK64)) return -1;
         546                 :            : #endif
         547                 :            : #ifdef F_SETLKW64
         548         [ -  + ]:          2 :     if (PyModule_AddIntMacro(m, F_SETLKW64)) return -1;
         549                 :            : #endif
         550                 :            : /* GNU extensions, as of glibc 2.2.4. */
         551                 :            : #ifdef FASYNC
         552         [ -  + ]:          2 :     if (PyModule_AddIntMacro(m, FASYNC)) return -1;
         553                 :            : #endif
         554                 :            : #ifdef F_SETLEASE
         555         [ -  + ]:          2 :     if (PyModule_AddIntMacro(m, F_SETLEASE)) return -1;
         556                 :            : #endif
         557                 :            : #ifdef F_GETLEASE
         558         [ -  + ]:          2 :     if (PyModule_AddIntMacro(m, F_GETLEASE)) return -1;
         559                 :            : #endif
         560                 :            : #ifdef F_NOTIFY
         561         [ -  + ]:          2 :     if (PyModule_AddIntMacro(m, F_NOTIFY)) return -1;
         562                 :            : #endif
         563                 :            : /* Old BSD flock(). */
         564                 :            : #ifdef F_EXLCK
         565         [ -  + ]:          2 :     if (PyModule_AddIntMacro(m, F_EXLCK)) return -1;
         566                 :            : #endif
         567                 :            : #ifdef F_SHLCK
         568         [ -  + ]:          2 :     if (PyModule_AddIntMacro(m, F_SHLCK)) return -1;
         569                 :            : #endif
         570                 :            :
         571                 :            : /* Linux specifics */
         572                 :            : #ifdef F_SETPIPE_SZ
         573         [ -  + ]:          2 :     if (PyModule_AddIntMacro(m, F_SETPIPE_SZ)) return -1;
         574                 :            : #endif
         575                 :            : #ifdef F_GETPIPE_SZ
         576         [ -  + ]:          2 :     if (PyModule_AddIntMacro(m, F_GETPIPE_SZ)) return -1;
         577                 :            : #endif
         578                 :            : #ifdef FICLONE
         579         [ -  + ]:          2 :     if (PyModule_AddIntMacro(m, FICLONE)) return -1;
         580                 :            : #endif
         581                 :            : #ifdef FICLONERANGE
         582         [ -  + ]:          2 :     if (PyModule_AddIntMacro(m, FICLONERANGE)) return -1;
         583                 :            : #endif
         584                 :            :
         585                 :            : /* OS X specifics */
         586                 :            : #ifdef F_FULLFSYNC
         587                 :            :     if (PyModule_AddIntMacro(m, F_FULLFSYNC)) return -1;
         588                 :            : #endif
         589                 :            : #ifdef F_NOCACHE
         590                 :            :     if (PyModule_AddIntMacro(m, F_NOCACHE)) return -1;
         591                 :            : #endif
         592                 :            :
         593                 :            : /* FreeBSD specifics */
         594                 :            : #ifdef F_DUP2FD
         595                 :            :     if (PyModule_AddIntMacro(m, F_DUP2FD)) return -1;
         596                 :            : #endif
         597                 :            : #ifdef F_DUP2FD_CLOEXEC
         598                 :            :     if (PyModule_AddIntMacro(m, F_DUP2FD_CLOEXEC)) return -1;
         599                 :            : #endif
         600                 :            :
         601                 :            : /* For F_{GET|SET}FL */
         602                 :            : #ifdef FD_CLOEXEC
         603         [ -  + ]:          2 :     if (PyModule_AddIntMacro(m, FD_CLOEXEC)) return -1;
         604                 :            : #endif
         605                 :            :
         606                 :            : /* For F_NOTIFY */
         607                 :            : #ifdef DN_ACCESS
         608         [ -  + ]:          2 :     if (PyModule_AddIntMacro(m, DN_ACCESS)) return -1;
         609                 :            : #endif
         610                 :            : #ifdef DN_MODIFY
         611         [ -  + ]:          2 :     if (PyModule_AddIntMacro(m, DN_MODIFY)) return -1;
         612                 :            : #endif
         613                 :            : #ifdef DN_CREATE
         614         [ -  + ]:          2 :     if (PyModule_AddIntMacro(m, DN_CREATE)) return -1;
         615                 :            : #endif
         616                 :            : #ifdef DN_DELETE
         617         [ -  + ]:          2 :     if (PyModule_AddIntMacro(m, DN_DELETE)) return -1;
         618                 :            : #endif
         619                 :            : #ifdef DN_RENAME
         620         [ -  + ]:          2 :     if (PyModule_AddIntMacro(m, DN_RENAME)) return -1;
         621                 :            : #endif
         622                 :            : #ifdef DN_ATTRIB
         623         [ -  + ]:          2 :     if (PyModule_AddIntMacro(m, DN_ATTRIB)) return -1;
         624                 :            : #endif
         625                 :            : #ifdef DN_MULTISHOT
         626         [ -  + ]:          2 :     if (PyModule_AddIntMacro(m, DN_MULTISHOT)) return -1;
         627                 :            : #endif
         628                 :            :
         629                 :            : #ifdef HAVE_STROPTS_H
         630                 :            :     /* Unix 98 guarantees that these are in stropts.h. */
         631                 :            :     if (PyModule_AddIntMacro(m, I_PUSH)) return -1;
         632                 :            :     if (PyModule_AddIntMacro(m, I_POP)) return -1;
         633                 :            :     if (PyModule_AddIntMacro(m, I_LOOK)) return -1;
         634                 :            :     if (PyModule_AddIntMacro(m, I_FLUSH)) return -1;
         635                 :            :     if (PyModule_AddIntMacro(m, I_FLUSHBAND)) return -1;
         636                 :            :     if (PyModule_AddIntMacro(m, I_SETSIG)) return -1;
         637                 :            :     if (PyModule_AddIntMacro(m, I_GETSIG)) return -1;
         638                 :            :     if (PyModule_AddIntMacro(m, I_FIND)) return -1;
         639                 :            :     if (PyModule_AddIntMacro(m, I_PEEK)) return -1;
         640                 :            :     if (PyModule_AddIntMacro(m, I_SRDOPT)) return -1;
         641                 :            :     if (PyModule_AddIntMacro(m, I_GRDOPT)) return -1;
         642                 :            :     if (PyModule_AddIntMacro(m, I_NREAD)) return -1;
         643                 :            :     if (PyModule_AddIntMacro(m, I_FDINSERT)) return -1;
         644                 :            :     if (PyModule_AddIntMacro(m, I_STR)) return -1;
         645                 :            :     if (PyModule_AddIntMacro(m, I_SWROPT)) return -1;
         646                 :            : #ifdef I_GWROPT
         647                 :            :     /* despite the comment above, old-ish glibcs miss a couple... */
         648                 :            :     if (PyModule_AddIntMacro(m, I_GWROPT)) return -1;
         649                 :            : #endif
         650                 :            :     if (PyModule_AddIntMacro(m, I_SENDFD)) return -1;
         651                 :            :     if (PyModule_AddIntMacro(m, I_RECVFD)) return -1;
         652                 :            :     if (PyModule_AddIntMacro(m, I_LIST)) return -1;
         653                 :            :     if (PyModule_AddIntMacro(m, I_ATMARK)) return -1;
         654                 :            :     if (PyModule_AddIntMacro(m, I_CKBAND)) return -1;
         655                 :            :     if (PyModule_AddIntMacro(m, I_GETBAND)) return -1;
         656                 :            :     if (PyModule_AddIntMacro(m, I_CANPUT)) return -1;
         657                 :            :     if (PyModule_AddIntMacro(m, I_SETCLTIME)) return -1;
         658                 :            : #ifdef I_GETCLTIME
         659                 :            :     if (PyModule_AddIntMacro(m, I_GETCLTIME)) return -1;
         660                 :            : #endif
         661                 :            :     if (PyModule_AddIntMacro(m, I_LINK)) return -1;
         662                 :            :     if (PyModule_AddIntMacro(m, I_UNLINK)) return -1;
         663                 :            :     if (PyModule_AddIntMacro(m, I_PLINK)) return -1;
         664                 :            :     if (PyModule_AddIntMacro(m, I_PUNLINK)) return -1;
         665                 :            : #endif
         666                 :            : #ifdef F_ADD_SEALS
         667                 :            :     /* Linux: file sealing for memfd_create() */
         668         [ -  + ]:          2 :     if (PyModule_AddIntMacro(m, F_ADD_SEALS)) return -1;
         669         [ -  + ]:          2 :     if (PyModule_AddIntMacro(m, F_GET_SEALS)) return -1;
         670         [ -  + ]:          2 :     if (PyModule_AddIntMacro(m, F_SEAL_SEAL)) return -1;
         671         [ -  + ]:          2 :     if (PyModule_AddIntMacro(m, F_SEAL_SHRINK)) return -1;
         672         [ -  + ]:          2 :     if (PyModule_AddIntMacro(m, F_SEAL_GROW)) return -1;
         673         [ -  + ]:          2 :     if (PyModule_AddIntMacro(m, F_SEAL_WRITE)) return -1;
         674                 :            : #endif
         675                 :          2 :     return 0;
         676                 :            : }
         677                 :            :
         678                 :            : static int
         679                 :          2 : fcntl_exec(PyObject *module)
         680                 :            : {
         681         [ -  + ]:          2 :     if (all_ins(module) < 0) {
         682                 :          0 :         return -1;
         683                 :            :     }
         684                 :          2 :     return 0;
         685                 :            : }
         686                 :            :
         687                 :            : static PyModuleDef_Slot fcntl_slots[] = {
         688                 :            :     {Py_mod_exec, fcntl_exec},
         689                 :            :     {0, NULL}
         690                 :            : };
         691                 :            :
         692                 :            : static struct PyModuleDef fcntlmodule = {
         693                 :            :     PyModuleDef_HEAD_INIT,
         694                 :            :     .m_name = "fcntl",
         695                 :            :     .m_doc = module_doc,
         696                 :            :     .m_size = 0,
         697                 :            :     .m_methods = fcntl_methods,
         698                 :            :     .m_slots = fcntl_slots,
         699                 :            : };
         700                 :            :
         701                 :            : PyMODINIT_FUNC
         702                 :          2 : PyInit_fcntl(void)
         703                 :            : {
         704                 :          2 :     return PyModuleDef_Init(&fcntlmodule);
         705                 :            : }

Generated by: LCOV version 1.14