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, 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);