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

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, 2 months ago
Right Patch Set: Created 5 years, 4 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:
Left: Side by side diff | Download
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
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 17
18 /*[clinic input] 18 /*[clinic input]
19 output preset file
19 module fcntl 20 module fcntl
20 [clinic start generated code]*/ 21 [clinic start generated code]*/
21 /*[clinic end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709] */ 22 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=c7356fdb126a904a]*/
22 23
23 static int 24 static int
24 conv_descriptor(PyObject *object, int *target) 25 conv_descriptor(PyObject *object, int *target)
25 { 26 {
26 int fd = PyObject_AsFileDescriptor(object); 27 int fd = PyObject_AsFileDescriptor(object);
27 28
28 if (fd < 0) 29 if (fd < 0)
29 return 0; 30 return 0;
30 *target = fd; 31 *target = fd;
31 return 1; 32 return 1;
32 } 33 }
33 34
35 /* Must come after conv_descriptor definition. */
36 #include "clinic/fcntlmodule.c.h"
34 37
35 /*[clinic input] 38 /*[clinic input]
36 fcntl.fcntl 39 fcntl.fcntl
37 40
38 fd: object(type='int', converter='conv_descriptor') 41 fd: object(type='int', converter='conv_descriptor')
39 code: int 42 code: int
loewis 2014/07/27 18:02:14 The parameter name should remain "op", in particul
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
40 arg: object = NULL 43 arg: object = NULL
41 / 44 /
42 45
43 Perform the operation op on file descriptor fd. 46 Perform the operation `code` on file descriptor fd.
44 47
45 The values used for op are operating system dependent, and are available 48 The values used for `code` are operating system dependent, and are available
46 as constants in the fcntl module, using the same names as used in 49 as constants in the fcntl module, using the same names as used in
47 the relevant C header files. The argument arg is optional, and 50 the relevant C header files. The argument arg is optional, and
48 defaults to 0; it may be an int or a string. If arg is given as a string, 51 defaults to 0; it may be an int or a string. If arg is given as a string,
49 the return value of fcntl is a string of that length, containing the 52 the return value of fcntl is a string of that length, containing the
50 resulting value put in the arg buffer by the operating system. The length 53 resulting value put in the arg buffer by the operating system. The length
51 of the arg string is not allowed to exceed 1024 bytes. If the arg given 54 of the arg string is not allowed to exceed 1024 bytes. If the arg given
52 is an integer or if none is specified, the result value is an integer 55 is an integer or if none is specified, the result value is an integer
53 corresponding to the return value of the fcntl call in the C code. 56 corresponding to the return value of the fcntl call in the C code.
54 [clinic start generated code]*/ 57 [clinic start generated code]*/
55 58
56 PyDoc_STRVAR(fcntl_fcntl__doc__,
57 "fcntl(fd, code, arg=None)\n"
58 "Perform the operation op on file descriptor fd.\n"
59 "\n"
60 "The values used for op are operating system dependent, and are available\n"
61 "as constants in the fcntl module, using the same names as used in\n"
62 "the relevant C header files. The argument arg is optional, and\n"
63 "defaults to 0; it may be an int or a string. If arg is given as a string,\n"
64 "the return value of fcntl is a string of that length, containing the\n"
65 "resulting value put in the arg buffer by the operating system. The length\n"
66 "of the arg string is not allowed to exceed 1024 bytes. If the arg given\n"
67 "is an integer or if none is specified, the result value is an integer\n"
68 "corresponding to the return value of the fcntl call in the C code.");
69
70 #define FCNTL_FCNTL_METHODDEF \
71 {"fcntl", (PyCFunction)fcntl_fcntl, METH_VARARGS, fcntl_fcntl__doc__},
72
73 static PyObject *
74 fcntl_fcntl_impl(PyModuleDef *module, int fd, int code, PyObject *arg);
75
76 static PyObject *
77 fcntl_fcntl(PyModuleDef *module, PyObject *args)
78 {
79 PyObject *return_value = NULL;
80 int fd;
81 int code;
82 PyObject *arg = NULL;
83
84 if (!PyArg_ParseTuple(args,
85 "O&i|O:fcntl",
86 conv_descriptor, &fd, &code, &arg))
87 goto exit;
88 return_value = fcntl_fcntl_impl(module, fd, code, arg);
89
90 exit:
91 return return_value;
92 }
93
94 static PyObject * 59 static PyObject *
95 fcntl_fcntl_impl(PyModuleDef *module, int fd, int code, PyObject *arg) 60 fcntl_fcntl_impl(PyModuleDef *module, int fd, int code, PyObject *arg)
96 /*[clinic end generated code: checksum=c6aa92ae153d591d93726f6ad89ce3232c1d4029] */ 61 /*[clinic end generated code: output=afc5bfa74a03ef0d input=4850c13a41e86930]*/
97 { 62 {
98 long long_arg = 0; 63 long long_arg = 0;
99 int ret; 64 int ret;
100 char *str; 65 char *str;
101 Py_ssize_t len; 66 Py_ssize_t len;
102 char buf[1024]; 67 char buf[1024];
103 PyObject *optional_arg_tuple; 68 PyObject *optional_arg_tuple;
104 69
105 if (arg != NULL) { 70 if (arg != NULL) {
106 int parse_result; 71 int parse_result;
107 // As the optional argument can be l or s#, need to use the magic of 72 // As the optional argument can be l or s#, need to use the magic of
108 // PyArg_ParseTuple() to do the right thing if the s# is needed. 73 // PyArg_ParseTuple() to do the right thing if the s# is needed.
109 optional_arg_tuple = PyTuple_Pack(1, arg); 74 optional_arg_tuple = PyTuple_Pack(1, arg);
110 75
111 if (PyArg_ParseTuple(optional_arg_tuple, "s#", &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.
112 Py_DECREF(optional_arg_tuple); 77 Py_DECREF(optional_arg_tuple);
113 78
114 if (len > sizeof buf) { 79 if ((size_t)len > sizeof buf) {
115 PyErr_SetString(PyExc_ValueError, 80 PyErr_SetString(PyExc_ValueError,
116 "fcntl string arg too long"); 81 "fcntl string arg too long");
117 return NULL; 82 return NULL;
118 } 83 }
119 memcpy(buf, str, len); 84 memcpy(buf, str, len);
120 Py_BEGIN_ALLOW_THREADS 85 Py_BEGIN_ALLOW_THREADS
121 ret = fcntl(fd, code, buf); 86 ret = fcntl(fd, code, buf);
122 Py_END_ALLOW_THREADS 87 Py_END_ALLOW_THREADS
123 if (ret < 0) { 88 if (ret < 0) {
124 PyErr_SetFromErrno(PyExc_IOError); 89 PyErr_SetFromErrno(PyExc_IOError);
125 return NULL; 90 return NULL;
126 } 91 }
127 return PyBytes_FromStringAndSize(buf, len); 92 return PyBytes_FromStringAndSize(buf, len);
128 } 93 }
129 94
130 PyErr_Clear(); 95 PyErr_Clear();
131 parse_result = PyArg_ParseTuple(optional_arg_tuple, 96 parse_result = PyArg_ParseTuple(optional_arg_tuple,
132 "l;fcntl requires a file or file descriptor," 97 "l;fcntl requires a file or file descriptor,"
133 " an integer and optionally a third integer or a string", 98 " an integer and optionally a third integer or a string",
134 &long_arg); 99 &long_arg);
135 Py_DECREF(optional_arg_tuple); 100 Py_DECREF(optional_arg_tuple);
136 if (!parse_result) { 101 if (!parse_result) {
137 return NULL; 102 return NULL;
138 } 103 }
139 } 104 }
140 105
141 Py_BEGIN_ALLOW_THREADS 106 Py_BEGIN_ALLOW_THREADS
142 ret = fcntl(fd, code, long_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
143 Py_END_ALLOW_THREADS 108 Py_END_ALLOW_THREADS
144 if (ret < 0) { 109 if (ret < 0) {
145 PyErr_SetFromErrno(PyExc_IOError); 110 PyErr_SetFromErrno(PyExc_IOError);
146 return NULL; 111 return NULL;
147 } 112 }
148 return PyLong_FromLong((long)ret); 113 return PyLong_FromLong((long)ret);
149 } 114 }
150 115
151 116
152 /* ioctl(fd, op, [arg]) */ 117 /*[clinic input]
118 fcntl.ioctl
119
120 fd: object(type='int', converter='conv_descriptor')
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
122 arg as ob_arg: object = NULL
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.
124 /
125
126 Perform the operation op on file descriptor fd.
127
128 The values used for op are operating system dependent, and are available as
129 constants in the fcntl or termios library modules, using the same names as
130 used in the relevant C header files.
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]*/
153 156
154 static PyObject * 157 static PyObject *
155 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]*/
156 { 160 {
157 #define IOCTL_BUFSZ 1024 161 #define IOCTL_BUFSZ 1024
158 int fd; 162 /* We use the unsigned non-checked 'I'
159 /* In PyArg_ParseTuple below, we use the unsigned non-checked 'I'
160 format for the 'code' parameter because Python turns 0x8000000 163 format for the 'code' parameter because Python turns 0x8000000
161 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
162 platforms) or a negative number on others (32-bit PyInt) 165 platforms) or a negative number on others (32-bit PyInt)
163 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
164 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
165 various platforms. See the termios.TIOCSWINSZ constant across 168 various platforms. See the termios.TIOCSWINSZ constant across
166 platforms for an example of this. 169 platforms for an example of this.
167 170
168 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
169 in their unsigned long ioctl codes this will break and need 172 in their unsigned long ioctl codes this will break and need
170 special casing based on the platform being built on. 173 special casing based on the platform being built on.
171 */ 174 */
172 unsigned int code; 175 int arg = 0;
173 int arg;
174 int ret; 176 int ret;
175 Py_buffer pstr; 177 Py_buffer pstr;
176 char *str; 178 char *str;
177 Py_ssize_t len; 179 Py_ssize_t len;
178 int mutate_arg = 1;
179 char buf[IOCTL_BUFSZ+1]; /* argument plus NUL byte */ 180 char buf[IOCTL_BUFSZ+1]; /* argument plus NUL byte */
180 181
181 if (PyArg_ParseTuple(args, "O&Iw*|i:ioctl", 182 if (ob_arg != NULL) {
182 conv_descriptor, &fd, &code, 183 PyObject* args = PyTuple_Pack(1, ob_arg);
183 &pstr, &mutate_arg)) { 184 if (PyArg_ParseTuple(args, "w*:ioctl", &pstr)) {
184 char *arg; 185 char *arg;
185 str = pstr.buf; 186 str = pstr.buf;
186 len = pstr.len; 187 len = pstr.len;
187 188
188 if (mutate_arg) { 189 if (mutate_arg) {
189 if (len <= IOCTL_BUFSZ) { 190 if (len <= IOCTL_BUFSZ) {
190 memcpy(buf, str, len); 191 memcpy(buf, str, len);
191 buf[len] = '\0'; 192 buf[len] = '\0';
192 arg = buf; 193 arg = buf;
194 }
195 else {
196 arg = str;
197 }
193 } 198 }
194 else { 199 else {
195 arg = str; 200 if (len > IOCTL_BUFSZ) {
196 } 201 PyBuffer_Release(&pstr);
197 } 202 PyErr_SetString(PyExc_ValueError,
198 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;
199 if (len > IOCTL_BUFSZ) { 240 if (len > IOCTL_BUFSZ) {
200 PyBuffer_Release(&pstr); 241 PyBuffer_Release(&pstr);
201 PyErr_SetString(PyExc_ValueError, 242 PyErr_SetString(PyExc_ValueError,
202 "ioctl string arg too long"); 243 "ioctl string arg too long");
203 return NULL; 244 return NULL;
204 } 245 }
205 else { 246 memcpy(buf, str, len);
206 memcpy(buf, str, len); 247 buf[len] = '\0';
207 buf[len] = '\0'; 248 Py_BEGIN_ALLOW_THREADS
208 arg = buf; 249 ret = ioctl(fd, code, buf);
209 }
210 }
211 if (buf == arg) {
212 Py_BEGIN_ALLOW_THREADS /* think array.resize() */
213 ret = ioctl(fd, code, arg);
214 Py_END_ALLOW_THREADS 250 Py_END_ALLOW_THREADS
215 } 251 if (ret < 0) {
216 else { 252 PyBuffer_Release(&pstr);
217 ret = ioctl(fd, code, arg); 253 PyErr_SetFromErrno(PyExc_IOError);
218 } 254 return NULL;
219 if (mutate_arg && (len <= IOCTL_BUFSZ)) { 255 }
220 memcpy(str, buf, len); 256 PyBuffer_Release(&pstr);
221 }
222 PyBuffer_Release(&pstr); /* No further access to str below this point */
223 if (ret < 0) {
224 PyErr_SetFromErrno(PyExc_IOError);
225 return NULL;
226 }
227 if (mutate_arg) {
228 return PyLong_FromLong(ret);
229 }
230 else {
231 return PyBytes_FromStringAndSize(buf, len); 257 return PyBytes_FromStringAndSize(buf, len);
232 } 258 }
233 } 259
234 260 PyErr_Clear();
235 PyErr_Clear(); 261 if (!PyArg_ParseTuple(args,
236 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.
237 conv_descriptor, &fd, &code, &pstr)) { 263 " an integer and optionally an integer or buffer argument",
238 str = pstr.buf; 264 &arg)) {
239 len = pstr.len; 265 return NULL;
240 if (len > IOCTL_BUFSZ) { 266 }
241 PyBuffer_Release(&pstr); 267 // Fall-through to outside the 'if' statement.
242 PyErr_SetString(PyExc_ValueError,
243 "ioctl string arg too long");
244 return NULL;
245 }
246 memcpy(buf, str, len);
247 buf[len] = '\0';
248 Py_BEGIN_ALLOW_THREADS
249 ret = ioctl(fd, code, buf);
250 Py_END_ALLOW_THREADS
251 if (ret < 0) {
252 PyBuffer_Release(&pstr);
253 PyErr_SetFromErrno(PyExc_IOError);
254 return NULL;
255 }
256 PyBuffer_Release(&pstr);
257 return PyBytes_FromStringAndSize(buf, len);
258 }
259
260 PyErr_Clear();
261 arg = 0;
262 if (!PyArg_ParseTuple(args,
263 "O&I|i;ioctl requires a file or file descriptor,"
264 " an integer and optionally an integer or buffer argument",
265 conv_descriptor, &fd, &code, &arg)) {
266 return NULL;
267 } 268 }
268 Py_BEGIN_ALLOW_THREADS 269 Py_BEGIN_ALLOW_THREADS
269 ret = ioctl(fd, code, arg); 270 ret = ioctl(fd, code, arg);
270 Py_END_ALLOW_THREADS 271 Py_END_ALLOW_THREADS
271 if (ret < 0) { 272 if (ret < 0) {
272 PyErr_SetFromErrno(PyExc_IOError); 273 PyErr_SetFromErrno(PyExc_IOError);
273 return NULL; 274 return NULL;
274 } 275 }
275 return PyLong_FromLong((long)ret); 276 return PyLong_FromLong((long)ret);
276 #undef IOCTL_BUFSZ 277 #undef IOCTL_BUFSZ
277 } 278 }
278 279
279 PyDoc_STRVAR(ioctl_doc,
280 "ioctl(fd, op[, arg[, mutate_flag]])\n\
281 \n\
282 Perform the operation op on file descriptor fd. The values used for op\n\
283 are operating system dependent, and are available as constants in the\n\
284 fcntl or termios library modules, using the same names as used in the\n\
285 relevant C header files.\n\
286 \n\
287 The argument arg is optional, and defaults to 0; it may be an int or a\n\
288 buffer containing character data (most likely a string or an array). \n\
289 \n\
290 If the argument is a mutable buffer (such as an array) and if the\n\
291 mutate_flag argument (which is only allowed in this case) is true then the\n\
292 buffer is (in effect) passed to the operating system and changes made by\n\
293 the OS will be reflected in the contents of the buffer after the call has\n\
294 returned. The return value is the integer returned by the ioctl system\n\
295 call.\n\
296 \n\
297 If the argument is a mutable buffer and the mutable_flag argument is not\n\
298 passed or is false, the behavior is as if a string had been passed. This\n\
299 behavior will change in future releases of Python.\n\
300 \n\
301 If the argument is an immutable buffer (most likely a string) then a copy\n\
302 of the buffer is passed to the operating system and the return value is a\n\
303 string of the same length containing whatever the operating system put in\n\
304 the buffer. The length of the arg buffer in this case is not allowed to\n\
305 exceed 1024 bytes.\n\
306 \n\
307 If the arg given is an integer or if none is specified, the result value is\n\
308 an integer corresponding to the return value of the ioctl call in the C\n\
309 code.");
310
311
312 /*[clinic input] 280 /*[clinic input]
313 fcntl.flock 281 fcntl.flock
314 282
315 fd: object(type='int', converter='conv_descriptor') 283 fd: object(type='int', converter='conv_descriptor')
316 code: int 284 code: int
loewis 2014/07/27 18:02:14 The documentation calls it "op", the old version "
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
317 / 285 /
318 286
319 Perform the lock operation op on file descriptor fd. 287 Perform the lock operation op on file descriptor fd.
320 288
321 See the Unix manual page for flock(2) for details (On some systems, this 289 See the Unix manual page for flock(2) for details (On some systems, this
322 function is emulated using fcntl()). 290 function is emulated using fcntl()).
323 [clinic start generated code]*/ 291 [clinic start generated code]*/
324 292
325 PyDoc_STRVAR(fcntl_flock__doc__,
326 "flock(fd, code)\n"
327 "Perform the lock operation op on file descriptor fd.\n"
328 "\n"
329 "See the Unix manual page for flock(2) for details (On some systems, this\n"
330 "function is emulated using fcntl()).");
331
332 #define FCNTL_FLOCK_METHODDEF \
333 {"flock", (PyCFunction)fcntl_flock, METH_VARARGS, fcntl_flock__doc__},
334
335 static PyObject *
336 fcntl_flock_impl(PyModuleDef *module, int fd, int code);
337
338 static PyObject *
339 fcntl_flock(PyModuleDef *module, PyObject *args)
340 {
341 PyObject *return_value = NULL;
342 int fd;
343 int code;
344
345 if (!PyArg_ParseTuple(args,
346 "O&i:flock",
347 conv_descriptor, &fd, &code))
348 goto exit;
349 return_value = fcntl_flock_impl(module, fd, code);
350
351 exit:
352 return return_value;
353 }
354
355 static PyObject * 293 static PyObject *
356 fcntl_flock_impl(PyModuleDef *module, int fd, int code) 294 fcntl_flock_impl(PyModuleDef *module, int fd, int code)
357 /*[clinic end generated code: checksum=3a8b37cd71057c8418e6769e14edb27b173026bb] */ 295 /*[clinic end generated code: output=c9035133a7dbfc96 input=b762aa9448d05e43]*/
358 { 296 {
359 int ret; 297 int ret;
360 298
361 #ifdef HAVE_FLOCK 299 #ifdef HAVE_FLOCK
362 Py_BEGIN_ALLOW_THREADS 300 Py_BEGIN_ALLOW_THREADS
363 ret = flock(fd, code); 301 ret = flock(fd, code);
364 Py_END_ALLOW_THREADS 302 Py_END_ALLOW_THREADS
365 #else 303 #else
366 304
367 #ifndef LOCK_SH 305 #ifndef LOCK_SH
(...skipping 26 matching lines...) Expand all
394 return NULL; 332 return NULL;
395 } 333 }
396 Py_RETURN_NONE; 334 Py_RETURN_NONE;
397 } 335 }
398 336
399 337
400 /*[clinic input] 338 /*[clinic input]
401 fcntl.lockf 339 fcntl.lockf
402 340
403 fd: object(type='int', converter='conv_descriptor') 341 fd: object(type='int', converter='conv_descriptor')
404 code: int 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
405 lenobj: object = NULL 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
406 startobj: object = NULL 344 startobj: object = NULL
407 whence: int = 0 345 whence: int = 0
loewis 2014/07/27 18:02:14 Here, the documentation parameter names are fd, o
408 / 346 /
409 347
410 A wrapper around the fcntl() locking calls. 348 A wrapper around the fcntl() locking calls.
411 349
412 fd is the file descriptor of the file to lock or unlock, and operation is one 350 fd is the file descriptor of the file to lock or unlock, and operation is one
413 of the following values: 351 of the following values:
414 352
415 LOCK_UN - unlock 353 LOCK_UN - unlock
416 LOCK_SH - acquire a shared lock 354 LOCK_SH - acquire a shared lock
417 LOCK_EX - acquire an exclusive lock 355 LOCK_EX - acquire an exclusive lock
418 356
419 When operation is LOCK_SH or LOCK_EX, it can also be bitwise ORed with 357 When operation is LOCK_SH or LOCK_EX, it can also be bitwise ORed with
420 LOCK_NB to avoid blocking on lock acquisition. If LOCK_NB is used and the 358 LOCK_NB to avoid blocking on lock acquisition. If LOCK_NB is used and the
421 lock cannot be acquired, an IOError will be raised and the exception will 359 lock cannot be acquired, an IOError will be raised and the exception will
422 have an errno attribute set to EACCES or EAGAIN (depending on the operating 360 have an errno attribute set to EACCES or EAGAIN (depending on the operating
423 system -- for portability, check for either value). 361 system -- for portability, check for either value).
424 362
425 length is the number of bytes to lock, with the default meaning to lock to 363 length is the number of bytes to lock, with the default meaning to lock to
426 EOF. start is the byte offset, relative to whence, to that the lock 364 EOF. start is the byte offset, relative to whence, to that the lock
427 starts. whence is as with fileobj.seek(), specifically: 365 starts. whence is as with fileobj.seek(), specifically:
428 366
429 0 - relative to the start of the file (SEEK_SET) 367 0 - relative to the start of the file (SEEK_SET)
430 1 - relative to the current buffer position (SEEK_CUR) 368 1 - relative to the current buffer position (SEEK_CUR)
431 2 - relative to the end of the file (SEEK_END) 369 2 - relative to the end of the file (SEEK_END)
432 [clinic start generated code]*/ 370 [clinic start generated code]*/
433 371
434 PyDoc_STRVAR(fcntl_lockf__doc__,
435 "lockf(fd, code, lenobj=None, startobj=None, whence=0)\n"
436 "A wrapper around the fcntl() locking calls.\n"
437 "\n"
438 "fd is the file descriptor of the file to lock or unlock, and operation is one\n "
439 "of the following values:\n"
440 "\n"
441 " LOCK_UN - unlock\n"
442 " LOCK_SH - acquire a shared lock\n"
443 " LOCK_EX - acquire an exclusive lock\n"
444 "\n"
445 "When operation is LOCK_SH or LOCK_EX, it can also be bitwise ORed with\n"
446 "LOCK_NB to avoid blocking on lock acquisition. If LOCK_NB is used and the\n"
447 "lock cannot be acquired, an IOError will be raised and the exception will\n"
448 "have an errno attribute set to EACCES or EAGAIN (depending on the operating\n"
449 "system -- for portability, check for either value).\n"
450 "\n"
451 "length is the number of bytes to lock, with the default meaning to lock to\n"
452 "EOF. start is the byte offset, relative to whence, to that the lock\n"
453 "starts. whence is as with fileobj.seek(), specifically:\n"
454 "\n"
455 " 0 - relative to the start of the file (SEEK_SET)\n"
456 " 1 - relative to the current buffer position (SEEK_CUR)\n"
457 " 2 - relative to the end of the file (SEEK_END)");
458
459 #define FCNTL_LOCKF_METHODDEF \
460 {"lockf", (PyCFunction)fcntl_lockf, METH_VARARGS, fcntl_lockf__doc__},
461
462 static PyObject *
463 fcntl_lockf_impl(PyModuleDef *module, int fd, int code, PyObject *lenobj, PyObje ct *startobj, int whence);
464
465 static PyObject *
466 fcntl_lockf(PyModuleDef *module, PyObject *args)
467 {
468 PyObject *return_value = NULL;
469 int fd;
470 int code;
471 PyObject *lenobj = NULL;
472 PyObject *startobj = NULL;
473 int whence = 0;
474
475 if (!PyArg_ParseTuple(args,
476 "O&i|OOi:lockf",
477 conv_descriptor, &fd, &code, &lenobj, &startobj, &whence))
478 goto exit;
479 return_value = fcntl_lockf_impl(module, fd, code, lenobj, startobj, whence);
480
481 exit:
482 return return_value;
483 }
484
485 static PyObject * 372 static PyObject *
486 fcntl_lockf_impl(PyModuleDef *module, int fd, int code, PyObject *lenobj, PyObje ct *startobj, int whence) 373 fcntl_lockf_impl(PyModuleDef *module, int fd, int code, PyObject *lenobj, PyObje ct *startobj, int whence)
487 /*[clinic end generated code: checksum=26d08a7fe50990b7443a197ddcc106bcb6f10bf1] */ 374 /*[clinic end generated code: output=5536df2892bf3ce9 input=44856fa06db36184]*/
488 { 375 {
489 int ret; 376 int ret;
490 377
491 #ifndef LOCK_SH 378 #ifndef LOCK_SH
492 #define LOCK_SH 1 /* shared lock */ 379 #define LOCK_SH 1 /* shared lock */
493 #define LOCK_EX 2 /* exclusive lock */ 380 #define LOCK_EX 2 /* exclusive lock */
494 #define LOCK_NB 4 /* don't block when locking */ 381 #define LOCK_NB 4 /* don't block when locking */
495 #define LOCK_UN 8 /* unlock */ 382 #define LOCK_UN 8 /* unlock */
496 #endif /* LOCK_SH */ 383 #endif /* LOCK_SH */
497 { 384 {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
535 ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l); 422 ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
536 Py_END_ALLOW_THREADS 423 Py_END_ALLOW_THREADS
537 } 424 }
538 if (ret < 0) { 425 if (ret < 0) {
539 PyErr_SetFromErrno(PyExc_IOError); 426 PyErr_SetFromErrno(PyExc_IOError);
540 return NULL; 427 return NULL;
541 } 428 }
542 Py_RETURN_NONE; 429 Py_RETURN_NONE;
543 } 430 }
544 431
545
546 /* List of functions */ 432 /* List of functions */
547 433
548 static PyMethodDef fcntl_methods[] = { 434 static PyMethodDef fcntl_methods[] = {
549 FCNTL_FCNTL_METHODDEF 435 FCNTL_FCNTL_METHODDEF
550 {"ioctl", fcntl_ioctl, METH_VARARGS, ioctl_doc}, 436 FCNTL_IOCTL_METHODDEF
551 FCNTL_FLOCK_METHODDEF 437 FCNTL_FLOCK_METHODDEF
552 FCNTL_LOCKF_METHODDEF 438 FCNTL_LOCKF_METHODDEF
553 {NULL, NULL} /* sentinel */ 439 {NULL, NULL} /* sentinel */
554 }; 440 };
555 441
556 442
557 PyDoc_STRVAR(module_doc, 443 PyDoc_STRVAR(module_doc,
558 "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\
559 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\
560 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\
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
762 m = PyModule_Create(&fcntlmodule); 648 m = PyModule_Create(&fcntlmodule);
763 if (m == NULL) 649 if (m == NULL)
764 return NULL; 650 return NULL;
765 651
766 /* Add some symbolic constants to the module */ 652 /* Add some symbolic constants to the module */
767 if (all_ins(m) < 0) 653 if (all_ins(m) < 0)
768 return NULL; 654 return NULL;
769 655
770 return m; 656 return m;
771 } 657 }
LEFTRIGHT

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