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