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