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.
7 See the file "Misc/COPYRIGHT" for information on usage and
8 redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
9 ******************************************************************/
19 #ifdef HAVE_SYS_FILE_H
23 #include <sys/ioctl.h>
27 /* fcntl(fd, opt, [arg]) */
30 fcntl_fcntl(PyObject
*self
, PyObject
*args
)
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");
46 memcpy(buf
, str
, len
);
47 Py_BEGIN_ALLOW_THREADS
48 ret
= fcntl(fd
, code
, buf
);
51 PyErr_SetFromErrno(PyExc_IOError
);
54 return PyString_FromStringAndSize(buf
, len
);
59 if (!PyArg_ParseTuple(args
, "ii|i;fcntl requires 2 integers and optionally a third integer or a string",
63 Py_BEGIN_ALLOW_THREADS
64 ret
= fcntl(fd
, code
, arg
);
67 PyErr_SetFromErrno(PyExc_IOError
);
70 return PyInt_FromLong((long)ret
);
73 static char fcntl_doc
[] =
75 "fcntl(fd, opt, [arg])\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]) */
91 fcntl_ioctl(PyObject
*self
, PyObject
*args
)
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");
107 memcpy(buf
, str
, len
);
108 Py_BEGIN_ALLOW_THREADS
109 ret
= ioctl(fd
, code
, buf
);
112 PyErr_SetFromErrno(PyExc_IOError
);
115 return PyString_FromStringAndSize(buf
, len
);
120 if (!PyArg_ParseTuple(args
, "ii|i;ioctl requires 2 integers and optionally a third integer or a string",
124 Py_BEGIN_ALLOW_THREADS
125 ret
= ioctl(fd
, code
, arg
);
128 PyErr_SetFromErrno(PyExc_IOError
);
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) */
151 fcntl_flock(PyObject
*self
, PyObject
*args
)
157 if (!PyArg_ParseTuple(args
, "ii:flock", &fd
, &code
))
161 Py_BEGIN_ALLOW_THREADS
162 ret
= flock(fd
, code
);
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 */
176 else if (code
& LOCK_SH
)
178 else if (code
& LOCK_EX
)
181 PyErr_SetString(PyExc_ValueError
,
182 "unrecognized flock argument");
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
);
190 #endif /* HAVE_FLOCK */
192 PyErr_SetFromErrno(PyExc_IOError
);
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) */
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
))
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 */
228 else if (code
& LOCK_SH
)
230 else if (code
& LOCK_EX
)
233 PyErr_SetString(PyExc_ValueError
,
234 "unrecognized flock argument");
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
);
242 l
.l_start
= PyLong_Check(startobj
) ?
243 PyLong_AsLongLong(startobj
) :
244 PyInt_AsLong(startobj
);
246 if (PyErr_Occurred())
249 if (lenobj
!= NULL
) {
250 #if !defined(HAVE_LARGEFILE_SUPPORT)
251 l
.l_len
= PyInt_AsLong(lenobj
);
253 l
.l_len
= PyLong_Check(lenobj
) ?
254 PyLong_AsLongLong(lenobj
) :
255 PyInt_AsLong(lenobj
);
257 if (PyErr_Occurred())
261 Py_BEGIN_ALLOW_THREADS
262 ret
= fcntl(fd
, (code
& LOCK_NB
) ? F_SETLK
: F_SETLKW
, &l
);
266 PyErr_SetFromErrno(PyExc_IOError
);
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 */
300 ins(PyObject
* d
, char* symbol
, long value
)
302 PyObject
* v
= PyInt_FromLong(value
);
303 if (!v
|| PyDict_SetItemString(d
, symbol
, v
) < 0)
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;
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
);
332 /* Check for errors */
333 if (PyErr_Occurred())
334 Py_FatalError("can't initialize module fcntl");