blob: 93fdf401f330c8cce467a7596a8254c08391f36c [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 [] =
265"lockf (fd, operation)\n\
266\n\
267This is a wrapper around the FCNTL.F_SETLK and FCNTL.F_SETLKW fcntl()\n\
268calls. See the Unix manual for details.";
269
Guido van Rossum02975121992-08-17 08:55:12 +0000270/* List of functions */
271
Roger E. Masse919213a1996-12-17 17:42:22 +0000272static PyMethodDef fcntl_methods[] = {
Guido van Rossuma2214c32000-08-02 20:46:51 +0000273 {"fcntl", fcntl_fcntl, METH_VARARGS, fcntl_doc},
274 {"ioctl", fcntl_ioctl, METH_VARARGS, ioctl_doc},
275 {"flock", fcntl_flock, METH_VARARGS, flock_doc},
276 {"lockf", fcntl_lockf, METH_VARARGS, lockf_doc},
Guido van Rossum02975121992-08-17 08:55:12 +0000277 {NULL, NULL} /* sentinel */
278};
279
280
Guido van Rossum185ead61998-11-23 15:32:55 +0000281static char module_doc [] =
282
283"This module performs file control and I/O control on file \n\
284descriptors. It is an interface to the fcntl() and ioctl() Unix\n\
285routines. File descriptors can be obtained with the fileno() method of\n\
286a file or socket object.";
287
Guido van Rossum02975121992-08-17 08:55:12 +0000288/* Module initialisation */
289
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000290static int
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000291ins(PyObject* d, char* symbol, long value)
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000292{
293 PyObject* v = PyInt_FromLong(value);
294 if (!v || PyDict_SetItemString(d, symbol, v) < 0)
295 return -1;
296
297 Py_DECREF(v);
298 return 0;
299}
300
301static int
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000302all_ins(PyObject* d)
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000303{
304 if (ins(d, "LOCK_SH", (long)LOCK_SH)) return -1;
305 if (ins(d, "LOCK_EX", (long)LOCK_EX)) return -1;
306 if (ins(d, "LOCK_NB", (long)LOCK_NB)) return -1;
307 if (ins(d, "LOCK_UN", (long)LOCK_UN)) return -1;
Guido van Rossum7c141031997-08-15 02:52:08 +0000308 return 0;
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000309}
310
Guido van Rossum3886bb61998-12-04 18:50:17 +0000311DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000312initfcntl(void)
Guido van Rossum02975121992-08-17 08:55:12 +0000313{
Roger E. Masse919213a1996-12-17 17:42:22 +0000314 PyObject *m, *d;
Guido van Rossum02975121992-08-17 08:55:12 +0000315
Guido van Rossum185ead61998-11-23 15:32:55 +0000316 /* Create the module and add the functions and documentation */
317 m = Py_InitModule3("fcntl", fcntl_methods, module_doc);
Guido van Rossum02975121992-08-17 08:55:12 +0000318
319 /* Add some symbolic constants to the module */
Roger E. Masse919213a1996-12-17 17:42:22 +0000320 d = PyModule_GetDict(m);
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000321 all_ins(d);
Guido van Rossum02975121992-08-17 08:55:12 +0000322}