blob: 43f9b22f67207015938cac59f475dcc40aa6fa3e [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
Saiyang Gou7514f4f2020-02-12 23:47:42 -080069 if (PySys_Audit("fcntl.fcntl", "iiO", fd, code, arg ? arg : Py_None) < 0) {
70 return NULL;
71 }
72
Brett Cannonb7299dd2014-11-09 20:22:01 -050073 if (arg != NULL) {
74 int parse_result;
75
76 if (PyArg_Parse(arg, "s#", &str, &len)) {
77 if ((size_t)len > sizeof buf) {
78 PyErr_SetString(PyExc_ValueError,
79 "fcntl string arg too long");
80 return NULL;
81 }
82 memcpy(buf, str, len);
nierobb409ffa2018-11-23 16:46:12 +010083 do {
84 Py_BEGIN_ALLOW_THREADS
85 ret = fcntl(fd, code, buf);
86 Py_END_ALLOW_THREADS
87 } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Brett Cannonb7299dd2014-11-09 20:22:01 -050088 if (ret < 0) {
nierobb409ffa2018-11-23 16:46:12 +010089 return !async_err ? PyErr_SetFromErrno(PyExc_OSError) : NULL;
Brett Cannonb7299dd2014-11-09 20:22:01 -050090 }
91 return PyBytes_FromStringAndSize(buf, len);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000092 }
Brett Cannonb7299dd2014-11-09 20:22:01 -050093
94 PyErr_Clear();
95 parse_result = PyArg_Parse(arg,
Serhiy Storchaka5a8dacf2014-11-10 11:25:50 +020096 "I;fcntl requires a file or file descriptor,"
Brett Cannonb7299dd2014-11-09 20:22:01 -050097 " an integer and optionally a third integer or a string",
98 &int_arg);
99 if (!parse_result) {
100 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000101 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000102 }
Guido van Rossum02975121992-08-17 08:55:12 +0000103
nierobb409ffa2018-11-23 16:46:12 +0100104 do {
105 Py_BEGIN_ALLOW_THREADS
106 ret = fcntl(fd, code, (int)int_arg);
107 Py_END_ALLOW_THREADS
108 } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000109 if (ret < 0) {
nierobb409ffa2018-11-23 16:46:12 +0100110 return !async_err ? PyErr_SetFromErrno(PyExc_OSError) : NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000111 }
112 return PyLong_FromLong((long)ret);
Guido van Rossum02975121992-08-17 08:55:12 +0000113}
114
Guido van Rossum185ead61998-11-23 15:32:55 +0000115
Brett Cannonb7299dd2014-11-09 20:22:01 -0500116/*[clinic input]
117fcntl.ioctl
Guido van Rossum02975121992-08-17 08:55:12 +0000118
Brett Cannonb7299dd2014-11-09 20:22:01 -0500119 fd: object(type='int', converter='conv_descriptor')
Serhiy Storchaka17d3a582015-03-20 20:04:21 +0200120 request as code: unsigned_int(bitwise=True)
121 arg as ob_arg: object(c_default='NULL') = 0
Brett Cannonb7299dd2014-11-09 20:22:01 -0500122 mutate_flag as mutate_arg: bool = True
123 /
124
Serhiy Storchaka17d3a582015-03-20 20:04:21 +0200125Perform the operation `request` on file descriptor `fd`.
Brett Cannonb7299dd2014-11-09 20:22:01 -0500126
Serhiy Storchaka17d3a582015-03-20 20:04:21 +0200127The values used for `request` are operating system dependent, and are available
128as constants in the fcntl or termios library modules, using the same names as
Brett Cannonb7299dd2014-11-09 20:22:01 -0500129used in the relevant C header files.
130
131The argument `arg` is optional, and defaults to 0; it may be an int or a
132buffer containing character data (most likely a string or an array).
133
134If the argument is a mutable buffer (such as an array) and if the
135mutate_flag argument (which is only allowed in this case) is true then the
136buffer is (in effect) passed to the operating system and changes made by
137the OS will be reflected in the contents of the buffer after the call has
138returned. The return value is the integer returned by the ioctl system
139call.
140
Serhiy Storchaka17d3a582015-03-20 20:04:21 +0200141If the argument is a mutable buffer and the mutable_flag argument is false,
142the behavior is as if a string had been passed.
Brett Cannonb7299dd2014-11-09 20:22:01 -0500143
144If the argument is an immutable buffer (most likely a string) then a copy
145of the buffer is passed to the operating system and the return value is a
146string of the same length containing whatever the operating system put in
147the buffer. The length of the arg buffer in this case is not allowed to
148exceed 1024 bytes.
149
150If the arg given is an integer or if none is specified, the result value is
151an integer corresponding to the return value of the ioctl call in the C
152code.
153[clinic start generated code]*/
Guido van Rossum02975121992-08-17 08:55:12 +0000154
Roger E. Masse919213a1996-12-17 17:42:22 +0000155static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300156fcntl_ioctl_impl(PyObject *module, int fd, unsigned int code,
Larry Hastings89964c42015-04-14 18:07:59 -0400157 PyObject *ob_arg, int mutate_arg)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300158/*[clinic end generated code: output=7f7f5840c65991be input=ede70c433cccbbb2]*/
Guido van Rossum02975121992-08-17 08:55:12 +0000159{
Thomas Wouters477c8d52006-05-27 19:21:47 +0000160#define IOCTL_BUFSZ 1024
Serhiy Storchaka483405b2015-02-17 10:14:30 +0200161 /* We use the unsigned non-checked 'I' format for the 'code' parameter
162 because the system expects it to be a 32bit bit field value
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000163 regardless of it being passed as an int or unsigned long on
164 various platforms. See the termios.TIOCSWINSZ constant across
R David Murrayd5a2f0b2013-11-07 10:51:07 -0500165 platforms for an example of this.
Christian Heimese25f35e2008-03-20 10:49:03 +0000166
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000167 If any of the 64bit platforms ever decide to use more than 32bits
168 in their unsigned long ioctl codes this will break and need
169 special casing based on the platform being built on.
170 */
Brett Cannonb7299dd2014-11-09 20:22:01 -0500171 int arg = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000172 int ret;
173 Py_buffer pstr;
174 char *str;
175 Py_ssize_t len;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000176 char buf[IOCTL_BUFSZ+1]; /* argument plus NUL byte */
Guido van Rossum02975121992-08-17 08:55:12 +0000177
Saiyang Gou7514f4f2020-02-12 23:47:42 -0800178 if (PySys_Audit("fcntl.ioctl", "iIO", fd, code,
179 ob_arg ? ob_arg : Py_None) < 0) {
180 return NULL;
181 }
182
Brett Cannonb7299dd2014-11-09 20:22:01 -0500183 if (ob_arg != NULL) {
184 if (PyArg_Parse(ob_arg, "w*:ioctl", &pstr)) {
185 char *arg;
186 str = pstr.buf;
187 len = pstr.len;
Michael W. Hudsonf0089982003-03-03 12:29:42 +0000188
Brett Cannonb7299dd2014-11-09 20:22:01 -0500189 if (mutate_arg) {
190 if (len <= IOCTL_BUFSZ) {
191 memcpy(buf, str, len);
192 buf[len] = '\0';
193 arg = buf;
194 }
195 else {
196 arg = str;
197 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000198 }
199 else {
Brett Cannonb7299dd2014-11-09 20:22:01 -0500200 if (len > IOCTL_BUFSZ) {
201 PyBuffer_Release(&pstr);
202 PyErr_SetString(PyExc_ValueError,
203 "ioctl string arg too long");
204 return NULL;
205 }
206 else {
207 memcpy(buf, str, len);
208 buf[len] = '\0';
209 arg = buf;
210 }
211 }
212 if (buf == arg) {
213 Py_BEGIN_ALLOW_THREADS /* think array.resize() */
214 ret = ioctl(fd, code, arg);
215 Py_END_ALLOW_THREADS
216 }
217 else {
218 ret = ioctl(fd, code, arg);
219 }
220 if (mutate_arg && (len <= IOCTL_BUFSZ)) {
221 memcpy(str, buf, len);
222 }
223 PyBuffer_Release(&pstr); /* No further access to str below this point */
224 if (ret < 0) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300225 PyErr_SetFromErrno(PyExc_OSError);
Brett Cannonb7299dd2014-11-09 20:22:01 -0500226 return NULL;
227 }
228 if (mutate_arg) {
229 return PyLong_FromLong(ret);
230 }
231 else {
232 return PyBytes_FromStringAndSize(buf, len);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000233 }
234 }
Brett Cannonb7299dd2014-11-09 20:22:01 -0500235
236 PyErr_Clear();
237 if (PyArg_Parse(ob_arg, "s*:ioctl", &pstr)) {
238 str = pstr.buf;
239 len = pstr.len;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000240 if (len > IOCTL_BUFSZ) {
241 PyBuffer_Release(&pstr);
242 PyErr_SetString(PyExc_ValueError,
Brett Cannonb7299dd2014-11-09 20:22:01 -0500243 "ioctl string arg too long");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000244 return NULL;
245 }
Brett Cannonb7299dd2014-11-09 20:22:01 -0500246 memcpy(buf, str, len);
247 buf[len] = '\0';
248 Py_BEGIN_ALLOW_THREADS
249 ret = ioctl(fd, code, buf);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000250 Py_END_ALLOW_THREADS
Brett Cannonb7299dd2014-11-09 20:22:01 -0500251 if (ret < 0) {
252 PyBuffer_Release(&pstr);
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300253 PyErr_SetFromErrno(PyExc_OSError);
Brett Cannonb7299dd2014-11-09 20:22:01 -0500254 return NULL;
255 }
256 PyBuffer_Release(&pstr);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000257 return PyBytes_FromStringAndSize(buf, len);
258 }
Michael W. Hudsonf0089982003-03-03 12:29:42 +0000259
Brett Cannonb7299dd2014-11-09 20:22:01 -0500260 PyErr_Clear();
261 if (!PyArg_Parse(ob_arg,
262 "i;ioctl requires a file or file descriptor,"
263 " an integer and optionally an integer or buffer argument",
264 &arg)) {
265 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000266 }
Brett Cannonb7299dd2014-11-09 20:22:01 -0500267 // Fall-through to outside the 'if' statement.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000268 }
269 Py_BEGIN_ALLOW_THREADS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000270 ret = ioctl(fd, code, arg);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000271 Py_END_ALLOW_THREADS
272 if (ret < 0) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300273 PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000274 return NULL;
275 }
276 return PyLong_FromLong((long)ret);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000277#undef IOCTL_BUFSZ
Guido van Rossum02975121992-08-17 08:55:12 +0000278}
279
Brett Cannonb7299dd2014-11-09 20:22:01 -0500280/*[clinic input]
281fcntl.flock
Guido van Rossum185ead61998-11-23 15:32:55 +0000282
Brett Cannonb7299dd2014-11-09 20:22:01 -0500283 fd: object(type='int', converter='conv_descriptor')
Serhiy Storchaka17d3a582015-03-20 20:04:21 +0200284 operation as code: int
Brett Cannonb7299dd2014-11-09 20:22:01 -0500285 /
Guido van Rossum02975121992-08-17 08:55:12 +0000286
Serhiy Storchaka17d3a582015-03-20 20:04:21 +0200287Perform the lock operation `operation` on file descriptor `fd`.
Brett Cannonb7299dd2014-11-09 20:22:01 -0500288
289See the Unix manual page for flock(2) for details (On some systems, this
290function is emulated using fcntl()).
291[clinic start generated code]*/
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000292
Roger E. Masse919213a1996-12-17 17:42:22 +0000293static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300294fcntl_flock_impl(PyObject *module, int fd, int code)
295/*[clinic end generated code: output=84059e2b37d2fc64 input=b70a0a41ca22a8a0]*/
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000296{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000297 int ret;
nierobb409ffa2018-11-23 16:46:12 +0100298 int async_err = 0;
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000299
Saiyang Gou7514f4f2020-02-12 23:47:42 -0800300 if (PySys_Audit("fcntl.flock", "ii", fd, code) < 0) {
301 return NULL;
302 }
303
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000304#ifdef HAVE_FLOCK
nierobb409ffa2018-11-23 16:46:12 +0100305 do {
306 Py_BEGIN_ALLOW_THREADS
307 ret = flock(fd, code);
308 Py_END_ALLOW_THREADS
309 } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000310#else
311
312#ifndef LOCK_SH
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000313#define LOCK_SH 1 /* shared lock */
314#define LOCK_EX 2 /* exclusive lock */
315#define LOCK_NB 4 /* don't block when locking */
316#define LOCK_UN 8 /* unlock */
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000317#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000318 {
319 struct flock l;
320 if (code == LOCK_UN)
321 l.l_type = F_UNLCK;
322 else if (code & LOCK_SH)
323 l.l_type = F_RDLCK;
324 else if (code & LOCK_EX)
325 l.l_type = F_WRLCK;
326 else {
327 PyErr_SetString(PyExc_ValueError,
328 "unrecognized flock argument");
329 return NULL;
330 }
331 l.l_whence = l.l_start = l.l_len = 0;
nierobb409ffa2018-11-23 16:46:12 +0100332 do {
333 Py_BEGIN_ALLOW_THREADS
334 ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
335 Py_END_ALLOW_THREADS
336 } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000337 }
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000338#endif /* HAVE_FLOCK */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000339 if (ret < 0) {
nierobb409ffa2018-11-23 16:46:12 +0100340 return !async_err ? PyErr_SetFromErrno(PyExc_OSError) : NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000341 }
Brett Cannonb7299dd2014-11-09 20:22:01 -0500342 Py_RETURN_NONE;
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000343}
344
Guido van Rossum185ead61998-11-23 15:32:55 +0000345
Brett Cannonb7299dd2014-11-09 20:22:01 -0500346/*[clinic input]
347fcntl.lockf
Guido van Rossum185ead61998-11-23 15:32:55 +0000348
Brett Cannonb7299dd2014-11-09 20:22:01 -0500349 fd: object(type='int', converter='conv_descriptor')
Serhiy Storchaka17d3a582015-03-20 20:04:21 +0200350 cmd as code: int
351 len as lenobj: object(c_default='NULL') = 0
352 start as startobj: object(c_default='NULL') = 0
Brett Cannonb7299dd2014-11-09 20:22:01 -0500353 whence: int = 0
354 /
355
356A wrapper around the fcntl() locking calls.
357
Serhiy Storchaka17d3a582015-03-20 20:04:21 +0200358`fd` is the file descriptor of the file to lock or unlock, and operation is one
Brett Cannonb7299dd2014-11-09 20:22:01 -0500359of the following values:
360
361 LOCK_UN - unlock
362 LOCK_SH - acquire a shared lock
363 LOCK_EX - acquire an exclusive lock
364
365When operation is LOCK_SH or LOCK_EX, it can also be bitwise ORed with
366LOCK_NB to avoid blocking on lock acquisition. If LOCK_NB is used and the
Victor Stinnerd0d51542016-04-09 11:32:58 +0200367lock cannot be acquired, an OSError will be raised and the exception will
Brett Cannonb7299dd2014-11-09 20:22:01 -0500368have an errno attribute set to EACCES or EAGAIN (depending on the operating
369system -- for portability, check for either value).
370
Serhiy Storchaka17d3a582015-03-20 20:04:21 +0200371`len` is the number of bytes to lock, with the default meaning to lock to
372EOF. `start` is the byte offset, relative to `whence`, to that the lock
373starts. `whence` is as with fileobj.seek(), specifically:
Brett Cannonb7299dd2014-11-09 20:22:01 -0500374
375 0 - relative to the start of the file (SEEK_SET)
376 1 - relative to the current buffer position (SEEK_CUR)
377 2 - relative to the end of the file (SEEK_END)
378[clinic start generated code]*/
379
Roger E. Masse919213a1996-12-17 17:42:22 +0000380static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300381fcntl_lockf_impl(PyObject *module, int fd, int code, PyObject *lenobj,
Larry Hastings89964c42015-04-14 18:07:59 -0400382 PyObject *startobj, int whence)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +0300383/*[clinic end generated code: output=4985e7a172e7461a input=3a5dc01b04371f1a]*/
Guido van Rossumc8643641996-09-11 23:17:20 +0000384{
Brett Cannonb7299dd2014-11-09 20:22:01 -0500385 int ret;
nierobb409ffa2018-11-23 16:46:12 +0100386 int async_err = 0;
Guido van Rossumc8643641996-09-11 23:17:20 +0000387
Saiyang Gou7514f4f2020-02-12 23:47:42 -0800388 if (PySys_Audit("fcntl.lockf", "iiOOi", fd, code, lenobj ? lenobj : Py_None,
389 startobj ? startobj : Py_None, whence) < 0) {
390 return NULL;
391 }
392
Guido van Rossumc8643641996-09-11 23:17:20 +0000393#ifndef LOCK_SH
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000394#define LOCK_SH 1 /* shared lock */
395#define LOCK_EX 2 /* exclusive lock */
396#define LOCK_NB 4 /* don't block when locking */
397#define LOCK_UN 8 /* unlock */
Andrew MacIntyre7bf68332002-03-03 02:59:16 +0000398#endif /* LOCK_SH */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000399 {
400 struct flock l;
401 if (code == LOCK_UN)
402 l.l_type = F_UNLCK;
403 else if (code & LOCK_SH)
404 l.l_type = F_RDLCK;
405 else if (code & LOCK_EX)
406 l.l_type = F_WRLCK;
407 else {
408 PyErr_SetString(PyExc_ValueError,
409 "unrecognized lockf argument");
410 return NULL;
411 }
412 l.l_start = l.l_len = 0;
413 if (startobj != NULL) {
Guido van Rossum056bad91999-01-06 18:44:23 +0000414#if !defined(HAVE_LARGEFILE_SUPPORT)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000415 l.l_start = PyLong_AsLong(startobj);
Guido van Rossum056bad91999-01-06 18:44:23 +0000416#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000417 l.l_start = PyLong_Check(startobj) ?
418 PyLong_AsLongLong(startobj) :
419 PyLong_AsLong(startobj);
Guido van Rossum056bad91999-01-06 18:44:23 +0000420#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000421 if (PyErr_Occurred())
422 return NULL;
423 }
424 if (lenobj != NULL) {
Guido van Rossum056bad91999-01-06 18:44:23 +0000425#if !defined(HAVE_LARGEFILE_SUPPORT)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000426 l.l_len = PyLong_AsLong(lenobj);
Guido van Rossum056bad91999-01-06 18:44:23 +0000427#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000428 l.l_len = PyLong_Check(lenobj) ?
429 PyLong_AsLongLong(lenobj) :
430 PyLong_AsLong(lenobj);
Guido van Rossum056bad91999-01-06 18:44:23 +0000431#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000432 if (PyErr_Occurred())
433 return NULL;
434 }
435 l.l_whence = whence;
nierobb409ffa2018-11-23 16:46:12 +0100436 do {
437 Py_BEGIN_ALLOW_THREADS
438 ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
439 Py_END_ALLOW_THREADS
440 } while (ret == -1 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000441 }
442 if (ret < 0) {
nierobb409ffa2018-11-23 16:46:12 +0100443 return !async_err ? PyErr_SetFromErrno(PyExc_OSError) : NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000444 }
Brett Cannonb7299dd2014-11-09 20:22:01 -0500445 Py_RETURN_NONE;
Guido van Rossumc8643641996-09-11 23:17:20 +0000446}
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000447
Guido van Rossum02975121992-08-17 08:55:12 +0000448/* List of functions */
449
Roger E. Masse919213a1996-12-17 17:42:22 +0000450static PyMethodDef fcntl_methods[] = {
Brett Cannonb7299dd2014-11-09 20:22:01 -0500451 FCNTL_FCNTL_METHODDEF
452 FCNTL_IOCTL_METHODDEF
453 FCNTL_FLOCK_METHODDEF
454 FCNTL_LOCKF_METHODDEF
455 {NULL, NULL} /* sentinel */
Guido van Rossum02975121992-08-17 08:55:12 +0000456};
457
458
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000459PyDoc_STRVAR(module_doc,
oldkaa0735f2018-02-02 16:52:55 +0800460"This module performs file control and I/O control on file\n\
Guido van Rossum185ead61998-11-23 15:32:55 +0000461descriptors. It is an interface to the fcntl() and ioctl() Unix\n\
462routines. File descriptors can be obtained with the fileno() method of\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000463a file or socket object.");
Guido van Rossum185ead61998-11-23 15:32:55 +0000464
Guido van Rossum02975121992-08-17 08:55:12 +0000465/* Module initialisation */
466
Martin v. Löwis14e73b12003-01-01 09:51:12 +0000467
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000468static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200469all_ins(PyObject* m)
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000470{
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200471 if (PyModule_AddIntMacro(m, LOCK_SH)) return -1;
472 if (PyModule_AddIntMacro(m, LOCK_EX)) return -1;
473 if (PyModule_AddIntMacro(m, LOCK_NB)) return -1;
474 if (PyModule_AddIntMacro(m, LOCK_UN)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000475/* GNU extensions, as of glibc 2.2.4 */
476#ifdef LOCK_MAND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200477 if (PyModule_AddIntMacro(m, LOCK_MAND)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000478#endif
479#ifdef LOCK_READ
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200480 if (PyModule_AddIntMacro(m, LOCK_READ)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000481#endif
482#ifdef LOCK_WRITE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200483 if (PyModule_AddIntMacro(m, LOCK_WRITE)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000484#endif
485#ifdef LOCK_RW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200486 if (PyModule_AddIntMacro(m, LOCK_RW)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000487#endif
488
Fred Drake152a25e2001-05-09 21:02:02 +0000489#ifdef F_DUPFD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200490 if (PyModule_AddIntMacro(m, F_DUPFD)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000491#endif
Victor Stinner2716d532013-01-08 00:52:40 +0100492#ifdef F_DUPFD_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200493 if (PyModule_AddIntMacro(m, F_DUPFD_CLOEXEC)) return -1;
Victor Stinner2716d532013-01-08 00:52:40 +0100494#endif
Fred Drake152a25e2001-05-09 21:02:02 +0000495#ifdef F_GETFD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200496 if (PyModule_AddIntMacro(m, F_GETFD)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000497#endif
498#ifdef F_SETFD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200499 if (PyModule_AddIntMacro(m, F_SETFD)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000500#endif
501#ifdef F_GETFL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200502 if (PyModule_AddIntMacro(m, F_GETFL)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000503#endif
504#ifdef F_SETFL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200505 if (PyModule_AddIntMacro(m, F_SETFL)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000506#endif
507#ifdef F_GETLK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200508 if (PyModule_AddIntMacro(m, F_GETLK)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000509#endif
510#ifdef F_SETLK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200511 if (PyModule_AddIntMacro(m, F_SETLK)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000512#endif
513#ifdef F_SETLKW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200514 if (PyModule_AddIntMacro(m, F_SETLKW)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000515#endif
Dong-hee Na3bfc8e02019-10-28 16:31:15 +0900516#ifdef F_OFD_GETLK
517 if (PyModule_AddIntMacro(m, F_OFD_GETLK)) return -1;
518#endif
519#ifdef F_OFD_SETLK
520 if (PyModule_AddIntMacro(m, F_OFD_SETLK)) return -1;
521#endif
522#ifdef F_OFD_SETLKW
523 if (PyModule_AddIntMacro(m, F_OFD_SETLKW)) return -1;
524#endif
Fred Drake152a25e2001-05-09 21:02:02 +0000525#ifdef F_GETOWN
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200526 if (PyModule_AddIntMacro(m, F_GETOWN)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000527#endif
528#ifdef F_SETOWN
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200529 if (PyModule_AddIntMacro(m, F_SETOWN)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000530#endif
Vinay Sharma13f37f22019-08-29 07:26:17 +0530531#ifdef F_GETPATH
532 if (PyModule_AddIntMacro(m, F_GETPATH)) return -1;
533#endif
Fred Drake152a25e2001-05-09 21:02:02 +0000534#ifdef F_GETSIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200535 if (PyModule_AddIntMacro(m, F_GETSIG)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000536#endif
537#ifdef F_SETSIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200538 if (PyModule_AddIntMacro(m, F_SETSIG)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000539#endif
540#ifdef F_RDLCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200541 if (PyModule_AddIntMacro(m, F_RDLCK)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000542#endif
543#ifdef F_WRLCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200544 if (PyModule_AddIntMacro(m, F_WRLCK)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000545#endif
546#ifdef F_UNLCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200547 if (PyModule_AddIntMacro(m, F_UNLCK)) return -1;
Fred Drake152a25e2001-05-09 21:02:02 +0000548#endif
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000549/* LFS constants */
550#ifdef F_GETLK64
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200551 if (PyModule_AddIntMacro(m, F_GETLK64)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000552#endif
553#ifdef F_SETLK64
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200554 if (PyModule_AddIntMacro(m, F_SETLK64)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000555#endif
556#ifdef F_SETLKW64
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200557 if (PyModule_AddIntMacro(m, F_SETLKW64)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000558#endif
559/* GNU extensions, as of glibc 2.2.4. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +0000560#ifdef FASYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200561 if (PyModule_AddIntMacro(m, FASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +0000562#endif
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000563#ifdef F_SETLEASE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200564 if (PyModule_AddIntMacro(m, F_SETLEASE)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000565#endif
566#ifdef F_GETLEASE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200567 if (PyModule_AddIntMacro(m, F_GETLEASE)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000568#endif
569#ifdef F_NOTIFY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200570 if (PyModule_AddIntMacro(m, F_NOTIFY)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000571#endif
572/* Old BSD flock(). */
573#ifdef F_EXLCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200574 if (PyModule_AddIntMacro(m, F_EXLCK)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000575#endif
576#ifdef F_SHLCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200577 if (PyModule_AddIntMacro(m, F_SHLCK)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000578#endif
579
Charles-François Natali23e1ecb2011-11-02 18:58:25 +0100580/* OS X specifics */
Georg Brandl6aa2d1f2008-08-12 08:35:52 +0000581#ifdef F_FULLFSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200582 if (PyModule_AddIntMacro(m, F_FULLFSYNC)) return -1;
Georg Brandl6aa2d1f2008-08-12 08:35:52 +0000583#endif
Charles-François Natali23e1ecb2011-11-02 18:58:25 +0100584#ifdef F_NOCACHE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200585 if (PyModule_AddIntMacro(m, F_NOCACHE)) return -1;
Charles-François Natali23e1ecb2011-11-02 18:58:25 +0100586#endif
Georg Brandl6aa2d1f2008-08-12 08:35:52 +0000587
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000588/* For F_{GET|SET}FL */
589#ifdef FD_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200590 if (PyModule_AddIntMacro(m, FD_CLOEXEC)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000591#endif
592
593/* For F_NOTIFY */
594#ifdef DN_ACCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200595 if (PyModule_AddIntMacro(m, DN_ACCESS)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000596#endif
597#ifdef DN_MODIFY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200598 if (PyModule_AddIntMacro(m, DN_MODIFY)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000599#endif
600#ifdef DN_CREATE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200601 if (PyModule_AddIntMacro(m, DN_CREATE)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000602#endif
603#ifdef DN_DELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200604 if (PyModule_AddIntMacro(m, DN_DELETE)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000605#endif
606#ifdef DN_RENAME
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200607 if (PyModule_AddIntMacro(m, DN_RENAME)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000608#endif
609#ifdef DN_ATTRIB
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200610 if (PyModule_AddIntMacro(m, DN_ATTRIB)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000611#endif
612#ifdef DN_MULTISHOT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200613 if (PyModule_AddIntMacro(m, DN_MULTISHOT)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000614#endif
615
Martin v. Löwis14e73b12003-01-01 09:51:12 +0000616#ifdef HAVE_STROPTS_H
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000617 /* Unix 98 guarantees that these are in stropts.h. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200618 if (PyModule_AddIntMacro(m, I_PUSH)) return -1;
619 if (PyModule_AddIntMacro(m, I_POP)) return -1;
620 if (PyModule_AddIntMacro(m, I_LOOK)) return -1;
621 if (PyModule_AddIntMacro(m, I_FLUSH)) return -1;
622 if (PyModule_AddIntMacro(m, I_FLUSHBAND)) return -1;
623 if (PyModule_AddIntMacro(m, I_SETSIG)) return -1;
624 if (PyModule_AddIntMacro(m, I_GETSIG)) return -1;
625 if (PyModule_AddIntMacro(m, I_FIND)) return -1;
626 if (PyModule_AddIntMacro(m, I_PEEK)) return -1;
627 if (PyModule_AddIntMacro(m, I_SRDOPT)) return -1;
628 if (PyModule_AddIntMacro(m, I_GRDOPT)) return -1;
629 if (PyModule_AddIntMacro(m, I_NREAD)) return -1;
630 if (PyModule_AddIntMacro(m, I_FDINSERT)) return -1;
631 if (PyModule_AddIntMacro(m, I_STR)) return -1;
632 if (PyModule_AddIntMacro(m, I_SWROPT)) return -1;
Michael W. Hudson505c4c22003-05-09 10:45:20 +0000633#ifdef I_GWROPT
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000634 /* despite the comment above, old-ish glibcs miss a couple... */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200635 if (PyModule_AddIntMacro(m, I_GWROPT)) return -1;
Michael W. Hudson505c4c22003-05-09 10:45:20 +0000636#endif
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200637 if (PyModule_AddIntMacro(m, I_SENDFD)) return -1;
638 if (PyModule_AddIntMacro(m, I_RECVFD)) return -1;
639 if (PyModule_AddIntMacro(m, I_LIST)) return -1;
640 if (PyModule_AddIntMacro(m, I_ATMARK)) return -1;
641 if (PyModule_AddIntMacro(m, I_CKBAND)) return -1;
642 if (PyModule_AddIntMacro(m, I_GETBAND)) return -1;
643 if (PyModule_AddIntMacro(m, I_CANPUT)) return -1;
644 if (PyModule_AddIntMacro(m, I_SETCLTIME)) return -1;
Michael W. Hudson505c4c22003-05-09 10:45:20 +0000645#ifdef I_GETCLTIME
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200646 if (PyModule_AddIntMacro(m, I_GETCLTIME)) return -1;
Michael W. Hudson505c4c22003-05-09 10:45:20 +0000647#endif
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200648 if (PyModule_AddIntMacro(m, I_LINK)) return -1;
649 if (PyModule_AddIntMacro(m, I_UNLINK)) return -1;
650 if (PyModule_AddIntMacro(m, I_PLINK)) return -1;
651 if (PyModule_AddIntMacro(m, I_PUNLINK)) return -1;
Martin v. Löwis14e73b12003-01-01 09:51:12 +0000652#endif
Christian Heimes8cbb5b62019-05-31 18:32:33 +0200653#ifdef F_ADD_SEALS
654 /* Linux: file sealing for memfd_create() */
655 if (PyModule_AddIntMacro(m, F_ADD_SEALS)) return -1;
656 if (PyModule_AddIntMacro(m, F_GET_SEALS)) return -1;
657 if (PyModule_AddIntMacro(m, F_SEAL_SEAL)) return -1;
658 if (PyModule_AddIntMacro(m, F_SEAL_SHRINK)) return -1;
659 if (PyModule_AddIntMacro(m, F_SEAL_GROW)) return -1;
660 if (PyModule_AddIntMacro(m, F_SEAL_WRITE)) return -1;
661#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000662 return 0;
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000663}
664
Martin v. Löwis1a214512008-06-11 05:26:20 +0000665
666static struct PyModuleDef fcntlmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000667 PyModuleDef_HEAD_INIT,
668 "fcntl",
669 module_doc,
670 -1,
671 fcntl_methods,
672 NULL,
673 NULL,
674 NULL,
675 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +0000676};
677
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000678PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +0000679PyInit_fcntl(void)
Guido van Rossum02975121992-08-17 08:55:12 +0000680{
Charles-Francois Natali74ca8862013-05-20 19:13:19 +0200681 PyObject *m;
Guido van Rossum02975121992-08-17 08:55:12 +0000682
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000683 /* Create the module and add the functions and documentation */
684 m = PyModule_Create(&fcntlmodule);
685 if (m == NULL)
686 return NULL;
Guido van Rossum02975121992-08-17 08:55:12 +0000687
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000688 /* Add some symbolic constants to the module */
Brandt Bucher54b32c92019-11-19 11:16:29 -0800689 if (all_ins(m) < 0) {
690 Py_DECREF(m);
Charles-François Natali5abca142013-12-01 14:30:47 +0100691 return NULL;
Brandt Bucher54b32c92019-11-19 11:16:29 -0800692 }
Charles-François Natali5abca142013-12-01 14:30:47 +0100693
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000694 return m;
Guido van Rossum02975121992-08-17 08:55:12 +0000695}