blob: 07551714227736e6279ee3c4734efb6d5885b227 [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 *
Guido van Rossum02975121992-08-17 08:55:12 +000030fcntl_fcntl(self, args)
Roger E. Masse919213a1996-12-17 17:42:22 +000031 PyObject *self; /* Not used */
32 PyObject *args;
Guido van Rossum02975121992-08-17 08:55:12 +000033{
34 int fd;
35 int code;
36 int arg;
37 int ret;
38 char *str;
39 int len;
40 char buf[1024];
41
Roger E. Masse919213a1996-12-17 17:42:22 +000042 if (PyArg_Parse(args, "(iis#)", &fd, &code, &str, &len)) {
Guido van Rossum02975121992-08-17 08:55:12 +000043 if (len > sizeof buf) {
Roger E. Masse919213a1996-12-17 17:42:22 +000044 PyErr_SetString(PyExc_ValueError,
45 "fcntl string arg too long");
Guido van Rossum02975121992-08-17 08:55:12 +000046 return NULL;
47 }
48 memcpy(buf, str, len);
Roger E. Masse919213a1996-12-17 17:42:22 +000049 Py_BEGIN_ALLOW_THREADS
Guido van Rossum903f4871995-10-07 19:18:22 +000050 ret = fcntl(fd, code, buf);
Roger E. Masse919213a1996-12-17 17:42:22 +000051 Py_END_ALLOW_THREADS
Guido van Rossum903f4871995-10-07 19:18:22 +000052 if (ret < 0) {
Roger E. Masse919213a1996-12-17 17:42:22 +000053 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum02975121992-08-17 08:55:12 +000054 return NULL;
55 }
Roger E. Masse919213a1996-12-17 17:42:22 +000056 return PyString_FromStringAndSize(buf, len);
Guido van Rossum02975121992-08-17 08:55:12 +000057 }
58
Roger E. Masse919213a1996-12-17 17:42:22 +000059 PyErr_Clear();
60 if (PyArg_Parse(args, "(ii)", &fd, &code))
Guido van Rossum02975121992-08-17 08:55:12 +000061 arg = 0;
62 else {
Roger E. Masse919213a1996-12-17 17:42:22 +000063 PyErr_Clear();
64 if (!PyArg_Parse(args, "(iii)", &fd, &code, &arg))
Guido van Rossum02975121992-08-17 08:55:12 +000065 return NULL;
66 }
Roger E. Masse919213a1996-12-17 17:42:22 +000067 Py_BEGIN_ALLOW_THREADS
Guido van Rossum02975121992-08-17 08:55:12 +000068 ret = fcntl(fd, code, arg);
Roger E. Masse919213a1996-12-17 17:42:22 +000069 Py_END_ALLOW_THREADS
Guido van Rossum02975121992-08-17 08:55:12 +000070 if (ret < 0) {
Roger E. Masse919213a1996-12-17 17:42:22 +000071 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum02975121992-08-17 08:55:12 +000072 return NULL;
73 }
Roger E. Masse919213a1996-12-17 17:42:22 +000074 return PyInt_FromLong((long)ret);
Guido van Rossum02975121992-08-17 08:55:12 +000075}
76
Guido van Rossum185ead61998-11-23 15:32:55 +000077static char fcntl_doc [] =
78
79"fcntl(fd, opt, [arg])\n\
80\n\
81Perform the requested operation on file descriptor fd. The operation\n\
82is defined by op and is operating system dependent. Typically these\n\
83codes can be retrieved from the library module FCNTL. The argument arg\n\
84is optional, and defaults to 0; it may be an int or a string.";
85
Guido van Rossum02975121992-08-17 08:55:12 +000086
87/* ioctl(fd, opt, [arg]) */
88
Roger E. Masse919213a1996-12-17 17:42:22 +000089static PyObject *
Guido van Rossum02975121992-08-17 08:55:12 +000090fcntl_ioctl(self, args)
Roger E. Masse919213a1996-12-17 17:42:22 +000091 PyObject *self; /* Not used */
92 PyObject *args;
Guido van Rossum02975121992-08-17 08:55:12 +000093{
94 int fd;
95 int code;
96 int arg;
97 int ret;
98 char *str;
99 int len;
100 char buf[1024];
101
Roger E. Masse919213a1996-12-17 17:42:22 +0000102 if (PyArg_Parse(args, "(iis#)", &fd, &code, &str, &len)) {
Guido van Rossum02975121992-08-17 08:55:12 +0000103 if (len > sizeof buf) {
Roger E. Masse919213a1996-12-17 17:42:22 +0000104 PyErr_SetString(PyExc_ValueError,
105 "ioctl string arg too long");
Guido van Rossum02975121992-08-17 08:55:12 +0000106 return NULL;
107 }
108 memcpy(buf, str, len);
Roger E. Masse919213a1996-12-17 17:42:22 +0000109 Py_BEGIN_ALLOW_THREADS
Guido van Rossum903f4871995-10-07 19:18:22 +0000110 ret = ioctl(fd, code, buf);
Roger E. Masse919213a1996-12-17 17:42:22 +0000111 Py_END_ALLOW_THREADS
Guido van Rossum903f4871995-10-07 19:18:22 +0000112 if (ret < 0) {
Roger E. Masse919213a1996-12-17 17:42:22 +0000113 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum02975121992-08-17 08:55:12 +0000114 return NULL;
115 }
Roger E. Masse919213a1996-12-17 17:42:22 +0000116 return PyString_FromStringAndSize(buf, len);
Guido van Rossum02975121992-08-17 08:55:12 +0000117 }
118
Roger E. Masse919213a1996-12-17 17:42:22 +0000119 PyErr_Clear();
120 if (PyArg_Parse(args, "(ii)", &fd, &code))
Guido van Rossum02975121992-08-17 08:55:12 +0000121 arg = 0;
122 else {
Roger E. Masse919213a1996-12-17 17:42:22 +0000123 PyErr_Clear();
124 if (!PyArg_Parse(args, "(iii)", &fd, &code, &arg))
Guido van Rossum02975121992-08-17 08:55:12 +0000125 return NULL;
126 }
Roger E. Masse919213a1996-12-17 17:42:22 +0000127 Py_BEGIN_ALLOW_THREADS
Guido van Rossum02975121992-08-17 08:55:12 +0000128 ret = ioctl(fd, code, arg);
Roger E. Masse919213a1996-12-17 17:42:22 +0000129 Py_END_ALLOW_THREADS
Guido van Rossum02975121992-08-17 08:55:12 +0000130 if (ret < 0) {
Roger E. Masse919213a1996-12-17 17:42:22 +0000131 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum02975121992-08-17 08:55:12 +0000132 return NULL;
133 }
Roger E. Masse919213a1996-12-17 17:42:22 +0000134 return PyInt_FromLong((long)ret);
Guido van Rossum02975121992-08-17 08:55:12 +0000135}
136
Guido van Rossum185ead61998-11-23 15:32:55 +0000137static char ioctl_doc [] =
138"ioctl(fd, opt, [arg])\n\
139\n\
140Perform the requested operation on file descriptor fd. The operation\n\
141is defined by op and is operating system dependent. Typically these\n\
142codes can be retrieved from the library module IOCTL. The argument arg\n\
143is optional, and defaults to 0; it may be an int or a string.";
144
Guido van Rossum02975121992-08-17 08:55:12 +0000145
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000146/* flock(fd, operation) */
147
Roger E. Masse919213a1996-12-17 17:42:22 +0000148static PyObject *
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000149fcntl_flock(self, args)
Roger E. Masse919213a1996-12-17 17:42:22 +0000150 PyObject *self; /* Not used */
151 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
Roger E. Masse919213a1996-12-17 17:42:22 +0000157 if (!PyArg_Parse(args, "(ii)", &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 *
Guido van Rossumc8643641996-09-11 23:17:20 +0000209fcntl_lockf(self, args)
Roger E. Masse919213a1996-12-17 17:42:22 +0000210 PyObject *self; /* Not used */
211 PyObject *args;
Guido van Rossumc8643641996-09-11 23:17:20 +0000212{
Guido van Rossum056bad91999-01-06 18:44:23 +0000213 int fd, code, ret, whence = 0;
214 PyObject *lenobj = NULL, *startobj = NULL;
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000215
Guido van Rossum43713e52000-02-29 13:59:29 +0000216 if (!PyArg_ParseTuple(args, "ii|OOi:lockf", &fd, &code,
Guido van Rossum056bad91999-01-06 18:44:23 +0000217 &lenobj, &startobj, &whence))
Guido van Rossumc8643641996-09-11 23:17:20 +0000218 return NULL;
219
Guido van Rossumc8643641996-09-11 23:17:20 +0000220#ifndef LOCK_SH
221#define LOCK_SH 1 /* shared lock */
222#define LOCK_EX 2 /* exclusive lock */
223#define LOCK_NB 4 /* don't block when locking */
224#define LOCK_UN 8 /* unlock */
225#endif
226 {
227 struct flock l;
228 if (code == LOCK_UN)
229 l.l_type = F_UNLCK;
230 else if (code & LOCK_SH)
231 l.l_type = F_RDLCK;
232 else if (code & LOCK_EX)
233 l.l_type = F_WRLCK;
234 else {
Roger E. Masse919213a1996-12-17 17:42:22 +0000235 PyErr_SetString(PyExc_ValueError,
236 "unrecognized flock argument");
Guido van Rossumc8643641996-09-11 23:17:20 +0000237 return NULL;
238 }
Guido van Rossum056bad91999-01-06 18:44:23 +0000239 l.l_start = l.l_len = 0;
240 if (startobj != NULL) {
241#if !defined(HAVE_LARGEFILE_SUPPORT)
242 l.l_start = PyInt_AsLong(startobj);
243#else
244 l.l_start = PyLong_Check(startobj) ?
245 PyLong_AsLongLong(startobj) :
246 PyInt_AsLong(startobj);
247#endif
248 if (PyErr_Occurred())
249 return NULL;
250 }
251 if (lenobj != NULL) {
252#if !defined(HAVE_LARGEFILE_SUPPORT)
253 l.l_len = PyInt_AsLong(lenobj);
254#else
255 l.l_len = PyLong_Check(lenobj) ?
256 PyLong_AsLongLong(lenobj) :
257 PyInt_AsLong(lenobj);
258#endif
259 if (PyErr_Occurred())
260 return NULL;
261 }
Guido van Rossumc8643641996-09-11 23:17:20 +0000262 l.l_whence = whence;
Guido van Rossum056bad91999-01-06 18:44:23 +0000263 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc8643641996-09-11 23:17:20 +0000264 ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
Guido van Rossum056bad91999-01-06 18:44:23 +0000265 Py_END_ALLOW_THREADS
Guido van Rossumc8643641996-09-11 23:17:20 +0000266 }
Guido van Rossumc8643641996-09-11 23:17:20 +0000267 if (ret < 0) {
Roger E. Masse919213a1996-12-17 17:42:22 +0000268 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumc8643641996-09-11 23:17:20 +0000269 return NULL;
270 }
Roger E. Masse919213a1996-12-17 17:42:22 +0000271 Py_INCREF(Py_None);
272 return Py_None;
Guido van Rossumc8643641996-09-11 23:17:20 +0000273}
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000274
Guido van Rossum185ead61998-11-23 15:32:55 +0000275static char lockf_doc [] =
276"lockf (fd, operation)\n\
277\n\
278This is a wrapper around the FCNTL.F_SETLK and FCNTL.F_SETLKW fcntl()\n\
279calls. See the Unix manual for details.";
280
Guido van Rossum02975121992-08-17 08:55:12 +0000281/* List of functions */
282
Roger E. Masse919213a1996-12-17 17:42:22 +0000283static PyMethodDef fcntl_methods[] = {
Guido van Rossum185ead61998-11-23 15:32:55 +0000284 {"fcntl", fcntl_fcntl, 0, fcntl_doc},
285 {"ioctl", fcntl_ioctl, 0, ioctl_doc},
286 {"flock", fcntl_flock, 0, flock_doc},
287 {"lockf", fcntl_lockf, 1, lockf_doc},
Guido van Rossum02975121992-08-17 08:55:12 +0000288 {NULL, NULL} /* sentinel */
289};
290
291
Guido van Rossum185ead61998-11-23 15:32:55 +0000292static char module_doc [] =
293
294"This module performs file control and I/O control on file \n\
295descriptors. It is an interface to the fcntl() and ioctl() Unix\n\
296routines. File descriptors can be obtained with the fileno() method of\n\
297a file or socket object.";
298
Guido van Rossum02975121992-08-17 08:55:12 +0000299/* Module initialisation */
300
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000301static int
302ins(d, symbol, value)
303 PyObject* d;
304 char* symbol;
305 long value;
306{
307 PyObject* v = PyInt_FromLong(value);
308 if (!v || PyDict_SetItemString(d, symbol, v) < 0)
309 return -1;
310
311 Py_DECREF(v);
312 return 0;
313}
314
315static int
316all_ins(d)
317 PyObject* d;
318{
319 if (ins(d, "LOCK_SH", (long)LOCK_SH)) return -1;
320 if (ins(d, "LOCK_EX", (long)LOCK_EX)) return -1;
321 if (ins(d, "LOCK_NB", (long)LOCK_NB)) return -1;
322 if (ins(d, "LOCK_UN", (long)LOCK_UN)) return -1;
Guido van Rossum7c141031997-08-15 02:52:08 +0000323 return 0;
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000324}
325
Guido van Rossum3886bb61998-12-04 18:50:17 +0000326DL_EXPORT(void)
Guido van Rossum02975121992-08-17 08:55:12 +0000327initfcntl()
328{
Roger E. Masse919213a1996-12-17 17:42:22 +0000329 PyObject *m, *d;
Guido van Rossum02975121992-08-17 08:55:12 +0000330
Guido van Rossum185ead61998-11-23 15:32:55 +0000331 /* Create the module and add the functions and documentation */
332 m = Py_InitModule3("fcntl", fcntl_methods, module_doc);
Guido van Rossum02975121992-08-17 08:55:12 +0000333
334 /* Add some symbolic constants to the module */
Roger E. Masse919213a1996-12-17 17:42:22 +0000335 d = PyModule_GetDict(m);
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000336 all_ins(d);
Guido van Rossum02975121992-08-17 08:55:12 +0000337
338 /* Check for errors */
Roger E. Masse919213a1996-12-17 17:42:22 +0000339 if (PyErr_Occurred())
340 Py_FatalError("can't initialize module fcntl");
Guido van Rossum02975121992-08-17 08:55:12 +0000341}