blob: 5331ea8c4d690ac8f4910292d55b6e2bdacbcf8c [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
Fred Drake152a25e2001-05-09 21:02:02 +000018static int
19conv_descriptor(PyObject *object, int *target)
20{
21 int fd = PyObject_AsFileDescriptor(object);
22
23 if (fd < 0)
24 return 0;
25 *target = fd;
26 return 1;
27}
28
29
Guido van Rossum02975121992-08-17 08:55:12 +000030/* fcntl(fd, opt, [arg]) */
31
Roger E. Masse919213a1996-12-17 17:42:22 +000032static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +000033fcntl_fcntl(PyObject *self, PyObject *args)
Guido van Rossum02975121992-08-17 08:55:12 +000034{
35 int fd;
36 int code;
37 int arg;
38 int ret;
39 char *str;
Thomas Wouters26cc63f2006-03-02 00:21:10 +000040 Py_ssize_t len;
Guido van Rossum02975121992-08-17 08:55:12 +000041 char buf[1024];
42
Fred Drake152a25e2001-05-09 21:02:02 +000043 if (PyArg_ParseTuple(args, "O&is#:fcntl",
44 conv_descriptor, &fd, &code, &str, &len)) {
Guido van Rossum02975121992-08-17 08:55:12 +000045 if (len > sizeof buf) {
Roger E. Masse919213a1996-12-17 17:42:22 +000046 PyErr_SetString(PyExc_ValueError,
47 "fcntl string arg too long");
Guido van Rossum02975121992-08-17 08:55:12 +000048 return NULL;
49 }
50 memcpy(buf, str, len);
Roger E. Masse919213a1996-12-17 17:42:22 +000051 Py_BEGIN_ALLOW_THREADS
Guido van Rossum903f4871995-10-07 19:18:22 +000052 ret = fcntl(fd, code, buf);
Roger E. Masse919213a1996-12-17 17:42:22 +000053 Py_END_ALLOW_THREADS
Guido van Rossum903f4871995-10-07 19:18:22 +000054 if (ret < 0) {
Roger E. Masse919213a1996-12-17 17:42:22 +000055 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum02975121992-08-17 08:55:12 +000056 return NULL;
57 }
Christian Heimes72b710a2008-05-26 13:28:38 +000058 return PyBytes_FromStringAndSize(buf, len);
Guido van Rossum02975121992-08-17 08:55:12 +000059 }
60
Roger E. Masse919213a1996-12-17 17:42:22 +000061 PyErr_Clear();
Guido van Rossuma2214c32000-08-02 20:46:51 +000062 arg = 0;
Fred Drake152a25e2001-05-09 21:02:02 +000063 if (!PyArg_ParseTuple(args,
64 "O&i|i;fcntl requires a file or file descriptor,"
65 " an integer and optionally a third integer or a string",
66 conv_descriptor, &fd, &code, &arg)) {
Guido van Rossuma2214c32000-08-02 20:46:51 +000067 return NULL;
Guido van Rossum02975121992-08-17 08:55:12 +000068 }
Roger E. Masse919213a1996-12-17 17:42:22 +000069 Py_BEGIN_ALLOW_THREADS
Guido van Rossum02975121992-08-17 08:55:12 +000070 ret = fcntl(fd, code, arg);
Roger E. Masse919213a1996-12-17 17:42:22 +000071 Py_END_ALLOW_THREADS
Guido van Rossum02975121992-08-17 08:55:12 +000072 if (ret < 0) {
Roger E. Masse919213a1996-12-17 17:42:22 +000073 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum02975121992-08-17 08:55:12 +000074 return NULL;
75 }
Christian Heimes217cfd12007-12-02 14:31:20 +000076 return PyLong_FromLong((long)ret);
Guido van Rossum02975121992-08-17 08:55:12 +000077}
78
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000079PyDoc_STRVAR(fcntl_doc,
Guido van Rossum185ead61998-11-23 15:32:55 +000080"fcntl(fd, opt, [arg])\n\
81\n\
82Perform the requested operation on file descriptor fd. The operation\n\
Fred Drake1d531992001-05-10 15:54:32 +000083is defined by op and is operating system dependent. These constants are\n\
84available from the fcntl module. The argument arg is optional, and\n\
85defaults to 0; it may be an int or a string. If arg is given as a string,\n\
86the return value of fcntl is a string of that length, containing the\n\
87resulting value put in the arg buffer by the operating system.The length\n\
88of the arg string is not allowed to exceed 1024 bytes. If the arg given\n\
89is an integer or if none is specified, the result value is an integer\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000090corresponding to the return value of the fcntl call in the C code.");
Guido van Rossum185ead61998-11-23 15:32:55 +000091
Guido van Rossum02975121992-08-17 08:55:12 +000092
93/* ioctl(fd, opt, [arg]) */
94
Roger E. Masse919213a1996-12-17 17:42:22 +000095static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +000096fcntl_ioctl(PyObject *self, PyObject *args)
Guido van Rossum02975121992-08-17 08:55:12 +000097{
Thomas Wouters477c8d52006-05-27 19:21:47 +000098#define IOCTL_BUFSZ 1024
Guido van Rossum02975121992-08-17 08:55:12 +000099 int fd;
Christian Heimese25f35e2008-03-20 10:49:03 +0000100 /* In PyArg_ParseTuple below, we use the unsigned non-checked 'I'
101 format for the 'code' parameter because Python turns 0x8000000
102 into either a large positive number (PyLong or PyInt on 64-bit
103 platforms) or a negative number on others (32-bit PyInt)
104 whereas the system expects it to be a 32bit bit field value
105 regardless of it being passed as an int or unsigned long on
106 various platforms. See the termios.TIOCSWINSZ constant across
107 platforms for an example of thise.
108
109 If any of the 64bit platforms ever decide to use more than 32bits
110 in their unsigned long ioctl codes this will break and need
111 special casing based on the platform being built on.
112 */
113 unsigned int code;
Guido van Rossum02975121992-08-17 08:55:12 +0000114 int arg;
115 int ret;
Martin v. Löwis423be952008-08-13 15:53:07 +0000116 Py_buffer pstr;
Guido van Rossum02975121992-08-17 08:55:12 +0000117 char *str;
Thomas Wouters26cc63f2006-03-02 00:21:10 +0000118 Py_ssize_t len;
Michael W. Hudson02d74f62004-11-30 14:31:54 +0000119 int mutate_arg = 1;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000120 char buf[IOCTL_BUFSZ+1]; /* argument plus NUL byte */
Guido van Rossum02975121992-08-17 08:55:12 +0000121
Martin v. Löwis423be952008-08-13 15:53:07 +0000122 if (PyArg_ParseTuple(args, "O&Iw*|i:ioctl",
Michael W. Hudsonf0089982003-03-03 12:29:42 +0000123 conv_descriptor, &fd, &code,
Martin v. Löwis423be952008-08-13 15:53:07 +0000124 &pstr, &mutate_arg)) {
Michael W. Hudsonf0089982003-03-03 12:29:42 +0000125 char *arg;
Martin v. Löwis423be952008-08-13 15:53:07 +0000126 str = pstr.buf;
127 len = pstr.len;
Michael W. Hudsonf0089982003-03-03 12:29:42 +0000128
Michael W. Hudsonf0089982003-03-03 12:29:42 +0000129 if (mutate_arg) {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000130 if (len <= IOCTL_BUFSZ) {
Michael W. Hudsonf0089982003-03-03 12:29:42 +0000131 memcpy(buf, str, len);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000132 buf[len] = '\0';
Michael W. Hudsonf0089982003-03-03 12:29:42 +0000133 arg = buf;
134 }
135 else {
136 arg = str;
137 }
138 }
139 else {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000140 if (len > IOCTL_BUFSZ) {
Martin v. Löwis423be952008-08-13 15:53:07 +0000141 PyBuffer_Release(&pstr);
Michael W. Hudsonf0089982003-03-03 12:29:42 +0000142 PyErr_SetString(PyExc_ValueError,
143 "ioctl string arg too long");
144 return NULL;
145 }
146 else {
147 memcpy(buf, str, len);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000148 buf[len] = '\0';
Michael W. Hudsonf0089982003-03-03 12:29:42 +0000149 arg = buf;
150 }
151 }
152 if (buf == arg) {
153 Py_BEGIN_ALLOW_THREADS /* think array.resize() */
154 ret = ioctl(fd, code, arg);
155 Py_END_ALLOW_THREADS
156 }
157 else {
158 ret = ioctl(fd, code, arg);
159 }
Thomas Wouters477c8d52006-05-27 19:21:47 +0000160 if (mutate_arg && (len < IOCTL_BUFSZ)) {
Michael W. Hudsonf0089982003-03-03 12:29:42 +0000161 memcpy(str, buf, len);
162 }
Martin v. Löwis423be952008-08-13 15:53:07 +0000163 PyBuffer_Release(&pstr); /* No further access to str below this point */
Michael W. Hudsonf0089982003-03-03 12:29:42 +0000164 if (ret < 0) {
165 PyErr_SetFromErrno(PyExc_IOError);
166 return NULL;
167 }
168 if (mutate_arg) {
Christian Heimes217cfd12007-12-02 14:31:20 +0000169 return PyLong_FromLong(ret);
Michael W. Hudsonf0089982003-03-03 12:29:42 +0000170 }
171 else {
Christian Heimes72b710a2008-05-26 13:28:38 +0000172 return PyBytes_FromStringAndSize(buf, len);
Michael W. Hudsonf0089982003-03-03 12:29:42 +0000173 }
174 }
175
176 PyErr_Clear();
Martin v. Löwis423be952008-08-13 15:53:07 +0000177 if (PyArg_ParseTuple(args, "O&Is*:ioctl",
178 conv_descriptor, &fd, &code, &pstr)) {
179 str = pstr.buf;
180 len = pstr.len;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000181 if (len > IOCTL_BUFSZ) {
Martin v. Löwis423be952008-08-13 15:53:07 +0000182 PyBuffer_Release(&pstr);
Roger E. Masse919213a1996-12-17 17:42:22 +0000183 PyErr_SetString(PyExc_ValueError,
184 "ioctl string arg too long");
Guido van Rossum02975121992-08-17 08:55:12 +0000185 return NULL;
186 }
187 memcpy(buf, str, len);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000188 buf[len] = '\0';
Roger E. Masse919213a1996-12-17 17:42:22 +0000189 Py_BEGIN_ALLOW_THREADS
Guido van Rossum903f4871995-10-07 19:18:22 +0000190 ret = ioctl(fd, code, buf);
Roger E. Masse919213a1996-12-17 17:42:22 +0000191 Py_END_ALLOW_THREADS
Guido van Rossum903f4871995-10-07 19:18:22 +0000192 if (ret < 0) {
Martin v. Löwis423be952008-08-13 15:53:07 +0000193 PyBuffer_Release(&pstr);
Roger E. Masse919213a1996-12-17 17:42:22 +0000194 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum02975121992-08-17 08:55:12 +0000195 return NULL;
196 }
Martin v. Löwis423be952008-08-13 15:53:07 +0000197 PyBuffer_Release(&pstr);
Christian Heimes72b710a2008-05-26 13:28:38 +0000198 return PyBytes_FromStringAndSize(buf, len);
Guido van Rossum02975121992-08-17 08:55:12 +0000199 }
200
Roger E. Masse919213a1996-12-17 17:42:22 +0000201 PyErr_Clear();
Guido van Rossuma2214c32000-08-02 20:46:51 +0000202 arg = 0;
Fred Drake460f0692001-05-14 21:02:36 +0000203 if (!PyArg_ParseTuple(args,
Michael W. Hudson8137bea2005-07-27 20:24:40 +0000204 "O&I|i;ioctl requires a file or file descriptor,"
Hye-Shik Chang97bb8ad2005-07-28 05:57:19 +0000205 " an integer and optionally an integer or buffer argument",
Fred Drake152a25e2001-05-09 21:02:02 +0000206 conv_descriptor, &fd, &code, &arg)) {
Guido van Rossuma2214c32000-08-02 20:46:51 +0000207 return NULL;
Guido van Rossum02975121992-08-17 08:55:12 +0000208 }
Roger E. Masse919213a1996-12-17 17:42:22 +0000209 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000210#ifdef __VMS
211 ret = ioctl(fd, code, (void *)arg);
212#else
Guido van Rossum02975121992-08-17 08:55:12 +0000213 ret = ioctl(fd, code, arg);
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000214#endif
Roger E. Masse919213a1996-12-17 17:42:22 +0000215 Py_END_ALLOW_THREADS
Guido van Rossum02975121992-08-17 08:55:12 +0000216 if (ret < 0) {
Roger E. Masse919213a1996-12-17 17:42:22 +0000217 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum02975121992-08-17 08:55:12 +0000218 return NULL;
219 }
Christian Heimes217cfd12007-12-02 14:31:20 +0000220 return PyLong_FromLong((long)ret);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000221#undef IOCTL_BUFSZ
Guido van Rossum02975121992-08-17 08:55:12 +0000222}
223
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000224PyDoc_STRVAR(ioctl_doc,
Michael W. Hudsonf0089982003-03-03 12:29:42 +0000225"ioctl(fd, opt[, arg[, mutate_flag]])\n\
Guido van Rossum185ead61998-11-23 15:32:55 +0000226\n\
Michael W. Hudsonf0089982003-03-03 12:29:42 +0000227Perform the requested operation on file descriptor fd. The operation is\n\
Neal Norwitz47308802003-06-30 01:54:04 +0000228defined by opt and is operating system dependent. Typically these codes are\n\
Michael W. Hudsonf0089982003-03-03 12:29:42 +0000229retrieved from the fcntl or termios library modules.\n\
230\n\
231The argument arg is optional, and defaults to 0; it may be an int or a\n\
232buffer containing character data (most likely a string or an array). \n\
233\n\
234If the argument is a mutable buffer (such as an array) and if the\n\
235mutate_flag argument (which is only allowed in this case) is true then the\n\
236buffer is (in effect) passed to the operating system and changes made by\n\
237the OS will be reflected in the contents of the buffer after the call has\n\
238returned. The return value is the integer returned by the ioctl system\n\
239call.\n\
240\n\
241If the argument is a mutable buffer and the mutable_flag argument is not\n\
242passed or is false, the behavior is as if a string had been passed. This\n\
243behavior will change in future releases of Python.\n\
244\n\
245If the argument is an immutable buffer (most likely a string) then a copy\n\
246of the buffer is passed to the operating system and the return value is a\n\
247string of the same length containing whatever the operating system put in\n\
248the buffer. The length of the arg buffer in this case is not allowed to\n\
249exceed 1024 bytes.\n\
250\n\
251If the arg given is an integer or if none is specified, the result value is\n\
252an integer corresponding to the return value of the ioctl call in the C\n\
253code.");
Guido van Rossum185ead61998-11-23 15:32:55 +0000254
Guido van Rossum02975121992-08-17 08:55:12 +0000255
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000256/* flock(fd, operation) */
257
Roger E. Masse919213a1996-12-17 17:42:22 +0000258static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000259fcntl_flock(PyObject *self, PyObject *args)
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000260{
261 int fd;
262 int code;
263 int ret;
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000264
Fred Drake152a25e2001-05-09 21:02:02 +0000265 if (!PyArg_ParseTuple(args, "O&i:flock",
266 conv_descriptor, &fd, &code))
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000267 return NULL;
268
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000269#ifdef HAVE_FLOCK
Guido van Rossum056bad91999-01-06 18:44:23 +0000270 Py_BEGIN_ALLOW_THREADS
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000271 ret = flock(fd, code);
Guido van Rossum056bad91999-01-06 18:44:23 +0000272 Py_END_ALLOW_THREADS
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000273#else
274
275#ifndef LOCK_SH
276#define LOCK_SH 1 /* shared lock */
277#define LOCK_EX 2 /* exclusive lock */
278#define LOCK_NB 4 /* don't block when locking */
279#define LOCK_UN 8 /* unlock */
280#endif
281 {
282 struct flock l;
283 if (code == LOCK_UN)
284 l.l_type = F_UNLCK;
285 else if (code & LOCK_SH)
286 l.l_type = F_RDLCK;
287 else if (code & LOCK_EX)
288 l.l_type = F_WRLCK;
289 else {
Roger E. Masse919213a1996-12-17 17:42:22 +0000290 PyErr_SetString(PyExc_ValueError,
291 "unrecognized flock argument");
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000292 return NULL;
293 }
294 l.l_whence = l.l_start = l.l_len = 0;
Guido van Rossum056bad91999-01-06 18:44:23 +0000295 Py_BEGIN_ALLOW_THREADS
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000296 ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
Guido van Rossum056bad91999-01-06 18:44:23 +0000297 Py_END_ALLOW_THREADS
Guido van Rossum3c0b79c1996-06-11 15:11:34 +0000298 }
299#endif /* HAVE_FLOCK */
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000300 if (ret < 0) {
Roger E. Masse919213a1996-12-17 17:42:22 +0000301 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000302 return NULL;
303 }
Roger E. Masse919213a1996-12-17 17:42:22 +0000304 Py_INCREF(Py_None);
305 return Py_None;
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000306}
307
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000308PyDoc_STRVAR(flock_doc,
Guido van Rossum185ead61998-11-23 15:32:55 +0000309"flock(fd, operation)\n\
310\n\
311Perform the lock operation op on file descriptor fd. See the Unix \n\
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000312manual page for flock(3) for details. (On some systems, this function is\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000313emulated using fcntl().)");
Guido van Rossum185ead61998-11-23 15:32:55 +0000314
315
Guido van Rossumc8643641996-09-11 23:17:20 +0000316/* lockf(fd, operation) */
Roger E. Masse919213a1996-12-17 17:42:22 +0000317static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000318fcntl_lockf(PyObject *self, PyObject *args)
Guido van Rossumc8643641996-09-11 23:17:20 +0000319{
Guido van Rossum056bad91999-01-06 18:44:23 +0000320 int fd, code, ret, whence = 0;
321 PyObject *lenobj = NULL, *startobj = NULL;
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000322
Fred Drake152a25e2001-05-09 21:02:02 +0000323 if (!PyArg_ParseTuple(args, "O&i|OOi:lockf",
324 conv_descriptor, &fd, &code,
Guido van Rossum056bad91999-01-06 18:44:23 +0000325 &lenobj, &startobj, &whence))
Guido van Rossumc8643641996-09-11 23:17:20 +0000326 return NULL;
327
Andrew MacIntyre7bf68332002-03-03 02:59:16 +0000328#if defined(PYOS_OS2) && defined(PYCC_GCC)
329 PyErr_SetString(PyExc_NotImplementedError,
330 "lockf not supported on OS/2 (EMX)");
331 return NULL;
332#else
Guido van Rossumc8643641996-09-11 23:17:20 +0000333#ifndef LOCK_SH
334#define LOCK_SH 1 /* shared lock */
335#define LOCK_EX 2 /* exclusive lock */
336#define LOCK_NB 4 /* don't block when locking */
337#define LOCK_UN 8 /* unlock */
Andrew MacIntyre7bf68332002-03-03 02:59:16 +0000338#endif /* LOCK_SH */
Guido van Rossumc8643641996-09-11 23:17:20 +0000339 {
340 struct flock l;
341 if (code == LOCK_UN)
342 l.l_type = F_UNLCK;
343 else if (code & LOCK_SH)
344 l.l_type = F_RDLCK;
345 else if (code & LOCK_EX)
346 l.l_type = F_WRLCK;
347 else {
Roger E. Masse919213a1996-12-17 17:42:22 +0000348 PyErr_SetString(PyExc_ValueError,
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000349 "unrecognized lockf argument");
Guido van Rossumc8643641996-09-11 23:17:20 +0000350 return NULL;
351 }
Guido van Rossum056bad91999-01-06 18:44:23 +0000352 l.l_start = l.l_len = 0;
353 if (startobj != NULL) {
354#if !defined(HAVE_LARGEFILE_SUPPORT)
Christian Heimes217cfd12007-12-02 14:31:20 +0000355 l.l_start = PyLong_AsLong(startobj);
Guido van Rossum056bad91999-01-06 18:44:23 +0000356#else
357 l.l_start = PyLong_Check(startobj) ?
358 PyLong_AsLongLong(startobj) :
Christian Heimes217cfd12007-12-02 14:31:20 +0000359 PyLong_AsLong(startobj);
Guido van Rossum056bad91999-01-06 18:44:23 +0000360#endif
361 if (PyErr_Occurred())
362 return NULL;
363 }
364 if (lenobj != NULL) {
365#if !defined(HAVE_LARGEFILE_SUPPORT)
Christian Heimes217cfd12007-12-02 14:31:20 +0000366 l.l_len = PyLong_AsLong(lenobj);
Guido van Rossum056bad91999-01-06 18:44:23 +0000367#else
368 l.l_len = PyLong_Check(lenobj) ?
369 PyLong_AsLongLong(lenobj) :
Christian Heimes217cfd12007-12-02 14:31:20 +0000370 PyLong_AsLong(lenobj);
Guido van Rossum056bad91999-01-06 18:44:23 +0000371#endif
372 if (PyErr_Occurred())
373 return NULL;
374 }
Guido van Rossumc8643641996-09-11 23:17:20 +0000375 l.l_whence = whence;
Guido van Rossum056bad91999-01-06 18:44:23 +0000376 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc8643641996-09-11 23:17:20 +0000377 ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
Guido van Rossum056bad91999-01-06 18:44:23 +0000378 Py_END_ALLOW_THREADS
Guido van Rossumc8643641996-09-11 23:17:20 +0000379 }
Guido van Rossumc8643641996-09-11 23:17:20 +0000380 if (ret < 0) {
Roger E. Masse919213a1996-12-17 17:42:22 +0000381 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumc8643641996-09-11 23:17:20 +0000382 return NULL;
383 }
Roger E. Masse919213a1996-12-17 17:42:22 +0000384 Py_INCREF(Py_None);
385 return Py_None;
Andrew MacIntyre7bf68332002-03-03 02:59:16 +0000386#endif /* defined(PYOS_OS2) && defined(PYCC_GCC) */
Guido van Rossumc8643641996-09-11 23:17:20 +0000387}
Guido van Rossum3539b1e1996-05-23 22:56:38 +0000388
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000389PyDoc_STRVAR(lockf_doc,
Sjoerd Mullender82e00d62001-01-25 10:10:39 +0000390"lockf (fd, operation, length=0, start=0, whence=0)\n\
391\n\
392This is essentially a wrapper around the fcntl() locking calls. fd is the\n\
393file descriptor of the file to lock or unlock, and operation is one of the\n\
394following values:\n\
395\n\
396 LOCK_UN - unlock\n\
397 LOCK_SH - acquire a shared lock\n\
398 LOCK_EX - acquire an exclusive lock\n\
399\n\
Christian Heimesfaf2f632008-01-06 16:59:19 +0000400When operation is LOCK_SH or LOCK_EX, it can also be bitwise ORed with\n\
Sjoerd Mullender82e00d62001-01-25 10:10:39 +0000401LOCK_NB to avoid blocking on lock acquisition. If LOCK_NB is used and the\n\
402lock cannot be acquired, an IOError will be raised and the exception will\n\
403have an errno attribute set to EACCES or EAGAIN (depending on the operating\n\
404system -- for portability, check for either value).\n\
405\n\
406length is the number of bytes to lock, with the default meaning to lock to\n\
407EOF. start is the byte offset, relative to whence, to that the lock\n\
408starts. whence is as with fileobj.seek(), specifically:\n\
409\n\
410 0 - relative to the start of the file (SEEK_SET)\n\
411 1 - relative to the current buffer position (SEEK_CUR)\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000412 2 - relative to the end of the file (SEEK_END)");
Guido van Rossum185ead61998-11-23 15:32:55 +0000413
Guido van Rossum02975121992-08-17 08:55:12 +0000414/* List of functions */
415
Roger E. Masse919213a1996-12-17 17:42:22 +0000416static PyMethodDef fcntl_methods[] = {
Guido van Rossuma2214c32000-08-02 20:46:51 +0000417 {"fcntl", fcntl_fcntl, METH_VARARGS, fcntl_doc},
418 {"ioctl", fcntl_ioctl, METH_VARARGS, ioctl_doc},
419 {"flock", fcntl_flock, METH_VARARGS, flock_doc},
420 {"lockf", fcntl_lockf, METH_VARARGS, lockf_doc},
Guido van Rossum02975121992-08-17 08:55:12 +0000421 {NULL, NULL} /* sentinel */
422};
423
424
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000425PyDoc_STRVAR(module_doc,
Guido van Rossum185ead61998-11-23 15:32:55 +0000426"This module performs file control and I/O control on file \n\
427descriptors. It is an interface to the fcntl() and ioctl() Unix\n\
428routines. File descriptors can be obtained with the fileno() method of\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000429a file or socket object.");
Guido van Rossum185ead61998-11-23 15:32:55 +0000430
Guido van Rossum02975121992-08-17 08:55:12 +0000431/* Module initialisation */
432
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000433static int
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000434ins(PyObject* d, char* symbol, long value)
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000435{
Christian Heimes217cfd12007-12-02 14:31:20 +0000436 PyObject* v = PyLong_FromLong(value);
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000437 if (!v || PyDict_SetItemString(d, symbol, v) < 0)
438 return -1;
439
440 Py_DECREF(v);
441 return 0;
442}
443
Martin v. Löwis14e73b12003-01-01 09:51:12 +0000444#define INS(x) if (ins(d, #x, (long)x)) return -1
445
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000446static int
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000447all_ins(PyObject* d)
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000448{
449 if (ins(d, "LOCK_SH", (long)LOCK_SH)) return -1;
450 if (ins(d, "LOCK_EX", (long)LOCK_EX)) return -1;
451 if (ins(d, "LOCK_NB", (long)LOCK_NB)) return -1;
452 if (ins(d, "LOCK_UN", (long)LOCK_UN)) return -1;
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000453/* GNU extensions, as of glibc 2.2.4 */
454#ifdef LOCK_MAND
455 if (ins(d, "LOCK_MAND", (long)LOCK_MAND)) return -1;
456#endif
457#ifdef LOCK_READ
458 if (ins(d, "LOCK_READ", (long)LOCK_READ)) return -1;
459#endif
460#ifdef LOCK_WRITE
461 if (ins(d, "LOCK_WRITE", (long)LOCK_WRITE)) return -1;
462#endif
463#ifdef LOCK_RW
464 if (ins(d, "LOCK_RW", (long)LOCK_RW)) return -1;
465#endif
466
Fred Drake152a25e2001-05-09 21:02:02 +0000467#ifdef F_DUPFD
468 if (ins(d, "F_DUPFD", (long)F_DUPFD)) return -1;
469#endif
470#ifdef F_GETFD
471 if (ins(d, "F_GETFD", (long)F_GETFD)) return -1;
472#endif
473#ifdef F_SETFD
474 if (ins(d, "F_SETFD", (long)F_SETFD)) return -1;
475#endif
476#ifdef F_GETFL
477 if (ins(d, "F_GETFL", (long)F_GETFL)) return -1;
478#endif
479#ifdef F_SETFL
480 if (ins(d, "F_SETFL", (long)F_SETFL)) return -1;
481#endif
482#ifdef F_GETLK
483 if (ins(d, "F_GETLK", (long)F_GETLK)) return -1;
484#endif
485#ifdef F_SETLK
486 if (ins(d, "F_SETLK", (long)F_SETLK)) return -1;
487#endif
488#ifdef F_SETLKW
489 if (ins(d, "F_SETLKW", (long)F_SETLKW)) return -1;
490#endif
491#ifdef F_GETOWN
492 if (ins(d, "F_GETOWN", (long)F_GETOWN)) return -1;
493#endif
494#ifdef F_SETOWN
495 if (ins(d, "F_SETOWN", (long)F_SETOWN)) return -1;
496#endif
497#ifdef F_GETSIG
498 if (ins(d, "F_GETSIG", (long)F_GETSIG)) return -1;
499#endif
500#ifdef F_SETSIG
501 if (ins(d, "F_SETSIG", (long)F_SETSIG)) return -1;
502#endif
503#ifdef F_RDLCK
504 if (ins(d, "F_RDLCK", (long)F_RDLCK)) return -1;
505#endif
506#ifdef F_WRLCK
507 if (ins(d, "F_WRLCK", (long)F_WRLCK)) return -1;
508#endif
509#ifdef F_UNLCK
510 if (ins(d, "F_UNLCK", (long)F_UNLCK)) return -1;
511#endif
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000512/* LFS constants */
513#ifdef F_GETLK64
514 if (ins(d, "F_GETLK64", (long)F_GETLK64)) return -1;
515#endif
516#ifdef F_SETLK64
517 if (ins(d, "F_SETLK64", (long)F_SETLK64)) return -1;
518#endif
519#ifdef F_SETLKW64
520 if (ins(d, "F_SETLKW64", (long)F_SETLKW64)) return -1;
521#endif
522/* GNU extensions, as of glibc 2.2.4. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +0000523#ifdef FASYNC
524 if (ins(d, "FASYNC", (long)FASYNC)) return -1;
525#endif
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000526#ifdef F_SETLEASE
527 if (ins(d, "F_SETLEASE", (long)F_SETLEASE)) return -1;
528#endif
529#ifdef F_GETLEASE
530 if (ins(d, "F_GETLEASE", (long)F_GETLEASE)) return -1;
531#endif
532#ifdef F_NOTIFY
533 if (ins(d, "F_NOTIFY", (long)F_NOTIFY)) return -1;
534#endif
535/* Old BSD flock(). */
536#ifdef F_EXLCK
537 if (ins(d, "F_EXLCK", (long)F_EXLCK)) return -1;
538#endif
539#ifdef F_SHLCK
540 if (ins(d, "F_SHLCK", (long)F_SHLCK)) return -1;
541#endif
542
Georg Brandl6aa2d1f2008-08-12 08:35:52 +0000543/* OS X (and maybe others) let you tell the storage device to flush to physical media */
544#ifdef F_FULLFSYNC
545 if (ins(d, "F_FULLFSYNC", (long)F_FULLFSYNC)) return -1;
546#endif
547
Martin v. Löwis1baeba62001-12-28 21:08:12 +0000548/* For F_{GET|SET}FL */
549#ifdef FD_CLOEXEC
550 if (ins(d, "FD_CLOEXEC", (long)FD_CLOEXEC)) return -1;
551#endif
552
553/* For F_NOTIFY */
554#ifdef DN_ACCESS
555 if (ins(d, "DN_ACCESS", (long)DN_ACCESS)) return -1;
556#endif
557#ifdef DN_MODIFY
558 if (ins(d, "DN_MODIFY", (long)DN_MODIFY)) return -1;
559#endif
560#ifdef DN_CREATE
561 if (ins(d, "DN_CREATE", (long)DN_CREATE)) return -1;
562#endif
563#ifdef DN_DELETE
564 if (ins(d, "DN_DELETE", (long)DN_DELETE)) return -1;
565#endif
566#ifdef DN_RENAME
567 if (ins(d, "DN_RENAME", (long)DN_RENAME)) return -1;
568#endif
569#ifdef DN_ATTRIB
570 if (ins(d, "DN_ATTRIB", (long)DN_ATTRIB)) return -1;
571#endif
572#ifdef DN_MULTISHOT
573 if (ins(d, "DN_MULTISHOT", (long)DN_MULTISHOT)) return -1;
574#endif
575
Martin v. Löwis14e73b12003-01-01 09:51:12 +0000576#ifdef HAVE_STROPTS_H
577 /* Unix 98 guarantees that these are in stropts.h. */
578 INS(I_PUSH);
579 INS(I_POP);
580 INS(I_LOOK);
581 INS(I_FLUSH);
582 INS(I_FLUSHBAND);
583 INS(I_SETSIG);
584 INS(I_GETSIG);
585 INS(I_FIND);
586 INS(I_PEEK);
587 INS(I_SRDOPT);
588 INS(I_GRDOPT);
589 INS(I_NREAD);
590 INS(I_FDINSERT);
591 INS(I_STR);
592 INS(I_SWROPT);
Michael W. Hudson505c4c22003-05-09 10:45:20 +0000593#ifdef I_GWROPT
594 /* despite the comment above, old-ish glibcs miss a couple... */
Martin v. Löwis14e73b12003-01-01 09:51:12 +0000595 INS(I_GWROPT);
Michael W. Hudson505c4c22003-05-09 10:45:20 +0000596#endif
Martin v. Löwis14e73b12003-01-01 09:51:12 +0000597 INS(I_SENDFD);
598 INS(I_RECVFD);
599 INS(I_LIST);
600 INS(I_ATMARK);
601 INS(I_CKBAND);
602 INS(I_GETBAND);
603 INS(I_CANPUT);
604 INS(I_SETCLTIME);
Michael W. Hudson505c4c22003-05-09 10:45:20 +0000605#ifdef I_GETCLTIME
Martin v. Löwis14e73b12003-01-01 09:51:12 +0000606 INS(I_GETCLTIME);
Michael W. Hudson505c4c22003-05-09 10:45:20 +0000607#endif
Martin v. Löwis14e73b12003-01-01 09:51:12 +0000608 INS(I_LINK);
609 INS(I_UNLINK);
610 INS(I_PLINK);
611 INS(I_PUNLINK);
612#endif
613
Guido van Rossum7c141031997-08-15 02:52:08 +0000614 return 0;
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000615}
616
Martin v. Löwis1a214512008-06-11 05:26:20 +0000617
618static struct PyModuleDef fcntlmodule = {
619 PyModuleDef_HEAD_INIT,
620 "fcntl",
621 module_doc,
622 -1,
623 fcntl_methods,
624 NULL,
625 NULL,
626 NULL,
627 NULL
628};
629
Mark Hammondfe51c6d2002-08-02 02:27:13 +0000630PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +0000631PyInit_fcntl(void)
Guido van Rossum02975121992-08-17 08:55:12 +0000632{
Roger E. Masse919213a1996-12-17 17:42:22 +0000633 PyObject *m, *d;
Guido van Rossum02975121992-08-17 08:55:12 +0000634
Guido van Rossum185ead61998-11-23 15:32:55 +0000635 /* Create the module and add the functions and documentation */
Martin v. Löwis1a214512008-06-11 05:26:20 +0000636 m = PyModule_Create(&fcntlmodule);
Neal Norwitz1ac754f2006-01-19 06:09:39 +0000637 if (m == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +0000638 return NULL;
Guido van Rossum02975121992-08-17 08:55:12 +0000639
640 /* Add some symbolic constants to the module */
Roger E. Masse919213a1996-12-17 17:42:22 +0000641 d = PyModule_GetDict(m);
Guido van Rossumf4e32c71997-07-31 19:39:54 +0000642 all_ins(d);
Martin v. Löwis1a214512008-06-11 05:26:20 +0000643 return m;
Guido van Rossum02975121992-08-17 08:55:12 +0000644}