blob: 59a4d4ae55e3f1ea4063aad0170a1d037ceb2c5c [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
Roger E. Masse919213a1996-12-17 17:42:22 +0000181 Py_BEGIN_ALLOW_THREADS
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000182#ifdef HAVE_FLOCK
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000183 ret = flock(fd, code);
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000184#else
185
186#ifndef LOCK_SH
187#define LOCK_SH 1 /* shared lock */
188#define LOCK_EX 2 /* exclusive lock */
189#define LOCK_NB 4 /* don't block when locking */
190#define LOCK_UN 8 /* unlock */
191#endif
192 {
193 struct flock l;
194 if (code == LOCK_UN)
195 l.l_type = F_UNLCK;
196 else if (code & LOCK_SH)
197 l.l_type = F_RDLCK;
198 else if (code & LOCK_EX)
199 l.l_type = F_WRLCK;
200 else {
Roger E. Masse919213a1996-12-17 17:42:22 +0000201 PyErr_SetString(PyExc_ValueError,
202 "unrecognized flock argument");
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000203 return NULL;
204 }
205 l.l_whence = l.l_start = l.l_len = 0;
206 ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
207 }
208#endif /* HAVE_FLOCK */
Roger E. Masse919213a1996-12-17 17:42:22 +0000209 Py_END_ALLOW_THREADS
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000210 if (ret < 0) {
Roger E. Masse919213a1996-12-17 17:42:22 +0000211 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000212 return NULL;
213 }
Roger E. Masse919213a1996-12-17 17:42:22 +0000214 Py_INCREF(Py_None);
215 return Py_None;
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000216}
217
Guido van Rossum185ead61998-11-23 15:32:55 +0000218static char flock_doc [] =
219"flock(fd, operation)\n\
220\n\
221Perform the lock operation op on file descriptor fd. See the Unix \n\
222manual flock(3) for details. (On some systems, this function is\n\
223emulated using fcntl().)";
224
225
Guido van Rossumc8643641996-09-11 23:17:20 +0000226/* lockf(fd, operation) */
Roger E. Masse919213a1996-12-17 17:42:22 +0000227static PyObject *
Guido van Rossumc8643641996-09-11 23:17:20 +0000228fcntl_lockf(self, args)
Roger E. Masse919213a1996-12-17 17:42:22 +0000229 PyObject *self; /* Not used */
230 PyObject *args;
Guido van Rossumc8643641996-09-11 23:17:20 +0000231{
232 int fd, code, len = 0, start = 0, whence = 0, ret;
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000233
Guido van Rossumc8643641996-09-11 23:17:20 +0000234 if (!PyArg_ParseTuple(args, "ii|iii", &fd, &code, &len,
235 &start, &whence))
236 return NULL;
237
Roger E. Masse919213a1996-12-17 17:42:22 +0000238 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc8643641996-09-11 23:17:20 +0000239#ifndef LOCK_SH
240#define LOCK_SH 1 /* shared lock */
241#define LOCK_EX 2 /* exclusive lock */
242#define LOCK_NB 4 /* don't block when locking */
243#define LOCK_UN 8 /* unlock */
244#endif
245 {
246 struct flock l;
247 if (code == LOCK_UN)
248 l.l_type = F_UNLCK;
249 else if (code & LOCK_SH)
250 l.l_type = F_RDLCK;
251 else if (code & LOCK_EX)
252 l.l_type = F_WRLCK;
253 else {
Roger E. Masse919213a1996-12-17 17:42:22 +0000254 PyErr_SetString(PyExc_ValueError,
255 "unrecognized flock argument");
Guido van Rossumc8643641996-09-11 23:17:20 +0000256 return NULL;
257 }
258 l.l_len = len;
259 l.l_start = start;
260 l.l_whence = whence;
261 ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
262 }
Roger E. Masse919213a1996-12-17 17:42:22 +0000263 Py_END_ALLOW_THREADS
Guido van Rossumc8643641996-09-11 23:17:20 +0000264 if (ret < 0) {
Roger E. Masse919213a1996-12-17 17:42:22 +0000265 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumc8643641996-09-11 23:17:20 +0000266 return NULL;
267 }
Roger E. Masse919213a1996-12-17 17:42:22 +0000268 Py_INCREF(Py_None);
269 return Py_None;
Guido van Rossumc8643641996-09-11 23:17:20 +0000270}
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000271
Guido van Rossum185ead61998-11-23 15:32:55 +0000272static char lockf_doc [] =
273"lockf (fd, operation)\n\
274\n\
275This is a wrapper around the FCNTL.F_SETLK and FCNTL.F_SETLKW fcntl()\n\
276calls. See the Unix manual for details.";
277
Guido van Rossum02975121992-08-17 08:55:12 +0000278/* List of functions */
279
Roger E. Masse919213a1996-12-17 17:42:22 +0000280static PyMethodDef fcntl_methods[] = {
Guido van Rossum185ead61998-11-23 15:32:55 +0000281 {"fcntl", fcntl_fcntl, 0, fcntl_doc},
282 {"ioctl", fcntl_ioctl, 0, ioctl_doc},
283 {"flock", fcntl_flock, 0, flock_doc},
284 {"lockf", fcntl_lockf, 1, lockf_doc},
Guido van Rossum02975121992-08-17 08:55:12 +0000285 {NULL, NULL} /* sentinel */
286};
287
288
Guido van Rossum185ead61998-11-23 15:32:55 +0000289static char module_doc [] =
290
291"This module performs file control and I/O control on file \n\
292descriptors. It is an interface to the fcntl() and ioctl() Unix\n\
293routines. File descriptors can be obtained with the fileno() method of\n\
294a file or socket object.";
295
Guido van Rossum02975121992-08-17 08:55:12 +0000296/* Module initialisation */
297
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000298static int
299ins(d, symbol, value)
300 PyObject* d;
301 char* symbol;
302 long value;
303{
304 PyObject* v = PyInt_FromLong(value);
305 if (!v || PyDict_SetItemString(d, symbol, v) < 0)
306 return -1;
307
308 Py_DECREF(v);
309 return 0;
310}
311
312static int
313all_ins(d)
314 PyObject* d;
315{
316 if (ins(d, "LOCK_SH", (long)LOCK_SH)) return -1;
317 if (ins(d, "LOCK_EX", (long)LOCK_EX)) return -1;
318 if (ins(d, "LOCK_NB", (long)LOCK_NB)) return -1;
319 if (ins(d, "LOCK_UN", (long)LOCK_UN)) return -1;
Guido van Rossum7c141031997-08-15 02:52:08 +0000320 return 0;
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000321}
322
Guido van Rossum3886bb61998-12-04 18:50:17 +0000323DL_EXPORT(void)
Guido van Rossum02975121992-08-17 08:55:12 +0000324initfcntl()
325{
Roger E. Masse919213a1996-12-17 17:42:22 +0000326 PyObject *m, *d;
Guido van Rossum02975121992-08-17 08:55:12 +0000327
Guido van Rossum185ead61998-11-23 15:32:55 +0000328 /* Create the module and add the functions and documentation */
329 m = Py_InitModule3("fcntl", fcntl_methods, module_doc);
Guido van Rossum02975121992-08-17 08:55:12 +0000330
331 /* Add some symbolic constants to the module */
Roger E. Masse919213a1996-12-17 17:42:22 +0000332 d = PyModule_GetDict(m);
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000333 all_ins(d);
Guido van Rossum02975121992-08-17 08:55:12 +0000334
335 /* Check for errors */
Roger E. Masse919213a1996-12-17 17:42:22 +0000336 if (PyErr_Occurred())
337 Py_FatalError("can't initialize module fcntl");
Guido van Rossum02975121992-08-17 08:55:12 +0000338}