LCOV - code coverage report
Current view: top level - Modules - fcntlmodule.c (source / functions) Hit Total Coverage
Test: CPython 3.12 LCOV report [commit acb105a7c1f] Lines: 132 195 67.7 %
Date: 2022-07-20 13:12:14 Functions: 7 7 100.0 %
Branches: 104 220 47.3 %

           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                 :         55 : fcntl_fcntl_impl(PyObject *module, int fd, int code, PyObject *arg)
      51                 :            : /*[clinic end generated code: output=888fc93b51c295bd input=7955340198e5f334]*/
      52                 :            : {
      53                 :         55 :     unsigned int int_arg = 0;
      54                 :            :     int ret;
      55                 :            :     char *str;
      56                 :            :     Py_ssize_t len;
      57                 :            :     char buf[1024];
      58                 :         55 :     int async_err = 0;
      59                 :            : 
      60   [ +  +  -  + ]:         55 :     if (PySys_Audit("fcntl.fcntl", "iiO", fd, code, arg ? arg : Py_None) < 0) {
      61                 :          0 :         return NULL;
      62                 :            :     }
      63                 :            : 
      64         [ +  + ]:         55 :     if (arg != NULL) {
      65                 :            :         int parse_result;
      66                 :            : 
      67         [ +  + ]:         31 :         if (PyArg_Parse(arg, "s#", &str, &len)) {
      68         [ -  + ]:          2 :             if ((size_t)len > sizeof buf) {
      69                 :          0 :                 PyErr_SetString(PyExc_ValueError,
      70                 :            :                                 "fcntl string arg too long");
      71                 :          0 :                 return NULL;
      72                 :            :             }
      73                 :          2 :             memcpy(buf, str, len);
      74                 :            :             do {
      75                 :          2 :                 Py_BEGIN_ALLOW_THREADS
      76                 :          2 :                 ret = fcntl(fd, code, buf);
      77                 :          2 :                 Py_END_ALLOW_THREADS
      78   [ -  +  -  -  :          2 :             } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
                   -  - ]
      79         [ -  + ]:          2 :             if (ret < 0) {
      80         [ #  # ]:          0 :                 return !async_err ? PyErr_SetFromErrno(PyExc_OSError) : NULL;
      81                 :            :             }
      82                 :          2 :             return PyBytes_FromStringAndSize(buf, len);
      83                 :            :         }
      84                 :            : 
      85                 :         29 :         PyErr_Clear();
      86                 :         29 :         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         [ -  + ]:         29 :         if (!parse_result) {
      91                 :          0 :           return NULL;
      92                 :            :         }
      93                 :            :     }
      94                 :            : 
      95                 :            :     do {
      96                 :         53 :         Py_BEGIN_ALLOW_THREADS
      97                 :         53 :         ret = fcntl(fd, code, (int)int_arg);
      98                 :         53 :         Py_END_ALLOW_THREADS
      99   [ -  +  -  -  :         53 :     } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
                   -  - ]
     100         [ -  + ]:         53 :     if (ret < 0) {
     101         [ #  # ]:          0 :         return !async_err ? PyErr_SetFromErrno(PyExc_OSError) : NULL;
     102                 :            :     }
     103                 :         53 :     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                 :          6 : 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                 :          6 :     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   [ +  -  -  + ]:          6 :     if (PySys_Audit("fcntl.ioctl", "iIO", fd, code,
     170                 :            :                     ob_arg ? ob_arg : Py_None) < 0) {
     171                 :          0 :         return NULL;
     172                 :            :     }
     173                 :            : 
     174         [ +  - ]:          6 :     if (ob_arg != NULL) {
     175         [ -  + ]:          6 :         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                 :          6 :         PyErr_Clear();
     228         [ +  - ]:          6 :         if (PyArg_Parse(ob_arg, "s*:ioctl", &pstr)) {
     229                 :          6 :             str = pstr.buf;
     230                 :          6 :             len = pstr.len;
     231         [ -  + ]:          6 :             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                 :          6 :             memcpy(buf, str, len);
     238                 :          6 :             buf[len] = '\0';
     239                 :          6 :             Py_BEGIN_ALLOW_THREADS
     240                 :          6 :             ret = ioctl(fd, code, buf);
     241                 :          6 :             Py_END_ALLOW_THREADS
     242         [ -  + ]:          6 :             if (ret < 0) {
     243                 :          0 :                 PyBuffer_Release(&pstr);
     244                 :          0 :                 PyErr_SetFromErrno(PyExc_OSError);
     245                 :          0 :                 return NULL;
     246                 :            :             }
     247                 :          6 :             PyBuffer_Release(&pstr);
     248                 :          6 :             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                 :         19 : fcntl_flock_impl(PyObject *module, int fd, int code)
     286                 :            : /*[clinic end generated code: output=84059e2b37d2fc64 input=0bfc00f795953452]*/
     287                 :            : {
     288                 :            :     int ret;
     289                 :         19 :     int async_err = 0;
     290                 :            : 
     291         [ -  + ]:         19 :     if (PySys_Audit("fcntl.flock", "ii", fd, code) < 0) {
     292                 :          0 :         return NULL;
     293                 :            :     }
     294                 :            : 
     295                 :            : #ifdef HAVE_FLOCK
     296                 :            :     do {
     297                 :         20 :         Py_BEGIN_ALLOW_THREADS
     298                 :         20 :         ret = flock(fd, code);
     299                 :         20 :         Py_END_ALLOW_THREADS
     300   [ +  +  +  +  :         20 :     } 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         [ +  + ]:         19 :     if (ret < 0) {
     331         [ +  - ]:          1 :         return !async_err ? PyErr_SetFromErrno(PyExc_OSError) : NULL;
     332                 :            :     }
     333                 :         18 :     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                 :         41 : 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                 :         41 :     int async_err = 0;
     378                 :            : 
     379   [ -  +  -  +  :         41 :     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         [ +  + ]:         41 :         if (code == LOCK_UN)
     393                 :         19 :             l.l_type = F_UNLCK;
     394         [ +  + ]:         22 :         else if (code & LOCK_SH)
     395                 :          1 :             l.l_type = F_RDLCK;
     396         [ +  - ]:         21 :         else if (code & LOCK_EX)
     397                 :         21 :             l.l_type = F_WRLCK;
     398                 :            :         else {
     399                 :          0 :             PyErr_SetString(PyExc_ValueError,
     400                 :            :                             "unrecognized lockf argument");
     401                 :          0 :             return NULL;
     402                 :            :         }
     403                 :         41 :         l.l_start = l.l_len = 0;
     404         [ -  + ]:         41 :         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         [ -  + ]:         41 :         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                 :         41 :         l.l_whence = whence;
     427                 :            :         do {
     428                 :         42 :             Py_BEGIN_ALLOW_THREADS
     429         [ +  + ]:         42 :             ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
     430                 :         42 :             Py_END_ALLOW_THREADS
     431   [ +  +  +  +  :         42 :         } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
                   +  - ]
     432                 :            :     }
     433         [ +  + ]:         41 :     if (ret < 0) {
     434         [ +  - ]:          3 :         return !async_err ? PyErr_SetFromErrno(PyExc_OSError) : NULL;
     435                 :            :     }
     436                 :         38 :     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                 :       1200 : all_ins(PyObject* m)
     461                 :            : {
     462         [ -  + ]:       1200 :     if (PyModule_AddIntMacro(m, LOCK_SH)) return -1;
     463         [ -  + ]:       1200 :     if (PyModule_AddIntMacro(m, LOCK_EX)) return -1;
     464         [ -  + ]:       1200 :     if (PyModule_AddIntMacro(m, LOCK_NB)) return -1;
     465         [ -  + ]:       1200 :     if (PyModule_AddIntMacro(m, LOCK_UN)) return -1;
     466                 :            : /* GNU extensions, as of glibc 2.2.4 */
     467                 :            : #ifdef LOCK_MAND
     468         [ -  + ]:       1200 :     if (PyModule_AddIntMacro(m, LOCK_MAND)) return -1;
     469                 :            : #endif
     470                 :            : #ifdef LOCK_READ
     471         [ -  + ]:       1200 :     if (PyModule_AddIntMacro(m, LOCK_READ)) return -1;
     472                 :            : #endif
     473                 :            : #ifdef LOCK_WRITE
     474         [ -  + ]:       1200 :     if (PyModule_AddIntMacro(m, LOCK_WRITE)) return -1;
     475                 :            : #endif
     476                 :            : #ifdef LOCK_RW
     477         [ -  + ]:       1200 :     if (PyModule_AddIntMacro(m, LOCK_RW)) return -1;
     478                 :            : #endif
     479                 :            : 
     480                 :            : #ifdef F_DUPFD
     481         [ -  + ]:       1200 :     if (PyModule_AddIntMacro(m, F_DUPFD)) return -1;
     482                 :            : #endif
     483                 :            : #ifdef F_DUPFD_CLOEXEC
     484         [ -  + ]:       1200 :     if (PyModule_AddIntMacro(m, F_DUPFD_CLOEXEC)) return -1;
     485                 :            : #endif
     486                 :            : #ifdef F_GETFD
     487         [ -  + ]:       1200 :     if (PyModule_AddIntMacro(m, F_GETFD)) return -1;
     488                 :            : #endif
     489                 :            : #ifdef F_SETFD
     490         [ -  + ]:       1200 :     if (PyModule_AddIntMacro(m, F_SETFD)) return -1;
     491                 :            : #endif
     492                 :            : #ifdef F_GETFL
     493         [ -  + ]:       1200 :     if (PyModule_AddIntMacro(m, F_GETFL)) return -1;
     494                 :            : #endif
     495                 :            : #ifdef F_SETFL
     496         [ -  + ]:       1200 :     if (PyModule_AddIntMacro(m, F_SETFL)) return -1;
     497                 :            : #endif
     498                 :            : #ifdef F_GETLK
     499         [ -  + ]:       1200 :     if (PyModule_AddIntMacro(m, F_GETLK)) return -1;
     500                 :            : #endif
     501                 :            : #ifdef F_SETLK
     502         [ -  + ]:       1200 :     if (PyModule_AddIntMacro(m, F_SETLK)) return -1;
     503                 :            : #endif
     504                 :            : #ifdef F_SETLKW
     505         [ -  + ]:       1200 :     if (PyModule_AddIntMacro(m, F_SETLKW)) return -1;
     506                 :            : #endif
     507                 :            : #ifdef F_OFD_GETLK
     508         [ -  + ]:       1200 :     if (PyModule_AddIntMacro(m, F_OFD_GETLK)) return -1;
     509                 :            : #endif
     510                 :            : #ifdef F_OFD_SETLK
     511         [ -  + ]:       1200 :     if (PyModule_AddIntMacro(m, F_OFD_SETLK)) return -1;
     512                 :            : #endif
     513                 :            : #ifdef F_OFD_SETLKW
     514         [ -  + ]:       1200 :     if (PyModule_AddIntMacro(m, F_OFD_SETLKW)) return -1;
     515                 :            : #endif
     516                 :            : #ifdef F_GETOWN
     517         [ -  + ]:       1200 :     if (PyModule_AddIntMacro(m, F_GETOWN)) return -1;
     518                 :            : #endif
     519                 :            : #ifdef F_SETOWN
     520         [ -  + ]:       1200 :     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         [ -  + ]:       1200 :     if (PyModule_AddIntMacro(m, F_GETSIG)) return -1;
     527                 :            : #endif
     528                 :            : #ifdef F_SETSIG
     529         [ -  + ]:       1200 :     if (PyModule_AddIntMacro(m, F_SETSIG)) return -1;
     530                 :            : #endif
     531                 :            : #ifdef F_RDLCK
     532         [ -  + ]:       1200 :     if (PyModule_AddIntMacro(m, F_RDLCK)) return -1;
     533                 :            : #endif
     534                 :            : #ifdef F_WRLCK
     535         [ -  + ]:       1200 :     if (PyModule_AddIntMacro(m, F_WRLCK)) return -1;
     536                 :            : #endif
     537                 :            : #ifdef F_UNLCK
     538         [ -  + ]:       1200 :     if (PyModule_AddIntMacro(m, F_UNLCK)) return -1;
     539                 :            : #endif
     540                 :            : /* LFS constants */
     541                 :            : #ifdef F_GETLK64
     542         [ -  + ]:       1200 :     if (PyModule_AddIntMacro(m, F_GETLK64)) return -1;
     543                 :            : #endif
     544                 :            : #ifdef F_SETLK64
     545         [ -  + ]:       1200 :     if (PyModule_AddIntMacro(m, F_SETLK64)) return -1;
     546                 :            : #endif
     547                 :            : #ifdef F_SETLKW64
     548         [ -  + ]:       1200 :     if (PyModule_AddIntMacro(m, F_SETLKW64)) return -1;
     549                 :            : #endif
     550                 :            : /* GNU extensions, as of glibc 2.2.4. */
     551                 :            : #ifdef FASYNC
     552         [ -  + ]:       1200 :     if (PyModule_AddIntMacro(m, FASYNC)) return -1;
     553                 :            : #endif
     554                 :            : #ifdef F_SETLEASE
     555         [ -  + ]:       1200 :     if (PyModule_AddIntMacro(m, F_SETLEASE)) return -1;
     556                 :            : #endif
     557                 :            : #ifdef F_GETLEASE
     558         [ -  + ]:       1200 :     if (PyModule_AddIntMacro(m, F_GETLEASE)) return -1;
     559                 :            : #endif
     560                 :            : #ifdef F_NOTIFY
     561         [ -  + ]:       1200 :     if (PyModule_AddIntMacro(m, F_NOTIFY)) return -1;
     562                 :            : #endif
     563                 :            : /* Old BSD flock(). */
     564                 :            : #ifdef F_EXLCK
     565         [ -  + ]:       1200 :     if (PyModule_AddIntMacro(m, F_EXLCK)) return -1;
     566                 :            : #endif
     567                 :            : #ifdef F_SHLCK
     568         [ -  + ]:       1200 :     if (PyModule_AddIntMacro(m, F_SHLCK)) return -1;
     569                 :            : #endif
     570                 :            : 
     571                 :            : /* Linux specifics */
     572                 :            : #ifdef F_SETPIPE_SZ
     573         [ -  + ]:       1200 :     if (PyModule_AddIntMacro(m, F_SETPIPE_SZ)) return -1;
     574                 :            : #endif
     575                 :            : #ifdef F_GETPIPE_SZ
     576         [ -  + ]:       1200 :     if (PyModule_AddIntMacro(m, F_GETPIPE_SZ)) return -1;
     577                 :            : #endif
     578                 :            : #ifdef FICLONE
     579         [ -  + ]:       1200 :     if (PyModule_AddIntMacro(m, FICLONE)) return -1;
     580                 :            : #endif
     581                 :            : #ifdef FICLONERANGE
     582         [ -  + ]:       1200 :     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         [ -  + ]:       1200 :     if (PyModule_AddIntMacro(m, FD_CLOEXEC)) return -1;
     604                 :            : #endif
     605                 :            : 
     606                 :            : /* For F_NOTIFY */
     607                 :            : #ifdef DN_ACCESS
     608         [ -  + ]:       1200 :     if (PyModule_AddIntMacro(m, DN_ACCESS)) return -1;
     609                 :            : #endif
     610                 :            : #ifdef DN_MODIFY
     611         [ -  + ]:       1200 :     if (PyModule_AddIntMacro(m, DN_MODIFY)) return -1;
     612                 :            : #endif
     613                 :            : #ifdef DN_CREATE
     614         [ -  + ]:       1200 :     if (PyModule_AddIntMacro(m, DN_CREATE)) return -1;
     615                 :            : #endif
     616                 :            : #ifdef DN_DELETE
     617         [ -  + ]:       1200 :     if (PyModule_AddIntMacro(m, DN_DELETE)) return -1;
     618                 :            : #endif
     619                 :            : #ifdef DN_RENAME
     620         [ -  + ]:       1200 :     if (PyModule_AddIntMacro(m, DN_RENAME)) return -1;
     621                 :            : #endif
     622                 :            : #ifdef DN_ATTRIB
     623         [ -  + ]:       1200 :     if (PyModule_AddIntMacro(m, DN_ATTRIB)) return -1;
     624                 :            : #endif
     625                 :            : #ifdef DN_MULTISHOT
     626         [ -  + ]:       1200 :     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         [ -  + ]:       1200 :     if (PyModule_AddIntMacro(m, F_ADD_SEALS)) return -1;
     669         [ -  + ]:       1200 :     if (PyModule_AddIntMacro(m, F_GET_SEALS)) return -1;
     670         [ -  + ]:       1200 :     if (PyModule_AddIntMacro(m, F_SEAL_SEAL)) return -1;
     671         [ -  + ]:       1200 :     if (PyModule_AddIntMacro(m, F_SEAL_SHRINK)) return -1;
     672         [ -  + ]:       1200 :     if (PyModule_AddIntMacro(m, F_SEAL_GROW)) return -1;
     673         [ -  + ]:       1200 :     if (PyModule_AddIntMacro(m, F_SEAL_WRITE)) return -1;
     674                 :            : #endif
     675                 :       1200 :     return 0;
     676                 :            : }
     677                 :            : 
     678                 :            : static int
     679                 :       1200 : fcntl_exec(PyObject *module)
     680                 :            : {
     681         [ -  + ]:       1200 :     if (all_ins(module) < 0) {
     682                 :          0 :         return -1;
     683                 :            :     }
     684                 :       1200 :     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                 :       1200 : PyInit_fcntl(void)
     703                 :            : {
     704                 :       1200 :     return PyModuleDef_Init(&fcntlmodule);
     705                 :            : }

Generated by: LCOV version 1.14