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