blob: 67690982037f017c8df31024daf1b5729f2b9ec2 [file] [log] [blame]
Guido van Rossum02975121992-08-17 08:55:12 +00001
2/* fcntl module */
3
Thomas Wouters26cc63f2006-03-02 00:21:10 +00004#define PY_SSIZE_T_CLEAN
5
Roger E. Masse919213a1996-12-17 17:42:22 +00006#include "Python.h"
Guido van Rossum02975121992-08-17 08:55:12 +00007
Guido van Rossuma376cc51996-12-05 23:43:35 +00008#ifdef HAVE_SYS_FILE_H
9#include <sys/file.h>
10#endif
11
Guido van Rossum3d65fa31996-12-09 18:49:14 +000012#include <sys/ioctl.h>
Guido van Rossum3c0b79c1996-06-11 15:11:34 +000013#include <fcntl.h>
Martin v. Löwis14e73b12003-01-01 09:51:12 +000014#ifdef HAVE_STROPTS_H
15#include <stropts.h>
16#endif
Guido van Rossum02975121992-08-17 08:55:12 +000017
Fred Drake152a25e2001-05-09 21:02:02 +000018static int
19conv_descriptor(PyObject *object, int *target)
20{
21 int fd = PyObject_AsFileDescriptor(object);
22
23 if (fd < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000024 return 0;
Fred Drake152a25e2001-05-09 21:02:02 +000025 *target = fd;
26 return 1;
27}
28
29
R David Murrayd5a2f0b2013-11-07 10:51:07 -050030/* fcntl(fd, op, [arg]) */
Guido van Rossum02975121992-08-17 08:55:12 +000031
Roger E. Masse919213a1996-12-17 17:42:22 +000032static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +000033fcntl_fcntl(PyObject *self, PyObject *args)
Guido van Rossum02975121992-08-17 08:55:12 +000034{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000035 int fd;
36 int code;
37 long arg;
38 int ret;
39 char *str;
40 Py_ssize_t len;
41 char buf[1024];
Guido van Rossum02975121992-08-17 08:55:12 +000042
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000043 if (PyArg_ParseTuple(args, "O&is#:fcntl",
44 conv_descriptor, &fd, &code, &str, &len)) {
45 if (len > sizeof buf) {
46 PyErr_SetString(PyExc_ValueError,
47 "fcntl string arg too long");
48 return NULL;
49 }
50 memcpy(buf, str, len);
51 Py_BEGIN_ALLOW_THREADS
52 ret = fcntl(fd, code, buf);
53 Py_END_ALLOW_THREADS
54 if (ret < 0) {
55 PyErr_SetFromErrno(PyExc_IOError);
56 return NULL;
57 }
58 return PyBytes_FromStringAndSize(buf, len);
59 }
Guido van Rossum02975121992-08-17 08:55:12 +000060
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000061 PyErr_Clear();
62 arg = 0;
63 if (!PyArg_ParseTuple(args,
64 "O&i|l;fcntl requires a file or file descriptor,"
65 " an integer and optionally a third integer or a string",
66 conv_descriptor, &fd, &code, &arg)) {
67 return NULL;
68 }
69 Py_BEGIN_ALLOW_THREADS
70 ret = fcntl(fd, code, arg);
71 Py_END_ALLOW_THREADS
72 if (ret < 0) {
73 PyErr_SetFromErrno(PyExc_IOError);
74 return NULL;
75 }
76 return PyLong_FromLong((long)ret);
Guido van Rossum02975121992-08-17 08:55:12 +000077}
78
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000079PyDoc_STRVAR(fcntl_doc,
R David Murrayd5a2f0b2013-11-07 10:51:07 -050080"fcntl(fd, op, [arg])\n\
Guido van Rossum185ead61998-11-23 15:32:55 +000081\n\
R David Murrayd5a2f0b2013-11-07 10:51:07 -050082Perform the operation op on file descriptor fd. The values used\n\
83for op are operating system dependent, and are available\n\
84as constants in the fcntl module, using the same names as used in\n\
85the relevant C header files. The argument arg is optional, and\n\
Georg Brandl1f94cd02010-09-05 17:09:18 +000086defaults to 0; it may be an int or a string. If arg is given as a string,\n\
Fred Drake1d531992001-05-10 15:54:32 +000087the return value of fcntl is a string of that length, containing the\n\
Georg Brandl1f94cd02010-09-05 17:09:18 +000088resulting value put in the arg buffer by the operating system. The length\n\
89of the arg string is not allowed to exceed 1024 bytes. If the arg given\n\
Fred Drake1d531992001-05-10 15:54:32 +000090is an integer or if none is specified, the result value is an integer\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000091corresponding to the return value of the fcntl call in the C code.");
Guido van Rossum185ead61998-11-23 15:32:55 +000092
Guido van Rossum02975121992-08-17 08:55:12 +000093
R David Murrayd5a2f0b2013-11-07 10:51:07 -050094/* ioctl(fd, op, [arg]) */
Guido van Rossum02975121992-08-17 08:55:12 +000095
Roger E. Masse919213a1996-12-17 17:42:22 +000096static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +000097fcntl_ioctl(PyObject *self, PyObject *args)
Guido van Rossum02975121992-08-17 08:55:12 +000098{
Thomas Wouters477c8d52006-05-27 19:21:47 +000099#define IOCTL_BUFSZ 1024
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000100 int fd;
101 /* In PyArg_ParseTuple below, we use the unsigned non-checked 'I'
102 format for the 'code' parameter because Python turns 0x8000000
103 into either a large positive number (PyLong or PyInt on 64-bit
104 platforms) or a negative number on others (32-bit PyInt)
105 whereas the system expects it to be a 32bit bit field value
106 regardless of it being passed as an int or unsigned long on
107 various platforms. See the termios.TIOCSWINSZ constant across
R David Murrayd5a2f0b2013-11-07 10:51:07 -0500108 platforms for an example of this.
Christian Heimese25f35e2008-03-20 10:49:03 +0000109
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000110 If any of the 64bit platforms ever decide to use more than 32bits
111 in their unsigned long ioctl codes this will break and need
112 special casing based on the platform being built on.
113 */
114 unsigned int code;
115 int arg;
116 int ret;
117 Py_buffer pstr;
118 char *str;
119 Py_ssize_t len;
120 int mutate_arg = 1;
121 char buf[IOCTL_BUFSZ+1]; /* argument plus NUL byte */
Guido van Rossum02975121992-08-17 08:55:12 +0000122
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000123 if (PyArg_ParseTuple(args, "O&Iw*|i:ioctl",
124 conv_descriptor, &fd, &code,
125 &pstr, &mutate_arg)) {
126 char *arg;
127 str = pstr.buf;
128 len = pstr.len;
Michael W. Hudsonf0089982003-03-03 12:29:42 +0000129
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000130 if (mutate_arg) {
131 if (len <= IOCTL_BUFSZ) {
132 memcpy(buf, str, len);
133 buf[len] = '\0';
134 arg = buf;
135 }
136 else {
137 arg = str;
138 }
139 }
140 else {
141 if (len > IOCTL_BUFSZ) {
142 PyBuffer_Release(&pstr);
143 PyErr_SetString(PyExc_ValueError,
144 "ioctl string arg too long");
145 return NULL;
146 }
147 else {
148 memcpy(buf, str, len);
149 buf[len] = '\0';
150 arg = buf;
151 }
152 }
153 if (buf == arg) {
154 Py_BEGIN_ALLOW_THREADS /* think array.resize() */
155 ret = ioctl(fd, code, arg);
156 Py_END_ALLOW_THREADS
157 }
158 else {
159 ret = ioctl(fd, code, arg);
160 }
Antoine Pitrou5e38aae2010-09-07 16:30:09 +0000161 if (mutate_arg && (len <= IOCTL_BUFSZ)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000162 memcpy(str, buf, len);
163 }
164 PyBuffer_Release(&pstr); /* No further access to str below this point */
165 if (ret < 0) {
166 PyErr_SetFromErrno(PyExc_IOError);
167 return NULL;
168 }
169 if (mutate_arg) {
170 return PyLong_FromLong(ret);
171 }
172 else {
173 return PyBytes_FromStringAndSize(buf, len);
174 }
175 }
Michael W. Hudsonf0089982003-03-03 12:29:42 +0000176
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000177 PyErr_Clear();
178 if (PyArg_ParseTuple(args, "O&Is*:ioctl",
179 conv_descriptor, &fd, &code, &pstr)) {
180 str = pstr.buf;
181 len = pstr.len;
182 if (len > IOCTL_BUFSZ) {
183 PyBuffer_Release(&pstr);
184 PyErr_SetString(PyExc_ValueError,
185 "ioctl string arg too long");
186 return NULL;
187 }
188 memcpy(buf, str, len);
189 buf[len] = '\0';
190 Py_BEGIN_ALLOW_THREADS
191 ret = ioctl(fd, code, buf);
192 Py_END_ALLOW_THREADS
193 if (ret < 0) {
194 PyBuffer_Release(&pstr);
195 PyErr_SetFromErrno(PyExc_IOError);
196 return NULL;
197 }
198 PyBuffer_Release(&pstr);
199 return PyBytes_FromStringAndSize(buf, len);
200 }
Guido van Rossum02975121992-08-17 08:55:12 +0000201
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000202 PyErr_Clear();
203 arg = 0;
204 if (!PyArg_ParseTuple(args,
205 "O&I|i;ioctl requires a file or file descriptor,"
206 " an integer and optionally an integer or buffer argument",
207 conv_descriptor, &fd, &code, &arg)) {
208 return NULL;
209 }
210 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000211#ifdef __VMS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000212 ret = ioctl(fd, code, (void *)arg);
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000213#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000214 ret = ioctl(fd, code, arg);
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000215#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000216 Py_END_ALLOW_THREADS
217 if (ret < 0) {
218 PyErr_SetFromErrno(PyExc_IOError);
219 return NULL;
220 }
221 return PyLong_FromLong((long)ret);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000222#undef IOCTL_BUFSZ
Guido van Rossum02975121992-08-17 08:55:12 +0000223}
224
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000225PyDoc_STRVAR(ioctl_doc,
R David Murrayd5a2f0b2013-11-07 10:51:07 -0500226"ioctl(fd, op[, arg[, mutate_flag]])\n\
Guido van Rossum185ead61998-11-23 15:32:55 +0000227\n\
R David Murrayd5a2f0b2013-11-07 10:51:07 -0500228Perform the operation op on file descriptor fd. The values used for op\n\
229are operating system dependent, and are available as constants in the\n\
230fcntl or termios library modules, using the same names as used in the\n\
231relevant C header files.\n\
Michael W. Hudsonf0089982003-03-03 12:29:42 +0000232\n\
233The argument arg is optional, and defaults to 0; it may be an int or a\n\
234buffer containing character data (most likely a string or an array). \n\
235\n\
236If the argument is a mutable buffer (such as an array) and if the\n\
237mutate_flag argument (which is only allowed in this case) is true then the\n\
238buffer is (in effect) passed to the operating system and changes made by\n\
239the OS will be reflected in the contents of the buffer after the call has\n\
240returned. The return value is the integer returned by the ioctl system\n\
241call.\n\
242\n\
243If the argument is a mutable buffer and the mutable_flag argument is not\n\
244passed or is false, the behavior is as if a string had been passed. This\n\
245behavior will change in future releases of Python.\n\
246\n\
247If the argument is an immutable buffer (most likely a string) then a copy\n\
248of the buffer is passed to the operating system and the return value is a\n\
249string of the same length containing whatever the operating system put in\n\
250the buffer. The length of the arg buffer in this case is not allowed to\n\
251exceed 1024 bytes.\n\
252\n\
253If the arg given is an integer or if none is specified, the result value is\n\
254an integer corresponding to the return value of the ioctl call in the C\n\
255code.");
Guido van Rossum185ead61998-11-23 15:32:55 +0000256
Guido van Rossum02975121992-08-17 08:55:12 +0000257
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000258/* flock(fd, operation) */
259
Roger E. Masse919213a1996-12-17 17:42:22 +0000260static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000261fcntl_flock(PyObject *self, PyObject *args)
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000262{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000263 int fd;
264 int code;
265 int ret;
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000266
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000267 if (!PyArg_ParseTuple(args, "O&i:flock",
268 conv_descriptor, &fd, &code))
269 return NULL;
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000270
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000271#ifdef HAVE_FLOCK
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000272 Py_BEGIN_ALLOW_THREADS
273 ret = flock(fd, code);
274 Py_END_ALLOW_THREADS
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000275#else
276
277#ifndef LOCK_SH
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000278#define LOCK_SH 1 /* shared lock */
279#define LOCK_EX 2 /* exclusive lock */
280#define LOCK_NB 4 /* don't block when locking */
281#define LOCK_UN 8 /* unlock */
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000282#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000283 {
284 struct flock l;
285 if (code == LOCK_UN)
286 l.l_type = F_UNLCK;
287 else if (code & LOCK_SH)
288 l.l_type = F_RDLCK;
289 else if (code & LOCK_EX)
290 l.l_type = F_WRLCK;
291 else {
292 PyErr_SetString(PyExc_ValueError,
293 "unrecognized flock argument");
294 return NULL;
295 }
296 l.l_whence = l.l_start = l.l_len = 0;
297 Py_BEGIN_ALLOW_THREADS
298 ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
299 Py_END_ALLOW_THREADS
300 }
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000301#endif /* HAVE_FLOCK */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000302 if (ret < 0) {
303 PyErr_SetFromErrno(PyExc_IOError);
304 return NULL;
305 }
306 Py_INCREF(Py_None);
307 return Py_None;
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000308}
309
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000310PyDoc_STRVAR(flock_doc,
Guido van Rossum185ead61998-11-23 15:32:55 +0000311"flock(fd, operation)\n\
312\n\
313Perform the lock operation op on file descriptor fd. See the Unix \n\
Ned Deily2a8b3f22013-10-02 12:20:46 -0700314manual page for flock(2) for details. (On some systems, this function is\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000315emulated using fcntl().)");
Guido van Rossum185ead61998-11-23 15:32:55 +0000316
317
Guido van Rossumc8643641996-09-11 23:17:20 +0000318/* lockf(fd, operation) */
Roger E. Masse919213a1996-12-17 17:42:22 +0000319static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000320fcntl_lockf(PyObject *self, PyObject *args)
Guido van Rossumc8643641996-09-11 23:17:20 +0000321{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000322 int fd, code, ret, whence = 0;
323 PyObject *lenobj = NULL, *startobj = NULL;
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000324
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000325 if (!PyArg_ParseTuple(args, "O&i|OOi:lockf",
326 conv_descriptor, &fd, &code,
327 &lenobj, &startobj, &whence))
328 return NULL;
Guido van Rossumc8643641996-09-11 23:17:20 +0000329
Andrew MacIntyre7bf68332002-03-03 02:59:16 +0000330#if defined(PYOS_OS2) && defined(PYCC_GCC)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000331 PyErr_SetString(PyExc_NotImplementedError,
332 "lockf not supported on OS/2 (EMX)");
333 return NULL;
Andrew MacIntyre7bf68332002-03-03 02:59:16 +0000334#else
Guido van Rossumc8643641996-09-11 23:17:20 +0000335#ifndef LOCK_SH
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000336#define LOCK_SH 1 /* shared lock */
337#define LOCK_EX 2 /* exclusive lock */
338#define LOCK_NB 4 /* don't block when locking */
339#define LOCK_UN 8 /* unlock */
Andrew MacIntyre7bf68332002-03-03 02:59:16 +0000340#endif /* LOCK_SH */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000341 {
342 struct flock l;
343 if (code == LOCK_UN)
344 l.l_type = F_UNLCK;
345 else if (code & LOCK_SH)
346 l.l_type = F_RDLCK;
347 else if (code & LOCK_EX)
348 l.l_type = F_WRLCK;
349 else {
350 PyErr_SetString(PyExc_ValueError,
351 "unrecognized lockf argument");
352 return NULL;
353 }
354 l.l_start = l.l_len = 0;
355 if (startobj != NULL) {
Guido van Rossum056bad91999-01-06 18:44:23 +0000356#if !defined(HAVE_LARGEFILE_SUPPORT)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000357 l.l_start = PyLong_AsLong(startobj);
Guido van Rossum056bad91999-01-06 18:44:23 +0000358#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000359 l.l_start = PyLong_Check(startobj) ?
360 PyLong_AsLongLong(startobj) :
361 PyLong_AsLong(startobj);
Guido van Rossum056bad91999-01-06 18:44:23 +0000362#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000363 if (PyErr_Occurred())
364 return NULL;
365 }
366 if (lenobj != NULL) {
Guido van Rossum056bad91999-01-06 18:44:23 +0000367#if !defined(HAVE_LARGEFILE_SUPPORT)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000368 l.l_len = PyLong_AsLong(lenobj);
Guido van Rossum056bad91999-01-06 18:44:23 +0000369#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000370 l.l_len = PyLong_Check(lenobj) ?
371 PyLong_AsLongLong(lenobj) :
372 PyLong_AsLong(lenobj);
Guido van Rossum056bad91999-01-06 18:44:23 +0000373#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000374 if (PyErr_Occurred())
375 return NULL;
376 }
377 l.l_whence = whence;
378 Py_BEGIN_ALLOW_THREADS
379 ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
380 Py_END_ALLOW_THREADS
381 }
382 if (ret < 0) {
383 PyErr_SetFromErrno(PyExc_IOError);
384 return NULL;
385 }
386 Py_INCREF(Py_None);
387 return Py_None;
Andrew MacIntyre7bf68332002-03-03 02:59:16 +0000388#endif /* defined(PYOS_OS2) && defined(PYCC_GCC) */
Guido van Rossumc8643641996-09-11 23:17:20 +0000389}
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000390
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000391PyDoc_STRVAR(lockf_doc,
Sjoerd Mullender82e00d62001-01-25 10:10:39 +0000392"lockf (fd, operation, length=0, start=0, whence=0)\n\
393\n\
394This is essentially a wrapper around the fcntl() locking calls. fd is the\n\
395file descriptor of the file to lock or unlock, and operation is one of the\n\
396following values:\n\
397\n\
398 LOCK_UN - unlock\n\
399 LOCK_SH - acquire a shared lock\n\
400 LOCK_EX - acquire an exclusive lock\n\
401\n\
Christian Heimesfaf2f632008-01-06 16:59:19 +0000402When operation is LOCK_SH or LOCK_EX, it can also be bitwise ORed with\n\
Sjoerd Mullender82e00d62001-01-25 10:10:39 +0000403LOCK_NB to avoid blocking on lock acquisition. If LOCK_NB is used and the\n\
404lock cannot be acquired, an IOError will be raised and the exception will\n\
405have an errno attribute set to EACCES or EAGAIN (depending on the operating\n\
406system -- for portability, check for either value).\n\
407\n\
408length is the number of bytes to lock, with the default meaning to lock to\n\
409EOF. start is the byte offset, relative to whence, to that the lock\n\
410starts. whence is as with fileobj.seek(), specifically:\n\
411\n\
412 0 - relative to the start of the file (SEEK_SET)\n\
413 1 - relative to the current buffer position (SEEK_CUR)\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000414 2 - relative to the end of the file (SEEK_END)");
Guido van Rossum185ead61998-11-23 15:32:55 +0000415
Guido van Rossum02975121992-08-17 08:55:12 +0000416/* List of functions */
417
Roger E. Masse919213a1996-12-17 17:42:22 +0000418static PyMethodDef fcntl_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000419 {"fcntl", fcntl_fcntl, METH_VARARGS, fcntl_doc},
420 {"ioctl", fcntl_ioctl, METH_VARARGS, ioctl_doc},
421 {"flock", fcntl_flock, METH_VARARGS, flock_doc},
422 {"lockf", fcntl_lockf, METH_VARARGS, lockf_doc},
423 {NULL, NULL} /* sentinel */
Guido van Rossum02975121992-08-17 08:55:12 +0000424};
425
426
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000427PyDoc_STRVAR(module_doc,
Guido van Rossum185ead61998-11-23 15:32:55 +0000428"This module performs file control and I/O control on file \n\
429descriptors. It is an interface to the fcntl() and ioctl() Unix\n\
430routines. File descriptors can be obtained with the fileno() method of\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000431a file or socket object.");
Guido van Rossum185ead61998-11-23 15:32:55 +0000432
Guido van Rossum02975121992-08-17 08:55:12 +0000433/* Module initialisation */
434
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000435static int
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000436ins(PyObject* d, char* symbol, long value)
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000437{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000438 PyObject* v = PyLong_FromLong(value);
439 if (!v || PyDict_SetItemString(d, symbol, v) < 0)
440 return -1;
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000441
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000442 Py_DECREF(v);
443 return 0;
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000444}
445
Martin v. Löwis14e73b12003-01-01 09:51:12 +0000446#define INS(x) if (ins(d, #x, (long)x)) return -1
447
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000448static int
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000449all_ins(PyObject* d)
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000450{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000451 if (ins(d, "LOCK_SH", (long)LOCK_SH)) return -1;
452 if (ins(d, "LOCK_EX", (long)LOCK_EX)) return -1;
453 if (ins(d, "LOCK_NB", (long)LOCK_NB)) return -1;
454 if (ins(d, "LOCK_UN", (long)LOCK_UN)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000455/* GNU extensions, as of glibc 2.2.4 */
456#ifdef LOCK_MAND
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000457 if (ins(d, "LOCK_MAND", (long)LOCK_MAND)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000458#endif
459#ifdef LOCK_READ
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000460 if (ins(d, "LOCK_READ", (long)LOCK_READ)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000461#endif
462#ifdef LOCK_WRITE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000463 if (ins(d, "LOCK_WRITE", (long)LOCK_WRITE)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000464#endif
465#ifdef LOCK_RW
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000466 if (ins(d, "LOCK_RW", (long)LOCK_RW)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000467#endif
468
Fred Drake152a25e2001-05-09 21:02:02 +0000469#ifdef F_DUPFD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000470 if (ins(d, "F_DUPFD", (long)F_DUPFD)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000471#endif
472#ifdef F_GETFD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000473 if (ins(d, "F_GETFD", (long)F_GETFD)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000474#endif
475#ifdef F_SETFD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000476 if (ins(d, "F_SETFD", (long)F_SETFD)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000477#endif
478#ifdef F_GETFL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000479 if (ins(d, "F_GETFL", (long)F_GETFL)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000480#endif
481#ifdef F_SETFL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000482 if (ins(d, "F_SETFL", (long)F_SETFL)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000483#endif
484#ifdef F_GETLK
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000485 if (ins(d, "F_GETLK", (long)F_GETLK)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000486#endif
487#ifdef F_SETLK
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000488 if (ins(d, "F_SETLK", (long)F_SETLK)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000489#endif
490#ifdef F_SETLKW
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000491 if (ins(d, "F_SETLKW", (long)F_SETLKW)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000492#endif
493#ifdef F_GETOWN
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000494 if (ins(d, "F_GETOWN", (long)F_GETOWN)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000495#endif
496#ifdef F_SETOWN
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000497 if (ins(d, "F_SETOWN", (long)F_SETOWN)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000498#endif
499#ifdef F_GETSIG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000500 if (ins(d, "F_GETSIG", (long)F_GETSIG)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000501#endif
502#ifdef F_SETSIG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000503 if (ins(d, "F_SETSIG", (long)F_SETSIG)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000504#endif
505#ifdef F_RDLCK
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000506 if (ins(d, "F_RDLCK", (long)F_RDLCK)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000507#endif
508#ifdef F_WRLCK
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000509 if (ins(d, "F_WRLCK", (long)F_WRLCK)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000510#endif
511#ifdef F_UNLCK
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000512 if (ins(d, "F_UNLCK", (long)F_UNLCK)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000513#endif
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000514/* LFS constants */
515#ifdef F_GETLK64
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000516 if (ins(d, "F_GETLK64", (long)F_GETLK64)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000517#endif
518#ifdef F_SETLK64
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000519 if (ins(d, "F_SETLK64", (long)F_SETLK64)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000520#endif
521#ifdef F_SETLKW64
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000522 if (ins(d, "F_SETLKW64", (long)F_SETLKW64)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000523#endif
524/* GNU extensions, as of glibc 2.2.4. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +0000525#ifdef FASYNC
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000526 if (ins(d, "FASYNC", (long)FASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +0000527#endif
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000528#ifdef F_SETLEASE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000529 if (ins(d, "F_SETLEASE", (long)F_SETLEASE)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000530#endif
531#ifdef F_GETLEASE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000532 if (ins(d, "F_GETLEASE", (long)F_GETLEASE)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000533#endif
534#ifdef F_NOTIFY
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000535 if (ins(d, "F_NOTIFY", (long)F_NOTIFY)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000536#endif
537/* Old BSD flock(). */
538#ifdef F_EXLCK
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000539 if (ins(d, "F_EXLCK", (long)F_EXLCK)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000540#endif
541#ifdef F_SHLCK
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000542 if (ins(d, "F_SHLCK", (long)F_SHLCK)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000543#endif
544
Charles-François Natali23e1ecb2011-11-02 18:58:25 +0100545/* OS X specifics */
Georg Brandl6aa2d1f2008-08-12 08:35:52 +0000546#ifdef F_FULLFSYNC
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000547 if (ins(d, "F_FULLFSYNC", (long)F_FULLFSYNC)) return -1;
Georg Brandl6aa2d1f2008-08-12 08:35:52 +0000548#endif
Charles-François Natali23e1ecb2011-11-02 18:58:25 +0100549#ifdef F_NOCACHE
550 if (ins(d, "F_NOCACHE", (long)F_NOCACHE)) return -1;
551#endif
Georg Brandl6aa2d1f2008-08-12 08:35:52 +0000552
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000553/* For F_{GET|SET}FL */
554#ifdef FD_CLOEXEC
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000555 if (ins(d, "FD_CLOEXEC", (long)FD_CLOEXEC)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000556#endif
557
558/* For F_NOTIFY */
559#ifdef DN_ACCESS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000560 if (ins(d, "DN_ACCESS", (long)DN_ACCESS)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000561#endif
562#ifdef DN_MODIFY
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000563 if (ins(d, "DN_MODIFY", (long)DN_MODIFY)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000564#endif
565#ifdef DN_CREATE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000566 if (ins(d, "DN_CREATE", (long)DN_CREATE)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000567#endif
568#ifdef DN_DELETE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000569 if (ins(d, "DN_DELETE", (long)DN_DELETE)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000570#endif
571#ifdef DN_RENAME
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000572 if (ins(d, "DN_RENAME", (long)DN_RENAME)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000573#endif
574#ifdef DN_ATTRIB
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000575 if (ins(d, "DN_ATTRIB", (long)DN_ATTRIB)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000576#endif
577#ifdef DN_MULTISHOT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000578 if (ins(d, "DN_MULTISHOT", (long)DN_MULTISHOT)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000579#endif
580
Martin v. Löwis14e73b12003-01-01 09:51:12 +0000581#ifdef HAVE_STROPTS_H
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000582 /* Unix 98 guarantees that these are in stropts.h. */
583 INS(I_PUSH);
584 INS(I_POP);
585 INS(I_LOOK);
586 INS(I_FLUSH);
587 INS(I_FLUSHBAND);
588 INS(I_SETSIG);
589 INS(I_GETSIG);
590 INS(I_FIND);
591 INS(I_PEEK);
592 INS(I_SRDOPT);
593 INS(I_GRDOPT);
594 INS(I_NREAD);
595 INS(I_FDINSERT);
596 INS(I_STR);
597 INS(I_SWROPT);
Michael W. Hudson505c4c22003-05-09 10:45:20 +0000598#ifdef I_GWROPT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000599 /* despite the comment above, old-ish glibcs miss a couple... */
600 INS(I_GWROPT);
Michael W. Hudson505c4c22003-05-09 10:45:20 +0000601#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000602 INS(I_SENDFD);
603 INS(I_RECVFD);
604 INS(I_LIST);
605 INS(I_ATMARK);
606 INS(I_CKBAND);
607 INS(I_GETBAND);
608 INS(I_CANPUT);
609 INS(I_SETCLTIME);
Michael W. Hudson505c4c22003-05-09 10:45:20 +0000610#ifdef I_GETCLTIME
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000611 INS(I_GETCLTIME);
Michael W. Hudson505c4c22003-05-09 10:45:20 +0000612#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000613 INS(I_LINK);
614 INS(I_UNLINK);
615 INS(I_PLINK);
616 INS(I_PUNLINK);
Martin v. Löwis14e73b12003-01-01 09:51:12 +0000617#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000618
619 return 0;
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000620}
621
Martin v. Löwis1a214512008-06-11 05:26:20 +0000622
623static struct PyModuleDef fcntlmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000624 PyModuleDef_HEAD_INIT,
625 "fcntl",
626 module_doc,
627 -1,
628 fcntl_methods,
629 NULL,
630 NULL,
631 NULL,
632 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +0000633};
634
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000635PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +0000636PyInit_fcntl(void)
Guido van Rossum02975121992-08-17 08:55:12 +0000637{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000638 PyObject *m, *d;
Guido van Rossum02975121992-08-17 08:55:12 +0000639
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000640 /* Create the module and add the functions and documentation */
641 m = PyModule_Create(&fcntlmodule);
642 if (m == NULL)
643 return NULL;
Guido van Rossum02975121992-08-17 08:55:12 +0000644
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000645 /* Add some symbolic constants to the module */
646 d = PyModule_GetDict(m);
647 all_ins(d);
648 return m;
Guido van Rossum02975121992-08-17 08:55:12 +0000649}