17db96d56Sopenharmony_ci
27db96d56Sopenharmony_ci/* fcntl module */
37db96d56Sopenharmony_ci
47db96d56Sopenharmony_ci#define PY_SSIZE_T_CLEAN
57db96d56Sopenharmony_ci
67db96d56Sopenharmony_ci#include "Python.h"
77db96d56Sopenharmony_ci
87db96d56Sopenharmony_ci#ifdef HAVE_SYS_FILE_H
97db96d56Sopenharmony_ci#include <sys/file.h>
107db96d56Sopenharmony_ci#endif
117db96d56Sopenharmony_ci
127db96d56Sopenharmony_ci#include <sys/ioctl.h>
137db96d56Sopenharmony_ci#include <fcntl.h>
147db96d56Sopenharmony_ci#ifdef HAVE_STROPTS_H
157db96d56Sopenharmony_ci#include <stropts.h>
167db96d56Sopenharmony_ci#endif
177db96d56Sopenharmony_ci
187db96d56Sopenharmony_ci/*[clinic input]
197db96d56Sopenharmony_cimodule fcntl
207db96d56Sopenharmony_ci[clinic start generated code]*/
217db96d56Sopenharmony_ci/*[clinic end generated code: output=da39a3ee5e6b4b0d input=124b58387c158179]*/
227db96d56Sopenharmony_ci
237db96d56Sopenharmony_ci#include "clinic/fcntlmodule.c.h"
247db96d56Sopenharmony_ci
257db96d56Sopenharmony_ci/*[clinic input]
267db96d56Sopenharmony_cifcntl.fcntl
277db96d56Sopenharmony_ci
287db96d56Sopenharmony_ci    fd: fildes
297db96d56Sopenharmony_ci    cmd as code: int
307db96d56Sopenharmony_ci    arg: object(c_default='NULL') = 0
317db96d56Sopenharmony_ci    /
327db96d56Sopenharmony_ci
337db96d56Sopenharmony_ciPerform the operation `cmd` on file descriptor fd.
347db96d56Sopenharmony_ci
357db96d56Sopenharmony_ciThe values used for `cmd` are operating system dependent, and are available
367db96d56Sopenharmony_cias constants in the fcntl module, using the same names as used in
377db96d56Sopenharmony_cithe relevant C header files.  The argument arg is optional, and
387db96d56Sopenharmony_cidefaults to 0; it may be an int or a string.  If arg is given as a string,
397db96d56Sopenharmony_cithe return value of fcntl is a string of that length, containing the
407db96d56Sopenharmony_ciresulting value put in the arg buffer by the operating system.  The length
417db96d56Sopenharmony_ciof the arg string is not allowed to exceed 1024 bytes.  If the arg given
427db96d56Sopenharmony_ciis an integer or if none is specified, the result value is an integer
437db96d56Sopenharmony_cicorresponding to the return value of the fcntl call in the C code.
447db96d56Sopenharmony_ci[clinic start generated code]*/
457db96d56Sopenharmony_ci
467db96d56Sopenharmony_cistatic PyObject *
477db96d56Sopenharmony_cifcntl_fcntl_impl(PyObject *module, int fd, int code, PyObject *arg)
487db96d56Sopenharmony_ci/*[clinic end generated code: output=888fc93b51c295bd input=7955340198e5f334]*/
497db96d56Sopenharmony_ci{
507db96d56Sopenharmony_ci    unsigned int int_arg = 0;
517db96d56Sopenharmony_ci    int ret;
527db96d56Sopenharmony_ci    char *str;
537db96d56Sopenharmony_ci    Py_ssize_t len;
547db96d56Sopenharmony_ci    char buf[1024];
557db96d56Sopenharmony_ci    int async_err = 0;
567db96d56Sopenharmony_ci
577db96d56Sopenharmony_ci    if (PySys_Audit("fcntl.fcntl", "iiO", fd, code, arg ? arg : Py_None) < 0) {
587db96d56Sopenharmony_ci        return NULL;
597db96d56Sopenharmony_ci    }
607db96d56Sopenharmony_ci
617db96d56Sopenharmony_ci    if (arg != NULL) {
627db96d56Sopenharmony_ci        int parse_result;
637db96d56Sopenharmony_ci
647db96d56Sopenharmony_ci        if (PyArg_Parse(arg, "s#", &str, &len)) {
657db96d56Sopenharmony_ci            if ((size_t)len > sizeof buf) {
667db96d56Sopenharmony_ci                PyErr_SetString(PyExc_ValueError,
677db96d56Sopenharmony_ci                                "fcntl string arg too long");
687db96d56Sopenharmony_ci                return NULL;
697db96d56Sopenharmony_ci            }
707db96d56Sopenharmony_ci            memcpy(buf, str, len);
717db96d56Sopenharmony_ci            do {
727db96d56Sopenharmony_ci                Py_BEGIN_ALLOW_THREADS
737db96d56Sopenharmony_ci                ret = fcntl(fd, code, buf);
747db96d56Sopenharmony_ci                Py_END_ALLOW_THREADS
757db96d56Sopenharmony_ci            } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
767db96d56Sopenharmony_ci            if (ret < 0) {
777db96d56Sopenharmony_ci                return !async_err ? PyErr_SetFromErrno(PyExc_OSError) : NULL;
787db96d56Sopenharmony_ci            }
797db96d56Sopenharmony_ci            return PyBytes_FromStringAndSize(buf, len);
807db96d56Sopenharmony_ci        }
817db96d56Sopenharmony_ci
827db96d56Sopenharmony_ci        PyErr_Clear();
837db96d56Sopenharmony_ci        parse_result = PyArg_Parse(arg,
847db96d56Sopenharmony_ci            "I;fcntl requires a file or file descriptor,"
857db96d56Sopenharmony_ci            " an integer and optionally a third integer or a string",
867db96d56Sopenharmony_ci            &int_arg);
877db96d56Sopenharmony_ci        if (!parse_result) {
887db96d56Sopenharmony_ci          return NULL;
897db96d56Sopenharmony_ci        }
907db96d56Sopenharmony_ci    }
917db96d56Sopenharmony_ci
927db96d56Sopenharmony_ci    do {
937db96d56Sopenharmony_ci        Py_BEGIN_ALLOW_THREADS
947db96d56Sopenharmony_ci        ret = fcntl(fd, code, (int)int_arg);
957db96d56Sopenharmony_ci        Py_END_ALLOW_THREADS
967db96d56Sopenharmony_ci    } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
977db96d56Sopenharmony_ci    if (ret < 0) {
987db96d56Sopenharmony_ci        return !async_err ? PyErr_SetFromErrno(PyExc_OSError) : NULL;
997db96d56Sopenharmony_ci    }
1007db96d56Sopenharmony_ci    return PyLong_FromLong((long)ret);
1017db96d56Sopenharmony_ci}
1027db96d56Sopenharmony_ci
1037db96d56Sopenharmony_ci
1047db96d56Sopenharmony_ci/*[clinic input]
1057db96d56Sopenharmony_cifcntl.ioctl
1067db96d56Sopenharmony_ci
1077db96d56Sopenharmony_ci    fd: fildes
1087db96d56Sopenharmony_ci    request as code: unsigned_int(bitwise=True)
1097db96d56Sopenharmony_ci    arg as ob_arg: object(c_default='NULL') = 0
1107db96d56Sopenharmony_ci    mutate_flag as mutate_arg: bool = True
1117db96d56Sopenharmony_ci    /
1127db96d56Sopenharmony_ci
1137db96d56Sopenharmony_ciPerform the operation `request` on file descriptor `fd`.
1147db96d56Sopenharmony_ci
1157db96d56Sopenharmony_ciThe values used for `request` are operating system dependent, and are available
1167db96d56Sopenharmony_cias constants in the fcntl or termios library modules, using the same names as
1177db96d56Sopenharmony_ciused in the relevant C header files.
1187db96d56Sopenharmony_ci
1197db96d56Sopenharmony_ciThe argument `arg` is optional, and defaults to 0; it may be an int or a
1207db96d56Sopenharmony_cibuffer containing character data (most likely a string or an array).
1217db96d56Sopenharmony_ci
1227db96d56Sopenharmony_ciIf the argument is a mutable buffer (such as an array) and if the
1237db96d56Sopenharmony_cimutate_flag argument (which is only allowed in this case) is true then the
1247db96d56Sopenharmony_cibuffer is (in effect) passed to the operating system and changes made by
1257db96d56Sopenharmony_cithe OS will be reflected in the contents of the buffer after the call has
1267db96d56Sopenharmony_cireturned.  The return value is the integer returned by the ioctl system
1277db96d56Sopenharmony_cicall.
1287db96d56Sopenharmony_ci
1297db96d56Sopenharmony_ciIf the argument is a mutable buffer and the mutable_flag argument is false,
1307db96d56Sopenharmony_cithe behavior is as if a string had been passed.
1317db96d56Sopenharmony_ci
1327db96d56Sopenharmony_ciIf the argument is an immutable buffer (most likely a string) then a copy
1337db96d56Sopenharmony_ciof the buffer is passed to the operating system and the return value is a
1347db96d56Sopenharmony_cistring of the same length containing whatever the operating system put in
1357db96d56Sopenharmony_cithe buffer.  The length of the arg buffer in this case is not allowed to
1367db96d56Sopenharmony_ciexceed 1024 bytes.
1377db96d56Sopenharmony_ci
1387db96d56Sopenharmony_ciIf the arg given is an integer or if none is specified, the result value is
1397db96d56Sopenharmony_cian integer corresponding to the return value of the ioctl call in the C
1407db96d56Sopenharmony_cicode.
1417db96d56Sopenharmony_ci[clinic start generated code]*/
1427db96d56Sopenharmony_ci
1437db96d56Sopenharmony_cistatic PyObject *
1447db96d56Sopenharmony_cifcntl_ioctl_impl(PyObject *module, int fd, unsigned int code,
1457db96d56Sopenharmony_ci                 PyObject *ob_arg, int mutate_arg)
1467db96d56Sopenharmony_ci/*[clinic end generated code: output=7f7f5840c65991be input=967b4a4cbeceb0a8]*/
1477db96d56Sopenharmony_ci{
1487db96d56Sopenharmony_ci#define IOCTL_BUFSZ 1024
1497db96d56Sopenharmony_ci    /* We use the unsigned non-checked 'I' format for the 'code' parameter
1507db96d56Sopenharmony_ci       because the system expects it to be a 32bit bit field value
1517db96d56Sopenharmony_ci       regardless of it being passed as an int or unsigned long on
1527db96d56Sopenharmony_ci       various platforms.  See the termios.TIOCSWINSZ constant across
1537db96d56Sopenharmony_ci       platforms for an example of this.
1547db96d56Sopenharmony_ci
1557db96d56Sopenharmony_ci       If any of the 64bit platforms ever decide to use more than 32bits
1567db96d56Sopenharmony_ci       in their unsigned long ioctl codes this will break and need
1577db96d56Sopenharmony_ci       special casing based on the platform being built on.
1587db96d56Sopenharmony_ci     */
1597db96d56Sopenharmony_ci    int arg = 0;
1607db96d56Sopenharmony_ci    int ret;
1617db96d56Sopenharmony_ci    Py_buffer pstr;
1627db96d56Sopenharmony_ci    char *str;
1637db96d56Sopenharmony_ci    Py_ssize_t len;
1647db96d56Sopenharmony_ci    char buf[IOCTL_BUFSZ+1];  /* argument plus NUL byte */
1657db96d56Sopenharmony_ci
1667db96d56Sopenharmony_ci    if (PySys_Audit("fcntl.ioctl", "iIO", fd, code,
1677db96d56Sopenharmony_ci                    ob_arg ? ob_arg : Py_None) < 0) {
1687db96d56Sopenharmony_ci        return NULL;
1697db96d56Sopenharmony_ci    }
1707db96d56Sopenharmony_ci
1717db96d56Sopenharmony_ci    if (ob_arg != NULL) {
1727db96d56Sopenharmony_ci        if (PyArg_Parse(ob_arg, "w*:ioctl", &pstr)) {
1737db96d56Sopenharmony_ci            char *arg;
1747db96d56Sopenharmony_ci            str = pstr.buf;
1757db96d56Sopenharmony_ci            len = pstr.len;
1767db96d56Sopenharmony_ci
1777db96d56Sopenharmony_ci            if (mutate_arg) {
1787db96d56Sopenharmony_ci                if (len <= IOCTL_BUFSZ) {
1797db96d56Sopenharmony_ci                    memcpy(buf, str, len);
1807db96d56Sopenharmony_ci                    buf[len] = '\0';
1817db96d56Sopenharmony_ci                    arg = buf;
1827db96d56Sopenharmony_ci                }
1837db96d56Sopenharmony_ci                else {
1847db96d56Sopenharmony_ci                    arg = str;
1857db96d56Sopenharmony_ci                }
1867db96d56Sopenharmony_ci            }
1877db96d56Sopenharmony_ci            else {
1887db96d56Sopenharmony_ci                if (len > IOCTL_BUFSZ) {
1897db96d56Sopenharmony_ci                    PyBuffer_Release(&pstr);
1907db96d56Sopenharmony_ci                    PyErr_SetString(PyExc_ValueError,
1917db96d56Sopenharmony_ci                        "ioctl string arg too long");
1927db96d56Sopenharmony_ci                    return NULL;
1937db96d56Sopenharmony_ci                }
1947db96d56Sopenharmony_ci                else {
1957db96d56Sopenharmony_ci                    memcpy(buf, str, len);
1967db96d56Sopenharmony_ci                    buf[len] = '\0';
1977db96d56Sopenharmony_ci                    arg = buf;
1987db96d56Sopenharmony_ci                }
1997db96d56Sopenharmony_ci            }
2007db96d56Sopenharmony_ci            if (buf == arg) {
2017db96d56Sopenharmony_ci                Py_BEGIN_ALLOW_THREADS /* think array.resize() */
2027db96d56Sopenharmony_ci                ret = ioctl(fd, code, arg);
2037db96d56Sopenharmony_ci                Py_END_ALLOW_THREADS
2047db96d56Sopenharmony_ci            }
2057db96d56Sopenharmony_ci            else {
2067db96d56Sopenharmony_ci                ret = ioctl(fd, code, arg);
2077db96d56Sopenharmony_ci            }
2087db96d56Sopenharmony_ci            if (mutate_arg && (len <= IOCTL_BUFSZ)) {
2097db96d56Sopenharmony_ci                memcpy(str, buf, len);
2107db96d56Sopenharmony_ci            }
2117db96d56Sopenharmony_ci            PyBuffer_Release(&pstr); /* No further access to str below this point */
2127db96d56Sopenharmony_ci            if (ret < 0) {
2137db96d56Sopenharmony_ci                PyErr_SetFromErrno(PyExc_OSError);
2147db96d56Sopenharmony_ci                return NULL;
2157db96d56Sopenharmony_ci            }
2167db96d56Sopenharmony_ci            if (mutate_arg) {
2177db96d56Sopenharmony_ci                return PyLong_FromLong(ret);
2187db96d56Sopenharmony_ci            }
2197db96d56Sopenharmony_ci            else {
2207db96d56Sopenharmony_ci                return PyBytes_FromStringAndSize(buf, len);
2217db96d56Sopenharmony_ci            }
2227db96d56Sopenharmony_ci        }
2237db96d56Sopenharmony_ci
2247db96d56Sopenharmony_ci        PyErr_Clear();
2257db96d56Sopenharmony_ci        if (PyArg_Parse(ob_arg, "s*:ioctl", &pstr)) {
2267db96d56Sopenharmony_ci            str = pstr.buf;
2277db96d56Sopenharmony_ci            len = pstr.len;
2287db96d56Sopenharmony_ci            if (len > IOCTL_BUFSZ) {
2297db96d56Sopenharmony_ci                PyBuffer_Release(&pstr);
2307db96d56Sopenharmony_ci                PyErr_SetString(PyExc_ValueError,
2317db96d56Sopenharmony_ci                                "ioctl string arg too long");
2327db96d56Sopenharmony_ci                return NULL;
2337db96d56Sopenharmony_ci            }
2347db96d56Sopenharmony_ci            memcpy(buf, str, len);
2357db96d56Sopenharmony_ci            buf[len] = '\0';
2367db96d56Sopenharmony_ci            Py_BEGIN_ALLOW_THREADS
2377db96d56Sopenharmony_ci            ret = ioctl(fd, code, buf);
2387db96d56Sopenharmony_ci            Py_END_ALLOW_THREADS
2397db96d56Sopenharmony_ci            if (ret < 0) {
2407db96d56Sopenharmony_ci                PyBuffer_Release(&pstr);
2417db96d56Sopenharmony_ci                PyErr_SetFromErrno(PyExc_OSError);
2427db96d56Sopenharmony_ci                return NULL;
2437db96d56Sopenharmony_ci            }
2447db96d56Sopenharmony_ci            PyBuffer_Release(&pstr);
2457db96d56Sopenharmony_ci            return PyBytes_FromStringAndSize(buf, len);
2467db96d56Sopenharmony_ci        }
2477db96d56Sopenharmony_ci
2487db96d56Sopenharmony_ci        PyErr_Clear();
2497db96d56Sopenharmony_ci        if (!PyArg_Parse(ob_arg,
2507db96d56Sopenharmony_ci             "i;ioctl requires a file or file descriptor,"
2517db96d56Sopenharmony_ci             " an integer and optionally an integer or buffer argument",
2527db96d56Sopenharmony_ci             &arg)) {
2537db96d56Sopenharmony_ci          return NULL;
2547db96d56Sopenharmony_ci        }
2557db96d56Sopenharmony_ci        // Fall-through to outside the 'if' statement.
2567db96d56Sopenharmony_ci    }
2577db96d56Sopenharmony_ci    Py_BEGIN_ALLOW_THREADS
2587db96d56Sopenharmony_ci    ret = ioctl(fd, code, arg);
2597db96d56Sopenharmony_ci    Py_END_ALLOW_THREADS
2607db96d56Sopenharmony_ci    if (ret < 0) {
2617db96d56Sopenharmony_ci        PyErr_SetFromErrno(PyExc_OSError);
2627db96d56Sopenharmony_ci        return NULL;
2637db96d56Sopenharmony_ci    }
2647db96d56Sopenharmony_ci    return PyLong_FromLong((long)ret);
2657db96d56Sopenharmony_ci#undef IOCTL_BUFSZ
2667db96d56Sopenharmony_ci}
2677db96d56Sopenharmony_ci
2687db96d56Sopenharmony_ci/*[clinic input]
2697db96d56Sopenharmony_cifcntl.flock
2707db96d56Sopenharmony_ci
2717db96d56Sopenharmony_ci    fd: fildes
2727db96d56Sopenharmony_ci    operation as code: int
2737db96d56Sopenharmony_ci    /
2747db96d56Sopenharmony_ci
2757db96d56Sopenharmony_ciPerform the lock operation `operation` on file descriptor `fd`.
2767db96d56Sopenharmony_ci
2777db96d56Sopenharmony_ciSee the Unix manual page for flock(2) for details (On some systems, this
2787db96d56Sopenharmony_cifunction is emulated using fcntl()).
2797db96d56Sopenharmony_ci[clinic start generated code]*/
2807db96d56Sopenharmony_ci
2817db96d56Sopenharmony_cistatic PyObject *
2827db96d56Sopenharmony_cifcntl_flock_impl(PyObject *module, int fd, int code)
2837db96d56Sopenharmony_ci/*[clinic end generated code: output=84059e2b37d2fc64 input=0bfc00f795953452]*/
2847db96d56Sopenharmony_ci{
2857db96d56Sopenharmony_ci    int ret;
2867db96d56Sopenharmony_ci    int async_err = 0;
2877db96d56Sopenharmony_ci
2887db96d56Sopenharmony_ci    if (PySys_Audit("fcntl.flock", "ii", fd, code) < 0) {
2897db96d56Sopenharmony_ci        return NULL;
2907db96d56Sopenharmony_ci    }
2917db96d56Sopenharmony_ci
2927db96d56Sopenharmony_ci#ifdef HAVE_FLOCK
2937db96d56Sopenharmony_ci    do {
2947db96d56Sopenharmony_ci        Py_BEGIN_ALLOW_THREADS
2957db96d56Sopenharmony_ci        ret = flock(fd, code);
2967db96d56Sopenharmony_ci        Py_END_ALLOW_THREADS
2977db96d56Sopenharmony_ci    } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
2987db96d56Sopenharmony_ci#else
2997db96d56Sopenharmony_ci
3007db96d56Sopenharmony_ci#ifndef LOCK_SH
3017db96d56Sopenharmony_ci#define LOCK_SH         1       /* shared lock */
3027db96d56Sopenharmony_ci#define LOCK_EX         2       /* exclusive lock */
3037db96d56Sopenharmony_ci#define LOCK_NB         4       /* don't block when locking */
3047db96d56Sopenharmony_ci#define LOCK_UN         8       /* unlock */
3057db96d56Sopenharmony_ci#endif
3067db96d56Sopenharmony_ci    {
3077db96d56Sopenharmony_ci        struct flock l;
3087db96d56Sopenharmony_ci        if (code == LOCK_UN)
3097db96d56Sopenharmony_ci            l.l_type = F_UNLCK;
3107db96d56Sopenharmony_ci        else if (code & LOCK_SH)
3117db96d56Sopenharmony_ci            l.l_type = F_RDLCK;
3127db96d56Sopenharmony_ci        else if (code & LOCK_EX)
3137db96d56Sopenharmony_ci            l.l_type = F_WRLCK;
3147db96d56Sopenharmony_ci        else {
3157db96d56Sopenharmony_ci            PyErr_SetString(PyExc_ValueError,
3167db96d56Sopenharmony_ci                            "unrecognized flock argument");
3177db96d56Sopenharmony_ci            return NULL;
3187db96d56Sopenharmony_ci        }
3197db96d56Sopenharmony_ci        l.l_whence = l.l_start = l.l_len = 0;
3207db96d56Sopenharmony_ci        do {
3217db96d56Sopenharmony_ci            Py_BEGIN_ALLOW_THREADS
3227db96d56Sopenharmony_ci            ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
3237db96d56Sopenharmony_ci            Py_END_ALLOW_THREADS
3247db96d56Sopenharmony_ci        } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3257db96d56Sopenharmony_ci    }
3267db96d56Sopenharmony_ci#endif /* HAVE_FLOCK */
3277db96d56Sopenharmony_ci    if (ret < 0) {
3287db96d56Sopenharmony_ci        return !async_err ? PyErr_SetFromErrno(PyExc_OSError) : NULL;
3297db96d56Sopenharmony_ci    }
3307db96d56Sopenharmony_ci    Py_RETURN_NONE;
3317db96d56Sopenharmony_ci}
3327db96d56Sopenharmony_ci
3337db96d56Sopenharmony_ci
3347db96d56Sopenharmony_ci/*[clinic input]
3357db96d56Sopenharmony_cifcntl.lockf
3367db96d56Sopenharmony_ci
3377db96d56Sopenharmony_ci    fd: fildes
3387db96d56Sopenharmony_ci    cmd as code: int
3397db96d56Sopenharmony_ci    len as lenobj: object(c_default='NULL') = 0
3407db96d56Sopenharmony_ci    start as startobj: object(c_default='NULL') = 0
3417db96d56Sopenharmony_ci    whence: int = 0
3427db96d56Sopenharmony_ci    /
3437db96d56Sopenharmony_ci
3447db96d56Sopenharmony_ciA wrapper around the fcntl() locking calls.
3457db96d56Sopenharmony_ci
3467db96d56Sopenharmony_ci`fd` is the file descriptor of the file to lock or unlock, and operation is one
3477db96d56Sopenharmony_ciof the following values:
3487db96d56Sopenharmony_ci
3497db96d56Sopenharmony_ci    LOCK_UN - unlock
3507db96d56Sopenharmony_ci    LOCK_SH - acquire a shared lock
3517db96d56Sopenharmony_ci    LOCK_EX - acquire an exclusive lock
3527db96d56Sopenharmony_ci
3537db96d56Sopenharmony_ciWhen operation is LOCK_SH or LOCK_EX, it can also be bitwise ORed with
3547db96d56Sopenharmony_ciLOCK_NB to avoid blocking on lock acquisition.  If LOCK_NB is used and the
3557db96d56Sopenharmony_cilock cannot be acquired, an OSError will be raised and the exception will
3567db96d56Sopenharmony_cihave an errno attribute set to EACCES or EAGAIN (depending on the operating
3577db96d56Sopenharmony_cisystem -- for portability, check for either value).
3587db96d56Sopenharmony_ci
3597db96d56Sopenharmony_ci`len` is the number of bytes to lock, with the default meaning to lock to
3607db96d56Sopenharmony_ciEOF.  `start` is the byte offset, relative to `whence`, to that the lock
3617db96d56Sopenharmony_cistarts.  `whence` is as with fileobj.seek(), specifically:
3627db96d56Sopenharmony_ci
3637db96d56Sopenharmony_ci    0 - relative to the start of the file (SEEK_SET)
3647db96d56Sopenharmony_ci    1 - relative to the current buffer position (SEEK_CUR)
3657db96d56Sopenharmony_ci    2 - relative to the end of the file (SEEK_END)
3667db96d56Sopenharmony_ci[clinic start generated code]*/
3677db96d56Sopenharmony_ci
3687db96d56Sopenharmony_cistatic PyObject *
3697db96d56Sopenharmony_cifcntl_lockf_impl(PyObject *module, int fd, int code, PyObject *lenobj,
3707db96d56Sopenharmony_ci                 PyObject *startobj, int whence)
3717db96d56Sopenharmony_ci/*[clinic end generated code: output=4985e7a172e7461a input=5480479fc63a04b8]*/
3727db96d56Sopenharmony_ci{
3737db96d56Sopenharmony_ci    int ret;
3747db96d56Sopenharmony_ci    int async_err = 0;
3757db96d56Sopenharmony_ci
3767db96d56Sopenharmony_ci    if (PySys_Audit("fcntl.lockf", "iiOOi", fd, code, lenobj ? lenobj : Py_None,
3777db96d56Sopenharmony_ci                    startobj ? startobj : Py_None, whence) < 0) {
3787db96d56Sopenharmony_ci        return NULL;
3797db96d56Sopenharmony_ci    }
3807db96d56Sopenharmony_ci
3817db96d56Sopenharmony_ci#ifndef LOCK_SH
3827db96d56Sopenharmony_ci#define LOCK_SH         1       /* shared lock */
3837db96d56Sopenharmony_ci#define LOCK_EX         2       /* exclusive lock */
3847db96d56Sopenharmony_ci#define LOCK_NB         4       /* don't block when locking */
3857db96d56Sopenharmony_ci#define LOCK_UN         8       /* unlock */
3867db96d56Sopenharmony_ci#endif  /* LOCK_SH */
3877db96d56Sopenharmony_ci    {
3887db96d56Sopenharmony_ci        struct flock l;
3897db96d56Sopenharmony_ci        if (code == LOCK_UN)
3907db96d56Sopenharmony_ci            l.l_type = F_UNLCK;
3917db96d56Sopenharmony_ci        else if (code & LOCK_SH)
3927db96d56Sopenharmony_ci            l.l_type = F_RDLCK;
3937db96d56Sopenharmony_ci        else if (code & LOCK_EX)
3947db96d56Sopenharmony_ci            l.l_type = F_WRLCK;
3957db96d56Sopenharmony_ci        else {
3967db96d56Sopenharmony_ci            PyErr_SetString(PyExc_ValueError,
3977db96d56Sopenharmony_ci                            "unrecognized lockf argument");
3987db96d56Sopenharmony_ci            return NULL;
3997db96d56Sopenharmony_ci        }
4007db96d56Sopenharmony_ci        l.l_start = l.l_len = 0;
4017db96d56Sopenharmony_ci        if (startobj != NULL) {
4027db96d56Sopenharmony_ci#if !defined(HAVE_LARGEFILE_SUPPORT)
4037db96d56Sopenharmony_ci            l.l_start = PyLong_AsLong(startobj);
4047db96d56Sopenharmony_ci#else
4057db96d56Sopenharmony_ci            l.l_start = PyLong_Check(startobj) ?
4067db96d56Sopenharmony_ci                            PyLong_AsLongLong(startobj) :
4077db96d56Sopenharmony_ci                    PyLong_AsLong(startobj);
4087db96d56Sopenharmony_ci#endif
4097db96d56Sopenharmony_ci            if (PyErr_Occurred())
4107db96d56Sopenharmony_ci                return NULL;
4117db96d56Sopenharmony_ci        }
4127db96d56Sopenharmony_ci        if (lenobj != NULL) {
4137db96d56Sopenharmony_ci#if !defined(HAVE_LARGEFILE_SUPPORT)
4147db96d56Sopenharmony_ci            l.l_len = PyLong_AsLong(lenobj);
4157db96d56Sopenharmony_ci#else
4167db96d56Sopenharmony_ci            l.l_len = PyLong_Check(lenobj) ?
4177db96d56Sopenharmony_ci                            PyLong_AsLongLong(lenobj) :
4187db96d56Sopenharmony_ci                    PyLong_AsLong(lenobj);
4197db96d56Sopenharmony_ci#endif
4207db96d56Sopenharmony_ci            if (PyErr_Occurred())
4217db96d56Sopenharmony_ci                return NULL;
4227db96d56Sopenharmony_ci        }
4237db96d56Sopenharmony_ci        l.l_whence = whence;
4247db96d56Sopenharmony_ci        do {
4257db96d56Sopenharmony_ci            Py_BEGIN_ALLOW_THREADS
4267db96d56Sopenharmony_ci            ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
4277db96d56Sopenharmony_ci            Py_END_ALLOW_THREADS
4287db96d56Sopenharmony_ci        } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
4297db96d56Sopenharmony_ci    }
4307db96d56Sopenharmony_ci    if (ret < 0) {
4317db96d56Sopenharmony_ci        return !async_err ? PyErr_SetFromErrno(PyExc_OSError) : NULL;
4327db96d56Sopenharmony_ci    }
4337db96d56Sopenharmony_ci    Py_RETURN_NONE;
4347db96d56Sopenharmony_ci}
4357db96d56Sopenharmony_ci
4367db96d56Sopenharmony_ci/* List of functions */
4377db96d56Sopenharmony_ci
4387db96d56Sopenharmony_cistatic PyMethodDef fcntl_methods[] = {
4397db96d56Sopenharmony_ci    FCNTL_FCNTL_METHODDEF
4407db96d56Sopenharmony_ci    FCNTL_IOCTL_METHODDEF
4417db96d56Sopenharmony_ci    FCNTL_FLOCK_METHODDEF
4427db96d56Sopenharmony_ci    FCNTL_LOCKF_METHODDEF
4437db96d56Sopenharmony_ci    {NULL, NULL}  /* sentinel */
4447db96d56Sopenharmony_ci};
4457db96d56Sopenharmony_ci
4467db96d56Sopenharmony_ci
4477db96d56Sopenharmony_ciPyDoc_STRVAR(module_doc,
4487db96d56Sopenharmony_ci"This module performs file control and I/O control on file\n\
4497db96d56Sopenharmony_cidescriptors.  It is an interface to the fcntl() and ioctl() Unix\n\
4507db96d56Sopenharmony_ciroutines.  File descriptors can be obtained with the fileno() method of\n\
4517db96d56Sopenharmony_cia file or socket object.");
4527db96d56Sopenharmony_ci
4537db96d56Sopenharmony_ci/* Module initialisation */
4547db96d56Sopenharmony_ci
4557db96d56Sopenharmony_ci
4567db96d56Sopenharmony_cistatic int
4577db96d56Sopenharmony_ciall_ins(PyObject* m)
4587db96d56Sopenharmony_ci{
4597db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, LOCK_SH)) return -1;
4607db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, LOCK_EX)) return -1;
4617db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, LOCK_NB)) return -1;
4627db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, LOCK_UN)) return -1;
4637db96d56Sopenharmony_ci/* GNU extensions, as of glibc 2.2.4 */
4647db96d56Sopenharmony_ci#ifdef LOCK_MAND
4657db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, LOCK_MAND)) return -1;
4667db96d56Sopenharmony_ci#endif
4677db96d56Sopenharmony_ci#ifdef LOCK_READ
4687db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, LOCK_READ)) return -1;
4697db96d56Sopenharmony_ci#endif
4707db96d56Sopenharmony_ci#ifdef LOCK_WRITE
4717db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, LOCK_WRITE)) return -1;
4727db96d56Sopenharmony_ci#endif
4737db96d56Sopenharmony_ci#ifdef LOCK_RW
4747db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, LOCK_RW)) return -1;
4757db96d56Sopenharmony_ci#endif
4767db96d56Sopenharmony_ci
4777db96d56Sopenharmony_ci#ifdef F_DUPFD
4787db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, F_DUPFD)) return -1;
4797db96d56Sopenharmony_ci#endif
4807db96d56Sopenharmony_ci#ifdef F_DUPFD_CLOEXEC
4817db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, F_DUPFD_CLOEXEC)) return -1;
4827db96d56Sopenharmony_ci#endif
4837db96d56Sopenharmony_ci#ifdef F_GETFD
4847db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, F_GETFD)) return -1;
4857db96d56Sopenharmony_ci#endif
4867db96d56Sopenharmony_ci#ifdef F_SETFD
4877db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, F_SETFD)) return -1;
4887db96d56Sopenharmony_ci#endif
4897db96d56Sopenharmony_ci#ifdef F_GETFL
4907db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, F_GETFL)) return -1;
4917db96d56Sopenharmony_ci#endif
4927db96d56Sopenharmony_ci#ifdef F_SETFL
4937db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, F_SETFL)) return -1;
4947db96d56Sopenharmony_ci#endif
4957db96d56Sopenharmony_ci#ifdef F_GETLK
4967db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, F_GETLK)) return -1;
4977db96d56Sopenharmony_ci#endif
4987db96d56Sopenharmony_ci#ifdef F_SETLK
4997db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, F_SETLK)) return -1;
5007db96d56Sopenharmony_ci#endif
5017db96d56Sopenharmony_ci#ifdef F_SETLKW
5027db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, F_SETLKW)) return -1;
5037db96d56Sopenharmony_ci#endif
5047db96d56Sopenharmony_ci#ifdef F_OFD_GETLK
5057db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, F_OFD_GETLK)) return -1;
5067db96d56Sopenharmony_ci#endif
5077db96d56Sopenharmony_ci#ifdef F_OFD_SETLK
5087db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, F_OFD_SETLK)) return -1;
5097db96d56Sopenharmony_ci#endif
5107db96d56Sopenharmony_ci#ifdef F_OFD_SETLKW
5117db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, F_OFD_SETLKW)) return -1;
5127db96d56Sopenharmony_ci#endif
5137db96d56Sopenharmony_ci#ifdef F_GETOWN
5147db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, F_GETOWN)) return -1;
5157db96d56Sopenharmony_ci#endif
5167db96d56Sopenharmony_ci#ifdef F_SETOWN
5177db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, F_SETOWN)) return -1;
5187db96d56Sopenharmony_ci#endif
5197db96d56Sopenharmony_ci#ifdef F_GETPATH
5207db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, F_GETPATH)) return -1;
5217db96d56Sopenharmony_ci#endif
5227db96d56Sopenharmony_ci#ifdef F_GETSIG
5237db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, F_GETSIG)) return -1;
5247db96d56Sopenharmony_ci#endif
5257db96d56Sopenharmony_ci#ifdef F_SETSIG
5267db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, F_SETSIG)) return -1;
5277db96d56Sopenharmony_ci#endif
5287db96d56Sopenharmony_ci#ifdef F_RDLCK
5297db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, F_RDLCK)) return -1;
5307db96d56Sopenharmony_ci#endif
5317db96d56Sopenharmony_ci#ifdef F_WRLCK
5327db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, F_WRLCK)) return -1;
5337db96d56Sopenharmony_ci#endif
5347db96d56Sopenharmony_ci#ifdef F_UNLCK
5357db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, F_UNLCK)) return -1;
5367db96d56Sopenharmony_ci#endif
5377db96d56Sopenharmony_ci/* LFS constants */
5387db96d56Sopenharmony_ci#ifdef F_GETLK64
5397db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, F_GETLK64)) return -1;
5407db96d56Sopenharmony_ci#endif
5417db96d56Sopenharmony_ci#ifdef F_SETLK64
5427db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, F_SETLK64)) return -1;
5437db96d56Sopenharmony_ci#endif
5447db96d56Sopenharmony_ci#ifdef F_SETLKW64
5457db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, F_SETLKW64)) return -1;
5467db96d56Sopenharmony_ci#endif
5477db96d56Sopenharmony_ci/* GNU extensions, as of glibc 2.2.4. */
5487db96d56Sopenharmony_ci#ifdef FASYNC
5497db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, FASYNC)) return -1;
5507db96d56Sopenharmony_ci#endif
5517db96d56Sopenharmony_ci#ifdef F_SETLEASE
5527db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, F_SETLEASE)) return -1;
5537db96d56Sopenharmony_ci#endif
5547db96d56Sopenharmony_ci#ifdef F_GETLEASE
5557db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, F_GETLEASE)) return -1;
5567db96d56Sopenharmony_ci#endif
5577db96d56Sopenharmony_ci#ifdef F_NOTIFY
5587db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, F_NOTIFY)) return -1;
5597db96d56Sopenharmony_ci#endif
5607db96d56Sopenharmony_ci/* Old BSD flock(). */
5617db96d56Sopenharmony_ci#ifdef F_EXLCK
5627db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, F_EXLCK)) return -1;
5637db96d56Sopenharmony_ci#endif
5647db96d56Sopenharmony_ci#ifdef F_SHLCK
5657db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, F_SHLCK)) return -1;
5667db96d56Sopenharmony_ci#endif
5677db96d56Sopenharmony_ci
5687db96d56Sopenharmony_ci/* Linux specifics */
5697db96d56Sopenharmony_ci#ifdef F_SETPIPE_SZ
5707db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, F_SETPIPE_SZ)) return -1;
5717db96d56Sopenharmony_ci#endif
5727db96d56Sopenharmony_ci#ifdef F_GETPIPE_SZ
5737db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, F_GETPIPE_SZ)) return -1;
5747db96d56Sopenharmony_ci#endif
5757db96d56Sopenharmony_ci
5767db96d56Sopenharmony_ci/* OS X specifics */
5777db96d56Sopenharmony_ci#ifdef F_FULLFSYNC
5787db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, F_FULLFSYNC)) return -1;
5797db96d56Sopenharmony_ci#endif
5807db96d56Sopenharmony_ci#ifdef F_NOCACHE
5817db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, F_NOCACHE)) return -1;
5827db96d56Sopenharmony_ci#endif
5837db96d56Sopenharmony_ci
5847db96d56Sopenharmony_ci/* FreeBSD specifics */
5857db96d56Sopenharmony_ci#ifdef F_DUP2FD
5867db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, F_DUP2FD)) return -1;
5877db96d56Sopenharmony_ci#endif
5887db96d56Sopenharmony_ci#ifdef F_DUP2FD_CLOEXEC
5897db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, F_DUP2FD_CLOEXEC)) return -1;
5907db96d56Sopenharmony_ci#endif
5917db96d56Sopenharmony_ci
5927db96d56Sopenharmony_ci/* For F_{GET|SET}FL */
5937db96d56Sopenharmony_ci#ifdef FD_CLOEXEC
5947db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, FD_CLOEXEC)) return -1;
5957db96d56Sopenharmony_ci#endif
5967db96d56Sopenharmony_ci
5977db96d56Sopenharmony_ci/* For F_NOTIFY */
5987db96d56Sopenharmony_ci#ifdef DN_ACCESS
5997db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, DN_ACCESS)) return -1;
6007db96d56Sopenharmony_ci#endif
6017db96d56Sopenharmony_ci#ifdef DN_MODIFY
6027db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, DN_MODIFY)) return -1;
6037db96d56Sopenharmony_ci#endif
6047db96d56Sopenharmony_ci#ifdef DN_CREATE
6057db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, DN_CREATE)) return -1;
6067db96d56Sopenharmony_ci#endif
6077db96d56Sopenharmony_ci#ifdef DN_DELETE
6087db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, DN_DELETE)) return -1;
6097db96d56Sopenharmony_ci#endif
6107db96d56Sopenharmony_ci#ifdef DN_RENAME
6117db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, DN_RENAME)) return -1;
6127db96d56Sopenharmony_ci#endif
6137db96d56Sopenharmony_ci#ifdef DN_ATTRIB
6147db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, DN_ATTRIB)) return -1;
6157db96d56Sopenharmony_ci#endif
6167db96d56Sopenharmony_ci#ifdef DN_MULTISHOT
6177db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, DN_MULTISHOT)) return -1;
6187db96d56Sopenharmony_ci#endif
6197db96d56Sopenharmony_ci
6207db96d56Sopenharmony_ci#ifdef HAVE_STROPTS_H
6217db96d56Sopenharmony_ci    /* Unix 98 guarantees that these are in stropts.h. */
6227db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, I_PUSH)) return -1;
6237db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, I_POP)) return -1;
6247db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, I_LOOK)) return -1;
6257db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, I_FLUSH)) return -1;
6267db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, I_FLUSHBAND)) return -1;
6277db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, I_SETSIG)) return -1;
6287db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, I_GETSIG)) return -1;
6297db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, I_FIND)) return -1;
6307db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, I_PEEK)) return -1;
6317db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, I_SRDOPT)) return -1;
6327db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, I_GRDOPT)) return -1;
6337db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, I_NREAD)) return -1;
6347db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, I_FDINSERT)) return -1;
6357db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, I_STR)) return -1;
6367db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, I_SWROPT)) return -1;
6377db96d56Sopenharmony_ci#ifdef I_GWROPT
6387db96d56Sopenharmony_ci    /* despite the comment above, old-ish glibcs miss a couple... */
6397db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, I_GWROPT)) return -1;
6407db96d56Sopenharmony_ci#endif
6417db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, I_SENDFD)) return -1;
6427db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, I_RECVFD)) return -1;
6437db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, I_LIST)) return -1;
6447db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, I_ATMARK)) return -1;
6457db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, I_CKBAND)) return -1;
6467db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, I_GETBAND)) return -1;
6477db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, I_CANPUT)) return -1;
6487db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, I_SETCLTIME)) return -1;
6497db96d56Sopenharmony_ci#ifdef I_GETCLTIME
6507db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, I_GETCLTIME)) return -1;
6517db96d56Sopenharmony_ci#endif
6527db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, I_LINK)) return -1;
6537db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, I_UNLINK)) return -1;
6547db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, I_PLINK)) return -1;
6557db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, I_PUNLINK)) return -1;
6567db96d56Sopenharmony_ci#endif
6577db96d56Sopenharmony_ci#ifdef F_ADD_SEALS
6587db96d56Sopenharmony_ci    /* Linux: file sealing for memfd_create() */
6597db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, F_ADD_SEALS)) return -1;
6607db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, F_GET_SEALS)) return -1;
6617db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, F_SEAL_SEAL)) return -1;
6627db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, F_SEAL_SHRINK)) return -1;
6637db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, F_SEAL_GROW)) return -1;
6647db96d56Sopenharmony_ci    if (PyModule_AddIntMacro(m, F_SEAL_WRITE)) return -1;
6657db96d56Sopenharmony_ci#endif
6667db96d56Sopenharmony_ci    return 0;
6677db96d56Sopenharmony_ci}
6687db96d56Sopenharmony_ci
6697db96d56Sopenharmony_cistatic int
6707db96d56Sopenharmony_cifcntl_exec(PyObject *module)
6717db96d56Sopenharmony_ci{
6727db96d56Sopenharmony_ci    if (all_ins(module) < 0) {
6737db96d56Sopenharmony_ci        return -1;
6747db96d56Sopenharmony_ci    }
6757db96d56Sopenharmony_ci    return 0;
6767db96d56Sopenharmony_ci}
6777db96d56Sopenharmony_ci
6787db96d56Sopenharmony_cistatic PyModuleDef_Slot fcntl_slots[] = {
6797db96d56Sopenharmony_ci    {Py_mod_exec, fcntl_exec},
6807db96d56Sopenharmony_ci    {0, NULL}
6817db96d56Sopenharmony_ci};
6827db96d56Sopenharmony_ci
6837db96d56Sopenharmony_cistatic struct PyModuleDef fcntlmodule = {
6847db96d56Sopenharmony_ci    PyModuleDef_HEAD_INIT,
6857db96d56Sopenharmony_ci    .m_name = "fcntl",
6867db96d56Sopenharmony_ci    .m_doc = module_doc,
6877db96d56Sopenharmony_ci    .m_size = 0,
6887db96d56Sopenharmony_ci    .m_methods = fcntl_methods,
6897db96d56Sopenharmony_ci    .m_slots = fcntl_slots,
6907db96d56Sopenharmony_ci};
6917db96d56Sopenharmony_ci
6927db96d56Sopenharmony_ciPyMODINIT_FUNC
6937db96d56Sopenharmony_ciPyInit_fcntl(void)
6947db96d56Sopenharmony_ci{
6957db96d56Sopenharmony_ci    return PyModuleDef_Init(&fcntlmodule);
6967db96d56Sopenharmony_ci}
697