blob: 9adba8cb5c8307cde9a52deca05e0bf2b41699b9 [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 Drake460f0692001-05-14 21:02:36 +0000127 if (!PyArg_ParseTuple(args,
128 "O&i|i;ioctl requires a file or file descriptor,"
129 " an integer and optionally a third integer or a string",
Fred Drake152a25e2001-05-09 21:02:02 +0000130 conv_descriptor, &fd, &code, &arg)) {
Guido van Rossuma2214c32000-08-02 20:46:51 +0000131 return NULL;
Guido van Rossum02975121992-08-17 08:55:12 +0000132 }
Roger E. Masse919213a1996-12-17 17:42:22 +0000133 Py_BEGIN_ALLOW_THREADS
Guido van Rossum02975121992-08-17 08:55:12 +0000134 ret = ioctl(fd, code, arg);
Roger E. Masse919213a1996-12-17 17:42:22 +0000135 Py_END_ALLOW_THREADS
Guido van Rossum02975121992-08-17 08:55:12 +0000136 if (ret < 0) {
Roger E. Masse919213a1996-12-17 17:42:22 +0000137 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum02975121992-08-17 08:55:12 +0000138 return NULL;
139 }
Roger E. Masse919213a1996-12-17 17:42:22 +0000140 return PyInt_FromLong((long)ret);
Guido van Rossum02975121992-08-17 08:55:12 +0000141}
142
Guido van Rossum185ead61998-11-23 15:32:55 +0000143static char ioctl_doc [] =
144"ioctl(fd, opt, [arg])\n\
145\n\
146Perform the requested operation on file descriptor fd. The operation\n\
147is defined by op and is operating system dependent. Typically these\n\
148codes can be retrieved from the library module IOCTL. The argument arg\n\
Guido van Rossuma2214c32000-08-02 20:46:51 +0000149is optional, and defaults to 0; it may be an int or a string. If arg is\n\
150given as a string, the return value of ioctl is a string of that length,\n\
151containing the resulting value put in the arg buffer by the operating system.\n\
152The length of the arg string is not allowed to exceed 1024 bytes. If the arg\n\
153given is an integer or if none is specified, the result value is an integer\n\
154corresponding to the return value of the ioctl call in the C code.";
Guido van Rossum185ead61998-11-23 15:32:55 +0000155
Guido van Rossum02975121992-08-17 08:55:12 +0000156
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000157/* flock(fd, operation) */
158
Roger E. Masse919213a1996-12-17 17:42:22 +0000159static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000160fcntl_flock(PyObject *self, PyObject *args)
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000161{
162 int fd;
163 int code;
164 int ret;
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000165
Fred Drake152a25e2001-05-09 21:02:02 +0000166 if (!PyArg_ParseTuple(args, "O&i:flock",
167 conv_descriptor, &fd, &code))
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000168 return NULL;
169
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000170#ifdef HAVE_FLOCK
Guido van Rossum056bad91999-01-06 18:44:23 +0000171 Py_BEGIN_ALLOW_THREADS
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000172 ret = flock(fd, code);
Guido van Rossum056bad91999-01-06 18:44:23 +0000173 Py_END_ALLOW_THREADS
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000174#else
175
176#ifndef LOCK_SH
177#define LOCK_SH 1 /* shared lock */
178#define LOCK_EX 2 /* exclusive lock */
179#define LOCK_NB 4 /* don't block when locking */
180#define LOCK_UN 8 /* unlock */
181#endif
182 {
183 struct flock l;
184 if (code == LOCK_UN)
185 l.l_type = F_UNLCK;
186 else if (code & LOCK_SH)
187 l.l_type = F_RDLCK;
188 else if (code & LOCK_EX)
189 l.l_type = F_WRLCK;
190 else {
Roger E. Masse919213a1996-12-17 17:42:22 +0000191 PyErr_SetString(PyExc_ValueError,
192 "unrecognized flock argument");
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000193 return NULL;
194 }
195 l.l_whence = l.l_start = l.l_len = 0;
Guido van Rossum056bad91999-01-06 18:44:23 +0000196 Py_BEGIN_ALLOW_THREADS
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000197 ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
Guido van Rossum056bad91999-01-06 18:44:23 +0000198 Py_END_ALLOW_THREADS
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000199 }
200#endif /* HAVE_FLOCK */
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000201 if (ret < 0) {
Roger E. Masse919213a1996-12-17 17:42:22 +0000202 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000203 return NULL;
204 }
Roger E. Masse919213a1996-12-17 17:42:22 +0000205 Py_INCREF(Py_None);
206 return Py_None;
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000207}
208
Guido van Rossum185ead61998-11-23 15:32:55 +0000209static char flock_doc [] =
210"flock(fd, operation)\n\
211\n\
212Perform the lock operation op on file descriptor fd. See the Unix \n\
213manual flock(3) for details. (On some systems, this function is\n\
214emulated using fcntl().)";
215
216
Guido van Rossumc8643641996-09-11 23:17:20 +0000217/* lockf(fd, operation) */
Roger E. Masse919213a1996-12-17 17:42:22 +0000218static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000219fcntl_lockf(PyObject *self, PyObject *args)
Guido van Rossumc8643641996-09-11 23:17:20 +0000220{
Guido van Rossum056bad91999-01-06 18:44:23 +0000221 int fd, code, ret, whence = 0;
222 PyObject *lenobj = NULL, *startobj = NULL;
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000223
Fred Drake152a25e2001-05-09 21:02:02 +0000224 if (!PyArg_ParseTuple(args, "O&i|OOi:lockf",
225 conv_descriptor, &fd, &code,
Guido van Rossum056bad91999-01-06 18:44:23 +0000226 &lenobj, &startobj, &whence))
Guido van Rossumc8643641996-09-11 23:17:20 +0000227 return NULL;
228
Guido van Rossumc8643641996-09-11 23:17:20 +0000229#ifndef LOCK_SH
230#define LOCK_SH 1 /* shared lock */
231#define LOCK_EX 2 /* exclusive lock */
232#define LOCK_NB 4 /* don't block when locking */
233#define LOCK_UN 8 /* unlock */
234#endif
235 {
236 struct flock l;
237 if (code == LOCK_UN)
238 l.l_type = F_UNLCK;
239 else if (code & LOCK_SH)
240 l.l_type = F_RDLCK;
241 else if (code & LOCK_EX)
242 l.l_type = F_WRLCK;
243 else {
Roger E. Masse919213a1996-12-17 17:42:22 +0000244 PyErr_SetString(PyExc_ValueError,
245 "unrecognized flock argument");
Guido van Rossumc8643641996-09-11 23:17:20 +0000246 return NULL;
247 }
Guido van Rossum056bad91999-01-06 18:44:23 +0000248 l.l_start = l.l_len = 0;
249 if (startobj != NULL) {
250#if !defined(HAVE_LARGEFILE_SUPPORT)
251 l.l_start = PyInt_AsLong(startobj);
252#else
253 l.l_start = PyLong_Check(startobj) ?
254 PyLong_AsLongLong(startobj) :
255 PyInt_AsLong(startobj);
256#endif
257 if (PyErr_Occurred())
258 return NULL;
259 }
260 if (lenobj != NULL) {
261#if !defined(HAVE_LARGEFILE_SUPPORT)
262 l.l_len = PyInt_AsLong(lenobj);
263#else
264 l.l_len = PyLong_Check(lenobj) ?
265 PyLong_AsLongLong(lenobj) :
266 PyInt_AsLong(lenobj);
267#endif
268 if (PyErr_Occurred())
269 return NULL;
270 }
Guido van Rossumc8643641996-09-11 23:17:20 +0000271 l.l_whence = whence;
Guido van Rossum056bad91999-01-06 18:44:23 +0000272 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc8643641996-09-11 23:17:20 +0000273 ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
Guido van Rossum056bad91999-01-06 18:44:23 +0000274 Py_END_ALLOW_THREADS
Guido van Rossumc8643641996-09-11 23:17:20 +0000275 }
Guido van Rossumc8643641996-09-11 23:17:20 +0000276 if (ret < 0) {
Roger E. Masse919213a1996-12-17 17:42:22 +0000277 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumc8643641996-09-11 23:17:20 +0000278 return NULL;
279 }
Roger E. Masse919213a1996-12-17 17:42:22 +0000280 Py_INCREF(Py_None);
281 return Py_None;
Guido van Rossumc8643641996-09-11 23:17:20 +0000282}
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000283
Guido van Rossum185ead61998-11-23 15:32:55 +0000284static char lockf_doc [] =
Sjoerd Mullender82e00d62001-01-25 10:10:39 +0000285"lockf (fd, operation, length=0, start=0, whence=0)\n\
286\n\
287This is essentially a wrapper around the fcntl() locking calls. fd is the\n\
288file descriptor of the file to lock or unlock, and operation is one of the\n\
289following values:\n\
290\n\
291 LOCK_UN - unlock\n\
292 LOCK_SH - acquire a shared lock\n\
293 LOCK_EX - acquire an exclusive lock\n\
294\n\
295When operation is LOCK_SH or LOCK_EX, it can also be bit-wise OR'd with\n\
296LOCK_NB to avoid blocking on lock acquisition. If LOCK_NB is used and the\n\
297lock cannot be acquired, an IOError will be raised and the exception will\n\
298have an errno attribute set to EACCES or EAGAIN (depending on the operating\n\
299system -- for portability, check for either value).\n\
300\n\
301length is the number of bytes to lock, with the default meaning to lock to\n\
302EOF. start is the byte offset, relative to whence, to that the lock\n\
303starts. whence is as with fileobj.seek(), specifically:\n\
304\n\
305 0 - relative to the start of the file (SEEK_SET)\n\
306 1 - relative to the current buffer position (SEEK_CUR)\n\
Barry Warsawbd3dc1f2001-01-25 00:20:13 +0000307 2 - relative to the end of the file (SEEK_END)";
Guido van Rossum185ead61998-11-23 15:32:55 +0000308
Guido van Rossum02975121992-08-17 08:55:12 +0000309/* List of functions */
310
Roger E. Masse919213a1996-12-17 17:42:22 +0000311static PyMethodDef fcntl_methods[] = {
Guido van Rossuma2214c32000-08-02 20:46:51 +0000312 {"fcntl", fcntl_fcntl, METH_VARARGS, fcntl_doc},
313 {"ioctl", fcntl_ioctl, METH_VARARGS, ioctl_doc},
314 {"flock", fcntl_flock, METH_VARARGS, flock_doc},
315 {"lockf", fcntl_lockf, METH_VARARGS, lockf_doc},
Guido van Rossum02975121992-08-17 08:55:12 +0000316 {NULL, NULL} /* sentinel */
317};
318
319
Guido van Rossum185ead61998-11-23 15:32:55 +0000320static char module_doc [] =
321
322"This module performs file control and I/O control on file \n\
323descriptors. It is an interface to the fcntl() and ioctl() Unix\n\
324routines. File descriptors can be obtained with the fileno() method of\n\
325a file or socket object.";
326
Guido van Rossum02975121992-08-17 08:55:12 +0000327/* Module initialisation */
328
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000329static int
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000330ins(PyObject* d, char* symbol, long value)
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000331{
332 PyObject* v = PyInt_FromLong(value);
333 if (!v || PyDict_SetItemString(d, symbol, v) < 0)
334 return -1;
335
336 Py_DECREF(v);
337 return 0;
338}
339
340static int
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000341all_ins(PyObject* d)
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000342{
343 if (ins(d, "LOCK_SH", (long)LOCK_SH)) return -1;
344 if (ins(d, "LOCK_EX", (long)LOCK_EX)) return -1;
345 if (ins(d, "LOCK_NB", (long)LOCK_NB)) return -1;
346 if (ins(d, "LOCK_UN", (long)LOCK_UN)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000347#ifdef F_DUPFD
348 if (ins(d, "F_DUPFD", (long)F_DUPFD)) return -1;
349#endif
350#ifdef F_GETFD
351 if (ins(d, "F_GETFD", (long)F_GETFD)) return -1;
352#endif
353#ifdef F_SETFD
354 if (ins(d, "F_SETFD", (long)F_SETFD)) return -1;
355#endif
356#ifdef F_GETFL
357 if (ins(d, "F_GETFL", (long)F_GETFL)) return -1;
358#endif
359#ifdef F_SETFL
360 if (ins(d, "F_SETFL", (long)F_SETFL)) return -1;
361#endif
362#ifdef F_GETLK
363 if (ins(d, "F_GETLK", (long)F_GETLK)) return -1;
364#endif
365#ifdef F_SETLK
366 if (ins(d, "F_SETLK", (long)F_SETLK)) return -1;
367#endif
368#ifdef F_SETLKW
369 if (ins(d, "F_SETLKW", (long)F_SETLKW)) return -1;
370#endif
371#ifdef F_GETOWN
372 if (ins(d, "F_GETOWN", (long)F_GETOWN)) return -1;
373#endif
374#ifdef F_SETOWN
375 if (ins(d, "F_SETOWN", (long)F_SETOWN)) return -1;
376#endif
377#ifdef F_GETSIG
378 if (ins(d, "F_GETSIG", (long)F_GETSIG)) return -1;
379#endif
380#ifdef F_SETSIG
381 if (ins(d, "F_SETSIG", (long)F_SETSIG)) return -1;
382#endif
383#ifdef F_RDLCK
384 if (ins(d, "F_RDLCK", (long)F_RDLCK)) return -1;
385#endif
386#ifdef F_WRLCK
387 if (ins(d, "F_WRLCK", (long)F_WRLCK)) return -1;
388#endif
389#ifdef F_UNLCK
390 if (ins(d, "F_UNLCK", (long)F_UNLCK)) return -1;
391#endif
Guido van Rossum7c141031997-08-15 02:52:08 +0000392 return 0;
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000393}
394
Guido van Rossum3886bb61998-12-04 18:50:17 +0000395DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000396initfcntl(void)
Guido van Rossum02975121992-08-17 08:55:12 +0000397{
Roger E. Masse919213a1996-12-17 17:42:22 +0000398 PyObject *m, *d;
Guido van Rossum02975121992-08-17 08:55:12 +0000399
Guido van Rossum185ead61998-11-23 15:32:55 +0000400 /* Create the module and add the functions and documentation */
401 m = Py_InitModule3("fcntl", fcntl_methods, module_doc);
Guido van Rossum02975121992-08-17 08:55:12 +0000402
403 /* Add some symbolic constants to the module */
Roger E. Masse919213a1996-12-17 17:42:22 +0000404 d = PyModule_GetDict(m);
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000405 all_ins(d);
Guido van Rossum02975121992-08-17 08:55:12 +0000406}