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