10 #ifdef HAVE_SYS_FILE_H
14 #include <sys/ioctl.h>
18 /* fcntl(fd, opt, [arg]) */
21 fcntl_fcntl(PyObject
*self
, PyObject
*args
)
31 if (PyArg_ParseTuple(args
, "iis#:fcntl", &fd
, &code
, &str
, &len
)) {
32 if (len
> sizeof buf
) {
33 PyErr_SetString(PyExc_ValueError
,
34 "fcntl string arg too long");
37 memcpy(buf
, str
, len
);
38 Py_BEGIN_ALLOW_THREADS
39 ret
= fcntl(fd
, code
, buf
);
42 PyErr_SetFromErrno(PyExc_IOError
);
45 return PyString_FromStringAndSize(buf
, len
);
50 if (!PyArg_ParseTuple(args
, "ii|i;fcntl requires 2 integers and optionally a third integer or a string",
54 Py_BEGIN_ALLOW_THREADS
55 ret
= fcntl(fd
, code
, arg
);
58 PyErr_SetFromErrno(PyExc_IOError
);
61 return PyInt_FromLong((long)ret
);
64 static char fcntl_doc
[] =
66 "fcntl(fd, opt, [arg])\n\
68 Perform the requested operation on file descriptor fd. The operation\n\
69 is defined by op and is operating system dependent. Typically these\n\
70 codes can be retrieved from the library module FCNTL. The argument arg\n\
71 is optional, and defaults to 0; it may be an int or a string. If arg is\n\
72 given as a string, the return value of fcntl is a string of that length,\n\
73 containing the resulting value put in the arg buffer by the operating system.\n\
74 The length of the arg string is not allowed to exceed 1024 bytes. If the arg\n\
75 given is an integer or if none is specified, the result value is an integer\n\
76 corresponding to the return value of the fcntl call in the C code.";
79 /* ioctl(fd, opt, [arg]) */
82 fcntl_ioctl(PyObject
*self
, PyObject
*args
)
92 if (PyArg_ParseTuple(args
, "iis#:ioctl", &fd
, &code
, &str
, &len
)) {
93 if (len
> sizeof buf
) {
94 PyErr_SetString(PyExc_ValueError
,
95 "ioctl string arg too long");
98 memcpy(buf
, str
, len
);
99 Py_BEGIN_ALLOW_THREADS
100 ret
= ioctl(fd
, code
, buf
);
103 PyErr_SetFromErrno(PyExc_IOError
);
106 return PyString_FromStringAndSize(buf
, len
);
111 if (!PyArg_ParseTuple(args
, "ii|i;ioctl requires 2 integers and optionally a third integer or a string",
115 Py_BEGIN_ALLOW_THREADS
116 ret
= ioctl(fd
, code
, arg
);
119 PyErr_SetFromErrno(PyExc_IOError
);
122 return PyInt_FromLong((long)ret
);
125 static char ioctl_doc
[] =
126 "ioctl(fd, opt, [arg])\n\
128 Perform the requested operation on file descriptor fd. The operation\n\
129 is defined by op and is operating system dependent. Typically these\n\
130 codes can be retrieved from the library module IOCTL. The argument arg\n\
131 is optional, and defaults to 0; it may be an int or a string. If arg is\n\
132 given as a string, the return value of ioctl is a string of that length,\n\
133 containing the resulting value put in the arg buffer by the operating system.\n\
134 The length of the arg string is not allowed to exceed 1024 bytes. If the arg\n\
135 given is an integer or if none is specified, the result value is an integer\n\
136 corresponding to the return value of the ioctl call in the C code.";
139 /* flock(fd, operation) */
142 fcntl_flock(PyObject
*self
, PyObject
*args
)
148 if (!PyArg_ParseTuple(args
, "ii:flock", &fd
, &code
))
152 Py_BEGIN_ALLOW_THREADS
153 ret
= flock(fd
, code
);
158 #define LOCK_SH 1 /* shared lock */
159 #define LOCK_EX 2 /* exclusive lock */
160 #define LOCK_NB 4 /* don't block when locking */
161 #define LOCK_UN 8 /* unlock */
167 else if (code
& LOCK_SH
)
169 else if (code
& LOCK_EX
)
172 PyErr_SetString(PyExc_ValueError
,
173 "unrecognized flock argument");
176 l
.l_whence
= l
.l_start
= l
.l_len
= 0;
177 Py_BEGIN_ALLOW_THREADS
178 ret
= fcntl(fd
, (code
& LOCK_NB
) ? F_SETLK
: F_SETLKW
, &l
);
181 #endif /* HAVE_FLOCK */
183 PyErr_SetFromErrno(PyExc_IOError
);
190 static char flock_doc
[] =
191 "flock(fd, operation)\n\
193 Perform the lock operation op on file descriptor fd. See the Unix \n\
194 manual flock(3) for details. (On some systems, this function is\n\
195 emulated using fcntl().)";
198 /* lockf(fd, operation) */
200 fcntl_lockf(PyObject
*self
, PyObject
*args
)
202 int fd
, code
, ret
, whence
= 0;
203 PyObject
*lenobj
= NULL
, *startobj
= NULL
;
205 if (!PyArg_ParseTuple(args
, "ii|OOi:lockf", &fd
, &code
,
206 &lenobj
, &startobj
, &whence
))
210 #define LOCK_SH 1 /* shared lock */
211 #define LOCK_EX 2 /* exclusive lock */
212 #define LOCK_NB 4 /* don't block when locking */
213 #define LOCK_UN 8 /* unlock */
219 else if (code
& LOCK_SH
)
221 else if (code
& LOCK_EX
)
224 PyErr_SetString(PyExc_ValueError
,
225 "unrecognized flock argument");
228 l
.l_start
= l
.l_len
= 0;
229 if (startobj
!= NULL
) {
230 #if !defined(HAVE_LARGEFILE_SUPPORT)
231 l
.l_start
= PyInt_AsLong(startobj
);
233 l
.l_start
= PyLong_Check(startobj
) ?
234 PyLong_AsLongLong(startobj
) :
235 PyInt_AsLong(startobj
);
237 if (PyErr_Occurred())
240 if (lenobj
!= NULL
) {
241 #if !defined(HAVE_LARGEFILE_SUPPORT)
242 l
.l_len
= PyInt_AsLong(lenobj
);
244 l
.l_len
= PyLong_Check(lenobj
) ?
245 PyLong_AsLongLong(lenobj
) :
246 PyInt_AsLong(lenobj
);
248 if (PyErr_Occurred())
252 Py_BEGIN_ALLOW_THREADS
253 ret
= fcntl(fd
, (code
& LOCK_NB
) ? F_SETLK
: F_SETLKW
, &l
);
257 PyErr_SetFromErrno(PyExc_IOError
);
264 static char lockf_doc
[] =
265 "lockf (fd, operation, length=0, start=0, whence=0)\n\
267 This is essentially a wrapper around the fcntl() locking calls. fd is the\n\
268 file descriptor of the file to lock or unlock, and operation is one of the\n\
272 LOCK_SH - acquire a shared lock\n\
273 LOCK_EX - acquire an exclusive lock\n\
275 When operation is LOCK_SH or LOCK_EX, it can also be bit-wise OR'd with\n\
276 LOCK_NB to avoid blocking on lock acquisition. If LOCK_NB is used and the\n\
277 lock cannot be acquired, an IOError will be raised and the exception will\n\
278 have an errno attribute set to EACCES or EAGAIN (depending on the operating\n\
279 system -- for portability, check for either value).\n\
281 length is the number of bytes to lock, with the default meaning to lock to\n\
282 EOF. start is the byte offset, relative to whence, to that the lock\n\
283 starts. whence is as with fileobj.seek(), specifically:\n\
285 0 - relative to the start of the file (SEEK_SET)\n\
286 1 - relative to the current buffer position (SEEK_CUR)\n\
287 2 - relative to the end of the file (SEEK_END)";
289 /* List of functions */
291 static PyMethodDef fcntl_methods
[] = {
292 {"fcntl", fcntl_fcntl
, METH_VARARGS
, fcntl_doc
},
293 {"ioctl", fcntl_ioctl
, METH_VARARGS
, ioctl_doc
},
294 {"flock", fcntl_flock
, METH_VARARGS
, flock_doc
},
295 {"lockf", fcntl_lockf
, METH_VARARGS
, lockf_doc
},
296 {NULL
, NULL
} /* sentinel */
300 static char module_doc
[] =
302 "This module performs file control and I/O control on file \n\
303 descriptors. It is an interface to the fcntl() and ioctl() Unix\n\
304 routines. File descriptors can be obtained with the fileno() method of\n\
305 a file or socket object.";
307 /* Module initialisation */
310 ins(PyObject
* d
, char* symbol
, long value
)
312 PyObject
* v
= PyInt_FromLong(value
);
313 if (!v
|| PyDict_SetItemString(d
, symbol
, v
) < 0)
323 if (ins(d
, "LOCK_SH", (long)LOCK_SH
)) return -1;
324 if (ins(d
, "LOCK_EX", (long)LOCK_EX
)) return -1;
325 if (ins(d
, "LOCK_NB", (long)LOCK_NB
)) return -1;
326 if (ins(d
, "LOCK_UN", (long)LOCK_UN
)) return -1;
335 /* Create the module and add the functions and documentation */
336 m
= Py_InitModule3("fcntl", fcntl_methods
, module_doc
);
338 /* Add some symbolic constants to the module */
339 d
= PyModule_GetDict(m
);