LCOV - code coverage report
Current view: top level - Modules - fcntlmodule.c (source / functions) Hit Total Coverage
Test: CPython lcov report Lines: 82 194 42.3 %
Date: 2017-04-19 Functions: 3 8 37.5 %

          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             : 
      12             : #include <sys/ioctl.h>
      13             : #include <fcntl.h>
      14             : #ifdef HAVE_STROPTS_H
      15             : #include <stropts.h>
      16             : #endif
      17             : 
      18             : static int
      19           0 : conv_descriptor(PyObject *object, int *target)
      20             : {
      21           0 :     int fd = PyObject_AsFileDescriptor(object);
      22             : 
      23           0 :     if (fd < 0)
      24           0 :         return 0;
      25           0 :     *target = fd;
      26           0 :     return 1;
      27             : }
      28             : 
      29             : 
      30             : /* fcntl(fd, op, [arg]) */
      31             : 
      32             : static PyObject *
      33           0 : fcntl_fcntl(PyObject *self, PyObject *args)
      34             : {
      35             :     int fd;
      36             :     int code;
      37             :     int arg;
      38             :     int ret;
      39             :     char *str;
      40             :     Py_ssize_t len;
      41             :     char buf[1024];
      42             : 
      43           0 :     if (PyArg_ParseTuple(args, "O&is#:fcntl",
      44             :                          conv_descriptor, &fd, &code, &str, &len)) {
      45           0 :         if (len > sizeof buf) {
      46           0 :             PyErr_SetString(PyExc_ValueError,
      47             :                             "fcntl string arg too long");
      48           0 :             return NULL;
      49             :         }
      50           0 :         memcpy(buf, str, len);
      51             :         Py_BEGIN_ALLOW_THREADS
      52           0 :         ret = fcntl(fd, code, buf);
      53             :         Py_END_ALLOW_THREADS
      54           0 :         if (ret < 0) {
      55           0 :             PyErr_SetFromErrno(PyExc_IOError);
      56           0 :             return NULL;
      57             :         }
      58           0 :         return PyString_FromStringAndSize(buf, len);
      59             :     }
      60             : 
      61           0 :     PyErr_Clear();
      62           0 :     arg = 0;
      63           0 :     if (!PyArg_ParseTuple(args,
      64             :          "O&i|I;fcntl requires a file or file descriptor,"
      65             :          " an integer and optionally a third integer or a string",
      66             :                           conv_descriptor, &fd, &code, &arg)) {
      67           0 :       return NULL;
      68             :     }
      69             :     Py_BEGIN_ALLOW_THREADS
      70           0 :     ret = fcntl(fd, code, arg);
      71             :     Py_END_ALLOW_THREADS
      72           0 :     if (ret < 0) {
      73           0 :         PyErr_SetFromErrno(PyExc_IOError);
      74           0 :         return NULL;
      75             :     }
      76           0 :     return PyInt_FromLong((long)ret);
      77             : }
      78             : 
      79             : PyDoc_STRVAR(fcntl_doc,
      80             : "fcntl(fd, op, [arg])\n\
      81             : \n\
      82             : Perform the operation op on file descriptor fd.  The values used\n\
      83             : for op are operating system dependent, and are available\n\
      84             : as constants in the fcntl module, using the same names as used in\n\
      85             : the relevant C header files.  The argument arg is optional, and\n\
      86             : defaults to 0; it may be an int or a string.  If arg is given as a string,\n\
      87             : the return value of fcntl is a string of that length, containing the\n\
      88             : resulting value put in the arg buffer by the operating system.  The length\n\
      89             : of the arg string is not allowed to exceed 1024 bytes.  If the arg given\n\
      90             : is an integer or if none is specified, the result value is an integer\n\
      91             : corresponding to the return value of the fcntl call in the C code.");
      92             : 
      93             : 
      94             : /* ioctl(fd, op, [arg]) */
      95             : 
      96             : static PyObject *
      97           0 : fcntl_ioctl(PyObject *self, PyObject *args)
      98             : {
      99             : #define IOCTL_BUFSZ 1024
     100             :     int fd;
     101             :     /* In PyArg_ParseTuple below, we use the unsigned non-checked 'I'
     102             :        format for the 'code' parameter because Python turns 0x8000000
     103             :        into either a large positive number (PyLong or PyInt on 64-bit
     104             :        platforms) or a negative number on others (32-bit PyInt)
     105             :        whereas the system expects it to be a 32bit bit field value
     106             :        regardless of it being passed as an int or unsigned long on
     107             :        various platforms.  See the termios.TIOCSWINSZ constant across
     108             :        platforms for an example of this.
     109             : 
     110             :        If any of the 64bit platforms ever decide to use more than 32bits
     111             :        in their unsigned long ioctl codes this will break and need
     112             :        special casing based on the platform being built on.
     113             :      */
     114             :     unsigned int code;
     115             :     int arg;
     116             :     int ret;
     117             :     char *str;
     118             :     Py_ssize_t len;
     119           0 :     int mutate_arg = 1;
     120             :     char buf[IOCTL_BUFSZ+1];  /* argument plus NUL byte */
     121             : 
     122           0 :     if (PyArg_ParseTuple(args, "O&Iw#|i:ioctl",
     123             :                          conv_descriptor, &fd, &code,
     124             :                          &str, &len, &mutate_arg)) {
     125             :         char *arg;
     126             : 
     127           0 :         if (mutate_arg) {
     128           0 :             if (len <= IOCTL_BUFSZ) {
     129           0 :                 memcpy(buf, str, len);
     130           0 :                 buf[len] = '\0';
     131           0 :                 arg = buf;
     132             :             }
     133             :             else {
     134           0 :                 arg = str;
     135             :             }
     136             :         }
     137             :         else {
     138           0 :             if (len > IOCTL_BUFSZ) {
     139           0 :                 PyErr_SetString(PyExc_ValueError,
     140             :                     "ioctl string arg too long");
     141           0 :                 return NULL;
     142             :             }
     143             :             else {
     144           0 :                 memcpy(buf, str, len);
     145           0 :                 buf[len] = '\0';
     146           0 :                 arg = buf;
     147             :             }
     148             :         }
     149           0 :         if (buf == arg) {
     150             :             Py_BEGIN_ALLOW_THREADS /* think array.resize() */
     151           0 :             ret = ioctl(fd, code, arg);
     152             :             Py_END_ALLOW_THREADS
     153             :         }
     154             :         else {
     155           0 :             ret = ioctl(fd, code, arg);
     156             :         }
     157           0 :         if (mutate_arg && (len <= IOCTL_BUFSZ)) {
     158           0 :             memcpy(str, buf, len);
     159             :         }
     160           0 :         if (ret < 0) {
     161           0 :             PyErr_SetFromErrno(PyExc_IOError);
     162           0 :             return NULL;
     163             :         }
     164           0 :         if (mutate_arg) {
     165           0 :             return PyInt_FromLong(ret);
     166             :         }
     167             :         else {
     168           0 :             return PyString_FromStringAndSize(buf, len);
     169             :         }
     170             :     }
     171             : 
     172           0 :     PyErr_Clear();
     173           0 :     if (PyArg_ParseTuple(args, "O&Is#:ioctl",
     174             :                          conv_descriptor, &fd, &code, &str, &len)) {
     175           0 :         if (len > IOCTL_BUFSZ) {
     176           0 :             PyErr_SetString(PyExc_ValueError,
     177             :                             "ioctl string arg too long");
     178           0 :             return NULL;
     179             :         }
     180           0 :         memcpy(buf, str, len);
     181           0 :         buf[len] = '\0';
     182             :         Py_BEGIN_ALLOW_THREADS
     183           0 :         ret = ioctl(fd, code, buf);
     184             :         Py_END_ALLOW_THREADS
     185           0 :         if (ret < 0) {
     186           0 :             PyErr_SetFromErrno(PyExc_IOError);
     187           0 :             return NULL;
     188             :         }
     189           0 :         return PyString_FromStringAndSize(buf, len);
     190             :     }
     191             : 
     192           0 :     PyErr_Clear();
     193           0 :     arg = 0;
     194           0 :     if (!PyArg_ParseTuple(args,
     195             :          "O&I|i;ioctl requires a file or file descriptor,"
     196             :          " an integer and optionally an integer or buffer argument",
     197             :                           conv_descriptor, &fd, &code, &arg)) {
     198           0 :       return NULL;
     199             :     }
     200             :     Py_BEGIN_ALLOW_THREADS
     201             : #ifdef __VMS
     202             :     ret = ioctl(fd, code, (void *)arg);
     203             : #else
     204           0 :     ret = ioctl(fd, code, arg);
     205             : #endif
     206             :     Py_END_ALLOW_THREADS
     207           0 :     if (ret < 0) {
     208           0 :         PyErr_SetFromErrno(PyExc_IOError);
     209           0 :         return NULL;
     210             :     }
     211           0 :     return PyInt_FromLong((long)ret);
     212             : #undef IOCTL_BUFSZ
     213             : }
     214             : 
     215             : PyDoc_STRVAR(ioctl_doc,
     216             : "ioctl(fd, op[, arg[, mutate_flag]])\n\
     217             : \n\
     218             : Perform the operation op on file descriptor fd.  The values used for op\n\
     219             : are operating system dependent, and are available as constants in the\n\
     220             : fcntl or termios library modules, using the same names as used in the\n\
     221             : relevant C header files.\n\
     222             : \n\
     223             : The argument arg is optional, and defaults to 0; it may be an int or a\n\
     224             : buffer containing character data (most likely a string or an array). \n\
     225             : \n\
     226             : If the argument is a mutable buffer (such as an array) and if the\n\
     227             : mutate_flag argument (which is only allowed in this case) is true then the\n\
     228             : buffer is (in effect) passed to the operating system and changes made by\n\
     229             : the OS will be reflected in the contents of the buffer after the call has\n\
     230             : returned.  The return value is the integer returned by the ioctl system\n\
     231             : call.\n\
     232             : \n\
     233             : If the argument is a mutable buffer and the mutable_flag argument is not\n\
     234             : passed or is false, the behavior is as if a string had been passed.  This\n\
     235             : behavior will change in future releases of Python.\n\
     236             : \n\
     237             : If the argument is an immutable buffer (most likely a string) then a copy\n\
     238             : of the buffer is passed to the operating system and the return value is a\n\
     239             : string of the same length containing whatever the operating system put in\n\
     240             : the buffer.  The length of the arg buffer in this case is not allowed to\n\
     241             : exceed 1024 bytes.\n\
     242             : \n\
     243             : If the arg given is an integer or if none is specified, the result value is\n\
     244             : an integer corresponding to the return value of the ioctl call in the C\n\
     245             : code.");
     246             : 
     247             : 
     248             : /* flock(fd, operation) */
     249             : 
     250             : static PyObject *
     251           0 : fcntl_flock(PyObject *self, PyObject *args)
     252             : {
     253             :     int fd;
     254             :     int code;
     255             :     int ret;
     256             : 
     257           0 :     if (!PyArg_ParseTuple(args, "O&i:flock",
     258             :                           conv_descriptor, &fd, &code))
     259           0 :         return NULL;
     260             : 
     261             : #ifdef HAVE_FLOCK
     262             :     Py_BEGIN_ALLOW_THREADS
     263           0 :     ret = flock(fd, code);
     264             :     Py_END_ALLOW_THREADS
     265             : #else
     266             : 
     267             : #ifndef LOCK_SH
     268             : #define LOCK_SH         1       /* shared lock */
     269             : #define LOCK_EX         2       /* exclusive lock */
     270             : #define LOCK_NB         4       /* don't block when locking */
     271             : #define LOCK_UN         8       /* unlock */
     272             : #endif
     273             :     {
     274             :         struct flock l;
     275             :         if (code == LOCK_UN)
     276             :             l.l_type = F_UNLCK;
     277             :         else if (code & LOCK_SH)
     278             :             l.l_type = F_RDLCK;
     279             :         else if (code & LOCK_EX)
     280             :             l.l_type = F_WRLCK;
     281             :         else {
     282             :             PyErr_SetString(PyExc_ValueError,
     283             :                             "unrecognized flock argument");
     284             :             return NULL;
     285             :         }
     286             :         l.l_whence = l.l_start = l.l_len = 0;
     287             :         Py_BEGIN_ALLOW_THREADS
     288             :         ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
     289             :         Py_END_ALLOW_THREADS
     290             :     }
     291             : #endif /* HAVE_FLOCK */
     292           0 :     if (ret < 0) {
     293           0 :         PyErr_SetFromErrno(PyExc_IOError);
     294           0 :         return NULL;
     295             :     }
     296           0 :     Py_INCREF(Py_None);
     297           0 :     return Py_None;
     298             : }
     299             : 
     300             : PyDoc_STRVAR(flock_doc,
     301             : "flock(fd, operation)\n\
     302             : \n\
     303             : Perform the lock operation op on file descriptor fd.  See the Unix \n\
     304             : manual page for flock(2) for details.  (On some systems, this function is\n\
     305             : emulated using fcntl().)");
     306             : 
     307             : 
     308             : /* lockf(fd, operation) */
     309             : static PyObject *
     310           0 : fcntl_lockf(PyObject *self, PyObject *args)
     311             : {
     312           0 :     int fd, code, ret, whence = 0;
     313           0 :     PyObject *lenobj = NULL, *startobj = NULL;
     314             : 
     315           0 :     if (!PyArg_ParseTuple(args, "O&i|OOi:lockf",
     316             :                           conv_descriptor, &fd, &code,
     317             :                           &lenobj, &startobj, &whence))
     318           0 :         return NULL;
     319             : 
     320             : #if defined(PYOS_OS2) && defined(PYCC_GCC)
     321             :     PyErr_SetString(PyExc_NotImplementedError,
     322             :                     "lockf not supported on OS/2 (EMX)");
     323             :     return NULL;
     324             : #else
     325             : #ifndef LOCK_SH
     326             : #define LOCK_SH         1       /* shared lock */
     327             : #define LOCK_EX         2       /* exclusive lock */
     328             : #define LOCK_NB         4       /* don't block when locking */
     329             : #define LOCK_UN         8       /* unlock */
     330             : #endif  /* LOCK_SH */
     331             :     {
     332             :         struct flock l;
     333           0 :         if (code == LOCK_UN)
     334           0 :             l.l_type = F_UNLCK;
     335           0 :         else if (code & LOCK_SH)
     336           0 :             l.l_type = F_RDLCK;
     337           0 :         else if (code & LOCK_EX)
     338           0 :             l.l_type = F_WRLCK;
     339             :         else {
     340           0 :             PyErr_SetString(PyExc_ValueError,
     341             :                             "unrecognized lockf argument");
     342           0 :             return NULL;
     343             :         }
     344           0 :         l.l_start = l.l_len = 0;
     345           0 :         if (startobj != NULL) {
     346             : #if !defined(HAVE_LARGEFILE_SUPPORT)
     347           0 :             l.l_start = PyInt_AsLong(startobj);
     348             : #else
     349             :             l.l_start = PyLong_Check(startobj) ?
     350             :                             PyLong_AsLongLong(startobj) :
     351             :                     PyInt_AsLong(startobj);
     352             : #endif
     353           0 :             if (PyErr_Occurred())
     354           0 :                 return NULL;
     355             :         }
     356           0 :         if (lenobj != NULL) {
     357             : #if !defined(HAVE_LARGEFILE_SUPPORT)
     358           0 :             l.l_len = PyInt_AsLong(lenobj);
     359             : #else
     360             :             l.l_len = PyLong_Check(lenobj) ?
     361             :                             PyLong_AsLongLong(lenobj) :
     362             :                     PyInt_AsLong(lenobj);
     363             : #endif
     364           0 :             if (PyErr_Occurred())
     365           0 :                 return NULL;
     366             :         }
     367           0 :         l.l_whence = whence;
     368             :         Py_BEGIN_ALLOW_THREADS
     369           0 :         ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
     370             :         Py_END_ALLOW_THREADS
     371             :     }
     372           0 :     if (ret < 0) {
     373           0 :         PyErr_SetFromErrno(PyExc_IOError);
     374           0 :         return NULL;
     375             :     }
     376           0 :     Py_INCREF(Py_None);
     377           0 :     return Py_None;
     378             : #endif  /* defined(PYOS_OS2) && defined(PYCC_GCC) */
     379             : }
     380             : 
     381             : PyDoc_STRVAR(lockf_doc,
     382             : "lockf (fd, operation, length=0, start=0, whence=0)\n\
     383             : \n\
     384             : This is essentially a wrapper around the fcntl() locking calls.  fd is the\n\
     385             : file descriptor of the file to lock or unlock, and operation is one of the\n\
     386             : following values:\n\
     387             : \n\
     388             :     LOCK_UN - unlock\n\
     389             :     LOCK_SH - acquire a shared lock\n\
     390             :     LOCK_EX - acquire an exclusive lock\n\
     391             : \n\
     392             : When operation is LOCK_SH or LOCK_EX, it can also be bitwise ORed with\n\
     393             : LOCK_NB to avoid blocking on lock acquisition.  If LOCK_NB is used and the\n\
     394             : lock cannot be acquired, an IOError will be raised and the exception will\n\
     395             : have an errno attribute set to EACCES or EAGAIN (depending on the operating\n\
     396             : system -- for portability, check for either value).\n\
     397             : \n\
     398             : length is the number of bytes to lock, with the default meaning to lock to\n\
     399             : EOF.  start is the byte offset, relative to whence, to that the lock\n\
     400             : starts.  whence is as with fileobj.seek(), specifically:\n\
     401             : \n\
     402             :     0 - relative to the start of the file (SEEK_SET)\n\
     403             :     1 - relative to the current buffer position (SEEK_CUR)\n\
     404             :     2 - relative to the end of the file (SEEK_END)");
     405             : 
     406             : /* List of functions */
     407             : 
     408             : static PyMethodDef fcntl_methods[] = {
     409             :     {"fcntl",           fcntl_fcntl, METH_VARARGS, fcntl_doc},
     410             :     {"ioctl",           fcntl_ioctl, METH_VARARGS, ioctl_doc},
     411             :     {"flock",           fcntl_flock, METH_VARARGS, flock_doc},
     412             :     {"lockf",       fcntl_lockf, METH_VARARGS, lockf_doc},
     413             :     {NULL,              NULL}           /* sentinel */
     414             : };
     415             : 
     416             : 
     417             : PyDoc_STRVAR(module_doc,
     418             : "This module performs file control and I/O control on file \n\
     419             : descriptors.  It is an interface to the fcntl() and ioctl() Unix\n\
     420             : routines.  File descriptors can be obtained with the fileno() method of\n\
     421             : a file or socket object.");
     422             : 
     423             : /* Module initialisation */
     424             : 
     425             : static int
     426         207 : ins(PyObject* d, char* symbol, long value)
     427             : {
     428         207 :     PyObject* v = PyInt_FromLong(value);
     429         207 :     if (!v || PyDict_SetItemString(d, symbol, v) < 0)
     430           0 :         return -1;
     431             : 
     432         207 :     Py_DECREF(v);
     433         207 :     return 0;
     434             : }
     435             : 
     436             : #define INS(x) if (ins(d, #x, (long)x)) return -1
     437             : 
     438             : static int
     439           3 : all_ins(PyObject* d)
     440             : {
     441           3 :     if (ins(d, "LOCK_SH", (long)LOCK_SH)) return -1;
     442           3 :     if (ins(d, "LOCK_EX", (long)LOCK_EX)) return -1;
     443           3 :     if (ins(d, "LOCK_NB", (long)LOCK_NB)) return -1;
     444           3 :     if (ins(d, "LOCK_UN", (long)LOCK_UN)) return -1;
     445             : /* GNU extensions, as of glibc 2.2.4 */
     446             : #ifdef LOCK_MAND
     447           3 :     if (ins(d, "LOCK_MAND", (long)LOCK_MAND)) return -1;
     448             : #endif
     449             : #ifdef LOCK_READ
     450           3 :     if (ins(d, "LOCK_READ", (long)LOCK_READ)) return -1;
     451             : #endif
     452             : #ifdef LOCK_WRITE
     453           3 :     if (ins(d, "LOCK_WRITE", (long)LOCK_WRITE)) return -1;
     454             : #endif
     455             : #ifdef LOCK_RW
     456           3 :     if (ins(d, "LOCK_RW", (long)LOCK_RW)) return -1;
     457             : #endif
     458             : 
     459             : #ifdef F_DUPFD
     460           3 :     if (ins(d, "F_DUPFD", (long)F_DUPFD)) return -1;
     461             : #endif
     462             : #ifdef F_GETFD
     463           3 :     if (ins(d, "F_GETFD", (long)F_GETFD)) return -1;
     464             : #endif
     465             : #ifdef F_SETFD
     466           3 :     if (ins(d, "F_SETFD", (long)F_SETFD)) return -1;
     467             : #endif
     468             : #ifdef F_GETFL
     469           3 :     if (ins(d, "F_GETFL", (long)F_GETFL)) return -1;
     470             : #endif
     471             : #ifdef F_SETFL
     472           3 :     if (ins(d, "F_SETFL", (long)F_SETFL)) return -1;
     473             : #endif
     474             : #ifdef F_GETLK
     475           3 :     if (ins(d, "F_GETLK", (long)F_GETLK)) return -1;
     476             : #endif
     477             : #ifdef F_SETLK
     478           3 :     if (ins(d, "F_SETLK", (long)F_SETLK)) return -1;
     479             : #endif
     480             : #ifdef F_SETLKW
     481           3 :     if (ins(d, "F_SETLKW", (long)F_SETLKW)) return -1;
     482             : #endif
     483             : #ifdef F_GETOWN
     484           3 :     if (ins(d, "F_GETOWN", (long)F_GETOWN)) return -1;
     485             : #endif
     486             : #ifdef F_SETOWN
     487           3 :     if (ins(d, "F_SETOWN", (long)F_SETOWN)) return -1;
     488             : #endif
     489             : #ifdef F_GETSIG
     490           3 :     if (ins(d, "F_GETSIG", (long)F_GETSIG)) return -1;
     491             : #endif
     492             : #ifdef F_SETSIG
     493           3 :     if (ins(d, "F_SETSIG", (long)F_SETSIG)) return -1;
     494             : #endif
     495             : #ifdef F_RDLCK
     496           3 :     if (ins(d, "F_RDLCK", (long)F_RDLCK)) return -1;
     497             : #endif
     498             : #ifdef F_WRLCK
     499           3 :     if (ins(d, "F_WRLCK", (long)F_WRLCK)) return -1;
     500             : #endif
     501             : #ifdef F_UNLCK
     502           3 :     if (ins(d, "F_UNLCK", (long)F_UNLCK)) return -1;
     503             : #endif
     504             : /* LFS constants */
     505             : #ifdef F_GETLK64
     506           3 :     if (ins(d, "F_GETLK64", (long)F_GETLK64)) return -1;
     507             : #endif
     508             : #ifdef F_SETLK64
     509           3 :     if (ins(d, "F_SETLK64", (long)F_SETLK64)) return -1;
     510             : #endif
     511             : #ifdef F_SETLKW64
     512           3 :     if (ins(d, "F_SETLKW64", (long)F_SETLKW64)) return -1;
     513             : #endif
     514             : /* GNU extensions, as of glibc 2.2.4. */
     515             : #ifdef FASYNC
     516           3 :     if (ins(d, "FASYNC", (long)FASYNC)) return -1;
     517             : #endif
     518             : #ifdef F_SETLEASE
     519           3 :     if (ins(d, "F_SETLEASE", (long)F_SETLEASE)) return -1;
     520             : #endif
     521             : #ifdef F_GETLEASE
     522           3 :     if (ins(d, "F_GETLEASE", (long)F_GETLEASE)) return -1;
     523             : #endif
     524             : #ifdef F_NOTIFY
     525           3 :     if (ins(d, "F_NOTIFY", (long)F_NOTIFY)) return -1;
     526             : #endif
     527             : /* Old BSD flock(). */
     528             : #ifdef F_EXLCK
     529           3 :     if (ins(d, "F_EXLCK", (long)F_EXLCK)) return -1;
     530             : #endif
     531             : #ifdef F_SHLCK
     532           3 :     if (ins(d, "F_SHLCK", (long)F_SHLCK)) return -1;
     533             : #endif
     534             : 
     535             : /* OS X (and maybe others) let you tell the storage device to flush to physical media */
     536             : #ifdef F_FULLFSYNC
     537             :     if (ins(d, "F_FULLFSYNC", (long)F_FULLFSYNC)) return -1;
     538             : #endif
     539             : 
     540             : /* For F_{GET|SET}FL */
     541             : #ifdef FD_CLOEXEC
     542           3 :     if (ins(d, "FD_CLOEXEC", (long)FD_CLOEXEC)) return -1;
     543             : #endif
     544             : 
     545             : /* For F_NOTIFY */
     546             : #ifdef DN_ACCESS
     547           3 :     if (ins(d, "DN_ACCESS", (long)DN_ACCESS)) return -1;
     548             : #endif
     549             : #ifdef DN_MODIFY
     550           3 :     if (ins(d, "DN_MODIFY", (long)DN_MODIFY)) return -1;
     551             : #endif
     552             : #ifdef DN_CREATE
     553           3 :     if (ins(d, "DN_CREATE", (long)DN_CREATE)) return -1;
     554             : #endif
     555             : #ifdef DN_DELETE
     556           3 :     if (ins(d, "DN_DELETE", (long)DN_DELETE)) return -1;
     557             : #endif
     558             : #ifdef DN_RENAME
     559           3 :     if (ins(d, "DN_RENAME", (long)DN_RENAME)) return -1;
     560             : #endif
     561             : #ifdef DN_ATTRIB
     562           3 :     if (ins(d, "DN_ATTRIB", (long)DN_ATTRIB)) return -1;
     563             : #endif
     564             : #ifdef DN_MULTISHOT
     565           3 :     if (ins(d, "DN_MULTISHOT", (long)DN_MULTISHOT)) return -1;
     566             : #endif
     567             : 
     568             : #ifdef HAVE_STROPTS_H
     569             :     /* Unix 98 guarantees that these are in stropts.h. */
     570           3 :     INS(I_PUSH);
     571           3 :     INS(I_POP);
     572           3 :     INS(I_LOOK);
     573           3 :     INS(I_FLUSH);
     574           3 :     INS(I_FLUSHBAND);
     575           3 :     INS(I_SETSIG);
     576           3 :     INS(I_GETSIG);
     577           3 :     INS(I_FIND);
     578           3 :     INS(I_PEEK);
     579           3 :     INS(I_SRDOPT);
     580           3 :     INS(I_GRDOPT);
     581           3 :     INS(I_NREAD);
     582           3 :     INS(I_FDINSERT);
     583           3 :     INS(I_STR);
     584           3 :     INS(I_SWROPT);
     585             : #ifdef I_GWROPT
     586             :     /* despite the comment above, old-ish glibcs miss a couple... */
     587           3 :     INS(I_GWROPT);
     588             : #endif
     589           3 :     INS(I_SENDFD);
     590           3 :     INS(I_RECVFD);
     591           3 :     INS(I_LIST);
     592           3 :     INS(I_ATMARK);
     593           3 :     INS(I_CKBAND);
     594           3 :     INS(I_GETBAND);
     595           3 :     INS(I_CANPUT);
     596           3 :     INS(I_SETCLTIME);
     597             : #ifdef I_GETCLTIME
     598           3 :     INS(I_GETCLTIME);
     599             : #endif
     600           3 :     INS(I_LINK);
     601           3 :     INS(I_UNLINK);
     602           3 :     INS(I_PLINK);
     603           3 :     INS(I_PUNLINK);
     604             : #endif
     605             : 
     606           3 :     return 0;
     607             : }
     608             : 
     609             : PyMODINIT_FUNC
     610           3 : initfcntl(void)
     611             : {
     612             :     PyObject *m, *d;
     613             : 
     614             :     /* Create the module and add the functions and documentation */
     615           3 :     m = Py_InitModule3("fcntl", fcntl_methods, module_doc);
     616           3 :     if (m == NULL)
     617           3 :         return;
     618             : 
     619             :     /* Add some symbolic constants to the module */
     620           3 :     d = PyModule_GetDict(m);
     621           3 :     all_ins(d);
     622             : }

Generated by: LCOV version 1.10