blob: 3cea1519deeda19811335b395d02bb13dddf7581 [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
Brett Cannonb7299dd2014-11-09 20:22:01 -050018/*[clinic input]
19output preset file
20module fcntl
21[clinic start generated code]*/
22/*[clinic end generated code: output=da39a3ee5e6b4b0d input=c7356fdb126a904a]*/
23
Fred Drake152a25e2001-05-09 21:02:02 +000024static int
25conv_descriptor(PyObject *object, int *target)
26{
27 int fd = PyObject_AsFileDescriptor(object);
28
29 if (fd < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000030 return 0;
Fred Drake152a25e2001-05-09 21:02:02 +000031 *target = fd;
32 return 1;
33}
34
Brett Cannonb7299dd2014-11-09 20:22:01 -050035/* Must come after conv_descriptor definition. */
36#include "clinic/fcntlmodule.c.h"
Fred Drake152a25e2001-05-09 21:02:02 +000037
Brett Cannonb7299dd2014-11-09 20:22:01 -050038/*[clinic input]
39fcntl.fcntl
40
41 fd: object(type='int', converter='conv_descriptor')
Serhiy Storchaka17d3a582015-03-20 20:04:21 +020042 cmd as code: int
43 arg: object(c_default='NULL') = 0
Brett Cannonb7299dd2014-11-09 20:22:01 -050044 /
45
Serhiy Storchaka17d3a582015-03-20 20:04:21 +020046Perform the operation `cmd` on file descriptor fd.
Brett Cannonb7299dd2014-11-09 20:22:01 -050047
Serhiy Storchaka17d3a582015-03-20 20:04:21 +020048The values used for `cmd` are operating system dependent, and are available
Brett Cannonb7299dd2014-11-09 20:22:01 -050049as constants in the fcntl module, using the same names as used in
50the relevant C header files. The argument arg is optional, and
51defaults to 0; it may be an int or a string. If arg is given as a string,
52the return value of fcntl is a string of that length, containing the
53resulting value put in the arg buffer by the operating system. The length
54of the arg string is not allowed to exceed 1024 bytes. If the arg given
55is an integer or if none is specified, the result value is an integer
56corresponding to the return value of the fcntl call in the C code.
57[clinic start generated code]*/
Guido van Rossum02975121992-08-17 08:55:12 +000058
Roger E. Masse919213a1996-12-17 17:42:22 +000059static PyObject *
Brett Cannonb7299dd2014-11-09 20:22:01 -050060fcntl_fcntl_impl(PyModuleDef *module, int fd, int code, PyObject *arg)
Serhiy Storchaka17d3a582015-03-20 20:04:21 +020061/*[clinic end generated code: output=afc5bfa74a03ef0d input=8cefbe59b29efbe2]*/
Guido van Rossum02975121992-08-17 08:55:12 +000062{
Serhiy Storchaka5a8dacf2014-11-10 11:25:50 +020063 unsigned int int_arg = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000064 int ret;
65 char *str;
66 Py_ssize_t len;
67 char buf[1024];
Guido van Rossum02975121992-08-17 08:55:12 +000068
Brett Cannonb7299dd2014-11-09 20:22:01 -050069 if (arg != NULL) {
70 int parse_result;
71
72 if (PyArg_Parse(arg, "s#", &str, &len)) {
73 if ((size_t)len > sizeof buf) {
74 PyErr_SetString(PyExc_ValueError,
75 "fcntl string arg too long");
76 return NULL;
77 }
78 memcpy(buf, str, len);
79 Py_BEGIN_ALLOW_THREADS
80 ret = fcntl(fd, code, buf);
81 Py_END_ALLOW_THREADS
82 if (ret < 0) {
83 PyErr_SetFromErrno(PyExc_IOError);
84 return NULL;
85 }
86 return PyBytes_FromStringAndSize(buf, len);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000087 }
Brett Cannonb7299dd2014-11-09 20:22:01 -050088
89 PyErr_Clear();
90 parse_result = PyArg_Parse(arg,
Serhiy Storchaka5a8dacf2014-11-10 11:25:50 +020091 "I;fcntl requires a file or file descriptor,"
Brett Cannonb7299dd2014-11-09 20:22:01 -050092 " an integer and optionally a third integer or a string",
93 &int_arg);
94 if (!parse_result) {
95 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000096 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000097 }
Guido van Rossum02975121992-08-17 08:55:12 +000098
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000099 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka5a8dacf2014-11-10 11:25:50 +0200100 ret = fcntl(fd, code, (int)int_arg);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000101 Py_END_ALLOW_THREADS
102 if (ret < 0) {
103 PyErr_SetFromErrno(PyExc_IOError);
104 return NULL;
105 }
106 return PyLong_FromLong((long)ret);
Guido van Rossum02975121992-08-17 08:55:12 +0000107}
108
Guido van Rossum185ead61998-11-23 15:32:55 +0000109
Brett Cannonb7299dd2014-11-09 20:22:01 -0500110/*[clinic input]
111fcntl.ioctl
Guido van Rossum02975121992-08-17 08:55:12 +0000112
Brett Cannonb7299dd2014-11-09 20:22:01 -0500113 fd: object(type='int', converter='conv_descriptor')
Serhiy Storchaka17d3a582015-03-20 20:04:21 +0200114 request as code: unsigned_int(bitwise=True)
115 arg as ob_arg: object(c_default='NULL') = 0
Brett Cannonb7299dd2014-11-09 20:22:01 -0500116 mutate_flag as mutate_arg: bool = True
117 /
118
Serhiy Storchaka17d3a582015-03-20 20:04:21 +0200119Perform the operation `request` on file descriptor `fd`.
Brett Cannonb7299dd2014-11-09 20:22:01 -0500120
Serhiy Storchaka17d3a582015-03-20 20:04:21 +0200121The values used for `request` are operating system dependent, and are available
122as constants in the fcntl or termios library modules, using the same names as
Brett Cannonb7299dd2014-11-09 20:22:01 -0500123used in the relevant C header files.
124
125The argument `arg` is optional, and defaults to 0; it may be an int or a
126buffer containing character data (most likely a string or an array).
127
128If the argument is a mutable buffer (such as an array) and if the
129mutate_flag argument (which is only allowed in this case) is true then the
130buffer is (in effect) passed to the operating system and changes made by
131the OS will be reflected in the contents of the buffer after the call has
132returned. The return value is the integer returned by the ioctl system
133call.
134
Serhiy Storchaka17d3a582015-03-20 20:04:21 +0200135If the argument is a mutable buffer and the mutable_flag argument is false,
136the behavior is as if a string had been passed.
Brett Cannonb7299dd2014-11-09 20:22:01 -0500137
138If the argument is an immutable buffer (most likely a string) then a copy
139of the buffer is passed to the operating system and the return value is a
140string of the same length containing whatever the operating system put in
141the buffer. The length of the arg buffer in this case is not allowed to
142exceed 1024 bytes.
143
144If the arg given is an integer or if none is specified, the result value is
145an integer corresponding to the return value of the ioctl call in the C
146code.
147[clinic start generated code]*/
Guido van Rossum02975121992-08-17 08:55:12 +0000148
Roger E. Masse919213a1996-12-17 17:42:22 +0000149static PyObject *
Brett Cannonb7299dd2014-11-09 20:22:01 -0500150fcntl_ioctl_impl(PyModuleDef *module, int fd, unsigned int code, PyObject *ob_arg, int mutate_arg)
Serhiy Storchaka17d3a582015-03-20 20:04:21 +0200151/*[clinic end generated code: output=ad47738c118622bf input=ede70c433cccbbb2]*/
Guido van Rossum02975121992-08-17 08:55:12 +0000152{
Thomas Wouters477c8d52006-05-27 19:21:47 +0000153#define IOCTL_BUFSZ 1024
Serhiy Storchaka483405b2015-02-17 10:14:30 +0200154 /* We use the unsigned non-checked 'I' format for the 'code' parameter
155 because the system expects it to be a 32bit bit field value
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000156 regardless of it being passed as an int or unsigned long on
157 various platforms. See the termios.TIOCSWINSZ constant across
R David Murrayd5a2f0b2013-11-07 10:51:07 -0500158 platforms for an example of this.
Christian Heimese25f35e2008-03-20 10:49:03 +0000159
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000160 If any of the 64bit platforms ever decide to use more than 32bits
161 in their unsigned long ioctl codes this will break and need
162 special casing based on the platform being built on.
163 */
Brett Cannonb7299dd2014-11-09 20:22:01 -0500164 int arg = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000165 int ret;
166 Py_buffer pstr;
167 char *str;
168 Py_ssize_t len;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000169 char buf[IOCTL_BUFSZ+1]; /* argument plus NUL byte */
Guido van Rossum02975121992-08-17 08:55:12 +0000170
Brett Cannonb7299dd2014-11-09 20:22:01 -0500171 if (ob_arg != NULL) {
172 if (PyArg_Parse(ob_arg, "w*:ioctl", &pstr)) {
173 char *arg;
174 str = pstr.buf;
175 len = pstr.len;
Michael W. Hudsonf0089982003-03-03 12:29:42 +0000176
Brett Cannonb7299dd2014-11-09 20:22:01 -0500177 if (mutate_arg) {
178 if (len <= IOCTL_BUFSZ) {
179 memcpy(buf, str, len);
180 buf[len] = '\0';
181 arg = buf;
182 }
183 else {
184 arg = str;
185 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000186 }
187 else {
Brett Cannonb7299dd2014-11-09 20:22:01 -0500188 if (len > IOCTL_BUFSZ) {
189 PyBuffer_Release(&pstr);
190 PyErr_SetString(PyExc_ValueError,
191 "ioctl string arg too long");
192 return NULL;
193 }
194 else {
195 memcpy(buf, str, len);
196 buf[len] = '\0';
197 arg = buf;
198 }
199 }
200 if (buf == arg) {
201 Py_BEGIN_ALLOW_THREADS /* think array.resize() */
202 ret = ioctl(fd, code, arg);
203 Py_END_ALLOW_THREADS
204 }
205 else {
206 ret = ioctl(fd, code, arg);
207 }
208 if (mutate_arg && (len <= IOCTL_BUFSZ)) {
209 memcpy(str, buf, len);
210 }
211 PyBuffer_Release(&pstr); /* No further access to str below this point */
212 if (ret < 0) {
213 PyErr_SetFromErrno(PyExc_IOError);
214 return NULL;
215 }
216 if (mutate_arg) {
217 return PyLong_FromLong(ret);
218 }
219 else {
220 return PyBytes_FromStringAndSize(buf, len);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000221 }
222 }
Brett Cannonb7299dd2014-11-09 20:22:01 -0500223
224 PyErr_Clear();
225 if (PyArg_Parse(ob_arg, "s*:ioctl", &pstr)) {
226 str = pstr.buf;
227 len = pstr.len;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000228 if (len > IOCTL_BUFSZ) {
229 PyBuffer_Release(&pstr);
230 PyErr_SetString(PyExc_ValueError,
Brett Cannonb7299dd2014-11-09 20:22:01 -0500231 "ioctl string arg too long");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000232 return NULL;
233 }
Brett Cannonb7299dd2014-11-09 20:22:01 -0500234 memcpy(buf, str, len);
235 buf[len] = '\0';
236 Py_BEGIN_ALLOW_THREADS
237 ret = ioctl(fd, code, buf);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000238 Py_END_ALLOW_THREADS
Brett Cannonb7299dd2014-11-09 20:22:01 -0500239 if (ret < 0) {
240 PyBuffer_Release(&pstr);
241 PyErr_SetFromErrno(PyExc_IOError);
242 return NULL;
243 }
244 PyBuffer_Release(&pstr);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000245 return PyBytes_FromStringAndSize(buf, len);
246 }
Michael W. Hudsonf0089982003-03-03 12:29:42 +0000247
Brett Cannonb7299dd2014-11-09 20:22:01 -0500248 PyErr_Clear();
249 if (!PyArg_Parse(ob_arg,
250 "i;ioctl requires a file or file descriptor,"
251 " an integer and optionally an integer or buffer argument",
252 &arg)) {
253 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000254 }
Brett Cannonb7299dd2014-11-09 20:22:01 -0500255 // Fall-through to outside the 'if' statement.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000256 }
257 Py_BEGIN_ALLOW_THREADS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000258 ret = ioctl(fd, code, arg);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000259 Py_END_ALLOW_THREADS
260 if (ret < 0) {
261 PyErr_SetFromErrno(PyExc_IOError);
262 return NULL;
263 }
264 return PyLong_FromLong((long)ret);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000265#undef IOCTL_BUFSZ
Guido van Rossum02975121992-08-17 08:55:12 +0000266}
267
Brett Cannonb7299dd2014-11-09 20:22:01 -0500268/*[clinic input]
269fcntl.flock
Guido van Rossum185ead61998-11-23 15:32:55 +0000270
Brett Cannonb7299dd2014-11-09 20:22:01 -0500271 fd: object(type='int', converter='conv_descriptor')
Serhiy Storchaka17d3a582015-03-20 20:04:21 +0200272 operation as code: int
Brett Cannonb7299dd2014-11-09 20:22:01 -0500273 /
Guido van Rossum02975121992-08-17 08:55:12 +0000274
Serhiy Storchaka17d3a582015-03-20 20:04:21 +0200275Perform the lock operation `operation` on file descriptor `fd`.
Brett Cannonb7299dd2014-11-09 20:22:01 -0500276
277See the Unix manual page for flock(2) for details (On some systems, this
278function is emulated using fcntl()).
279[clinic start generated code]*/
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000280
Roger E. Masse919213a1996-12-17 17:42:22 +0000281static PyObject *
Brett Cannonb7299dd2014-11-09 20:22:01 -0500282fcntl_flock_impl(PyModuleDef *module, int fd, int code)
Serhiy Storchaka17d3a582015-03-20 20:04:21 +0200283/*[clinic end generated code: output=c9035133a7dbfc96 input=b70a0a41ca22a8a0]*/
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000284{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000285 int ret;
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000286
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000287#ifdef HAVE_FLOCK
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000288 Py_BEGIN_ALLOW_THREADS
289 ret = flock(fd, code);
290 Py_END_ALLOW_THREADS
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000291#else
292
293#ifndef LOCK_SH
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000294#define LOCK_SH 1 /* shared lock */
295#define LOCK_EX 2 /* exclusive lock */
296#define LOCK_NB 4 /* don't block when locking */
297#define LOCK_UN 8 /* unlock */
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000298#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000299 {
300 struct flock l;
301 if (code == LOCK_UN)
302 l.l_type = F_UNLCK;
303 else if (code & LOCK_SH)
304 l.l_type = F_RDLCK;
305 else if (code & LOCK_EX)
306 l.l_type = F_WRLCK;
307 else {
308 PyErr_SetString(PyExc_ValueError,
309 "unrecognized flock argument");
310 return NULL;
311 }
312 l.l_whence = l.l_start = l.l_len = 0;
313 Py_BEGIN_ALLOW_THREADS
314 ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
315 Py_END_ALLOW_THREADS
316 }
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000317#endif /* HAVE_FLOCK */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000318 if (ret < 0) {
319 PyErr_SetFromErrno(PyExc_IOError);
320 return NULL;
321 }
Brett Cannonb7299dd2014-11-09 20:22:01 -0500322 Py_RETURN_NONE;
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000323}
324
Guido van Rossum185ead61998-11-23 15:32:55 +0000325
Brett Cannonb7299dd2014-11-09 20:22:01 -0500326/*[clinic input]
327fcntl.lockf
Guido van Rossum185ead61998-11-23 15:32:55 +0000328
Brett Cannonb7299dd2014-11-09 20:22:01 -0500329 fd: object(type='int', converter='conv_descriptor')
Serhiy Storchaka17d3a582015-03-20 20:04:21 +0200330 cmd as code: int
331 len as lenobj: object(c_default='NULL') = 0
332 start as startobj: object(c_default='NULL') = 0
Brett Cannonb7299dd2014-11-09 20:22:01 -0500333 whence: int = 0
334 /
335
336A wrapper around the fcntl() locking calls.
337
Serhiy Storchaka17d3a582015-03-20 20:04:21 +0200338`fd` is the file descriptor of the file to lock or unlock, and operation is one
Brett Cannonb7299dd2014-11-09 20:22:01 -0500339of the following values:
340
341 LOCK_UN - unlock
342 LOCK_SH - acquire a shared lock
343 LOCK_EX - acquire an exclusive lock
344
345When operation is LOCK_SH or LOCK_EX, it can also be bitwise ORed with
346LOCK_NB to avoid blocking on lock acquisition. If LOCK_NB is used and the
347lock cannot be acquired, an IOError will be raised and the exception will
348have an errno attribute set to EACCES or EAGAIN (depending on the operating
349system -- for portability, check for either value).
350
Serhiy Storchaka17d3a582015-03-20 20:04:21 +0200351`len` is the number of bytes to lock, with the default meaning to lock to
352EOF. `start` is the byte offset, relative to `whence`, to that the lock
353starts. `whence` is as with fileobj.seek(), specifically:
Brett Cannonb7299dd2014-11-09 20:22:01 -0500354
355 0 - relative to the start of the file (SEEK_SET)
356 1 - relative to the current buffer position (SEEK_CUR)
357 2 - relative to the end of the file (SEEK_END)
358[clinic start generated code]*/
359
Roger E. Masse919213a1996-12-17 17:42:22 +0000360static PyObject *
Brett Cannonb7299dd2014-11-09 20:22:01 -0500361fcntl_lockf_impl(PyModuleDef *module, int fd, int code, PyObject *lenobj, PyObject *startobj, int whence)
Serhiy Storchaka17d3a582015-03-20 20:04:21 +0200362/*[clinic end generated code: output=5536df2892bf3ce9 input=9c594391de821f24]*/
Guido van Rossumc8643641996-09-11 23:17:20 +0000363{
Brett Cannonb7299dd2014-11-09 20:22:01 -0500364 int ret;
Guido van Rossumc8643641996-09-11 23:17:20 +0000365
Guido van Rossumc8643641996-09-11 23:17:20 +0000366#ifndef LOCK_SH
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000367#define LOCK_SH 1 /* shared lock */
368#define LOCK_EX 2 /* exclusive lock */
369#define LOCK_NB 4 /* don't block when locking */
370#define LOCK_UN 8 /* unlock */
Andrew MacIntyre7bf68332002-03-03 02:59:16 +0000371#endif /* LOCK_SH */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000372 {
373 struct flock l;
374 if (code == LOCK_UN)
375 l.l_type = F_UNLCK;
376 else if (code & LOCK_SH)
377 l.l_type = F_RDLCK;
378 else if (code & LOCK_EX)
379 l.l_type = F_WRLCK;
380 else {
381 PyErr_SetString(PyExc_ValueError,
382 "unrecognized lockf argument");
383 return NULL;
384 }
385 l.l_start = l.l_len = 0;
386 if (startobj != NULL) {
Guido van Rossum056bad91999-01-06 18:44:23 +0000387#if !defined(HAVE_LARGEFILE_SUPPORT)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000388 l.l_start = PyLong_AsLong(startobj);
Guido van Rossum056bad91999-01-06 18:44:23 +0000389#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000390 l.l_start = PyLong_Check(startobj) ?
391 PyLong_AsLongLong(startobj) :
392 PyLong_AsLong(startobj);
Guido van Rossum056bad91999-01-06 18:44:23 +0000393#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000394 if (PyErr_Occurred())
395 return NULL;
396 }
397 if (lenobj != NULL) {
Guido van Rossum056bad91999-01-06 18:44:23 +0000398#if !defined(HAVE_LARGEFILE_SUPPORT)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000399 l.l_len = PyLong_AsLong(lenobj);
Guido van Rossum056bad91999-01-06 18:44:23 +0000400#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000401 l.l_len = PyLong_Check(lenobj) ?
402 PyLong_AsLongLong(lenobj) :
403 PyLong_AsLong(lenobj);
Guido van Rossum056bad91999-01-06 18:44:23 +0000404#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000405 if (PyErr_Occurred())
406 return NULL;
407 }
408 l.l_whence = whence;
409 Py_BEGIN_ALLOW_THREADS
410 ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
411 Py_END_ALLOW_THREADS
412 }
413 if (ret < 0) {
414 PyErr_SetFromErrno(PyExc_IOError);
415 return NULL;
416 }
Brett Cannonb7299dd2014-11-09 20:22:01 -0500417 Py_RETURN_NONE;
Guido van Rossumc8643641996-09-11 23:17:20 +0000418}
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000419
Guido van Rossum02975121992-08-17 08:55:12 +0000420/* List of functions */
421
Roger E. Masse919213a1996-12-17 17:42:22 +0000422static PyMethodDef fcntl_methods[] = {
Brett Cannonb7299dd2014-11-09 20:22:01 -0500423 FCNTL_FCNTL_METHODDEF
424 FCNTL_IOCTL_METHODDEF
425 FCNTL_FLOCK_METHODDEF
426 FCNTL_LOCKF_METHODDEF
427 {NULL, NULL} /* sentinel */
Guido van Rossum02975121992-08-17 08:55:12 +0000428};
429
430
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000431PyDoc_STRVAR(module_doc,
Guido van Rossum185ead61998-11-23 15:32:55 +0000432"This module performs file control and I/O control on file \n\
433descriptors. It is an interface to the fcntl() and ioctl() Unix\n\
434routines. File descriptors can be obtained with the fileno() method of\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000435a file or socket object.");
Guido van Rossum185ead61998-11-23 15:32:55 +0000436
Guido van Rossum02975121992-08-17 08:55:12 +0000437/* Module initialisation */
438
Martin v. Löwis14e73b12003-01-01 09:51:12 +0000439
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000440static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200441all_ins(PyObject* m)
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000442{
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200443 if (PyModule_AddIntMacro(m, LOCK_SH)) return -1;
444 if (PyModule_AddIntMacro(m, LOCK_EX)) return -1;
445 if (PyModule_AddIntMacro(m, LOCK_NB)) return -1;
446 if (PyModule_AddIntMacro(m, LOCK_UN)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000447/* GNU extensions, as of glibc 2.2.4 */
448#ifdef LOCK_MAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200449 if (PyModule_AddIntMacro(m, LOCK_MAND)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000450#endif
451#ifdef LOCK_READ
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200452 if (PyModule_AddIntMacro(m, LOCK_READ)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000453#endif
454#ifdef LOCK_WRITE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200455 if (PyModule_AddIntMacro(m, LOCK_WRITE)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000456#endif
457#ifdef LOCK_RW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200458 if (PyModule_AddIntMacro(m, LOCK_RW)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000459#endif
460
Fred Drake152a25e2001-05-09 21:02:02 +0000461#ifdef F_DUPFD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200462 if (PyModule_AddIntMacro(m, F_DUPFD)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000463#endif
Victor Stinner2716d532013-01-08 00:52:40 +0100464#ifdef F_DUPFD_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200465 if (PyModule_AddIntMacro(m, F_DUPFD_CLOEXEC)) return -1;
Victor Stinner2716d532013-01-08 00:52:40 +0100466#endif
Fred Drake152a25e2001-05-09 21:02:02 +0000467#ifdef F_GETFD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200468 if (PyModule_AddIntMacro(m, F_GETFD)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000469#endif
470#ifdef F_SETFD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200471 if (PyModule_AddIntMacro(m, F_SETFD)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000472#endif
473#ifdef F_GETFL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200474 if (PyModule_AddIntMacro(m, F_GETFL)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000475#endif
476#ifdef F_SETFL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200477 if (PyModule_AddIntMacro(m, F_SETFL)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000478#endif
479#ifdef F_GETLK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200480 if (PyModule_AddIntMacro(m, F_GETLK)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000481#endif
482#ifdef F_SETLK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200483 if (PyModule_AddIntMacro(m, F_SETLK)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000484#endif
485#ifdef F_SETLKW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200486 if (PyModule_AddIntMacro(m, F_SETLKW)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000487#endif
488#ifdef F_GETOWN
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200489 if (PyModule_AddIntMacro(m, F_GETOWN)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000490#endif
491#ifdef F_SETOWN
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200492 if (PyModule_AddIntMacro(m, F_SETOWN)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000493#endif
494#ifdef F_GETSIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200495 if (PyModule_AddIntMacro(m, F_GETSIG)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000496#endif
497#ifdef F_SETSIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200498 if (PyModule_AddIntMacro(m, F_SETSIG)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000499#endif
500#ifdef F_RDLCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200501 if (PyModule_AddIntMacro(m, F_RDLCK)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000502#endif
503#ifdef F_WRLCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200504 if (PyModule_AddIntMacro(m, F_WRLCK)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000505#endif
506#ifdef F_UNLCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200507 if (PyModule_AddIntMacro(m, F_UNLCK)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000508#endif
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000509/* LFS constants */
510#ifdef F_GETLK64
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200511 if (PyModule_AddIntMacro(m, F_GETLK64)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000512#endif
513#ifdef F_SETLK64
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200514 if (PyModule_AddIntMacro(m, F_SETLK64)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000515#endif
516#ifdef F_SETLKW64
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200517 if (PyModule_AddIntMacro(m, F_SETLKW64)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000518#endif
519/* GNU extensions, as of glibc 2.2.4. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +0000520#ifdef FASYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200521 if (PyModule_AddIntMacro(m, FASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +0000522#endif
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000523#ifdef F_SETLEASE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200524 if (PyModule_AddIntMacro(m, F_SETLEASE)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000525#endif
526#ifdef F_GETLEASE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200527 if (PyModule_AddIntMacro(m, F_GETLEASE)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000528#endif
529#ifdef F_NOTIFY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200530 if (PyModule_AddIntMacro(m, F_NOTIFY)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000531#endif
532/* Old BSD flock(). */
533#ifdef F_EXLCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200534 if (PyModule_AddIntMacro(m, F_EXLCK)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000535#endif
536#ifdef F_SHLCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200537 if (PyModule_AddIntMacro(m, F_SHLCK)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000538#endif
539
Charles-François Natali23e1ecb2011-11-02 18:58:25 +0100540/* OS X specifics */
Georg Brandl6aa2d1f2008-08-12 08:35:52 +0000541#ifdef F_FULLFSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200542 if (PyModule_AddIntMacro(m, F_FULLFSYNC)) return -1;
Georg Brandl6aa2d1f2008-08-12 08:35:52 +0000543#endif
Charles-François Natali23e1ecb2011-11-02 18:58:25 +0100544#ifdef F_NOCACHE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200545 if (PyModule_AddIntMacro(m, F_NOCACHE)) return -1;
Charles-François Natali23e1ecb2011-11-02 18:58:25 +0100546#endif
Georg Brandl6aa2d1f2008-08-12 08:35:52 +0000547
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000548/* For F_{GET|SET}FL */
549#ifdef FD_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200550 if (PyModule_AddIntMacro(m, FD_CLOEXEC)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000551#endif
552
553/* For F_NOTIFY */
554#ifdef DN_ACCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200555 if (PyModule_AddIntMacro(m, DN_ACCESS)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000556#endif
557#ifdef DN_MODIFY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200558 if (PyModule_AddIntMacro(m, DN_MODIFY)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000559#endif
560#ifdef DN_CREATE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200561 if (PyModule_AddIntMacro(m, DN_CREATE)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000562#endif
563#ifdef DN_DELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200564 if (PyModule_AddIntMacro(m, DN_DELETE)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000565#endif
566#ifdef DN_RENAME
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200567 if (PyModule_AddIntMacro(m, DN_RENAME)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000568#endif
569#ifdef DN_ATTRIB
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200570 if (PyModule_AddIntMacro(m, DN_ATTRIB)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000571#endif
572#ifdef DN_MULTISHOT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200573 if (PyModule_AddIntMacro(m, 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. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200578 if (PyModule_AddIntMacro(m, I_PUSH)) return -1;
579 if (PyModule_AddIntMacro(m, I_POP)) return -1;
580 if (PyModule_AddIntMacro(m, I_LOOK)) return -1;
581 if (PyModule_AddIntMacro(m, I_FLUSH)) return -1;
582 if (PyModule_AddIntMacro(m, I_FLUSHBAND)) return -1;
583 if (PyModule_AddIntMacro(m, I_SETSIG)) return -1;
584 if (PyModule_AddIntMacro(m, I_GETSIG)) return -1;
585 if (PyModule_AddIntMacro(m, I_FIND)) return -1;
586 if (PyModule_AddIntMacro(m, I_PEEK)) return -1;
587 if (PyModule_AddIntMacro(m, I_SRDOPT)) return -1;
588 if (PyModule_AddIntMacro(m, I_GRDOPT)) return -1;
589 if (PyModule_AddIntMacro(m, I_NREAD)) return -1;
590 if (PyModule_AddIntMacro(m, I_FDINSERT)) return -1;
591 if (PyModule_AddIntMacro(m, I_STR)) return -1;
592 if (PyModule_AddIntMacro(m, I_SWROPT)) return -1;
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... */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200595 if (PyModule_AddIntMacro(m, I_GWROPT)) return -1;
Michael W. Hudson505c4c22003-05-09 10:45:20 +0000596#endif
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200597 if (PyModule_AddIntMacro(m, I_SENDFD)) return -1;
598 if (PyModule_AddIntMacro(m, I_RECVFD)) return -1;
599 if (PyModule_AddIntMacro(m, I_LIST)) return -1;
600 if (PyModule_AddIntMacro(m, I_ATMARK)) return -1;
601 if (PyModule_AddIntMacro(m, I_CKBAND)) return -1;
602 if (PyModule_AddIntMacro(m, I_GETBAND)) return -1;
603 if (PyModule_AddIntMacro(m, I_CANPUT)) return -1;
604 if (PyModule_AddIntMacro(m, I_SETCLTIME)) return -1;
Michael W. Hudson505c4c22003-05-09 10:45:20 +0000605#ifdef I_GETCLTIME
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200606 if (PyModule_AddIntMacro(m, I_GETCLTIME)) return -1;
Michael W. Hudson505c4c22003-05-09 10:45:20 +0000607#endif
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200608 if (PyModule_AddIntMacro(m, I_LINK)) return -1;
609 if (PyModule_AddIntMacro(m, I_UNLINK)) return -1;
610 if (PyModule_AddIntMacro(m, I_PLINK)) return -1;
611 if (PyModule_AddIntMacro(m, I_PUNLINK)) return -1;
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{
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200633 PyObject *m;
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 */
Charles-François Natali5abca142013-12-01 14:30:47 +0100641 if (all_ins(m) < 0)
642 return NULL;
643
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000644 return m;
Guido van Rossum02975121992-08-17 08:55:12 +0000645}