blob: 8f7407f52ab0053c03a2c25f06f813ebfe9f8ca2 [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
98
99/* ioctl(fd, opt, [arg]) */
100
Roger E. Masse919213a1996-12-17 17:42:22 +0000101static PyObject *
Guido van Rossum02975121992-08-17 08:55:12 +0000102fcntl_ioctl(self, args)
Roger E. Masse919213a1996-12-17 17:42:22 +0000103 PyObject *self; /* Not used */
104 PyObject *args;
Guido van Rossum02975121992-08-17 08:55:12 +0000105{
106 int fd;
107 int code;
108 int arg;
109 int ret;
110 char *str;
111 int len;
112 char buf[1024];
113
Roger E. Masse919213a1996-12-17 17:42:22 +0000114 if (PyArg_Parse(args, "(iis#)", &fd, &code, &str, &len)) {
Guido van Rossum02975121992-08-17 08:55:12 +0000115 if (len > sizeof buf) {
Roger E. Masse919213a1996-12-17 17:42:22 +0000116 PyErr_SetString(PyExc_ValueError,
117 "ioctl string arg too long");
Guido van Rossum02975121992-08-17 08:55:12 +0000118 return NULL;
119 }
120 memcpy(buf, str, len);
Roger E. Masse919213a1996-12-17 17:42:22 +0000121 Py_BEGIN_ALLOW_THREADS
Guido van Rossum903f4871995-10-07 19:18:22 +0000122 ret = ioctl(fd, code, buf);
Roger E. Masse919213a1996-12-17 17:42:22 +0000123 Py_END_ALLOW_THREADS
Guido van Rossum903f4871995-10-07 19:18:22 +0000124 if (ret < 0) {
Roger E. Masse919213a1996-12-17 17:42:22 +0000125 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum02975121992-08-17 08:55:12 +0000126 return NULL;
127 }
Roger E. Masse919213a1996-12-17 17:42:22 +0000128 return PyString_FromStringAndSize(buf, len);
Guido van Rossum02975121992-08-17 08:55:12 +0000129 }
130
Roger E. Masse919213a1996-12-17 17:42:22 +0000131 PyErr_Clear();
132 if (PyArg_Parse(args, "(ii)", &fd, &code))
Guido van Rossum02975121992-08-17 08:55:12 +0000133 arg = 0;
134 else {
Roger E. Masse919213a1996-12-17 17:42:22 +0000135 PyErr_Clear();
136 if (!PyArg_Parse(args, "(iii)", &fd, &code, &arg))
Guido van Rossum02975121992-08-17 08:55:12 +0000137 return NULL;
138 }
Roger E. Masse919213a1996-12-17 17:42:22 +0000139 Py_BEGIN_ALLOW_THREADS
Guido van Rossum02975121992-08-17 08:55:12 +0000140 ret = ioctl(fd, code, arg);
Roger E. Masse919213a1996-12-17 17:42:22 +0000141 Py_END_ALLOW_THREADS
Guido van Rossum02975121992-08-17 08:55:12 +0000142 if (ret < 0) {
Roger E. Masse919213a1996-12-17 17:42:22 +0000143 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum02975121992-08-17 08:55:12 +0000144 return NULL;
145 }
Roger E. Masse919213a1996-12-17 17:42:22 +0000146 return PyInt_FromLong((long)ret);
Guido van Rossum02975121992-08-17 08:55:12 +0000147}
148
149
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000150/* flock(fd, operation) */
151
Roger E. Masse919213a1996-12-17 17:42:22 +0000152static PyObject *
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000153fcntl_flock(self, args)
Roger E. Masse919213a1996-12-17 17:42:22 +0000154 PyObject *self; /* Not used */
155 PyObject *args;
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000156{
157 int fd;
158 int code;
159 int ret;
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000160
Roger E. Masse919213a1996-12-17 17:42:22 +0000161 if (!PyArg_Parse(args, "(ii)", &fd, &code))
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000162 return NULL;
163
Roger E. Masse919213a1996-12-17 17:42:22 +0000164 Py_BEGIN_ALLOW_THREADS
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000165#ifdef HAVE_FLOCK
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000166 ret = flock(fd, code);
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000167#else
168
169#ifndef LOCK_SH
170#define LOCK_SH 1 /* shared lock */
171#define LOCK_EX 2 /* exclusive lock */
172#define LOCK_NB 4 /* don't block when locking */
173#define LOCK_UN 8 /* unlock */
174#endif
175 {
176 struct flock l;
177 if (code == LOCK_UN)
178 l.l_type = F_UNLCK;
179 else if (code & LOCK_SH)
180 l.l_type = F_RDLCK;
181 else if (code & LOCK_EX)
182 l.l_type = F_WRLCK;
183 else {
Roger E. Masse919213a1996-12-17 17:42:22 +0000184 PyErr_SetString(PyExc_ValueError,
185 "unrecognized flock argument");
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000186 return NULL;
187 }
188 l.l_whence = l.l_start = l.l_len = 0;
189 ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
190 }
191#endif /* HAVE_FLOCK */
Roger E. Masse919213a1996-12-17 17:42:22 +0000192 Py_END_ALLOW_THREADS
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000193 if (ret < 0) {
Roger E. Masse919213a1996-12-17 17:42:22 +0000194 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000195 return NULL;
196 }
Roger E. Masse919213a1996-12-17 17:42:22 +0000197 Py_INCREF(Py_None);
198 return Py_None;
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000199}
200
Guido van Rossumc8643641996-09-11 23:17:20 +0000201/* lockf(fd, operation) */
Roger E. Masse919213a1996-12-17 17:42:22 +0000202static PyObject *
Guido van Rossumc8643641996-09-11 23:17:20 +0000203fcntl_lockf(self, args)
Roger E. Masse919213a1996-12-17 17:42:22 +0000204 PyObject *self; /* Not used */
205 PyObject *args;
Guido van Rossumc8643641996-09-11 23:17:20 +0000206{
207 int fd, code, len = 0, start = 0, whence = 0, ret;
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000208
Guido van Rossumc8643641996-09-11 23:17:20 +0000209 if (!PyArg_ParseTuple(args, "ii|iii", &fd, &code, &len,
210 &start, &whence))
211 return NULL;
212
Roger E. Masse919213a1996-12-17 17:42:22 +0000213 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc8643641996-09-11 23:17:20 +0000214#ifndef LOCK_SH
215#define LOCK_SH 1 /* shared lock */
216#define LOCK_EX 2 /* exclusive lock */
217#define LOCK_NB 4 /* don't block when locking */
218#define LOCK_UN 8 /* unlock */
219#endif
220 {
221 struct flock l;
222 if (code == LOCK_UN)
223 l.l_type = F_UNLCK;
224 else if (code & LOCK_SH)
225 l.l_type = F_RDLCK;
226 else if (code & LOCK_EX)
227 l.l_type = F_WRLCK;
228 else {
Roger E. Masse919213a1996-12-17 17:42:22 +0000229 PyErr_SetString(PyExc_ValueError,
230 "unrecognized flock argument");
Guido van Rossumc8643641996-09-11 23:17:20 +0000231 return NULL;
232 }
233 l.l_len = len;
234 l.l_start = start;
235 l.l_whence = whence;
236 ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
237 }
Roger E. Masse919213a1996-12-17 17:42:22 +0000238 Py_END_ALLOW_THREADS
Guido van Rossumc8643641996-09-11 23:17:20 +0000239 if (ret < 0) {
Roger E. Masse919213a1996-12-17 17:42:22 +0000240 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumc8643641996-09-11 23:17:20 +0000241 return NULL;
242 }
Roger E. Masse919213a1996-12-17 17:42:22 +0000243 Py_INCREF(Py_None);
244 return Py_None;
Guido van Rossumc8643641996-09-11 23:17:20 +0000245}
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000246
Guido van Rossum02975121992-08-17 08:55:12 +0000247/* List of functions */
248
Roger E. Masse919213a1996-12-17 17:42:22 +0000249static PyMethodDef fcntl_methods[] = {
Guido van Rossum02975121992-08-17 08:55:12 +0000250 {"fcntl", fcntl_fcntl},
251 {"ioctl", fcntl_ioctl},
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000252 {"flock", fcntl_flock},
Guido van Rossumc8643641996-09-11 23:17:20 +0000253 {"lockf", fcntl_lockf, 1},
Guido van Rossum02975121992-08-17 08:55:12 +0000254 {NULL, NULL} /* sentinel */
255};
256
257
258/* Module initialisation */
259
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000260static int
261ins(d, symbol, value)
262 PyObject* d;
263 char* symbol;
264 long value;
265{
266 PyObject* v = PyInt_FromLong(value);
267 if (!v || PyDict_SetItemString(d, symbol, v) < 0)
268 return -1;
269
270 Py_DECREF(v);
271 return 0;
272}
273
274static int
275all_ins(d)
276 PyObject* d;
277{
278 if (ins(d, "LOCK_SH", (long)LOCK_SH)) return -1;
279 if (ins(d, "LOCK_EX", (long)LOCK_EX)) return -1;
280 if (ins(d, "LOCK_NB", (long)LOCK_NB)) return -1;
281 if (ins(d, "LOCK_UN", (long)LOCK_UN)) return -1;
Guido van Rossum7c141031997-08-15 02:52:08 +0000282 return 0;
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000283}
284
Guido van Rossum02975121992-08-17 08:55:12 +0000285void
286initfcntl()
287{
Roger E. Masse919213a1996-12-17 17:42:22 +0000288 PyObject *m, *d;
Guido van Rossum02975121992-08-17 08:55:12 +0000289
290 /* Create the module and add the functions */
Roger E. Masse919213a1996-12-17 17:42:22 +0000291 m = Py_InitModule("fcntl", fcntl_methods);
Guido van Rossum02975121992-08-17 08:55:12 +0000292
293 /* Add some symbolic constants to the module */
Roger E. Masse919213a1996-12-17 17:42:22 +0000294 d = PyModule_GetDict(m);
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000295 all_ins(d);
Guido van Rossum02975121992-08-17 08:55:12 +0000296
297 /* Check for errors */
Roger E. Masse919213a1996-12-17 17:42:22 +0000298 if (PyErr_Occurred())
299 Py_FatalError("can't initialize module fcntl");
Guido van Rossum02975121992-08-17 08:55:12 +0000300}