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

Side by Side Diff: Modules/fcntlmodule.c

Issue 20152: Derby: Convert the _imp module to use Argument Clinic
Patch Set: Created 6 years 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:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 module fcntl
20 [clinic start generated code]*/
21 /*[clinic end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709] */
17 22
18 static int 23 static int
19 conv_descriptor(PyObject *object, int *target) 24 conv_descriptor(PyObject *object, int *target)
20 { 25 {
21 int fd = PyObject_AsFileDescriptor(object); 26 int fd = PyObject_AsFileDescriptor(object);
22 27
23 if (fd < 0) 28 if (fd < 0)
24 return 0; 29 return 0;
25 *target = fd; 30 *target = fd;
26 return 1; 31 return 1;
27 } 32 }
28 33
29 34
30 /* fcntl(fd, op, [arg]) */ 35 /*[clinic input]
36 fcntl.fcntl
37
38 fd: object(type='int', converter='conv_descriptor')
39 code: int
loewis 2014/07/27 18:02:14 The parameter name should remain "op", in particul
40 arg: object = NULL
41 /
42
43 Perform the operation op on file descriptor fd.
44
45 The values used for op are operating system dependent, and are available
46 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
48 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
50 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
52 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.
54 [clinic start generated code]*/
55
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__},
31 72
32 static PyObject * 73 static PyObject *
33 fcntl_fcntl(PyObject *self, PyObject *args) 74 fcntl_fcntl_impl(PyModuleDef *module, int fd, int code, PyObject *arg);
75
76 static PyObject *
77 fcntl_fcntl(PyModuleDef *module, PyObject *args)
34 { 78 {
79 PyObject *return_value = NULL;
35 int fd; 80 int fd;
36 int code; 81 int code;
37 long arg; 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 *
95 fcntl_fcntl_impl(PyModuleDef *module, int fd, int code, PyObject *arg)
96 /*[clinic end generated code: checksum=c6aa92ae153d591d93726f6ad89ce3232c1d4029] */
97 {
98 long long_arg = 0;
38 int ret; 99 int ret;
39 char *str; 100 char *str;
40 Py_ssize_t len; 101 Py_ssize_t len;
41 char buf[1024]; 102 char buf[1024];
103 PyObject *optional_arg_tuple;
42 104
43 if (PyArg_ParseTuple(args, "O&is#:fcntl", 105 if (arg != NULL) {
44 conv_descriptor, &fd, &code, &str, &len)) { 106 int parse_result;
45 if (len > sizeof buf) { 107 // 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.
109 optional_arg_tuple = PyTuple_Pack(1, arg);
110
111 if (PyArg_ParseTuple(optional_arg_tuple, "s#", &str, &len)) {
112 Py_DECREF(optional_arg_tuple);
113
114 if (len > sizeof buf) {
46 PyErr_SetString(PyExc_ValueError, 115 PyErr_SetString(PyExc_ValueError,
47 "fcntl string arg too long"); 116 "fcntl string arg too long");
48 return NULL; 117 return NULL;
118 }
119 memcpy(buf, str, len);
120 Py_BEGIN_ALLOW_THREADS
121 ret = fcntl(fd, code, buf);
122 Py_END_ALLOW_THREADS
123 if (ret < 0) {
124 PyErr_SetFromErrno(PyExc_IOError);
125 return NULL;
126 }
127 return PyBytes_FromStringAndSize(buf, len);
49 } 128 }
50 memcpy(buf, str, len); 129
51 Py_BEGIN_ALLOW_THREADS 130 PyErr_Clear();
52 ret = fcntl(fd, code, buf); 131 parse_result = PyArg_ParseTuple(optional_arg_tuple,
53 Py_END_ALLOW_THREADS 132 "l;fcntl requires a file or file descriptor,"
54 if (ret < 0) { 133 " an integer and optionally a third integer or a string",
55 PyErr_SetFromErrno(PyExc_IOError); 134 &long_arg);
56 return NULL; 135 Py_DECREF(optional_arg_tuple);
57 } 136 if (!parse_result) {
58 return PyBytes_FromStringAndSize(buf, len); 137 return NULL;
138 }
59 } 139 }
60 140
61 PyErr_Clear();
62 arg = 0;
63 if (!PyArg_ParseTuple(args,
64 "O&i|l;fcntl requires a file or file descriptor,"
65 " an integer and optionally a third integer or a string",
66 conv_descriptor, &fd, &code, &arg)) {
67 return NULL;
68 }
69 Py_BEGIN_ALLOW_THREADS 141 Py_BEGIN_ALLOW_THREADS
70 ret = fcntl(fd, code, arg); 142 ret = fcntl(fd, code, long_arg);
71 Py_END_ALLOW_THREADS 143 Py_END_ALLOW_THREADS
72 if (ret < 0) { 144 if (ret < 0) {
73 PyErr_SetFromErrno(PyExc_IOError); 145 PyErr_SetFromErrno(PyExc_IOError);
74 return NULL; 146 return NULL;
75 } 147 }
76 return PyLong_FromLong((long)ret); 148 return PyLong_FromLong((long)ret);
77 } 149 }
78
79 PyDoc_STRVAR(fcntl_doc,
80 "fcntl(fd, op, [arg])\n\
81 \n\
82 Perform the operation op on file descriptor fd. The values used\n\
83 for op are operating system dependent, and are available\n\
84 as constants in the fcntl module, using the same names as used in\n\
85 the relevant C header files. The argument arg is optional, and\n\
86 defaults to 0; it may be an int or a string. If arg is given as a string,\n\
87 the return value of fcntl is a string of that length, containing the\n\
88 resulting value put in the arg buffer by the operating system. The length\n\
89 of the arg string is not allowed to exceed 1024 bytes. If the arg given\n\
90 is an integer or if none is specified, the result value is an integer\n\
91 corresponding to the return value of the fcntl call in the C code.");
92 150
93 151
94 /* ioctl(fd, op, [arg]) */ 152 /* ioctl(fd, op, [arg]) */
95 153
96 static PyObject * 154 static PyObject *
97 fcntl_ioctl(PyObject *self, PyObject *args) 155 fcntl_ioctl(PyObject *self, PyObject *args)
98 { 156 {
99 #define IOCTL_BUFSZ 1024 157 #define IOCTL_BUFSZ 1024
100 int fd; 158 int fd;
101 /* In PyArg_ParseTuple below, we use the unsigned non-checked 'I' 159 /* In PyArg_ParseTuple below, we use the unsigned non-checked 'I'
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
244 of the buffer is passed to the operating system and the return value is a\n\ 302 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\ 303 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\ 304 the buffer. The length of the arg buffer in this case is not allowed to\n\
247 exceed 1024 bytes.\n\ 305 exceed 1024 bytes.\n\
248 \n\ 306 \n\
249 If the arg given is an integer or if none is specified, the result value is\n\ 307 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\ 308 an integer corresponding to the return value of the ioctl call in the C\n\
251 code."); 309 code.");
252 310
253 311
254 /* flock(fd, operation) */ 312 /*[clinic input]
313 fcntl.flock
314
315 fd: object(type='int', converter='conv_descriptor')
316 code: int
loewis 2014/07/27 18:02:14 The documentation calls it "op", the old version "
317 /
318
319 Perform the lock operation op on file descriptor fd.
320
321 See the Unix manual page for flock(2) for details (On some systems, this
322 function is emulated using fcntl()).
323 [clinic start generated code]*/
324
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__},
255 334
256 static PyObject * 335 static PyObject *
257 fcntl_flock(PyObject *self, PyObject *args) 336 fcntl_flock_impl(PyModuleDef *module, int fd, int code);
337
338 static PyObject *
339 fcntl_flock(PyModuleDef *module, PyObject *args)
258 { 340 {
341 PyObject *return_value = NULL;
259 int fd; 342 int fd;
260 int code; 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 *
356 fcntl_flock_impl(PyModuleDef *module, int fd, int code)
357 /*[clinic end generated code: checksum=3a8b37cd71057c8418e6769e14edb27b173026bb] */
358 {
261 int ret; 359 int ret;
262
263 if (!PyArg_ParseTuple(args, "O&i:flock",
264 conv_descriptor, &fd, &code))
265 return NULL;
266 360
267 #ifdef HAVE_FLOCK 361 #ifdef HAVE_FLOCK
268 Py_BEGIN_ALLOW_THREADS 362 Py_BEGIN_ALLOW_THREADS
269 ret = flock(fd, code); 363 ret = flock(fd, code);
270 Py_END_ALLOW_THREADS 364 Py_END_ALLOW_THREADS
271 #else 365 #else
272 366
273 #ifndef LOCK_SH 367 #ifndef LOCK_SH
274 #define LOCK_SH 1 /* shared lock */ 368 #define LOCK_SH 1 /* shared lock */
275 #define LOCK_EX 2 /* exclusive lock */ 369 #define LOCK_EX 2 /* exclusive lock */
(...skipping 16 matching lines...) Expand all
292 l.l_whence = l.l_start = l.l_len = 0; 386 l.l_whence = l.l_start = l.l_len = 0;
293 Py_BEGIN_ALLOW_THREADS 387 Py_BEGIN_ALLOW_THREADS
294 ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l); 388 ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
295 Py_END_ALLOW_THREADS 389 Py_END_ALLOW_THREADS
296 } 390 }
297 #endif /* HAVE_FLOCK */ 391 #endif /* HAVE_FLOCK */
298 if (ret < 0) { 392 if (ret < 0) {
299 PyErr_SetFromErrno(PyExc_IOError); 393 PyErr_SetFromErrno(PyExc_IOError);
300 return NULL; 394 return NULL;
301 } 395 }
302 Py_INCREF(Py_None); 396 Py_RETURN_NONE;
303 return Py_None;
304 } 397 }
305 398
306 PyDoc_STRVAR(flock_doc,
307 "flock(fd, operation)\n\
308 \n\
309 Perform the lock operation op on file descriptor fd. See the Unix \n\
310 manual page for flock(2) for details. (On some systems, this function is\n\
311 emulated using fcntl().)");
312 399
400 /*[clinic input]
401 fcntl.lockf
313 402
314 /* lockf(fd, operation) */ 403 fd: object(type='int', converter='conv_descriptor')
404 code: int
405 lenobj: object = NULL
406 startobj: object = NULL
407 whence: int = 0
loewis 2014/07/27 18:02:14 Here, the documentation parameter names are fd, o
408 /
409
410 A wrapper around the fcntl() locking calls.
411
412 fd is the file descriptor of the file to lock or unlock, and operation is one
413 of the following values:
414
415 LOCK_UN - unlock
416 LOCK_SH - acquire a shared lock
417 LOCK_EX - acquire an exclusive lock
418
419 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
421 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
423 system -- for portability, check for either value).
424
425 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
427 starts. whence is as with fileobj.seek(), specifically:
428
429 0 - relative to the start of the file (SEEK_SET)
430 1 - relative to the current buffer position (SEEK_CUR)
431 2 - relative to the end of the file (SEEK_END)
432 [clinic start generated code]*/
433
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
315 static PyObject * 462 static PyObject *
316 fcntl_lockf(PyObject *self, PyObject *args) 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)
317 { 467 {
318 int fd, code, ret, whence = 0; 468 PyObject *return_value = NULL;
319 PyObject *lenobj = NULL, *startobj = NULL; 469 int fd;
470 int code;
471 PyObject *lenobj = NULL;
472 PyObject *startobj = NULL;
473 int whence = 0;
320 474
321 if (!PyArg_ParseTuple(args, "O&i|OOi:lockf", 475 if (!PyArg_ParseTuple(args,
322 conv_descriptor, &fd, &code, 476 "O&i|OOi:lockf",
323 &lenobj, &startobj, &whence)) 477 conv_descriptor, &fd, &code, &lenobj, &startobj, &whence))
324 return NULL; 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 *
486 fcntl_lockf_impl(PyModuleDef *module, int fd, int code, PyObject *lenobj, PyObje ct *startobj, int whence)
487 /*[clinic end generated code: checksum=26d08a7fe50990b7443a197ddcc106bcb6f10bf1] */
488 {
489 int ret;
325 490
326 #ifndef LOCK_SH 491 #ifndef LOCK_SH
327 #define LOCK_SH 1 /* shared lock */ 492 #define LOCK_SH 1 /* shared lock */
328 #define LOCK_EX 2 /* exclusive lock */ 493 #define LOCK_EX 2 /* exclusive lock */
329 #define LOCK_NB 4 /* don't block when locking */ 494 #define LOCK_NB 4 /* don't block when locking */
330 #define LOCK_UN 8 /* unlock */ 495 #define LOCK_UN 8 /* unlock */
331 #endif /* LOCK_SH */ 496 #endif /* LOCK_SH */
332 { 497 {
333 struct flock l; 498 struct flock l;
334 if (code == LOCK_UN) 499 if (code == LOCK_UN)
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
367 } 532 }
368 l.l_whence = whence; 533 l.l_whence = whence;
369 Py_BEGIN_ALLOW_THREADS 534 Py_BEGIN_ALLOW_THREADS
370 ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l); 535 ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l);
371 Py_END_ALLOW_THREADS 536 Py_END_ALLOW_THREADS
372 } 537 }
373 if (ret < 0) { 538 if (ret < 0) {
374 PyErr_SetFromErrno(PyExc_IOError); 539 PyErr_SetFromErrno(PyExc_IOError);
375 return NULL; 540 return NULL;
376 } 541 }
377 Py_INCREF(Py_None); 542 Py_RETURN_NONE;
378 return Py_None;
379 } 543 }
380 544
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 545
406 /* List of functions */ 546 /* List of functions */
407 547
408 static PyMethodDef fcntl_methods[] = { 548 static PyMethodDef fcntl_methods[] = {
409 {"fcntl", fcntl_fcntl, METH_VARARGS, fcntl_doc}, 549 FCNTL_FCNTL_METHODDEF
410 {"ioctl", fcntl_ioctl, METH_VARARGS, ioctl_doc}, 550 {"ioctl", fcntl_ioctl, METH_VARARGS, ioctl_doc},
411 {"flock", fcntl_flock, METH_VARARGS, flock_doc}, 551 FCNTL_FLOCK_METHODDEF
412 {"lockf", fcntl_lockf, METH_VARARGS, lockf_doc}, 552 FCNTL_LOCKF_METHODDEF
413 {NULL, NULL} /* sentinel */ 553 {NULL, NULL} /* sentinel */
414 }; 554 };
415 555
416 556
417 PyDoc_STRVAR(module_doc, 557 PyDoc_STRVAR(module_doc,
418 "This module performs file control and I/O control on file \n\ 558 "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\ 559 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\ 560 routines. File descriptors can be obtained with the fileno() method of\n\
421 a file or socket object."); 561 a file or socket object.");
422 562
423 /* Module initialisation */ 563 /* Module initialisation */
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
622 m = PyModule_Create(&fcntlmodule); 762 m = PyModule_Create(&fcntlmodule);
623 if (m == NULL) 763 if (m == NULL)
624 return NULL; 764 return NULL;
625 765
626 /* Add some symbolic constants to the module */ 766 /* Add some symbolic constants to the module */
627 if (all_ins(m) < 0) 767 if (all_ins(m) < 0)
628 return NULL; 768 return NULL;
629 769
630 return m; 770 return m;
631 } 771 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

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