Merged revisions 75928 via svnmerge from
[python/dscho.git] / Modules / fcntlmodule.c
blob683c5b6d9f159883310f2ec7bef0e19a1f6a021f
2 /* fcntl module */
4 #define PY_SSIZE_T_CLEAN
6 #include "Python.h"
8 #ifdef HAVE_SYS_FILE_H
9 #include <sys/file.h>
10 #endif
12 #include <sys/ioctl.h>
13 #include <fcntl.h>
14 #ifdef HAVE_STROPTS_H
15 #include <stropts.h>
16 #endif
18 static int
19 conv_descriptor(PyObject *object, int *target)
21 int fd = PyObject_AsFileDescriptor(object);
23 if (fd < 0)
24 return 0;
25 *target = fd;
26 return 1;
30 /* fcntl(fd, opt, [arg]) */
32 static PyObject *
33 fcntl_fcntl(PyObject *self, PyObject *args)
35 int fd;
36 int code;
37 long arg;
38 int ret;
39 char *str;
40 Py_ssize_t len;
41 char buf[1024];
43 if (PyArg_ParseTuple(args, "O&is#:fcntl",
44 conv_descriptor, &fd, &code, &str, &len)) {
45 if (len > sizeof buf) {
46 PyErr_SetString(PyExc_ValueError,
47 "fcntl string arg too long");
48 return NULL;
50 memcpy(buf, str, len);
51 Py_BEGIN_ALLOW_THREADS
52 ret = fcntl(fd, code, buf);
53 Py_END_ALLOW_THREADS
54 if (ret < 0) {
55 PyErr_SetFromErrno(PyExc_IOError);
56 return NULL;
58 return PyBytes_FromStringAndSize(buf, len);
61 PyErr_Clear();
62 arg = 0;
63 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 return NULL;
69 Py_BEGIN_ALLOW_THREADS
70 ret = fcntl(fd, code, arg);
71 Py_END_ALLOW_THREADS
72 if (ret < 0) {
73 PyErr_SetFromErrno(PyExc_IOError);
74 return NULL;
76 return PyLong_FromLong((long)ret);
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.");
93 /* ioctl(fd, opt, [arg]) */
95 static PyObject *
96 fcntl_ioctl(PyObject *self, PyObject *args)
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.
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.
113 unsigned int code;
114 int arg;
115 int ret;
116 Py_buffer pstr;
117 char *str;
118 Py_ssize_t len;
119 int mutate_arg = 1;
120 char buf[IOCTL_BUFSZ+1]; /* argument plus NUL byte */
122 if (PyArg_ParseTuple(args, "O&Iw*|i:ioctl",
123 conv_descriptor, &fd, &code,
124 &pstr, &mutate_arg)) {
125 char *arg;
126 str = pstr.buf;
127 len = pstr.len;
129 if (mutate_arg) {
130 if (len <= IOCTL_BUFSZ) {
131 memcpy(buf, str, len);
132 buf[len] = '\0';
133 arg = buf;
135 else {
136 arg = str;
139 else {
140 if (len > IOCTL_BUFSZ) {
141 PyBuffer_Release(&pstr);
142 PyErr_SetString(PyExc_ValueError,
143 "ioctl string arg too long");
144 return NULL;
146 else {
147 memcpy(buf, str, len);
148 buf[len] = '\0';
149 arg = buf;
152 if (buf == arg) {
153 Py_BEGIN_ALLOW_THREADS /* think array.resize() */
154 ret = ioctl(fd, code, arg);
155 Py_END_ALLOW_THREADS
157 else {
158 ret = ioctl(fd, code, arg);
160 if (mutate_arg && (len < IOCTL_BUFSZ)) {
161 memcpy(str, buf, len);
163 PyBuffer_Release(&pstr); /* No further access to str below this point */
164 if (ret < 0) {
165 PyErr_SetFromErrno(PyExc_IOError);
166 return NULL;
168 if (mutate_arg) {
169 return PyLong_FromLong(ret);
171 else {
172 return PyBytes_FromStringAndSize(buf, len);
176 PyErr_Clear();
177 if (PyArg_ParseTuple(args, "O&Is*:ioctl",
178 conv_descriptor, &fd, &code, &pstr)) {
179 str = pstr.buf;
180 len = pstr.len;
181 if (len > IOCTL_BUFSZ) {
182 PyBuffer_Release(&pstr);
183 PyErr_SetString(PyExc_ValueError,
184 "ioctl string arg too long");
185 return NULL;
187 memcpy(buf, str, len);
188 buf[len] = '\0';
189 Py_BEGIN_ALLOW_THREADS
190 ret = ioctl(fd, code, buf);
191 Py_END_ALLOW_THREADS
192 if (ret < 0) {
193 PyBuffer_Release(&pstr);
194 PyErr_SetFromErrno(PyExc_IOError);
195 return NULL;
197 PyBuffer_Release(&pstr);
198 return PyBytes_FromStringAndSize(buf, len);
201 PyErr_Clear();
202 arg = 0;
203 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 return NULL;
209 Py_BEGIN_ALLOW_THREADS
210 #ifdef __VMS
211 ret = ioctl(fd, code, (void *)arg);
212 #else
213 ret = ioctl(fd, code, arg);
214 #endif
215 Py_END_ALLOW_THREADS
216 if (ret < 0) {
217 PyErr_SetFromErrno(PyExc_IOError);
218 return NULL;
220 return PyLong_FromLong((long)ret);
221 #undef IOCTL_BUFSZ
224 PyDoc_STRVAR(ioctl_doc,
225 "ioctl(fd, opt[, arg[, mutate_flag]])\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\
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\
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\
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\
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\
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.");
256 /* flock(fd, operation) */
258 static PyObject *
259 fcntl_flock(PyObject *self, PyObject *args)
261 int fd;
262 int code;
263 int ret;
265 if (!PyArg_ParseTuple(args, "O&i:flock",
266 conv_descriptor, &fd, &code))
267 return NULL;
269 #ifdef HAVE_FLOCK
270 Py_BEGIN_ALLOW_THREADS
271 ret = flock(fd, code);
272 Py_END_ALLOW_THREADS
273 #else
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
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;
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
299 #endif /* HAVE_FLOCK */
300 if (ret < 0) {
301 PyErr_SetFromErrno(PyExc_IOError);
302 return NULL;
304 Py_INCREF(Py_None);
305 return Py_None;
308 PyDoc_STRVAR(flock_doc,
309 "flock(fd, operation)\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().)");
316 /* lockf(fd, operation) */
317 static PyObject *
318 fcntl_lockf(PyObject *self, PyObject *args)
320 int fd, code, ret, whence = 0;
321 PyObject *lenobj = NULL, *startobj = NULL;
323 if (!PyArg_ParseTuple(args, "O&i|OOi:lockf",
324 conv_descriptor, &fd, &code,
325 &lenobj, &startobj, &whence))
326 return NULL;
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 */
340 struct flock l;
341 if (code == LOCK_UN)
342 l.l_type = F_UNLCK;
343 else if (code & LOCK_SH)
344 l.l_type = F_RDLCK;
345 else if (code & LOCK_EX)
346 l.l_type = F_WRLCK;
347 else {
348 PyErr_SetString(PyExc_ValueError,
349 "unrecognized lockf argument");
350 return NULL;
352 l.l_start = l.l_len = 0;
353 if (startobj != NULL) {
354 #if !defined(HAVE_LARGEFILE_SUPPORT)
355 l.l_start = PyLong_AsLong(startobj);
356 #else
357 l.l_start = PyLong_Check(startobj) ?
358 PyLong_AsLongLong(startobj) :
359 PyLong_AsLong(startobj);
360 #endif
361 if (PyErr_Occurred())
362 return NULL;
364 if (lenobj != NULL) {
365 #if !defined(HAVE_LARGEFILE_SUPPORT)
366 l.l_len = PyLong_AsLong(lenobj);
367 #else
368 l.l_len = PyLong_Check(lenobj) ?
369 PyLong_AsLongLong(lenobj) :
370 PyLong_AsLong(lenobj);
371 #endif
372 if (PyErr_Occurred())
373 return NULL;
375 l.l_whence = whence;
376 Py_BEGIN_ALLOW_THREADS
377 ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
378 Py_END_ALLOW_THREADS
380 if (ret < 0) {
381 PyErr_SetFromErrno(PyExc_IOError);
382 return NULL;
384 Py_INCREF(Py_None);
385 return Py_None;
386 #endif /* defined(PYOS_OS2) && defined(PYCC_GCC) */
389 PyDoc_STRVAR(lockf_doc,
390 "lockf (fd, operation, length=0, start=0, whence=0)\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\
396 LOCK_UN - unlock\n\
397 LOCK_SH - acquire a shared lock\n\
398 LOCK_EX - acquire an exclusive lock\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\
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\
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)");
414 /* List of functions */
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 */
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.");
431 /* Module initialisation */
433 static int
434 ins(PyObject* d, char* symbol, long value)
436 PyObject* v = PyLong_FromLong(value);
437 if (!v || PyDict_SetItemString(d, symbol, v) < 0)
438 return -1;
440 Py_DECREF(v);
441 return 0;
444 #define INS(x) if (ins(d, #x, (long)x)) return -1
446 static int
447 all_ins(PyObject* d)
449 if (ins(d, "LOCK_SH", (long)LOCK_SH)) return -1;
450 if (ins(d, "LOCK_EX", (long)LOCK_EX)) return -1;
451 if (ins(d, "LOCK_NB", (long)LOCK_NB)) return -1;
452 if (ins(d, "LOCK_UN", (long)LOCK_UN)) return -1;
453 /* GNU extensions, as of glibc 2.2.4 */
454 #ifdef LOCK_MAND
455 if (ins(d, "LOCK_MAND", (long)LOCK_MAND)) return -1;
456 #endif
457 #ifdef LOCK_READ
458 if (ins(d, "LOCK_READ", (long)LOCK_READ)) return -1;
459 #endif
460 #ifdef LOCK_WRITE
461 if (ins(d, "LOCK_WRITE", (long)LOCK_WRITE)) return -1;
462 #endif
463 #ifdef LOCK_RW
464 if (ins(d, "LOCK_RW", (long)LOCK_RW)) return -1;
465 #endif
467 #ifdef F_DUPFD
468 if (ins(d, "F_DUPFD", (long)F_DUPFD)) return -1;
469 #endif
470 #ifdef F_GETFD
471 if (ins(d, "F_GETFD", (long)F_GETFD)) return -1;
472 #endif
473 #ifdef F_SETFD
474 if (ins(d, "F_SETFD", (long)F_SETFD)) return -1;
475 #endif
476 #ifdef F_GETFL
477 if (ins(d, "F_GETFL", (long)F_GETFL)) return -1;
478 #endif
479 #ifdef F_SETFL
480 if (ins(d, "F_SETFL", (long)F_SETFL)) return -1;
481 #endif
482 #ifdef F_GETLK
483 if (ins(d, "F_GETLK", (long)F_GETLK)) return -1;
484 #endif
485 #ifdef F_SETLK
486 if (ins(d, "F_SETLK", (long)F_SETLK)) return -1;
487 #endif
488 #ifdef F_SETLKW
489 if (ins(d, "F_SETLKW", (long)F_SETLKW)) return -1;
490 #endif
491 #ifdef F_GETOWN
492 if (ins(d, "F_GETOWN", (long)F_GETOWN)) return -1;
493 #endif
494 #ifdef F_SETOWN
495 if (ins(d, "F_SETOWN", (long)F_SETOWN)) return -1;
496 #endif
497 #ifdef F_GETSIG
498 if (ins(d, "F_GETSIG", (long)F_GETSIG)) return -1;
499 #endif
500 #ifdef F_SETSIG
501 if (ins(d, "F_SETSIG", (long)F_SETSIG)) return -1;
502 #endif
503 #ifdef F_RDLCK
504 if (ins(d, "F_RDLCK", (long)F_RDLCK)) return -1;
505 #endif
506 #ifdef F_WRLCK
507 if (ins(d, "F_WRLCK", (long)F_WRLCK)) return -1;
508 #endif
509 #ifdef F_UNLCK
510 if (ins(d, "F_UNLCK", (long)F_UNLCK)) return -1;
511 #endif
512 /* LFS constants */
513 #ifdef F_GETLK64
514 if (ins(d, "F_GETLK64", (long)F_GETLK64)) return -1;
515 #endif
516 #ifdef F_SETLK64
517 if (ins(d, "F_SETLK64", (long)F_SETLK64)) return -1;
518 #endif
519 #ifdef F_SETLKW64
520 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 if (ins(d, "FASYNC", (long)FASYNC)) return -1;
525 #endif
526 #ifdef F_SETLEASE
527 if (ins(d, "F_SETLEASE", (long)F_SETLEASE)) return -1;
528 #endif
529 #ifdef F_GETLEASE
530 if (ins(d, "F_GETLEASE", (long)F_GETLEASE)) return -1;
531 #endif
532 #ifdef F_NOTIFY
533 if (ins(d, "F_NOTIFY", (long)F_NOTIFY)) return -1;
534 #endif
535 /* Old BSD flock(). */
536 #ifdef F_EXLCK
537 if (ins(d, "F_EXLCK", (long)F_EXLCK)) return -1;
538 #endif
539 #ifdef F_SHLCK
540 if (ins(d, "F_SHLCK", (long)F_SHLCK)) return -1;
541 #endif
543 /* OS X (and maybe others) let you tell the storage device to flush to physical media */
544 #ifdef F_FULLFSYNC
545 if (ins(d, "F_FULLFSYNC", (long)F_FULLFSYNC)) return -1;
546 #endif
548 /* For F_{GET|SET}FL */
549 #ifdef FD_CLOEXEC
550 if (ins(d, "FD_CLOEXEC", (long)FD_CLOEXEC)) return -1;
551 #endif
553 /* For F_NOTIFY */
554 #ifdef DN_ACCESS
555 if (ins(d, "DN_ACCESS", (long)DN_ACCESS)) return -1;
556 #endif
557 #ifdef DN_MODIFY
558 if (ins(d, "DN_MODIFY", (long)DN_MODIFY)) return -1;
559 #endif
560 #ifdef DN_CREATE
561 if (ins(d, "DN_CREATE", (long)DN_CREATE)) return -1;
562 #endif
563 #ifdef DN_DELETE
564 if (ins(d, "DN_DELETE", (long)DN_DELETE)) return -1;
565 #endif
566 #ifdef DN_RENAME
567 if (ins(d, "DN_RENAME", (long)DN_RENAME)) return -1;
568 #endif
569 #ifdef DN_ATTRIB
570 if (ins(d, "DN_ATTRIB", (long)DN_ATTRIB)) return -1;
571 #endif
572 #ifdef DN_MULTISHOT
573 if (ins(d, "DN_MULTISHOT", (long)DN_MULTISHOT)) return -1;
574 #endif
576 #ifdef HAVE_STROPTS_H
577 /* Unix 98 guarantees that these are in stropts.h. */
578 INS(I_PUSH);
579 INS(I_POP);
580 INS(I_LOOK);
581 INS(I_FLUSH);
582 INS(I_FLUSHBAND);
583 INS(I_SETSIG);
584 INS(I_GETSIG);
585 INS(I_FIND);
586 INS(I_PEEK);
587 INS(I_SRDOPT);
588 INS(I_GRDOPT);
589 INS(I_NREAD);
590 INS(I_FDINSERT);
591 INS(I_STR);
592 INS(I_SWROPT);
593 #ifdef I_GWROPT
594 /* despite the comment above, old-ish glibcs miss a couple... */
595 INS(I_GWROPT);
596 #endif
597 INS(I_SENDFD);
598 INS(I_RECVFD);
599 INS(I_LIST);
600 INS(I_ATMARK);
601 INS(I_CKBAND);
602 INS(I_GETBAND);
603 INS(I_CANPUT);
604 INS(I_SETCLTIME);
605 #ifdef I_GETCLTIME
606 INS(I_GETCLTIME);
607 #endif
608 INS(I_LINK);
609 INS(I_UNLINK);
610 INS(I_PLINK);
611 INS(I_PUNLINK);
612 #endif
614 return 0;
618 static struct PyModuleDef fcntlmodule = {
619 PyModuleDef_HEAD_INIT,
620 "fcntl",
621 module_doc,
623 fcntl_methods,
624 NULL,
625 NULL,
626 NULL,
627 NULL
630 PyMODINIT_FUNC
631 PyInit_fcntl(void)
633 PyObject *m, *d;
635 /* Create the module and add the functions and documentation */
636 m = PyModule_Create(&fcntlmodule);
637 if (m == NULL)
638 return NULL;
640 /* Add some symbolic constants to the module */
641 d = PyModule_GetDict(m);
642 all_ins(d);
643 return m;