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