LCOV - code coverage report
Current view: top level - Modules - fcntlmodule.c (source / functions) Hit Total Coverage
Test: CPython lcov report Lines: 114 195 58.5 %
Date: 2022-07-07 18:19:46 Functions: 6 7 85.7 %

          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           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          21 : fcntl_flock_impl(PyObject *module, int fd, int code)
     286             : /*[clinic end generated code: output=84059e2b37d2fc64 input=0bfc00f795953452]*/
     287             : {
     288             :     int ret;
     289          21 :     int async_err = 0;
     290             : 
     291          21 :     if (PySys_Audit("fcntl.flock", "ii", fd, code) < 0) {
     292           0 :         return NULL;
     293             :     }
     294             : 
     295             : #ifdef HAVE_FLOCK
     296             :     do {
     297          22 :         Py_BEGIN_ALLOW_THREADS
     298          22 :         ret = flock(fd, code);
     299          22 :         Py_END_ALLOW_THREADS
     300          22 :     } 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          21 :     if (ret < 0) {
     331           1 :         return !async_err ? PyErr_SetFromErrno(PyExc_OSError) : NULL;
     332             :     }
     333          20 :     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          43 : 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          43 :     int async_err = 0;
     378             : 
     379          43 :     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          43 :         if (code == LOCK_UN)
     393          20 :             l.l_type = F_UNLCK;
     394          23 :         else if (code & LOCK_SH)
     395           1 :             l.l_type = F_RDLCK;
     396          22 :         else if (code & LOCK_EX)
     397          22 :             l.l_type = F_WRLCK;
     398             :         else {
     399           0 :             PyErr_SetString(PyExc_ValueError,
     400             :                             "unrecognized lockf argument");
     401           0 :             return NULL;
     402             :         }
     403          43 :         l.l_start = l.l_len = 0;
     404          43 :         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          43 :         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          43 :         l.l_whence = whence;
     427             :         do {
     428          44 :             Py_BEGIN_ALLOW_THREADS
     429          44 :             ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
     430          44 :             Py_END_ALLOW_THREADS
     431          44 :         } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
     432             :     }
     433          43 :     if (ret < 0) {
     434           3 :         return !async_err ? PyErr_SetFromErrno(PyExc_OSError) : NULL;
     435             :     }
     436          40 :     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        1202 : all_ins(PyObject* m)
     461             : {
     462        1202 :     if (PyModule_AddIntMacro(m, LOCK_SH)) return -1;
     463        1202 :     if (PyModule_AddIntMacro(m, LOCK_EX)) return -1;
     464        1202 :     if (PyModule_AddIntMacro(m, LOCK_NB)) return -1;
     465        1202 :     if (PyModule_AddIntMacro(m, LOCK_UN)) return -1;
     466             : /* GNU extensions, as of glibc 2.2.4 */
     467             : #ifdef LOCK_MAND
     468        1202 :     if (PyModule_AddIntMacro(m, LOCK_MAND)) return -1;
     469             : #endif
     470             : #ifdef LOCK_READ
     471        1202 :     if (PyModule_AddIntMacro(m, LOCK_READ)) return -1;
     472             : #endif
     473             : #ifdef LOCK_WRITE
     474        1202 :     if (PyModule_AddIntMacro(m, LOCK_WRITE)) return -1;
     475             : #endif
     476             : #ifdef LOCK_RW
     477        1202 :     if (PyModule_AddIntMacro(m, LOCK_RW)) return -1;
     478             : #endif
     479             : 
     480             : #ifdef F_DUPFD
     481        1202 :     if (PyModule_AddIntMacro(m, F_DUPFD)) return -1;
     482             : #endif
     483             : #ifdef F_DUPFD_CLOEXEC
     484        1202 :     if (PyModule_AddIntMacro(m, F_DUPFD_CLOEXEC)) return -1;
     485             : #endif
     486             : #ifdef F_GETFD
     487        1202 :     if (PyModule_AddIntMacro(m, F_GETFD)) return -1;
     488             : #endif
     489             : #ifdef F_SETFD
     490        1202 :     if (PyModule_AddIntMacro(m, F_SETFD)) return -1;
     491             : #endif
     492             : #ifdef F_GETFL
     493        1202 :     if (PyModule_AddIntMacro(m, F_GETFL)) return -1;
     494             : #endif
     495             : #ifdef F_SETFL
     496        1202 :     if (PyModule_AddIntMacro(m, F_SETFL)) return -1;
     497             : #endif
     498             : #ifdef F_GETLK
     499        1202 :     if (PyModule_AddIntMacro(m, F_GETLK)) return -1;
     500             : #endif
     501             : #ifdef F_SETLK
     502        1202 :     if (PyModule_AddIntMacro(m, F_SETLK)) return -1;
     503             : #endif
     504             : #ifdef F_SETLKW
     505        1202 :     if (PyModule_AddIntMacro(m, F_SETLKW)) return -1;
     506             : #endif
     507             : #ifdef F_OFD_GETLK
     508        1202 :     if (PyModule_AddIntMacro(m, F_OFD_GETLK)) return -1;
     509             : #endif
     510             : #ifdef F_OFD_SETLK
     511        1202 :     if (PyModule_AddIntMacro(m, F_OFD_SETLK)) return -1;
     512             : #endif
     513             : #ifdef F_OFD_SETLKW
     514        1202 :     if (PyModule_AddIntMacro(m, F_OFD_SETLKW)) return -1;
     515             : #endif
     516             : #ifdef F_GETOWN
     517        1202 :     if (PyModule_AddIntMacro(m, F_GETOWN)) return -1;
     518             : #endif
     519             : #ifdef F_SETOWN
     520        1202 :     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        1202 :     if (PyModule_AddIntMacro(m, F_GETSIG)) return -1;
     527             : #endif
     528             : #ifdef F_SETSIG
     529        1202 :     if (PyModule_AddIntMacro(m, F_SETSIG)) return -1;
     530             : #endif
     531             : #ifdef F_RDLCK
     532        1202 :     if (PyModule_AddIntMacro(m, F_RDLCK)) return -1;
     533             : #endif
     534             : #ifdef F_WRLCK
     535        1202 :     if (PyModule_AddIntMacro(m, F_WRLCK)) return -1;
     536             : #endif
     537             : #ifdef F_UNLCK
     538        1202 :     if (PyModule_AddIntMacro(m, F_UNLCK)) return -1;
     539             : #endif
     540             : /* LFS constants */
     541             : #ifdef F_GETLK64
     542        1202 :     if (PyModule_AddIntMacro(m, F_GETLK64)) return -1;
     543             : #endif
     544             : #ifdef F_SETLK64
     545        1202 :     if (PyModule_AddIntMacro(m, F_SETLK64)) return -1;
     546             : #endif
     547             : #ifdef F_SETLKW64
     548        1202 :     if (PyModule_AddIntMacro(m, F_SETLKW64)) return -1;
     549             : #endif
     550             : /* GNU extensions, as of glibc 2.2.4. */
     551             : #ifdef FASYNC
     552        1202 :     if (PyModule_AddIntMacro(m, FASYNC)) return -1;
     553             : #endif
     554             : #ifdef F_SETLEASE
     555        1202 :     if (PyModule_AddIntMacro(m, F_SETLEASE)) return -1;
     556             : #endif
     557             : #ifdef F_GETLEASE
     558        1202 :     if (PyModule_AddIntMacro(m, F_GETLEASE)) return -1;
     559             : #endif
     560             : #ifdef F_NOTIFY
     561        1202 :     if (PyModule_AddIntMacro(m, F_NOTIFY)) return -1;
     562             : #endif
     563             : /* Old BSD flock(). */
     564             : #ifdef F_EXLCK
     565        1202 :     if (PyModule_AddIntMacro(m, F_EXLCK)) return -1;
     566             : #endif
     567             : #ifdef F_SHLCK
     568        1202 :     if (PyModule_AddIntMacro(m, F_SHLCK)) return -1;
     569             : #endif
     570             : 
     571             : /* Linux specifics */
     572             : #ifdef F_SETPIPE_SZ
     573        1202 :     if (PyModule_AddIntMacro(m, F_SETPIPE_SZ)) return -1;
     574             : #endif
     575             : #ifdef F_GETPIPE_SZ
     576        1202 :     if (PyModule_AddIntMacro(m, F_GETPIPE_SZ)) return -1;
     577             : #endif
     578             : #ifdef FICLONE
     579        1202 :     if (PyModule_AddIntMacro(m, FICLONE)) return -1;
     580             : #endif
     581             : #ifdef FICLONERANGE
     582        1202 :     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        1202 :     if (PyModule_AddIntMacro(m, FD_CLOEXEC)) return -1;
     604             : #endif
     605             : 
     606             : /* For F_NOTIFY */
     607             : #ifdef DN_ACCESS
     608        1202 :     if (PyModule_AddIntMacro(m, DN_ACCESS)) return -1;
     609             : #endif
     610             : #ifdef DN_MODIFY
     611        1202 :     if (PyModule_AddIntMacro(m, DN_MODIFY)) return -1;
     612             : #endif
     613             : #ifdef DN_CREATE
     614        1202 :     if (PyModule_AddIntMacro(m, DN_CREATE)) return -1;
     615             : #endif
     616             : #ifdef DN_DELETE
     617        1202 :     if (PyModule_AddIntMacro(m, DN_DELETE)) return -1;
     618             : #endif
     619             : #ifdef DN_RENAME
     620        1202 :     if (PyModule_AddIntMacro(m, DN_RENAME)) return -1;
     621             : #endif
     622             : #ifdef DN_ATTRIB
     623        1202 :     if (PyModule_AddIntMacro(m, DN_ATTRIB)) return -1;
     624             : #endif
     625             : #ifdef DN_MULTISHOT
     626        1202 :     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        1202 :     if (PyModule_AddIntMacro(m, F_ADD_SEALS)) return -1;
     669        1202 :     if (PyModule_AddIntMacro(m, F_GET_SEALS)) return -1;
     670        1202 :     if (PyModule_AddIntMacro(m, F_SEAL_SEAL)) return -1;
     671        1202 :     if (PyModule_AddIntMacro(m, F_SEAL_SHRINK)) return -1;
     672        1202 :     if (PyModule_AddIntMacro(m, F_SEAL_GROW)) return -1;
     673        1202 :     if (PyModule_AddIntMacro(m, F_SEAL_WRITE)) return -1;
     674             : #endif
     675        1202 :     return 0;
     676             : }
     677             : 
     678             : static int
     679        1202 : fcntl_exec(PyObject *module)
     680             : {
     681        1202 :     if (all_ins(module) < 0) {
     682           0 :         return -1;
     683             :     }
     684        1202 :     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        1202 : PyInit_fcntl(void)
     703             : {
     704        1202 :     return PyModuleDef_Init(&fcntlmodule);
     705             : }

Generated by: LCOV version 1.14