Branch data 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 : 6 : 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 : 6 : 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 [ + - - + ]: 6 : if (PySys_Audit("fcntl.ioctl", "iIO", fd, code,
170 : : ob_arg ? ob_arg : Py_None) < 0) {
171 : 0 : return NULL;
172 : : }
173 : :
174 [ + - ]: 6 : if (ob_arg != NULL) {
175 [ - + ]: 6 : 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 : 6 : PyErr_Clear();
228 [ + - ]: 6 : if (PyArg_Parse(ob_arg, "s*:ioctl", &pstr)) {
229 : 6 : str = pstr.buf;
230 : 6 : len = pstr.len;
231 [ - + ]: 6 : 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 : 6 : memcpy(buf, str, len);
238 : 6 : buf[len] = '\0';
239 : 6 : Py_BEGIN_ALLOW_THREADS
240 : 6 : ret = ioctl(fd, code, buf);
241 : 6 : Py_END_ALLOW_THREADS
242 [ - + ]: 6 : if (ret < 0) {
243 : 0 : PyBuffer_Release(&pstr);
244 : 0 : PyErr_SetFromErrno(PyExc_OSError);
245 : 0 : return NULL;
246 : : }
247 : 6 : PyBuffer_Release(&pstr);
248 : 6 : 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 : 19 : fcntl_flock_impl(PyObject *module, int fd, int code)
286 : : /*[clinic end generated code: output=84059e2b37d2fc64 input=0bfc00f795953452]*/
287 : : {
288 : : int ret;
289 : 19 : int async_err = 0;
290 : :
291 [ - + ]: 19 : if (PySys_Audit("fcntl.flock", "ii", fd, code) < 0) {
292 : 0 : return NULL;
293 : : }
294 : :
295 : : #ifdef HAVE_FLOCK
296 : : do {
297 : 20 : Py_BEGIN_ALLOW_THREADS
298 : 20 : ret = flock(fd, code);
299 : 20 : Py_END_ALLOW_THREADS
300 [ + + + + : 20 : } 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 [ + + ]: 19 : if (ret < 0) {
331 [ + - ]: 1 : return !async_err ? PyErr_SetFromErrno(PyExc_OSError) : NULL;
332 : : }
333 : 18 : 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 : 41 : 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 : 41 : int async_err = 0;
378 : :
379 [ - + - + : 41 : 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 [ + + ]: 41 : if (code == LOCK_UN)
393 : 19 : l.l_type = F_UNLCK;
394 [ + + ]: 22 : else if (code & LOCK_SH)
395 : 1 : l.l_type = F_RDLCK;
396 [ + - ]: 21 : else if (code & LOCK_EX)
397 : 21 : l.l_type = F_WRLCK;
398 : : else {
399 : 0 : PyErr_SetString(PyExc_ValueError,
400 : : "unrecognized lockf argument");
401 : 0 : return NULL;
402 : : }
403 : 41 : l.l_start = l.l_len = 0;
404 [ - + ]: 41 : 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 [ - + ]: 41 : 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 : 41 : l.l_whence = whence;
427 : : do {
428 : 42 : Py_BEGIN_ALLOW_THREADS
429 [ + + ]: 42 : ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
430 : 42 : Py_END_ALLOW_THREADS
431 [ + + + + : 42 : } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
+ - ]
432 : : }
433 [ + + ]: 41 : if (ret < 0) {
434 [ + - ]: 3 : return !async_err ? PyErr_SetFromErrno(PyExc_OSError) : NULL;
435 : : }
436 : 38 : 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 : 1200 : all_ins(PyObject* m)
461 : : {
462 [ - + ]: 1200 : if (PyModule_AddIntMacro(m, LOCK_SH)) return -1;
463 [ - + ]: 1200 : if (PyModule_AddIntMacro(m, LOCK_EX)) return -1;
464 [ - + ]: 1200 : if (PyModule_AddIntMacro(m, LOCK_NB)) return -1;
465 [ - + ]: 1200 : if (PyModule_AddIntMacro(m, LOCK_UN)) return -1;
466 : : /* GNU extensions, as of glibc 2.2.4 */
467 : : #ifdef LOCK_MAND
468 [ - + ]: 1200 : if (PyModule_AddIntMacro(m, LOCK_MAND)) return -1;
469 : : #endif
470 : : #ifdef LOCK_READ
471 [ - + ]: 1200 : if (PyModule_AddIntMacro(m, LOCK_READ)) return -1;
472 : : #endif
473 : : #ifdef LOCK_WRITE
474 [ - + ]: 1200 : if (PyModule_AddIntMacro(m, LOCK_WRITE)) return -1;
475 : : #endif
476 : : #ifdef LOCK_RW
477 [ - + ]: 1200 : if (PyModule_AddIntMacro(m, LOCK_RW)) return -1;
478 : : #endif
479 : :
480 : : #ifdef F_DUPFD
481 [ - + ]: 1200 : if (PyModule_AddIntMacro(m, F_DUPFD)) return -1;
482 : : #endif
483 : : #ifdef F_DUPFD_CLOEXEC
484 [ - + ]: 1200 : if (PyModule_AddIntMacro(m, F_DUPFD_CLOEXEC)) return -1;
485 : : #endif
486 : : #ifdef F_GETFD
487 [ - + ]: 1200 : if (PyModule_AddIntMacro(m, F_GETFD)) return -1;
488 : : #endif
489 : : #ifdef F_SETFD
490 [ - + ]: 1200 : if (PyModule_AddIntMacro(m, F_SETFD)) return -1;
491 : : #endif
492 : : #ifdef F_GETFL
493 [ - + ]: 1200 : if (PyModule_AddIntMacro(m, F_GETFL)) return -1;
494 : : #endif
495 : : #ifdef F_SETFL
496 [ - + ]: 1200 : if (PyModule_AddIntMacro(m, F_SETFL)) return -1;
497 : : #endif
498 : : #ifdef F_GETLK
499 [ - + ]: 1200 : if (PyModule_AddIntMacro(m, F_GETLK)) return -1;
500 : : #endif
501 : : #ifdef F_SETLK
502 [ - + ]: 1200 : if (PyModule_AddIntMacro(m, F_SETLK)) return -1;
503 : : #endif
504 : : #ifdef F_SETLKW
505 [ - + ]: 1200 : if (PyModule_AddIntMacro(m, F_SETLKW)) return -1;
506 : : #endif
507 : : #ifdef F_OFD_GETLK
508 [ - + ]: 1200 : if (PyModule_AddIntMacro(m, F_OFD_GETLK)) return -1;
509 : : #endif
510 : : #ifdef F_OFD_SETLK
511 [ - + ]: 1200 : if (PyModule_AddIntMacro(m, F_OFD_SETLK)) return -1;
512 : : #endif
513 : : #ifdef F_OFD_SETLKW
514 [ - + ]: 1200 : if (PyModule_AddIntMacro(m, F_OFD_SETLKW)) return -1;
515 : : #endif
516 : : #ifdef F_GETOWN
517 [ - + ]: 1200 : if (PyModule_AddIntMacro(m, F_GETOWN)) return -1;
518 : : #endif
519 : : #ifdef F_SETOWN
520 [ - + ]: 1200 : 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 [ - + ]: 1200 : if (PyModule_AddIntMacro(m, F_GETSIG)) return -1;
527 : : #endif
528 : : #ifdef F_SETSIG
529 [ - + ]: 1200 : if (PyModule_AddIntMacro(m, F_SETSIG)) return -1;
530 : : #endif
531 : : #ifdef F_RDLCK
532 [ - + ]: 1200 : if (PyModule_AddIntMacro(m, F_RDLCK)) return -1;
533 : : #endif
534 : : #ifdef F_WRLCK
535 [ - + ]: 1200 : if (PyModule_AddIntMacro(m, F_WRLCK)) return -1;
536 : : #endif
537 : : #ifdef F_UNLCK
538 [ - + ]: 1200 : if (PyModule_AddIntMacro(m, F_UNLCK)) return -1;
539 : : #endif
540 : : /* LFS constants */
541 : : #ifdef F_GETLK64
542 [ - + ]: 1200 : if (PyModule_AddIntMacro(m, F_GETLK64)) return -1;
543 : : #endif
544 : : #ifdef F_SETLK64
545 [ - + ]: 1200 : if (PyModule_AddIntMacro(m, F_SETLK64)) return -1;
546 : : #endif
547 : : #ifdef F_SETLKW64
548 [ - + ]: 1200 : if (PyModule_AddIntMacro(m, F_SETLKW64)) return -1;
549 : : #endif
550 : : /* GNU extensions, as of glibc 2.2.4. */
551 : : #ifdef FASYNC
552 [ - + ]: 1200 : if (PyModule_AddIntMacro(m, FASYNC)) return -1;
553 : : #endif
554 : : #ifdef F_SETLEASE
555 [ - + ]: 1200 : if (PyModule_AddIntMacro(m, F_SETLEASE)) return -1;
556 : : #endif
557 : : #ifdef F_GETLEASE
558 [ - + ]: 1200 : if (PyModule_AddIntMacro(m, F_GETLEASE)) return -1;
559 : : #endif
560 : : #ifdef F_NOTIFY
561 [ - + ]: 1200 : if (PyModule_AddIntMacro(m, F_NOTIFY)) return -1;
562 : : #endif
563 : : /* Old BSD flock(). */
564 : : #ifdef F_EXLCK
565 [ - + ]: 1200 : if (PyModule_AddIntMacro(m, F_EXLCK)) return -1;
566 : : #endif
567 : : #ifdef F_SHLCK
568 [ - + ]: 1200 : if (PyModule_AddIntMacro(m, F_SHLCK)) return -1;
569 : : #endif
570 : :
571 : : /* Linux specifics */
572 : : #ifdef F_SETPIPE_SZ
573 [ - + ]: 1200 : if (PyModule_AddIntMacro(m, F_SETPIPE_SZ)) return -1;
574 : : #endif
575 : : #ifdef F_GETPIPE_SZ
576 [ - + ]: 1200 : if (PyModule_AddIntMacro(m, F_GETPIPE_SZ)) return -1;
577 : : #endif
578 : : #ifdef FICLONE
579 [ - + ]: 1200 : if (PyModule_AddIntMacro(m, FICLONE)) return -1;
580 : : #endif
581 : : #ifdef FICLONERANGE
582 [ - + ]: 1200 : 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 [ - + ]: 1200 : if (PyModule_AddIntMacro(m, FD_CLOEXEC)) return -1;
604 : : #endif
605 : :
606 : : /* For F_NOTIFY */
607 : : #ifdef DN_ACCESS
608 [ - + ]: 1200 : if (PyModule_AddIntMacro(m, DN_ACCESS)) return -1;
609 : : #endif
610 : : #ifdef DN_MODIFY
611 [ - + ]: 1200 : if (PyModule_AddIntMacro(m, DN_MODIFY)) return -1;
612 : : #endif
613 : : #ifdef DN_CREATE
614 [ - + ]: 1200 : if (PyModule_AddIntMacro(m, DN_CREATE)) return -1;
615 : : #endif
616 : : #ifdef DN_DELETE
617 [ - + ]: 1200 : if (PyModule_AddIntMacro(m, DN_DELETE)) return -1;
618 : : #endif
619 : : #ifdef DN_RENAME
620 [ - + ]: 1200 : if (PyModule_AddIntMacro(m, DN_RENAME)) return -1;
621 : : #endif
622 : : #ifdef DN_ATTRIB
623 [ - + ]: 1200 : if (PyModule_AddIntMacro(m, DN_ATTRIB)) return -1;
624 : : #endif
625 : : #ifdef DN_MULTISHOT
626 [ - + ]: 1200 : 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 [ - + ]: 1200 : if (PyModule_AddIntMacro(m, F_ADD_SEALS)) return -1;
669 [ - + ]: 1200 : if (PyModule_AddIntMacro(m, F_GET_SEALS)) return -1;
670 [ - + ]: 1200 : if (PyModule_AddIntMacro(m, F_SEAL_SEAL)) return -1;
671 [ - + ]: 1200 : if (PyModule_AddIntMacro(m, F_SEAL_SHRINK)) return -1;
672 [ - + ]: 1200 : if (PyModule_AddIntMacro(m, F_SEAL_GROW)) return -1;
673 [ - + ]: 1200 : if (PyModule_AddIntMacro(m, F_SEAL_WRITE)) return -1;
674 : : #endif
675 : 1200 : return 0;
676 : : }
677 : :
678 : : static int
679 : 1200 : fcntl_exec(PyObject *module)
680 : : {
681 [ - + ]: 1200 : if (all_ins(module) < 0) {
682 : 0 : return -1;
683 : : }
684 : 1200 : 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 : 1200 : PyInit_fcntl(void)
703 : : {
704 : 1200 : return PyModuleDef_Init(&fcntlmodule);
705 : : }
|