blob: 5aa5516055fb4f319b3c00362f89bfbe6fdf9011 [file] [log] [blame]
Guido van Rossum02975121992-08-17 08:55:12 +00001
2/* fcntl module */
3
Roger E. Masse919213a1996-12-17 17:42:22 +00004#include "Python.h"
Guido van Rossum02975121992-08-17 08:55:12 +00005
Guido van Rossuma376cc51996-12-05 23:43:35 +00006#ifdef HAVE_UNISTD_H
7#include <unistd.h>
8#endif
9
10#ifdef HAVE_SYS_FILE_H
11#include <sys/file.h>
12#endif
13
Guido van Rossum3d65fa31996-12-09 18:49:14 +000014#include <sys/ioctl.h>
Guido van Rossum3c0b79c1996-06-11 15:11:34 +000015#include <fcntl.h>
16
Guido van Rossum02975121992-08-17 08:55:12 +000017
18/* fcntl(fd, opt, [arg]) */
19
Roger E. Masse919213a1996-12-17 17:42:22 +000020static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +000021fcntl_fcntl(PyObject *self, PyObject *args)
Guido van Rossum02975121992-08-17 08:55:12 +000022{
23 int fd;
24 int code;
25 int arg;
26 int ret;
27 char *str;
28 int len;
29 char buf[1024];
30
Guido van Rossuma2214c32000-08-02 20:46:51 +000031 if (PyArg_ParseTuple(args, "iis#:fcntl", &fd, &code, &str, &len)) {
Guido van Rossum02975121992-08-17 08:55:12 +000032 if (len > sizeof buf) {
Roger E. Masse919213a1996-12-17 17:42:22 +000033 PyErr_SetString(PyExc_ValueError,
34 "fcntl string arg too long");
Guido van Rossum02975121992-08-17 08:55:12 +000035 return NULL;
36 }
37 memcpy(buf, str, len);
Roger E. Masse919213a1996-12-17 17:42:22 +000038 Py_BEGIN_ALLOW_THREADS
Guido van Rossum903f4871995-10-07 19:18:22 +000039 ret = fcntl(fd, code, buf);
Roger E. Masse919213a1996-12-17 17:42:22 +000040 Py_END_ALLOW_THREADS
Guido van Rossum903f4871995-10-07 19:18:22 +000041 if (ret < 0) {
Roger E. Masse919213a1996-12-17 17:42:22 +000042 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum02975121992-08-17 08:55:12 +000043 return NULL;
44 }
Roger E. Masse919213a1996-12-17 17:42:22 +000045 return PyString_FromStringAndSize(buf, len);
Guido van Rossum02975121992-08-17 08:55:12 +000046 }
47
Roger E. Masse919213a1996-12-17 17:42:22 +000048 PyErr_Clear();
Guido van Rossuma2214c32000-08-02 20:46:51 +000049 arg = 0;
50 if (!PyArg_ParseTuple(args, "ii|i;fcntl requires 2 integers and optionally a third integer or a string",
51 &fd, &code, &arg)) {
52 return NULL;
Guido van Rossum02975121992-08-17 08:55:12 +000053 }
Roger E. Masse919213a1996-12-17 17:42:22 +000054 Py_BEGIN_ALLOW_THREADS
Guido van Rossum02975121992-08-17 08:55:12 +000055 ret = fcntl(fd, code, arg);
Roger E. Masse919213a1996-12-17 17:42:22 +000056 Py_END_ALLOW_THREADS
Guido van Rossum02975121992-08-17 08:55:12 +000057 if (ret < 0) {
Roger E. Masse919213a1996-12-17 17:42:22 +000058 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum02975121992-08-17 08:55:12 +000059 return NULL;
60 }
Roger E. Masse919213a1996-12-17 17:42:22 +000061 return PyInt_FromLong((long)ret);
Guido van Rossum02975121992-08-17 08:55:12 +000062}
63
Guido van Rossum185ead61998-11-23 15:32:55 +000064static char fcntl_doc [] =
65
66"fcntl(fd, opt, [arg])\n\
67\n\
68Perform the requested operation on file descriptor fd. The operation\n\
69is defined by op and is operating system dependent. Typically these\n\
70codes can be retrieved from the library module FCNTL. The argument arg\n\
Guido van Rossuma2214c32000-08-02 20:46:51 +000071is optional, and defaults to 0; it may be an int or a string. If arg is\n\
72given as a string, the return value of fcntl is a string of that length,\n\
73containing the resulting value put in the arg buffer by the operating system.\n\
74The length of the arg string is not allowed to exceed 1024 bytes. If the arg\n\
75given is an integer or if none is specified, the result value is an integer\n\
76corresponding to the return value of the fcntl call in the C code.";
Guido van Rossum185ead61998-11-23 15:32:55 +000077
Guido van Rossum02975121992-08-17 08:55:12 +000078
79/* ioctl(fd, opt, [arg]) */
80
Roger E. Masse919213a1996-12-17 17:42:22 +000081static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +000082fcntl_ioctl(PyObject *self, PyObject *args)
Guido van Rossum02975121992-08-17 08:55:12 +000083{
84 int fd;
85 int code;
86 int arg;
87 int ret;
88 char *str;
89 int len;
90 char buf[1024];
91
Guido van Rossuma2214c32000-08-02 20:46:51 +000092 if (PyArg_ParseTuple(args, "iis#:ioctl", &fd, &code, &str, &len)) {
Guido van Rossum02975121992-08-17 08:55:12 +000093 if (len > sizeof buf) {
Roger E. Masse919213a1996-12-17 17:42:22 +000094 PyErr_SetString(PyExc_ValueError,
95 "ioctl string arg too long");
Guido van Rossum02975121992-08-17 08:55:12 +000096 return NULL;
97 }
98 memcpy(buf, str, len);
Roger E. Masse919213a1996-12-17 17:42:22 +000099 Py_BEGIN_ALLOW_THREADS
Guido van Rossum903f4871995-10-07 19:18:22 +0000100 ret = ioctl(fd, code, buf);
Roger E. Masse919213a1996-12-17 17:42:22 +0000101 Py_END_ALLOW_THREADS
Guido van Rossum903f4871995-10-07 19:18:22 +0000102 if (ret < 0) {
Roger E. Masse919213a1996-12-17 17:42:22 +0000103 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum02975121992-08-17 08:55:12 +0000104 return NULL;
105 }
Roger E. Masse919213a1996-12-17 17:42:22 +0000106 return PyString_FromStringAndSize(buf, len);
Guido van Rossum02975121992-08-17 08:55:12 +0000107 }
108
Roger E. Masse919213a1996-12-17 17:42:22 +0000109 PyErr_Clear();
Guido van Rossuma2214c32000-08-02 20:46:51 +0000110 arg = 0;
111 if (!PyArg_ParseTuple(args, "ii|i;ioctl requires 2 integers and optionally a third integer or a string",
112 &fd, &code, &arg)) {
113 return NULL;
Guido van Rossum02975121992-08-17 08:55:12 +0000114 }
Roger E. Masse919213a1996-12-17 17:42:22 +0000115 Py_BEGIN_ALLOW_THREADS
Guido van Rossum02975121992-08-17 08:55:12 +0000116 ret = ioctl(fd, code, arg);
Roger E. Masse919213a1996-12-17 17:42:22 +0000117 Py_END_ALLOW_THREADS
Guido van Rossum02975121992-08-17 08:55:12 +0000118 if (ret < 0) {
Roger E. Masse919213a1996-12-17 17:42:22 +0000119 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum02975121992-08-17 08:55:12 +0000120 return NULL;
121 }
Roger E. Masse919213a1996-12-17 17:42:22 +0000122 return PyInt_FromLong((long)ret);
Guido van Rossum02975121992-08-17 08:55:12 +0000123}
124
Guido van Rossum185ead61998-11-23 15:32:55 +0000125static char ioctl_doc [] =
126"ioctl(fd, opt, [arg])\n\
127\n\
128Perform the requested operation on file descriptor fd. The operation\n\
129is defined by op and is operating system dependent. Typically these\n\
130codes can be retrieved from the library module IOCTL. The argument arg\n\
Guido van Rossuma2214c32000-08-02 20:46:51 +0000131is optional, and defaults to 0; it may be an int or a string. If arg is\n\
132given as a string, the return value of ioctl is a string of that length,\n\
133containing the resulting value put in the arg buffer by the operating system.\n\
134The length of the arg string is not allowed to exceed 1024 bytes. If the arg\n\
135given is an integer or if none is specified, the result value is an integer\n\
136corresponding to the return value of the ioctl call in the C code.";
Guido van Rossum185ead61998-11-23 15:32:55 +0000137
Guido van Rossum02975121992-08-17 08:55:12 +0000138
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000139/* flock(fd, operation) */
140
Roger E. Masse919213a1996-12-17 17:42:22 +0000141static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000142fcntl_flock(PyObject *self, PyObject *args)
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000143{
144 int fd;
145 int code;
146 int ret;
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000147
Guido van Rossuma2214c32000-08-02 20:46:51 +0000148 if (!PyArg_ParseTuple(args, "ii:flock", &fd, &code))
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000149 return NULL;
150
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000151#ifdef HAVE_FLOCK
Guido van Rossum056bad91999-01-06 18:44:23 +0000152 Py_BEGIN_ALLOW_THREADS
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000153 ret = flock(fd, code);
Guido van Rossum056bad91999-01-06 18:44:23 +0000154 Py_END_ALLOW_THREADS
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000155#else
156
157#ifndef LOCK_SH
158#define LOCK_SH 1 /* shared lock */
159#define LOCK_EX 2 /* exclusive lock */
160#define LOCK_NB 4 /* don't block when locking */
161#define LOCK_UN 8 /* unlock */
162#endif
163 {
164 struct flock l;
165 if (code == LOCK_UN)
166 l.l_type = F_UNLCK;
167 else if (code & LOCK_SH)
168 l.l_type = F_RDLCK;
169 else if (code & LOCK_EX)
170 l.l_type = F_WRLCK;
171 else {
Roger E. Masse919213a1996-12-17 17:42:22 +0000172 PyErr_SetString(PyExc_ValueError,
173 "unrecognized flock argument");
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000174 return NULL;
175 }
176 l.l_whence = l.l_start = l.l_len = 0;
Guido van Rossum056bad91999-01-06 18:44:23 +0000177 Py_BEGIN_ALLOW_THREADS
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000178 ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
Guido van Rossum056bad91999-01-06 18:44:23 +0000179 Py_END_ALLOW_THREADS
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000180 }
181#endif /* HAVE_FLOCK */
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000182 if (ret < 0) {
Roger E. Masse919213a1996-12-17 17:42:22 +0000183 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000184 return NULL;
185 }
Roger E. Masse919213a1996-12-17 17:42:22 +0000186 Py_INCREF(Py_None);
187 return Py_None;
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000188}
189
Guido van Rossum185ead61998-11-23 15:32:55 +0000190static char flock_doc [] =
191"flock(fd, operation)\n\
192\n\
193Perform the lock operation op on file descriptor fd. See the Unix \n\
194manual flock(3) for details. (On some systems, this function is\n\
195emulated using fcntl().)";
196
197
Guido van Rossumc8643641996-09-11 23:17:20 +0000198/* lockf(fd, operation) */
Roger E. Masse919213a1996-12-17 17:42:22 +0000199static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000200fcntl_lockf(PyObject *self, PyObject *args)
Guido van Rossumc8643641996-09-11 23:17:20 +0000201{
Guido van Rossum056bad91999-01-06 18:44:23 +0000202 int fd, code, ret, whence = 0;
203 PyObject *lenobj = NULL, *startobj = NULL;
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000204
Guido van Rossum43713e52000-02-29 13:59:29 +0000205 if (!PyArg_ParseTuple(args, "ii|OOi:lockf", &fd, &code,
Guido van Rossum056bad91999-01-06 18:44:23 +0000206 &lenobj, &startobj, &whence))
Guido van Rossumc8643641996-09-11 23:17:20 +0000207 return NULL;
208
Guido van Rossumc8643641996-09-11 23:17:20 +0000209#ifndef LOCK_SH
210#define LOCK_SH 1 /* shared lock */
211#define LOCK_EX 2 /* exclusive lock */
212#define LOCK_NB 4 /* don't block when locking */
213#define LOCK_UN 8 /* unlock */
214#endif
215 {
216 struct flock l;
217 if (code == LOCK_UN)
218 l.l_type = F_UNLCK;
219 else if (code & LOCK_SH)
220 l.l_type = F_RDLCK;
221 else if (code & LOCK_EX)
222 l.l_type = F_WRLCK;
223 else {
Roger E. Masse919213a1996-12-17 17:42:22 +0000224 PyErr_SetString(PyExc_ValueError,
225 "unrecognized flock argument");
Guido van Rossumc8643641996-09-11 23:17:20 +0000226 return NULL;
227 }
Guido van Rossum056bad91999-01-06 18:44:23 +0000228 l.l_start = l.l_len = 0;
229 if (startobj != NULL) {
230#if !defined(HAVE_LARGEFILE_SUPPORT)
231 l.l_start = PyInt_AsLong(startobj);
232#else
233 l.l_start = PyLong_Check(startobj) ?
234 PyLong_AsLongLong(startobj) :
235 PyInt_AsLong(startobj);
236#endif
237 if (PyErr_Occurred())
238 return NULL;
239 }
240 if (lenobj != NULL) {
241#if !defined(HAVE_LARGEFILE_SUPPORT)
242 l.l_len = PyInt_AsLong(lenobj);
243#else
244 l.l_len = PyLong_Check(lenobj) ?
245 PyLong_AsLongLong(lenobj) :
246 PyInt_AsLong(lenobj);
247#endif
248 if (PyErr_Occurred())
249 return NULL;
250 }
Guido van Rossumc8643641996-09-11 23:17:20 +0000251 l.l_whence = whence;
Guido van Rossum056bad91999-01-06 18:44:23 +0000252 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc8643641996-09-11 23:17:20 +0000253 ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
Guido van Rossum056bad91999-01-06 18:44:23 +0000254 Py_END_ALLOW_THREADS
Guido van Rossumc8643641996-09-11 23:17:20 +0000255 }
Guido van Rossumc8643641996-09-11 23:17:20 +0000256 if (ret < 0) {
Roger E. Masse919213a1996-12-17 17:42:22 +0000257 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumc8643641996-09-11 23:17:20 +0000258 return NULL;
259 }
Roger E. Masse919213a1996-12-17 17:42:22 +0000260 Py_INCREF(Py_None);
261 return Py_None;
Guido van Rossumc8643641996-09-11 23:17:20 +0000262}
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000263
Guido van Rossum185ead61998-11-23 15:32:55 +0000264static char lockf_doc [] =
Sjoerd Mullender82e00d62001-01-25 10:10:39 +0000265"lockf (fd, operation, length=0, start=0, whence=0)\n\
266\n\
267This is essentially a wrapper around the fcntl() locking calls. fd is the\n\
268file descriptor of the file to lock or unlock, and operation is one of the\n\
269following values:\n\
270\n\
271 LOCK_UN - unlock\n\
272 LOCK_SH - acquire a shared lock\n\
273 LOCK_EX - acquire an exclusive lock\n\
274\n\
275When operation is LOCK_SH or LOCK_EX, it can also be bit-wise OR'd with\n\
276LOCK_NB to avoid blocking on lock acquisition. If LOCK_NB is used and the\n\
277lock cannot be acquired, an IOError will be raised and the exception will\n\
278have an errno attribute set to EACCES or EAGAIN (depending on the operating\n\
279system -- for portability, check for either value).\n\
280\n\
281length is the number of bytes to lock, with the default meaning to lock to\n\
282EOF. start is the byte offset, relative to whence, to that the lock\n\
283starts. whence is as with fileobj.seek(), specifically:\n\
284\n\
285 0 - relative to the start of the file (SEEK_SET)\n\
286 1 - relative to the current buffer position (SEEK_CUR)\n\
Barry Warsawbd3dc1f2001-01-25 00:20:13 +0000287 2 - relative to the end of the file (SEEK_END)";
Guido van Rossum185ead61998-11-23 15:32:55 +0000288
Guido van Rossum02975121992-08-17 08:55:12 +0000289/* List of functions */
290
Roger E. Masse919213a1996-12-17 17:42:22 +0000291static PyMethodDef fcntl_methods[] = {
Guido van Rossuma2214c32000-08-02 20:46:51 +0000292 {"fcntl", fcntl_fcntl, METH_VARARGS, fcntl_doc},
293 {"ioctl", fcntl_ioctl, METH_VARARGS, ioctl_doc},
294 {"flock", fcntl_flock, METH_VARARGS, flock_doc},
295 {"lockf", fcntl_lockf, METH_VARARGS, lockf_doc},
Guido van Rossum02975121992-08-17 08:55:12 +0000296 {NULL, NULL} /* sentinel */
297};
298
299
Guido van Rossum185ead61998-11-23 15:32:55 +0000300static char module_doc [] =
301
302"This module performs file control and I/O control on file \n\
303descriptors. It is an interface to the fcntl() and ioctl() Unix\n\
304routines. File descriptors can be obtained with the fileno() method of\n\
305a file or socket object.";
306
Guido van Rossum02975121992-08-17 08:55:12 +0000307/* Module initialisation */
308
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000309static int
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000310ins(PyObject* d, char* symbol, long value)
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000311{
312 PyObject* v = PyInt_FromLong(value);
313 if (!v || PyDict_SetItemString(d, symbol, v) < 0)
314 return -1;
315
316 Py_DECREF(v);
317 return 0;
318}
319
320static int
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000321all_ins(PyObject* d)
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000322{
323 if (ins(d, "LOCK_SH", (long)LOCK_SH)) return -1;
324 if (ins(d, "LOCK_EX", (long)LOCK_EX)) return -1;
325 if (ins(d, "LOCK_NB", (long)LOCK_NB)) return -1;
326 if (ins(d, "LOCK_UN", (long)LOCK_UN)) return -1;
Guido van Rossum7c141031997-08-15 02:52:08 +0000327 return 0;
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000328}
329
Guido van Rossum3886bb61998-12-04 18:50:17 +0000330DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000331initfcntl(void)
Guido van Rossum02975121992-08-17 08:55:12 +0000332{
Roger E. Masse919213a1996-12-17 17:42:22 +0000333 PyObject *m, *d;
Guido van Rossum02975121992-08-17 08:55:12 +0000334
Guido van Rossum185ead61998-11-23 15:32:55 +0000335 /* Create the module and add the functions and documentation */
336 m = Py_InitModule3("fcntl", fcntl_methods, module_doc);
Guido van Rossum02975121992-08-17 08:55:12 +0000337
338 /* Add some symbolic constants to the module */
Roger E. Masse919213a1996-12-17 17:42:22 +0000339 d = PyModule_GetDict(m);
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000340 all_ins(d);
Guido van Rossum02975121992-08-17 08:55:12 +0000341}