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]
19 module 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]
26 fcntl.fcntl
27 
28     fd: fildes
29     cmd as code: int
30     arg: object(c_default='NULL') = 0
31     /
32 
33 Perform the operation `cmd` on file descriptor fd.
34 
35 The values used for `cmd` are operating system dependent, and are available
36 as constants in the fcntl module, using the same names as used in
37 the relevant C header files.  The argument arg is optional, and
38 defaults to 0; it may be an int or a string.  If arg is given as a string,
39 the return value of fcntl is a string of that length, containing the
40 resulting value put in the arg buffer by the operating system.  The length
41 of the arg string is not allowed to exceed 1024 bytes.  If the arg given
42 is an integer or if none is specified, the result value is an integer
43 corresponding to the return value of the fcntl call in the C code.
44 [clinic start generated code]*/
45 
46 static PyObject *
fcntl_fcntl_impl(PyObject * module,int fd,int code,PyObject * arg)47 fcntl_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]
105 fcntl.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 
113 Perform the operation `request` on file descriptor `fd`.
114 
115 The values used for `request` are operating system dependent, and are available
116 as constants in the fcntl or termios library modules, using the same names as
117 used in the relevant C header files.
118 
119 The argument `arg` is optional, and defaults to 0; it may be an int or a
120 buffer containing character data (most likely a string or an array).
121 
122 If the argument is a mutable buffer (such as an array) and if the
123 mutate_flag argument (which is only allowed in this case) is true then the
124 buffer is (in effect) passed to the operating system and changes made by
125 the OS will be reflected in the contents of the buffer after the call has
126 returned.  The return value is the integer returned by the ioctl system
127 call.
128 
129 If the argument is a mutable buffer and the mutable_flag argument is false,
130 the behavior is as if a string had been passed.
131 
132 If the argument is an immutable buffer (most likely a string) then a copy
133 of the buffer is passed to the operating system and the return value is a
134 string of the same length containing whatever the operating system put in
135 the buffer.  The length of the arg buffer in this case is not allowed to
136 exceed 1024 bytes.
137 
138 If the arg given is an integer or if none is specified, the result value is
139 an integer corresponding to the return value of the ioctl call in the C
140 code.
141 [clinic start generated code]*/
142 
143 static PyObject *
fcntl_ioctl_impl(PyObject * module,int fd,unsigned int code,PyObject * ob_arg,int mutate_arg)144 fcntl_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]
269 fcntl.flock
270 
271     fd: fildes
272     operation as code: int
273     /
274 
275 Perform the lock operation `operation` on file descriptor `fd`.
276 
277 See the Unix manual page for flock(2) for details (On some systems, this
278 function is emulated using fcntl()).
279 [clinic start generated code]*/
280 
281 static PyObject *
fcntl_flock_impl(PyObject * module,int fd,int code)282 fcntl_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]
335 fcntl.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 
344 A wrapper around the fcntl() locking calls.
345 
346 `fd` is the file descriptor of the file to lock or unlock, and operation is one
347 of the following values:
348 
349     LOCK_UN - unlock
350     LOCK_SH - acquire a shared lock
351     LOCK_EX - acquire an exclusive lock
352 
353 When operation is LOCK_SH or LOCK_EX, it can also be bitwise ORed with
354 LOCK_NB to avoid blocking on lock acquisition.  If LOCK_NB is used and the
355 lock cannot be acquired, an OSError will be raised and the exception will
356 have an errno attribute set to EACCES or EAGAIN (depending on the operating
357 system -- for portability, check for either value).
358 
359 `len` is the number of bytes to lock, with the default meaning to lock to
360 EOF.  `start` is the byte offset, relative to `whence`, to that the lock
361 starts.  `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 
368 static PyObject *
fcntl_lockf_impl(PyObject * module,int fd,int code,PyObject * lenobj,PyObject * startobj,int whence)369 fcntl_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 
438 static 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 
447 PyDoc_STRVAR(module_doc,
448 "This module performs file control and I/O control on file\n\
449 descriptors.  It is an interface to the fcntl() and ioctl() Unix\n\
450 routines.  File descriptors can be obtained with the fileno() method of\n\
451 a file or socket object.");
452 
453 /* Module initialisation */
454 
455 
456 static int
all_ins(PyObject * m)457 all_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 
669 static int
fcntl_exec(PyObject * module)670 fcntl_exec(PyObject *module)
671 {
672     if (all_ins(module) < 0) {
673         return -1;
674     }
675     return 0;
676 }
677 
678 static PyModuleDef_Slot fcntl_slots[] = {
679     {Py_mod_exec, fcntl_exec},
680     {0, NULL}
681 };
682 
683 static 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 
692 PyMODINIT_FUNC
PyInit_fcntl(void)693 PyInit_fcntl(void)
694 {
695     return PyModuleDef_Init(&fcntlmodule);
696 }
697