blob: cabff06269f187b64c47e2a04b3b05227fc2bf41 [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]
Brett Cannonb7299dd2014-11-09 20:22:01 -050019module fcntl
20[clinic start generated code]*/
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030021/*[clinic end generated code: output=da39a3ee5e6b4b0d input=124b58387c158179]*/
Brett Cannonb7299dd2014-11-09 20:22:01 -050022
Fred Drake152a25e2001-05-09 21:02:02 +000023static int
24conv_descriptor(PyObject *object, int *target)
25{
26 int fd = PyObject_AsFileDescriptor(object);
27
28 if (fd < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000029 return 0;
Fred Drake152a25e2001-05-09 21:02:02 +000030 *target = fd;
31 return 1;
32}
33
Brett Cannonb7299dd2014-11-09 20:22:01 -050034/* Must come after conv_descriptor definition. */
35#include "clinic/fcntlmodule.c.h"
Fred Drake152a25e2001-05-09 21:02:02 +000036
Brett Cannonb7299dd2014-11-09 20:22:01 -050037/*[clinic input]
38fcntl.fcntl
39
40 fd: object(type='int', converter='conv_descriptor')
Serhiy Storchaka17d3a582015-03-20 20:04:21 +020041 cmd as code: int
42 arg: object(c_default='NULL') = 0
Brett Cannonb7299dd2014-11-09 20:22:01 -050043 /
44
Serhiy Storchaka17d3a582015-03-20 20:04:21 +020045Perform the operation `cmd` on file descriptor fd.
Brett Cannonb7299dd2014-11-09 20:22:01 -050046
Serhiy Storchaka17d3a582015-03-20 20:04:21 +020047The values used for `cmd` are operating system dependent, and are available
Brett Cannonb7299dd2014-11-09 20:22:01 -050048as constants in the fcntl module, using the same names as used in
49the relevant C header files. The argument arg is optional, and
50defaults to 0; it may be an int or a string. If arg is given as a string,
51the return value of fcntl is a string of that length, containing the
52resulting value put in the arg buffer by the operating system. The length
53of the arg string is not allowed to exceed 1024 bytes. If the arg given
54is an integer or if none is specified, the result value is an integer
55corresponding to the return value of the fcntl call in the C code.
56[clinic start generated code]*/
Guido van Rossum02975121992-08-17 08:55:12 +000057
Roger E. Masse919213a1996-12-17 17:42:22 +000058static PyObject *
Brett Cannonb7299dd2014-11-09 20:22:01 -050059fcntl_fcntl_impl(PyModuleDef *module, int fd, int code, PyObject *arg)
Serhiy Storchaka17d3a582015-03-20 20:04:21 +020060/*[clinic end generated code: output=afc5bfa74a03ef0d input=8cefbe59b29efbe2]*/
Guido van Rossum02975121992-08-17 08:55:12 +000061{
Serhiy Storchaka5a8dacf2014-11-10 11:25:50 +020062 unsigned int int_arg = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000063 int ret;
64 char *str;
65 Py_ssize_t len;
66 char buf[1024];
Guido van Rossum02975121992-08-17 08:55:12 +000067
Brett Cannonb7299dd2014-11-09 20:22:01 -050068 if (arg != NULL) {
69 int parse_result;
70
71 if (PyArg_Parse(arg, "s#", &str, &len)) {
72 if ((size_t)len > sizeof buf) {
73 PyErr_SetString(PyExc_ValueError,
74 "fcntl string arg too long");
75 return NULL;
76 }
77 memcpy(buf, str, len);
78 Py_BEGIN_ALLOW_THREADS
79 ret = fcntl(fd, code, buf);
80 Py_END_ALLOW_THREADS
81 if (ret < 0) {
82 PyErr_SetFromErrno(PyExc_IOError);
83 return NULL;
84 }
85 return PyBytes_FromStringAndSize(buf, len);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000086 }
Brett Cannonb7299dd2014-11-09 20:22:01 -050087
88 PyErr_Clear();
89 parse_result = PyArg_Parse(arg,
Serhiy Storchaka5a8dacf2014-11-10 11:25:50 +020090 "I;fcntl requires a file or file descriptor,"
Brett Cannonb7299dd2014-11-09 20:22:01 -050091 " an integer and optionally a third integer or a string",
92 &int_arg);
93 if (!parse_result) {
94 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000095 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000096 }
Guido van Rossum02975121992-08-17 08:55:12 +000097
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000098 Py_BEGIN_ALLOW_THREADS
Serhiy Storchaka5a8dacf2014-11-10 11:25:50 +020099 ret = fcntl(fd, code, (int)int_arg);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000100 Py_END_ALLOW_THREADS
101 if (ret < 0) {
102 PyErr_SetFromErrno(PyExc_IOError);
103 return NULL;
104 }
105 return PyLong_FromLong((long)ret);
Guido van Rossum02975121992-08-17 08:55:12 +0000106}
107
Guido van Rossum185ead61998-11-23 15:32:55 +0000108
Brett Cannonb7299dd2014-11-09 20:22:01 -0500109/*[clinic input]
110fcntl.ioctl
Guido van Rossum02975121992-08-17 08:55:12 +0000111
Brett Cannonb7299dd2014-11-09 20:22:01 -0500112 fd: object(type='int', converter='conv_descriptor')
Serhiy Storchaka17d3a582015-03-20 20:04:21 +0200113 request as code: unsigned_int(bitwise=True)
114 arg as ob_arg: object(c_default='NULL') = 0
Brett Cannonb7299dd2014-11-09 20:22:01 -0500115 mutate_flag as mutate_arg: bool = True
116 /
117
Serhiy Storchaka17d3a582015-03-20 20:04:21 +0200118Perform the operation `request` on file descriptor `fd`.
Brett Cannonb7299dd2014-11-09 20:22:01 -0500119
Serhiy Storchaka17d3a582015-03-20 20:04:21 +0200120The values used for `request` are operating system dependent, and are available
121as constants in the fcntl or termios library modules, using the same names as
Brett Cannonb7299dd2014-11-09 20:22:01 -0500122used in the relevant C header files.
123
124The argument `arg` is optional, and defaults to 0; it may be an int or a
125buffer containing character data (most likely a string or an array).
126
127If the argument is a mutable buffer (such as an array) and if the
128mutate_flag argument (which is only allowed in this case) is true then the
129buffer is (in effect) passed to the operating system and changes made by
130the OS will be reflected in the contents of the buffer after the call has
131returned. The return value is the integer returned by the ioctl system
132call.
133
Serhiy Storchaka17d3a582015-03-20 20:04:21 +0200134If the argument is a mutable buffer and the mutable_flag argument is false,
135the behavior is as if a string had been passed.
Brett Cannonb7299dd2014-11-09 20:22:01 -0500136
137If the argument is an immutable buffer (most likely a string) then a copy
138of the buffer is passed to the operating system and the return value is a
139string of the same length containing whatever the operating system put in
140the buffer. The length of the arg buffer in this case is not allowed to
141exceed 1024 bytes.
142
143If the arg given is an integer or if none is specified, the result value is
144an integer corresponding to the return value of the ioctl call in the C
145code.
146[clinic start generated code]*/
Guido van Rossum02975121992-08-17 08:55:12 +0000147
Roger E. Masse919213a1996-12-17 17:42:22 +0000148static PyObject *
Brett Cannonb7299dd2014-11-09 20:22:01 -0500149fcntl_ioctl_impl(PyModuleDef *module, int fd, unsigned int code, PyObject *ob_arg, int mutate_arg)
Serhiy Storchaka17d3a582015-03-20 20:04:21 +0200150/*[clinic end generated code: output=ad47738c118622bf input=ede70c433cccbbb2]*/
Guido van Rossum02975121992-08-17 08:55:12 +0000151{
Thomas Wouters477c8d52006-05-27 19:21:47 +0000152#define IOCTL_BUFSZ 1024
Serhiy Storchaka483405b2015-02-17 10:14:30 +0200153 /* We use the unsigned non-checked 'I' format for the 'code' parameter
154 because the system expects it to be a 32bit bit field value
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000155 regardless of it being passed as an int or unsigned long on
156 various platforms. See the termios.TIOCSWINSZ constant across
R David Murrayd5a2f0b2013-11-07 10:51:07 -0500157 platforms for an example of this.
Christian Heimese25f35e2008-03-20 10:49:03 +0000158
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000159 If any of the 64bit platforms ever decide to use more than 32bits
160 in their unsigned long ioctl codes this will break and need
161 special casing based on the platform being built on.
162 */
Brett Cannonb7299dd2014-11-09 20:22:01 -0500163 int arg = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000164 int ret;
165 Py_buffer pstr;
166 char *str;
167 Py_ssize_t len;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000168 char buf[IOCTL_BUFSZ+1]; /* argument plus NUL byte */
Guido van Rossum02975121992-08-17 08:55:12 +0000169
Brett Cannonb7299dd2014-11-09 20:22:01 -0500170 if (ob_arg != NULL) {
171 if (PyArg_Parse(ob_arg, "w*:ioctl", &pstr)) {
172 char *arg;
173 str = pstr.buf;
174 len = pstr.len;
Michael W. Hudsonf0089982003-03-03 12:29:42 +0000175
Brett Cannonb7299dd2014-11-09 20:22:01 -0500176 if (mutate_arg) {
177 if (len <= IOCTL_BUFSZ) {
178 memcpy(buf, str, len);
179 buf[len] = '\0';
180 arg = buf;
181 }
182 else {
183 arg = str;
184 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000185 }
186 else {
Brett Cannonb7299dd2014-11-09 20:22:01 -0500187 if (len > IOCTL_BUFSZ) {
188 PyBuffer_Release(&pstr);
189 PyErr_SetString(PyExc_ValueError,
190 "ioctl string arg too long");
191 return NULL;
192 }
193 else {
194 memcpy(buf, str, len);
195 buf[len] = '\0';
196 arg = buf;
197 }
198 }
199 if (buf == arg) {
200 Py_BEGIN_ALLOW_THREADS /* think array.resize() */
201 ret = ioctl(fd, code, arg);
202 Py_END_ALLOW_THREADS
203 }
204 else {
205 ret = ioctl(fd, code, arg);
206 }
207 if (mutate_arg && (len <= IOCTL_BUFSZ)) {
208 memcpy(str, buf, len);
209 }
210 PyBuffer_Release(&pstr); /* No further access to str below this point */
211 if (ret < 0) {
212 PyErr_SetFromErrno(PyExc_IOError);
213 return NULL;
214 }
215 if (mutate_arg) {
216 return PyLong_FromLong(ret);
217 }
218 else {
219 return PyBytes_FromStringAndSize(buf, len);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000220 }
221 }
Brett Cannonb7299dd2014-11-09 20:22:01 -0500222
223 PyErr_Clear();
224 if (PyArg_Parse(ob_arg, "s*:ioctl", &pstr)) {
225 str = pstr.buf;
226 len = pstr.len;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000227 if (len > IOCTL_BUFSZ) {
228 PyBuffer_Release(&pstr);
229 PyErr_SetString(PyExc_ValueError,
Brett Cannonb7299dd2014-11-09 20:22:01 -0500230 "ioctl string arg too long");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000231 return NULL;
232 }
Brett Cannonb7299dd2014-11-09 20:22:01 -0500233 memcpy(buf, str, len);
234 buf[len] = '\0';
235 Py_BEGIN_ALLOW_THREADS
236 ret = ioctl(fd, code, buf);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000237 Py_END_ALLOW_THREADS
Brett Cannonb7299dd2014-11-09 20:22:01 -0500238 if (ret < 0) {
239 PyBuffer_Release(&pstr);
240 PyErr_SetFromErrno(PyExc_IOError);
241 return NULL;
242 }
243 PyBuffer_Release(&pstr);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000244 return PyBytes_FromStringAndSize(buf, len);
245 }
Michael W. Hudsonf0089982003-03-03 12:29:42 +0000246
Brett Cannonb7299dd2014-11-09 20:22:01 -0500247 PyErr_Clear();
248 if (!PyArg_Parse(ob_arg,
249 "i;ioctl requires a file or file descriptor,"
250 " an integer and optionally an integer or buffer argument",
251 &arg)) {
252 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000253 }
Brett Cannonb7299dd2014-11-09 20:22:01 -0500254 // Fall-through to outside the 'if' statement.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000255 }
256 Py_BEGIN_ALLOW_THREADS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000257 ret = ioctl(fd, code, arg);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000258 Py_END_ALLOW_THREADS
259 if (ret < 0) {
260 PyErr_SetFromErrno(PyExc_IOError);
261 return NULL;
262 }
263 return PyLong_FromLong((long)ret);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000264#undef IOCTL_BUFSZ
Guido van Rossum02975121992-08-17 08:55:12 +0000265}
266
Brett Cannonb7299dd2014-11-09 20:22:01 -0500267/*[clinic input]
268fcntl.flock
Guido van Rossum185ead61998-11-23 15:32:55 +0000269
Brett Cannonb7299dd2014-11-09 20:22:01 -0500270 fd: object(type='int', converter='conv_descriptor')
Serhiy Storchaka17d3a582015-03-20 20:04:21 +0200271 operation as code: int
Brett Cannonb7299dd2014-11-09 20:22:01 -0500272 /
Guido van Rossum02975121992-08-17 08:55:12 +0000273
Serhiy Storchaka17d3a582015-03-20 20:04:21 +0200274Perform the lock operation `operation` on file descriptor `fd`.
Brett Cannonb7299dd2014-11-09 20:22:01 -0500275
276See the Unix manual page for flock(2) for details (On some systems, this
277function is emulated using fcntl()).
278[clinic start generated code]*/
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000279
Roger E. Masse919213a1996-12-17 17:42:22 +0000280static PyObject *
Brett Cannonb7299dd2014-11-09 20:22:01 -0500281fcntl_flock_impl(PyModuleDef *module, int fd, int code)
Serhiy Storchaka17d3a582015-03-20 20:04:21 +0200282/*[clinic end generated code: output=c9035133a7dbfc96 input=b70a0a41ca22a8a0]*/
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000283{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000284 int ret;
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000285
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000286#ifdef HAVE_FLOCK
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000287 Py_BEGIN_ALLOW_THREADS
288 ret = flock(fd, code);
289 Py_END_ALLOW_THREADS
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000290#else
291
292#ifndef LOCK_SH
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000293#define LOCK_SH 1 /* shared lock */
294#define LOCK_EX 2 /* exclusive lock */
295#define LOCK_NB 4 /* don't block when locking */
296#define LOCK_UN 8 /* unlock */
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000297#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000298 {
299 struct flock l;
300 if (code == LOCK_UN)
301 l.l_type = F_UNLCK;
302 else if (code & LOCK_SH)
303 l.l_type = F_RDLCK;
304 else if (code & LOCK_EX)
305 l.l_type = F_WRLCK;
306 else {
307 PyErr_SetString(PyExc_ValueError,
308 "unrecognized flock argument");
309 return NULL;
310 }
311 l.l_whence = l.l_start = l.l_len = 0;
312 Py_BEGIN_ALLOW_THREADS
313 ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
314 Py_END_ALLOW_THREADS
315 }
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000316#endif /* HAVE_FLOCK */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000317 if (ret < 0) {
318 PyErr_SetFromErrno(PyExc_IOError);
319 return NULL;
320 }
Brett Cannonb7299dd2014-11-09 20:22:01 -0500321 Py_RETURN_NONE;
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000322}
323
Guido van Rossum185ead61998-11-23 15:32:55 +0000324
Brett Cannonb7299dd2014-11-09 20:22:01 -0500325/*[clinic input]
326fcntl.lockf
Guido van Rossum185ead61998-11-23 15:32:55 +0000327
Brett Cannonb7299dd2014-11-09 20:22:01 -0500328 fd: object(type='int', converter='conv_descriptor')
Serhiy Storchaka17d3a582015-03-20 20:04:21 +0200329 cmd as code: int
330 len as lenobj: object(c_default='NULL') = 0
331 start as startobj: object(c_default='NULL') = 0
Brett Cannonb7299dd2014-11-09 20:22:01 -0500332 whence: int = 0
333 /
334
335A wrapper around the fcntl() locking calls.
336
Serhiy Storchaka17d3a582015-03-20 20:04:21 +0200337`fd` is the file descriptor of the file to lock or unlock, and operation is one
Brett Cannonb7299dd2014-11-09 20:22:01 -0500338of the following values:
339
340 LOCK_UN - unlock
341 LOCK_SH - acquire a shared lock
342 LOCK_EX - acquire an exclusive lock
343
344When operation is LOCK_SH or LOCK_EX, it can also be bitwise ORed with
345LOCK_NB to avoid blocking on lock acquisition. If LOCK_NB is used and the
346lock cannot be acquired, an IOError will be raised and the exception will
347have an errno attribute set to EACCES or EAGAIN (depending on the operating
348system -- for portability, check for either value).
349
Serhiy Storchaka17d3a582015-03-20 20:04:21 +0200350`len` is the number of bytes to lock, with the default meaning to lock to
351EOF. `start` is the byte offset, relative to `whence`, to that the lock
352starts. `whence` is as with fileobj.seek(), specifically:
Brett Cannonb7299dd2014-11-09 20:22:01 -0500353
354 0 - relative to the start of the file (SEEK_SET)
355 1 - relative to the current buffer position (SEEK_CUR)
356 2 - relative to the end of the file (SEEK_END)
357[clinic start generated code]*/
358
Roger E. Masse919213a1996-12-17 17:42:22 +0000359static PyObject *
Brett Cannonb7299dd2014-11-09 20:22:01 -0500360fcntl_lockf_impl(PyModuleDef *module, int fd, int code, PyObject *lenobj, PyObject *startobj, int whence)
Serhiy Storchaka17d3a582015-03-20 20:04:21 +0200361/*[clinic end generated code: output=5536df2892bf3ce9 input=9c594391de821f24]*/
Guido van Rossumc8643641996-09-11 23:17:20 +0000362{
Brett Cannonb7299dd2014-11-09 20:22:01 -0500363 int ret;
Guido van Rossumc8643641996-09-11 23:17:20 +0000364
Guido van Rossumc8643641996-09-11 23:17:20 +0000365#ifndef LOCK_SH
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000366#define LOCK_SH 1 /* shared lock */
367#define LOCK_EX 2 /* exclusive lock */
368#define LOCK_NB 4 /* don't block when locking */
369#define LOCK_UN 8 /* unlock */
Andrew MacIntyre7bf68332002-03-03 02:59:16 +0000370#endif /* LOCK_SH */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000371 {
372 struct flock l;
373 if (code == LOCK_UN)
374 l.l_type = F_UNLCK;
375 else if (code & LOCK_SH)
376 l.l_type = F_RDLCK;
377 else if (code & LOCK_EX)
378 l.l_type = F_WRLCK;
379 else {
380 PyErr_SetString(PyExc_ValueError,
381 "unrecognized lockf argument");
382 return NULL;
383 }
384 l.l_start = l.l_len = 0;
385 if (startobj != NULL) {
Guido van Rossum056bad91999-01-06 18:44:23 +0000386#if !defined(HAVE_LARGEFILE_SUPPORT)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000387 l.l_start = PyLong_AsLong(startobj);
Guido van Rossum056bad91999-01-06 18:44:23 +0000388#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000389 l.l_start = PyLong_Check(startobj) ?
390 PyLong_AsLongLong(startobj) :
391 PyLong_AsLong(startobj);
Guido van Rossum056bad91999-01-06 18:44:23 +0000392#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000393 if (PyErr_Occurred())
394 return NULL;
395 }
396 if (lenobj != NULL) {
Guido van Rossum056bad91999-01-06 18:44:23 +0000397#if !defined(HAVE_LARGEFILE_SUPPORT)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000398 l.l_len = PyLong_AsLong(lenobj);
Guido van Rossum056bad91999-01-06 18:44:23 +0000399#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000400 l.l_len = PyLong_Check(lenobj) ?
401 PyLong_AsLongLong(lenobj) :
402 PyLong_AsLong(lenobj);
Guido van Rossum056bad91999-01-06 18:44:23 +0000403#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000404 if (PyErr_Occurred())
405 return NULL;
406 }
407 l.l_whence = whence;
408 Py_BEGIN_ALLOW_THREADS
409 ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
410 Py_END_ALLOW_THREADS
411 }
412 if (ret < 0) {
413 PyErr_SetFromErrno(PyExc_IOError);
414 return NULL;
415 }
Brett Cannonb7299dd2014-11-09 20:22:01 -0500416 Py_RETURN_NONE;
Guido van Rossumc8643641996-09-11 23:17:20 +0000417}
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000418
Guido van Rossum02975121992-08-17 08:55:12 +0000419/* List of functions */
420
Roger E. Masse919213a1996-12-17 17:42:22 +0000421static PyMethodDef fcntl_methods[] = {
Brett Cannonb7299dd2014-11-09 20:22:01 -0500422 FCNTL_FCNTL_METHODDEF
423 FCNTL_IOCTL_METHODDEF
424 FCNTL_FLOCK_METHODDEF
425 FCNTL_LOCKF_METHODDEF
426 {NULL, NULL} /* sentinel */
Guido van Rossum02975121992-08-17 08:55:12 +0000427};
428
429
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000430PyDoc_STRVAR(module_doc,
Guido van Rossum185ead61998-11-23 15:32:55 +0000431"This module performs file control and I/O control on file \n\
432descriptors. It is an interface to the fcntl() and ioctl() Unix\n\
433routines. File descriptors can be obtained with the fileno() method of\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000434a file or socket object.");
Guido van Rossum185ead61998-11-23 15:32:55 +0000435
Guido van Rossum02975121992-08-17 08:55:12 +0000436/* Module initialisation */
437
Martin v. Löwis14e73b12003-01-01 09:51:12 +0000438
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000439static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200440all_ins(PyObject* m)
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000441{
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200442 if (PyModule_AddIntMacro(m, LOCK_SH)) return -1;
443 if (PyModule_AddIntMacro(m, LOCK_EX)) return -1;
444 if (PyModule_AddIntMacro(m, LOCK_NB)) return -1;
445 if (PyModule_AddIntMacro(m, LOCK_UN)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000446/* GNU extensions, as of glibc 2.2.4 */
447#ifdef LOCK_MAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200448 if (PyModule_AddIntMacro(m, LOCK_MAND)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000449#endif
450#ifdef LOCK_READ
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200451 if (PyModule_AddIntMacro(m, LOCK_READ)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000452#endif
453#ifdef LOCK_WRITE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200454 if (PyModule_AddIntMacro(m, LOCK_WRITE)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000455#endif
456#ifdef LOCK_RW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200457 if (PyModule_AddIntMacro(m, LOCK_RW)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000458#endif
459
Fred Drake152a25e2001-05-09 21:02:02 +0000460#ifdef F_DUPFD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200461 if (PyModule_AddIntMacro(m, F_DUPFD)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000462#endif
Victor Stinner2716d532013-01-08 00:52:40 +0100463#ifdef F_DUPFD_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200464 if (PyModule_AddIntMacro(m, F_DUPFD_CLOEXEC)) return -1;
Victor Stinner2716d532013-01-08 00:52:40 +0100465#endif
Fred Drake152a25e2001-05-09 21:02:02 +0000466#ifdef F_GETFD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200467 if (PyModule_AddIntMacro(m, F_GETFD)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000468#endif
469#ifdef F_SETFD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200470 if (PyModule_AddIntMacro(m, F_SETFD)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000471#endif
472#ifdef F_GETFL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200473 if (PyModule_AddIntMacro(m, F_GETFL)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000474#endif
475#ifdef F_SETFL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200476 if (PyModule_AddIntMacro(m, F_SETFL)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000477#endif
478#ifdef F_GETLK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200479 if (PyModule_AddIntMacro(m, F_GETLK)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000480#endif
481#ifdef F_SETLK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200482 if (PyModule_AddIntMacro(m, F_SETLK)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000483#endif
484#ifdef F_SETLKW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200485 if (PyModule_AddIntMacro(m, F_SETLKW)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000486#endif
487#ifdef F_GETOWN
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200488 if (PyModule_AddIntMacro(m, F_GETOWN)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000489#endif
490#ifdef F_SETOWN
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200491 if (PyModule_AddIntMacro(m, F_SETOWN)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000492#endif
493#ifdef F_GETSIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200494 if (PyModule_AddIntMacro(m, F_GETSIG)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000495#endif
496#ifdef F_SETSIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200497 if (PyModule_AddIntMacro(m, F_SETSIG)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000498#endif
499#ifdef F_RDLCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200500 if (PyModule_AddIntMacro(m, F_RDLCK)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000501#endif
502#ifdef F_WRLCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200503 if (PyModule_AddIntMacro(m, F_WRLCK)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000504#endif
505#ifdef F_UNLCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200506 if (PyModule_AddIntMacro(m, F_UNLCK)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000507#endif
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000508/* LFS constants */
509#ifdef F_GETLK64
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200510 if (PyModule_AddIntMacro(m, F_GETLK64)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000511#endif
512#ifdef F_SETLK64
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200513 if (PyModule_AddIntMacro(m, F_SETLK64)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000514#endif
515#ifdef F_SETLKW64
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200516 if (PyModule_AddIntMacro(m, F_SETLKW64)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000517#endif
518/* GNU extensions, as of glibc 2.2.4. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +0000519#ifdef FASYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200520 if (PyModule_AddIntMacro(m, FASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +0000521#endif
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000522#ifdef F_SETLEASE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200523 if (PyModule_AddIntMacro(m, F_SETLEASE)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000524#endif
525#ifdef F_GETLEASE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200526 if (PyModule_AddIntMacro(m, F_GETLEASE)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000527#endif
528#ifdef F_NOTIFY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200529 if (PyModule_AddIntMacro(m, F_NOTIFY)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000530#endif
531/* Old BSD flock(). */
532#ifdef F_EXLCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200533 if (PyModule_AddIntMacro(m, F_EXLCK)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000534#endif
535#ifdef F_SHLCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200536 if (PyModule_AddIntMacro(m, F_SHLCK)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000537#endif
538
Charles-François Natali23e1ecb2011-11-02 18:58:25 +0100539/* OS X specifics */
Georg Brandl6aa2d1f2008-08-12 08:35:52 +0000540#ifdef F_FULLFSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200541 if (PyModule_AddIntMacro(m, F_FULLFSYNC)) return -1;
Georg Brandl6aa2d1f2008-08-12 08:35:52 +0000542#endif
Charles-François Natali23e1ecb2011-11-02 18:58:25 +0100543#ifdef F_NOCACHE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200544 if (PyModule_AddIntMacro(m, F_NOCACHE)) return -1;
Charles-François Natali23e1ecb2011-11-02 18:58:25 +0100545#endif
Georg Brandl6aa2d1f2008-08-12 08:35:52 +0000546
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000547/* For F_{GET|SET}FL */
548#ifdef FD_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200549 if (PyModule_AddIntMacro(m, FD_CLOEXEC)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000550#endif
551
552/* For F_NOTIFY */
553#ifdef DN_ACCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200554 if (PyModule_AddIntMacro(m, DN_ACCESS)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000555#endif
556#ifdef DN_MODIFY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200557 if (PyModule_AddIntMacro(m, DN_MODIFY)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000558#endif
559#ifdef DN_CREATE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200560 if (PyModule_AddIntMacro(m, DN_CREATE)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000561#endif
562#ifdef DN_DELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200563 if (PyModule_AddIntMacro(m, DN_DELETE)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000564#endif
565#ifdef DN_RENAME
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200566 if (PyModule_AddIntMacro(m, DN_RENAME)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000567#endif
568#ifdef DN_ATTRIB
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200569 if (PyModule_AddIntMacro(m, DN_ATTRIB)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000570#endif
571#ifdef DN_MULTISHOT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200572 if (PyModule_AddIntMacro(m, DN_MULTISHOT)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000573#endif
574
Martin v. Löwis14e73b12003-01-01 09:51:12 +0000575#ifdef HAVE_STROPTS_H
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000576 /* Unix 98 guarantees that these are in stropts.h. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200577 if (PyModule_AddIntMacro(m, I_PUSH)) return -1;
578 if (PyModule_AddIntMacro(m, I_POP)) return -1;
579 if (PyModule_AddIntMacro(m, I_LOOK)) return -1;
580 if (PyModule_AddIntMacro(m, I_FLUSH)) return -1;
581 if (PyModule_AddIntMacro(m, I_FLUSHBAND)) return -1;
582 if (PyModule_AddIntMacro(m, I_SETSIG)) return -1;
583 if (PyModule_AddIntMacro(m, I_GETSIG)) return -1;
584 if (PyModule_AddIntMacro(m, I_FIND)) return -1;
585 if (PyModule_AddIntMacro(m, I_PEEK)) return -1;
586 if (PyModule_AddIntMacro(m, I_SRDOPT)) return -1;
587 if (PyModule_AddIntMacro(m, I_GRDOPT)) return -1;
588 if (PyModule_AddIntMacro(m, I_NREAD)) return -1;
589 if (PyModule_AddIntMacro(m, I_FDINSERT)) return -1;
590 if (PyModule_AddIntMacro(m, I_STR)) return -1;
591 if (PyModule_AddIntMacro(m, I_SWROPT)) return -1;
Michael W. Hudson505c4c22003-05-09 10:45:20 +0000592#ifdef I_GWROPT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000593 /* despite the comment above, old-ish glibcs miss a couple... */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200594 if (PyModule_AddIntMacro(m, I_GWROPT)) return -1;
Michael W. Hudson505c4c22003-05-09 10:45:20 +0000595#endif
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200596 if (PyModule_AddIntMacro(m, I_SENDFD)) return -1;
597 if (PyModule_AddIntMacro(m, I_RECVFD)) return -1;
598 if (PyModule_AddIntMacro(m, I_LIST)) return -1;
599 if (PyModule_AddIntMacro(m, I_ATMARK)) return -1;
600 if (PyModule_AddIntMacro(m, I_CKBAND)) return -1;
601 if (PyModule_AddIntMacro(m, I_GETBAND)) return -1;
602 if (PyModule_AddIntMacro(m, I_CANPUT)) return -1;
603 if (PyModule_AddIntMacro(m, I_SETCLTIME)) return -1;
Michael W. Hudson505c4c22003-05-09 10:45:20 +0000604#ifdef I_GETCLTIME
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200605 if (PyModule_AddIntMacro(m, I_GETCLTIME)) return -1;
Michael W. Hudson505c4c22003-05-09 10:45:20 +0000606#endif
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200607 if (PyModule_AddIntMacro(m, I_LINK)) return -1;
608 if (PyModule_AddIntMacro(m, I_UNLINK)) return -1;
609 if (PyModule_AddIntMacro(m, I_PLINK)) return -1;
610 if (PyModule_AddIntMacro(m, I_PUNLINK)) return -1;
Martin v. Löwis14e73b12003-01-01 09:51:12 +0000611#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000612
613 return 0;
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000614}
615
Martin v. Löwis1a214512008-06-11 05:26:20 +0000616
617static struct PyModuleDef fcntlmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000618 PyModuleDef_HEAD_INIT,
619 "fcntl",
620 module_doc,
621 -1,
622 fcntl_methods,
623 NULL,
624 NULL,
625 NULL,
626 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +0000627};
628
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000629PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +0000630PyInit_fcntl(void)
Guido van Rossum02975121992-08-17 08:55:12 +0000631{
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200632 PyObject *m;
Guido van Rossum02975121992-08-17 08:55:12 +0000633
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000634 /* Create the module and add the functions and documentation */
635 m = PyModule_Create(&fcntlmodule);
636 if (m == NULL)
637 return NULL;
Guido van Rossum02975121992-08-17 08:55:12 +0000638
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000639 /* Add some symbolic constants to the module */
Charles-François Natali5abca142013-12-01 14:30:47 +0100640 if (all_ins(m) < 0)
641 return NULL;
642
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000643 return m;
Guido van Rossum02975121992-08-17 08:55:12 +0000644}