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