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