blob: a938d9e88bf017425c803f2c8265f9fed74014e4 [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)
Martin Panter6d57fe12016-09-17 03:26:16 +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 *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030059fcntl_fcntl_impl(PyObject *module, int fd, int code, PyObject *arg)
60/*[clinic end generated code: output=888fc93b51c295bd 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];
nierobb409ffa2018-11-23 16:46:12 +010067 int async_err = 0;
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);
nierobb409ffa2018-11-23 16:46:12 +010079 do {
80 Py_BEGIN_ALLOW_THREADS
81 ret = fcntl(fd, code, buf);
82 Py_END_ALLOW_THREADS
83 } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Brett Cannonb7299dd2014-11-09 20:22:01 -050084 if (ret < 0) {
nierobb409ffa2018-11-23 16:46:12 +010085 return !async_err ? PyErr_SetFromErrno(PyExc_OSError) : NULL;
Brett Cannonb7299dd2014-11-09 20:22:01 -050086 }
87 return PyBytes_FromStringAndSize(buf, len);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000088 }
Brett Cannonb7299dd2014-11-09 20:22:01 -050089
90 PyErr_Clear();
91 parse_result = PyArg_Parse(arg,
Serhiy Storchaka5a8dacf2014-11-10 11:25:50 +020092 "I;fcntl requires a file or file descriptor,"
Brett Cannonb7299dd2014-11-09 20:22:01 -050093 " an integer and optionally a third integer or a string",
94 &int_arg);
95 if (!parse_result) {
96 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000097 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000098 }
Guido van Rossum02975121992-08-17 08:55:12 +000099
nierobb409ffa2018-11-23 16:46:12 +0100100 do {
101 Py_BEGIN_ALLOW_THREADS
102 ret = fcntl(fd, code, (int)int_arg);
103 Py_END_ALLOW_THREADS
104 } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000105 if (ret < 0) {
nierobb409ffa2018-11-23 16:46:12 +0100106 return !async_err ? PyErr_SetFromErrno(PyExc_OSError) : NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000107 }
108 return PyLong_FromLong((long)ret);
Guido van Rossum02975121992-08-17 08:55:12 +0000109}
110
Guido van Rossum185ead61998-11-23 15:32:55 +0000111
Brett Cannonb7299dd2014-11-09 20:22:01 -0500112/*[clinic input]
113fcntl.ioctl
Guido van Rossum02975121992-08-17 08:55:12 +0000114
Brett Cannonb7299dd2014-11-09 20:22:01 -0500115 fd: object(type='int', converter='conv_descriptor')
Serhiy Storchaka17d3a582015-03-20 20:04:21 +0200116 request as code: unsigned_int(bitwise=True)
117 arg as ob_arg: object(c_default='NULL') = 0
Brett Cannonb7299dd2014-11-09 20:22:01 -0500118 mutate_flag as mutate_arg: bool = True
119 /
120
Serhiy Storchaka17d3a582015-03-20 20:04:21 +0200121Perform the operation `request` on file descriptor `fd`.
Brett Cannonb7299dd2014-11-09 20:22:01 -0500122
Serhiy Storchaka17d3a582015-03-20 20:04:21 +0200123The values used for `request` are operating system dependent, and are available
124as constants in the fcntl or termios library modules, using the same names as
Brett Cannonb7299dd2014-11-09 20:22:01 -0500125used in the relevant C header files.
126
127The argument `arg` is optional, and defaults to 0; it may be an int or a
128buffer containing character data (most likely a string or an array).
129
130If the argument is a mutable buffer (such as an array) and if the
131mutate_flag argument (which is only allowed in this case) is true then the
132buffer is (in effect) passed to the operating system and changes made by
133the OS will be reflected in the contents of the buffer after the call has
134returned. The return value is the integer returned by the ioctl system
135call.
136
Serhiy Storchaka17d3a582015-03-20 20:04:21 +0200137If the argument is a mutable buffer and the mutable_flag argument is false,
138the behavior is as if a string had been passed.
Brett Cannonb7299dd2014-11-09 20:22:01 -0500139
140If the argument is an immutable buffer (most likely a string) then a copy
141of the buffer is passed to the operating system and the return value is a
142string of the same length containing whatever the operating system put in
143the buffer. The length of the arg buffer in this case is not allowed to
144exceed 1024 bytes.
145
146If the arg given is an integer or if none is specified, the result value is
147an integer corresponding to the return value of the ioctl call in the C
148code.
149[clinic start generated code]*/
Guido van Rossum02975121992-08-17 08:55:12 +0000150
Roger E. Masse919213a1996-12-17 17:42:22 +0000151static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300152fcntl_ioctl_impl(PyObject *module, int fd, unsigned int code,
Larry Hastings89964c42015-04-14 18:07:59 -0400153 PyObject *ob_arg, int mutate_arg)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300154/*[clinic end generated code: output=7f7f5840c65991be input=ede70c433cccbbb2]*/
Guido van Rossum02975121992-08-17 08:55:12 +0000155{
Thomas Wouters477c8d52006-05-27 19:21:47 +0000156#define IOCTL_BUFSZ 1024
Serhiy Storchaka483405b2015-02-17 10:14:30 +0200157 /* We use the unsigned non-checked 'I' format for the 'code' parameter
158 because the system expects it to be a 32bit bit field value
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000159 regardless of it being passed as an int or unsigned long on
160 various platforms. See the termios.TIOCSWINSZ constant across
R David Murrayd5a2f0b2013-11-07 10:51:07 -0500161 platforms for an example of this.
Christian Heimese25f35e2008-03-20 10:49:03 +0000162
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000163 If any of the 64bit platforms ever decide to use more than 32bits
164 in their unsigned long ioctl codes this will break and need
165 special casing based on the platform being built on.
166 */
Brett Cannonb7299dd2014-11-09 20:22:01 -0500167 int arg = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000168 int ret;
169 Py_buffer pstr;
170 char *str;
171 Py_ssize_t len;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000172 char buf[IOCTL_BUFSZ+1]; /* argument plus NUL byte */
Guido van Rossum02975121992-08-17 08:55:12 +0000173
Brett Cannonb7299dd2014-11-09 20:22:01 -0500174 if (ob_arg != NULL) {
175 if (PyArg_Parse(ob_arg, "w*:ioctl", &pstr)) {
176 char *arg;
177 str = pstr.buf;
178 len = pstr.len;
Michael W. Hudsonf0089982003-03-03 12:29:42 +0000179
Brett Cannonb7299dd2014-11-09 20:22:01 -0500180 if (mutate_arg) {
181 if (len <= IOCTL_BUFSZ) {
182 memcpy(buf, str, len);
183 buf[len] = '\0';
184 arg = buf;
185 }
186 else {
187 arg = str;
188 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000189 }
190 else {
Brett Cannonb7299dd2014-11-09 20:22:01 -0500191 if (len > IOCTL_BUFSZ) {
192 PyBuffer_Release(&pstr);
193 PyErr_SetString(PyExc_ValueError,
194 "ioctl string arg too long");
195 return NULL;
196 }
197 else {
198 memcpy(buf, str, len);
199 buf[len] = '\0';
200 arg = buf;
201 }
202 }
203 if (buf == arg) {
204 Py_BEGIN_ALLOW_THREADS /* think array.resize() */
205 ret = ioctl(fd, code, arg);
206 Py_END_ALLOW_THREADS
207 }
208 else {
209 ret = ioctl(fd, code, arg);
210 }
211 if (mutate_arg && (len <= IOCTL_BUFSZ)) {
212 memcpy(str, buf, len);
213 }
214 PyBuffer_Release(&pstr); /* No further access to str below this point */
215 if (ret < 0) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300216 PyErr_SetFromErrno(PyExc_OSError);
Brett Cannonb7299dd2014-11-09 20:22:01 -0500217 return NULL;
218 }
219 if (mutate_arg) {
220 return PyLong_FromLong(ret);
221 }
222 else {
223 return PyBytes_FromStringAndSize(buf, len);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000224 }
225 }
Brett Cannonb7299dd2014-11-09 20:22:01 -0500226
227 PyErr_Clear();
228 if (PyArg_Parse(ob_arg, "s*:ioctl", &pstr)) {
229 str = pstr.buf;
230 len = pstr.len;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000231 if (len > IOCTL_BUFSZ) {
232 PyBuffer_Release(&pstr);
233 PyErr_SetString(PyExc_ValueError,
Brett Cannonb7299dd2014-11-09 20:22:01 -0500234 "ioctl string arg too long");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000235 return NULL;
236 }
Brett Cannonb7299dd2014-11-09 20:22:01 -0500237 memcpy(buf, str, len);
238 buf[len] = '\0';
239 Py_BEGIN_ALLOW_THREADS
240 ret = ioctl(fd, code, buf);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000241 Py_END_ALLOW_THREADS
Brett Cannonb7299dd2014-11-09 20:22:01 -0500242 if (ret < 0) {
243 PyBuffer_Release(&pstr);
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300244 PyErr_SetFromErrno(PyExc_OSError);
Brett Cannonb7299dd2014-11-09 20:22:01 -0500245 return NULL;
246 }
247 PyBuffer_Release(&pstr);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000248 return PyBytes_FromStringAndSize(buf, len);
249 }
Michael W. Hudsonf0089982003-03-03 12:29:42 +0000250
Brett Cannonb7299dd2014-11-09 20:22:01 -0500251 PyErr_Clear();
252 if (!PyArg_Parse(ob_arg,
253 "i;ioctl requires a file or file descriptor,"
254 " an integer and optionally an integer or buffer argument",
255 &arg)) {
256 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000257 }
Brett Cannonb7299dd2014-11-09 20:22:01 -0500258 // Fall-through to outside the 'if' statement.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000259 }
260 Py_BEGIN_ALLOW_THREADS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000261 ret = ioctl(fd, code, arg);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000262 Py_END_ALLOW_THREADS
263 if (ret < 0) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300264 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000265 return NULL;
266 }
267 return PyLong_FromLong((long)ret);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000268#undef IOCTL_BUFSZ
Guido van Rossum02975121992-08-17 08:55:12 +0000269}
270
Brett Cannonb7299dd2014-11-09 20:22:01 -0500271/*[clinic input]
272fcntl.flock
Guido van Rossum185ead61998-11-23 15:32:55 +0000273
Brett Cannonb7299dd2014-11-09 20:22:01 -0500274 fd: object(type='int', converter='conv_descriptor')
Serhiy Storchaka17d3a582015-03-20 20:04:21 +0200275 operation as code: int
Brett Cannonb7299dd2014-11-09 20:22:01 -0500276 /
Guido van Rossum02975121992-08-17 08:55:12 +0000277
Serhiy Storchaka17d3a582015-03-20 20:04:21 +0200278Perform the lock operation `operation` on file descriptor `fd`.
Brett Cannonb7299dd2014-11-09 20:22:01 -0500279
280See the Unix manual page for flock(2) for details (On some systems, this
281function is emulated using fcntl()).
282[clinic start generated code]*/
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000283
Roger E. Masse919213a1996-12-17 17:42:22 +0000284static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300285fcntl_flock_impl(PyObject *module, int fd, int code)
286/*[clinic end generated code: output=84059e2b37d2fc64 input=b70a0a41ca22a8a0]*/
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000287{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000288 int ret;
nierobb409ffa2018-11-23 16:46:12 +0100289 int async_err = 0;
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000290
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000291#ifdef HAVE_FLOCK
nierobb409ffa2018-11-23 16:46:12 +0100292 do {
293 Py_BEGIN_ALLOW_THREADS
294 ret = flock(fd, code);
295 Py_END_ALLOW_THREADS
296 } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000297#else
298
299#ifndef LOCK_SH
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000300#define LOCK_SH 1 /* shared lock */
301#define LOCK_EX 2 /* exclusive lock */
302#define LOCK_NB 4 /* don't block when locking */
303#define LOCK_UN 8 /* unlock */
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000304#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000305 {
306 struct flock l;
307 if (code == LOCK_UN)
308 l.l_type = F_UNLCK;
309 else if (code & LOCK_SH)
310 l.l_type = F_RDLCK;
311 else if (code & LOCK_EX)
312 l.l_type = F_WRLCK;
313 else {
314 PyErr_SetString(PyExc_ValueError,
315 "unrecognized flock argument");
316 return NULL;
317 }
318 l.l_whence = l.l_start = l.l_len = 0;
nierobb409ffa2018-11-23 16:46:12 +0100319 do {
320 Py_BEGIN_ALLOW_THREADS
321 ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
322 Py_END_ALLOW_THREADS
323 } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000324 }
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000325#endif /* HAVE_FLOCK */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000326 if (ret < 0) {
nierobb409ffa2018-11-23 16:46:12 +0100327 return !async_err ? PyErr_SetFromErrno(PyExc_OSError) : NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000328 }
Brett Cannonb7299dd2014-11-09 20:22:01 -0500329 Py_RETURN_NONE;
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000330}
331
Guido van Rossum185ead61998-11-23 15:32:55 +0000332
Brett Cannonb7299dd2014-11-09 20:22:01 -0500333/*[clinic input]
334fcntl.lockf
Guido van Rossum185ead61998-11-23 15:32:55 +0000335
Brett Cannonb7299dd2014-11-09 20:22:01 -0500336 fd: object(type='int', converter='conv_descriptor')
Serhiy Storchaka17d3a582015-03-20 20:04:21 +0200337 cmd as code: int
338 len as lenobj: object(c_default='NULL') = 0
339 start as startobj: object(c_default='NULL') = 0
Brett Cannonb7299dd2014-11-09 20:22:01 -0500340 whence: int = 0
341 /
342
343A wrapper around the fcntl() locking calls.
344
Serhiy Storchaka17d3a582015-03-20 20:04:21 +0200345`fd` is the file descriptor of the file to lock or unlock, and operation is one
Brett Cannonb7299dd2014-11-09 20:22:01 -0500346of the following values:
347
348 LOCK_UN - unlock
349 LOCK_SH - acquire a shared lock
350 LOCK_EX - acquire an exclusive lock
351
352When operation is LOCK_SH or LOCK_EX, it can also be bitwise ORed with
353LOCK_NB to avoid blocking on lock acquisition. If LOCK_NB is used and the
Victor Stinnerd0d51542016-04-09 11:32:58 +0200354lock cannot be acquired, an OSError will be raised and the exception will
Brett Cannonb7299dd2014-11-09 20:22:01 -0500355have an errno attribute set to EACCES or EAGAIN (depending on the operating
356system -- for portability, check for either value).
357
Serhiy Storchaka17d3a582015-03-20 20:04:21 +0200358`len` is the number of bytes to lock, with the default meaning to lock to
359EOF. `start` is the byte offset, relative to `whence`, to that the lock
360starts. `whence` is as with fileobj.seek(), specifically:
Brett Cannonb7299dd2014-11-09 20:22:01 -0500361
362 0 - relative to the start of the file (SEEK_SET)
363 1 - relative to the current buffer position (SEEK_CUR)
364 2 - relative to the end of the file (SEEK_END)
365[clinic start generated code]*/
366
Roger E. Masse919213a1996-12-17 17:42:22 +0000367static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300368fcntl_lockf_impl(PyObject *module, int fd, int code, PyObject *lenobj,
Larry Hastings89964c42015-04-14 18:07:59 -0400369 PyObject *startobj, int whence)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300370/*[clinic end generated code: output=4985e7a172e7461a input=3a5dc01b04371f1a]*/
Guido van Rossumc8643641996-09-11 23:17:20 +0000371{
Brett Cannonb7299dd2014-11-09 20:22:01 -0500372 int ret;
nierobb409ffa2018-11-23 16:46:12 +0100373 int async_err = 0;
Guido van Rossumc8643641996-09-11 23:17:20 +0000374
Guido van Rossumc8643641996-09-11 23:17:20 +0000375#ifndef LOCK_SH
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000376#define LOCK_SH 1 /* shared lock */
377#define LOCK_EX 2 /* exclusive lock */
378#define LOCK_NB 4 /* don't block when locking */
379#define LOCK_UN 8 /* unlock */
Andrew MacIntyre7bf68332002-03-03 02:59:16 +0000380#endif /* LOCK_SH */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000381 {
382 struct flock l;
383 if (code == LOCK_UN)
384 l.l_type = F_UNLCK;
385 else if (code & LOCK_SH)
386 l.l_type = F_RDLCK;
387 else if (code & LOCK_EX)
388 l.l_type = F_WRLCK;
389 else {
390 PyErr_SetString(PyExc_ValueError,
391 "unrecognized lockf argument");
392 return NULL;
393 }
394 l.l_start = l.l_len = 0;
395 if (startobj != NULL) {
Guido van Rossum056bad91999-01-06 18:44:23 +0000396#if !defined(HAVE_LARGEFILE_SUPPORT)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000397 l.l_start = PyLong_AsLong(startobj);
Guido van Rossum056bad91999-01-06 18:44:23 +0000398#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000399 l.l_start = PyLong_Check(startobj) ?
400 PyLong_AsLongLong(startobj) :
401 PyLong_AsLong(startobj);
Guido van Rossum056bad91999-01-06 18:44:23 +0000402#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000403 if (PyErr_Occurred())
404 return NULL;
405 }
406 if (lenobj != NULL) {
Guido van Rossum056bad91999-01-06 18:44:23 +0000407#if !defined(HAVE_LARGEFILE_SUPPORT)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000408 l.l_len = PyLong_AsLong(lenobj);
Guido van Rossum056bad91999-01-06 18:44:23 +0000409#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000410 l.l_len = PyLong_Check(lenobj) ?
411 PyLong_AsLongLong(lenobj) :
412 PyLong_AsLong(lenobj);
Guido van Rossum056bad91999-01-06 18:44:23 +0000413#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000414 if (PyErr_Occurred())
415 return NULL;
416 }
417 l.l_whence = whence;
nierobb409ffa2018-11-23 16:46:12 +0100418 do {
419 Py_BEGIN_ALLOW_THREADS
420 ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
421 Py_END_ALLOW_THREADS
422 } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000423 }
424 if (ret < 0) {
nierobb409ffa2018-11-23 16:46:12 +0100425 return !async_err ? PyErr_SetFromErrno(PyExc_OSError) : NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000426 }
Brett Cannonb7299dd2014-11-09 20:22:01 -0500427 Py_RETURN_NONE;
Guido van Rossumc8643641996-09-11 23:17:20 +0000428}
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000429
Guido van Rossum02975121992-08-17 08:55:12 +0000430/* List of functions */
431
Roger E. Masse919213a1996-12-17 17:42:22 +0000432static PyMethodDef fcntl_methods[] = {
Brett Cannonb7299dd2014-11-09 20:22:01 -0500433 FCNTL_FCNTL_METHODDEF
434 FCNTL_IOCTL_METHODDEF
435 FCNTL_FLOCK_METHODDEF
436 FCNTL_LOCKF_METHODDEF
437 {NULL, NULL} /* sentinel */
Guido van Rossum02975121992-08-17 08:55:12 +0000438};
439
440
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000441PyDoc_STRVAR(module_doc,
oldkaa0735f2018-02-02 16:52:55 +0800442"This module performs file control and I/O control on file\n\
Guido van Rossum185ead61998-11-23 15:32:55 +0000443descriptors. It is an interface to the fcntl() and ioctl() Unix\n\
444routines. File descriptors can be obtained with the fileno() method of\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000445a file or socket object.");
Guido van Rossum185ead61998-11-23 15:32:55 +0000446
Guido van Rossum02975121992-08-17 08:55:12 +0000447/* Module initialisation */
448
Martin v. Löwis14e73b12003-01-01 09:51:12 +0000449
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000450static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200451all_ins(PyObject* m)
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000452{
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200453 if (PyModule_AddIntMacro(m, LOCK_SH)) return -1;
454 if (PyModule_AddIntMacro(m, LOCK_EX)) return -1;
455 if (PyModule_AddIntMacro(m, LOCK_NB)) return -1;
456 if (PyModule_AddIntMacro(m, LOCK_UN)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000457/* GNU extensions, as of glibc 2.2.4 */
458#ifdef LOCK_MAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200459 if (PyModule_AddIntMacro(m, LOCK_MAND)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000460#endif
461#ifdef LOCK_READ
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200462 if (PyModule_AddIntMacro(m, LOCK_READ)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000463#endif
464#ifdef LOCK_WRITE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200465 if (PyModule_AddIntMacro(m, LOCK_WRITE)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000466#endif
467#ifdef LOCK_RW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200468 if (PyModule_AddIntMacro(m, LOCK_RW)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000469#endif
470
Fred Drake152a25e2001-05-09 21:02:02 +0000471#ifdef F_DUPFD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200472 if (PyModule_AddIntMacro(m, F_DUPFD)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000473#endif
Victor Stinner2716d532013-01-08 00:52:40 +0100474#ifdef F_DUPFD_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200475 if (PyModule_AddIntMacro(m, F_DUPFD_CLOEXEC)) return -1;
Victor Stinner2716d532013-01-08 00:52:40 +0100476#endif
Fred Drake152a25e2001-05-09 21:02:02 +0000477#ifdef F_GETFD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200478 if (PyModule_AddIntMacro(m, F_GETFD)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000479#endif
480#ifdef F_SETFD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200481 if (PyModule_AddIntMacro(m, F_SETFD)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000482#endif
483#ifdef F_GETFL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200484 if (PyModule_AddIntMacro(m, F_GETFL)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000485#endif
486#ifdef F_SETFL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200487 if (PyModule_AddIntMacro(m, F_SETFL)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000488#endif
489#ifdef F_GETLK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200490 if (PyModule_AddIntMacro(m, F_GETLK)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000491#endif
492#ifdef F_SETLK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200493 if (PyModule_AddIntMacro(m, F_SETLK)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000494#endif
495#ifdef F_SETLKW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200496 if (PyModule_AddIntMacro(m, F_SETLKW)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000497#endif
498#ifdef F_GETOWN
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200499 if (PyModule_AddIntMacro(m, F_GETOWN)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000500#endif
501#ifdef F_SETOWN
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200502 if (PyModule_AddIntMacro(m, F_SETOWN)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000503#endif
504#ifdef F_GETSIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200505 if (PyModule_AddIntMacro(m, F_GETSIG)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000506#endif
507#ifdef F_SETSIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200508 if (PyModule_AddIntMacro(m, F_SETSIG)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000509#endif
510#ifdef F_RDLCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200511 if (PyModule_AddIntMacro(m, F_RDLCK)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000512#endif
513#ifdef F_WRLCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200514 if (PyModule_AddIntMacro(m, F_WRLCK)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000515#endif
516#ifdef F_UNLCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200517 if (PyModule_AddIntMacro(m, F_UNLCK)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000518#endif
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000519/* LFS constants */
520#ifdef F_GETLK64
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200521 if (PyModule_AddIntMacro(m, F_GETLK64)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000522#endif
523#ifdef F_SETLK64
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200524 if (PyModule_AddIntMacro(m, F_SETLK64)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000525#endif
526#ifdef F_SETLKW64
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200527 if (PyModule_AddIntMacro(m, F_SETLKW64)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000528#endif
529/* GNU extensions, as of glibc 2.2.4. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +0000530#ifdef FASYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200531 if (PyModule_AddIntMacro(m, FASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +0000532#endif
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000533#ifdef F_SETLEASE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200534 if (PyModule_AddIntMacro(m, F_SETLEASE)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000535#endif
536#ifdef F_GETLEASE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200537 if (PyModule_AddIntMacro(m, F_GETLEASE)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000538#endif
539#ifdef F_NOTIFY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200540 if (PyModule_AddIntMacro(m, F_NOTIFY)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000541#endif
542/* Old BSD flock(). */
543#ifdef F_EXLCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200544 if (PyModule_AddIntMacro(m, F_EXLCK)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000545#endif
546#ifdef F_SHLCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200547 if (PyModule_AddIntMacro(m, F_SHLCK)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000548#endif
549
Charles-François Natali23e1ecb2011-11-02 18:58:25 +0100550/* OS X specifics */
Georg Brandl6aa2d1f2008-08-12 08:35:52 +0000551#ifdef F_FULLFSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200552 if (PyModule_AddIntMacro(m, F_FULLFSYNC)) return -1;
Georg Brandl6aa2d1f2008-08-12 08:35:52 +0000553#endif
Charles-François Natali23e1ecb2011-11-02 18:58:25 +0100554#ifdef F_NOCACHE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200555 if (PyModule_AddIntMacro(m, F_NOCACHE)) return -1;
Charles-François Natali23e1ecb2011-11-02 18:58:25 +0100556#endif
Georg Brandl6aa2d1f2008-08-12 08:35:52 +0000557
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000558/* For F_{GET|SET}FL */
559#ifdef FD_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200560 if (PyModule_AddIntMacro(m, FD_CLOEXEC)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000561#endif
562
563/* For F_NOTIFY */
564#ifdef DN_ACCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200565 if (PyModule_AddIntMacro(m, DN_ACCESS)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000566#endif
567#ifdef DN_MODIFY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200568 if (PyModule_AddIntMacro(m, DN_MODIFY)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000569#endif
570#ifdef DN_CREATE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200571 if (PyModule_AddIntMacro(m, DN_CREATE)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000572#endif
573#ifdef DN_DELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200574 if (PyModule_AddIntMacro(m, DN_DELETE)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000575#endif
576#ifdef DN_RENAME
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200577 if (PyModule_AddIntMacro(m, DN_RENAME)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000578#endif
579#ifdef DN_ATTRIB
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200580 if (PyModule_AddIntMacro(m, DN_ATTRIB)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000581#endif
582#ifdef DN_MULTISHOT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200583 if (PyModule_AddIntMacro(m, DN_MULTISHOT)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000584#endif
585
Martin v. Löwis14e73b12003-01-01 09:51:12 +0000586#ifdef HAVE_STROPTS_H
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000587 /* Unix 98 guarantees that these are in stropts.h. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200588 if (PyModule_AddIntMacro(m, I_PUSH)) return -1;
589 if (PyModule_AddIntMacro(m, I_POP)) return -1;
590 if (PyModule_AddIntMacro(m, I_LOOK)) return -1;
591 if (PyModule_AddIntMacro(m, I_FLUSH)) return -1;
592 if (PyModule_AddIntMacro(m, I_FLUSHBAND)) return -1;
593 if (PyModule_AddIntMacro(m, I_SETSIG)) return -1;
594 if (PyModule_AddIntMacro(m, I_GETSIG)) return -1;
595 if (PyModule_AddIntMacro(m, I_FIND)) return -1;
596 if (PyModule_AddIntMacro(m, I_PEEK)) return -1;
597 if (PyModule_AddIntMacro(m, I_SRDOPT)) return -1;
598 if (PyModule_AddIntMacro(m, I_GRDOPT)) return -1;
599 if (PyModule_AddIntMacro(m, I_NREAD)) return -1;
600 if (PyModule_AddIntMacro(m, I_FDINSERT)) return -1;
601 if (PyModule_AddIntMacro(m, I_STR)) return -1;
602 if (PyModule_AddIntMacro(m, I_SWROPT)) return -1;
Michael W. Hudson505c4c22003-05-09 10:45:20 +0000603#ifdef I_GWROPT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000604 /* despite the comment above, old-ish glibcs miss a couple... */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200605 if (PyModule_AddIntMacro(m, I_GWROPT)) 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_SENDFD)) return -1;
608 if (PyModule_AddIntMacro(m, I_RECVFD)) return -1;
609 if (PyModule_AddIntMacro(m, I_LIST)) return -1;
610 if (PyModule_AddIntMacro(m, I_ATMARK)) return -1;
611 if (PyModule_AddIntMacro(m, I_CKBAND)) return -1;
612 if (PyModule_AddIntMacro(m, I_GETBAND)) return -1;
613 if (PyModule_AddIntMacro(m, I_CANPUT)) return -1;
614 if (PyModule_AddIntMacro(m, I_SETCLTIME)) return -1;
Michael W. Hudson505c4c22003-05-09 10:45:20 +0000615#ifdef I_GETCLTIME
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200616 if (PyModule_AddIntMacro(m, I_GETCLTIME)) return -1;
Michael W. Hudson505c4c22003-05-09 10:45:20 +0000617#endif
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200618 if (PyModule_AddIntMacro(m, I_LINK)) return -1;
619 if (PyModule_AddIntMacro(m, I_UNLINK)) return -1;
620 if (PyModule_AddIntMacro(m, I_PLINK)) return -1;
621 if (PyModule_AddIntMacro(m, I_PUNLINK)) return -1;
Martin v. Löwis14e73b12003-01-01 09:51:12 +0000622#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000623
624 return 0;
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000625}
626
Martin v. Löwis1a214512008-06-11 05:26:20 +0000627
628static struct PyModuleDef fcntlmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000629 PyModuleDef_HEAD_INIT,
630 "fcntl",
631 module_doc,
632 -1,
633 fcntl_methods,
634 NULL,
635 NULL,
636 NULL,
637 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +0000638};
639
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000640PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +0000641PyInit_fcntl(void)
Guido van Rossum02975121992-08-17 08:55:12 +0000642{
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200643 PyObject *m;
Guido van Rossum02975121992-08-17 08:55:12 +0000644
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000645 /* Create the module and add the functions and documentation */
646 m = PyModule_Create(&fcntlmodule);
647 if (m == NULL)
648 return NULL;
Guido van Rossum02975121992-08-17 08:55:12 +0000649
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000650 /* Add some symbolic constants to the module */
Charles-François Natali5abca142013-12-01 14:30:47 +0100651 if (all_ins(m) < 0)
652 return NULL;
653
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000654 return m;
Guido van Rossum02975121992-08-17 08:55:12 +0000655}