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 *
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 *
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 if (ret < 0) {
212 PyErr_SetFromErrno(PyExc_OSError);
213 PyBuffer_Release(&pstr);
214 return NULL;
215 }
216 PyBuffer_Release(&pstr);
217 if (mutate_arg) {
218 return PyLong_FromLong(ret);
219 }
220 else {
221 return PyBytes_FromStringAndSize(buf, len);
222 }
223 }
224
225 PyErr_Clear();
226 if (PyArg_Parse(ob_arg, "s*:ioctl", &pstr)) {
227 str = pstr.buf;
228 len = pstr.len;
229 if (len > IOCTL_BUFSZ) {
230 PyBuffer_Release(&pstr);
231 PyErr_SetString(PyExc_ValueError,
232 "ioctl string arg too long");
233 return NULL;
234 }
235 memcpy(buf, str, len);
236 buf[len] = '\0';
237 Py_BEGIN_ALLOW_THREADS
238 ret = ioctl(fd, code, buf);
239 Py_END_ALLOW_THREADS
240 if (ret < 0) {
241 PyErr_SetFromErrno(PyExc_OSError);
242 PyBuffer_Release(&pstr);
243 return NULL;
244 }
245 PyBuffer_Release(&pstr);
246 return PyBytes_FromStringAndSize(buf, len);
247 }
248
249 PyErr_Clear();
250 if (!PyArg_Parse(ob_arg,
251 "i;ioctl requires a file or file descriptor,"
252 " an integer and optionally an integer or buffer argument",
253 &arg)) {
254 return NULL;
255 }
256 // Fall-through to outside the 'if' statement.
257 }
258 Py_BEGIN_ALLOW_THREADS
259 ret = ioctl(fd, code, arg);
260 Py_END_ALLOW_THREADS
261 if (ret < 0) {
262 PyErr_SetFromErrno(PyExc_OSError);
263 return NULL;
264 }
265 return PyLong_FromLong((long)ret);
266 #undef IOCTL_BUFSZ
267 }
268
269 /*[clinic input]
270 fcntl.flock
271
272 fd: fildes
273 operation as code: int
274 /
275
276 Perform the lock operation `operation` on file descriptor `fd`.
277
278 See the Unix manual page for flock(2) for details (On some systems, this
279 function is emulated using fcntl()).
280 [clinic start generated code]*/
281
282 static PyObject *
283 fcntl_flock_impl(PyObject *module, int fd, int code)
284 /*[clinic end generated code: output=84059e2b37d2fc64 input=0bfc00f795953452]*/
285 {
286 int ret;
287 int async_err = 0;
288
289 if (PySys_Audit("fcntl.flock", "ii", fd, code) < 0) {
290 return NULL;
291 }
292
293 #ifdef HAVE_FLOCK
294 do {
295 Py_BEGIN_ALLOW_THREADS
296 ret = flock(fd, code);
297 Py_END_ALLOW_THREADS
298 } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
299 #else
300
301 #ifndef LOCK_SH
302 #define LOCK_SH 1 /* shared lock */
303 #define LOCK_EX 2 /* exclusive lock */
304 #define LOCK_NB 4 /* don't block when locking */
305 #define LOCK_UN 8 /* unlock */
306 #endif
307 {
308 struct flock l;
309 if (code == LOCK_UN)
310 l.l_type = F_UNLCK;
311 else if (code & LOCK_SH)
312 l.l_type = F_RDLCK;
313 else if (code & LOCK_EX)
314 l.l_type = F_WRLCK;
315 else {
316 PyErr_SetString(PyExc_ValueError,
317 "unrecognized flock argument");
318 return NULL;
319 }
320 l.l_whence = l.l_start = l.l_len = 0;
321 do {
322 Py_BEGIN_ALLOW_THREADS
323 ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
324 Py_END_ALLOW_THREADS
325 } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
326 }
327 #endif /* HAVE_FLOCK */
328 if (ret < 0) {
329 return !async_err ? PyErr_SetFromErrno(PyExc_OSError) : NULL;
330 }
331 Py_RETURN_NONE;
332 }
333
334
335 /*[clinic input]
336 fcntl.lockf
337
338 fd: fildes
339 cmd as code: int
340 len as lenobj: object(c_default='NULL') = 0
341 start as startobj: object(c_default='NULL') = 0
342 whence: int = 0
343 /
344
345 A wrapper around the fcntl() locking calls.
346
347 `fd` is the file descriptor of the file to lock or unlock, and operation is one
348 of the following values:
349
350 LOCK_UN - unlock
351 LOCK_SH - acquire a shared lock
352 LOCK_EX - acquire an exclusive lock
353
354 When operation is LOCK_SH or LOCK_EX, it can also be bitwise ORed with
355 LOCK_NB to avoid blocking on lock acquisition. If LOCK_NB is used and the
356 lock cannot be acquired, an OSError will be raised and the exception will
357 have an errno attribute set to EACCES or EAGAIN (depending on the operating
358 system -- for portability, check for either value).
359
360 `len` is the number of bytes to lock, with the default meaning to lock to
361 EOF. `start` is the byte offset, relative to `whence`, to that the lock
362 starts. `whence` is as with fileobj.seek(), specifically:
363
364 0 - relative to the start of the file (SEEK_SET)
365 1 - relative to the current buffer position (SEEK_CUR)
366 2 - relative to the end of the file (SEEK_END)
367 [clinic start generated code]*/
368
369 static PyObject *
370 fcntl_lockf_impl(PyObject *module, int fd, int code, PyObject *lenobj,
371 PyObject *startobj, int whence)
372 /*[clinic end generated code: output=4985e7a172e7461a input=5480479fc63a04b8]*/
373 {
374 int ret;
375 int async_err = 0;
376
377 if (PySys_Audit("fcntl.lockf", "iiOOi", fd, code, lenobj ? lenobj : Py_None,
378 startobj ? startobj : Py_None, whence) < 0) {
379 return NULL;
380 }
381
382 #ifndef LOCK_SH
383 #define LOCK_SH 1 /* shared lock */
384 #define LOCK_EX 2 /* exclusive lock */
385 #define LOCK_NB 4 /* don't block when locking */
386 #define LOCK_UN 8 /* unlock */
387 #endif /* LOCK_SH */
388 {
389 struct flock l;
390 if (code == LOCK_UN)
391 l.l_type = F_UNLCK;
392 else if (code & LOCK_SH)
393 l.l_type = F_RDLCK;
394 else if (code & LOCK_EX)
395 l.l_type = F_WRLCK;
396 else {
397 PyErr_SetString(PyExc_ValueError,
398 "unrecognized lockf argument");
399 return NULL;
400 }
401 l.l_start = l.l_len = 0;
402 if (startobj != NULL) {
403 #if !defined(HAVE_LARGEFILE_SUPPORT)
404 l.l_start = PyLong_AsLong(startobj);
405 #else
406 l.l_start = PyLong_Check(startobj) ?
407 PyLong_AsLongLong(startobj) :
408 PyLong_AsLong(startobj);
409 #endif
410 if (PyErr_Occurred())
411 return NULL;
412 }
413 if (lenobj != NULL) {
414 #if !defined(HAVE_LARGEFILE_SUPPORT)
415 l.l_len = PyLong_AsLong(lenobj);
416 #else
417 l.l_len = PyLong_Check(lenobj) ?
418 PyLong_AsLongLong(lenobj) :
419 PyLong_AsLong(lenobj);
420 #endif
421 if (PyErr_Occurred())
422 return NULL;
423 }
424 l.l_whence = whence;
425 do {
426 Py_BEGIN_ALLOW_THREADS
427 ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
428 Py_END_ALLOW_THREADS
429 } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
430 }
431 if (ret < 0) {
432 return !async_err ? PyErr_SetFromErrno(PyExc_OSError) : NULL;
433 }
434 Py_RETURN_NONE;
435 }
436
437 /* List of functions */
438
439 static PyMethodDef fcntl_methods[] = {
440 FCNTL_FCNTL_METHODDEF
441 FCNTL_IOCTL_METHODDEF
442 FCNTL_FLOCK_METHODDEF
443 FCNTL_LOCKF_METHODDEF
444 {NULL, NULL} /* sentinel */
445 };
446
447
448 PyDoc_STRVAR(module_doc,
449 "This module performs file control and I/O control on file\n\
450 descriptors. It is an interface to the fcntl() and ioctl() Unix\n\
451 routines. File descriptors can be obtained with the fileno() method of\n\
452 a file or socket object.");
453
454 /* Module initialisation */
455
456
457 static int
458 all_ins(PyObject* m)
459 {
460 if (PyModule_AddIntMacro(m, LOCK_SH)) return -1;
461 if (PyModule_AddIntMacro(m, LOCK_EX)) return -1;
462 if (PyModule_AddIntMacro(m, LOCK_NB)) return -1;
463 if (PyModule_AddIntMacro(m, LOCK_UN)) return -1;
464 /* GNU extensions, as of glibc 2.2.4 */
465 #ifdef LOCK_MAND
466 if (PyModule_AddIntMacro(m, LOCK_MAND)) return -1;
467 #endif
468 #ifdef LOCK_READ
469 if (PyModule_AddIntMacro(m, LOCK_READ)) return -1;
470 #endif
471 #ifdef LOCK_WRITE
472 if (PyModule_AddIntMacro(m, LOCK_WRITE)) return -1;
473 #endif
474 #ifdef LOCK_RW
475 if (PyModule_AddIntMacro(m, LOCK_RW)) return -1;
476 #endif
477
478 #ifdef F_DUPFD
479 if (PyModule_AddIntMacro(m, F_DUPFD)) return -1;
480 #endif
481 #ifdef F_DUPFD_CLOEXEC
482 if (PyModule_AddIntMacro(m, F_DUPFD_CLOEXEC)) return -1;
483 #endif
484 #ifdef F_GETFD
485 if (PyModule_AddIntMacro(m, F_GETFD)) return -1;
486 #endif
487 #ifdef F_SETFD
488 if (PyModule_AddIntMacro(m, F_SETFD)) return -1;
489 #endif
490 #ifdef F_GETFL
491 if (PyModule_AddIntMacro(m, F_GETFL)) return -1;
492 #endif
493 #ifdef F_SETFL
494 if (PyModule_AddIntMacro(m, F_SETFL)) return -1;
495 #endif
496 #ifdef F_GETLK
497 if (PyModule_AddIntMacro(m, F_GETLK)) return -1;
498 #endif
499 #ifdef F_SETLK
500 if (PyModule_AddIntMacro(m, F_SETLK)) return -1;
501 #endif
502 #ifdef F_SETLKW
503 if (PyModule_AddIntMacro(m, F_SETLKW)) return -1;
504 #endif
505 #ifdef F_OFD_GETLK
506 if (PyModule_AddIntMacro(m, F_OFD_GETLK)) return -1;
507 #endif
508 #ifdef F_OFD_SETLK
509 if (PyModule_AddIntMacro(m, F_OFD_SETLK)) return -1;
510 #endif
511 #ifdef F_OFD_SETLKW
512 if (PyModule_AddIntMacro(m, F_OFD_SETLKW)) return -1;
513 #endif
514 #ifdef F_GETOWN
515 if (PyModule_AddIntMacro(m, F_GETOWN)) return -1;
516 #endif
517 #ifdef F_SETOWN
518 if (PyModule_AddIntMacro(m, F_SETOWN)) return -1;
519 #endif
520 #ifdef F_GETPATH
521 if (PyModule_AddIntMacro(m, F_GETPATH)) return -1;
522 #endif
523 #ifdef F_GETSIG
524 if (PyModule_AddIntMacro(m, F_GETSIG)) return -1;
525 #endif
526 #ifdef F_SETSIG
527 if (PyModule_AddIntMacro(m, F_SETSIG)) return -1;
528 #endif
529 #ifdef F_RDLCK
530 if (PyModule_AddIntMacro(m, F_RDLCK)) return -1;
531 #endif
532 #ifdef F_WRLCK
533 if (PyModule_AddIntMacro(m, F_WRLCK)) return -1;
534 #endif
535 #ifdef F_UNLCK
536 if (PyModule_AddIntMacro(m, F_UNLCK)) return -1;
537 #endif
538 /* LFS constants */
539 #ifdef F_GETLK64
540 if (PyModule_AddIntMacro(m, F_GETLK64)) return -1;
541 #endif
542 #ifdef F_SETLK64
543 if (PyModule_AddIntMacro(m, F_SETLK64)) return -1;
544 #endif
545 #ifdef F_SETLKW64
546 if (PyModule_AddIntMacro(m, F_SETLKW64)) return -1;
547 #endif
548 /* GNU extensions, as of glibc 2.2.4. */
549 #ifdef FASYNC
550 if (PyModule_AddIntMacro(m, FASYNC)) return -1;
551 #endif
552 #ifdef F_SETLEASE
553 if (PyModule_AddIntMacro(m, F_SETLEASE)) return -1;
554 #endif
555 #ifdef F_GETLEASE
556 if (PyModule_AddIntMacro(m, F_GETLEASE)) return -1;
557 #endif
558 #ifdef F_NOTIFY
559 if (PyModule_AddIntMacro(m, F_NOTIFY)) return -1;
560 #endif
561 /* Old BSD flock(). */
562 #ifdef F_EXLCK
563 if (PyModule_AddIntMacro(m, F_EXLCK)) return -1;
564 #endif
565 #ifdef F_SHLCK
566 if (PyModule_AddIntMacro(m, F_SHLCK)) return -1;
567 #endif
568
569 /* Linux specifics */
570 #ifdef F_SETPIPE_SZ
571 if (PyModule_AddIntMacro(m, F_SETPIPE_SZ)) return -1;
572 #endif
573 #ifdef F_GETPIPE_SZ
574 if (PyModule_AddIntMacro(m, F_GETPIPE_SZ)) return -1;
575 #endif
576
577 /* OS X specifics */
578 #ifdef F_FULLFSYNC
579 if (PyModule_AddIntMacro(m, F_FULLFSYNC)) return -1;
580 #endif
581 #ifdef F_NOCACHE
582 if (PyModule_AddIntMacro(m, F_NOCACHE)) return -1;
583 #endif
584
585 /* FreeBSD specifics */
586 #ifdef F_DUP2FD
587 if (PyModule_AddIntMacro(m, F_DUP2FD)) return -1;
588 #endif
589 #ifdef F_DUP2FD_CLOEXEC
590 if (PyModule_AddIntMacro(m, F_DUP2FD_CLOEXEC)) return -1;
591 #endif
592
593 /* For F_{GET|SET}FL */
594 #ifdef FD_CLOEXEC
595 if (PyModule_AddIntMacro(m, FD_CLOEXEC)) return -1;
596 #endif
597
598 /* For F_NOTIFY */
599 #ifdef DN_ACCESS
600 if (PyModule_AddIntMacro(m, DN_ACCESS)) return -1;
601 #endif
602 #ifdef DN_MODIFY
603 if (PyModule_AddIntMacro(m, DN_MODIFY)) return -1;
604 #endif
605 #ifdef DN_CREATE
606 if (PyModule_AddIntMacro(m, DN_CREATE)) return -1;
607 #endif
608 #ifdef DN_DELETE
609 if (PyModule_AddIntMacro(m, DN_DELETE)) return -1;
610 #endif
611 #ifdef DN_RENAME
612 if (PyModule_AddIntMacro(m, DN_RENAME)) return -1;
613 #endif
614 #ifdef DN_ATTRIB
615 if (PyModule_AddIntMacro(m, DN_ATTRIB)) return -1;
616 #endif
617 #ifdef DN_MULTISHOT
618 if (PyModule_AddIntMacro(m, DN_MULTISHOT)) return -1;
619 #endif
620
621 #ifdef HAVE_STROPTS_H
622 /* Unix 98 guarantees that these are in stropts.h. */
623 if (PyModule_AddIntMacro(m, I_PUSH)) return -1;
624 if (PyModule_AddIntMacro(m, I_POP)) return -1;
625 if (PyModule_AddIntMacro(m, I_LOOK)) return -1;
626 if (PyModule_AddIntMacro(m, I_FLUSH)) return -1;
627 if (PyModule_AddIntMacro(m, I_FLUSHBAND)) return -1;
628 if (PyModule_AddIntMacro(m, I_SETSIG)) return -1;
629 if (PyModule_AddIntMacro(m, I_GETSIG)) return -1;
630 if (PyModule_AddIntMacro(m, I_FIND)) return -1;
631 if (PyModule_AddIntMacro(m, I_PEEK)) return -1;
632 if (PyModule_AddIntMacro(m, I_SRDOPT)) return -1;
633 if (PyModule_AddIntMacro(m, I_GRDOPT)) return -1;
634 if (PyModule_AddIntMacro(m, I_NREAD)) return -1;
635 if (PyModule_AddIntMacro(m, I_FDINSERT)) return -1;
636 if (PyModule_AddIntMacro(m, I_STR)) return -1;
637 if (PyModule_AddIntMacro(m, I_SWROPT)) return -1;
638 #ifdef I_GWROPT
639 /* despite the comment above, old-ish glibcs miss a couple... */
640 if (PyModule_AddIntMacro(m, I_GWROPT)) return -1;
641 #endif
642 if (PyModule_AddIntMacro(m, I_SENDFD)) return -1;
643 if (PyModule_AddIntMacro(m, I_RECVFD)) return -1;
644 if (PyModule_AddIntMacro(m, I_LIST)) return -1;
645 if (PyModule_AddIntMacro(m, I_ATMARK)) return -1;
646 if (PyModule_AddIntMacro(m, I_CKBAND)) return -1;
647 if (PyModule_AddIntMacro(m, I_GETBAND)) return -1;
648 if (PyModule_AddIntMacro(m, I_CANPUT)) return -1;
649 if (PyModule_AddIntMacro(m, I_SETCLTIME)) return -1;
650 #ifdef I_GETCLTIME
651 if (PyModule_AddIntMacro(m, I_GETCLTIME)) return -1;
652 #endif
653 if (PyModule_AddIntMacro(m, I_LINK)) return -1;
654 if (PyModule_AddIntMacro(m, I_UNLINK)) return -1;
655 if (PyModule_AddIntMacro(m, I_PLINK)) return -1;
656 if (PyModule_AddIntMacro(m, I_PUNLINK)) return -1;
657 #endif
658 #ifdef F_ADD_SEALS
659 /* Linux: file sealing for memfd_create() */
660 if (PyModule_AddIntMacro(m, F_ADD_SEALS)) return -1;
661 if (PyModule_AddIntMacro(m, F_GET_SEALS)) return -1;
662 if (PyModule_AddIntMacro(m, F_SEAL_SEAL)) return -1;
663 if (PyModule_AddIntMacro(m, F_SEAL_SHRINK)) return -1;
664 if (PyModule_AddIntMacro(m, F_SEAL_GROW)) return -1;
665 if (PyModule_AddIntMacro(m, F_SEAL_WRITE)) return -1;
666 #endif
667 return 0;
668 }
669
670 static int
671 fcntl_exec(PyObject *module)
672 {
673 if (all_ins(module) < 0) {
674 return -1;
675 }
676 return 0;
677 }
678
679 static PyModuleDef_Slot fcntl_slots[] = {
680 {Py_mod_exec, fcntl_exec},
681 {0, NULL}
682 };
683
684 static struct PyModuleDef fcntlmodule = {
685 PyModuleDef_HEAD_INIT,
686 .m_name = "fcntl",
687 .m_doc = module_doc,
688 .m_size = 0,
689 .m_methods = fcntl_methods,
690 .m_slots = fcntl_slots,
691 };
692
693 PyMODINIT_FUNC
694 PyInit_fcntl(void)
695 {
696 return PyModuleDef_Init(&fcntlmodule);
697 }