Bump version to 0.9.1.
[python/dscho.git] / Modules / fcntlmodule.c
blob174a904ced531d842b8e23f5b3b5ab6b283194b2
1 /***********************************************************
2 Copyright (c) 2000, BeOpen.com.
3 Copyright (c) 1995-2000, Corporation for National Research Initiatives.
4 Copyright (c) 1990-1995, Stichting Mathematisch Centrum.
5 All rights reserved.
7 See the file "Misc/COPYRIGHT" for information on usage and
8 redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
9 ******************************************************************/
11 /* fcntl module */
13 #include "Python.h"
15 #ifdef HAVE_UNISTD_H
16 #include <unistd.h>
17 #endif
19 #ifdef HAVE_SYS_FILE_H
20 #include <sys/file.h>
21 #endif
23 #include <sys/ioctl.h>
24 #include <fcntl.h>
27 /* fcntl(fd, opt, [arg]) */
29 static PyObject *
30 fcntl_fcntl(PyObject *self, PyObject *args)
32 int fd;
33 int code;
34 int arg;
35 int ret;
36 char *str;
37 int len;
38 char buf[1024];
40 if (PyArg_ParseTuple(args, "iis#:fcntl", &fd, &code, &str, &len)) {
41 if (len > sizeof buf) {
42 PyErr_SetString(PyExc_ValueError,
43 "fcntl string arg too long");
44 return NULL;
46 memcpy(buf, str, len);
47 Py_BEGIN_ALLOW_THREADS
48 ret = fcntl(fd, code, buf);
49 Py_END_ALLOW_THREADS
50 if (ret < 0) {
51 PyErr_SetFromErrno(PyExc_IOError);
52 return NULL;
54 return PyString_FromStringAndSize(buf, len);
57 PyErr_Clear();
58 arg = 0;
59 if (!PyArg_ParseTuple(args, "ii|i;fcntl requires 2 integers and optionally a third integer or a string",
60 &fd, &code, &arg)) {
61 return NULL;
63 Py_BEGIN_ALLOW_THREADS
64 ret = fcntl(fd, code, arg);
65 Py_END_ALLOW_THREADS
66 if (ret < 0) {
67 PyErr_SetFromErrno(PyExc_IOError);
68 return NULL;
70 return PyInt_FromLong((long)ret);
73 static char fcntl_doc [] =
75 "fcntl(fd, opt, [arg])\n\
76 \n\
77 Perform the requested operation on file descriptor fd. The operation\n\
78 is defined by op and is operating system dependent. Typically these\n\
79 codes can be retrieved from the library module FCNTL. The argument arg\n\
80 is optional, and defaults to 0; it may be an int or a string. If arg is\n\
81 given as a string, the return value of fcntl is a string of that length,\n\
82 containing the resulting value put in the arg buffer by the operating system.\n\
83 The length of the arg string is not allowed to exceed 1024 bytes. If the arg\n\
84 given is an integer or if none is specified, the result value is an integer\n\
85 corresponding to the return value of the fcntl call in the C code.";
88 /* ioctl(fd, opt, [arg]) */
90 static PyObject *
91 fcntl_ioctl(PyObject *self, PyObject *args)
93 int fd;
94 int code;
95 int arg;
96 int ret;
97 char *str;
98 int len;
99 char buf[1024];
101 if (PyArg_ParseTuple(args, "iis#:ioctl", &fd, &code, &str, &len)) {
102 if (len > sizeof buf) {
103 PyErr_SetString(PyExc_ValueError,
104 "ioctl string arg too long");
105 return NULL;
107 memcpy(buf, str, len);
108 Py_BEGIN_ALLOW_THREADS
109 ret = ioctl(fd, code, buf);
110 Py_END_ALLOW_THREADS
111 if (ret < 0) {
112 PyErr_SetFromErrno(PyExc_IOError);
113 return NULL;
115 return PyString_FromStringAndSize(buf, len);
118 PyErr_Clear();
119 arg = 0;
120 if (!PyArg_ParseTuple(args, "ii|i;ioctl requires 2 integers and optionally a third integer or a string",
121 &fd, &code, &arg)) {
122 return NULL;
124 Py_BEGIN_ALLOW_THREADS
125 ret = ioctl(fd, code, arg);
126 Py_END_ALLOW_THREADS
127 if (ret < 0) {
128 PyErr_SetFromErrno(PyExc_IOError);
129 return NULL;
131 return PyInt_FromLong((long)ret);
134 static char ioctl_doc [] =
135 "ioctl(fd, opt, [arg])\n\
137 Perform the requested operation on file descriptor fd. The operation\n\
138 is defined by op and is operating system dependent. Typically these\n\
139 codes can be retrieved from the library module IOCTL. The argument arg\n\
140 is optional, and defaults to 0; it may be an int or a string. If arg is\n\
141 given as a string, the return value of ioctl is a string of that length,\n\
142 containing the resulting value put in the arg buffer by the operating system.\n\
143 The length of the arg string is not allowed to exceed 1024 bytes. If the arg\n\
144 given is an integer or if none is specified, the result value is an integer\n\
145 corresponding to the return value of the ioctl call in the C code.";
148 /* flock(fd, operation) */
150 static PyObject *
151 fcntl_flock(PyObject *self, PyObject *args)
153 int fd;
154 int code;
155 int ret;
157 if (!PyArg_ParseTuple(args, "ii:flock", &fd, &code))
158 return NULL;
160 #ifdef HAVE_FLOCK
161 Py_BEGIN_ALLOW_THREADS
162 ret = flock(fd, code);
163 Py_END_ALLOW_THREADS
164 #else
166 #ifndef LOCK_SH
167 #define LOCK_SH 1 /* shared lock */
168 #define LOCK_EX 2 /* exclusive lock */
169 #define LOCK_NB 4 /* don't block when locking */
170 #define LOCK_UN 8 /* unlock */
171 #endif
173 struct flock l;
174 if (code == LOCK_UN)
175 l.l_type = F_UNLCK;
176 else if (code & LOCK_SH)
177 l.l_type = F_RDLCK;
178 else if (code & LOCK_EX)
179 l.l_type = F_WRLCK;
180 else {
181 PyErr_SetString(PyExc_ValueError,
182 "unrecognized flock argument");
183 return NULL;
185 l.l_whence = l.l_start = l.l_len = 0;
186 Py_BEGIN_ALLOW_THREADS
187 ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
188 Py_END_ALLOW_THREADS
190 #endif /* HAVE_FLOCK */
191 if (ret < 0) {
192 PyErr_SetFromErrno(PyExc_IOError);
193 return NULL;
195 Py_INCREF(Py_None);
196 return Py_None;
199 static char flock_doc [] =
200 "flock(fd, operation)\n\
202 Perform the lock operation op on file descriptor fd. See the Unix \n\
203 manual flock(3) for details. (On some systems, this function is\n\
204 emulated using fcntl().)";
207 /* lockf(fd, operation) */
208 static PyObject *
209 fcntl_lockf(PyObject *self, PyObject *args)
211 int fd, code, ret, whence = 0;
212 PyObject *lenobj = NULL, *startobj = NULL;
214 if (!PyArg_ParseTuple(args, "ii|OOi:lockf", &fd, &code,
215 &lenobj, &startobj, &whence))
216 return NULL;
218 #ifndef LOCK_SH
219 #define LOCK_SH 1 /* shared lock */
220 #define LOCK_EX 2 /* exclusive lock */
221 #define LOCK_NB 4 /* don't block when locking */
222 #define LOCK_UN 8 /* unlock */
223 #endif
225 struct flock l;
226 if (code == LOCK_UN)
227 l.l_type = F_UNLCK;
228 else if (code & LOCK_SH)
229 l.l_type = F_RDLCK;
230 else if (code & LOCK_EX)
231 l.l_type = F_WRLCK;
232 else {
233 PyErr_SetString(PyExc_ValueError,
234 "unrecognized flock argument");
235 return NULL;
237 l.l_start = l.l_len = 0;
238 if (startobj != NULL) {
239 #if !defined(HAVE_LARGEFILE_SUPPORT)
240 l.l_start = PyInt_AsLong(startobj);
241 #else
242 l.l_start = PyLong_Check(startobj) ?
243 PyLong_AsLongLong(startobj) :
244 PyInt_AsLong(startobj);
245 #endif
246 if (PyErr_Occurred())
247 return NULL;
249 if (lenobj != NULL) {
250 #if !defined(HAVE_LARGEFILE_SUPPORT)
251 l.l_len = PyInt_AsLong(lenobj);
252 #else
253 l.l_len = PyLong_Check(lenobj) ?
254 PyLong_AsLongLong(lenobj) :
255 PyInt_AsLong(lenobj);
256 #endif
257 if (PyErr_Occurred())
258 return NULL;
260 l.l_whence = whence;
261 Py_BEGIN_ALLOW_THREADS
262 ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
263 Py_END_ALLOW_THREADS
265 if (ret < 0) {
266 PyErr_SetFromErrno(PyExc_IOError);
267 return NULL;
269 Py_INCREF(Py_None);
270 return Py_None;
273 static char lockf_doc [] =
274 "lockf (fd, operation)\n\
276 This is a wrapper around the FCNTL.F_SETLK and FCNTL.F_SETLKW fcntl()\n\
277 calls. See the Unix manual for details.";
279 /* List of functions */
281 static PyMethodDef fcntl_methods[] = {
282 {"fcntl", fcntl_fcntl, METH_VARARGS, fcntl_doc},
283 {"ioctl", fcntl_ioctl, METH_VARARGS, ioctl_doc},
284 {"flock", fcntl_flock, METH_VARARGS, flock_doc},
285 {"lockf", fcntl_lockf, METH_VARARGS, lockf_doc},
286 {NULL, NULL} /* sentinel */
290 static char module_doc [] =
292 "This module performs file control and I/O control on file \n\
293 descriptors. It is an interface to the fcntl() and ioctl() Unix\n\
294 routines. File descriptors can be obtained with the fileno() method of\n\
295 a file or socket object.";
297 /* Module initialisation */
299 static int
300 ins(PyObject* d, char* symbol, long value)
302 PyObject* v = PyInt_FromLong(value);
303 if (!v || PyDict_SetItemString(d, symbol, v) < 0)
304 return -1;
306 Py_DECREF(v);
307 return 0;
310 static int
311 all_ins(PyObject* d)
313 if (ins(d, "LOCK_SH", (long)LOCK_SH)) return -1;
314 if (ins(d, "LOCK_EX", (long)LOCK_EX)) return -1;
315 if (ins(d, "LOCK_NB", (long)LOCK_NB)) return -1;
316 if (ins(d, "LOCK_UN", (long)LOCK_UN)) return -1;
317 return 0;
320 DL_EXPORT(void)
321 initfcntl(void)
323 PyObject *m, *d;
325 /* Create the module and add the functions and documentation */
326 m = Py_InitModule3("fcntl", fcntl_methods, module_doc);
328 /* Add some symbolic constants to the module */
329 d = PyModule_GetDict(m);
330 all_ins(d);
332 /* Check for errors */
333 if (PyErr_Occurred())
334 Py_FatalError("can't initialize module fcntl");