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|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
)) {
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, 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.
119 char buf
[IOCTL_BUFSZ
+1]; /* argument plus NUL byte */
121 if (PyArg_ParseTuple(args
, "O&Iw#|i:ioctl",
122 conv_descriptor
, &fd
, &code
,
123 &str
, &len
, &mutate_arg
)) {
127 if (len
<= IOCTL_BUFSZ
) {
128 memcpy(buf
, str
, len
);
137 if (len
> IOCTL_BUFSZ
) {
138 PyErr_SetString(PyExc_ValueError
,
139 "ioctl string arg too long");
143 memcpy(buf
, str
, len
);
149 Py_BEGIN_ALLOW_THREADS
/* think array.resize() */
150 ret
= ioctl(fd
, code
, arg
);
154 ret
= ioctl(fd
, code
, arg
);
156 if (mutate_arg
&& (len
< IOCTL_BUFSZ
)) {
157 memcpy(str
, buf
, len
);
160 PyErr_SetFromErrno(PyExc_IOError
);
164 return PyInt_FromLong(ret
);
167 return PyString_FromStringAndSize(buf
, len
);
172 if (PyArg_ParseTuple(args
, "O&Is#:ioctl",
173 conv_descriptor
, &fd
, &code
, &str
, &len
)) {
174 if (len
> IOCTL_BUFSZ
) {
175 PyErr_SetString(PyExc_ValueError
,
176 "ioctl string arg too long");
179 memcpy(buf
, str
, len
);
181 Py_BEGIN_ALLOW_THREADS
182 ret
= ioctl(fd
, code
, buf
);
185 PyErr_SetFromErrno(PyExc_IOError
);
188 return PyString_FromStringAndSize(buf
, len
);
193 if (!PyArg_ParseTuple(args
,
194 "O&I|i;ioctl requires a file or file descriptor,"
195 " an integer and optionally an integer or buffer argument",
196 conv_descriptor
, &fd
, &code
, &arg
)) {
199 Py_BEGIN_ALLOW_THREADS
201 ret
= ioctl(fd
, code
, (void *)arg
);
203 ret
= ioctl(fd
, code
, arg
);
207 PyErr_SetFromErrno(PyExc_IOError
);
210 return PyInt_FromLong((long)ret
);
214 PyDoc_STRVAR(ioctl_doc
,
215 "ioctl(fd, opt[, arg[, mutate_flag]])\n\
217 Perform the requested operation on file descriptor fd. The operation is\n\
218 defined by opt and is operating system dependent. Typically these codes are\n\
219 retrieved from the fcntl or termios library modules.\n\
221 The argument arg is optional, and defaults to 0; it may be an int or a\n\
222 buffer containing character data (most likely a string or an array). \n\
224 If the argument is a mutable buffer (such as an array) and if the\n\
225 mutate_flag argument (which is only allowed in this case) is true then the\n\
226 buffer is (in effect) passed to the operating system and changes made by\n\
227 the OS will be reflected in the contents of the buffer after the call has\n\
228 returned. The return value is the integer returned by the ioctl system\n\
231 If the argument is a mutable buffer and the mutable_flag argument is not\n\
232 passed or is false, the behavior is as if a string had been passed. This\n\
233 behavior will change in future releases of Python.\n\
235 If the argument is an immutable buffer (most likely a string) then a copy\n\
236 of the buffer is passed to the operating system and the return value is a\n\
237 string of the same length containing whatever the operating system put in\n\
238 the buffer. The length of the arg buffer in this case is not allowed to\n\
239 exceed 1024 bytes.\n\
241 If the arg given is an integer or if none is specified, the result value is\n\
242 an integer corresponding to the return value of the ioctl call in the C\n\
246 /* flock(fd, operation) */
249 fcntl_flock(PyObject
*self
, PyObject
*args
)
255 if (!PyArg_ParseTuple(args
, "O&i:flock",
256 conv_descriptor
, &fd
, &code
))
260 Py_BEGIN_ALLOW_THREADS
261 ret
= flock(fd
, code
);
266 #define LOCK_SH 1 /* shared lock */
267 #define LOCK_EX 2 /* exclusive lock */
268 #define LOCK_NB 4 /* don't block when locking */
269 #define LOCK_UN 8 /* unlock */
275 else if (code
& LOCK_SH
)
277 else if (code
& LOCK_EX
)
280 PyErr_SetString(PyExc_ValueError
,
281 "unrecognized flock argument");
284 l
.l_whence
= l
.l_start
= l
.l_len
= 0;
285 Py_BEGIN_ALLOW_THREADS
286 ret
= fcntl(fd
, (code
& LOCK_NB
) ? F_SETLK
: F_SETLKW
, &l
);
289 #endif /* HAVE_FLOCK */
291 PyErr_SetFromErrno(PyExc_IOError
);
298 PyDoc_STRVAR(flock_doc
,
299 "flock(fd, operation)\n\
301 Perform the lock operation op on file descriptor fd. See the Unix \n\
302 manual page for flock(3) for details. (On some systems, this function is\n\
303 emulated using fcntl().)");
306 /* lockf(fd, operation) */
308 fcntl_lockf(PyObject
*self
, PyObject
*args
)
310 int fd
, code
, ret
, whence
= 0;
311 PyObject
*lenobj
= NULL
, *startobj
= NULL
;
313 if (!PyArg_ParseTuple(args
, "O&i|OOi:lockf",
314 conv_descriptor
, &fd
, &code
,
315 &lenobj
, &startobj
, &whence
))
318 #if defined(PYOS_OS2) && defined(PYCC_GCC)
319 PyErr_SetString(PyExc_NotImplementedError
,
320 "lockf not supported on OS/2 (EMX)");
324 #define LOCK_SH 1 /* shared lock */
325 #define LOCK_EX 2 /* exclusive lock */
326 #define LOCK_NB 4 /* don't block when locking */
327 #define LOCK_UN 8 /* unlock */
333 else if (code
& LOCK_SH
)
335 else if (code
& LOCK_EX
)
338 PyErr_SetString(PyExc_ValueError
,
339 "unrecognized lockf argument");
342 l
.l_start
= l
.l_len
= 0;
343 if (startobj
!= NULL
) {
344 #if !defined(HAVE_LARGEFILE_SUPPORT)
345 l
.l_start
= PyInt_AsLong(startobj
);
347 l
.l_start
= PyLong_Check(startobj
) ?
348 PyLong_AsLongLong(startobj
) :
349 PyInt_AsLong(startobj
);
351 if (PyErr_Occurred())
354 if (lenobj
!= NULL
) {
355 #if !defined(HAVE_LARGEFILE_SUPPORT)
356 l
.l_len
= PyInt_AsLong(lenobj
);
358 l
.l_len
= PyLong_Check(lenobj
) ?
359 PyLong_AsLongLong(lenobj
) :
360 PyInt_AsLong(lenobj
);
362 if (PyErr_Occurred())
366 Py_BEGIN_ALLOW_THREADS
367 ret
= fcntl(fd
, (code
& LOCK_NB
) ? F_SETLK
: F_SETLKW
, &l
);
371 PyErr_SetFromErrno(PyExc_IOError
);
376 #endif /* defined(PYOS_OS2) && defined(PYCC_GCC) */
379 PyDoc_STRVAR(lockf_doc
,
380 "lockf (fd, operation, length=0, start=0, whence=0)\n\
382 This is essentially a wrapper around the fcntl() locking calls. fd is the\n\
383 file descriptor of the file to lock or unlock, and operation is one of the\n\
387 LOCK_SH - acquire a shared lock\n\
388 LOCK_EX - acquire an exclusive lock\n\
390 When operation is LOCK_SH or LOCK_EX, it can also be bitwise ORed with\n\
391 LOCK_NB to avoid blocking on lock acquisition. If LOCK_NB is used and the\n\
392 lock cannot be acquired, an IOError will be raised and the exception will\n\
393 have an errno attribute set to EACCES or EAGAIN (depending on the operating\n\
394 system -- for portability, check for either value).\n\
396 length is the number of bytes to lock, with the default meaning to lock to\n\
397 EOF. start is the byte offset, relative to whence, to that the lock\n\
398 starts. whence is as with fileobj.seek(), specifically:\n\
400 0 - relative to the start of the file (SEEK_SET)\n\
401 1 - relative to the current buffer position (SEEK_CUR)\n\
402 2 - relative to the end of the file (SEEK_END)");
404 /* List of functions */
406 static PyMethodDef fcntl_methods
[] = {
407 {"fcntl", fcntl_fcntl
, METH_VARARGS
, fcntl_doc
},
408 {"ioctl", fcntl_ioctl
, METH_VARARGS
, ioctl_doc
},
409 {"flock", fcntl_flock
, METH_VARARGS
, flock_doc
},
410 {"lockf", fcntl_lockf
, METH_VARARGS
, lockf_doc
},
411 {NULL
, NULL
} /* sentinel */
415 PyDoc_STRVAR(module_doc
,
416 "This module performs file control and I/O control on file \n\
417 descriptors. It is an interface to the fcntl() and ioctl() Unix\n\
418 routines. File descriptors can be obtained with the fileno() method of\n\
419 a file or socket object.");
421 /* Module initialisation */
424 ins(PyObject
* d
, char* symbol
, long value
)
426 PyObject
* v
= PyInt_FromLong(value
);
427 if (!v
|| PyDict_SetItemString(d
, symbol
, v
) < 0)
434 #define INS(x) if (ins(d, #x, (long)x)) return -1
439 if (ins(d
, "LOCK_SH", (long)LOCK_SH
)) return -1;
440 if (ins(d
, "LOCK_EX", (long)LOCK_EX
)) return -1;
441 if (ins(d
, "LOCK_NB", (long)LOCK_NB
)) return -1;
442 if (ins(d
, "LOCK_UN", (long)LOCK_UN
)) return -1;
443 /* GNU extensions, as of glibc 2.2.4 */
445 if (ins(d
, "LOCK_MAND", (long)LOCK_MAND
)) return -1;
448 if (ins(d
, "LOCK_READ", (long)LOCK_READ
)) return -1;
451 if (ins(d
, "LOCK_WRITE", (long)LOCK_WRITE
)) return -1;
454 if (ins(d
, "LOCK_RW", (long)LOCK_RW
)) return -1;
458 if (ins(d
, "F_DUPFD", (long)F_DUPFD
)) return -1;
461 if (ins(d
, "F_GETFD", (long)F_GETFD
)) return -1;
464 if (ins(d
, "F_SETFD", (long)F_SETFD
)) return -1;
467 if (ins(d
, "F_GETFL", (long)F_GETFL
)) return -1;
470 if (ins(d
, "F_SETFL", (long)F_SETFL
)) return -1;
473 if (ins(d
, "F_GETLK", (long)F_GETLK
)) return -1;
476 if (ins(d
, "F_SETLK", (long)F_SETLK
)) return -1;
479 if (ins(d
, "F_SETLKW", (long)F_SETLKW
)) return -1;
482 if (ins(d
, "F_GETOWN", (long)F_GETOWN
)) return -1;
485 if (ins(d
, "F_SETOWN", (long)F_SETOWN
)) return -1;
488 if (ins(d
, "F_GETSIG", (long)F_GETSIG
)) return -1;
491 if (ins(d
, "F_SETSIG", (long)F_SETSIG
)) return -1;
494 if (ins(d
, "F_RDLCK", (long)F_RDLCK
)) return -1;
497 if (ins(d
, "F_WRLCK", (long)F_WRLCK
)) return -1;
500 if (ins(d
, "F_UNLCK", (long)F_UNLCK
)) return -1;
504 if (ins(d
, "F_GETLK64", (long)F_GETLK64
)) return -1;
507 if (ins(d
, "F_SETLK64", (long)F_SETLK64
)) return -1;
510 if (ins(d
, "F_SETLKW64", (long)F_SETLKW64
)) return -1;
512 /* GNU extensions, as of glibc 2.2.4. */
514 if (ins(d
, "FASYNC", (long)FASYNC
)) return -1;
517 if (ins(d
, "F_SETLEASE", (long)F_SETLEASE
)) return -1;
520 if (ins(d
, "F_GETLEASE", (long)F_GETLEASE
)) return -1;
523 if (ins(d
, "F_NOTIFY", (long)F_NOTIFY
)) return -1;
525 /* Old BSD flock(). */
527 if (ins(d
, "F_EXLCK", (long)F_EXLCK
)) return -1;
530 if (ins(d
, "F_SHLCK", (long)F_SHLCK
)) return -1;
533 /* OS X (and maybe others) let you tell the storage device to flush to physical media */
535 if (ins(d
, "F_FULLFSYNC", (long)F_FULLFSYNC
)) return -1;
538 /* For F_{GET|SET}FL */
540 if (ins(d
, "FD_CLOEXEC", (long)FD_CLOEXEC
)) return -1;
545 if (ins(d
, "DN_ACCESS", (long)DN_ACCESS
)) return -1;
548 if (ins(d
, "DN_MODIFY", (long)DN_MODIFY
)) return -1;
551 if (ins(d
, "DN_CREATE", (long)DN_CREATE
)) return -1;
554 if (ins(d
, "DN_DELETE", (long)DN_DELETE
)) return -1;
557 if (ins(d
, "DN_RENAME", (long)DN_RENAME
)) return -1;
560 if (ins(d
, "DN_ATTRIB", (long)DN_ATTRIB
)) return -1;
563 if (ins(d
, "DN_MULTISHOT", (long)DN_MULTISHOT
)) return -1;
566 #ifdef HAVE_STROPTS_H
567 /* Unix 98 guarantees that these are in stropts.h. */
584 /* despite the comment above, old-ish glibcs miss a couple... */
612 /* Create the module and add the functions and documentation */
613 m
= Py_InitModule3("fcntl", fcntl_methods
, module_doc
);
617 /* Add some symbolic constants to the module */
618 d
= PyModule_GetDict(m
);