blob: 1764bca705db00906486ad320b3b73be8b1f8cbf [file] [log] [blame]
Guido van Rossum02975121992-08-17 08:55:12 +00001/***********************************************************
Guido van Rossum524b5881995-01-04 19:10:35 +00002Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
Guido van Rossum02975121992-08-17 08:55:12 +00004
5 All Rights Reserved
6
Guido van Rossumd266eb41996-10-25 14:44:06 +00007Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
Guido van Rossum02975121992-08-17 08:55:12 +00009provided that the above copyright notice appear in all copies and that
Guido van Rossumd266eb41996-10-25 14:44:06 +000010both that copyright notice and this permission notice appear in
Guido van Rossum02975121992-08-17 08:55:12 +000011supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000012Centrum or CWI or Corporation for National Research Initiatives or
13CNRI not be used in advertising or publicity pertaining to
14distribution of the software without specific, written prior
15permission.
Guido van Rossum02975121992-08-17 08:55:12 +000016
Guido van Rossumd266eb41996-10-25 14:44:06 +000017While CWI is the initial source for this software, a modified version
18is made available by the Corporation for National Research Initiatives
19(CNRI) at the Internet address ftp://ftp.python.org.
20
21STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28PERFORMANCE OF THIS SOFTWARE.
Guido van Rossum02975121992-08-17 08:55:12 +000029
30******************************************************************/
31
32/* fcntl module */
33
Roger E. Masse919213a1996-12-17 17:42:22 +000034#include "Python.h"
Guido van Rossum02975121992-08-17 08:55:12 +000035
Guido van Rossuma376cc51996-12-05 23:43:35 +000036#ifdef HAVE_UNISTD_H
37#include <unistd.h>
38#endif
39
40#ifdef HAVE_SYS_FILE_H
41#include <sys/file.h>
42#endif
43
Guido van Rossum3d65fa31996-12-09 18:49:14 +000044#include <sys/ioctl.h>
Guido van Rossum3c0b79c1996-06-11 15:11:34 +000045#include <fcntl.h>
46
Guido van Rossum02975121992-08-17 08:55:12 +000047
48/* fcntl(fd, opt, [arg]) */
49
Roger E. Masse919213a1996-12-17 17:42:22 +000050static PyObject *
Guido van Rossum02975121992-08-17 08:55:12 +000051fcntl_fcntl(self, args)
Roger E. Masse919213a1996-12-17 17:42:22 +000052 PyObject *self; /* Not used */
53 PyObject *args;
Guido van Rossum02975121992-08-17 08:55:12 +000054{
55 int fd;
56 int code;
57 int arg;
58 int ret;
59 char *str;
60 int len;
61 char buf[1024];
62
Roger E. Masse919213a1996-12-17 17:42:22 +000063 if (PyArg_Parse(args, "(iis#)", &fd, &code, &str, &len)) {
Guido van Rossum02975121992-08-17 08:55:12 +000064 if (len > sizeof buf) {
Roger E. Masse919213a1996-12-17 17:42:22 +000065 PyErr_SetString(PyExc_ValueError,
66 "fcntl string arg too long");
Guido van Rossum02975121992-08-17 08:55:12 +000067 return NULL;
68 }
69 memcpy(buf, str, len);
Roger E. Masse919213a1996-12-17 17:42:22 +000070 Py_BEGIN_ALLOW_THREADS
Guido van Rossum903f4871995-10-07 19:18:22 +000071 ret = fcntl(fd, code, buf);
Roger E. Masse919213a1996-12-17 17:42:22 +000072 Py_END_ALLOW_THREADS
Guido van Rossum903f4871995-10-07 19:18:22 +000073 if (ret < 0) {
Roger E. Masse919213a1996-12-17 17:42:22 +000074 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum02975121992-08-17 08:55:12 +000075 return NULL;
76 }
Roger E. Masse919213a1996-12-17 17:42:22 +000077 return PyString_FromStringAndSize(buf, len);
Guido van Rossum02975121992-08-17 08:55:12 +000078 }
79
Roger E. Masse919213a1996-12-17 17:42:22 +000080 PyErr_Clear();
81 if (PyArg_Parse(args, "(ii)", &fd, &code))
Guido van Rossum02975121992-08-17 08:55:12 +000082 arg = 0;
83 else {
Roger E. Masse919213a1996-12-17 17:42:22 +000084 PyErr_Clear();
85 if (!PyArg_Parse(args, "(iii)", &fd, &code, &arg))
Guido van Rossum02975121992-08-17 08:55:12 +000086 return NULL;
87 }
Roger E. Masse919213a1996-12-17 17:42:22 +000088 Py_BEGIN_ALLOW_THREADS
Guido van Rossum02975121992-08-17 08:55:12 +000089 ret = fcntl(fd, code, arg);
Roger E. Masse919213a1996-12-17 17:42:22 +000090 Py_END_ALLOW_THREADS
Guido van Rossum02975121992-08-17 08:55:12 +000091 if (ret < 0) {
Roger E. Masse919213a1996-12-17 17:42:22 +000092 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum02975121992-08-17 08:55:12 +000093 return NULL;
94 }
Roger E. Masse919213a1996-12-17 17:42:22 +000095 return PyInt_FromLong((long)ret);
Guido van Rossum02975121992-08-17 08:55:12 +000096}
97
Guido van Rossum185ead61998-11-23 15:32:55 +000098static char fcntl_doc [] =
99
100"fcntl(fd, opt, [arg])\n\
101\n\
102Perform the requested operation on file descriptor fd. The operation\n\
103is defined by op and is operating system dependent. Typically these\n\
104codes can be retrieved from the library module FCNTL. The argument arg\n\
105is optional, and defaults to 0; it may be an int or a string.";
106
Guido van Rossum02975121992-08-17 08:55:12 +0000107
108/* ioctl(fd, opt, [arg]) */
109
Roger E. Masse919213a1996-12-17 17:42:22 +0000110static PyObject *
Guido van Rossum02975121992-08-17 08:55:12 +0000111fcntl_ioctl(self, args)
Roger E. Masse919213a1996-12-17 17:42:22 +0000112 PyObject *self; /* Not used */
113 PyObject *args;
Guido van Rossum02975121992-08-17 08:55:12 +0000114{
115 int fd;
116 int code;
117 int arg;
118 int ret;
119 char *str;
120 int len;
121 char buf[1024];
122
Roger E. Masse919213a1996-12-17 17:42:22 +0000123 if (PyArg_Parse(args, "(iis#)", &fd, &code, &str, &len)) {
Guido van Rossum02975121992-08-17 08:55:12 +0000124 if (len > sizeof buf) {
Roger E. Masse919213a1996-12-17 17:42:22 +0000125 PyErr_SetString(PyExc_ValueError,
126 "ioctl string arg too long");
Guido van Rossum02975121992-08-17 08:55:12 +0000127 return NULL;
128 }
129 memcpy(buf, str, len);
Roger E. Masse919213a1996-12-17 17:42:22 +0000130 Py_BEGIN_ALLOW_THREADS
Guido van Rossum903f4871995-10-07 19:18:22 +0000131 ret = ioctl(fd, code, buf);
Roger E. Masse919213a1996-12-17 17:42:22 +0000132 Py_END_ALLOW_THREADS
Guido van Rossum903f4871995-10-07 19:18:22 +0000133 if (ret < 0) {
Roger E. Masse919213a1996-12-17 17:42:22 +0000134 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum02975121992-08-17 08:55:12 +0000135 return NULL;
136 }
Roger E. Masse919213a1996-12-17 17:42:22 +0000137 return PyString_FromStringAndSize(buf, len);
Guido van Rossum02975121992-08-17 08:55:12 +0000138 }
139
Roger E. Masse919213a1996-12-17 17:42:22 +0000140 PyErr_Clear();
141 if (PyArg_Parse(args, "(ii)", &fd, &code))
Guido van Rossum02975121992-08-17 08:55:12 +0000142 arg = 0;
143 else {
Roger E. Masse919213a1996-12-17 17:42:22 +0000144 PyErr_Clear();
145 if (!PyArg_Parse(args, "(iii)", &fd, &code, &arg))
Guido van Rossum02975121992-08-17 08:55:12 +0000146 return NULL;
147 }
Roger E. Masse919213a1996-12-17 17:42:22 +0000148 Py_BEGIN_ALLOW_THREADS
Guido van Rossum02975121992-08-17 08:55:12 +0000149 ret = ioctl(fd, code, arg);
Roger E. Masse919213a1996-12-17 17:42:22 +0000150 Py_END_ALLOW_THREADS
Guido van Rossum02975121992-08-17 08:55:12 +0000151 if (ret < 0) {
Roger E. Masse919213a1996-12-17 17:42:22 +0000152 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum02975121992-08-17 08:55:12 +0000153 return NULL;
154 }
Roger E. Masse919213a1996-12-17 17:42:22 +0000155 return PyInt_FromLong((long)ret);
Guido van Rossum02975121992-08-17 08:55:12 +0000156}
157
Guido van Rossum185ead61998-11-23 15:32:55 +0000158static char ioctl_doc [] =
159"ioctl(fd, opt, [arg])\n\
160\n\
161Perform the requested operation on file descriptor fd. The operation\n\
162is defined by op and is operating system dependent. Typically these\n\
163codes can be retrieved from the library module IOCTL. The argument arg\n\
164is optional, and defaults to 0; it may be an int or a string.";
165
Guido van Rossum02975121992-08-17 08:55:12 +0000166
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000167/* flock(fd, operation) */
168
Roger E. Masse919213a1996-12-17 17:42:22 +0000169static PyObject *
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000170fcntl_flock(self, args)
Roger E. Masse919213a1996-12-17 17:42:22 +0000171 PyObject *self; /* Not used */
172 PyObject *args;
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000173{
174 int fd;
175 int code;
176 int ret;
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000177
Roger E. Masse919213a1996-12-17 17:42:22 +0000178 if (!PyArg_Parse(args, "(ii)", &fd, &code))
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000179 return NULL;
180
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000181#ifdef HAVE_FLOCK
Guido van Rossum056bad91999-01-06 18:44:23 +0000182 Py_BEGIN_ALLOW_THREADS
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000183 ret = flock(fd, code);
Guido van Rossum056bad91999-01-06 18:44:23 +0000184 Py_END_ALLOW_THREADS
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000185#else
186
187#ifndef LOCK_SH
188#define LOCK_SH 1 /* shared lock */
189#define LOCK_EX 2 /* exclusive lock */
190#define LOCK_NB 4 /* don't block when locking */
191#define LOCK_UN 8 /* unlock */
192#endif
193 {
194 struct flock l;
195 if (code == LOCK_UN)
196 l.l_type = F_UNLCK;
197 else if (code & LOCK_SH)
198 l.l_type = F_RDLCK;
199 else if (code & LOCK_EX)
200 l.l_type = F_WRLCK;
201 else {
Roger E. Masse919213a1996-12-17 17:42:22 +0000202 PyErr_SetString(PyExc_ValueError,
203 "unrecognized flock argument");
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000204 return NULL;
205 }
206 l.l_whence = l.l_start = l.l_len = 0;
Guido van Rossum056bad91999-01-06 18:44:23 +0000207 Py_BEGIN_ALLOW_THREADS
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000208 ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
Guido van Rossum056bad91999-01-06 18:44:23 +0000209 Py_END_ALLOW_THREADS
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000210 }
211#endif /* HAVE_FLOCK */
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000212 if (ret < 0) {
Roger E. Masse919213a1996-12-17 17:42:22 +0000213 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000214 return NULL;
215 }
Roger E. Masse919213a1996-12-17 17:42:22 +0000216 Py_INCREF(Py_None);
217 return Py_None;
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000218}
219
Guido van Rossum185ead61998-11-23 15:32:55 +0000220static char flock_doc [] =
221"flock(fd, operation)\n\
222\n\
223Perform the lock operation op on file descriptor fd. See the Unix \n\
224manual flock(3) for details. (On some systems, this function is\n\
225emulated using fcntl().)";
226
227
Guido van Rossumc8643641996-09-11 23:17:20 +0000228/* lockf(fd, operation) */
Roger E. Masse919213a1996-12-17 17:42:22 +0000229static PyObject *
Guido van Rossumc8643641996-09-11 23:17:20 +0000230fcntl_lockf(self, args)
Roger E. Masse919213a1996-12-17 17:42:22 +0000231 PyObject *self; /* Not used */
232 PyObject *args;
Guido van Rossumc8643641996-09-11 23:17:20 +0000233{
Guido van Rossum056bad91999-01-06 18:44:23 +0000234 int fd, code, ret, whence = 0;
235 PyObject *lenobj = NULL, *startobj = NULL;
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000236
Guido van Rossum056bad91999-01-06 18:44:23 +0000237 if (!PyArg_ParseTuple(args, "ii|OOi", &fd, &code,
238 &lenobj, &startobj, &whence))
Guido van Rossumc8643641996-09-11 23:17:20 +0000239 return NULL;
240
Guido van Rossumc8643641996-09-11 23:17:20 +0000241#ifndef LOCK_SH
242#define LOCK_SH 1 /* shared lock */
243#define LOCK_EX 2 /* exclusive lock */
244#define LOCK_NB 4 /* don't block when locking */
245#define LOCK_UN 8 /* unlock */
246#endif
247 {
248 struct flock l;
249 if (code == LOCK_UN)
250 l.l_type = F_UNLCK;
251 else if (code & LOCK_SH)
252 l.l_type = F_RDLCK;
253 else if (code & LOCK_EX)
254 l.l_type = F_WRLCK;
255 else {
Roger E. Masse919213a1996-12-17 17:42:22 +0000256 PyErr_SetString(PyExc_ValueError,
257 "unrecognized flock argument");
Guido van Rossumc8643641996-09-11 23:17:20 +0000258 return NULL;
259 }
Guido van Rossum056bad91999-01-06 18:44:23 +0000260 l.l_start = l.l_len = 0;
261 if (startobj != NULL) {
262#if !defined(HAVE_LARGEFILE_SUPPORT)
263 l.l_start = PyInt_AsLong(startobj);
264#else
265 l.l_start = PyLong_Check(startobj) ?
266 PyLong_AsLongLong(startobj) :
267 PyInt_AsLong(startobj);
268#endif
269 if (PyErr_Occurred())
270 return NULL;
271 }
272 if (lenobj != NULL) {
273#if !defined(HAVE_LARGEFILE_SUPPORT)
274 l.l_len = PyInt_AsLong(lenobj);
275#else
276 l.l_len = PyLong_Check(lenobj) ?
277 PyLong_AsLongLong(lenobj) :
278 PyInt_AsLong(lenobj);
279#endif
280 if (PyErr_Occurred())
281 return NULL;
282 }
Guido van Rossumc8643641996-09-11 23:17:20 +0000283 l.l_whence = whence;
Guido van Rossum056bad91999-01-06 18:44:23 +0000284 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc8643641996-09-11 23:17:20 +0000285 ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
Guido van Rossum056bad91999-01-06 18:44:23 +0000286 Py_END_ALLOW_THREADS
Guido van Rossumc8643641996-09-11 23:17:20 +0000287 }
Guido van Rossumc8643641996-09-11 23:17:20 +0000288 if (ret < 0) {
Roger E. Masse919213a1996-12-17 17:42:22 +0000289 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumc8643641996-09-11 23:17:20 +0000290 return NULL;
291 }
Roger E. Masse919213a1996-12-17 17:42:22 +0000292 Py_INCREF(Py_None);
293 return Py_None;
Guido van Rossumc8643641996-09-11 23:17:20 +0000294}
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000295
Guido van Rossum185ead61998-11-23 15:32:55 +0000296static char lockf_doc [] =
297"lockf (fd, operation)\n\
298\n\
299This is a wrapper around the FCNTL.F_SETLK and FCNTL.F_SETLKW fcntl()\n\
300calls. See the Unix manual for details.";
301
Guido van Rossum02975121992-08-17 08:55:12 +0000302/* List of functions */
303
Roger E. Masse919213a1996-12-17 17:42:22 +0000304static PyMethodDef fcntl_methods[] = {
Guido van Rossum185ead61998-11-23 15:32:55 +0000305 {"fcntl", fcntl_fcntl, 0, fcntl_doc},
306 {"ioctl", fcntl_ioctl, 0, ioctl_doc},
307 {"flock", fcntl_flock, 0, flock_doc},
308 {"lockf", fcntl_lockf, 1, lockf_doc},
Guido van Rossum02975121992-08-17 08:55:12 +0000309 {NULL, NULL} /* sentinel */
310};
311
312
Guido van Rossum185ead61998-11-23 15:32:55 +0000313static char module_doc [] =
314
315"This module performs file control and I/O control on file \n\
316descriptors. It is an interface to the fcntl() and ioctl() Unix\n\
317routines. File descriptors can be obtained with the fileno() method of\n\
318a file or socket object.";
319
Guido van Rossum02975121992-08-17 08:55:12 +0000320/* Module initialisation */
321
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000322static int
323ins(d, symbol, value)
324 PyObject* d;
325 char* symbol;
326 long value;
327{
328 PyObject* v = PyInt_FromLong(value);
329 if (!v || PyDict_SetItemString(d, symbol, v) < 0)
330 return -1;
331
332 Py_DECREF(v);
333 return 0;
334}
335
336static int
337all_ins(d)
338 PyObject* d;
339{
340 if (ins(d, "LOCK_SH", (long)LOCK_SH)) return -1;
341 if (ins(d, "LOCK_EX", (long)LOCK_EX)) return -1;
342 if (ins(d, "LOCK_NB", (long)LOCK_NB)) return -1;
343 if (ins(d, "LOCK_UN", (long)LOCK_UN)) return -1;
Guido van Rossum7c141031997-08-15 02:52:08 +0000344 return 0;
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000345}
346
Guido van Rossum3886bb61998-12-04 18:50:17 +0000347DL_EXPORT(void)
Guido van Rossum02975121992-08-17 08:55:12 +0000348initfcntl()
349{
Roger E. Masse919213a1996-12-17 17:42:22 +0000350 PyObject *m, *d;
Guido van Rossum02975121992-08-17 08:55:12 +0000351
Guido van Rossum185ead61998-11-23 15:32:55 +0000352 /* Create the module and add the functions and documentation */
353 m = Py_InitModule3("fcntl", fcntl_methods, module_doc);
Guido van Rossum02975121992-08-17 08:55:12 +0000354
355 /* Add some symbolic constants to the module */
Roger E. Masse919213a1996-12-17 17:42:22 +0000356 d = PyModule_GetDict(m);
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000357 all_ins(d);
Guido van Rossum02975121992-08-17 08:55:12 +0000358
359 /* Check for errors */
Roger E. Masse919213a1996-12-17 17:42:22 +0000360 if (PyErr_Occurred())
361 Py_FatalError("can't initialize module fcntl");
Guido van Rossum02975121992-08-17 08:55:12 +0000362}