blob: 906993ab87a9e4a42508e4c42ac6d3f47e9cbf9b [file] [log] [blame]
Guido van Rossum02975121992-08-17 08:55:12 +00001/***********************************************************
Guido van Rossum524b5881995-01-04 19:10:35 +00002Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
Guido van Rossum02975121992-08-17 08:55:12 +00004
5 All Rights Reserved
6
Guido van Rossumd266eb41996-10-25 14:44:06 +00007Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
Guido van Rossum02975121992-08-17 08:55:12 +00009provided that the above copyright notice appear in all copies and that
Guido van Rossumd266eb41996-10-25 14:44:06 +000010both that copyright notice and this permission notice appear in
Guido van Rossum02975121992-08-17 08:55:12 +000011supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000012Centrum or CWI or Corporation for National Research Initiatives or
13CNRI not be used in advertising or publicity pertaining to
14distribution of the software without specific, written prior
15permission.
Guido van Rossum02975121992-08-17 08:55:12 +000016
Guido van Rossumd266eb41996-10-25 14:44:06 +000017While CWI is the initial source for this software, a modified version
18is made available by the Corporation for National Research Initiatives
19(CNRI) at the Internet address ftp://ftp.python.org.
20
21STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28PERFORMANCE OF THIS SOFTWARE.
Guido van Rossum02975121992-08-17 08:55:12 +000029
30******************************************************************/
31
32/* fcntl module */
33
Roger E. Masse919213a1996-12-17 17:42:22 +000034#include "Python.h"
35/*#include "modsupport.h"*/
Guido van Rossum02975121992-08-17 08:55:12 +000036
Guido van Rossuma376cc51996-12-05 23:43:35 +000037#ifdef HAVE_UNISTD_H
38#include <unistd.h>
39#endif
40
41#ifdef HAVE_SYS_FILE_H
42#include <sys/file.h>
43#endif
44
Guido van Rossum3d65fa31996-12-09 18:49:14 +000045#include <sys/ioctl.h>
Guido van Rossum3c0b79c1996-06-11 15:11:34 +000046#include <fcntl.h>
47
Guido van Rossum02975121992-08-17 08:55:12 +000048
49/* fcntl(fd, opt, [arg]) */
50
Roger E. Masse919213a1996-12-17 17:42:22 +000051static PyObject *
Guido van Rossum02975121992-08-17 08:55:12 +000052fcntl_fcntl(self, args)
Roger E. Masse919213a1996-12-17 17:42:22 +000053 PyObject *self; /* Not used */
54 PyObject *args;
Guido van Rossum02975121992-08-17 08:55:12 +000055{
56 int fd;
57 int code;
58 int arg;
59 int ret;
60 char *str;
61 int len;
62 char buf[1024];
63
Roger E. Masse919213a1996-12-17 17:42:22 +000064 if (PyArg_Parse(args, "(iis#)", &fd, &code, &str, &len)) {
Guido van Rossum02975121992-08-17 08:55:12 +000065 if (len > sizeof buf) {
Roger E. Masse919213a1996-12-17 17:42:22 +000066 PyErr_SetString(PyExc_ValueError,
67 "fcntl string arg too long");
Guido van Rossum02975121992-08-17 08:55:12 +000068 return NULL;
69 }
70 memcpy(buf, str, len);
Roger E. Masse919213a1996-12-17 17:42:22 +000071 Py_BEGIN_ALLOW_THREADS
Guido van Rossum903f4871995-10-07 19:18:22 +000072 ret = fcntl(fd, code, buf);
Roger E. Masse919213a1996-12-17 17:42:22 +000073 Py_END_ALLOW_THREADS
Guido van Rossum903f4871995-10-07 19:18:22 +000074 if (ret < 0) {
Roger E. Masse919213a1996-12-17 17:42:22 +000075 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum02975121992-08-17 08:55:12 +000076 return NULL;
77 }
Roger E. Masse919213a1996-12-17 17:42:22 +000078 return PyString_FromStringAndSize(buf, len);
Guido van Rossum02975121992-08-17 08:55:12 +000079 }
80
Roger E. Masse919213a1996-12-17 17:42:22 +000081 PyErr_Clear();
82 if (PyArg_Parse(args, "(ii)", &fd, &code))
Guido van Rossum02975121992-08-17 08:55:12 +000083 arg = 0;
84 else {
Roger E. Masse919213a1996-12-17 17:42:22 +000085 PyErr_Clear();
86 if (!PyArg_Parse(args, "(iii)", &fd, &code, &arg))
Guido van Rossum02975121992-08-17 08:55:12 +000087 return NULL;
88 }
Roger E. Masse919213a1996-12-17 17:42:22 +000089 Py_BEGIN_ALLOW_THREADS
Guido van Rossum02975121992-08-17 08:55:12 +000090 ret = fcntl(fd, code, arg);
Roger E. Masse919213a1996-12-17 17:42:22 +000091 Py_END_ALLOW_THREADS
Guido van Rossum02975121992-08-17 08:55:12 +000092 if (ret < 0) {
Roger E. Masse919213a1996-12-17 17:42:22 +000093 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum02975121992-08-17 08:55:12 +000094 return NULL;
95 }
Roger E. Masse919213a1996-12-17 17:42:22 +000096 return PyInt_FromLong((long)ret);
Guido van Rossum02975121992-08-17 08:55:12 +000097}
98
99
100/* ioctl(fd, opt, [arg]) */
101
Roger E. Masse919213a1996-12-17 17:42:22 +0000102static PyObject *
Guido van Rossum02975121992-08-17 08:55:12 +0000103fcntl_ioctl(self, args)
Roger E. Masse919213a1996-12-17 17:42:22 +0000104 PyObject *self; /* Not used */
105 PyObject *args;
Guido van Rossum02975121992-08-17 08:55:12 +0000106{
107 int fd;
108 int code;
109 int arg;
110 int ret;
111 char *str;
112 int len;
113 char buf[1024];
114
Roger E. Masse919213a1996-12-17 17:42:22 +0000115 if (PyArg_Parse(args, "(iis#)", &fd, &code, &str, &len)) {
Guido van Rossum02975121992-08-17 08:55:12 +0000116 if (len > sizeof buf) {
Roger E. Masse919213a1996-12-17 17:42:22 +0000117 PyErr_SetString(PyExc_ValueError,
118 "ioctl string arg too long");
Guido van Rossum02975121992-08-17 08:55:12 +0000119 return NULL;
120 }
121 memcpy(buf, str, len);
Roger E. Masse919213a1996-12-17 17:42:22 +0000122 Py_BEGIN_ALLOW_THREADS
Guido van Rossum903f4871995-10-07 19:18:22 +0000123 ret = ioctl(fd, code, buf);
Roger E. Masse919213a1996-12-17 17:42:22 +0000124 Py_END_ALLOW_THREADS
Guido van Rossum903f4871995-10-07 19:18:22 +0000125 if (ret < 0) {
Roger E. Masse919213a1996-12-17 17:42:22 +0000126 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum02975121992-08-17 08:55:12 +0000127 return NULL;
128 }
Roger E. Masse919213a1996-12-17 17:42:22 +0000129 return PyString_FromStringAndSize(buf, len);
Guido van Rossum02975121992-08-17 08:55:12 +0000130 }
131
Roger E. Masse919213a1996-12-17 17:42:22 +0000132 PyErr_Clear();
133 if (PyArg_Parse(args, "(ii)", &fd, &code))
Guido van Rossum02975121992-08-17 08:55:12 +0000134 arg = 0;
135 else {
Roger E. Masse919213a1996-12-17 17:42:22 +0000136 PyErr_Clear();
137 if (!PyArg_Parse(args, "(iii)", &fd, &code, &arg))
Guido van Rossum02975121992-08-17 08:55:12 +0000138 return NULL;
139 }
Roger E. Masse919213a1996-12-17 17:42:22 +0000140 Py_BEGIN_ALLOW_THREADS
Guido van Rossum02975121992-08-17 08:55:12 +0000141 ret = ioctl(fd, code, arg);
Roger E. Masse919213a1996-12-17 17:42:22 +0000142 Py_END_ALLOW_THREADS
Guido van Rossum02975121992-08-17 08:55:12 +0000143 if (ret < 0) {
Roger E. Masse919213a1996-12-17 17:42:22 +0000144 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum02975121992-08-17 08:55:12 +0000145 return NULL;
146 }
Roger E. Masse919213a1996-12-17 17:42:22 +0000147 return PyInt_FromLong((long)ret);
Guido van Rossum02975121992-08-17 08:55:12 +0000148}
149
150
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000151/* flock(fd, operation) */
152
Roger E. Masse919213a1996-12-17 17:42:22 +0000153static PyObject *
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000154fcntl_flock(self, args)
Roger E. Masse919213a1996-12-17 17:42:22 +0000155 PyObject *self; /* Not used */
156 PyObject *args;
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000157{
158 int fd;
159 int code;
160 int ret;
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000161
Roger E. Masse919213a1996-12-17 17:42:22 +0000162 if (!PyArg_Parse(args, "(ii)", &fd, &code))
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000163 return NULL;
164
Roger E. Masse919213a1996-12-17 17:42:22 +0000165 Py_BEGIN_ALLOW_THREADS
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000166#ifdef HAVE_FLOCK
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000167 ret = flock(fd, code);
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000168#else
169
170#ifndef LOCK_SH
171#define LOCK_SH 1 /* shared lock */
172#define LOCK_EX 2 /* exclusive lock */
173#define LOCK_NB 4 /* don't block when locking */
174#define LOCK_UN 8 /* unlock */
175#endif
176 {
177 struct flock l;
178 if (code == LOCK_UN)
179 l.l_type = F_UNLCK;
180 else if (code & LOCK_SH)
181 l.l_type = F_RDLCK;
182 else if (code & LOCK_EX)
183 l.l_type = F_WRLCK;
184 else {
Roger E. Masse919213a1996-12-17 17:42:22 +0000185 PyErr_SetString(PyExc_ValueError,
186 "unrecognized flock argument");
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000187 return NULL;
188 }
189 l.l_whence = l.l_start = l.l_len = 0;
190 ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
191 }
192#endif /* HAVE_FLOCK */
Roger E. Masse919213a1996-12-17 17:42:22 +0000193 Py_END_ALLOW_THREADS
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000194 if (ret < 0) {
Roger E. Masse919213a1996-12-17 17:42:22 +0000195 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000196 return NULL;
197 }
Roger E. Masse919213a1996-12-17 17:42:22 +0000198 Py_INCREF(Py_None);
199 return Py_None;
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000200}
201
Guido van Rossumc8643641996-09-11 23:17:20 +0000202/* lockf(fd, operation) */
Roger E. Masse919213a1996-12-17 17:42:22 +0000203static PyObject *
Guido van Rossumc8643641996-09-11 23:17:20 +0000204fcntl_lockf(self, args)
Roger E. Masse919213a1996-12-17 17:42:22 +0000205 PyObject *self; /* Not used */
206 PyObject *args;
Guido van Rossumc8643641996-09-11 23:17:20 +0000207{
208 int fd, code, len = 0, start = 0, whence = 0, ret;
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000209
Guido van Rossumc8643641996-09-11 23:17:20 +0000210 if (!PyArg_ParseTuple(args, "ii|iii", &fd, &code, &len,
211 &start, &whence))
212 return NULL;
213
Roger E. Masse919213a1996-12-17 17:42:22 +0000214 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc8643641996-09-11 23:17:20 +0000215#ifndef LOCK_SH
216#define LOCK_SH 1 /* shared lock */
217#define LOCK_EX 2 /* exclusive lock */
218#define LOCK_NB 4 /* don't block when locking */
219#define LOCK_UN 8 /* unlock */
220#endif
221 {
222 struct flock l;
223 if (code == LOCK_UN)
224 l.l_type = F_UNLCK;
225 else if (code & LOCK_SH)
226 l.l_type = F_RDLCK;
227 else if (code & LOCK_EX)
228 l.l_type = F_WRLCK;
229 else {
Roger E. Masse919213a1996-12-17 17:42:22 +0000230 PyErr_SetString(PyExc_ValueError,
231 "unrecognized flock argument");
Guido van Rossumc8643641996-09-11 23:17:20 +0000232 return NULL;
233 }
234 l.l_len = len;
235 l.l_start = start;
236 l.l_whence = whence;
237 ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
238 }
Roger E. Masse919213a1996-12-17 17:42:22 +0000239 Py_END_ALLOW_THREADS
Guido van Rossumc8643641996-09-11 23:17:20 +0000240 if (ret < 0) {
Roger E. Masse919213a1996-12-17 17:42:22 +0000241 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumc8643641996-09-11 23:17:20 +0000242 return NULL;
243 }
Roger E. Masse919213a1996-12-17 17:42:22 +0000244 Py_INCREF(Py_None);
245 return Py_None;
Guido van Rossumc8643641996-09-11 23:17:20 +0000246}
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000247
Guido van Rossum02975121992-08-17 08:55:12 +0000248/* List of functions */
249
Roger E. Masse919213a1996-12-17 17:42:22 +0000250static PyMethodDef fcntl_methods[] = {
Guido van Rossum02975121992-08-17 08:55:12 +0000251 {"fcntl", fcntl_fcntl},
252 {"ioctl", fcntl_ioctl},
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000253 {"flock", fcntl_flock},
Guido van Rossumc8643641996-09-11 23:17:20 +0000254 {"lockf", fcntl_lockf, 1},
Guido van Rossum02975121992-08-17 08:55:12 +0000255 {NULL, NULL} /* sentinel */
256};
257
258
259/* Module initialisation */
260
261void
262initfcntl()
263{
Roger E. Masse919213a1996-12-17 17:42:22 +0000264 PyObject *m, *d;
Guido van Rossum02975121992-08-17 08:55:12 +0000265
266 /* Create the module and add the functions */
Roger E. Masse919213a1996-12-17 17:42:22 +0000267 m = Py_InitModule("fcntl", fcntl_methods);
Guido van Rossum02975121992-08-17 08:55:12 +0000268
269 /* Add some symbolic constants to the module */
Roger E. Masse919213a1996-12-17 17:42:22 +0000270 d = PyModule_GetDict(m);
Guido van Rossum02975121992-08-17 08:55:12 +0000271
272 /* Check for errors */
Roger E. Masse919213a1996-12-17 17:42:22 +0000273 if (PyErr_Occurred())
274 Py_FatalError("can't initialize module fcntl");
Guido van Rossum02975121992-08-17 08:55:12 +0000275}