blob: 1483847fb8ba207de728827c4d272f32b4555c7a [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
Roger E. Masse919213a1996-12-17 17:42:22 +000040 if (PyArg_Parse(args, "(iis#)", &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();
58 if (PyArg_Parse(args, "(ii)", &fd, &code))
Guido van Rossum02975121992-08-17 08:55:12 +000059 arg = 0;
60 else {
Roger E. Masse919213a1996-12-17 17:42:22 +000061 PyErr_Clear();
62 if (!PyArg_Parse(args, "(iii)", &fd, &code, &arg))
Guido van Rossum02975121992-08-17 08:55:12 +000063 return NULL;
64 }
Roger E. Masse919213a1996-12-17 17:42:22 +000065 Py_BEGIN_ALLOW_THREADS
Guido van Rossum02975121992-08-17 08:55:12 +000066 ret = fcntl(fd, code, arg);
Roger E. Masse919213a1996-12-17 17:42:22 +000067 Py_END_ALLOW_THREADS
Guido van Rossum02975121992-08-17 08:55:12 +000068 if (ret < 0) {
Roger E. Masse919213a1996-12-17 17:42:22 +000069 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum02975121992-08-17 08:55:12 +000070 return NULL;
71 }
Roger E. Masse919213a1996-12-17 17:42:22 +000072 return PyInt_FromLong((long)ret);
Guido van Rossum02975121992-08-17 08:55:12 +000073}
74
Guido van Rossum185ead61998-11-23 15:32:55 +000075static char fcntl_doc [] =
76
77"fcntl(fd, opt, [arg])\n\
78\n\
79Perform the requested operation on file descriptor fd. The operation\n\
80is defined by op and is operating system dependent. Typically these\n\
81codes can be retrieved from the library module FCNTL. The argument arg\n\
82is optional, and defaults to 0; it may be an int or a string.";
83
Guido van Rossum02975121992-08-17 08:55:12 +000084
85/* ioctl(fd, opt, [arg]) */
86
Roger E. Masse919213a1996-12-17 17:42:22 +000087static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +000088fcntl_ioctl(PyObject *self, PyObject *args)
Guido van Rossum02975121992-08-17 08:55:12 +000089{
90 int fd;
91 int code;
92 int arg;
93 int ret;
94 char *str;
95 int len;
96 char buf[1024];
97
Roger E. Masse919213a1996-12-17 17:42:22 +000098 if (PyArg_Parse(args, "(iis#)", &fd, &code, &str, &len)) {
Guido van Rossum02975121992-08-17 08:55:12 +000099 if (len > sizeof buf) {
Roger E. Masse919213a1996-12-17 17:42:22 +0000100 PyErr_SetString(PyExc_ValueError,
101 "ioctl string arg too long");
Guido van Rossum02975121992-08-17 08:55:12 +0000102 return NULL;
103 }
104 memcpy(buf, str, len);
Roger E. Masse919213a1996-12-17 17:42:22 +0000105 Py_BEGIN_ALLOW_THREADS
Guido van Rossum903f4871995-10-07 19:18:22 +0000106 ret = ioctl(fd, code, buf);
Roger E. Masse919213a1996-12-17 17:42:22 +0000107 Py_END_ALLOW_THREADS
Guido van Rossum903f4871995-10-07 19:18:22 +0000108 if (ret < 0) {
Roger E. Masse919213a1996-12-17 17:42:22 +0000109 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum02975121992-08-17 08:55:12 +0000110 return NULL;
111 }
Roger E. Masse919213a1996-12-17 17:42:22 +0000112 return PyString_FromStringAndSize(buf, len);
Guido van Rossum02975121992-08-17 08:55:12 +0000113 }
114
Roger E. Masse919213a1996-12-17 17:42:22 +0000115 PyErr_Clear();
116 if (PyArg_Parse(args, "(ii)", &fd, &code))
Guido van Rossum02975121992-08-17 08:55:12 +0000117 arg = 0;
118 else {
Roger E. Masse919213a1996-12-17 17:42:22 +0000119 PyErr_Clear();
120 if (!PyArg_Parse(args, "(iii)", &fd, &code, &arg))
Guido van Rossum02975121992-08-17 08:55:12 +0000121 return NULL;
122 }
Roger E. Masse919213a1996-12-17 17:42:22 +0000123 Py_BEGIN_ALLOW_THREADS
Guido van Rossum02975121992-08-17 08:55:12 +0000124 ret = ioctl(fd, code, arg);
Roger E. Masse919213a1996-12-17 17:42:22 +0000125 Py_END_ALLOW_THREADS
Guido van Rossum02975121992-08-17 08:55:12 +0000126 if (ret < 0) {
Roger E. Masse919213a1996-12-17 17:42:22 +0000127 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum02975121992-08-17 08:55:12 +0000128 return NULL;
129 }
Roger E. Masse919213a1996-12-17 17:42:22 +0000130 return PyInt_FromLong((long)ret);
Guido van Rossum02975121992-08-17 08:55:12 +0000131}
132
Guido van Rossum185ead61998-11-23 15:32:55 +0000133static char ioctl_doc [] =
134"ioctl(fd, opt, [arg])\n\
135\n\
136Perform the requested operation on file descriptor fd. The operation\n\
137is defined by op and is operating system dependent. Typically these\n\
138codes can be retrieved from the library module IOCTL. The argument arg\n\
139is optional, and defaults to 0; it may be an int or a string.";
140
Guido van Rossum02975121992-08-17 08:55:12 +0000141
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000142/* flock(fd, operation) */
143
Roger E. Masse919213a1996-12-17 17:42:22 +0000144static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000145fcntl_flock(PyObject *self, PyObject *args)
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000146{
147 int fd;
148 int code;
149 int ret;
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000150
Roger E. Masse919213a1996-12-17 17:42:22 +0000151 if (!PyArg_Parse(args, "(ii)", &fd, &code))
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000152 return NULL;
153
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000154#ifdef HAVE_FLOCK
Guido van Rossum056bad91999-01-06 18:44:23 +0000155 Py_BEGIN_ALLOW_THREADS
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000156 ret = flock(fd, code);
Guido van Rossum056bad91999-01-06 18:44:23 +0000157 Py_END_ALLOW_THREADS
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000158#else
159
160#ifndef LOCK_SH
161#define LOCK_SH 1 /* shared lock */
162#define LOCK_EX 2 /* exclusive lock */
163#define LOCK_NB 4 /* don't block when locking */
164#define LOCK_UN 8 /* unlock */
165#endif
166 {
167 struct flock l;
168 if (code == LOCK_UN)
169 l.l_type = F_UNLCK;
170 else if (code & LOCK_SH)
171 l.l_type = F_RDLCK;
172 else if (code & LOCK_EX)
173 l.l_type = F_WRLCK;
174 else {
Roger E. Masse919213a1996-12-17 17:42:22 +0000175 PyErr_SetString(PyExc_ValueError,
176 "unrecognized flock argument");
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000177 return NULL;
178 }
179 l.l_whence = l.l_start = l.l_len = 0;
Guido van Rossum056bad91999-01-06 18:44:23 +0000180 Py_BEGIN_ALLOW_THREADS
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000181 ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
Guido van Rossum056bad91999-01-06 18:44:23 +0000182 Py_END_ALLOW_THREADS
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000183 }
184#endif /* HAVE_FLOCK */
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000185 if (ret < 0) {
Roger E. Masse919213a1996-12-17 17:42:22 +0000186 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000187 return NULL;
188 }
Roger E. Masse919213a1996-12-17 17:42:22 +0000189 Py_INCREF(Py_None);
190 return Py_None;
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000191}
192
Guido van Rossum185ead61998-11-23 15:32:55 +0000193static char flock_doc [] =
194"flock(fd, operation)\n\
195\n\
196Perform the lock operation op on file descriptor fd. See the Unix \n\
197manual flock(3) for details. (On some systems, this function is\n\
198emulated using fcntl().)";
199
200
Guido van Rossumc8643641996-09-11 23:17:20 +0000201/* lockf(fd, operation) */
Roger E. Masse919213a1996-12-17 17:42:22 +0000202static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000203fcntl_lockf(PyObject *self, PyObject *args)
Guido van Rossumc8643641996-09-11 23:17:20 +0000204{
Guido van Rossum056bad91999-01-06 18:44:23 +0000205 int fd, code, ret, whence = 0;
206 PyObject *lenobj = NULL, *startobj = NULL;
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000207
Guido van Rossum43713e52000-02-29 13:59:29 +0000208 if (!PyArg_ParseTuple(args, "ii|OOi:lockf", &fd, &code,
Guido van Rossum056bad91999-01-06 18:44:23 +0000209 &lenobj, &startobj, &whence))
Guido van Rossumc8643641996-09-11 23:17:20 +0000210 return NULL;
211
Guido van Rossumc8643641996-09-11 23:17:20 +0000212#ifndef LOCK_SH
213#define LOCK_SH 1 /* shared lock */
214#define LOCK_EX 2 /* exclusive lock */
215#define LOCK_NB 4 /* don't block when locking */
216#define LOCK_UN 8 /* unlock */
217#endif
218 {
219 struct flock l;
220 if (code == LOCK_UN)
221 l.l_type = F_UNLCK;
222 else if (code & LOCK_SH)
223 l.l_type = F_RDLCK;
224 else if (code & LOCK_EX)
225 l.l_type = F_WRLCK;
226 else {
Roger E. Masse919213a1996-12-17 17:42:22 +0000227 PyErr_SetString(PyExc_ValueError,
228 "unrecognized flock argument");
Guido van Rossumc8643641996-09-11 23:17:20 +0000229 return NULL;
230 }
Guido van Rossum056bad91999-01-06 18:44:23 +0000231 l.l_start = l.l_len = 0;
232 if (startobj != NULL) {
233#if !defined(HAVE_LARGEFILE_SUPPORT)
234 l.l_start = PyInt_AsLong(startobj);
235#else
236 l.l_start = PyLong_Check(startobj) ?
237 PyLong_AsLongLong(startobj) :
238 PyInt_AsLong(startobj);
239#endif
240 if (PyErr_Occurred())
241 return NULL;
242 }
243 if (lenobj != NULL) {
244#if !defined(HAVE_LARGEFILE_SUPPORT)
245 l.l_len = PyInt_AsLong(lenobj);
246#else
247 l.l_len = PyLong_Check(lenobj) ?
248 PyLong_AsLongLong(lenobj) :
249 PyInt_AsLong(lenobj);
250#endif
251 if (PyErr_Occurred())
252 return NULL;
253 }
Guido van Rossumc8643641996-09-11 23:17:20 +0000254 l.l_whence = whence;
Guido van Rossum056bad91999-01-06 18:44:23 +0000255 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc8643641996-09-11 23:17:20 +0000256 ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
Guido van Rossum056bad91999-01-06 18:44:23 +0000257 Py_END_ALLOW_THREADS
Guido van Rossumc8643641996-09-11 23:17:20 +0000258 }
Guido van Rossumc8643641996-09-11 23:17:20 +0000259 if (ret < 0) {
Roger E. Masse919213a1996-12-17 17:42:22 +0000260 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumc8643641996-09-11 23:17:20 +0000261 return NULL;
262 }
Roger E. Masse919213a1996-12-17 17:42:22 +0000263 Py_INCREF(Py_None);
264 return Py_None;
Guido van Rossumc8643641996-09-11 23:17:20 +0000265}
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000266
Guido van Rossum185ead61998-11-23 15:32:55 +0000267static char lockf_doc [] =
268"lockf (fd, operation)\n\
269\n\
270This is a wrapper around the FCNTL.F_SETLK and FCNTL.F_SETLKW fcntl()\n\
271calls. See the Unix manual for details.";
272
Guido van Rossum02975121992-08-17 08:55:12 +0000273/* List of functions */
274
Roger E. Masse919213a1996-12-17 17:42:22 +0000275static PyMethodDef fcntl_methods[] = {
Guido van Rossum185ead61998-11-23 15:32:55 +0000276 {"fcntl", fcntl_fcntl, 0, fcntl_doc},
277 {"ioctl", fcntl_ioctl, 0, ioctl_doc},
278 {"flock", fcntl_flock, 0, flock_doc},
279 {"lockf", fcntl_lockf, 1, lockf_doc},
Guido van Rossum02975121992-08-17 08:55:12 +0000280 {NULL, NULL} /* sentinel */
281};
282
283
Guido van Rossum185ead61998-11-23 15:32:55 +0000284static char module_doc [] =
285
286"This module performs file control and I/O control on file \n\
287descriptors. It is an interface to the fcntl() and ioctl() Unix\n\
288routines. File descriptors can be obtained with the fileno() method of\n\
289a file or socket object.";
290
Guido van Rossum02975121992-08-17 08:55:12 +0000291/* Module initialisation */
292
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000293static int
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000294ins(PyObject* d, char* symbol, long value)
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000295{
296 PyObject* v = PyInt_FromLong(value);
297 if (!v || PyDict_SetItemString(d, symbol, v) < 0)
298 return -1;
299
300 Py_DECREF(v);
301 return 0;
302}
303
304static int
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000305all_ins(PyObject* d)
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000306{
307 if (ins(d, "LOCK_SH", (long)LOCK_SH)) return -1;
308 if (ins(d, "LOCK_EX", (long)LOCK_EX)) return -1;
309 if (ins(d, "LOCK_NB", (long)LOCK_NB)) return -1;
310 if (ins(d, "LOCK_UN", (long)LOCK_UN)) return -1;
Guido van Rossum7c141031997-08-15 02:52:08 +0000311 return 0;
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000312}
313
Guido van Rossum3886bb61998-12-04 18:50:17 +0000314DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000315initfcntl(void)
Guido van Rossum02975121992-08-17 08:55:12 +0000316{
Roger E. Masse919213a1996-12-17 17:42:22 +0000317 PyObject *m, *d;
Guido van Rossum02975121992-08-17 08:55:12 +0000318
Guido van Rossum185ead61998-11-23 15:32:55 +0000319 /* Create the module and add the functions and documentation */
320 m = Py_InitModule3("fcntl", fcntl_methods, module_doc);
Guido van Rossum02975121992-08-17 08:55:12 +0000321
322 /* Add some symbolic constants to the module */
Roger E. Masse919213a1996-12-17 17:42:22 +0000323 d = PyModule_GetDict(m);
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000324 all_ins(d);
Guido van Rossum02975121992-08-17 08:55:12 +0000325
326 /* Check for errors */
Roger E. Masse919213a1996-12-17 17:42:22 +0000327 if (PyErr_Occurred())
328 Py_FatalError("can't initialize module fcntl");
Guido van Rossum02975121992-08-17 08:55:12 +0000329}