Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(2)

Delta Between Two Patch Sets: Modules/fcntlmodule.c

Issue 20152: Derby: Convert the _imp module to use Argument Clinic
Left Patch Set: Created 6 years ago
Right Patch Set: Created 5 years, 3 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Right: Side by side diff | Download
« no previous file with change/comment | « Modules/clinic/fcntlmodule.c.h ('k') | no next file » | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
(no file at all)
1 1
2 /* fcntl module */ 2 /* fcntl module */
3 3
4 #define PY_SSIZE_T_CLEAN 4 #define PY_SSIZE_T_CLEAN
5 5
6 #include "Python.h" 6 #include "Python.h"
7 7
8 #ifdef HAVE_SYS_FILE_H 8 #ifdef HAVE_SYS_FILE_H
9 #include <sys/file.h> 9 #include <sys/file.h>
10 #endif 10 #endif
11 11
12 #include <sys/ioctl.h> 12 #include <sys/ioctl.h>
13 #include <fcntl.h> 13 #include <fcntl.h>
14 #ifdef HAVE_STROPTS_H 14 #ifdef HAVE_STROPTS_H
15 #include <stropts.h> 15 #include <stropts.h>
16 #endif 16 #endif
17
18 /*[clinic input]
19 output preset file
20 module fcntl
21 [clinic start generated code]*/
22 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=c7356fdb126a904a]*/
17 23
18 static int 24 static int
19 conv_descriptor(PyObject *object, int *target) 25 conv_descriptor(PyObject *object, int *target)
20 { 26 {
21 int fd = PyObject_AsFileDescriptor(object); 27 int fd = PyObject_AsFileDescriptor(object);
22 28
23 if (fd < 0) 29 if (fd < 0)
24 return 0; 30 return 0;
25 *target = fd; 31 *target = fd;
26 return 1; 32 return 1;
27 } 33 }
28 34
29 35 /* Must come after conv_descriptor definition. */
30 /* fcntl(fd, op, [arg]) */ 36 #include "clinic/fcntlmodule.c.h"
37
38 /*[clinic input]
39 fcntl.fcntl
40
41 fd: object(type='int', converter='conv_descriptor')
42 code: int
storchaka 2014/11/07 20:30:43 In fcntl manpage this argument is named as cmd.
brett.cannon 2014/11/08 15:16:33 I would rather not play with argument names or doc
43 arg: object = NULL
44 /
45
46 Perform the operation `code` on file descriptor fd.
47
48 The values used for `code` are operating system dependent, and are available
49 as constants in the fcntl module, using the same names as used in
50 the relevant C header files. The argument arg is optional, and
51 defaults to 0; it may be an int or a string. If arg is given as a string,
52 the return value of fcntl is a string of that length, containing the
53 resulting value put in the arg buffer by the operating system. The length
54 of the arg string is not allowed to exceed 1024 bytes. If the arg given
55 is an integer or if none is specified, the result value is an integer
56 corresponding to the return value of the fcntl call in the C code.
57 [clinic start generated code]*/
31 58
32 static PyObject * 59 static PyObject *
33 fcntl_fcntl(PyObject *self, PyObject *args) 60 fcntl_fcntl_impl(PyModuleDef *module, int fd, int code, PyObject *arg)
61 /*[clinic end generated code: output=afc5bfa74a03ef0d input=4850c13a41e86930]*/
34 { 62 {
35 int fd; 63 long long_arg = 0;
36 int code;
37 long arg;
38 int ret; 64 int ret;
39 char *str; 65 char *str;
40 Py_ssize_t len; 66 Py_ssize_t len;
41 char buf[1024]; 67 char buf[1024];
42 68 PyObject *optional_arg_tuple;
43 if (PyArg_ParseTuple(args, "O&is#:fcntl", 69
44 conv_descriptor, &fd, &code, &str, &len)) { 70 if (arg != NULL) {
45 if ((size_t)len > sizeof buf) { 71 int parse_result;
46 PyErr_SetString(PyExc_ValueError, 72 // As the optional argument can be l or s#, need to use the magic of
47 "fcntl string arg too long"); 73 // PyArg_ParseTuple() to do the right thing if the s# is needed.
48 return NULL; 74 optional_arg_tuple = PyTuple_Pack(1, arg);
49 } 75
50 memcpy(buf, str, len); 76 if (PyArg_ParseTuple(optional_arg_tuple, "s#", &str, &len)) {
storchaka 2014/11/07 20:30:43 PyArg_Parse(arg, "s#", &str, &len) And same below
brett.cannon 2014/11/10 02:18:30 Done.
51 Py_BEGIN_ALLOW_THREADS 77 Py_DECREF(optional_arg_tuple);
52 ret = fcntl(fd, code, buf); 78
53 Py_END_ALLOW_THREADS 79 if ((size_t)len > sizeof buf) {
54 if (ret < 0) { 80 PyErr_SetString(PyExc_ValueError,
55 PyErr_SetFromErrno(PyExc_IOError); 81 "fcntl string arg too long");
56 return NULL; 82 return NULL;
57 } 83 }
58 return PyBytes_FromStringAndSize(buf, len); 84 memcpy(buf, str, len);
59 } 85 Py_BEGIN_ALLOW_THREADS
60 86 ret = fcntl(fd, code, buf);
61 PyErr_Clear(); 87 Py_END_ALLOW_THREADS
62 arg = 0; 88 if (ret < 0) {
63 if (!PyArg_ParseTuple(args, 89 PyErr_SetFromErrno(PyExc_IOError);
64 "O&i|l;fcntl requires a file or file descriptor," 90 return NULL;
65 " an integer and optionally a third integer or a string", 91 }
66 conv_descriptor, &fd, &code, &arg)) { 92 return PyBytes_FromStringAndSize(buf, len);
67 return NULL; 93 }
68 } 94
95 PyErr_Clear();
96 parse_result = PyArg_ParseTuple(optional_arg_tuple,
97 "l;fcntl requires a file or file descriptor,"
98 " an integer and optionally a third integer or a string",
99 &long_arg);
100 Py_DECREF(optional_arg_tuple);
101 if (!parse_result) {
102 return NULL;
103 }
104 }
105
69 Py_BEGIN_ALLOW_THREADS 106 Py_BEGIN_ALLOW_THREADS
70 ret = fcntl(fd, code, arg); 107 ret = fcntl(fd, code, long_arg);
storchaka 2014/11/07 20:30:43 Here is a bug. An argument should be int.
brett.cannon 2014/11/10 02:18:30 I take it this is a pre-existing bug? I don't see
71 Py_END_ALLOW_THREADS 108 Py_END_ALLOW_THREADS
72 if (ret < 0) { 109 if (ret < 0) {
73 PyErr_SetFromErrno(PyExc_IOError); 110 PyErr_SetFromErrno(PyExc_IOError);
74 return NULL; 111 return NULL;
75 } 112 }
76 return PyLong_FromLong((long)ret); 113 return PyLong_FromLong((long)ret);
77 } 114 }
78 115
79 PyDoc_STRVAR(fcntl_doc, 116
80 "fcntl(fd, op, [arg])\n\ 117 /*[clinic input]
81 \n\ 118 fcntl.ioctl
82 Perform the operation op on file descriptor fd. The values used\n\ 119
83 for op are operating system dependent, and are available\n\ 120 fd: object(type='int', converter='conv_descriptor')
84 as constants in the fcntl module, using the same names as used in\n\ 121 op as code: unsigned_int(bitwise=True)
storchaka 2014/11/07 20:30:43 In ioctl manpage this argument is named as request
brett.cannon 2014/11/08 15:16:33 Don't want to change argument names in this patch
85 the relevant C header files. The argument arg is optional, and\n\ 122 arg as ob_arg: object = NULL
86 defaults to 0; it may be an int or a string. If arg is given as a string,\n\ 123 mutate_flag as mutate_arg: int = 1
storchaka 2014/11/07 20:30:43 Actually this is boolean flag.
brett.cannon 2014/11/10 02:18:30 Done.
87 the return value of fcntl is a string of that length, containing the\n\ 124 /
88 resulting value put in the arg buffer by the operating system. The length\n\ 125
89 of the arg string is not allowed to exceed 1024 bytes. If the arg given\n\ 126 Perform the operation op on file descriptor fd.
90 is an integer or if none is specified, the result value is an integer\n\ 127
91 corresponding to the return value of the fcntl call in the C code."); 128 The values used for op are operating system dependent, and are available as
92 129 constants in the fcntl or termios library modules, using the same names as
93 130 used in the relevant C header files.
94 /* ioctl(fd, op, [arg]) */ 131
132 The argument `arg` is optional, and defaults to 0; it may be an int or a
133 buffer containing character data (most likely a string or an array).
134
135 If the argument is a mutable buffer (such as an array) and if the
136 mutate_flag argument (which is only allowed in this case) is true then the
137 buffer is (in effect) passed to the operating system and changes made by
138 the OS will be reflected in the contents of the buffer after the call has
139 returned. The return value is the integer returned by the ioctl system
140 call.
141
142 If the argument is a mutable buffer and the mutable_flag argument is not
143 passed or is false, the behavior is as if a string had been passed. This
144 behavior will change in future releases of Python.
145
146 If the argument is an immutable buffer (most likely a string) then a copy
147 of the buffer is passed to the operating system and the return value is a
148 string of the same length containing whatever the operating system put in
149 the buffer. The length of the arg buffer in this case is not allowed to
150 exceed 1024 bytes.
151
152 If the arg given is an integer or if none is specified, the result value is
153 an integer corresponding to the return value of the ioctl call in the C
154 code.
155 [clinic start generated code]*/
95 156
96 static PyObject * 157 static PyObject *
97 fcntl_ioctl(PyObject *self, PyObject *args) 158 fcntl_ioctl_impl(PyModuleDef *module, int fd, unsigned int code, PyObject *ob_ar g, int mutate_arg)
159 /*[clinic end generated code: output=ad47738c118622bf input=d957bea7135aedcf]*/
98 { 160 {
99 #define IOCTL_BUFSZ 1024 161 #define IOCTL_BUFSZ 1024
100 int fd; 162 /* We use the unsigned non-checked 'I'
101 /* In PyArg_ParseTuple below, we use the unsigned non-checked 'I'
102 format for the 'code' parameter because Python turns 0x8000000 163 format for the 'code' parameter because Python turns 0x8000000
103 into either a large positive number (PyLong or PyInt on 64-bit 164 into either a large positive number (PyLong or PyInt on 64-bit
104 platforms) or a negative number on others (32-bit PyInt) 165 platforms) or a negative number on others (32-bit PyInt)
105 whereas the system expects it to be a 32bit bit field value 166 whereas the system expects it to be a 32bit bit field value
106 regardless of it being passed as an int or unsigned long on 167 regardless of it being passed as an int or unsigned long on
107 various platforms. See the termios.TIOCSWINSZ constant across 168 various platforms. See the termios.TIOCSWINSZ constant across
108 platforms for an example of this. 169 platforms for an example of this.
109 170
110 If any of the 64bit platforms ever decide to use more than 32bits 171 If any of the 64bit platforms ever decide to use more than 32bits
111 in their unsigned long ioctl codes this will break and need 172 in their unsigned long ioctl codes this will break and need
112 special casing based on the platform being built on. 173 special casing based on the platform being built on.
113 */ 174 */
114 unsigned int code; 175 int arg = 0;
115 int arg;
116 int ret; 176 int ret;
117 Py_buffer pstr; 177 Py_buffer pstr;
118 char *str; 178 char *str;
119 Py_ssize_t len; 179 Py_ssize_t len;
120 int mutate_arg = 1;
121 char buf[IOCTL_BUFSZ+1]; /* argument plus NUL byte */ 180 char buf[IOCTL_BUFSZ+1]; /* argument plus NUL byte */
122 181
123 if (PyArg_ParseTuple(args, "O&Iw*|i:ioctl", 182 if (ob_arg != NULL) {
124 conv_descriptor, &fd, &code, 183 PyObject* args = PyTuple_Pack(1, ob_arg);
125 &pstr, &mutate_arg)) { 184 if (PyArg_ParseTuple(args, "w*:ioctl", &pstr)) {
126 char *arg; 185 char *arg;
127 str = pstr.buf; 186 str = pstr.buf;
128 len = pstr.len; 187 len = pstr.len;
129 188
130 if (mutate_arg) { 189 if (mutate_arg) {
131 if (len <= IOCTL_BUFSZ) { 190 if (len <= IOCTL_BUFSZ) {
132 memcpy(buf, str, len); 191 memcpy(buf, str, len);
133 buf[len] = '\0'; 192 buf[len] = '\0';
134 arg = buf; 193 arg = buf;
194 }
195 else {
196 arg = str;
197 }
135 } 198 }
136 else { 199 else {
137 arg = str; 200 if (len > IOCTL_BUFSZ) {
138 } 201 PyBuffer_Release(&pstr);
139 } 202 PyErr_SetString(PyExc_ValueError,
140 else { 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 poin t */
224 if (ret < 0) {
225 PyErr_SetFromErrno(PyExc_IOError);
226 return NULL;
227 }
228 if (mutate_arg) {
229 return PyLong_FromLong(ret);
230 }
231 else {
232 return PyBytes_FromStringAndSize(buf, len);
233 }
234 }
235
236 PyErr_Clear();
237 if (PyArg_ParseTuple(args, "s*:ioctl", &pstr)) {
238 str = pstr.buf;
239 len = pstr.len;
141 if (len > IOCTL_BUFSZ) { 240 if (len > IOCTL_BUFSZ) {
142 PyBuffer_Release(&pstr); 241 PyBuffer_Release(&pstr);
143 PyErr_SetString(PyExc_ValueError, 242 PyErr_SetString(PyExc_ValueError,
144 "ioctl string arg too long"); 243 "ioctl string arg too long");
145 return NULL; 244 return NULL;
146 } 245 }
147 else { 246 memcpy(buf, str, len);
148 memcpy(buf, str, len); 247 buf[len] = '\0';
149 buf[len] = '\0'; 248 Py_BEGIN_ALLOW_THREADS
150 arg = buf; 249 ret = ioctl(fd, code, buf);
151 }
152 }
153 if (buf == arg) {
154 Py_BEGIN_ALLOW_THREADS /* think array.resize() */
155 ret = ioctl(fd, code, arg);
156 Py_END_ALLOW_THREADS 250 Py_END_ALLOW_THREADS
157 } 251 if (ret < 0) {
158 else { 252 PyBuffer_Release(&pstr);
159 ret = ioctl(fd, code, arg); 253 PyErr_SetFromErrno(PyExc_IOError);
160 } 254 return NULL;
161 if (mutate_arg && (len <= IOCTL_BUFSZ)) { 255 }
162 memcpy(str, buf, len); 256 PyBuffer_Release(&pstr);
163 }
164 PyBuffer_Release(&pstr); /* No further access to str below this point */
165 if (ret < 0) {
166 PyErr_SetFromErrno(PyExc_IOError);
167 return NULL;
168 }
169 if (mutate_arg) {
170 return PyLong_FromLong(ret);
171 }
172 else {
173 return PyBytes_FromStringAndSize(buf, len); 257 return PyBytes_FromStringAndSize(buf, len);
174 } 258 }
175 } 259
176 260 PyErr_Clear();
177 PyErr_Clear(); 261 if (!PyArg_ParseTuple(args,
178 if (PyArg_ParseTuple(args, "O&Is*:ioctl", 262 "I;ioctl requires a file or file descriptor,"
storchaka 2014/11/07 20:30:43 Why "i" was changed to "I" here?
brett.cannon 2014/11/10 02:18:30 Accident. Fixed.
179 conv_descriptor, &fd, &code, &pstr)) { 263 " an integer and optionally an integer or buffer argument",
180 str = pstr.buf; 264 &arg)) {
181 len = pstr.len; 265 return NULL;
182 if (len > IOCTL_BUFSZ) { 266 }
183 PyBuffer_Release(&pstr); 267 // Fall-through to outside the 'if' statement.
184 PyErr_SetString(PyExc_ValueError,
185 "ioctl string arg too long");
186 return NULL;
187 }
188 memcpy(buf, str, len);
189 buf[len] = '\0';
190 Py_BEGIN_ALLOW_THREADS
191 ret = ioctl(fd, code, buf);
192 Py_END_ALLOW_THREADS
193 if (ret < 0) {
194 PyBuffer_Release(&pstr);
195 PyErr_SetFromErrno(PyExc_IOError);
196 return NULL;
197 }
198 PyBuffer_Release(&pstr);
199 return PyBytes_FromStringAndSize(buf, len);
200 }
201
202 PyErr_Clear();
203 arg = 0;
204 if (!PyArg_ParseTuple(args,
205 "O&I|i;ioctl requires a file or file descriptor,"
206 " an integer and optionally an integer or buffer argument",
207 conv_descriptor, &fd, &code, &arg)) {
208 return NULL;
209 } 268 }
210 Py_BEGIN_ALLOW_THREADS 269 Py_BEGIN_ALLOW_THREADS
211 ret = ioctl(fd, code, arg); 270 ret = ioctl(fd, code, arg);
212 Py_END_ALLOW_THREADS 271 Py_END_ALLOW_THREADS
213 if (ret < 0) { 272 if (ret < 0) {
214 PyErr_SetFromErrno(PyExc_IOError); 273 PyErr_SetFromErrno(PyExc_IOError);
215 return NULL; 274 return NULL;
216 } 275 }
217 return PyLong_FromLong((long)ret); 276 return PyLong_FromLong((long)ret);
218 #undef IOCTL_BUFSZ 277 #undef IOCTL_BUFSZ
219 } 278 }
220 279
221 PyDoc_STRVAR(ioctl_doc, 280 /*[clinic input]
222 "ioctl(fd, op[, arg[, mutate_flag]])\n\ 281 fcntl.flock
223 \n\ 282
224 Perform the operation op on file descriptor fd. The values used for op\n\ 283 fd: object(type='int', converter='conv_descriptor')
225 are operating system dependent, and are available as constants in the\n\ 284 code: int
storchaka 2014/11/07 20:30:43 In flock manpage this argument is named as operati
brett.cannon 2014/11/08 15:16:33 Don't want to change argument names in this patch
226 fcntl or termios library modules, using the same names as used in the\n\ 285 /
227 relevant C header files.\n\ 286
228 \n\ 287 Perform the lock operation op on file descriptor fd.
229 The argument arg is optional, and defaults to 0; it may be an int or a\n\ 288
230 buffer containing character data (most likely a string or an array). \n\ 289 See the Unix manual page for flock(2) for details (On some systems, this
231 \n\ 290 function is emulated using fcntl()).
232 If the argument is a mutable buffer (such as an array) and if the\n\ 291 [clinic start generated code]*/
233 mutate_flag argument (which is only allowed in this case) is true then the\n\
234 buffer is (in effect) passed to the operating system and changes made by\n\
235 the OS will be reflected in the contents of the buffer after the call has\n\
236 returned. The return value is the integer returned by the ioctl system\n\
237 call.\n\
238 \n\
239 If the argument is a mutable buffer and the mutable_flag argument is not\n\
240 passed or is false, the behavior is as if a string had been passed. This\n\
241 behavior will change in future releases of Python.\n\
242 \n\
243 If the argument is an immutable buffer (most likely a string) then a copy\n\
244 of the buffer is passed to the operating system and the return value is a\n\
245 string of the same length containing whatever the operating system put in\n\
246 the buffer. The length of the arg buffer in this case is not allowed to\n\
247 exceed 1024 bytes.\n\
248 \n\
249 If the arg given is an integer or if none is specified, the result value is\n\
250 an integer corresponding to the return value of the ioctl call in the C\n\
251 code.");
252
253
254 /* flock(fd, operation) */
255 292
256 static PyObject * 293 static PyObject *
257 fcntl_flock(PyObject *self, PyObject *args) 294 fcntl_flock_impl(PyModuleDef *module, int fd, int code)
295 /*[clinic end generated code: output=c9035133a7dbfc96 input=b762aa9448d05e43]*/
258 { 296 {
259 int fd;
260 int code;
261 int ret; 297 int ret;
262
263 if (!PyArg_ParseTuple(args, "O&i:flock",
264 conv_descriptor, &fd, &code))
265 return NULL;
266 298
267 #ifdef HAVE_FLOCK 299 #ifdef HAVE_FLOCK
268 Py_BEGIN_ALLOW_THREADS 300 Py_BEGIN_ALLOW_THREADS
269 ret = flock(fd, code); 301 ret = flock(fd, code);
270 Py_END_ALLOW_THREADS 302 Py_END_ALLOW_THREADS
271 #else 303 #else
272 304
273 #ifndef LOCK_SH 305 #ifndef LOCK_SH
274 #define LOCK_SH 1 /* shared lock */ 306 #define LOCK_SH 1 /* shared lock */
275 #define LOCK_EX 2 /* exclusive lock */ 307 #define LOCK_EX 2 /* exclusive lock */
(...skipping 16 matching lines...) Expand all
292 l.l_whence = l.l_start = l.l_len = 0; 324 l.l_whence = l.l_start = l.l_len = 0;
293 Py_BEGIN_ALLOW_THREADS 325 Py_BEGIN_ALLOW_THREADS
294 ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l); 326 ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
295 Py_END_ALLOW_THREADS 327 Py_END_ALLOW_THREADS
296 } 328 }
297 #endif /* HAVE_FLOCK */ 329 #endif /* HAVE_FLOCK */
298 if (ret < 0) { 330 if (ret < 0) {
299 PyErr_SetFromErrno(PyExc_IOError); 331 PyErr_SetFromErrno(PyExc_IOError);
300 return NULL; 332 return NULL;
301 } 333 }
302 Py_INCREF(Py_None); 334 Py_RETURN_NONE;
303 return Py_None;
304 } 335 }
305 336
306 PyDoc_STRVAR(flock_doc, 337
307 "flock(fd, operation)\n\ 338 /*[clinic input]
308 \n\ 339 fcntl.lockf
309 Perform the lock operation op on file descriptor fd. See the Unix \n\ 340
310 manual page for flock(2) for details. (On some systems, this function is\n\ 341 fd: object(type='int', converter='conv_descriptor')
311 emulated using fcntl().)"); 342 code: int
storchaka 2014/11/07 20:30:43 In lockf manpage on Linux this argument is named a
brett.cannon 2014/11/08 15:16:33 Don't want to change argument names in this patch
312 343 lenobj: object = NULL
storchaka 2014/11/07 20:30:43 In lockf manpage on Linux this argument is named a
brett.cannon 2014/11/08 15:16:33 Don't want to change argument names in this patch
brett.cannon 2014/11/08 15:16:33 Don't want to change argument names in this patch
313 344 startobj: object = NULL
314 /* lockf(fd, operation) */ 345 whence: int = 0
346 /
347
348 A wrapper around the fcntl() locking calls.
349
350 fd is the file descriptor of the file to lock or unlock, and operation is one
351 of the following values:
352
353 LOCK_UN - unlock
354 LOCK_SH - acquire a shared lock
355 LOCK_EX - acquire an exclusive lock
356
357 When operation is LOCK_SH or LOCK_EX, it can also be bitwise ORed with
358 LOCK_NB to avoid blocking on lock acquisition. If LOCK_NB is used and the
359 lock cannot be acquired, an IOError will be raised and the exception will
360 have an errno attribute set to EACCES or EAGAIN (depending on the operating
361 system -- for portability, check for either value).
362
363 length is the number of bytes to lock, with the default meaning to lock to
364 EOF. start is the byte offset, relative to whence, to that the lock
365 starts. whence is as with fileobj.seek(), specifically:
366
367 0 - relative to the start of the file (SEEK_SET)
368 1 - relative to the current buffer position (SEEK_CUR)
369 2 - relative to the end of the file (SEEK_END)
370 [clinic start generated code]*/
371
315 static PyObject * 372 static PyObject *
316 fcntl_lockf(PyObject *self, PyObject *args) 373 fcntl_lockf_impl(PyModuleDef *module, int fd, int code, PyObject *lenobj, PyObje ct *startobj, int whence)
374 /*[clinic end generated code: output=5536df2892bf3ce9 input=44856fa06db36184]*/
317 { 375 {
318 int fd, code, ret, whence = 0; 376 int ret;
319 PyObject *lenobj = NULL, *startobj = NULL;
320
321 if (!PyArg_ParseTuple(args, "O&i|OOi:lockf",
322 conv_descriptor, &fd, &code,
323 &lenobj, &startobj, &whence))
324 return NULL;
325 377
326 #ifndef LOCK_SH 378 #ifndef LOCK_SH
327 #define LOCK_SH 1 /* shared lock */ 379 #define LOCK_SH 1 /* shared lock */
328 #define LOCK_EX 2 /* exclusive lock */ 380 #define LOCK_EX 2 /* exclusive lock */
329 #define LOCK_NB 4 /* don't block when locking */ 381 #define LOCK_NB 4 /* don't block when locking */
330 #define LOCK_UN 8 /* unlock */ 382 #define LOCK_UN 8 /* unlock */
331 #endif /* LOCK_SH */ 383 #endif /* LOCK_SH */
332 { 384 {
333 struct flock l; 385 struct flock l;
334 if (code == LOCK_UN) 386 if (code == LOCK_UN)
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
367 } 419 }
368 l.l_whence = whence; 420 l.l_whence = whence;
369 Py_BEGIN_ALLOW_THREADS 421 Py_BEGIN_ALLOW_THREADS
370 ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l); 422 ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
371 Py_END_ALLOW_THREADS 423 Py_END_ALLOW_THREADS
372 } 424 }
373 if (ret < 0) { 425 if (ret < 0) {
374 PyErr_SetFromErrno(PyExc_IOError); 426 PyErr_SetFromErrno(PyExc_IOError);
375 return NULL; 427 return NULL;
376 } 428 }
377 Py_INCREF(Py_None); 429 Py_RETURN_NONE;
378 return Py_None;
379 } 430 }
380 431
381 PyDoc_STRVAR(lockf_doc,
382 "lockf (fd, operation, length=0, start=0, whence=0)\n\
383 \n\
384 This is essentially a wrapper around the fcntl() locking calls. fd is the\n\
385 file descriptor of the file to lock or unlock, and operation is one of the\n\
386 following values:\n\
387 \n\
388 LOCK_UN - unlock\n\
389 LOCK_SH - acquire a shared lock\n\
390 LOCK_EX - acquire an exclusive lock\n\
391 \n\
392 When operation is LOCK_SH or LOCK_EX, it can also be bitwise ORed with\n\
393 LOCK_NB to avoid blocking on lock acquisition. If LOCK_NB is used and the\n\
394 lock cannot be acquired, an IOError will be raised and the exception will\n\
395 have an errno attribute set to EACCES or EAGAIN (depending on the operating\n\
396 system -- for portability, check for either value).\n\
397 \n\
398 length is the number of bytes to lock, with the default meaning to lock to\n\
399 EOF. start is the byte offset, relative to whence, to that the lock\n\
400 starts. whence is as with fileobj.seek(), specifically:\n\
401 \n\
402 0 - relative to the start of the file (SEEK_SET)\n\
403 1 - relative to the current buffer position (SEEK_CUR)\n\
404 2 - relative to the end of the file (SEEK_END)");
405
406 /* List of functions */ 432 /* List of functions */
407 433
408 static PyMethodDef fcntl_methods[] = { 434 static PyMethodDef fcntl_methods[] = {
409 {"fcntl", fcntl_fcntl, METH_VARARGS, fcntl_doc}, 435 FCNTL_FCNTL_METHODDEF
410 {"ioctl", fcntl_ioctl, METH_VARARGS, ioctl_doc}, 436 FCNTL_IOCTL_METHODDEF
411 {"flock", fcntl_flock, METH_VARARGS, flock_doc}, 437 FCNTL_FLOCK_METHODDEF
412 {"lockf", fcntl_lockf, METH_VARARGS, lockf_doc}, 438 FCNTL_LOCKF_METHODDEF
413 {NULL, NULL} /* sentinel */ 439 {NULL, NULL} /* sentinel */
414 }; 440 };
415 441
416 442
417 PyDoc_STRVAR(module_doc, 443 PyDoc_STRVAR(module_doc,
418 "This module performs file control and I/O control on file \n\ 444 "This module performs file control and I/O control on file \n\
419 descriptors. It is an interface to the fcntl() and ioctl() Unix\n\ 445 descriptors. It is an interface to the fcntl() and ioctl() Unix\n\
420 routines. File descriptors can be obtained with the fileno() method of\n\ 446 routines. File descriptors can be obtained with the fileno() method of\n\
421 a file or socket object."); 447 a file or socket object.");
422 448
423 /* Module initialisation */ 449 /* Module initialisation */
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
622 m = PyModule_Create(&fcntlmodule); 648 m = PyModule_Create(&fcntlmodule);
623 if (m == NULL) 649 if (m == NULL)
624 return NULL; 650 return NULL;
625 651
626 /* Add some symbolic constants to the module */ 652 /* Add some symbolic constants to the module */
627 if (all_ins(m) < 0) 653 if (all_ins(m) < 0)
628 return NULL; 654 return NULL;
629 655
630 return m; 656 return m;
631 } 657 }
LEFTRIGHT

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+