blob: 9d8b58782730a75425f1417cecf23d4df778fedb [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
R David Murraya6912192013-11-07 10:52:53 -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 Pitrouc83ea132010-05-09 14:46:46 +000035 int fd;
36 int code;
Serhiy Storchaka069bdcb2014-11-10 10:42:06 +020037 int arg;
Antoine Pitrouc83ea132010-05-09 14:46:46 +000038 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,
Serhiy Storchaka069bdcb2014-11-10 10:42:06 +020064 "O&i|I;fcntl requires a file or file descriptor,"
Antoine Pitrouc83ea132010-05-09 14:46:46 +000065 " 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,
R David Murraya6912192013-11-07 10:52:53 -050080"fcntl(fd, op, [arg])\n\
Guido van Rossum185ead61998-11-23 15:32:55 +000081\n\
R David Murraya6912192013-11-07 10:52:53 -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 Brandl21946af2010-10-06 09:28:45 +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 Brandl21946af2010-10-06 09:28:45 +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 Murraya6912192013-11-07 10:52:53 -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 Wouters6dbff332006-04-25 13:53:23 +000099#define IOCTL_BUFSZ 1024
Antoine Pitrouc83ea132010-05-09 14:46:46 +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 Murraya6912192013-11-07 10:52:53 -0500108 platforms for an example of this.
Gregory P. Smitha5cfcad2008-03-19 23:03:25 +0000109
Antoine Pitrouc83ea132010-05-09 14:46:46 +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 char *str;
118 Py_ssize_t len;
119 int mutate_arg = 1;
120 char buf[IOCTL_BUFSZ+1]; /* argument plus NUL byte */
Guido van Rossum02975121992-08-17 08:55:12 +0000121
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000122 if (PyArg_ParseTuple(args, "O&Iw#|i:ioctl",
123 conv_descriptor, &fd, &code,
124 &str, &len, &mutate_arg)) {
125 char *arg;
Michael W. Hudsonf0089982003-03-03 12:29:42 +0000126
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000127 if (mutate_arg) {
128 if (len <= IOCTL_BUFSZ) {
129 memcpy(buf, str, len);
130 buf[len] = '\0';
131 arg = buf;
132 }
133 else {
134 arg = str;
135 }
136 }
137 else {
138 if (len > IOCTL_BUFSZ) {
139 PyErr_SetString(PyExc_ValueError,
140 "ioctl string arg too long");
141 return NULL;
142 }
143 else {
144 memcpy(buf, str, len);
145 buf[len] = '\0';
146 arg = buf;
147 }
148 }
149 if (buf == arg) {
150 Py_BEGIN_ALLOW_THREADS /* think array.resize() */
151 ret = ioctl(fd, code, arg);
152 Py_END_ALLOW_THREADS
153 }
154 else {
155 ret = ioctl(fd, code, arg);
156 }
Antoine Pitrouf4f61712010-09-07 16:34:47 +0000157 if (mutate_arg && (len <= IOCTL_BUFSZ)) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000158 memcpy(str, buf, len);
159 }
160 if (ret < 0) {
161 PyErr_SetFromErrno(PyExc_IOError);
162 return NULL;
163 }
164 if (mutate_arg) {
165 return PyInt_FromLong(ret);
166 }
167 else {
168 return PyString_FromStringAndSize(buf, len);
169 }
170 }
Michael W. Hudsonf0089982003-03-03 12:29:42 +0000171
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000172 PyErr_Clear();
173 if (PyArg_ParseTuple(args, "O&Is#:ioctl",
174 conv_descriptor, &fd, &code, &str, &len)) {
175 if (len > IOCTL_BUFSZ) {
176 PyErr_SetString(PyExc_ValueError,
177 "ioctl string arg too long");
178 return NULL;
179 }
180 memcpy(buf, str, len);
181 buf[len] = '\0';
182 Py_BEGIN_ALLOW_THREADS
183 ret = ioctl(fd, code, buf);
184 Py_END_ALLOW_THREADS
185 if (ret < 0) {
186 PyErr_SetFromErrno(PyExc_IOError);
187 return NULL;
188 }
189 return PyString_FromStringAndSize(buf, len);
190 }
Guido van Rossum02975121992-08-17 08:55:12 +0000191
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000192 PyErr_Clear();
193 arg = 0;
194 if (!PyArg_ParseTuple(args,
195 "O&I|i;ioctl requires a file or file descriptor,"
196 " an integer and optionally an integer or buffer argument",
197 conv_descriptor, &fd, &code, &arg)) {
198 return NULL;
199 }
200 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000201#ifdef __VMS
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000202 ret = ioctl(fd, code, (void *)arg);
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000203#else
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000204 ret = ioctl(fd, code, arg);
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000205#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000206 Py_END_ALLOW_THREADS
207 if (ret < 0) {
208 PyErr_SetFromErrno(PyExc_IOError);
209 return NULL;
210 }
211 return PyInt_FromLong((long)ret);
Thomas Wouters6dbff332006-04-25 13:53:23 +0000212#undef IOCTL_BUFSZ
Guido van Rossum02975121992-08-17 08:55:12 +0000213}
214
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000215PyDoc_STRVAR(ioctl_doc,
R David Murraya6912192013-11-07 10:52:53 -0500216"ioctl(fd, op[, arg[, mutate_flag]])\n\
Guido van Rossum185ead61998-11-23 15:32:55 +0000217\n\
R David Murraya6912192013-11-07 10:52:53 -0500218Perform the operation op on file descriptor fd. The values used for op\n\
219are operating system dependent, and are available as constants in the\n\
220fcntl or termios library modules, using the same names as used in the\n\
221relevant C header files.\n\
Michael W. Hudsonf0089982003-03-03 12:29:42 +0000222\n\
223The argument arg is optional, and defaults to 0; it may be an int or a\n\
224buffer containing character data (most likely a string or an array). \n\
225\n\
226If the argument is a mutable buffer (such as an array) and if the\n\
227mutate_flag argument (which is only allowed in this case) is true then the\n\
228buffer is (in effect) passed to the operating system and changes made by\n\
229the OS will be reflected in the contents of the buffer after the call has\n\
230returned. The return value is the integer returned by the ioctl system\n\
231call.\n\
232\n\
233If the argument is a mutable buffer and the mutable_flag argument is not\n\
234passed or is false, the behavior is as if a string had been passed. This\n\
235behavior will change in future releases of Python.\n\
236\n\
237If the argument is an immutable buffer (most likely a string) then a copy\n\
238of the buffer is passed to the operating system and the return value is a\n\
239string of the same length containing whatever the operating system put in\n\
240the buffer. The length of the arg buffer in this case is not allowed to\n\
241exceed 1024 bytes.\n\
242\n\
243If the arg given is an integer or if none is specified, the result value is\n\
244an integer corresponding to the return value of the ioctl call in the C\n\
245code.");
Guido van Rossum185ead61998-11-23 15:32:55 +0000246
Guido van Rossum02975121992-08-17 08:55:12 +0000247
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000248/* flock(fd, operation) */
249
Roger E. Masse919213a1996-12-17 17:42:22 +0000250static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000251fcntl_flock(PyObject *self, PyObject *args)
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000252{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000253 int fd;
254 int code;
255 int ret;
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000256
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000257 if (!PyArg_ParseTuple(args, "O&i:flock",
258 conv_descriptor, &fd, &code))
259 return NULL;
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000260
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000261#ifdef HAVE_FLOCK
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000262 Py_BEGIN_ALLOW_THREADS
263 ret = flock(fd, code);
264 Py_END_ALLOW_THREADS
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000265#else
266
267#ifndef LOCK_SH
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000268#define LOCK_SH 1 /* shared lock */
269#define LOCK_EX 2 /* exclusive lock */
270#define LOCK_NB 4 /* don't block when locking */
271#define LOCK_UN 8 /* unlock */
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000272#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000273 {
274 struct flock l;
275 if (code == LOCK_UN)
276 l.l_type = F_UNLCK;
277 else if (code & LOCK_SH)
278 l.l_type = F_RDLCK;
279 else if (code & LOCK_EX)
280 l.l_type = F_WRLCK;
281 else {
282 PyErr_SetString(PyExc_ValueError,
283 "unrecognized flock argument");
284 return NULL;
285 }
286 l.l_whence = l.l_start = l.l_len = 0;
287 Py_BEGIN_ALLOW_THREADS
288 ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
289 Py_END_ALLOW_THREADS
290 }
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000291#endif /* HAVE_FLOCK */
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000292 if (ret < 0) {
293 PyErr_SetFromErrno(PyExc_IOError);
294 return NULL;
295 }
296 Py_INCREF(Py_None);
297 return Py_None;
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000298}
299
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000300PyDoc_STRVAR(flock_doc,
Guido van Rossum185ead61998-11-23 15:32:55 +0000301"flock(fd, operation)\n\
302\n\
303Perform the lock operation op on file descriptor fd. See the Unix \n\
Ned Deilyebca3a52013-10-02 12:20:18 -0700304manual page for flock(2) for details. (On some systems, this function is\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000305emulated using fcntl().)");
Guido van Rossum185ead61998-11-23 15:32:55 +0000306
307
Guido van Rossumc8643641996-09-11 23:17:20 +0000308/* lockf(fd, operation) */
Roger E. Masse919213a1996-12-17 17:42:22 +0000309static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000310fcntl_lockf(PyObject *self, PyObject *args)
Guido van Rossumc8643641996-09-11 23:17:20 +0000311{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000312 int fd, code, ret, whence = 0;
313 PyObject *lenobj = NULL, *startobj = NULL;
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000314
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000315 if (!PyArg_ParseTuple(args, "O&i|OOi:lockf",
316 conv_descriptor, &fd, &code,
317 &lenobj, &startobj, &whence))
318 return NULL;
Guido van Rossumc8643641996-09-11 23:17:20 +0000319
Andrew MacIntyre7bf68332002-03-03 02:59:16 +0000320#if defined(PYOS_OS2) && defined(PYCC_GCC)
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000321 PyErr_SetString(PyExc_NotImplementedError,
322 "lockf not supported on OS/2 (EMX)");
323 return NULL;
Andrew MacIntyre7bf68332002-03-03 02:59:16 +0000324#else
Guido van Rossumc8643641996-09-11 23:17:20 +0000325#ifndef LOCK_SH
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000326#define LOCK_SH 1 /* shared lock */
327#define LOCK_EX 2 /* exclusive lock */
328#define LOCK_NB 4 /* don't block when locking */
329#define LOCK_UN 8 /* unlock */
Andrew MacIntyre7bf68332002-03-03 02:59:16 +0000330#endif /* LOCK_SH */
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000331 {
332 struct flock l;
333 if (code == LOCK_UN)
334 l.l_type = F_UNLCK;
335 else if (code & LOCK_SH)
336 l.l_type = F_RDLCK;
337 else if (code & LOCK_EX)
338 l.l_type = F_WRLCK;
339 else {
340 PyErr_SetString(PyExc_ValueError,
341 "unrecognized lockf argument");
342 return NULL;
343 }
344 l.l_start = l.l_len = 0;
345 if (startobj != NULL) {
Guido van Rossum056bad91999-01-06 18:44:23 +0000346#if !defined(HAVE_LARGEFILE_SUPPORT)
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000347 l.l_start = PyInt_AsLong(startobj);
Guido van Rossum056bad91999-01-06 18:44:23 +0000348#else
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000349 l.l_start = PyLong_Check(startobj) ?
350 PyLong_AsLongLong(startobj) :
351 PyInt_AsLong(startobj);
Guido van Rossum056bad91999-01-06 18:44:23 +0000352#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000353 if (PyErr_Occurred())
354 return NULL;
355 }
356 if (lenobj != NULL) {
Guido van Rossum056bad91999-01-06 18:44:23 +0000357#if !defined(HAVE_LARGEFILE_SUPPORT)
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000358 l.l_len = PyInt_AsLong(lenobj);
Guido van Rossum056bad91999-01-06 18:44:23 +0000359#else
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000360 l.l_len = PyLong_Check(lenobj) ?
361 PyLong_AsLongLong(lenobj) :
362 PyInt_AsLong(lenobj);
Guido van Rossum056bad91999-01-06 18:44:23 +0000363#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000364 if (PyErr_Occurred())
365 return NULL;
366 }
367 l.l_whence = whence;
368 Py_BEGIN_ALLOW_THREADS
369 ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
370 Py_END_ALLOW_THREADS
371 }
372 if (ret < 0) {
373 PyErr_SetFromErrno(PyExc_IOError);
374 return NULL;
375 }
376 Py_INCREF(Py_None);
377 return Py_None;
Andrew MacIntyre7bf68332002-03-03 02:59:16 +0000378#endif /* defined(PYOS_OS2) && defined(PYCC_GCC) */
Guido van Rossumc8643641996-09-11 23:17:20 +0000379}
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000380
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000381PyDoc_STRVAR(lockf_doc,
Sjoerd Mullender82e00d62001-01-25 10:10:39 +0000382"lockf (fd, operation, length=0, start=0, whence=0)\n\
383\n\
384This is essentially a wrapper around the fcntl() locking calls. fd is the\n\
385file descriptor of the file to lock or unlock, and operation is one of the\n\
386following values:\n\
387\n\
388 LOCK_UN - unlock\n\
389 LOCK_SH - acquire a shared lock\n\
390 LOCK_EX - acquire an exclusive lock\n\
391\n\
Georg Brandlf725b952008-01-05 19:44:22 +0000392When operation is LOCK_SH or LOCK_EX, it can also be bitwise ORed with\n\
Sjoerd Mullender82e00d62001-01-25 10:10:39 +0000393LOCK_NB to avoid blocking on lock acquisition. If LOCK_NB is used and the\n\
394lock cannot be acquired, an IOError will be raised and the exception will\n\
395have an errno attribute set to EACCES or EAGAIN (depending on the operating\n\
396system -- for portability, check for either value).\n\
397\n\
398length is the number of bytes to lock, with the default meaning to lock to\n\
399EOF. start is the byte offset, relative to whence, to that the lock\n\
400starts. whence is as with fileobj.seek(), specifically:\n\
401\n\
402 0 - relative to the start of the file (SEEK_SET)\n\
403 1 - relative to the current buffer position (SEEK_CUR)\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000404 2 - relative to the end of the file (SEEK_END)");
Guido van Rossum185ead61998-11-23 15:32:55 +0000405
Guido van Rossum02975121992-08-17 08:55:12 +0000406/* List of functions */
407
Roger E. Masse919213a1996-12-17 17:42:22 +0000408static PyMethodDef fcntl_methods[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000409 {"fcntl", fcntl_fcntl, METH_VARARGS, fcntl_doc},
410 {"ioctl", fcntl_ioctl, METH_VARARGS, ioctl_doc},
411 {"flock", fcntl_flock, METH_VARARGS, flock_doc},
412 {"lockf", fcntl_lockf, METH_VARARGS, lockf_doc},
413 {NULL, NULL} /* sentinel */
Guido van Rossum02975121992-08-17 08:55:12 +0000414};
415
416
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000417PyDoc_STRVAR(module_doc,
Guido van Rossum185ead61998-11-23 15:32:55 +0000418"This module performs file control and I/O control on file \n\
419descriptors. It is an interface to the fcntl() and ioctl() Unix\n\
420routines. File descriptors can be obtained with the fileno() method of\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000421a file or socket object.");
Guido van Rossum185ead61998-11-23 15:32:55 +0000422
Guido van Rossum02975121992-08-17 08:55:12 +0000423/* Module initialisation */
424
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000425static int
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000426ins(PyObject* d, char* symbol, long value)
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000427{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000428 PyObject* v = PyInt_FromLong(value);
429 if (!v || PyDict_SetItemString(d, symbol, v) < 0)
430 return -1;
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000431
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000432 Py_DECREF(v);
433 return 0;
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000434}
435
Martin v. Löwis14e73b12003-01-01 09:51:12 +0000436#define INS(x) if (ins(d, #x, (long)x)) return -1
437
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000438static int
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000439all_ins(PyObject* d)
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000440{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000441 if (ins(d, "LOCK_SH", (long)LOCK_SH)) return -1;
442 if (ins(d, "LOCK_EX", (long)LOCK_EX)) return -1;
443 if (ins(d, "LOCK_NB", (long)LOCK_NB)) return -1;
444 if (ins(d, "LOCK_UN", (long)LOCK_UN)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000445/* GNU extensions, as of glibc 2.2.4 */
446#ifdef LOCK_MAND
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000447 if (ins(d, "LOCK_MAND", (long)LOCK_MAND)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000448#endif
449#ifdef LOCK_READ
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000450 if (ins(d, "LOCK_READ", (long)LOCK_READ)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000451#endif
452#ifdef LOCK_WRITE
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000453 if (ins(d, "LOCK_WRITE", (long)LOCK_WRITE)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000454#endif
455#ifdef LOCK_RW
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000456 if (ins(d, "LOCK_RW", (long)LOCK_RW)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000457#endif
458
Fred Drake152a25e2001-05-09 21:02:02 +0000459#ifdef F_DUPFD
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000460 if (ins(d, "F_DUPFD", (long)F_DUPFD)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000461#endif
462#ifdef F_GETFD
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000463 if (ins(d, "F_GETFD", (long)F_GETFD)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000464#endif
465#ifdef F_SETFD
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000466 if (ins(d, "F_SETFD", (long)F_SETFD)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000467#endif
468#ifdef F_GETFL
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000469 if (ins(d, "F_GETFL", (long)F_GETFL)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000470#endif
471#ifdef F_SETFL
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000472 if (ins(d, "F_SETFL", (long)F_SETFL)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000473#endif
474#ifdef F_GETLK
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000475 if (ins(d, "F_GETLK", (long)F_GETLK)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000476#endif
477#ifdef F_SETLK
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000478 if (ins(d, "F_SETLK", (long)F_SETLK)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000479#endif
480#ifdef F_SETLKW
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000481 if (ins(d, "F_SETLKW", (long)F_SETLKW)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000482#endif
483#ifdef F_GETOWN
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000484 if (ins(d, "F_GETOWN", (long)F_GETOWN)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000485#endif
486#ifdef F_SETOWN
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000487 if (ins(d, "F_SETOWN", (long)F_SETOWN)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000488#endif
489#ifdef F_GETSIG
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000490 if (ins(d, "F_GETSIG", (long)F_GETSIG)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000491#endif
492#ifdef F_SETSIG
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000493 if (ins(d, "F_SETSIG", (long)F_SETSIG)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000494#endif
495#ifdef F_RDLCK
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000496 if (ins(d, "F_RDLCK", (long)F_RDLCK)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000497#endif
498#ifdef F_WRLCK
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000499 if (ins(d, "F_WRLCK", (long)F_WRLCK)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000500#endif
501#ifdef F_UNLCK
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000502 if (ins(d, "F_UNLCK", (long)F_UNLCK)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000503#endif
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000504/* LFS constants */
505#ifdef F_GETLK64
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000506 if (ins(d, "F_GETLK64", (long)F_GETLK64)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000507#endif
508#ifdef F_SETLK64
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000509 if (ins(d, "F_SETLK64", (long)F_SETLK64)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000510#endif
511#ifdef F_SETLKW64
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000512 if (ins(d, "F_SETLKW64", (long)F_SETLKW64)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000513#endif
514/* GNU extensions, as of glibc 2.2.4. */
Georg Brandl5049a852008-05-16 13:10:15 +0000515#ifdef FASYNC
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000516 if (ins(d, "FASYNC", (long)FASYNC)) return -1;
Georg Brandl5049a852008-05-16 13:10:15 +0000517#endif
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000518#ifdef F_SETLEASE
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000519 if (ins(d, "F_SETLEASE", (long)F_SETLEASE)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000520#endif
521#ifdef F_GETLEASE
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000522 if (ins(d, "F_GETLEASE", (long)F_GETLEASE)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000523#endif
524#ifdef F_NOTIFY
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000525 if (ins(d, "F_NOTIFY", (long)F_NOTIFY)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000526#endif
527/* Old BSD flock(). */
528#ifdef F_EXLCK
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000529 if (ins(d, "F_EXLCK", (long)F_EXLCK)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000530#endif
531#ifdef F_SHLCK
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000532 if (ins(d, "F_SHLCK", (long)F_SHLCK)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000533#endif
534
Guido van Rossumd6939012008-08-07 18:51:38 +0000535/* OS X (and maybe others) let you tell the storage device to flush to physical media */
536#ifdef F_FULLFSYNC
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000537 if (ins(d, "F_FULLFSYNC", (long)F_FULLFSYNC)) return -1;
Guido van Rossumd6939012008-08-07 18:51:38 +0000538#endif
539
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000540/* For F_{GET|SET}FL */
541#ifdef FD_CLOEXEC
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000542 if (ins(d, "FD_CLOEXEC", (long)FD_CLOEXEC)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000543#endif
544
545/* For F_NOTIFY */
546#ifdef DN_ACCESS
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000547 if (ins(d, "DN_ACCESS", (long)DN_ACCESS)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000548#endif
549#ifdef DN_MODIFY
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000550 if (ins(d, "DN_MODIFY", (long)DN_MODIFY)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000551#endif
552#ifdef DN_CREATE
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000553 if (ins(d, "DN_CREATE", (long)DN_CREATE)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000554#endif
555#ifdef DN_DELETE
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000556 if (ins(d, "DN_DELETE", (long)DN_DELETE)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000557#endif
558#ifdef DN_RENAME
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000559 if (ins(d, "DN_RENAME", (long)DN_RENAME)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000560#endif
561#ifdef DN_ATTRIB
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000562 if (ins(d, "DN_ATTRIB", (long)DN_ATTRIB)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000563#endif
564#ifdef DN_MULTISHOT
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000565 if (ins(d, "DN_MULTISHOT", (long)DN_MULTISHOT)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000566#endif
567
Martin v. Löwis14e73b12003-01-01 09:51:12 +0000568#ifdef HAVE_STROPTS_H
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000569 /* Unix 98 guarantees that these are in stropts.h. */
570 INS(I_PUSH);
571 INS(I_POP);
572 INS(I_LOOK);
573 INS(I_FLUSH);
574 INS(I_FLUSHBAND);
575 INS(I_SETSIG);
576 INS(I_GETSIG);
577 INS(I_FIND);
578 INS(I_PEEK);
579 INS(I_SRDOPT);
580 INS(I_GRDOPT);
581 INS(I_NREAD);
582 INS(I_FDINSERT);
583 INS(I_STR);
584 INS(I_SWROPT);
Michael W. Hudson505c4c22003-05-09 10:45:20 +0000585#ifdef I_GWROPT
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000586 /* despite the comment above, old-ish glibcs miss a couple... */
587 INS(I_GWROPT);
Michael W. Hudson505c4c22003-05-09 10:45:20 +0000588#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000589 INS(I_SENDFD);
590 INS(I_RECVFD);
591 INS(I_LIST);
592 INS(I_ATMARK);
593 INS(I_CKBAND);
594 INS(I_GETBAND);
595 INS(I_CANPUT);
596 INS(I_SETCLTIME);
Michael W. Hudson505c4c22003-05-09 10:45:20 +0000597#ifdef I_GETCLTIME
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000598 INS(I_GETCLTIME);
Michael W. Hudson505c4c22003-05-09 10:45:20 +0000599#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000600 INS(I_LINK);
601 INS(I_UNLINK);
602 INS(I_PLINK);
603 INS(I_PUNLINK);
Martin v. Löwis14e73b12003-01-01 09:51:12 +0000604#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000605
606 return 0;
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000607}
608
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000609PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000610initfcntl(void)
Guido van Rossum02975121992-08-17 08:55:12 +0000611{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000612 PyObject *m, *d;
Guido van Rossum02975121992-08-17 08:55:12 +0000613
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000614 /* Create the module and add the functions and documentation */
615 m = Py_InitModule3("fcntl", fcntl_methods, module_doc);
616 if (m == NULL)
617 return;
Guido van Rossum02975121992-08-17 08:55:12 +0000618
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000619 /* Add some symbolic constants to the module */
620 d = PyModule_GetDict(m);
621 all_ins(d);
Guido van Rossum02975121992-08-17 08:55:12 +0000622}