blob: 174a904ced531d842b8e23f5b3b5ab6b283194b2 [file] [log] [blame]
Guido van Rossum02975121992-08-17 08:55:12 +00001/***********************************************************
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00002Copyright (c) 2000, BeOpen.com.
3Copyright (c) 1995-2000, Corporation for National Research Initiatives.
4Copyright (c) 1990-1995, Stichting Mathematisch Centrum.
5All rights reserved.
Guido van Rossum02975121992-08-17 08:55:12 +00006
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00007See the file "Misc/COPYRIGHT" for information on usage and
8redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
Guido van Rossum02975121992-08-17 08:55:12 +00009******************************************************************/
10
11/* fcntl module */
12
Roger E. Masse919213a1996-12-17 17:42:22 +000013#include "Python.h"
Guido van Rossum02975121992-08-17 08:55:12 +000014
Guido van Rossuma376cc51996-12-05 23:43:35 +000015#ifdef HAVE_UNISTD_H
16#include <unistd.h>
17#endif
18
19#ifdef HAVE_SYS_FILE_H
20#include <sys/file.h>
21#endif
22
Guido van Rossum3d65fa31996-12-09 18:49:14 +000023#include <sys/ioctl.h>
Guido van Rossum3c0b79c1996-06-11 15:11:34 +000024#include <fcntl.h>
25
Guido van Rossum02975121992-08-17 08:55:12 +000026
27/* fcntl(fd, opt, [arg]) */
28
Roger E. Masse919213a1996-12-17 17:42:22 +000029static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +000030fcntl_fcntl(PyObject *self, PyObject *args)
Guido van Rossum02975121992-08-17 08:55:12 +000031{
32 int fd;
33 int code;
34 int arg;
35 int ret;
36 char *str;
37 int len;
38 char buf[1024];
39
Guido van Rossuma2214c32000-08-02 20:46:51 +000040 if (PyArg_ParseTuple(args, "iis#:fcntl", &fd, &code, &str, &len)) {
Guido van Rossum02975121992-08-17 08:55:12 +000041 if (len > sizeof buf) {
Roger E. Masse919213a1996-12-17 17:42:22 +000042 PyErr_SetString(PyExc_ValueError,
43 "fcntl string arg too long");
Guido van Rossum02975121992-08-17 08:55:12 +000044 return NULL;
45 }
46 memcpy(buf, str, len);
Roger E. Masse919213a1996-12-17 17:42:22 +000047 Py_BEGIN_ALLOW_THREADS
Guido van Rossum903f4871995-10-07 19:18:22 +000048 ret = fcntl(fd, code, buf);
Roger E. Masse919213a1996-12-17 17:42:22 +000049 Py_END_ALLOW_THREADS
Guido van Rossum903f4871995-10-07 19:18:22 +000050 if (ret < 0) {
Roger E. Masse919213a1996-12-17 17:42:22 +000051 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum02975121992-08-17 08:55:12 +000052 return NULL;
53 }
Roger E. Masse919213a1996-12-17 17:42:22 +000054 return PyString_FromStringAndSize(buf, len);
Guido van Rossum02975121992-08-17 08:55:12 +000055 }
56
Roger E. Masse919213a1996-12-17 17:42:22 +000057 PyErr_Clear();
Guido van Rossuma2214c32000-08-02 20:46:51 +000058 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;
Guido van Rossum02975121992-08-17 08:55:12 +000062 }
Roger E. Masse919213a1996-12-17 17:42:22 +000063 Py_BEGIN_ALLOW_THREADS
Guido van Rossum02975121992-08-17 08:55:12 +000064 ret = fcntl(fd, code, arg);
Roger E. Masse919213a1996-12-17 17:42:22 +000065 Py_END_ALLOW_THREADS
Guido van Rossum02975121992-08-17 08:55:12 +000066 if (ret < 0) {
Roger E. Masse919213a1996-12-17 17:42:22 +000067 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum02975121992-08-17 08:55:12 +000068 return NULL;
69 }
Roger E. Masse919213a1996-12-17 17:42:22 +000070 return PyInt_FromLong((long)ret);
Guido van Rossum02975121992-08-17 08:55:12 +000071}
72
Guido van Rossum185ead61998-11-23 15:32:55 +000073static char fcntl_doc [] =
74
75"fcntl(fd, opt, [arg])\n\
76\n\
77Perform the requested operation on file descriptor fd. The operation\n\
78is defined by op and is operating system dependent. Typically these\n\
79codes can be retrieved from the library module FCNTL. The argument arg\n\
Guido van Rossuma2214c32000-08-02 20:46:51 +000080is optional, and defaults to 0; it may be an int or a string. If arg is\n\
81given as a string, the return value of fcntl is a string of that length,\n\
82containing the resulting value put in the arg buffer by the operating system.\n\
83The length of the arg string is not allowed to exceed 1024 bytes. If the arg\n\
84given is an integer or if none is specified, the result value is an integer\n\
85corresponding to the return value of the fcntl call in the C code.";
Guido van Rossum185ead61998-11-23 15:32:55 +000086
Guido van Rossum02975121992-08-17 08:55:12 +000087
88/* ioctl(fd, opt, [arg]) */
89
Roger E. Masse919213a1996-12-17 17:42:22 +000090static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +000091fcntl_ioctl(PyObject *self, PyObject *args)
Guido van Rossum02975121992-08-17 08:55:12 +000092{
93 int fd;
94 int code;
95 int arg;
96 int ret;
97 char *str;
98 int len;
99 char buf[1024];
100
Guido van Rossuma2214c32000-08-02 20:46:51 +0000101 if (PyArg_ParseTuple(args, "iis#:ioctl", &fd, &code, &str, &len)) {
Guido van Rossum02975121992-08-17 08:55:12 +0000102 if (len > sizeof buf) {
Roger E. Masse919213a1996-12-17 17:42:22 +0000103 PyErr_SetString(PyExc_ValueError,
104 "ioctl string arg too long");
Guido van Rossum02975121992-08-17 08:55:12 +0000105 return NULL;
106 }
107 memcpy(buf, str, len);
Roger E. Masse919213a1996-12-17 17:42:22 +0000108 Py_BEGIN_ALLOW_THREADS
Guido van Rossum903f4871995-10-07 19:18:22 +0000109 ret = ioctl(fd, code, buf);
Roger E. Masse919213a1996-12-17 17:42:22 +0000110 Py_END_ALLOW_THREADS
Guido van Rossum903f4871995-10-07 19:18:22 +0000111 if (ret < 0) {
Roger E. Masse919213a1996-12-17 17:42:22 +0000112 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum02975121992-08-17 08:55:12 +0000113 return NULL;
114 }
Roger E. Masse919213a1996-12-17 17:42:22 +0000115 return PyString_FromStringAndSize(buf, len);
Guido van Rossum02975121992-08-17 08:55:12 +0000116 }
117
Roger E. Masse919213a1996-12-17 17:42:22 +0000118 PyErr_Clear();
Guido van Rossuma2214c32000-08-02 20:46:51 +0000119 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;
Guido van Rossum02975121992-08-17 08:55:12 +0000123 }
Roger E. Masse919213a1996-12-17 17:42:22 +0000124 Py_BEGIN_ALLOW_THREADS
Guido van Rossum02975121992-08-17 08:55:12 +0000125 ret = ioctl(fd, code, arg);
Roger E. Masse919213a1996-12-17 17:42:22 +0000126 Py_END_ALLOW_THREADS
Guido van Rossum02975121992-08-17 08:55:12 +0000127 if (ret < 0) {
Roger E. Masse919213a1996-12-17 17:42:22 +0000128 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum02975121992-08-17 08:55:12 +0000129 return NULL;
130 }
Roger E. Masse919213a1996-12-17 17:42:22 +0000131 return PyInt_FromLong((long)ret);
Guido van Rossum02975121992-08-17 08:55:12 +0000132}
133
Guido van Rossum185ead61998-11-23 15:32:55 +0000134static char ioctl_doc [] =
135"ioctl(fd, opt, [arg])\n\
136\n\
137Perform the requested operation on file descriptor fd. The operation\n\
138is defined by op and is operating system dependent. Typically these\n\
139codes can be retrieved from the library module IOCTL. The argument arg\n\
Guido van Rossuma2214c32000-08-02 20:46:51 +0000140is optional, and defaults to 0; it may be an int or a string. If arg is\n\
141given as a string, the return value of ioctl is a string of that length,\n\
142containing the resulting value put in the arg buffer by the operating system.\n\
143The length of the arg string is not allowed to exceed 1024 bytes. If the arg\n\
144given is an integer or if none is specified, the result value is an integer\n\
145corresponding to the return value of the ioctl call in the C code.";
Guido van Rossum185ead61998-11-23 15:32:55 +0000146
Guido van Rossum02975121992-08-17 08:55:12 +0000147
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000148/* flock(fd, operation) */
149
Roger E. Masse919213a1996-12-17 17:42:22 +0000150static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000151fcntl_flock(PyObject *self, PyObject *args)
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000152{
153 int fd;
154 int code;
155 int ret;
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000156
Guido van Rossuma2214c32000-08-02 20:46:51 +0000157 if (!PyArg_ParseTuple(args, "ii:flock", &fd, &code))
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000158 return NULL;
159
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000160#ifdef HAVE_FLOCK
Guido van Rossum056bad91999-01-06 18:44:23 +0000161 Py_BEGIN_ALLOW_THREADS
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000162 ret = flock(fd, code);
Guido van Rossum056bad91999-01-06 18:44:23 +0000163 Py_END_ALLOW_THREADS
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000164#else
165
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
172 {
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 {
Roger E. Masse919213a1996-12-17 17:42:22 +0000181 PyErr_SetString(PyExc_ValueError,
182 "unrecognized flock argument");
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000183 return NULL;
184 }
185 l.l_whence = l.l_start = l.l_len = 0;
Guido van Rossum056bad91999-01-06 18:44:23 +0000186 Py_BEGIN_ALLOW_THREADS
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000187 ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
Guido van Rossum056bad91999-01-06 18:44:23 +0000188 Py_END_ALLOW_THREADS
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000189 }
190#endif /* HAVE_FLOCK */
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000191 if (ret < 0) {
Roger E. Masse919213a1996-12-17 17:42:22 +0000192 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000193 return NULL;
194 }
Roger E. Masse919213a1996-12-17 17:42:22 +0000195 Py_INCREF(Py_None);
196 return Py_None;
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000197}
198
Guido van Rossum185ead61998-11-23 15:32:55 +0000199static char flock_doc [] =
200"flock(fd, operation)\n\
201\n\
202Perform the lock operation op on file descriptor fd. See the Unix \n\
203manual flock(3) for details. (On some systems, this function is\n\
204emulated using fcntl().)";
205
206
Guido van Rossumc8643641996-09-11 23:17:20 +0000207/* lockf(fd, operation) */
Roger E. Masse919213a1996-12-17 17:42:22 +0000208static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000209fcntl_lockf(PyObject *self, PyObject *args)
Guido van Rossumc8643641996-09-11 23:17:20 +0000210{
Guido van Rossum056bad91999-01-06 18:44:23 +0000211 int fd, code, ret, whence = 0;
212 PyObject *lenobj = NULL, *startobj = NULL;
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000213
Guido van Rossum43713e52000-02-29 13:59:29 +0000214 if (!PyArg_ParseTuple(args, "ii|OOi:lockf", &fd, &code,
Guido van Rossum056bad91999-01-06 18:44:23 +0000215 &lenobj, &startobj, &whence))
Guido van Rossumc8643641996-09-11 23:17:20 +0000216 return NULL;
217
Guido van Rossumc8643641996-09-11 23:17:20 +0000218#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
224 {
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 {
Roger E. Masse919213a1996-12-17 17:42:22 +0000233 PyErr_SetString(PyExc_ValueError,
234 "unrecognized flock argument");
Guido van Rossumc8643641996-09-11 23:17:20 +0000235 return NULL;
236 }
Guido van Rossum056bad91999-01-06 18:44:23 +0000237 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;
248 }
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;
259 }
Guido van Rossumc8643641996-09-11 23:17:20 +0000260 l.l_whence = whence;
Guido van Rossum056bad91999-01-06 18:44:23 +0000261 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc8643641996-09-11 23:17:20 +0000262 ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
Guido van Rossum056bad91999-01-06 18:44:23 +0000263 Py_END_ALLOW_THREADS
Guido van Rossumc8643641996-09-11 23:17:20 +0000264 }
Guido van Rossumc8643641996-09-11 23:17:20 +0000265 if (ret < 0) {
Roger E. Masse919213a1996-12-17 17:42:22 +0000266 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumc8643641996-09-11 23:17:20 +0000267 return NULL;
268 }
Roger E. Masse919213a1996-12-17 17:42:22 +0000269 Py_INCREF(Py_None);
270 return Py_None;
Guido van Rossumc8643641996-09-11 23:17:20 +0000271}
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000272
Guido van Rossum185ead61998-11-23 15:32:55 +0000273static char lockf_doc [] =
274"lockf (fd, operation)\n\
275\n\
276This is a wrapper around the FCNTL.F_SETLK and FCNTL.F_SETLKW fcntl()\n\
277calls. See the Unix manual for details.";
278
Guido van Rossum02975121992-08-17 08:55:12 +0000279/* List of functions */
280
Roger E. Masse919213a1996-12-17 17:42:22 +0000281static PyMethodDef fcntl_methods[] = {
Guido van Rossuma2214c32000-08-02 20:46:51 +0000282 {"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},
Guido van Rossum02975121992-08-17 08:55:12 +0000286 {NULL, NULL} /* sentinel */
287};
288
289
Guido van Rossum185ead61998-11-23 15:32:55 +0000290static char module_doc [] =
291
292"This module performs file control and I/O control on file \n\
293descriptors. It is an interface to the fcntl() and ioctl() Unix\n\
294routines. File descriptors can be obtained with the fileno() method of\n\
295a file or socket object.";
296
Guido van Rossum02975121992-08-17 08:55:12 +0000297/* Module initialisation */
298
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000299static int
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000300ins(PyObject* d, char* symbol, long value)
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000301{
302 PyObject* v = PyInt_FromLong(value);
303 if (!v || PyDict_SetItemString(d, symbol, v) < 0)
304 return -1;
305
306 Py_DECREF(v);
307 return 0;
308}
309
310static int
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000311all_ins(PyObject* d)
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000312{
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;
Guido van Rossum7c141031997-08-15 02:52:08 +0000317 return 0;
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000318}
319
Guido van Rossum3886bb61998-12-04 18:50:17 +0000320DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000321initfcntl(void)
Guido van Rossum02975121992-08-17 08:55:12 +0000322{
Roger E. Masse919213a1996-12-17 17:42:22 +0000323 PyObject *m, *d;
Guido van Rossum02975121992-08-17 08:55:12 +0000324
Guido van Rossum185ead61998-11-23 15:32:55 +0000325 /* Create the module and add the functions and documentation */
326 m = Py_InitModule3("fcntl", fcntl_methods, module_doc);
Guido van Rossum02975121992-08-17 08:55:12 +0000327
328 /* Add some symbolic constants to the module */
Roger E. Masse919213a1996-12-17 17:42:22 +0000329 d = PyModule_GetDict(m);
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000330 all_ins(d);
Guido van Rossum02975121992-08-17 08:55:12 +0000331
332 /* Check for errors */
Roger E. Masse919213a1996-12-17 17:42:22 +0000333 if (PyErr_Occurred())
334 Py_FatalError("can't initialize module fcntl");
Guido van Rossum02975121992-08-17 08:55:12 +0000335}