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