blob: cdf0f9bf3790e2b06cabbd3839de17c3caef5bff [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
Brett Cannonb7299dd2014-11-09 20:22:01 -050023#include "clinic/fcntlmodule.c.h"
Fred Drake152a25e2001-05-09 21:02:02 +000024
Brett Cannonb7299dd2014-11-09 20:22:01 -050025/*[clinic input]
26fcntl.fcntl
27
Serhiy Storchaka9975cc52020-10-09 23:00:45 +030028 fd: fildes
Serhiy Storchaka17d3a582015-03-20 20:04:21 +020029 cmd as code: int
30 arg: object(c_default='NULL') = 0
Brett Cannonb7299dd2014-11-09 20:22:01 -050031 /
32
Serhiy Storchaka17d3a582015-03-20 20:04:21 +020033Perform the operation `cmd` on file descriptor fd.
Brett Cannonb7299dd2014-11-09 20:22:01 -050034
Serhiy Storchaka17d3a582015-03-20 20:04:21 +020035The values used for `cmd` are operating system dependent, and are available
Brett Cannonb7299dd2014-11-09 20:22:01 -050036as constants in the fcntl module, using the same names as used in
37the relevant C header files. The argument arg is optional, and
38defaults to 0; it may be an int or a string. If arg is given as a string,
39the return value of fcntl is a string of that length, containing the
40resulting value put in the arg buffer by the operating system. The length
41of the arg string is not allowed to exceed 1024 bytes. If the arg given
42is an integer or if none is specified, the result value is an integer
43corresponding to the return value of the fcntl call in the C code.
44[clinic start generated code]*/
Guido van Rossum02975121992-08-17 08:55:12 +000045
Roger E. Masse919213a1996-12-17 17:42:22 +000046static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030047fcntl_fcntl_impl(PyObject *module, int fd, int code, PyObject *arg)
Serhiy Storchaka9975cc52020-10-09 23:00:45 +030048/*[clinic end generated code: output=888fc93b51c295bd input=7955340198e5f334]*/
Guido van Rossum02975121992-08-17 08:55:12 +000049{
Serhiy Storchaka5a8dacf2014-11-10 11:25:50 +020050 unsigned int int_arg = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000051 int ret;
52 char *str;
53 Py_ssize_t len;
54 char buf[1024];
nierobb409ffa2018-11-23 16:46:12 +010055 int async_err = 0;
Guido van Rossum02975121992-08-17 08:55:12 +000056
Saiyang Gou7514f4f2020-02-12 23:47:42 -080057 if (PySys_Audit("fcntl.fcntl", "iiO", fd, code, arg ? arg : Py_None) < 0) {
58 return NULL;
59 }
60
Brett Cannonb7299dd2014-11-09 20:22:01 -050061 if (arg != NULL) {
62 int parse_result;
63
64 if (PyArg_Parse(arg, "s#", &str, &len)) {
65 if ((size_t)len > sizeof buf) {
66 PyErr_SetString(PyExc_ValueError,
67 "fcntl string arg too long");
68 return NULL;
69 }
70 memcpy(buf, str, len);
nierobb409ffa2018-11-23 16:46:12 +010071 do {
72 Py_BEGIN_ALLOW_THREADS
73 ret = fcntl(fd, code, buf);
74 Py_END_ALLOW_THREADS
75 } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Brett Cannonb7299dd2014-11-09 20:22:01 -050076 if (ret < 0) {
nierobb409ffa2018-11-23 16:46:12 +010077 return !async_err ? PyErr_SetFromErrno(PyExc_OSError) : NULL;
Brett Cannonb7299dd2014-11-09 20:22:01 -050078 }
79 return PyBytes_FromStringAndSize(buf, len);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000080 }
Brett Cannonb7299dd2014-11-09 20:22:01 -050081
82 PyErr_Clear();
83 parse_result = PyArg_Parse(arg,
Serhiy Storchaka5a8dacf2014-11-10 11:25:50 +020084 "I;fcntl requires a file or file descriptor,"
Brett Cannonb7299dd2014-11-09 20:22:01 -050085 " an integer and optionally a third integer or a string",
86 &int_arg);
87 if (!parse_result) {
88 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000089 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000090 }
Guido van Rossum02975121992-08-17 08:55:12 +000091
nierobb409ffa2018-11-23 16:46:12 +010092 do {
93 Py_BEGIN_ALLOW_THREADS
94 ret = fcntl(fd, code, (int)int_arg);
95 Py_END_ALLOW_THREADS
96 } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000097 if (ret < 0) {
nierobb409ffa2018-11-23 16:46:12 +010098 return !async_err ? PyErr_SetFromErrno(PyExc_OSError) : NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000099 }
100 return PyLong_FromLong((long)ret);
Guido van Rossum02975121992-08-17 08:55:12 +0000101}
102
Guido van Rossum185ead61998-11-23 15:32:55 +0000103
Brett Cannonb7299dd2014-11-09 20:22:01 -0500104/*[clinic input]
105fcntl.ioctl
Guido van Rossum02975121992-08-17 08:55:12 +0000106
Serhiy Storchaka9975cc52020-10-09 23:00:45 +0300107 fd: fildes
Serhiy Storchaka17d3a582015-03-20 20:04:21 +0200108 request as code: unsigned_int(bitwise=True)
109 arg as ob_arg: object(c_default='NULL') = 0
Brett Cannonb7299dd2014-11-09 20:22:01 -0500110 mutate_flag as mutate_arg: bool = True
111 /
112
Serhiy Storchaka17d3a582015-03-20 20:04:21 +0200113Perform the operation `request` on file descriptor `fd`.
Brett Cannonb7299dd2014-11-09 20:22:01 -0500114
Serhiy Storchaka17d3a582015-03-20 20:04:21 +0200115The values used for `request` are operating system dependent, and are available
116as constants in the fcntl or termios library modules, using the same names as
Brett Cannonb7299dd2014-11-09 20:22:01 -0500117used in the relevant C header files.
118
119The argument `arg` is optional, and defaults to 0; it may be an int or a
120buffer containing character data (most likely a string or an array).
121
122If the argument is a mutable buffer (such as an array) and if the
123mutate_flag argument (which is only allowed in this case) is true then the
124buffer is (in effect) passed to the operating system and changes made by
125the OS will be reflected in the contents of the buffer after the call has
126returned. The return value is the integer returned by the ioctl system
127call.
128
Serhiy Storchaka17d3a582015-03-20 20:04:21 +0200129If the argument is a mutable buffer and the mutable_flag argument is false,
130the behavior is as if a string had been passed.
Brett Cannonb7299dd2014-11-09 20:22:01 -0500131
132If the argument is an immutable buffer (most likely a string) then a copy
133of the buffer is passed to the operating system and the return value is a
134string of the same length containing whatever the operating system put in
135the buffer. The length of the arg buffer in this case is not allowed to
136exceed 1024 bytes.
137
138If the arg given is an integer or if none is specified, the result value is
139an integer corresponding to the return value of the ioctl call in the C
140code.
141[clinic start generated code]*/
Guido van Rossum02975121992-08-17 08:55:12 +0000142
Roger E. Masse919213a1996-12-17 17:42:22 +0000143static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300144fcntl_ioctl_impl(PyObject *module, int fd, unsigned int code,
Larry Hastings89964c42015-04-14 18:07:59 -0400145 PyObject *ob_arg, int mutate_arg)
Serhiy Storchaka9975cc52020-10-09 23:00:45 +0300146/*[clinic end generated code: output=7f7f5840c65991be input=967b4a4cbeceb0a8]*/
Guido van Rossum02975121992-08-17 08:55:12 +0000147{
Thomas Wouters477c8d52006-05-27 19:21:47 +0000148#define IOCTL_BUFSZ 1024
Serhiy Storchaka483405b2015-02-17 10:14:30 +0200149 /* We use the unsigned non-checked 'I' format for the 'code' parameter
150 because the system expects it to be a 32bit bit field value
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000151 regardless of it being passed as an int or unsigned long on
152 various platforms. See the termios.TIOCSWINSZ constant across
R David Murrayd5a2f0b2013-11-07 10:51:07 -0500153 platforms for an example of this.
Christian Heimese25f35e2008-03-20 10:49:03 +0000154
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000155 If any of the 64bit platforms ever decide to use more than 32bits
156 in their unsigned long ioctl codes this will break and need
157 special casing based on the platform being built on.
158 */
Brett Cannonb7299dd2014-11-09 20:22:01 -0500159 int arg = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000160 int ret;
161 Py_buffer pstr;
162 char *str;
163 Py_ssize_t len;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000164 char buf[IOCTL_BUFSZ+1]; /* argument plus NUL byte */
Guido van Rossum02975121992-08-17 08:55:12 +0000165
Saiyang Gou7514f4f2020-02-12 23:47:42 -0800166 if (PySys_Audit("fcntl.ioctl", "iIO", fd, code,
167 ob_arg ? ob_arg : Py_None) < 0) {
168 return NULL;
169 }
170
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) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300213 PyErr_SetFromErrno(PyExc_OSError);
Brett Cannonb7299dd2014-11-09 20:22:01 -0500214 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);
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300241 PyErr_SetFromErrno(PyExc_OSError);
Brett Cannonb7299dd2014-11-09 20:22:01 -0500242 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) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300261 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000262 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
Serhiy Storchaka9975cc52020-10-09 23:00:45 +0300271 fd: fildes
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 *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300282fcntl_flock_impl(PyObject *module, int fd, int code)
Serhiy Storchaka9975cc52020-10-09 23:00:45 +0300283/*[clinic end generated code: output=84059e2b37d2fc64 input=0bfc00f795953452]*/
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000284{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000285 int ret;
nierobb409ffa2018-11-23 16:46:12 +0100286 int async_err = 0;
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000287
Saiyang Gou7514f4f2020-02-12 23:47:42 -0800288 if (PySys_Audit("fcntl.flock", "ii", fd, code) < 0) {
289 return NULL;
290 }
291
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000292#ifdef HAVE_FLOCK
nierobb409ffa2018-11-23 16:46:12 +0100293 do {
294 Py_BEGIN_ALLOW_THREADS
295 ret = flock(fd, code);
296 Py_END_ALLOW_THREADS
297 } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000298#else
299
300#ifndef LOCK_SH
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000301#define LOCK_SH 1 /* shared lock */
302#define LOCK_EX 2 /* exclusive lock */
303#define LOCK_NB 4 /* don't block when locking */
304#define LOCK_UN 8 /* unlock */
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000305#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000306 {
307 struct flock l;
308 if (code == LOCK_UN)
309 l.l_type = F_UNLCK;
310 else if (code & LOCK_SH)
311 l.l_type = F_RDLCK;
312 else if (code & LOCK_EX)
313 l.l_type = F_WRLCK;
314 else {
315 PyErr_SetString(PyExc_ValueError,
316 "unrecognized flock argument");
317 return NULL;
318 }
319 l.l_whence = l.l_start = l.l_len = 0;
nierobb409ffa2018-11-23 16:46:12 +0100320 do {
321 Py_BEGIN_ALLOW_THREADS
322 ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
323 Py_END_ALLOW_THREADS
324 } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000325 }
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000326#endif /* HAVE_FLOCK */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000327 if (ret < 0) {
nierobb409ffa2018-11-23 16:46:12 +0100328 return !async_err ? PyErr_SetFromErrno(PyExc_OSError) : NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000329 }
Brett Cannonb7299dd2014-11-09 20:22:01 -0500330 Py_RETURN_NONE;
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000331}
332
Guido van Rossum185ead61998-11-23 15:32:55 +0000333
Brett Cannonb7299dd2014-11-09 20:22:01 -0500334/*[clinic input]
335fcntl.lockf
Guido van Rossum185ead61998-11-23 15:32:55 +0000336
Serhiy Storchaka9975cc52020-10-09 23:00:45 +0300337 fd: fildes
Serhiy Storchaka17d3a582015-03-20 20:04:21 +0200338 cmd as code: int
339 len as lenobj: object(c_default='NULL') = 0
340 start as startobj: object(c_default='NULL') = 0
Brett Cannonb7299dd2014-11-09 20:22:01 -0500341 whence: int = 0
342 /
343
344A wrapper around the fcntl() locking calls.
345
Serhiy Storchaka17d3a582015-03-20 20:04:21 +0200346`fd` is the file descriptor of the file to lock or unlock, and operation is one
Brett Cannonb7299dd2014-11-09 20:22:01 -0500347of the following values:
348
349 LOCK_UN - unlock
350 LOCK_SH - acquire a shared lock
351 LOCK_EX - acquire an exclusive lock
352
353When operation is LOCK_SH or LOCK_EX, it can also be bitwise ORed with
354LOCK_NB to avoid blocking on lock acquisition. If LOCK_NB is used and the
Victor Stinnerd0d51542016-04-09 11:32:58 +0200355lock cannot be acquired, an OSError will be raised and the exception will
Brett Cannonb7299dd2014-11-09 20:22:01 -0500356have an errno attribute set to EACCES or EAGAIN (depending on the operating
357system -- for portability, check for either value).
358
Serhiy Storchaka17d3a582015-03-20 20:04:21 +0200359`len` is the number of bytes to lock, with the default meaning to lock to
360EOF. `start` is the byte offset, relative to `whence`, to that the lock
361starts. `whence` is as with fileobj.seek(), specifically:
Brett Cannonb7299dd2014-11-09 20:22:01 -0500362
363 0 - relative to the start of the file (SEEK_SET)
364 1 - relative to the current buffer position (SEEK_CUR)
365 2 - relative to the end of the file (SEEK_END)
366[clinic start generated code]*/
367
Roger E. Masse919213a1996-12-17 17:42:22 +0000368static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300369fcntl_lockf_impl(PyObject *module, int fd, int code, PyObject *lenobj,
Larry Hastings89964c42015-04-14 18:07:59 -0400370 PyObject *startobj, int whence)
Serhiy Storchaka9975cc52020-10-09 23:00:45 +0300371/*[clinic end generated code: output=4985e7a172e7461a input=5480479fc63a04b8]*/
Guido van Rossumc8643641996-09-11 23:17:20 +0000372{
Brett Cannonb7299dd2014-11-09 20:22:01 -0500373 int ret;
nierobb409ffa2018-11-23 16:46:12 +0100374 int async_err = 0;
Guido van Rossumc8643641996-09-11 23:17:20 +0000375
Saiyang Gou7514f4f2020-02-12 23:47:42 -0800376 if (PySys_Audit("fcntl.lockf", "iiOOi", fd, code, lenobj ? lenobj : Py_None,
377 startobj ? startobj : Py_None, whence) < 0) {
378 return NULL;
379 }
380
Guido van Rossumc8643641996-09-11 23:17:20 +0000381#ifndef LOCK_SH
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000382#define LOCK_SH 1 /* shared lock */
383#define LOCK_EX 2 /* exclusive lock */
384#define LOCK_NB 4 /* don't block when locking */
385#define LOCK_UN 8 /* unlock */
Andrew MacIntyre7bf68332002-03-03 02:59:16 +0000386#endif /* LOCK_SH */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000387 {
388 struct flock l;
389 if (code == LOCK_UN)
390 l.l_type = F_UNLCK;
391 else if (code & LOCK_SH)
392 l.l_type = F_RDLCK;
393 else if (code & LOCK_EX)
394 l.l_type = F_WRLCK;
395 else {
396 PyErr_SetString(PyExc_ValueError,
397 "unrecognized lockf argument");
398 return NULL;
399 }
400 l.l_start = l.l_len = 0;
401 if (startobj != NULL) {
Guido van Rossum056bad91999-01-06 18:44:23 +0000402#if !defined(HAVE_LARGEFILE_SUPPORT)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000403 l.l_start = PyLong_AsLong(startobj);
Guido van Rossum056bad91999-01-06 18:44:23 +0000404#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000405 l.l_start = PyLong_Check(startobj) ?
406 PyLong_AsLongLong(startobj) :
407 PyLong_AsLong(startobj);
Guido van Rossum056bad91999-01-06 18:44:23 +0000408#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000409 if (PyErr_Occurred())
410 return NULL;
411 }
412 if (lenobj != NULL) {
Guido van Rossum056bad91999-01-06 18:44:23 +0000413#if !defined(HAVE_LARGEFILE_SUPPORT)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000414 l.l_len = PyLong_AsLong(lenobj);
Guido van Rossum056bad91999-01-06 18:44:23 +0000415#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000416 l.l_len = PyLong_Check(lenobj) ?
417 PyLong_AsLongLong(lenobj) :
418 PyLong_AsLong(lenobj);
Guido van Rossum056bad91999-01-06 18:44:23 +0000419#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000420 if (PyErr_Occurred())
421 return NULL;
422 }
423 l.l_whence = whence;
nierobb409ffa2018-11-23 16:46:12 +0100424 do {
425 Py_BEGIN_ALLOW_THREADS
426 ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
427 Py_END_ALLOW_THREADS
428 } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000429 }
430 if (ret < 0) {
nierobb409ffa2018-11-23 16:46:12 +0100431 return !async_err ? PyErr_SetFromErrno(PyExc_OSError) : NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000432 }
Brett Cannonb7299dd2014-11-09 20:22:01 -0500433 Py_RETURN_NONE;
Guido van Rossumc8643641996-09-11 23:17:20 +0000434}
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000435
Guido van Rossum02975121992-08-17 08:55:12 +0000436/* List of functions */
437
Roger E. Masse919213a1996-12-17 17:42:22 +0000438static PyMethodDef fcntl_methods[] = {
Brett Cannonb7299dd2014-11-09 20:22:01 -0500439 FCNTL_FCNTL_METHODDEF
440 FCNTL_IOCTL_METHODDEF
441 FCNTL_FLOCK_METHODDEF
442 FCNTL_LOCKF_METHODDEF
443 {NULL, NULL} /* sentinel */
Guido van Rossum02975121992-08-17 08:55:12 +0000444};
445
446
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000447PyDoc_STRVAR(module_doc,
oldkaa0735f2018-02-02 16:52:55 +0800448"This module performs file control and I/O control on file\n\
Guido van Rossum185ead61998-11-23 15:32:55 +0000449descriptors. It is an interface to the fcntl() and ioctl() Unix\n\
450routines. File descriptors can be obtained with the fileno() method of\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000451a file or socket object.");
Guido van Rossum185ead61998-11-23 15:32:55 +0000452
Guido van Rossum02975121992-08-17 08:55:12 +0000453/* Module initialisation */
454
Martin v. Löwis14e73b12003-01-01 09:51:12 +0000455
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000456static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200457all_ins(PyObject* m)
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000458{
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200459 if (PyModule_AddIntMacro(m, LOCK_SH)) return -1;
460 if (PyModule_AddIntMacro(m, LOCK_EX)) return -1;
461 if (PyModule_AddIntMacro(m, LOCK_NB)) return -1;
462 if (PyModule_AddIntMacro(m, LOCK_UN)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000463/* GNU extensions, as of glibc 2.2.4 */
464#ifdef LOCK_MAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200465 if (PyModule_AddIntMacro(m, LOCK_MAND)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000466#endif
467#ifdef LOCK_READ
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200468 if (PyModule_AddIntMacro(m, LOCK_READ)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000469#endif
470#ifdef LOCK_WRITE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200471 if (PyModule_AddIntMacro(m, LOCK_WRITE)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000472#endif
473#ifdef LOCK_RW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200474 if (PyModule_AddIntMacro(m, LOCK_RW)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000475#endif
476
Fred Drake152a25e2001-05-09 21:02:02 +0000477#ifdef F_DUPFD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200478 if (PyModule_AddIntMacro(m, F_DUPFD)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000479#endif
Victor Stinner2716d532013-01-08 00:52:40 +0100480#ifdef F_DUPFD_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200481 if (PyModule_AddIntMacro(m, F_DUPFD_CLOEXEC)) return -1;
Victor Stinner2716d532013-01-08 00:52:40 +0100482#endif
Fred Drake152a25e2001-05-09 21:02:02 +0000483#ifdef F_GETFD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200484 if (PyModule_AddIntMacro(m, F_GETFD)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000485#endif
486#ifdef F_SETFD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200487 if (PyModule_AddIntMacro(m, F_SETFD)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000488#endif
489#ifdef F_GETFL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200490 if (PyModule_AddIntMacro(m, F_GETFL)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000491#endif
492#ifdef F_SETFL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200493 if (PyModule_AddIntMacro(m, F_SETFL)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000494#endif
495#ifdef F_GETLK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200496 if (PyModule_AddIntMacro(m, F_GETLK)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000497#endif
498#ifdef F_SETLK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200499 if (PyModule_AddIntMacro(m, F_SETLK)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000500#endif
501#ifdef F_SETLKW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200502 if (PyModule_AddIntMacro(m, F_SETLKW)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000503#endif
Dong-hee Na3bfc8e02019-10-28 16:31:15 +0900504#ifdef F_OFD_GETLK
505 if (PyModule_AddIntMacro(m, F_OFD_GETLK)) return -1;
506#endif
507#ifdef F_OFD_SETLK
508 if (PyModule_AddIntMacro(m, F_OFD_SETLK)) return -1;
509#endif
510#ifdef F_OFD_SETLKW
511 if (PyModule_AddIntMacro(m, F_OFD_SETLKW)) return -1;
512#endif
Fred Drake152a25e2001-05-09 21:02:02 +0000513#ifdef F_GETOWN
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200514 if (PyModule_AddIntMacro(m, F_GETOWN)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000515#endif
516#ifdef F_SETOWN
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200517 if (PyModule_AddIntMacro(m, F_SETOWN)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000518#endif
Vinay Sharma13f37f22019-08-29 07:26:17 +0530519#ifdef F_GETPATH
520 if (PyModule_AddIntMacro(m, F_GETPATH)) return -1;
521#endif
Fred Drake152a25e2001-05-09 21:02:02 +0000522#ifdef F_GETSIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200523 if (PyModule_AddIntMacro(m, F_GETSIG)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000524#endif
525#ifdef F_SETSIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200526 if (PyModule_AddIntMacro(m, F_SETSIG)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000527#endif
528#ifdef F_RDLCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200529 if (PyModule_AddIntMacro(m, F_RDLCK)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000530#endif
531#ifdef F_WRLCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200532 if (PyModule_AddIntMacro(m, F_WRLCK)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000533#endif
534#ifdef F_UNLCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200535 if (PyModule_AddIntMacro(m, F_UNLCK)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000536#endif
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000537/* LFS constants */
538#ifdef F_GETLK64
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200539 if (PyModule_AddIntMacro(m, F_GETLK64)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000540#endif
541#ifdef F_SETLK64
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200542 if (PyModule_AddIntMacro(m, F_SETLK64)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000543#endif
544#ifdef F_SETLKW64
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200545 if (PyModule_AddIntMacro(m, F_SETLKW64)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000546#endif
547/* GNU extensions, as of glibc 2.2.4. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +0000548#ifdef FASYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200549 if (PyModule_AddIntMacro(m, FASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +0000550#endif
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000551#ifdef F_SETLEASE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200552 if (PyModule_AddIntMacro(m, F_SETLEASE)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000553#endif
554#ifdef F_GETLEASE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200555 if (PyModule_AddIntMacro(m, F_GETLEASE)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000556#endif
557#ifdef F_NOTIFY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200558 if (PyModule_AddIntMacro(m, F_NOTIFY)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000559#endif
560/* Old BSD flock(). */
561#ifdef F_EXLCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200562 if (PyModule_AddIntMacro(m, F_EXLCK)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000563#endif
564#ifdef F_SHLCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200565 if (PyModule_AddIntMacro(m, F_SHLCK)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000566#endif
567
Ruben Vorderman23c0fb82020-10-20 01:30:02 +0200568/* Linux specifics */
569#ifdef F_SETPIPE_SZ
570 if (PyModule_AddIntMacro(m, F_SETPIPE_SZ)) return -1;
571#endif
572#ifdef F_GETPIPE_SZ
573 if (PyModule_AddIntMacro(m, F_GETPIPE_SZ)) return -1;
574#endif
575
Charles-François Natali23e1ecb2011-11-02 18:58:25 +0100576/* OS X specifics */
Georg Brandl6aa2d1f2008-08-12 08:35:52 +0000577#ifdef F_FULLFSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200578 if (PyModule_AddIntMacro(m, F_FULLFSYNC)) return -1;
Georg Brandl6aa2d1f2008-08-12 08:35:52 +0000579#endif
Charles-François Natali23e1ecb2011-11-02 18:58:25 +0100580#ifdef F_NOCACHE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200581 if (PyModule_AddIntMacro(m, F_NOCACHE)) return -1;
Charles-François Natali23e1ecb2011-11-02 18:58:25 +0100582#endif
Georg Brandl6aa2d1f2008-08-12 08:35:52 +0000583
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000584/* For F_{GET|SET}FL */
585#ifdef FD_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200586 if (PyModule_AddIntMacro(m, FD_CLOEXEC)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000587#endif
588
589/* For F_NOTIFY */
590#ifdef DN_ACCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200591 if (PyModule_AddIntMacro(m, DN_ACCESS)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000592#endif
593#ifdef DN_MODIFY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200594 if (PyModule_AddIntMacro(m, DN_MODIFY)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000595#endif
596#ifdef DN_CREATE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200597 if (PyModule_AddIntMacro(m, DN_CREATE)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000598#endif
599#ifdef DN_DELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200600 if (PyModule_AddIntMacro(m, DN_DELETE)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000601#endif
602#ifdef DN_RENAME
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200603 if (PyModule_AddIntMacro(m, DN_RENAME)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000604#endif
605#ifdef DN_ATTRIB
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200606 if (PyModule_AddIntMacro(m, DN_ATTRIB)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000607#endif
608#ifdef DN_MULTISHOT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200609 if (PyModule_AddIntMacro(m, DN_MULTISHOT)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000610#endif
611
Martin v. Löwis14e73b12003-01-01 09:51:12 +0000612#ifdef HAVE_STROPTS_H
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000613 /* Unix 98 guarantees that these are in stropts.h. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200614 if (PyModule_AddIntMacro(m, I_PUSH)) return -1;
615 if (PyModule_AddIntMacro(m, I_POP)) return -1;
616 if (PyModule_AddIntMacro(m, I_LOOK)) return -1;
617 if (PyModule_AddIntMacro(m, I_FLUSH)) return -1;
618 if (PyModule_AddIntMacro(m, I_FLUSHBAND)) return -1;
619 if (PyModule_AddIntMacro(m, I_SETSIG)) return -1;
620 if (PyModule_AddIntMacro(m, I_GETSIG)) return -1;
621 if (PyModule_AddIntMacro(m, I_FIND)) return -1;
622 if (PyModule_AddIntMacro(m, I_PEEK)) return -1;
623 if (PyModule_AddIntMacro(m, I_SRDOPT)) return -1;
624 if (PyModule_AddIntMacro(m, I_GRDOPT)) return -1;
625 if (PyModule_AddIntMacro(m, I_NREAD)) return -1;
626 if (PyModule_AddIntMacro(m, I_FDINSERT)) return -1;
627 if (PyModule_AddIntMacro(m, I_STR)) return -1;
628 if (PyModule_AddIntMacro(m, I_SWROPT)) return -1;
Michael W. Hudson505c4c22003-05-09 10:45:20 +0000629#ifdef I_GWROPT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000630 /* despite the comment above, old-ish glibcs miss a couple... */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200631 if (PyModule_AddIntMacro(m, I_GWROPT)) return -1;
Michael W. Hudson505c4c22003-05-09 10:45:20 +0000632#endif
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200633 if (PyModule_AddIntMacro(m, I_SENDFD)) return -1;
634 if (PyModule_AddIntMacro(m, I_RECVFD)) return -1;
635 if (PyModule_AddIntMacro(m, I_LIST)) return -1;
636 if (PyModule_AddIntMacro(m, I_ATMARK)) return -1;
637 if (PyModule_AddIntMacro(m, I_CKBAND)) return -1;
638 if (PyModule_AddIntMacro(m, I_GETBAND)) return -1;
639 if (PyModule_AddIntMacro(m, I_CANPUT)) return -1;
640 if (PyModule_AddIntMacro(m, I_SETCLTIME)) return -1;
Michael W. Hudson505c4c22003-05-09 10:45:20 +0000641#ifdef I_GETCLTIME
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200642 if (PyModule_AddIntMacro(m, I_GETCLTIME)) return -1;
Michael W. Hudson505c4c22003-05-09 10:45:20 +0000643#endif
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200644 if (PyModule_AddIntMacro(m, I_LINK)) return -1;
645 if (PyModule_AddIntMacro(m, I_UNLINK)) return -1;
646 if (PyModule_AddIntMacro(m, I_PLINK)) return -1;
647 if (PyModule_AddIntMacro(m, I_PUNLINK)) return -1;
Martin v. Löwis14e73b12003-01-01 09:51:12 +0000648#endif
Christian Heimes8cbb5b62019-05-31 18:32:33 +0200649#ifdef F_ADD_SEALS
650 /* Linux: file sealing for memfd_create() */
651 if (PyModule_AddIntMacro(m, F_ADD_SEALS)) return -1;
652 if (PyModule_AddIntMacro(m, F_GET_SEALS)) return -1;
653 if (PyModule_AddIntMacro(m, F_SEAL_SEAL)) return -1;
654 if (PyModule_AddIntMacro(m, F_SEAL_SHRINK)) return -1;
655 if (PyModule_AddIntMacro(m, F_SEAL_GROW)) return -1;
656 if (PyModule_AddIntMacro(m, F_SEAL_WRITE)) return -1;
657#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000658 return 0;
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000659}
660
Dong-hee Nae9684fa2020-06-02 01:12:24 +0900661static int
662fcntl_exec(PyObject *module)
663{
664 if (all_ins(module) < 0) {
665 return -1;
666 }
667 return 0;
668}
669
670static PyModuleDef_Slot fcntl_slots[] = {
671 {Py_mod_exec, fcntl_exec},
672 {0, NULL}
673};
Martin v. Löwis1a214512008-06-11 05:26:20 +0000674
675static struct PyModuleDef fcntlmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000676 PyModuleDef_HEAD_INIT,
Dong-hee Nae9684fa2020-06-02 01:12:24 +0900677 .m_name = "fcntl",
678 .m_doc = module_doc,
679 .m_size = 0,
680 .m_methods = fcntl_methods,
681 .m_slots = fcntl_slots,
Martin v. Löwis1a214512008-06-11 05:26:20 +0000682};
683
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000684PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +0000685PyInit_fcntl(void)
Guido van Rossum02975121992-08-17 08:55:12 +0000686{
Dong-hee Nae9684fa2020-06-02 01:12:24 +0900687 return PyModuleDef_Init(&fcntlmodule);
Guido van Rossum02975121992-08-17 08:55:12 +0000688}