Changeset 388 for python/vendor/current/Modules/fcntlmodule.c
- Timestamp:
- Mar 19, 2014, 11:11:30 AM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
python/vendor/current/Modules/fcntlmodule.c
r2 r388 22 22 23 23 if (fd < 0) 24 24 return 0; 25 25 *target = fd; 26 26 return 1; … … 33 33 fcntl_fcntl(PyObject *self, PyObject *args) 34 34 { 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 " an integer and optionally a third integer or a string",66 67 68 69 70 71 72 73 74 75 76 35 int fd; 36 int code; 37 long arg; 38 int ret; 39 char *str; 40 Py_ssize_t len; 41 char buf[1024]; 42 43 if (PyArg_ParseTuple(args, "O&is#:fcntl", 44 conv_descriptor, &fd, &code, &str, &len)) { 45 if (len > sizeof buf) { 46 PyErr_SetString(PyExc_ValueError, 47 "fcntl string arg too long"); 48 return NULL; 49 } 50 memcpy(buf, str, len); 51 Py_BEGIN_ALLOW_THREADS 52 ret = fcntl(fd, code, buf); 53 Py_END_ALLOW_THREADS 54 if (ret < 0) { 55 PyErr_SetFromErrno(PyExc_IOError); 56 return NULL; 57 } 58 return PyString_FromStringAndSize(buf, len); 59 } 60 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 70 ret = fcntl(fd, code, arg); 71 Py_END_ALLOW_THREADS 72 if (ret < 0) { 73 PyErr_SetFromErrno(PyExc_IOError); 74 return NULL; 75 } 76 return PyInt_FromLong((long)ret); 77 77 } 78 78 … … 83 83 is defined by op and is operating system dependent. These constants are\n\ 84 84 available from the fcntl module. The argument arg is optional, and\n\ 85 defaults to 0; it may be an int or a string. If arg is given as a string,\n\85 defaults to 0; it may be an int or a string. If arg is given as a string,\n\ 86 86 the return value of fcntl is a string of that length, containing the\n\ 87 resulting value put in the arg buffer by the operating system. The length\n\88 of the arg string is not allowed to exceed 1024 bytes. If the arg given\n\87 resulting value put in the arg buffer by the operating system. The length\n\ 88 of the arg string is not allowed to exceed 1024 bytes. If the arg given\n\ 89 89 is an integer or if none is specified, the result value is an integer\n\ 90 90 corresponding to the return value of the fcntl call in the C code."); … … 97 97 { 98 98 #define IOCTL_BUFSZ 1024 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 conv_descriptor, &fd, &code,123 124 125 126 127 128 129 130 131 } 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 if (mutate_arg && (len <IOCTL_BUFSZ)) {157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 99 int fd; 100 /* 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; 114 int arg; 115 int ret; 116 char *str; 117 Py_ssize_t len; 118 int mutate_arg = 1; 119 char buf[IOCTL_BUFSZ+1]; /* argument plus NUL byte */ 120 121 if (PyArg_ParseTuple(args, "O&Iw#|i:ioctl", 122 conv_descriptor, &fd, &code, 123 &str, &len, &mutate_arg)) { 124 char *arg; 125 126 if (mutate_arg) { 127 if (len <= IOCTL_BUFSZ) { 128 memcpy(buf, str, len); 129 buf[len] = '\0'; 130 arg = buf; 131 } 132 else { 133 arg = str; 134 } 135 } 136 else { 137 if (len > IOCTL_BUFSZ) { 138 PyErr_SetString(PyExc_ValueError, 139 "ioctl string arg too long"); 140 return NULL; 141 } 142 else { 143 memcpy(buf, str, len); 144 buf[len] = '\0'; 145 arg = buf; 146 } 147 } 148 if (buf == arg) { 149 Py_BEGIN_ALLOW_THREADS /* think array.resize() */ 150 ret = ioctl(fd, code, arg); 151 Py_END_ALLOW_THREADS 152 } 153 else { 154 ret = ioctl(fd, code, arg); 155 } 156 if (mutate_arg && (len <= IOCTL_BUFSZ)) { 157 memcpy(str, buf, len); 158 } 159 if (ret < 0) { 160 PyErr_SetFromErrno(PyExc_IOError); 161 return NULL; 162 } 163 if (mutate_arg) { 164 return PyInt_FromLong(ret); 165 } 166 else { 167 return PyString_FromStringAndSize(buf, len); 168 } 169 } 170 171 PyErr_Clear(); 172 if (PyArg_ParseTuple(args, "O&Is#:ioctl", 173 conv_descriptor, &fd, &code, &str, &len)) { 174 if (len > IOCTL_BUFSZ) { 175 PyErr_SetString(PyExc_ValueError, 176 "ioctl string arg too long"); 177 return NULL; 178 } 179 memcpy(buf, str, len); 180 buf[len] = '\0'; 181 Py_BEGIN_ALLOW_THREADS 182 ret = ioctl(fd, code, buf); 183 Py_END_ALLOW_THREADS 184 if (ret < 0) { 185 PyErr_SetFromErrno(PyExc_IOError); 186 return NULL; 187 } 188 return PyString_FromStringAndSize(buf, len); 189 } 190 191 PyErr_Clear(); 192 arg = 0; 193 if (!PyArg_ParseTuple(args, 194 "O&I|i;ioctl requires a file or file descriptor," 195 " an integer and optionally an integer or buffer argument", 196 conv_descriptor, &fd, &code, &arg)) { 197 return NULL; 198 } 199 Py_BEGIN_ALLOW_THREADS 200 200 #ifdef __VMS 201 201 ret = ioctl(fd, code, (void *)arg); 202 202 #else 203 204 #endif 205 206 207 208 209 210 203 ret = ioctl(fd, code, arg); 204 #endif 205 Py_END_ALLOW_THREADS 206 if (ret < 0) { 207 PyErr_SetFromErrno(PyExc_IOError); 208 return NULL; 209 } 210 return PyInt_FromLong((long)ret); 211 211 #undef IOCTL_BUFSZ 212 212 } … … 249 249 fcntl_flock(PyObject *self, PyObject *args) 250 250 { 251 252 253 254 255 256 257 251 int fd; 252 int code; 253 int ret; 254 255 if (!PyArg_ParseTuple(args, "O&i:flock", 256 conv_descriptor, &fd, &code)) 257 return NULL; 258 258 259 259 #ifdef HAVE_FLOCK 260 261 262 260 Py_BEGIN_ALLOW_THREADS 261 ret = flock(fd, code); 262 Py_END_ALLOW_THREADS 263 263 #else 264 264 265 265 #ifndef LOCK_SH 266 #define LOCK_SH 1/* shared lock */267 #define LOCK_EX 2/* exclusive lock */268 #define LOCK_NB 4/* don't block when locking */269 #define LOCK_UN 8/* unlock */270 #endif 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 266 #define LOCK_SH 1 /* shared lock */ 267 #define LOCK_EX 2 /* exclusive lock */ 268 #define LOCK_NB 4 /* don't block when locking */ 269 #define LOCK_UN 8 /* unlock */ 270 #endif 271 { 272 struct flock l; 273 if (code == LOCK_UN) 274 l.l_type = F_UNLCK; 275 else if (code & LOCK_SH) 276 l.l_type = F_RDLCK; 277 else if (code & LOCK_EX) 278 l.l_type = F_WRLCK; 279 else { 280 PyErr_SetString(PyExc_ValueError, 281 "unrecognized flock argument"); 282 return NULL; 283 } 284 l.l_whence = l.l_start = l.l_len = 0; 285 Py_BEGIN_ALLOW_THREADS 286 ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l); 287 Py_END_ALLOW_THREADS 288 } 289 289 #endif /* HAVE_FLOCK */ 290 291 292 293 294 295 290 if (ret < 0) { 291 PyErr_SetFromErrno(PyExc_IOError); 292 return NULL; 293 } 294 Py_INCREF(Py_None); 295 return Py_None; 296 296 } 297 297 … … 300 300 \n\ 301 301 Perform the lock operation op on file descriptor fd. See the Unix \n\ 302 manual page for flock( 3) for details. (On some systems, this function is\n\302 manual page for flock(2) for details. (On some systems, this function is\n\ 303 303 emulated using fcntl().)"); 304 304 … … 308 308 fcntl_lockf(PyObject *self, PyObject *args) 309 309 { 310 311 312 313 314 315 316 310 int fd, code, ret, whence = 0; 311 PyObject *lenobj = NULL, *startobj = NULL; 312 313 if (!PyArg_ParseTuple(args, "O&i|OOi:lockf", 314 conv_descriptor, &fd, &code, 315 &lenobj, &startobj, &whence)) 316 return NULL; 317 317 318 318 #if defined(PYOS_OS2) && defined(PYCC_GCC) 319 320 321 319 PyErr_SetString(PyExc_NotImplementedError, 320 "lockf not supported on OS/2 (EMX)"); 321 return NULL; 322 322 #else 323 323 #ifndef LOCK_SH 324 #define LOCK_SH 1/* shared lock */325 #define LOCK_EX 2/* exclusive lock */326 #define LOCK_NB 4/* don't block when locking */327 #define LOCK_UN 8/* unlock */324 #define LOCK_SH 1 /* shared lock */ 325 #define LOCK_EX 2 /* exclusive lock */ 326 #define LOCK_NB 4 /* don't block when locking */ 327 #define LOCK_UN 8 /* unlock */ 328 328 #endif /* LOCK_SH */ 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 329 { 330 struct flock l; 331 if (code == LOCK_UN) 332 l.l_type = F_UNLCK; 333 else if (code & LOCK_SH) 334 l.l_type = F_RDLCK; 335 else if (code & LOCK_EX) 336 l.l_type = F_WRLCK; 337 else { 338 PyErr_SetString(PyExc_ValueError, 339 "unrecognized lockf argument"); 340 return NULL; 341 } 342 l.l_start = l.l_len = 0; 343 if (startobj != NULL) { 344 344 #if !defined(HAVE_LARGEFILE_SUPPORT) 345 345 l.l_start = PyInt_AsLong(startobj); 346 346 #else 347 348 349 350 #endif 351 352 353 354 347 l.l_start = PyLong_Check(startobj) ? 348 PyLong_AsLongLong(startobj) : 349 PyInt_AsLong(startobj); 350 #endif 351 if (PyErr_Occurred()) 352 return NULL; 353 } 354 if (lenobj != NULL) { 355 355 #if !defined(HAVE_LARGEFILE_SUPPORT) 356 356 l.l_len = PyInt_AsLong(lenobj); 357 357 #else 358 359 360 361 #endif 362 363 364 365 366 367 368 369 370 371 372 373 374 375 358 l.l_len = PyLong_Check(lenobj) ? 359 PyLong_AsLongLong(lenobj) : 360 PyInt_AsLong(lenobj); 361 #endif 362 if (PyErr_Occurred()) 363 return NULL; 364 } 365 l.l_whence = whence; 366 Py_BEGIN_ALLOW_THREADS 367 ret = fcntl(fd, (code & LOCK_NB) ? F_SETLK : F_SETLKW, &l); 368 Py_END_ALLOW_THREADS 369 } 370 if (ret < 0) { 371 PyErr_SetFromErrno(PyExc_IOError); 372 return NULL; 373 } 374 Py_INCREF(Py_None); 375 return Py_None; 376 376 #endif /* defined(PYOS_OS2) && defined(PYCC_GCC) */ 377 377 } … … 405 405 406 406 static PyMethodDef fcntl_methods[] = { 407 {"fcntl",fcntl_fcntl, METH_VARARGS, fcntl_doc},408 {"ioctl",fcntl_ioctl, METH_VARARGS, ioctl_doc},409 {"flock",fcntl_flock, METH_VARARGS, flock_doc},410 411 {NULL, NULL}/* sentinel */407 {"fcntl", fcntl_fcntl, METH_VARARGS, fcntl_doc}, 408 {"ioctl", fcntl_ioctl, METH_VARARGS, ioctl_doc}, 409 {"flock", fcntl_flock, METH_VARARGS, flock_doc}, 410 {"lockf", fcntl_lockf, METH_VARARGS, lockf_doc}, 411 {NULL, NULL} /* sentinel */ 412 412 }; 413 413 … … 424 424 ins(PyObject* d, char* symbol, long value) 425 425 { 426 427 428 429 430 431 426 PyObject* v = PyInt_FromLong(value); 427 if (!v || PyDict_SetItemString(d, symbol, v) < 0) 428 return -1; 429 430 Py_DECREF(v); 431 return 0; 432 432 } 433 433 … … 437 437 all_ins(PyObject* d) 438 438 { 439 440 441 442 439 if (ins(d, "LOCK_SH", (long)LOCK_SH)) return -1; 440 if (ins(d, "LOCK_EX", (long)LOCK_EX)) return -1; 441 if (ins(d, "LOCK_NB", (long)LOCK_NB)) return -1; 442 if (ins(d, "LOCK_UN", (long)LOCK_UN)) return -1; 443 443 /* GNU extensions, as of glibc 2.2.4 */ 444 444 #ifdef LOCK_MAND 445 445 if (ins(d, "LOCK_MAND", (long)LOCK_MAND)) return -1; 446 446 #endif 447 447 #ifdef LOCK_READ 448 448 if (ins(d, "LOCK_READ", (long)LOCK_READ)) return -1; 449 449 #endif 450 450 #ifdef LOCK_WRITE 451 451 if (ins(d, "LOCK_WRITE", (long)LOCK_WRITE)) return -1; 452 452 #endif 453 453 #ifdef LOCK_RW 454 454 if (ins(d, "LOCK_RW", (long)LOCK_RW)) return -1; 455 455 #endif 456 456 457 457 #ifdef F_DUPFD 458 458 if (ins(d, "F_DUPFD", (long)F_DUPFD)) return -1; 459 459 #endif 460 460 #ifdef F_GETFD 461 461 if (ins(d, "F_GETFD", (long)F_GETFD)) return -1; 462 462 #endif 463 463 #ifdef F_SETFD 464 464 if (ins(d, "F_SETFD", (long)F_SETFD)) return -1; 465 465 #endif 466 466 #ifdef F_GETFL 467 467 if (ins(d, "F_GETFL", (long)F_GETFL)) return -1; 468 468 #endif 469 469 #ifdef F_SETFL 470 470 if (ins(d, "F_SETFL", (long)F_SETFL)) return -1; 471 471 #endif 472 472 #ifdef F_GETLK 473 473 if (ins(d, "F_GETLK", (long)F_GETLK)) return -1; 474 474 #endif 475 475 #ifdef F_SETLK 476 476 if (ins(d, "F_SETLK", (long)F_SETLK)) return -1; 477 477 #endif 478 478 #ifdef F_SETLKW 479 479 if (ins(d, "F_SETLKW", (long)F_SETLKW)) return -1; 480 480 #endif 481 481 #ifdef F_GETOWN 482 482 if (ins(d, "F_GETOWN", (long)F_GETOWN)) return -1; 483 483 #endif 484 484 #ifdef F_SETOWN 485 485 if (ins(d, "F_SETOWN", (long)F_SETOWN)) return -1; 486 486 #endif 487 487 #ifdef F_GETSIG 488 488 if (ins(d, "F_GETSIG", (long)F_GETSIG)) return -1; 489 489 #endif 490 490 #ifdef F_SETSIG 491 491 if (ins(d, "F_SETSIG", (long)F_SETSIG)) return -1; 492 492 #endif 493 493 #ifdef F_RDLCK 494 494 if (ins(d, "F_RDLCK", (long)F_RDLCK)) return -1; 495 495 #endif 496 496 #ifdef F_WRLCK 497 497 if (ins(d, "F_WRLCK", (long)F_WRLCK)) return -1; 498 498 #endif 499 499 #ifdef F_UNLCK 500 500 if (ins(d, "F_UNLCK", (long)F_UNLCK)) return -1; 501 501 #endif 502 502 /* LFS constants */ 503 503 #ifdef F_GETLK64 504 504 if (ins(d, "F_GETLK64", (long)F_GETLK64)) return -1; 505 505 #endif 506 506 #ifdef F_SETLK64 507 507 if (ins(d, "F_SETLK64", (long)F_SETLK64)) return -1; 508 508 #endif 509 509 #ifdef F_SETLKW64 510 510 if (ins(d, "F_SETLKW64", (long)F_SETLKW64)) return -1; 511 511 #endif 512 512 /* GNU extensions, as of glibc 2.2.4. */ 513 513 #ifdef FASYNC 514 514 if (ins(d, "FASYNC", (long)FASYNC)) return -1; 515 515 #endif 516 516 #ifdef F_SETLEASE 517 517 if (ins(d, "F_SETLEASE", (long)F_SETLEASE)) return -1; 518 518 #endif 519 519 #ifdef F_GETLEASE 520 520 if (ins(d, "F_GETLEASE", (long)F_GETLEASE)) return -1; 521 521 #endif 522 522 #ifdef F_NOTIFY 523 523 if (ins(d, "F_NOTIFY", (long)F_NOTIFY)) return -1; 524 524 #endif 525 525 /* Old BSD flock(). */ 526 526 #ifdef F_EXLCK 527 527 if (ins(d, "F_EXLCK", (long)F_EXLCK)) return -1; 528 528 #endif 529 529 #ifdef F_SHLCK 530 530 if (ins(d, "F_SHLCK", (long)F_SHLCK)) return -1; 531 531 #endif 532 532 533 533 /* OS X (and maybe others) let you tell the storage device to flush to physical media */ 534 534 #ifdef F_FULLFSYNC 535 535 if (ins(d, "F_FULLFSYNC", (long)F_FULLFSYNC)) return -1; 536 536 #endif 537 537 538 538 /* For F_{GET|SET}FL */ 539 539 #ifdef FD_CLOEXEC 540 540 if (ins(d, "FD_CLOEXEC", (long)FD_CLOEXEC)) return -1; 541 541 #endif 542 542 543 543 /* For F_NOTIFY */ 544 544 #ifdef DN_ACCESS 545 545 if (ins(d, "DN_ACCESS", (long)DN_ACCESS)) return -1; 546 546 #endif 547 547 #ifdef DN_MODIFY 548 548 if (ins(d, "DN_MODIFY", (long)DN_MODIFY)) return -1; 549 549 #endif 550 550 #ifdef DN_CREATE 551 551 if (ins(d, "DN_CREATE", (long)DN_CREATE)) return -1; 552 552 #endif 553 553 #ifdef DN_DELETE 554 554 if (ins(d, "DN_DELETE", (long)DN_DELETE)) return -1; 555 555 #endif 556 556 #ifdef DN_RENAME 557 557 if (ins(d, "DN_RENAME", (long)DN_RENAME)) return -1; 558 558 #endif 559 559 #ifdef DN_ATTRIB 560 560 if (ins(d, "DN_ATTRIB", (long)DN_ATTRIB)) return -1; 561 561 #endif 562 562 #ifdef DN_MULTISHOT 563 563 if (ins(d, "DN_MULTISHOT", (long)DN_MULTISHOT)) return -1; 564 564 #endif 565 565 566 566 #ifdef HAVE_STROPTS_H 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 567 /* Unix 98 guarantees that these are in stropts.h. */ 568 INS(I_PUSH); 569 INS(I_POP); 570 INS(I_LOOK); 571 INS(I_FLUSH); 572 INS(I_FLUSHBAND); 573 INS(I_SETSIG); 574 INS(I_GETSIG); 575 INS(I_FIND); 576 INS(I_PEEK); 577 INS(I_SRDOPT); 578 INS(I_GRDOPT); 579 INS(I_NREAD); 580 INS(I_FDINSERT); 581 INS(I_STR); 582 INS(I_SWROPT); 583 583 #ifdef I_GWROPT 584 585 586 #endif 587 588 589 590 591 592 593 594 584 /* despite the comment above, old-ish glibcs miss a couple... */ 585 INS(I_GWROPT); 586 #endif 587 INS(I_SENDFD); 588 INS(I_RECVFD); 589 INS(I_LIST); 590 INS(I_ATMARK); 591 INS(I_CKBAND); 592 INS(I_GETBAND); 593 INS(I_CANPUT); 594 INS(I_SETCLTIME); 595 595 #ifdef I_GETCLTIME 596 597 #endif 598 599 600 601 602 #endif 603 604 596 INS(I_GETCLTIME); 597 #endif 598 INS(I_LINK); 599 INS(I_UNLINK); 600 INS(I_PLINK); 601 INS(I_PUNLINK); 602 #endif 603 604 return 0; 605 605 } 606 606 … … 608 608 initfcntl(void) 609 609 { 610 611 612 613 614 615 616 617 618 619 620 } 610 PyObject *m, *d; 611 612 /* Create the module and add the functions and documentation */ 613 m = Py_InitModule3("fcntl", fcntl_methods, module_doc); 614 if (m == NULL) 615 return; 616 617 /* Add some symbolic constants to the module */ 618 d = PyModule_GetDict(m); 619 all_ins(d); 620 }
Note:
See TracChangeset
for help on using the changeset viewer.