Ditched '_find_SET()', since it was a no-value-added wrapper around
[python/dscho.git] / Modules / fcntlmodule.c
blob1764bca705db00906486ad320b3b73be8b1f8cbf
1 /***********************************************************
2 Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3 The Netherlands.
5 All Rights Reserved
7 Permission to use, copy, modify, and distribute this software and its
8 documentation for any purpose and without fee is hereby granted,
9 provided that the above copyright notice appear in all copies and that
10 both that copyright notice and this permission notice appear in
11 supporting documentation, and that the names of Stichting Mathematisch
12 Centrum or CWI or Corporation for National Research Initiatives or
13 CNRI not be used in advertising or publicity pertaining to
14 distribution of the software without specific, written prior
15 permission.
17 While CWI is the initial source for this software, a modified version
18 is made available by the Corporation for National Research Initiatives
19 (CNRI) at the Internet address ftp://ftp.python.org.
21 STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22 REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23 MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24 CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26 PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27 TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28 PERFORMANCE OF THIS SOFTWARE.
30 ******************************************************************/
32 /* fcntl module */
34 #include "Python.h"
36 #ifdef HAVE_UNISTD_H
37 #include <unistd.h>
38 #endif
40 #ifdef HAVE_SYS_FILE_H
41 #include <sys/file.h>
42 #endif
44 #include <sys/ioctl.h>
45 #include <fcntl.h>
48 /* fcntl(fd, opt, [arg]) */
50 static PyObject *
51 fcntl_fcntl(self, args)
52 PyObject *self; /* Not used */
53 PyObject *args;
55 int fd;
56 int code;
57 int arg;
58 int ret;
59 char *str;
60 int len;
61 char buf[1024];
63 if (PyArg_Parse(args, "(iis#)", &fd, &code, &str, &len)) {
64 if (len > sizeof buf) {
65 PyErr_SetString(PyExc_ValueError,
66 "fcntl string arg too long");
67 return NULL;
69 memcpy(buf, str, len);
70 Py_BEGIN_ALLOW_THREADS
71 ret = fcntl(fd, code, buf);
72 Py_END_ALLOW_THREADS
73 if (ret < 0) {
74 PyErr_SetFromErrno(PyExc_IOError);
75 return NULL;
77 return PyString_FromStringAndSize(buf, len);
80 PyErr_Clear();
81 if (PyArg_Parse(args, "(ii)", &fd, &code))
82 arg = 0;
83 else {
84 PyErr_Clear();
85 if (!PyArg_Parse(args, "(iii)", &fd, &code, &arg))
86 return NULL;
88 Py_BEGIN_ALLOW_THREADS
89 ret = fcntl(fd, code, arg);
90 Py_END_ALLOW_THREADS
91 if (ret < 0) {
92 PyErr_SetFromErrno(PyExc_IOError);
93 return NULL;
95 return PyInt_FromLong((long)ret);
98 static char fcntl_doc [] =
100 "fcntl(fd, opt, [arg])\n\
102 Perform the requested operation on file descriptor fd. The operation\n\
103 is defined by op and is operating system dependent. Typically these\n\
104 codes can be retrieved from the library module FCNTL. The argument arg\n\
105 is optional, and defaults to 0; it may be an int or a string.";
108 /* ioctl(fd, opt, [arg]) */
110 static PyObject *
111 fcntl_ioctl(self, args)
112 PyObject *self; /* Not used */
113 PyObject *args;
115 int fd;
116 int code;
117 int arg;
118 int ret;
119 char *str;
120 int len;
121 char buf[1024];
123 if (PyArg_Parse(args, "(iis#)", &fd, &code, &str, &len)) {
124 if (len > sizeof buf) {
125 PyErr_SetString(PyExc_ValueError,
126 "ioctl string arg too long");
127 return NULL;
129 memcpy(buf, str, len);
130 Py_BEGIN_ALLOW_THREADS
131 ret = ioctl(fd, code, buf);
132 Py_END_ALLOW_THREADS
133 if (ret < 0) {
134 PyErr_SetFromErrno(PyExc_IOError);
135 return NULL;
137 return PyString_FromStringAndSize(buf, len);
140 PyErr_Clear();
141 if (PyArg_Parse(args, "(ii)", &fd, &code))
142 arg = 0;
143 else {
144 PyErr_Clear();
145 if (!PyArg_Parse(args, "(iii)", &fd, &code, &arg))
146 return NULL;
148 Py_BEGIN_ALLOW_THREADS
149 ret = ioctl(fd, code, arg);
150 Py_END_ALLOW_THREADS
151 if (ret < 0) {
152 PyErr_SetFromErrno(PyExc_IOError);
153 return NULL;
155 return PyInt_FromLong((long)ret);
158 static char ioctl_doc [] =
159 "ioctl(fd, opt, [arg])\n\
161 Perform the requested operation on file descriptor fd. The operation\n\
162 is defined by op and is operating system dependent. Typically these\n\
163 codes can be retrieved from the library module IOCTL. The argument arg\n\
164 is optional, and defaults to 0; it may be an int or a string.";
167 /* flock(fd, operation) */
169 static PyObject *
170 fcntl_flock(self, args)
171 PyObject *self; /* Not used */
172 PyObject *args;
174 int fd;
175 int code;
176 int ret;
178 if (!PyArg_Parse(args, "(ii)", &fd, &code))
179 return NULL;
181 #ifdef HAVE_FLOCK
182 Py_BEGIN_ALLOW_THREADS
183 ret = flock(fd, code);
184 Py_END_ALLOW_THREADS
185 #else
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
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 {
202 PyErr_SetString(PyExc_ValueError,
203 "unrecognized flock argument");
204 return NULL;
206 l.l_whence = l.l_start = l.l_len = 0;
207 Py_BEGIN_ALLOW_THREADS
208 ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
209 Py_END_ALLOW_THREADS
211 #endif /* HAVE_FLOCK */
212 if (ret < 0) {
213 PyErr_SetFromErrno(PyExc_IOError);
214 return NULL;
216 Py_INCREF(Py_None);
217 return Py_None;
220 static char flock_doc [] =
221 "flock(fd, operation)\n\
223 Perform the lock operation op on file descriptor fd. See the Unix \n\
224 manual flock(3) for details. (On some systems, this function is\n\
225 emulated using fcntl().)";
228 /* lockf(fd, operation) */
229 static PyObject *
230 fcntl_lockf(self, args)
231 PyObject *self; /* Not used */
232 PyObject *args;
234 int fd, code, ret, whence = 0;
235 PyObject *lenobj = NULL, *startobj = NULL;
237 if (!PyArg_ParseTuple(args, "ii|OOi", &fd, &code,
238 &lenobj, &startobj, &whence))
239 return NULL;
241 #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
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 {
256 PyErr_SetString(PyExc_ValueError,
257 "unrecognized flock argument");
258 return NULL;
260 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;
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;
283 l.l_whence = whence;
284 Py_BEGIN_ALLOW_THREADS
285 ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
286 Py_END_ALLOW_THREADS
288 if (ret < 0) {
289 PyErr_SetFromErrno(PyExc_IOError);
290 return NULL;
292 Py_INCREF(Py_None);
293 return Py_None;
296 static char lockf_doc [] =
297 "lockf (fd, operation)\n\
299 This is a wrapper around the FCNTL.F_SETLK and FCNTL.F_SETLKW fcntl()\n\
300 calls. See the Unix manual for details.";
302 /* List of functions */
304 static PyMethodDef fcntl_methods[] = {
305 {"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},
309 {NULL, NULL} /* sentinel */
313 static char module_doc [] =
315 "This module performs file control and I/O control on file \n\
316 descriptors. It is an interface to the fcntl() and ioctl() Unix\n\
317 routines. File descriptors can be obtained with the fileno() method of\n\
318 a file or socket object.";
320 /* Module initialisation */
322 static int
323 ins(d, symbol, value)
324 PyObject* d;
325 char* symbol;
326 long value;
328 PyObject* v = PyInt_FromLong(value);
329 if (!v || PyDict_SetItemString(d, symbol, v) < 0)
330 return -1;
332 Py_DECREF(v);
333 return 0;
336 static int
337 all_ins(d)
338 PyObject* d;
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;
344 return 0;
347 DL_EXPORT(void)
348 initfcntl()
350 PyObject *m, *d;
352 /* Create the module and add the functions and documentation */
353 m = Py_InitModule3("fcntl", fcntl_methods, module_doc);
355 /* Add some symbolic constants to the module */
356 d = PyModule_GetDict(m);
357 all_ins(d);
359 /* Check for errors */
360 if (PyErr_Occurred())
361 Py_FatalError("can't initialize module fcntl");