blob: c45dbe903db179c118848077e0702ac855622073 [file] [log] [blame]
Guido van Rossum02975121992-08-17 08:55:12 +00001
2/* fcntl module */
3
Roger E. Masse919213a1996-12-17 17:42:22 +00004#include "Python.h"
Guido van Rossum02975121992-08-17 08:55:12 +00005
Guido van Rossuma376cc51996-12-05 23:43:35 +00006#ifdef HAVE_UNISTD_H
7#include <unistd.h>
8#endif
9
10#ifdef HAVE_SYS_FILE_H
11#include <sys/file.h>
12#endif
13
Guido van Rossum3d65fa31996-12-09 18:49:14 +000014#include <sys/ioctl.h>
Guido van Rossum3c0b79c1996-06-11 15:11:34 +000015#include <fcntl.h>
16
Guido van Rossum02975121992-08-17 08:55:12 +000017
Fred Drake152a25e2001-05-09 21:02:02 +000018static int
19conv_descriptor(PyObject *object, int *target)
20{
21 int fd = PyObject_AsFileDescriptor(object);
22
23 if (fd < 0)
24 return 0;
25 *target = fd;
26 return 1;
27}
28
29
Guido van Rossum02975121992-08-17 08:55:12 +000030/* fcntl(fd, opt, [arg]) */
31
Roger E. Masse919213a1996-12-17 17:42:22 +000032static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +000033fcntl_fcntl(PyObject *self, PyObject *args)
Guido van Rossum02975121992-08-17 08:55:12 +000034{
35 int fd;
36 int code;
37 int arg;
38 int ret;
39 char *str;
40 int len;
41 char buf[1024];
42
Fred Drake152a25e2001-05-09 21:02:02 +000043 if (PyArg_ParseTuple(args, "O&is#:fcntl",
44 conv_descriptor, &fd, &code, &str, &len)) {
Guido van Rossum02975121992-08-17 08:55:12 +000045 if (len > sizeof buf) {
Roger E. Masse919213a1996-12-17 17:42:22 +000046 PyErr_SetString(PyExc_ValueError,
47 "fcntl string arg too long");
Guido van Rossum02975121992-08-17 08:55:12 +000048 return NULL;
49 }
50 memcpy(buf, str, len);
Roger E. Masse919213a1996-12-17 17:42:22 +000051 Py_BEGIN_ALLOW_THREADS
Guido van Rossum903f4871995-10-07 19:18:22 +000052 ret = fcntl(fd, code, buf);
Roger E. Masse919213a1996-12-17 17:42:22 +000053 Py_END_ALLOW_THREADS
Guido van Rossum903f4871995-10-07 19:18:22 +000054 if (ret < 0) {
Roger E. Masse919213a1996-12-17 17:42:22 +000055 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum02975121992-08-17 08:55:12 +000056 return NULL;
57 }
Roger E. Masse919213a1996-12-17 17:42:22 +000058 return PyString_FromStringAndSize(buf, len);
Guido van Rossum02975121992-08-17 08:55:12 +000059 }
60
Roger E. Masse919213a1996-12-17 17:42:22 +000061 PyErr_Clear();
Guido van Rossuma2214c32000-08-02 20:46:51 +000062 arg = 0;
Fred Drake152a25e2001-05-09 21:02:02 +000063 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)) {
Guido van Rossuma2214c32000-08-02 20:46:51 +000067 return NULL;
Guido van Rossum02975121992-08-17 08:55:12 +000068 }
Roger E. Masse919213a1996-12-17 17:42:22 +000069 Py_BEGIN_ALLOW_THREADS
Guido van Rossum02975121992-08-17 08:55:12 +000070 ret = fcntl(fd, code, arg);
Roger E. Masse919213a1996-12-17 17:42:22 +000071 Py_END_ALLOW_THREADS
Guido van Rossum02975121992-08-17 08:55:12 +000072 if (ret < 0) {
Roger E. Masse919213a1996-12-17 17:42:22 +000073 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum02975121992-08-17 08:55:12 +000074 return NULL;
75 }
Roger E. Masse919213a1996-12-17 17:42:22 +000076 return PyInt_FromLong((long)ret);
Guido van Rossum02975121992-08-17 08:55:12 +000077}
78
Guido van Rossum185ead61998-11-23 15:32:55 +000079static char fcntl_doc [] =
80
81"fcntl(fd, opt, [arg])\n\
82\n\
83Perform the requested operation on file descriptor fd. The operation\n\
Fred Drake1d531992001-05-10 15:54:32 +000084is defined by op and is operating system dependent. These constants are\n\
85available from the fcntl module. The argument arg is optional, and\n\
86defaults to 0; it may be an int or a string. If arg is given as a string,\n\
87the return value of fcntl is a string of that length, containing the\n\
88resulting value put in the arg buffer by the operating system.The length\n\
89of the arg string is not allowed to exceed 1024 bytes. If the arg given\n\
90is an integer or if none is specified, the result value is an integer\n\
Guido van Rossuma2214c32000-08-02 20:46:51 +000091corresponding to the return value of the fcntl call in the C code.";
Guido van Rossum185ead61998-11-23 15:32:55 +000092
Guido van Rossum02975121992-08-17 08:55:12 +000093
94/* ioctl(fd, opt, [arg]) */
95
Roger E. Masse919213a1996-12-17 17:42:22 +000096static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +000097fcntl_ioctl(PyObject *self, PyObject *args)
Guido van Rossum02975121992-08-17 08:55:12 +000098{
99 int fd;
100 int code;
101 int arg;
102 int ret;
103 char *str;
104 int len;
105 char buf[1024];
106
Fred Drake152a25e2001-05-09 21:02:02 +0000107 if (PyArg_ParseTuple(args, "O&is#:ioctl",
108 conv_descriptor, &fd, &code, &str, &len)) {
Guido van Rossum02975121992-08-17 08:55:12 +0000109 if (len > sizeof buf) {
Roger E. Masse919213a1996-12-17 17:42:22 +0000110 PyErr_SetString(PyExc_ValueError,
111 "ioctl string arg too long");
Guido van Rossum02975121992-08-17 08:55:12 +0000112 return NULL;
113 }
114 memcpy(buf, str, len);
Roger E. Masse919213a1996-12-17 17:42:22 +0000115 Py_BEGIN_ALLOW_THREADS
Guido van Rossum903f4871995-10-07 19:18:22 +0000116 ret = ioctl(fd, code, buf);
Roger E. Masse919213a1996-12-17 17:42:22 +0000117 Py_END_ALLOW_THREADS
Guido van Rossum903f4871995-10-07 19:18:22 +0000118 if (ret < 0) {
Roger E. Masse919213a1996-12-17 17:42:22 +0000119 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum02975121992-08-17 08:55:12 +0000120 return NULL;
121 }
Roger E. Masse919213a1996-12-17 17:42:22 +0000122 return PyString_FromStringAndSize(buf, len);
Guido van Rossum02975121992-08-17 08:55:12 +0000123 }
124
Roger E. Masse919213a1996-12-17 17:42:22 +0000125 PyErr_Clear();
Guido van Rossuma2214c32000-08-02 20:46:51 +0000126 arg = 0;
Fred Drake152a25e2001-05-09 21:02:02 +0000127 if (!PyArg_ParseTuple(args, "O&i|i;ioctl requires 2 integers and optionally a third integer or a string",
128 conv_descriptor, &fd, &code, &arg)) {
Guido van Rossuma2214c32000-08-02 20:46:51 +0000129 return NULL;
Guido van Rossum02975121992-08-17 08:55:12 +0000130 }
Roger E. Masse919213a1996-12-17 17:42:22 +0000131 Py_BEGIN_ALLOW_THREADS
Guido van Rossum02975121992-08-17 08:55:12 +0000132 ret = ioctl(fd, code, arg);
Roger E. Masse919213a1996-12-17 17:42:22 +0000133 Py_END_ALLOW_THREADS
Guido van Rossum02975121992-08-17 08:55:12 +0000134 if (ret < 0) {
Roger E. Masse919213a1996-12-17 17:42:22 +0000135 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum02975121992-08-17 08:55:12 +0000136 return NULL;
137 }
Roger E. Masse919213a1996-12-17 17:42:22 +0000138 return PyInt_FromLong((long)ret);
Guido van Rossum02975121992-08-17 08:55:12 +0000139}
140
Guido van Rossum185ead61998-11-23 15:32:55 +0000141static char ioctl_doc [] =
142"ioctl(fd, opt, [arg])\n\
143\n\
144Perform the requested operation on file descriptor fd. The operation\n\
145is defined by op and is operating system dependent. Typically these\n\
146codes can be retrieved from the library module IOCTL. The argument arg\n\
Guido van Rossuma2214c32000-08-02 20:46:51 +0000147is optional, and defaults to 0; it may be an int or a string. If arg is\n\
148given as a string, the return value of ioctl is a string of that length,\n\
149containing the resulting value put in the arg buffer by the operating system.\n\
150The length of the arg string is not allowed to exceed 1024 bytes. If the arg\n\
151given is an integer or if none is specified, the result value is an integer\n\
152corresponding to the return value of the ioctl call in the C code.";
Guido van Rossum185ead61998-11-23 15:32:55 +0000153
Guido van Rossum02975121992-08-17 08:55:12 +0000154
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000155/* flock(fd, operation) */
156
Roger E. Masse919213a1996-12-17 17:42:22 +0000157static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000158fcntl_flock(PyObject *self, PyObject *args)
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000159{
160 int fd;
161 int code;
162 int ret;
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000163
Fred Drake152a25e2001-05-09 21:02:02 +0000164 if (!PyArg_ParseTuple(args, "O&i:flock",
165 conv_descriptor, &fd, &code))
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000166 return NULL;
167
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000168#ifdef HAVE_FLOCK
Guido van Rossum056bad91999-01-06 18:44:23 +0000169 Py_BEGIN_ALLOW_THREADS
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000170 ret = flock(fd, code);
Guido van Rossum056bad91999-01-06 18:44:23 +0000171 Py_END_ALLOW_THREADS
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000172#else
173
174#ifndef LOCK_SH
175#define LOCK_SH 1 /* shared lock */
176#define LOCK_EX 2 /* exclusive lock */
177#define LOCK_NB 4 /* don't block when locking */
178#define LOCK_UN 8 /* unlock */
179#endif
180 {
181 struct flock l;
182 if (code == LOCK_UN)
183 l.l_type = F_UNLCK;
184 else if (code & LOCK_SH)
185 l.l_type = F_RDLCK;
186 else if (code & LOCK_EX)
187 l.l_type = F_WRLCK;
188 else {
Roger E. Masse919213a1996-12-17 17:42:22 +0000189 PyErr_SetString(PyExc_ValueError,
190 "unrecognized flock argument");
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000191 return NULL;
192 }
193 l.l_whence = l.l_start = l.l_len = 0;
Guido van Rossum056bad91999-01-06 18:44:23 +0000194 Py_BEGIN_ALLOW_THREADS
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000195 ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
Guido van Rossum056bad91999-01-06 18:44:23 +0000196 Py_END_ALLOW_THREADS
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000197 }
198#endif /* HAVE_FLOCK */
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000199 if (ret < 0) {
Roger E. Masse919213a1996-12-17 17:42:22 +0000200 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000201 return NULL;
202 }
Roger E. Masse919213a1996-12-17 17:42:22 +0000203 Py_INCREF(Py_None);
204 return Py_None;
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000205}
206
Guido van Rossum185ead61998-11-23 15:32:55 +0000207static char flock_doc [] =
208"flock(fd, operation)\n\
209\n\
210Perform the lock operation op on file descriptor fd. See the Unix \n\
211manual flock(3) for details. (On some systems, this function is\n\
212emulated using fcntl().)";
213
214
Guido van Rossumc8643641996-09-11 23:17:20 +0000215/* lockf(fd, operation) */
Roger E. Masse919213a1996-12-17 17:42:22 +0000216static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000217fcntl_lockf(PyObject *self, PyObject *args)
Guido van Rossumc8643641996-09-11 23:17:20 +0000218{
Guido van Rossum056bad91999-01-06 18:44:23 +0000219 int fd, code, ret, whence = 0;
220 PyObject *lenobj = NULL, *startobj = NULL;
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000221
Fred Drake152a25e2001-05-09 21:02:02 +0000222 if (!PyArg_ParseTuple(args, "O&i|OOi:lockf",
223 conv_descriptor, &fd, &code,
Guido van Rossum056bad91999-01-06 18:44:23 +0000224 &lenobj, &startobj, &whence))
Guido van Rossumc8643641996-09-11 23:17:20 +0000225 return NULL;
226
Guido van Rossumc8643641996-09-11 23:17:20 +0000227#ifndef LOCK_SH
228#define LOCK_SH 1 /* shared lock */
229#define LOCK_EX 2 /* exclusive lock */
230#define LOCK_NB 4 /* don't block when locking */
231#define LOCK_UN 8 /* unlock */
232#endif
233 {
234 struct flock l;
235 if (code == LOCK_UN)
236 l.l_type = F_UNLCK;
237 else if (code & LOCK_SH)
238 l.l_type = F_RDLCK;
239 else if (code & LOCK_EX)
240 l.l_type = F_WRLCK;
241 else {
Roger E. Masse919213a1996-12-17 17:42:22 +0000242 PyErr_SetString(PyExc_ValueError,
243 "unrecognized flock argument");
Guido van Rossumc8643641996-09-11 23:17:20 +0000244 return NULL;
245 }
Guido van Rossum056bad91999-01-06 18:44:23 +0000246 l.l_start = l.l_len = 0;
247 if (startobj != NULL) {
248#if !defined(HAVE_LARGEFILE_SUPPORT)
249 l.l_start = PyInt_AsLong(startobj);
250#else
251 l.l_start = PyLong_Check(startobj) ?
252 PyLong_AsLongLong(startobj) :
253 PyInt_AsLong(startobj);
254#endif
255 if (PyErr_Occurred())
256 return NULL;
257 }
258 if (lenobj != NULL) {
259#if !defined(HAVE_LARGEFILE_SUPPORT)
260 l.l_len = PyInt_AsLong(lenobj);
261#else
262 l.l_len = PyLong_Check(lenobj) ?
263 PyLong_AsLongLong(lenobj) :
264 PyInt_AsLong(lenobj);
265#endif
266 if (PyErr_Occurred())
267 return NULL;
268 }
Guido van Rossumc8643641996-09-11 23:17:20 +0000269 l.l_whence = whence;
Guido van Rossum056bad91999-01-06 18:44:23 +0000270 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc8643641996-09-11 23:17:20 +0000271 ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
Guido van Rossum056bad91999-01-06 18:44:23 +0000272 Py_END_ALLOW_THREADS
Guido van Rossumc8643641996-09-11 23:17:20 +0000273 }
Guido van Rossumc8643641996-09-11 23:17:20 +0000274 if (ret < 0) {
Roger E. Masse919213a1996-12-17 17:42:22 +0000275 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumc8643641996-09-11 23:17:20 +0000276 return NULL;
277 }
Roger E. Masse919213a1996-12-17 17:42:22 +0000278 Py_INCREF(Py_None);
279 return Py_None;
Guido van Rossumc8643641996-09-11 23:17:20 +0000280}
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000281
Guido van Rossum185ead61998-11-23 15:32:55 +0000282static char lockf_doc [] =
Sjoerd Mullender82e00d62001-01-25 10:10:39 +0000283"lockf (fd, operation, length=0, start=0, whence=0)\n\
284\n\
285This is essentially a wrapper around the fcntl() locking calls. fd is the\n\
286file descriptor of the file to lock or unlock, and operation is one of the\n\
287following values:\n\
288\n\
289 LOCK_UN - unlock\n\
290 LOCK_SH - acquire a shared lock\n\
291 LOCK_EX - acquire an exclusive lock\n\
292\n\
293When operation is LOCK_SH or LOCK_EX, it can also be bit-wise OR'd with\n\
294LOCK_NB to avoid blocking on lock acquisition. If LOCK_NB is used and the\n\
295lock cannot be acquired, an IOError will be raised and the exception will\n\
296have an errno attribute set to EACCES or EAGAIN (depending on the operating\n\
297system -- for portability, check for either value).\n\
298\n\
299length is the number of bytes to lock, with the default meaning to lock to\n\
300EOF. start is the byte offset, relative to whence, to that the lock\n\
301starts. whence is as with fileobj.seek(), specifically:\n\
302\n\
303 0 - relative to the start of the file (SEEK_SET)\n\
304 1 - relative to the current buffer position (SEEK_CUR)\n\
Barry Warsawbd3dc1f2001-01-25 00:20:13 +0000305 2 - relative to the end of the file (SEEK_END)";
Guido van Rossum185ead61998-11-23 15:32:55 +0000306
Guido van Rossum02975121992-08-17 08:55:12 +0000307/* List of functions */
308
Roger E. Masse919213a1996-12-17 17:42:22 +0000309static PyMethodDef fcntl_methods[] = {
Guido van Rossuma2214c32000-08-02 20:46:51 +0000310 {"fcntl", fcntl_fcntl, METH_VARARGS, fcntl_doc},
311 {"ioctl", fcntl_ioctl, METH_VARARGS, ioctl_doc},
312 {"flock", fcntl_flock, METH_VARARGS, flock_doc},
313 {"lockf", fcntl_lockf, METH_VARARGS, lockf_doc},
Guido van Rossum02975121992-08-17 08:55:12 +0000314 {NULL, NULL} /* sentinel */
315};
316
317
Guido van Rossum185ead61998-11-23 15:32:55 +0000318static char module_doc [] =
319
320"This module performs file control and I/O control on file \n\
321descriptors. It is an interface to the fcntl() and ioctl() Unix\n\
322routines. File descriptors can be obtained with the fileno() method of\n\
323a file or socket object.";
324
Guido van Rossum02975121992-08-17 08:55:12 +0000325/* Module initialisation */
326
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000327static int
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000328ins(PyObject* d, char* symbol, long value)
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000329{
330 PyObject* v = PyInt_FromLong(value);
331 if (!v || PyDict_SetItemString(d, symbol, v) < 0)
332 return -1;
333
334 Py_DECREF(v);
335 return 0;
336}
337
338static int
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000339all_ins(PyObject* d)
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000340{
341 if (ins(d, "LOCK_SH", (long)LOCK_SH)) return -1;
342 if (ins(d, "LOCK_EX", (long)LOCK_EX)) return -1;
343 if (ins(d, "LOCK_NB", (long)LOCK_NB)) return -1;
344 if (ins(d, "LOCK_UN", (long)LOCK_UN)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000345#ifdef F_DUPFD
346 if (ins(d, "F_DUPFD", (long)F_DUPFD)) return -1;
347#endif
348#ifdef F_GETFD
349 if (ins(d, "F_GETFD", (long)F_GETFD)) return -1;
350#endif
351#ifdef F_SETFD
352 if (ins(d, "F_SETFD", (long)F_SETFD)) return -1;
353#endif
354#ifdef F_GETFL
355 if (ins(d, "F_GETFL", (long)F_GETFL)) return -1;
356#endif
357#ifdef F_SETFL
358 if (ins(d, "F_SETFL", (long)F_SETFL)) return -1;
359#endif
360#ifdef F_GETLK
361 if (ins(d, "F_GETLK", (long)F_GETLK)) return -1;
362#endif
363#ifdef F_SETLK
364 if (ins(d, "F_SETLK", (long)F_SETLK)) return -1;
365#endif
366#ifdef F_SETLKW
367 if (ins(d, "F_SETLKW", (long)F_SETLKW)) return -1;
368#endif
369#ifdef F_GETOWN
370 if (ins(d, "F_GETOWN", (long)F_GETOWN)) return -1;
371#endif
372#ifdef F_SETOWN
373 if (ins(d, "F_SETOWN", (long)F_SETOWN)) return -1;
374#endif
375#ifdef F_GETSIG
376 if (ins(d, "F_GETSIG", (long)F_GETSIG)) return -1;
377#endif
378#ifdef F_SETSIG
379 if (ins(d, "F_SETSIG", (long)F_SETSIG)) return -1;
380#endif
381#ifdef F_RDLCK
382 if (ins(d, "F_RDLCK", (long)F_RDLCK)) return -1;
383#endif
384#ifdef F_WRLCK
385 if (ins(d, "F_WRLCK", (long)F_WRLCK)) return -1;
386#endif
387#ifdef F_UNLCK
388 if (ins(d, "F_UNLCK", (long)F_UNLCK)) return -1;
389#endif
Guido van Rossum7c141031997-08-15 02:52:08 +0000390 return 0;
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000391}
392
Guido van Rossum3886bb61998-12-04 18:50:17 +0000393DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000394initfcntl(void)
Guido van Rossum02975121992-08-17 08:55:12 +0000395{
Roger E. Masse919213a1996-12-17 17:42:22 +0000396 PyObject *m, *d;
Guido van Rossum02975121992-08-17 08:55:12 +0000397
Guido van Rossum185ead61998-11-23 15:32:55 +0000398 /* Create the module and add the functions and documentation */
399 m = Py_InitModule3("fcntl", fcntl_methods, module_doc);
Guido van Rossum02975121992-08-17 08:55:12 +0000400
401 /* Add some symbolic constants to the module */
Roger E. Masse919213a1996-12-17 17:42:22 +0000402 d = PyModule_GetDict(m);
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000403 all_ins(d);
Guido van Rossum02975121992-08-17 08:55:12 +0000404}