blob: bfc59855dd9834c201377463b708c5ff8fe18143 [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
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 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,
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 Brandl1f94cd02010-09-05 17:09:18 +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 Brandl1f94cd02010-09-05 17:09:18 +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 Wouters477c8d52006-05-27 19:21:47 +000098#define IOCTL_BUFSZ 1024
Antoine Pitrouf95a1b32010-05-09 15:52:27 +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.
Christian Heimese25f35e2008-03-20 10:49:03 +0000108
Antoine Pitrouf95a1b32010-05-09 15:52:27 +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 Py_buffer pstr;
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 Pitrouf95a1b32010-05-09 15:52:27 +0000122 if (PyArg_ParseTuple(args, "O&Iw*|i:ioctl",
123 conv_descriptor, &fd, &code,
124 &pstr, &mutate_arg)) {
125 char *arg;
126 str = pstr.buf;
127 len = pstr.len;
Michael W. Hudsonf0089982003-03-03 12:29:42 +0000128
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000129 if (mutate_arg) {
130 if (len <= IOCTL_BUFSZ) {
131 memcpy(buf, str, len);
132 buf[len] = '\0';
133 arg = buf;
134 }
135 else {
136 arg = str;
137 }
138 }
139 else {
140 if (len > IOCTL_BUFSZ) {
141 PyBuffer_Release(&pstr);
142 PyErr_SetString(PyExc_ValueError,
143 "ioctl string arg too long");
144 return NULL;
145 }
146 else {
147 memcpy(buf, str, len);
148 buf[len] = '\0';
149 arg = buf;
150 }
151 }
152 if (buf == arg) {
153 Py_BEGIN_ALLOW_THREADS /* think array.resize() */
154 ret = ioctl(fd, code, arg);
155 Py_END_ALLOW_THREADS
156 }
157 else {
158 ret = ioctl(fd, code, arg);
159 }
Antoine Pitrou5e38aae2010-09-07 16:30:09 +0000160 if (mutate_arg && (len <= IOCTL_BUFSZ)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000161 memcpy(str, buf, len);
162 }
163 PyBuffer_Release(&pstr); /* No further access to str below this point */
164 if (ret < 0) {
165 PyErr_SetFromErrno(PyExc_IOError);
166 return NULL;
167 }
168 if (mutate_arg) {
169 return PyLong_FromLong(ret);
170 }
171 else {
172 return PyBytes_FromStringAndSize(buf, len);
173 }
174 }
Michael W. Hudsonf0089982003-03-03 12:29:42 +0000175
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000176 PyErr_Clear();
177 if (PyArg_ParseTuple(args, "O&Is*:ioctl",
178 conv_descriptor, &fd, &code, &pstr)) {
179 str = pstr.buf;
180 len = pstr.len;
181 if (len > IOCTL_BUFSZ) {
182 PyBuffer_Release(&pstr);
183 PyErr_SetString(PyExc_ValueError,
184 "ioctl string arg too long");
185 return NULL;
186 }
187 memcpy(buf, str, len);
188 buf[len] = '\0';
189 Py_BEGIN_ALLOW_THREADS
190 ret = ioctl(fd, code, buf);
191 Py_END_ALLOW_THREADS
192 if (ret < 0) {
193 PyBuffer_Release(&pstr);
194 PyErr_SetFromErrno(PyExc_IOError);
195 return NULL;
196 }
197 PyBuffer_Release(&pstr);
198 return PyBytes_FromStringAndSize(buf, len);
199 }
Guido van Rossum02975121992-08-17 08:55:12 +0000200
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000201 PyErr_Clear();
202 arg = 0;
203 if (!PyArg_ParseTuple(args,
204 "O&I|i;ioctl requires a file or file descriptor,"
205 " an integer and optionally an integer or buffer argument",
206 conv_descriptor, &fd, &code, &arg)) {
207 return NULL;
208 }
209 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000210#ifdef __VMS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000211 ret = ioctl(fd, code, (void *)arg);
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000212#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000213 ret = ioctl(fd, code, arg);
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000214#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000215 Py_END_ALLOW_THREADS
216 if (ret < 0) {
217 PyErr_SetFromErrno(PyExc_IOError);
218 return NULL;
219 }
220 return PyLong_FromLong((long)ret);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000221#undef IOCTL_BUFSZ
Guido van Rossum02975121992-08-17 08:55:12 +0000222}
223
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000224PyDoc_STRVAR(ioctl_doc,
Michael W. Hudsonf0089982003-03-03 12:29:42 +0000225"ioctl(fd, opt[, arg[, mutate_flag]])\n\
Guido van Rossum185ead61998-11-23 15:32:55 +0000226\n\
Michael W. Hudsonf0089982003-03-03 12:29:42 +0000227Perform the requested operation on file descriptor fd. The operation is\n\
Neal Norwitz47308802003-06-30 01:54:04 +0000228defined by opt and is operating system dependent. Typically these codes are\n\
Michael W. Hudsonf0089982003-03-03 12:29:42 +0000229retrieved from the fcntl or termios library modules.\n\
230\n\
231The argument arg is optional, and defaults to 0; it may be an int or a\n\
232buffer containing character data (most likely a string or an array). \n\
233\n\
234If the argument is a mutable buffer (such as an array) and if the\n\
235mutate_flag argument (which is only allowed in this case) is true then the\n\
236buffer is (in effect) passed to the operating system and changes made by\n\
237the OS will be reflected in the contents of the buffer after the call has\n\
238returned. The return value is the integer returned by the ioctl system\n\
239call.\n\
240\n\
241If the argument is a mutable buffer and the mutable_flag argument is not\n\
242passed or is false, the behavior is as if a string had been passed. This\n\
243behavior will change in future releases of Python.\n\
244\n\
245If the argument is an immutable buffer (most likely a string) then a copy\n\
246of the buffer is passed to the operating system and the return value is a\n\
247string of the same length containing whatever the operating system put in\n\
248the buffer. The length of the arg buffer in this case is not allowed to\n\
249exceed 1024 bytes.\n\
250\n\
251If the arg given is an integer or if none is specified, the result value is\n\
252an integer corresponding to the return value of the ioctl call in the C\n\
253code.");
Guido van Rossum185ead61998-11-23 15:32:55 +0000254
Guido van Rossum02975121992-08-17 08:55:12 +0000255
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000256/* flock(fd, operation) */
257
Roger E. Masse919213a1996-12-17 17:42:22 +0000258static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000259fcntl_flock(PyObject *self, PyObject *args)
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000260{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000261 int fd;
262 int code;
263 int ret;
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000264
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000265 if (!PyArg_ParseTuple(args, "O&i:flock",
266 conv_descriptor, &fd, &code))
267 return NULL;
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000268
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000269#ifdef HAVE_FLOCK
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000270 Py_BEGIN_ALLOW_THREADS
271 ret = flock(fd, code);
272 Py_END_ALLOW_THREADS
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000273#else
274
275#ifndef LOCK_SH
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000276#define LOCK_SH 1 /* shared lock */
277#define LOCK_EX 2 /* exclusive lock */
278#define LOCK_NB 4 /* don't block when locking */
279#define LOCK_UN 8 /* unlock */
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000280#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000281 {
282 struct flock l;
283 if (code == LOCK_UN)
284 l.l_type = F_UNLCK;
285 else if (code & LOCK_SH)
286 l.l_type = F_RDLCK;
287 else if (code & LOCK_EX)
288 l.l_type = F_WRLCK;
289 else {
290 PyErr_SetString(PyExc_ValueError,
291 "unrecognized flock argument");
292 return NULL;
293 }
294 l.l_whence = l.l_start = l.l_len = 0;
295 Py_BEGIN_ALLOW_THREADS
296 ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
297 Py_END_ALLOW_THREADS
298 }
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000299#endif /* HAVE_FLOCK */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000300 if (ret < 0) {
301 PyErr_SetFromErrno(PyExc_IOError);
302 return NULL;
303 }
304 Py_INCREF(Py_None);
305 return Py_None;
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000306}
307
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000308PyDoc_STRVAR(flock_doc,
Guido van Rossum185ead61998-11-23 15:32:55 +0000309"flock(fd, operation)\n\
310\n\
311Perform the lock operation op on file descriptor fd. See the Unix \n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000312manual page for flock(3) for details. (On some systems, this function is\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000313emulated using fcntl().)");
Guido van Rossum185ead61998-11-23 15:32:55 +0000314
315
Guido van Rossumc8643641996-09-11 23:17:20 +0000316/* lockf(fd, operation) */
Roger E. Masse919213a1996-12-17 17:42:22 +0000317static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000318fcntl_lockf(PyObject *self, PyObject *args)
Guido van Rossumc8643641996-09-11 23:17:20 +0000319{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000320 int fd, code, ret, whence = 0;
321 PyObject *lenobj = NULL, *startobj = NULL;
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000322
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000323 if (!PyArg_ParseTuple(args, "O&i|OOi:lockf",
324 conv_descriptor, &fd, &code,
325 &lenobj, &startobj, &whence))
326 return NULL;
Guido van Rossumc8643641996-09-11 23:17:20 +0000327
Andrew MacIntyre7bf68332002-03-03 02:59:16 +0000328#if defined(PYOS_OS2) && defined(PYCC_GCC)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000329 PyErr_SetString(PyExc_NotImplementedError,
330 "lockf not supported on OS/2 (EMX)");
331 return NULL;
Andrew MacIntyre7bf68332002-03-03 02:59:16 +0000332#else
Guido van Rossumc8643641996-09-11 23:17:20 +0000333#ifndef LOCK_SH
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000334#define LOCK_SH 1 /* shared lock */
335#define LOCK_EX 2 /* exclusive lock */
336#define LOCK_NB 4 /* don't block when locking */
337#define LOCK_UN 8 /* unlock */
Andrew MacIntyre7bf68332002-03-03 02:59:16 +0000338#endif /* LOCK_SH */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000339 {
340 struct flock l;
341 if (code == LOCK_UN)
342 l.l_type = F_UNLCK;
343 else if (code & LOCK_SH)
344 l.l_type = F_RDLCK;
345 else if (code & LOCK_EX)
346 l.l_type = F_WRLCK;
347 else {
348 PyErr_SetString(PyExc_ValueError,
349 "unrecognized lockf argument");
350 return NULL;
351 }
352 l.l_start = l.l_len = 0;
353 if (startobj != NULL) {
Guido van Rossum056bad91999-01-06 18:44:23 +0000354#if !defined(HAVE_LARGEFILE_SUPPORT)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000355 l.l_start = PyLong_AsLong(startobj);
Guido van Rossum056bad91999-01-06 18:44:23 +0000356#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000357 l.l_start = PyLong_Check(startobj) ?
358 PyLong_AsLongLong(startobj) :
359 PyLong_AsLong(startobj);
Guido van Rossum056bad91999-01-06 18:44:23 +0000360#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000361 if (PyErr_Occurred())
362 return NULL;
363 }
364 if (lenobj != NULL) {
Guido van Rossum056bad91999-01-06 18:44:23 +0000365#if !defined(HAVE_LARGEFILE_SUPPORT)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000366 l.l_len = PyLong_AsLong(lenobj);
Guido van Rossum056bad91999-01-06 18:44:23 +0000367#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000368 l.l_len = PyLong_Check(lenobj) ?
369 PyLong_AsLongLong(lenobj) :
370 PyLong_AsLong(lenobj);
Guido van Rossum056bad91999-01-06 18:44:23 +0000371#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000372 if (PyErr_Occurred())
373 return NULL;
374 }
375 l.l_whence = whence;
376 Py_BEGIN_ALLOW_THREADS
377 ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
378 Py_END_ALLOW_THREADS
379 }
380 if (ret < 0) {
381 PyErr_SetFromErrno(PyExc_IOError);
382 return NULL;
383 }
384 Py_INCREF(Py_None);
385 return Py_None;
Andrew MacIntyre7bf68332002-03-03 02:59:16 +0000386#endif /* defined(PYOS_OS2) && defined(PYCC_GCC) */
Guido van Rossumc8643641996-09-11 23:17:20 +0000387}
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000388
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000389PyDoc_STRVAR(lockf_doc,
Sjoerd Mullender82e00d62001-01-25 10:10:39 +0000390"lockf (fd, operation, length=0, start=0, whence=0)\n\
391\n\
392This is essentially a wrapper around the fcntl() locking calls. fd is the\n\
393file descriptor of the file to lock or unlock, and operation is one of the\n\
394following values:\n\
395\n\
396 LOCK_UN - unlock\n\
397 LOCK_SH - acquire a shared lock\n\
398 LOCK_EX - acquire an exclusive lock\n\
399\n\
Christian Heimesfaf2f632008-01-06 16:59:19 +0000400When operation is LOCK_SH or LOCK_EX, it can also be bitwise ORed with\n\
Sjoerd Mullender82e00d62001-01-25 10:10:39 +0000401LOCK_NB to avoid blocking on lock acquisition. If LOCK_NB is used and the\n\
402lock cannot be acquired, an IOError will be raised and the exception will\n\
403have an errno attribute set to EACCES or EAGAIN (depending on the operating\n\
404system -- for portability, check for either value).\n\
405\n\
406length is the number of bytes to lock, with the default meaning to lock to\n\
407EOF. start is the byte offset, relative to whence, to that the lock\n\
408starts. whence is as with fileobj.seek(), specifically:\n\
409\n\
410 0 - relative to the start of the file (SEEK_SET)\n\
411 1 - relative to the current buffer position (SEEK_CUR)\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000412 2 - relative to the end of the file (SEEK_END)");
Guido van Rossum185ead61998-11-23 15:32:55 +0000413
Guido van Rossum02975121992-08-17 08:55:12 +0000414/* List of functions */
415
Roger E. Masse919213a1996-12-17 17:42:22 +0000416static PyMethodDef fcntl_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000417 {"fcntl", fcntl_fcntl, METH_VARARGS, fcntl_doc},
418 {"ioctl", fcntl_ioctl, METH_VARARGS, ioctl_doc},
419 {"flock", fcntl_flock, METH_VARARGS, flock_doc},
420 {"lockf", fcntl_lockf, METH_VARARGS, lockf_doc},
421 {NULL, NULL} /* sentinel */
Guido van Rossum02975121992-08-17 08:55:12 +0000422};
423
424
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000425PyDoc_STRVAR(module_doc,
Guido van Rossum185ead61998-11-23 15:32:55 +0000426"This module performs file control and I/O control on file \n\
427descriptors. It is an interface to the fcntl() and ioctl() Unix\n\
428routines. File descriptors can be obtained with the fileno() method of\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000429a file or socket object.");
Guido van Rossum185ead61998-11-23 15:32:55 +0000430
Guido van Rossum02975121992-08-17 08:55:12 +0000431/* Module initialisation */
432
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000433static int
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000434ins(PyObject* d, char* symbol, long value)
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000435{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000436 PyObject* v = PyLong_FromLong(value);
437 if (!v || PyDict_SetItemString(d, symbol, v) < 0)
438 return -1;
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000439
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000440 Py_DECREF(v);
441 return 0;
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000442}
443
Martin v. Löwis14e73b12003-01-01 09:51:12 +0000444#define INS(x) if (ins(d, #x, (long)x)) return -1
445
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000446static int
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000447all_ins(PyObject* d)
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000448{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000449 if (ins(d, "LOCK_SH", (long)LOCK_SH)) return -1;
450 if (ins(d, "LOCK_EX", (long)LOCK_EX)) return -1;
451 if (ins(d, "LOCK_NB", (long)LOCK_NB)) return -1;
452 if (ins(d, "LOCK_UN", (long)LOCK_UN)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000453/* GNU extensions, as of glibc 2.2.4 */
454#ifdef LOCK_MAND
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000455 if (ins(d, "LOCK_MAND", (long)LOCK_MAND)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000456#endif
457#ifdef LOCK_READ
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000458 if (ins(d, "LOCK_READ", (long)LOCK_READ)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000459#endif
460#ifdef LOCK_WRITE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000461 if (ins(d, "LOCK_WRITE", (long)LOCK_WRITE)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000462#endif
463#ifdef LOCK_RW
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000464 if (ins(d, "LOCK_RW", (long)LOCK_RW)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000465#endif
466
Fred Drake152a25e2001-05-09 21:02:02 +0000467#ifdef F_DUPFD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000468 if (ins(d, "F_DUPFD", (long)F_DUPFD)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000469#endif
470#ifdef F_GETFD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000471 if (ins(d, "F_GETFD", (long)F_GETFD)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000472#endif
473#ifdef F_SETFD
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000474 if (ins(d, "F_SETFD", (long)F_SETFD)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000475#endif
476#ifdef F_GETFL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000477 if (ins(d, "F_GETFL", (long)F_GETFL)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000478#endif
479#ifdef F_SETFL
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000480 if (ins(d, "F_SETFL", (long)F_SETFL)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000481#endif
482#ifdef F_GETLK
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000483 if (ins(d, "F_GETLK", (long)F_GETLK)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000484#endif
485#ifdef F_SETLK
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000486 if (ins(d, "F_SETLK", (long)F_SETLK)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000487#endif
488#ifdef F_SETLKW
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000489 if (ins(d, "F_SETLKW", (long)F_SETLKW)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000490#endif
491#ifdef F_GETOWN
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000492 if (ins(d, "F_GETOWN", (long)F_GETOWN)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000493#endif
494#ifdef F_SETOWN
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000495 if (ins(d, "F_SETOWN", (long)F_SETOWN)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000496#endif
497#ifdef F_GETSIG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000498 if (ins(d, "F_GETSIG", (long)F_GETSIG)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000499#endif
500#ifdef F_SETSIG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000501 if (ins(d, "F_SETSIG", (long)F_SETSIG)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000502#endif
503#ifdef F_RDLCK
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000504 if (ins(d, "F_RDLCK", (long)F_RDLCK)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000505#endif
506#ifdef F_WRLCK
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000507 if (ins(d, "F_WRLCK", (long)F_WRLCK)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000508#endif
509#ifdef F_UNLCK
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000510 if (ins(d, "F_UNLCK", (long)F_UNLCK)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000511#endif
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000512/* LFS constants */
513#ifdef F_GETLK64
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000514 if (ins(d, "F_GETLK64", (long)F_GETLK64)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000515#endif
516#ifdef F_SETLK64
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000517 if (ins(d, "F_SETLK64", (long)F_SETLK64)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000518#endif
519#ifdef F_SETLKW64
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000520 if (ins(d, "F_SETLKW64", (long)F_SETLKW64)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000521#endif
522/* GNU extensions, as of glibc 2.2.4. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +0000523#ifdef FASYNC
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000524 if (ins(d, "FASYNC", (long)FASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +0000525#endif
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000526#ifdef F_SETLEASE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000527 if (ins(d, "F_SETLEASE", (long)F_SETLEASE)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000528#endif
529#ifdef F_GETLEASE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000530 if (ins(d, "F_GETLEASE", (long)F_GETLEASE)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000531#endif
532#ifdef F_NOTIFY
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000533 if (ins(d, "F_NOTIFY", (long)F_NOTIFY)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000534#endif
535/* Old BSD flock(). */
536#ifdef F_EXLCK
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000537 if (ins(d, "F_EXLCK", (long)F_EXLCK)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000538#endif
539#ifdef F_SHLCK
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000540 if (ins(d, "F_SHLCK", (long)F_SHLCK)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000541#endif
542
Georg Brandl6aa2d1f2008-08-12 08:35:52 +0000543/* OS X (and maybe others) let you tell the storage device to flush to physical media */
544#ifdef F_FULLFSYNC
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000545 if (ins(d, "F_FULLFSYNC", (long)F_FULLFSYNC)) return -1;
Georg Brandl6aa2d1f2008-08-12 08:35:52 +0000546#endif
547
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000548/* For F_{GET|SET}FL */
549#ifdef FD_CLOEXEC
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000550 if (ins(d, "FD_CLOEXEC", (long)FD_CLOEXEC)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000551#endif
552
553/* For F_NOTIFY */
554#ifdef DN_ACCESS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000555 if (ins(d, "DN_ACCESS", (long)DN_ACCESS)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000556#endif
557#ifdef DN_MODIFY
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000558 if (ins(d, "DN_MODIFY", (long)DN_MODIFY)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000559#endif
560#ifdef DN_CREATE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000561 if (ins(d, "DN_CREATE", (long)DN_CREATE)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000562#endif
563#ifdef DN_DELETE
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000564 if (ins(d, "DN_DELETE", (long)DN_DELETE)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000565#endif
566#ifdef DN_RENAME
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000567 if (ins(d, "DN_RENAME", (long)DN_RENAME)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000568#endif
569#ifdef DN_ATTRIB
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000570 if (ins(d, "DN_ATTRIB", (long)DN_ATTRIB)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000571#endif
572#ifdef DN_MULTISHOT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000573 if (ins(d, "DN_MULTISHOT", (long)DN_MULTISHOT)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000574#endif
575
Martin v. Löwis14e73b12003-01-01 09:51:12 +0000576#ifdef HAVE_STROPTS_H
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000577 /* Unix 98 guarantees that these are in stropts.h. */
578 INS(I_PUSH);
579 INS(I_POP);
580 INS(I_LOOK);
581 INS(I_FLUSH);
582 INS(I_FLUSHBAND);
583 INS(I_SETSIG);
584 INS(I_GETSIG);
585 INS(I_FIND);
586 INS(I_PEEK);
587 INS(I_SRDOPT);
588 INS(I_GRDOPT);
589 INS(I_NREAD);
590 INS(I_FDINSERT);
591 INS(I_STR);
592 INS(I_SWROPT);
Michael W. Hudson505c4c22003-05-09 10:45:20 +0000593#ifdef I_GWROPT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000594 /* despite the comment above, old-ish glibcs miss a couple... */
595 INS(I_GWROPT);
Michael W. Hudson505c4c22003-05-09 10:45:20 +0000596#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000597 INS(I_SENDFD);
598 INS(I_RECVFD);
599 INS(I_LIST);
600 INS(I_ATMARK);
601 INS(I_CKBAND);
602 INS(I_GETBAND);
603 INS(I_CANPUT);
604 INS(I_SETCLTIME);
Michael W. Hudson505c4c22003-05-09 10:45:20 +0000605#ifdef I_GETCLTIME
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000606 INS(I_GETCLTIME);
Michael W. Hudson505c4c22003-05-09 10:45:20 +0000607#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000608 INS(I_LINK);
609 INS(I_UNLINK);
610 INS(I_PLINK);
611 INS(I_PUNLINK);
Martin v. Löwis14e73b12003-01-01 09:51:12 +0000612#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000613
614 return 0;
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000615}
616
Martin v. Löwis1a214512008-06-11 05:26:20 +0000617
618static struct PyModuleDef fcntlmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000619 PyModuleDef_HEAD_INIT,
620 "fcntl",
621 module_doc,
622 -1,
623 fcntl_methods,
624 NULL,
625 NULL,
626 NULL,
627 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +0000628};
629
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000630PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +0000631PyInit_fcntl(void)
Guido van Rossum02975121992-08-17 08:55:12 +0000632{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000633 PyObject *m, *d;
Guido van Rossum02975121992-08-17 08:55:12 +0000634
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000635 /* Create the module and add the functions and documentation */
636 m = PyModule_Create(&fcntlmodule);
637 if (m == NULL)
638 return NULL;
Guido van Rossum02975121992-08-17 08:55:12 +0000639
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000640 /* Add some symbolic constants to the module */
641 d = PyModule_GetDict(m);
642 all_ins(d);
643 return m;
Guido van Rossum02975121992-08-17 08:55:12 +0000644}