blob: 997867a136edec6bf5782fb2811af415639d23b0 [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 Pitrouc83ea132010-05-09 14:46:46 +000024 return 0;
Fred Drake152a25e2001-05-09 21:02:02 +000025 *target = fd;
26 return 1;
27}
28
29
Guido van Rossum02975121992-08-17 08:55:12 +000030/* fcntl(fd, opt, [arg]) */
31
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 Pitrouc83ea132010-05-09 14:46:46 +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 Pitrouc83ea132010-05-09 14:46:46 +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 PyString_FromStringAndSize(buf, len);
59 }
Guido van Rossum02975121992-08-17 08:55:12 +000060
Antoine Pitrouc83ea132010-05-09 14:46:46 +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 PyInt_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,
Guido van Rossum185ead61998-11-23 15:32:55 +000080"fcntl(fd, opt, [arg])\n\
81\n\
82Perform the requested operation on file descriptor fd. The operation\n\
Fred Drake1d531992001-05-10 15:54:32 +000083is defined by op and is operating system dependent. These constants are\n\
84available from the fcntl module. The argument arg is optional, and\n\
Georg Brandl21946af2010-10-06 09:28:45 +000085defaults 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 +000086the return value of fcntl is a string of that length, containing the\n\
Georg Brandl21946af2010-10-06 09:28:45 +000087resulting value put in the arg buffer by the operating system. The length\n\
88of the arg string is not allowed to exceed 1024 bytes. If the arg given\n\
Fred Drake1d531992001-05-10 15:54:32 +000089is an integer or if none is specified, the result value is an integer\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000090corresponding to the return value of the fcntl call in the C code.");
Guido van Rossum185ead61998-11-23 15:32:55 +000091
Guido van Rossum02975121992-08-17 08:55:12 +000092
93/* ioctl(fd, opt, [arg]) */
94
Roger E. Masse919213a1996-12-17 17:42:22 +000095static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +000096fcntl_ioctl(PyObject *self, PyObject *args)
Guido van Rossum02975121992-08-17 08:55:12 +000097{
Thomas Wouters6dbff332006-04-25 13:53:23 +000098#define IOCTL_BUFSZ 1024
Antoine Pitrouc83ea132010-05-09 14:46:46 +000099 int fd;
100 /* In PyArg_ParseTuple below, we use the unsigned non-checked 'I'
101 format for the 'code' parameter because Python turns 0x8000000
102 into either a large positive number (PyLong or PyInt on 64-bit
103 platforms) or a negative number on others (32-bit PyInt)
104 whereas the system expects it to be a 32bit bit field value
105 regardless of it being passed as an int or unsigned long on
106 various platforms. See the termios.TIOCSWINSZ constant across
107 platforms for an example of thise.
Gregory P. Smitha5cfcad2008-03-19 23:03:25 +0000108
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000109 If any of the 64bit platforms ever decide to use more than 32bits
110 in their unsigned long ioctl codes this will break and need
111 special casing based on the platform being built on.
112 */
113 unsigned int code;
114 int arg;
115 int ret;
116 char *str;
117 Py_ssize_t len;
118 int mutate_arg = 1;
119 char buf[IOCTL_BUFSZ+1]; /* argument plus NUL byte */
Guido van Rossum02975121992-08-17 08:55:12 +0000120
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000121 if (PyArg_ParseTuple(args, "O&Iw#|i:ioctl",
122 conv_descriptor, &fd, &code,
123 &str, &len, &mutate_arg)) {
124 char *arg;
Michael W. Hudsonf0089982003-03-03 12:29:42 +0000125
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000126 if (mutate_arg) {
127 if (len <= IOCTL_BUFSZ) {
128 memcpy(buf, str, len);
129 buf[len] = '\0';
130 arg = buf;
131 }
132 else {
133 arg = str;
134 }
135 }
136 else {
137 if (len > IOCTL_BUFSZ) {
138 PyErr_SetString(PyExc_ValueError,
139 "ioctl string arg too long");
140 return NULL;
141 }
142 else {
143 memcpy(buf, str, len);
144 buf[len] = '\0';
145 arg = buf;
146 }
147 }
148 if (buf == arg) {
149 Py_BEGIN_ALLOW_THREADS /* think array.resize() */
150 ret = ioctl(fd, code, arg);
151 Py_END_ALLOW_THREADS
152 }
153 else {
154 ret = ioctl(fd, code, arg);
155 }
Antoine Pitrouf4f61712010-09-07 16:34:47 +0000156 if (mutate_arg && (len <= IOCTL_BUFSZ)) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000157 memcpy(str, buf, len);
158 }
159 if (ret < 0) {
160 PyErr_SetFromErrno(PyExc_IOError);
161 return NULL;
162 }
163 if (mutate_arg) {
164 return PyInt_FromLong(ret);
165 }
166 else {
167 return PyString_FromStringAndSize(buf, len);
168 }
169 }
Michael W. Hudsonf0089982003-03-03 12:29:42 +0000170
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000171 PyErr_Clear();
172 if (PyArg_ParseTuple(args, "O&Is#:ioctl",
173 conv_descriptor, &fd, &code, &str, &len)) {
174 if (len > IOCTL_BUFSZ) {
175 PyErr_SetString(PyExc_ValueError,
176 "ioctl string arg too long");
177 return NULL;
178 }
179 memcpy(buf, str, len);
180 buf[len] = '\0';
181 Py_BEGIN_ALLOW_THREADS
182 ret = ioctl(fd, code, buf);
183 Py_END_ALLOW_THREADS
184 if (ret < 0) {
185 PyErr_SetFromErrno(PyExc_IOError);
186 return NULL;
187 }
188 return PyString_FromStringAndSize(buf, len);
189 }
Guido van Rossum02975121992-08-17 08:55:12 +0000190
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000191 PyErr_Clear();
192 arg = 0;
193 if (!PyArg_ParseTuple(args,
194 "O&I|i;ioctl requires a file or file descriptor,"
195 " an integer and optionally an integer or buffer argument",
196 conv_descriptor, &fd, &code, &arg)) {
197 return NULL;
198 }
199 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000200#ifdef __VMS
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000201 ret = ioctl(fd, code, (void *)arg);
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000202#else
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000203 ret = ioctl(fd, code, arg);
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000204#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000205 Py_END_ALLOW_THREADS
206 if (ret < 0) {
207 PyErr_SetFromErrno(PyExc_IOError);
208 return NULL;
209 }
210 return PyInt_FromLong((long)ret);
Thomas Wouters6dbff332006-04-25 13:53:23 +0000211#undef IOCTL_BUFSZ
Guido van Rossum02975121992-08-17 08:55:12 +0000212}
213
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000214PyDoc_STRVAR(ioctl_doc,
Michael W. Hudsonf0089982003-03-03 12:29:42 +0000215"ioctl(fd, opt[, arg[, mutate_flag]])\n\
Guido van Rossum185ead61998-11-23 15:32:55 +0000216\n\
Michael W. Hudsonf0089982003-03-03 12:29:42 +0000217Perform the requested operation on file descriptor fd. The operation is\n\
Neal Norwitz47308802003-06-30 01:54:04 +0000218defined by opt and is operating system dependent. Typically these codes are\n\
Michael W. Hudsonf0089982003-03-03 12:29:42 +0000219retrieved from the fcntl or termios library modules.\n\
220\n\
221The argument arg is optional, and defaults to 0; it may be an int or a\n\
222buffer containing character data (most likely a string or an array). \n\
223\n\
224If the argument is a mutable buffer (such as an array) and if the\n\
225mutate_flag argument (which is only allowed in this case) is true then the\n\
226buffer is (in effect) passed to the operating system and changes made by\n\
227the OS will be reflected in the contents of the buffer after the call has\n\
228returned. The return value is the integer returned by the ioctl system\n\
229call.\n\
230\n\
231If the argument is a mutable buffer and the mutable_flag argument is not\n\
232passed or is false, the behavior is as if a string had been passed. This\n\
233behavior will change in future releases of Python.\n\
234\n\
235If the argument is an immutable buffer (most likely a string) then a copy\n\
236of the buffer is passed to the operating system and the return value is a\n\
237string of the same length containing whatever the operating system put in\n\
238the buffer. The length of the arg buffer in this case is not allowed to\n\
239exceed 1024 bytes.\n\
240\n\
241If the arg given is an integer or if none is specified, the result value is\n\
242an integer corresponding to the return value of the ioctl call in the C\n\
243code.");
Guido van Rossum185ead61998-11-23 15:32:55 +0000244
Guido van Rossum02975121992-08-17 08:55:12 +0000245
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000246/* flock(fd, operation) */
247
Roger E. Masse919213a1996-12-17 17:42:22 +0000248static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000249fcntl_flock(PyObject *self, PyObject *args)
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000250{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000251 int fd;
252 int code;
253 int ret;
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000254
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000255 if (!PyArg_ParseTuple(args, "O&i:flock",
256 conv_descriptor, &fd, &code))
257 return NULL;
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000258
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000259#ifdef HAVE_FLOCK
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000260 Py_BEGIN_ALLOW_THREADS
261 ret = flock(fd, code);
262 Py_END_ALLOW_THREADS
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000263#else
264
265#ifndef LOCK_SH
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000266#define LOCK_SH 1 /* shared lock */
267#define LOCK_EX 2 /* exclusive lock */
268#define LOCK_NB 4 /* don't block when locking */
269#define LOCK_UN 8 /* unlock */
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000270#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000271 {
272 struct flock l;
273 if (code == LOCK_UN)
274 l.l_type = F_UNLCK;
275 else if (code & LOCK_SH)
276 l.l_type = F_RDLCK;
277 else if (code & LOCK_EX)
278 l.l_type = F_WRLCK;
279 else {
280 PyErr_SetString(PyExc_ValueError,
281 "unrecognized flock argument");
282 return NULL;
283 }
284 l.l_whence = l.l_start = l.l_len = 0;
285 Py_BEGIN_ALLOW_THREADS
286 ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
287 Py_END_ALLOW_THREADS
288 }
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000289#endif /* HAVE_FLOCK */
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000290 if (ret < 0) {
291 PyErr_SetFromErrno(PyExc_IOError);
292 return NULL;
293 }
294 Py_INCREF(Py_None);
295 return Py_None;
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000296}
297
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000298PyDoc_STRVAR(flock_doc,
Guido van Rossum185ead61998-11-23 15:32:55 +0000299"flock(fd, operation)\n\
300\n\
301Perform the lock operation op on file descriptor fd. See the Unix \n\
Andrew M. Kuchling8d9a01a2006-07-29 15:43:13 +0000302manual page for flock(3) for details. (On some systems, this function is\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000303emulated using fcntl().)");
Guido van Rossum185ead61998-11-23 15:32:55 +0000304
305
Guido van Rossumc8643641996-09-11 23:17:20 +0000306/* lockf(fd, operation) */
Roger E. Masse919213a1996-12-17 17:42:22 +0000307static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000308fcntl_lockf(PyObject *self, PyObject *args)
Guido van Rossumc8643641996-09-11 23:17:20 +0000309{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000310 int fd, code, ret, whence = 0;
311 PyObject *lenobj = NULL, *startobj = NULL;
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000312
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000313 if (!PyArg_ParseTuple(args, "O&i|OOi:lockf",
314 conv_descriptor, &fd, &code,
315 &lenobj, &startobj, &whence))
316 return NULL;
Guido van Rossumc8643641996-09-11 23:17:20 +0000317
Andrew MacIntyre7bf68332002-03-03 02:59:16 +0000318#if defined(PYOS_OS2) && defined(PYCC_GCC)
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000319 PyErr_SetString(PyExc_NotImplementedError,
320 "lockf not supported on OS/2 (EMX)");
321 return NULL;
Andrew MacIntyre7bf68332002-03-03 02:59:16 +0000322#else
Guido van Rossumc8643641996-09-11 23:17:20 +0000323#ifndef LOCK_SH
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000324#define LOCK_SH 1 /* shared lock */
325#define LOCK_EX 2 /* exclusive lock */
326#define LOCK_NB 4 /* don't block when locking */
327#define LOCK_UN 8 /* unlock */
Andrew MacIntyre7bf68332002-03-03 02:59:16 +0000328#endif /* LOCK_SH */
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000329 {
330 struct flock l;
331 if (code == LOCK_UN)
332 l.l_type = F_UNLCK;
333 else if (code & LOCK_SH)
334 l.l_type = F_RDLCK;
335 else if (code & LOCK_EX)
336 l.l_type = F_WRLCK;
337 else {
338 PyErr_SetString(PyExc_ValueError,
339 "unrecognized lockf argument");
340 return NULL;
341 }
342 l.l_start = l.l_len = 0;
343 if (startobj != NULL) {
Guido van Rossum056bad91999-01-06 18:44:23 +0000344#if !defined(HAVE_LARGEFILE_SUPPORT)
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000345 l.l_start = PyInt_AsLong(startobj);
Guido van Rossum056bad91999-01-06 18:44:23 +0000346#else
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000347 l.l_start = PyLong_Check(startobj) ?
348 PyLong_AsLongLong(startobj) :
349 PyInt_AsLong(startobj);
Guido van Rossum056bad91999-01-06 18:44:23 +0000350#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000351 if (PyErr_Occurred())
352 return NULL;
353 }
354 if (lenobj != NULL) {
Guido van Rossum056bad91999-01-06 18:44:23 +0000355#if !defined(HAVE_LARGEFILE_SUPPORT)
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000356 l.l_len = PyInt_AsLong(lenobj);
Guido van Rossum056bad91999-01-06 18:44:23 +0000357#else
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000358 l.l_len = PyLong_Check(lenobj) ?
359 PyLong_AsLongLong(lenobj) :
360 PyInt_AsLong(lenobj);
Guido van Rossum056bad91999-01-06 18:44:23 +0000361#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000362 if (PyErr_Occurred())
363 return NULL;
364 }
365 l.l_whence = whence;
366 Py_BEGIN_ALLOW_THREADS
367 ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
368 Py_END_ALLOW_THREADS
369 }
370 if (ret < 0) {
371 PyErr_SetFromErrno(PyExc_IOError);
372 return NULL;
373 }
374 Py_INCREF(Py_None);
375 return Py_None;
Andrew MacIntyre7bf68332002-03-03 02:59:16 +0000376#endif /* defined(PYOS_OS2) && defined(PYCC_GCC) */
Guido van Rossumc8643641996-09-11 23:17:20 +0000377}
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000378
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000379PyDoc_STRVAR(lockf_doc,
Sjoerd Mullender82e00d62001-01-25 10:10:39 +0000380"lockf (fd, operation, length=0, start=0, whence=0)\n\
381\n\
382This is essentially a wrapper around the fcntl() locking calls. fd is the\n\
383file descriptor of the file to lock or unlock, and operation is one of the\n\
384following values:\n\
385\n\
386 LOCK_UN - unlock\n\
387 LOCK_SH - acquire a shared lock\n\
388 LOCK_EX - acquire an exclusive lock\n\
389\n\
Georg Brandlf725b952008-01-05 19:44:22 +0000390When operation is LOCK_SH or LOCK_EX, it can also be bitwise ORed with\n\
Sjoerd Mullender82e00d62001-01-25 10:10:39 +0000391LOCK_NB to avoid blocking on lock acquisition. If LOCK_NB is used and the\n\
392lock cannot be acquired, an IOError will be raised and the exception will\n\
393have an errno attribute set to EACCES or EAGAIN (depending on the operating\n\
394system -- for portability, check for either value).\n\
395\n\
396length is the number of bytes to lock, with the default meaning to lock to\n\
397EOF. start is the byte offset, relative to whence, to that the lock\n\
398starts. whence is as with fileobj.seek(), specifically:\n\
399\n\
400 0 - relative to the start of the file (SEEK_SET)\n\
401 1 - relative to the current buffer position (SEEK_CUR)\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000402 2 - relative to the end of the file (SEEK_END)");
Guido van Rossum185ead61998-11-23 15:32:55 +0000403
Guido van Rossum02975121992-08-17 08:55:12 +0000404/* List of functions */
405
Roger E. Masse919213a1996-12-17 17:42:22 +0000406static PyMethodDef fcntl_methods[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000407 {"fcntl", fcntl_fcntl, METH_VARARGS, fcntl_doc},
408 {"ioctl", fcntl_ioctl, METH_VARARGS, ioctl_doc},
409 {"flock", fcntl_flock, METH_VARARGS, flock_doc},
410 {"lockf", fcntl_lockf, METH_VARARGS, lockf_doc},
411 {NULL, NULL} /* sentinel */
Guido van Rossum02975121992-08-17 08:55:12 +0000412};
413
414
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000415PyDoc_STRVAR(module_doc,
Guido van Rossum185ead61998-11-23 15:32:55 +0000416"This module performs file control and I/O control on file \n\
417descriptors. It is an interface to the fcntl() and ioctl() Unix\n\
418routines. File descriptors can be obtained with the fileno() method of\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000419a file or socket object.");
Guido van Rossum185ead61998-11-23 15:32:55 +0000420
Guido van Rossum02975121992-08-17 08:55:12 +0000421/* Module initialisation */
422
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000423static int
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000424ins(PyObject* d, char* symbol, long value)
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000425{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000426 PyObject* v = PyInt_FromLong(value);
427 if (!v || PyDict_SetItemString(d, symbol, v) < 0)
428 return -1;
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000429
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000430 Py_DECREF(v);
431 return 0;
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000432}
433
Martin v. Löwis14e73b12003-01-01 09:51:12 +0000434#define INS(x) if (ins(d, #x, (long)x)) return -1
435
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000436static int
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000437all_ins(PyObject* d)
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000438{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000439 if (ins(d, "LOCK_SH", (long)LOCK_SH)) return -1;
440 if (ins(d, "LOCK_EX", (long)LOCK_EX)) return -1;
441 if (ins(d, "LOCK_NB", (long)LOCK_NB)) return -1;
442 if (ins(d, "LOCK_UN", (long)LOCK_UN)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000443/* GNU extensions, as of glibc 2.2.4 */
444#ifdef LOCK_MAND
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000445 if (ins(d, "LOCK_MAND", (long)LOCK_MAND)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000446#endif
447#ifdef LOCK_READ
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000448 if (ins(d, "LOCK_READ", (long)LOCK_READ)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000449#endif
450#ifdef LOCK_WRITE
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000451 if (ins(d, "LOCK_WRITE", (long)LOCK_WRITE)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000452#endif
453#ifdef LOCK_RW
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000454 if (ins(d, "LOCK_RW", (long)LOCK_RW)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000455#endif
456
Fred Drake152a25e2001-05-09 21:02:02 +0000457#ifdef F_DUPFD
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000458 if (ins(d, "F_DUPFD", (long)F_DUPFD)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000459#endif
460#ifdef F_GETFD
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000461 if (ins(d, "F_GETFD", (long)F_GETFD)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000462#endif
463#ifdef F_SETFD
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000464 if (ins(d, "F_SETFD", (long)F_SETFD)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000465#endif
466#ifdef F_GETFL
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000467 if (ins(d, "F_GETFL", (long)F_GETFL)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000468#endif
469#ifdef F_SETFL
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000470 if (ins(d, "F_SETFL", (long)F_SETFL)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000471#endif
472#ifdef F_GETLK
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000473 if (ins(d, "F_GETLK", (long)F_GETLK)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000474#endif
475#ifdef F_SETLK
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000476 if (ins(d, "F_SETLK", (long)F_SETLK)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000477#endif
478#ifdef F_SETLKW
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000479 if (ins(d, "F_SETLKW", (long)F_SETLKW)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000480#endif
481#ifdef F_GETOWN
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000482 if (ins(d, "F_GETOWN", (long)F_GETOWN)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000483#endif
484#ifdef F_SETOWN
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000485 if (ins(d, "F_SETOWN", (long)F_SETOWN)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000486#endif
487#ifdef F_GETSIG
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000488 if (ins(d, "F_GETSIG", (long)F_GETSIG)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000489#endif
490#ifdef F_SETSIG
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000491 if (ins(d, "F_SETSIG", (long)F_SETSIG)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000492#endif
493#ifdef F_RDLCK
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000494 if (ins(d, "F_RDLCK", (long)F_RDLCK)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000495#endif
496#ifdef F_WRLCK
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000497 if (ins(d, "F_WRLCK", (long)F_WRLCK)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000498#endif
499#ifdef F_UNLCK
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000500 if (ins(d, "F_UNLCK", (long)F_UNLCK)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000501#endif
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000502/* LFS constants */
503#ifdef F_GETLK64
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000504 if (ins(d, "F_GETLK64", (long)F_GETLK64)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000505#endif
506#ifdef F_SETLK64
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000507 if (ins(d, "F_SETLK64", (long)F_SETLK64)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000508#endif
509#ifdef F_SETLKW64
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000510 if (ins(d, "F_SETLKW64", (long)F_SETLKW64)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000511#endif
512/* GNU extensions, as of glibc 2.2.4. */
Georg Brandl5049a852008-05-16 13:10:15 +0000513#ifdef FASYNC
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000514 if (ins(d, "FASYNC", (long)FASYNC)) return -1;
Georg Brandl5049a852008-05-16 13:10:15 +0000515#endif
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000516#ifdef F_SETLEASE
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000517 if (ins(d, "F_SETLEASE", (long)F_SETLEASE)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000518#endif
519#ifdef F_GETLEASE
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000520 if (ins(d, "F_GETLEASE", (long)F_GETLEASE)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000521#endif
522#ifdef F_NOTIFY
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000523 if (ins(d, "F_NOTIFY", (long)F_NOTIFY)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000524#endif
525/* Old BSD flock(). */
526#ifdef F_EXLCK
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000527 if (ins(d, "F_EXLCK", (long)F_EXLCK)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000528#endif
529#ifdef F_SHLCK
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000530 if (ins(d, "F_SHLCK", (long)F_SHLCK)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000531#endif
532
Guido van Rossumd6939012008-08-07 18:51:38 +0000533/* OS X (and maybe others) let you tell the storage device to flush to physical media */
534#ifdef F_FULLFSYNC
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000535 if (ins(d, "F_FULLFSYNC", (long)F_FULLFSYNC)) return -1;
Guido van Rossumd6939012008-08-07 18:51:38 +0000536#endif
537
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000538/* For F_{GET|SET}FL */
539#ifdef FD_CLOEXEC
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000540 if (ins(d, "FD_CLOEXEC", (long)FD_CLOEXEC)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000541#endif
542
543/* For F_NOTIFY */
544#ifdef DN_ACCESS
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000545 if (ins(d, "DN_ACCESS", (long)DN_ACCESS)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000546#endif
547#ifdef DN_MODIFY
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000548 if (ins(d, "DN_MODIFY", (long)DN_MODIFY)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000549#endif
550#ifdef DN_CREATE
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000551 if (ins(d, "DN_CREATE", (long)DN_CREATE)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000552#endif
553#ifdef DN_DELETE
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000554 if (ins(d, "DN_DELETE", (long)DN_DELETE)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000555#endif
556#ifdef DN_RENAME
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000557 if (ins(d, "DN_RENAME", (long)DN_RENAME)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000558#endif
559#ifdef DN_ATTRIB
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000560 if (ins(d, "DN_ATTRIB", (long)DN_ATTRIB)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000561#endif
562#ifdef DN_MULTISHOT
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000563 if (ins(d, "DN_MULTISHOT", (long)DN_MULTISHOT)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000564#endif
565
Martin v. Löwis14e73b12003-01-01 09:51:12 +0000566#ifdef HAVE_STROPTS_H
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000567 /* Unix 98 guarantees that these are in stropts.h. */
568 INS(I_PUSH);
569 INS(I_POP);
570 INS(I_LOOK);
571 INS(I_FLUSH);
572 INS(I_FLUSHBAND);
573 INS(I_SETSIG);
574 INS(I_GETSIG);
575 INS(I_FIND);
576 INS(I_PEEK);
577 INS(I_SRDOPT);
578 INS(I_GRDOPT);
579 INS(I_NREAD);
580 INS(I_FDINSERT);
581 INS(I_STR);
582 INS(I_SWROPT);
Michael W. Hudson505c4c22003-05-09 10:45:20 +0000583#ifdef I_GWROPT
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000584 /* despite the comment above, old-ish glibcs miss a couple... */
585 INS(I_GWROPT);
Michael W. Hudson505c4c22003-05-09 10:45:20 +0000586#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000587 INS(I_SENDFD);
588 INS(I_RECVFD);
589 INS(I_LIST);
590 INS(I_ATMARK);
591 INS(I_CKBAND);
592 INS(I_GETBAND);
593 INS(I_CANPUT);
594 INS(I_SETCLTIME);
Michael W. Hudson505c4c22003-05-09 10:45:20 +0000595#ifdef I_GETCLTIME
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000596 INS(I_GETCLTIME);
Michael W. Hudson505c4c22003-05-09 10:45:20 +0000597#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000598 INS(I_LINK);
599 INS(I_UNLINK);
600 INS(I_PLINK);
601 INS(I_PUNLINK);
Martin v. Löwis14e73b12003-01-01 09:51:12 +0000602#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000603
604 return 0;
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000605}
606
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000607PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000608initfcntl(void)
Guido van Rossum02975121992-08-17 08:55:12 +0000609{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000610 PyObject *m, *d;
Guido van Rossum02975121992-08-17 08:55:12 +0000611
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000612 /* Create the module and add the functions and documentation */
613 m = Py_InitModule3("fcntl", fcntl_methods, module_doc);
614 if (m == NULL)
615 return;
Guido van Rossum02975121992-08-17 08:55:12 +0000616
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000617 /* Add some symbolic constants to the module */
618 d = PyModule_GetDict(m);
619 all_ins(d);
Guido van Rossum02975121992-08-17 08:55:12 +0000620}