4 #define PY_SSIZE_T_CLEAN
12 #include <sys/ioctl.h>
19 conv_descriptor(PyObject
*object
, int *target
)
21 int fd
= PyObject_AsFileDescriptor(object
);
30 /* fcntl(fd, opt, [arg]) */
33 fcntl_fcntl(PyObject
*self
, PyObject
*args
)
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");
50 memcpy(buf
, str
, len
);
51 Py_BEGIN_ALLOW_THREADS
52 ret
= fcntl(fd
, code
, buf
);
55 PyErr_SetFromErrno(PyExc_IOError
);
58 return PyString_FromStringAndSize(buf
, len
);
63 if (!PyArg_ParseTuple(args
,
64 "O&i|i;fcntl requires a file or file descriptor,"
65 " an integer and optionally a third integer or a string",
66 conv_descriptor
, &fd
, &code
, &arg
)) {
69 Py_BEGIN_ALLOW_THREADS
70 ret
= fcntl(fd
, code
, arg
);
73 PyErr_SetFromErrno(PyExc_IOError
);
76 return PyInt_FromLong((long)ret
);
79 PyDoc_STRVAR(fcntl_doc
,
80 "fcntl(fd, opt, [arg])\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]) */
96 fcntl_ioctl(PyObject
*self
, PyObject
*args
)
98 #define IOCTL_BUFSZ 1024
100 /* In PyArg_ParseTuple below, use the unsigned int 'I' format for
101 the signed int 'code' variable, because Python turns 0x8000000
102 into a large positive number (PyLong, or PyInt on 64-bit
103 platforms,) whereas C expects it to be a negative int */
110 char buf
[IOCTL_BUFSZ
+1]; /* argument plus NUL byte */
112 if (PyArg_ParseTuple(args
, "O&Iw#|i:ioctl",
113 conv_descriptor
, &fd
, &code
,
114 &str
, &len
, &mutate_arg
)) {
118 if (len
<= IOCTL_BUFSZ
) {
119 memcpy(buf
, str
, len
);
128 if (len
> IOCTL_BUFSZ
) {
129 PyErr_SetString(PyExc_ValueError
,
130 "ioctl string arg too long");
134 memcpy(buf
, str
, len
);
140 Py_BEGIN_ALLOW_THREADS
/* think array.resize() */
141 ret
= ioctl(fd
, code
, arg
);
145 ret
= ioctl(fd
, code
, arg
);
147 if (mutate_arg
&& (len
< IOCTL_BUFSZ
)) {
148 memcpy(str
, buf
, len
);
151 PyErr_SetFromErrno(PyExc_IOError
);
155 return PyInt_FromLong(ret
);
158 return PyString_FromStringAndSize(buf
, len
);
163 if (PyArg_ParseTuple(args
, "O&Is#:ioctl",
164 conv_descriptor
, &fd
, &code
, &str
, &len
)) {
165 if (len
> IOCTL_BUFSZ
) {
166 PyErr_SetString(PyExc_ValueError
,
167 "ioctl string arg too long");
170 memcpy(buf
, str
, len
);
172 Py_BEGIN_ALLOW_THREADS
173 ret
= ioctl(fd
, code
, buf
);
176 PyErr_SetFromErrno(PyExc_IOError
);
179 return PyString_FromStringAndSize(buf
, len
);
184 if (!PyArg_ParseTuple(args
,
185 "O&I|i;ioctl requires a file or file descriptor,"
186 " an integer and optionally an integer or buffer argument",
187 conv_descriptor
, &fd
, &code
, &arg
)) {
190 Py_BEGIN_ALLOW_THREADS
192 ret
= ioctl(fd
, code
, (void *)arg
);
194 ret
= ioctl(fd
, code
, arg
);
198 PyErr_SetFromErrno(PyExc_IOError
);
201 return PyInt_FromLong((long)ret
);
205 PyDoc_STRVAR(ioctl_doc
,
206 "ioctl(fd, opt[, arg[, mutate_flag]])\n\
208 Perform the requested operation on file descriptor fd. The operation is\n\
209 defined by opt and is operating system dependent. Typically these codes are\n\
210 retrieved from the fcntl or termios library modules.\n\
212 The argument arg is optional, and defaults to 0; it may be an int or a\n\
213 buffer containing character data (most likely a string or an array). \n\
215 If the argument is a mutable buffer (such as an array) and if the\n\
216 mutate_flag argument (which is only allowed in this case) is true then the\n\
217 buffer is (in effect) passed to the operating system and changes made by\n\
218 the OS will be reflected in the contents of the buffer after the call has\n\
219 returned. The return value is the integer returned by the ioctl system\n\
222 If the argument is a mutable buffer and the mutable_flag argument is not\n\
223 passed or is false, the behavior is as if a string had been passed. This\n\
224 behavior will change in future releases of Python.\n\
226 If the argument is an immutable buffer (most likely a string) then a copy\n\
227 of the buffer is passed to the operating system and the return value is a\n\
228 string of the same length containing whatever the operating system put in\n\
229 the buffer. The length of the arg buffer in this case is not allowed to\n\
230 exceed 1024 bytes.\n\
232 If the arg given is an integer or if none is specified, the result value is\n\
233 an integer corresponding to the return value of the ioctl call in the C\n\
237 /* flock(fd, operation) */
240 fcntl_flock(PyObject
*self
, PyObject
*args
)
246 if (!PyArg_ParseTuple(args
, "O&i:flock",
247 conv_descriptor
, &fd
, &code
))
251 Py_BEGIN_ALLOW_THREADS
252 ret
= flock(fd
, code
);
257 #define LOCK_SH 1 /* shared lock */
258 #define LOCK_EX 2 /* exclusive lock */
259 #define LOCK_NB 4 /* don't block when locking */
260 #define LOCK_UN 8 /* unlock */
266 else if (code
& LOCK_SH
)
268 else if (code
& LOCK_EX
)
271 PyErr_SetString(PyExc_ValueError
,
272 "unrecognized flock argument");
275 l
.l_whence
= l
.l_start
= l
.l_len
= 0;
276 Py_BEGIN_ALLOW_THREADS
277 ret
= fcntl(fd
, (code
& LOCK_NB
) ? F_SETLK
: F_SETLKW
, &l
);
280 #endif /* HAVE_FLOCK */
282 PyErr_SetFromErrno(PyExc_IOError
);
289 PyDoc_STRVAR(flock_doc
,
290 "flock(fd, operation)\n\
292 Perform the lock operation op on file descriptor fd. See the Unix \n\
293 manual page for flock(3) for details. (On some systems, this function is\n\
294 emulated using fcntl().)");
297 /* lockf(fd, operation) */
299 fcntl_lockf(PyObject
*self
, PyObject
*args
)
301 int fd
, code
, ret
, whence
= 0;
302 PyObject
*lenobj
= NULL
, *startobj
= NULL
;
304 if (!PyArg_ParseTuple(args
, "O&i|OOi:lockf",
305 conv_descriptor
, &fd
, &code
,
306 &lenobj
, &startobj
, &whence
))
309 #if defined(PYOS_OS2) && defined(PYCC_GCC)
310 PyErr_SetString(PyExc_NotImplementedError
,
311 "lockf not supported on OS/2 (EMX)");
315 #define LOCK_SH 1 /* shared lock */
316 #define LOCK_EX 2 /* exclusive lock */
317 #define LOCK_NB 4 /* don't block when locking */
318 #define LOCK_UN 8 /* unlock */
324 else if (code
& LOCK_SH
)
326 else if (code
& LOCK_EX
)
329 PyErr_SetString(PyExc_ValueError
,
330 "unrecognized lockf argument");
333 l
.l_start
= l
.l_len
= 0;
334 if (startobj
!= NULL
) {
335 #if !defined(HAVE_LARGEFILE_SUPPORT)
336 l
.l_start
= PyInt_AsLong(startobj
);
338 l
.l_start
= PyLong_Check(startobj
) ?
339 PyLong_AsLongLong(startobj
) :
340 PyInt_AsLong(startobj
);
342 if (PyErr_Occurred())
345 if (lenobj
!= NULL
) {
346 #if !defined(HAVE_LARGEFILE_SUPPORT)
347 l
.l_len
= PyInt_AsLong(lenobj
);
349 l
.l_len
= PyLong_Check(lenobj
) ?
350 PyLong_AsLongLong(lenobj
) :
351 PyInt_AsLong(lenobj
);
353 if (PyErr_Occurred())
357 Py_BEGIN_ALLOW_THREADS
358 ret
= fcntl(fd
, (code
& LOCK_NB
) ? F_SETLK
: F_SETLKW
, &l
);
362 PyErr_SetFromErrno(PyExc_IOError
);
367 #endif /* defined(PYOS_OS2) && defined(PYCC_GCC) */
370 PyDoc_STRVAR(lockf_doc
,
371 "lockf (fd, operation, length=0, start=0, whence=0)\n\
373 This is essentially a wrapper around the fcntl() locking calls. fd is the\n\
374 file descriptor of the file to lock or unlock, and operation is one of the\n\
378 LOCK_SH - acquire a shared lock\n\
379 LOCK_EX - acquire an exclusive lock\n\
381 When operation is LOCK_SH or LOCK_EX, it can also be bitwise ORed with\n\
382 LOCK_NB to avoid blocking on lock acquisition. If LOCK_NB is used and the\n\
383 lock cannot be acquired, an IOError will be raised and the exception will\n\
384 have an errno attribute set to EACCES or EAGAIN (depending on the operating\n\
385 system -- for portability, check for either value).\n\
387 length is the number of bytes to lock, with the default meaning to lock to\n\
388 EOF. start is the byte offset, relative to whence, to that the lock\n\
389 starts. whence is as with fileobj.seek(), specifically:\n\
391 0 - relative to the start of the file (SEEK_SET)\n\
392 1 - relative to the current buffer position (SEEK_CUR)\n\
393 2 - relative to the end of the file (SEEK_END)");
395 /* List of functions */
397 static PyMethodDef fcntl_methods
[] = {
398 {"fcntl", fcntl_fcntl
, METH_VARARGS
, fcntl_doc
},
399 {"ioctl", fcntl_ioctl
, METH_VARARGS
, ioctl_doc
},
400 {"flock", fcntl_flock
, METH_VARARGS
, flock_doc
},
401 {"lockf", fcntl_lockf
, METH_VARARGS
, lockf_doc
},
402 {NULL
, NULL
} /* sentinel */
406 PyDoc_STRVAR(module_doc
,
407 "This module performs file control and I/O control on file \n\
408 descriptors. It is an interface to the fcntl() and ioctl() Unix\n\
409 routines. File descriptors can be obtained with the fileno() method of\n\
410 a file or socket object.");
412 /* Module initialisation */
415 ins(PyObject
* d
, char* symbol
, long value
)
417 PyObject
* v
= PyInt_FromLong(value
);
418 if (!v
|| PyDict_SetItemString(d
, symbol
, v
) < 0)
425 #define INS(x) if (ins(d, #x, (long)x)) return -1
430 if (ins(d
, "LOCK_SH", (long)LOCK_SH
)) return -1;
431 if (ins(d
, "LOCK_EX", (long)LOCK_EX
)) return -1;
432 if (ins(d
, "LOCK_NB", (long)LOCK_NB
)) return -1;
433 if (ins(d
, "LOCK_UN", (long)LOCK_UN
)) return -1;
434 /* GNU extensions, as of glibc 2.2.4 */
436 if (ins(d
, "LOCK_MAND", (long)LOCK_MAND
)) return -1;
439 if (ins(d
, "LOCK_READ", (long)LOCK_READ
)) return -1;
442 if (ins(d
, "LOCK_WRITE", (long)LOCK_WRITE
)) return -1;
445 if (ins(d
, "LOCK_RW", (long)LOCK_RW
)) return -1;
449 if (ins(d
, "F_DUPFD", (long)F_DUPFD
)) return -1;
452 if (ins(d
, "F_GETFD", (long)F_GETFD
)) return -1;
455 if (ins(d
, "F_SETFD", (long)F_SETFD
)) return -1;
458 if (ins(d
, "F_GETFL", (long)F_GETFL
)) return -1;
461 if (ins(d
, "F_SETFL", (long)F_SETFL
)) return -1;
464 if (ins(d
, "F_GETLK", (long)F_GETLK
)) return -1;
467 if (ins(d
, "F_SETLK", (long)F_SETLK
)) return -1;
470 if (ins(d
, "F_SETLKW", (long)F_SETLKW
)) return -1;
473 if (ins(d
, "F_GETOWN", (long)F_GETOWN
)) return -1;
476 if (ins(d
, "F_SETOWN", (long)F_SETOWN
)) return -1;
479 if (ins(d
, "F_GETSIG", (long)F_GETSIG
)) return -1;
482 if (ins(d
, "F_SETSIG", (long)F_SETSIG
)) return -1;
485 if (ins(d
, "F_RDLCK", (long)F_RDLCK
)) return -1;
488 if (ins(d
, "F_WRLCK", (long)F_WRLCK
)) return -1;
491 if (ins(d
, "F_UNLCK", (long)F_UNLCK
)) return -1;
495 if (ins(d
, "F_GETLK64", (long)F_GETLK64
)) return -1;
498 if (ins(d
, "F_SETLK64", (long)F_SETLK64
)) return -1;
501 if (ins(d
, "F_SETLKW64", (long)F_SETLKW64
)) return -1;
503 /* GNU extensions, as of glibc 2.2.4. */
505 if (ins(d
, "F_SETLEASE", (long)F_SETLEASE
)) return -1;
508 if (ins(d
, "F_GETLEASE", (long)F_GETLEASE
)) return -1;
511 if (ins(d
, "F_NOTIFY", (long)F_NOTIFY
)) return -1;
513 /* Old BSD flock(). */
515 if (ins(d
, "F_EXLCK", (long)F_EXLCK
)) return -1;
518 if (ins(d
, "F_SHLCK", (long)F_SHLCK
)) return -1;
521 /* For F_{GET|SET}FL */
523 if (ins(d
, "FD_CLOEXEC", (long)FD_CLOEXEC
)) return -1;
528 if (ins(d
, "DN_ACCESS", (long)DN_ACCESS
)) return -1;
531 if (ins(d
, "DN_MODIFY", (long)DN_MODIFY
)) return -1;
534 if (ins(d
, "DN_CREATE", (long)DN_CREATE
)) return -1;
537 if (ins(d
, "DN_DELETE", (long)DN_DELETE
)) return -1;
540 if (ins(d
, "DN_RENAME", (long)DN_RENAME
)) return -1;
543 if (ins(d
, "DN_ATTRIB", (long)DN_ATTRIB
)) return -1;
546 if (ins(d
, "DN_MULTISHOT", (long)DN_MULTISHOT
)) return -1;
549 #ifdef HAVE_STROPTS_H
550 /* Unix 98 guarantees that these are in stropts.h. */
567 /* despite the comment above, old-ish glibcs miss a couple... */
595 /* Create the module and add the functions and documentation */
596 m
= Py_InitModule3("fcntl", fcntl_methods
, module_doc
);
600 /* Add some symbolic constants to the module */
601 d
= PyModule_GetDict(m
);