10 #include <sys/ioctl.h>
17 conv_descriptor(PyObject
*object
, int *target
)
19 int fd
= PyObject_AsFileDescriptor(object
);
28 /* fcntl(fd, opt, [arg]) */
31 fcntl_fcntl(PyObject
*self
, PyObject
*args
)
41 if (PyArg_ParseTuple(args
, "O&is#:fcntl",
42 conv_descriptor
, &fd
, &code
, &str
, &len
)) {
43 if (len
> sizeof buf
) {
44 PyErr_SetString(PyExc_ValueError
,
45 "fcntl string arg too long");
48 memcpy(buf
, str
, len
);
49 Py_BEGIN_ALLOW_THREADS
50 ret
= fcntl(fd
, code
, buf
);
53 PyErr_SetFromErrno(PyExc_IOError
);
56 return PyString_FromStringAndSize(buf
, len
);
61 if (!PyArg_ParseTuple(args
,
62 "O&i|i;fcntl requires a file or file descriptor,"
63 " an integer and optionally a third integer or a string",
64 conv_descriptor
, &fd
, &code
, &arg
)) {
67 Py_BEGIN_ALLOW_THREADS
68 ret
= fcntl(fd
, code
, arg
);
71 PyErr_SetFromErrno(PyExc_IOError
);
74 return PyInt_FromLong((long)ret
);
77 PyDoc_STRVAR(fcntl_doc
,
78 "fcntl(fd, opt, [arg])\n\
80 Perform the requested operation on file descriptor fd. The operation\n\
81 is defined by op and is operating system dependent. These constants are\n\
82 available from the fcntl module. The argument arg is optional, and\n\
83 defaults to 0; it may be an int or a string. If arg is given as a string,\n\
84 the return value of fcntl is a string of that length, containing the\n\
85 resulting value put in the arg buffer by the operating system.The length\n\
86 of the arg string is not allowed to exceed 1024 bytes. If the arg given\n\
87 is an integer or if none is specified, the result value is an integer\n\
88 corresponding to the return value of the fcntl call in the C code.");
91 /* ioctl(fd, opt, [arg]) */
94 fcntl_ioctl(PyObject
*self
, PyObject
*args
)
105 if (PyArg_ParseTuple(args
, "O&Iw#|i:ioctl",
106 conv_descriptor
, &fd
, &code
,
107 &str
, &len
, &mutate_arg
)) {
111 if (len
<= sizeof buf
) {
112 memcpy(buf
, str
, len
);
120 if (len
> sizeof buf
) {
121 PyErr_SetString(PyExc_ValueError
,
122 "ioctl string arg too long");
126 memcpy(buf
, str
, len
);
131 Py_BEGIN_ALLOW_THREADS
/* think array.resize() */
132 ret
= ioctl(fd
, code
, arg
);
136 ret
= ioctl(fd
, code
, arg
);
138 if (mutate_arg
&& (len
< sizeof buf
)) {
139 memcpy(str
, buf
, len
);
142 PyErr_SetFromErrno(PyExc_IOError
);
146 return PyInt_FromLong(ret
);
149 return PyString_FromStringAndSize(buf
, len
);
154 if (PyArg_ParseTuple(args
, "O&Is#:ioctl",
155 conv_descriptor
, &fd
, &code
, &str
, &len
)) {
156 if (len
> sizeof buf
) {
157 PyErr_SetString(PyExc_ValueError
,
158 "ioctl string arg too long");
161 memcpy(buf
, str
, len
);
162 Py_BEGIN_ALLOW_THREADS
163 ret
= ioctl(fd
, code
, buf
);
166 PyErr_SetFromErrno(PyExc_IOError
);
169 return PyString_FromStringAndSize(buf
, len
);
174 if (!PyArg_ParseTuple(args
,
175 "O&I|i;ioctl requires a file or file descriptor,"
176 " an integer and optionally an integer or buffer argument",
177 conv_descriptor
, &fd
, &code
, &arg
)) {
180 Py_BEGIN_ALLOW_THREADS
182 ret
= ioctl(fd
, code
, (void *)arg
);
184 ret
= ioctl(fd
, code
, arg
);
188 PyErr_SetFromErrno(PyExc_IOError
);
191 return PyInt_FromLong((long)ret
);
194 PyDoc_STRVAR(ioctl_doc
,
195 "ioctl(fd, opt[, arg[, mutate_flag]])\n\
197 Perform the requested operation on file descriptor fd. The operation is\n\
198 defined by opt and is operating system dependent. Typically these codes are\n\
199 retrieved from the fcntl or termios library modules.\n\
201 The argument arg is optional, and defaults to 0; it may be an int or a\n\
202 buffer containing character data (most likely a string or an array). \n\
204 If the argument is a mutable buffer (such as an array) and if the\n\
205 mutate_flag argument (which is only allowed in this case) is true then the\n\
206 buffer is (in effect) passed to the operating system and changes made by\n\
207 the OS will be reflected in the contents of the buffer after the call has\n\
208 returned. The return value is the integer returned by the ioctl system\n\
211 If the argument is a mutable buffer and the mutable_flag argument is not\n\
212 passed or is false, the behavior is as if a string had been passed. This\n\
213 behavior will change in future releases of Python.\n\
215 If the argument is an immutable buffer (most likely a string) then a copy\n\
216 of the buffer is passed to the operating system and the return value is a\n\
217 string of the same length containing whatever the operating system put in\n\
218 the buffer. The length of the arg buffer in this case is not allowed to\n\
219 exceed 1024 bytes.\n\
221 If the arg given is an integer or if none is specified, the result value is\n\
222 an integer corresponding to the return value of the ioctl call in the C\n\
226 /* flock(fd, operation) */
229 fcntl_flock(PyObject
*self
, PyObject
*args
)
235 if (!PyArg_ParseTuple(args
, "O&i:flock",
236 conv_descriptor
, &fd
, &code
))
240 Py_BEGIN_ALLOW_THREADS
241 ret
= flock(fd
, code
);
246 #define LOCK_SH 1 /* shared lock */
247 #define LOCK_EX 2 /* exclusive lock */
248 #define LOCK_NB 4 /* don't block when locking */
249 #define LOCK_UN 8 /* unlock */
255 else if (code
& LOCK_SH
)
257 else if (code
& LOCK_EX
)
260 PyErr_SetString(PyExc_ValueError
,
261 "unrecognized flock argument");
264 l
.l_whence
= l
.l_start
= l
.l_len
= 0;
265 Py_BEGIN_ALLOW_THREADS
266 ret
= fcntl(fd
, (code
& LOCK_NB
) ? F_SETLK
: F_SETLKW
, &l
);
269 #endif /* HAVE_FLOCK */
271 PyErr_SetFromErrno(PyExc_IOError
);
278 PyDoc_STRVAR(flock_doc
,
279 "flock(fd, operation)\n\
281 Perform the lock operation op on file descriptor fd. See the Unix \n\
282 manual flock(3) for details. (On some systems, this function is\n\
283 emulated using fcntl().)");
286 /* lockf(fd, operation) */
288 fcntl_lockf(PyObject
*self
, PyObject
*args
)
290 int fd
, code
, ret
, whence
= 0;
291 PyObject
*lenobj
= NULL
, *startobj
= NULL
;
293 if (!PyArg_ParseTuple(args
, "O&i|OOi:lockf",
294 conv_descriptor
, &fd
, &code
,
295 &lenobj
, &startobj
, &whence
))
298 #if defined(PYOS_OS2) && defined(PYCC_GCC)
299 PyErr_SetString(PyExc_NotImplementedError
,
300 "lockf not supported on OS/2 (EMX)");
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 */
313 else if (code
& LOCK_SH
)
315 else if (code
& LOCK_EX
)
318 PyErr_SetString(PyExc_ValueError
,
319 "unrecognized flock argument");
322 l
.l_start
= l
.l_len
= 0;
323 if (startobj
!= NULL
) {
324 #if !defined(HAVE_LARGEFILE_SUPPORT)
325 l
.l_start
= PyInt_AsLong(startobj
);
327 l
.l_start
= PyLong_Check(startobj
) ?
328 PyLong_AsLongLong(startobj
) :
329 PyInt_AsLong(startobj
);
331 if (PyErr_Occurred())
334 if (lenobj
!= NULL
) {
335 #if !defined(HAVE_LARGEFILE_SUPPORT)
336 l
.l_len
= PyInt_AsLong(lenobj
);
338 l
.l_len
= PyLong_Check(lenobj
) ?
339 PyLong_AsLongLong(lenobj
) :
340 PyInt_AsLong(lenobj
);
342 if (PyErr_Occurred())
346 Py_BEGIN_ALLOW_THREADS
347 ret
= fcntl(fd
, (code
& LOCK_NB
) ? F_SETLK
: F_SETLKW
, &l
);
351 PyErr_SetFromErrno(PyExc_IOError
);
356 #endif /* defined(PYOS_OS2) && defined(PYCC_GCC) */
359 PyDoc_STRVAR(lockf_doc
,
360 "lockf (fd, operation, length=0, start=0, whence=0)\n\
362 This is essentially a wrapper around the fcntl() locking calls. fd is the\n\
363 file descriptor of the file to lock or unlock, and operation is one of the\n\
367 LOCK_SH - acquire a shared lock\n\
368 LOCK_EX - acquire an exclusive lock\n\
370 When operation is LOCK_SH or LOCK_EX, it can also be bit-wise OR'd with\n\
371 LOCK_NB to avoid blocking on lock acquisition. If LOCK_NB is used and the\n\
372 lock cannot be acquired, an IOError will be raised and the exception will\n\
373 have an errno attribute set to EACCES or EAGAIN (depending on the operating\n\
374 system -- for portability, check for either value).\n\
376 length is the number of bytes to lock, with the default meaning to lock to\n\
377 EOF. start is the byte offset, relative to whence, to that the lock\n\
378 starts. whence is as with fileobj.seek(), specifically:\n\
380 0 - relative to the start of the file (SEEK_SET)\n\
381 1 - relative to the current buffer position (SEEK_CUR)\n\
382 2 - relative to the end of the file (SEEK_END)");
384 /* List of functions */
386 static PyMethodDef fcntl_methods
[] = {
387 {"fcntl", fcntl_fcntl
, METH_VARARGS
, fcntl_doc
},
388 {"ioctl", fcntl_ioctl
, METH_VARARGS
, ioctl_doc
},
389 {"flock", fcntl_flock
, METH_VARARGS
, flock_doc
},
390 {"lockf", fcntl_lockf
, METH_VARARGS
, lockf_doc
},
391 {NULL
, NULL
} /* sentinel */
395 PyDoc_STRVAR(module_doc
,
396 "This module performs file control and I/O control on file \n\
397 descriptors. It is an interface to the fcntl() and ioctl() Unix\n\
398 routines. File descriptors can be obtained with the fileno() method of\n\
399 a file or socket object.");
401 /* Module initialisation */
404 ins(PyObject
* d
, char* symbol
, long value
)
406 PyObject
* v
= PyInt_FromLong(value
);
407 if (!v
|| PyDict_SetItemString(d
, symbol
, v
) < 0)
414 #define INS(x) if (ins(d, #x, (long)x)) return -1
419 if (ins(d
, "LOCK_SH", (long)LOCK_SH
)) return -1;
420 if (ins(d
, "LOCK_EX", (long)LOCK_EX
)) return -1;
421 if (ins(d
, "LOCK_NB", (long)LOCK_NB
)) return -1;
422 if (ins(d
, "LOCK_UN", (long)LOCK_UN
)) return -1;
423 /* GNU extensions, as of glibc 2.2.4 */
425 if (ins(d
, "LOCK_MAND", (long)LOCK_MAND
)) return -1;
428 if (ins(d
, "LOCK_READ", (long)LOCK_READ
)) return -1;
431 if (ins(d
, "LOCK_WRITE", (long)LOCK_WRITE
)) return -1;
434 if (ins(d
, "LOCK_RW", (long)LOCK_RW
)) return -1;
438 if (ins(d
, "F_DUPFD", (long)F_DUPFD
)) return -1;
441 if (ins(d
, "F_GETFD", (long)F_GETFD
)) return -1;
444 if (ins(d
, "F_SETFD", (long)F_SETFD
)) return -1;
447 if (ins(d
, "F_GETFL", (long)F_GETFL
)) return -1;
450 if (ins(d
, "F_SETFL", (long)F_SETFL
)) return -1;
453 if (ins(d
, "F_GETLK", (long)F_GETLK
)) return -1;
456 if (ins(d
, "F_SETLK", (long)F_SETLK
)) return -1;
459 if (ins(d
, "F_SETLKW", (long)F_SETLKW
)) return -1;
462 if (ins(d
, "F_GETOWN", (long)F_GETOWN
)) return -1;
465 if (ins(d
, "F_SETOWN", (long)F_SETOWN
)) return -1;
468 if (ins(d
, "F_GETSIG", (long)F_GETSIG
)) return -1;
471 if (ins(d
, "F_SETSIG", (long)F_SETSIG
)) return -1;
474 if (ins(d
, "F_RDLCK", (long)F_RDLCK
)) return -1;
477 if (ins(d
, "F_WRLCK", (long)F_WRLCK
)) return -1;
480 if (ins(d
, "F_UNLCK", (long)F_UNLCK
)) return -1;
484 if (ins(d
, "F_GETLK64", (long)F_GETLK64
)) return -1;
487 if (ins(d
, "F_SETLK64", (long)F_SETLK64
)) return -1;
490 if (ins(d
, "F_SETLKW64", (long)F_SETLKW64
)) return -1;
492 /* GNU extensions, as of glibc 2.2.4. */
494 if (ins(d
, "F_SETLEASE", (long)F_SETLEASE
)) return -1;
497 if (ins(d
, "F_GETLEASE", (long)F_GETLEASE
)) return -1;
500 if (ins(d
, "F_NOTIFY", (long)F_NOTIFY
)) return -1;
502 /* Old BSD flock(). */
504 if (ins(d
, "F_EXLCK", (long)F_EXLCK
)) return -1;
507 if (ins(d
, "F_SHLCK", (long)F_SHLCK
)) return -1;
510 /* For F_{GET|SET}FL */
512 if (ins(d
, "FD_CLOEXEC", (long)FD_CLOEXEC
)) return -1;
517 if (ins(d
, "DN_ACCESS", (long)DN_ACCESS
)) return -1;
520 if (ins(d
, "DN_MODIFY", (long)DN_MODIFY
)) return -1;
523 if (ins(d
, "DN_CREATE", (long)DN_CREATE
)) return -1;
526 if (ins(d
, "DN_DELETE", (long)DN_DELETE
)) return -1;
529 if (ins(d
, "DN_RENAME", (long)DN_RENAME
)) return -1;
532 if (ins(d
, "DN_ATTRIB", (long)DN_ATTRIB
)) return -1;
535 if (ins(d
, "DN_MULTISHOT", (long)DN_MULTISHOT
)) return -1;
538 #ifdef HAVE_STROPTS_H
539 /* Unix 98 guarantees that these are in stropts.h. */
556 /* despite the comment above, old-ish glibcs miss a couple... */
584 /* Create the module and add the functions and documentation */
585 m
= Py_InitModule3("fcntl", fcntl_methods
, module_doc
);
589 /* Add some symbolic constants to the module */
590 d
= PyModule_GetDict(m
);