posixmodule.c revision bf19d169504823c258a9aae4bf61c8df9ff5987f
1 2/* POSIX module implementation */ 3 4/* This file is also used for Windows NT/MS-Win. In that case the 5 module actually calls itself 'nt', not 'posix', and a few 6 functions are either unimplemented or implemented differently. The source 7 assumes that for Windows NT, the macro 'MS_WINDOWS' is defined independent 8 of the compiler used. Different compilers define their own feature 9 test macro, e.g. '__BORLANDC__' or '_MSC_VER'. */ 10 11 12 13#ifdef __APPLE__ 14 /* 15 * Step 1 of support for weak-linking a number of symbols existing on 16 * OSX 10.4 and later, see the comment in the #ifdef __APPLE__ block 17 * at the end of this file for more information. 18 */ 19# pragma weak lchown 20# pragma weak statvfs 21# pragma weak fstatvfs 22 23#endif /* __APPLE__ */ 24 25#define PY_SSIZE_T_CLEAN 26 27#include "Python.h" 28#ifndef MS_WINDOWS 29#include "posixmodule.h" 30#endif 31 32#ifdef __cplusplus 33extern "C" { 34#endif 35 36PyDoc_STRVAR(posix__doc__, 37"This module provides access to operating system functionality that is\n\ 38standardized by the C Standard and the POSIX standard (a thinly\n\ 39disguised Unix interface). Refer to the library manual and\n\ 40corresponding Unix manual entries for more information on calls."); 41 42 43#ifdef HAVE_SYS_UIO_H 44#include <sys/uio.h> 45#endif 46 47#ifdef HAVE_SYS_TYPES_H 48#include <sys/types.h> 49#endif /* HAVE_SYS_TYPES_H */ 50 51#ifdef HAVE_SYS_STAT_H 52#include <sys/stat.h> 53#endif /* HAVE_SYS_STAT_H */ 54 55#ifdef HAVE_SYS_WAIT_H 56#include <sys/wait.h> /* For WNOHANG */ 57#endif 58 59#ifdef HAVE_SIGNAL_H 60#include <signal.h> 61#endif 62 63#ifdef HAVE_FCNTL_H 64#include <fcntl.h> 65#endif /* HAVE_FCNTL_H */ 66 67#ifdef HAVE_GRP_H 68#include <grp.h> 69#endif 70 71#ifdef HAVE_SYSEXITS_H 72#include <sysexits.h> 73#endif /* HAVE_SYSEXITS_H */ 74 75#ifdef HAVE_SYS_LOADAVG_H 76#include <sys/loadavg.h> 77#endif 78 79#ifdef HAVE_LANGINFO_H 80#include <langinfo.h> 81#endif 82 83#ifdef HAVE_SYS_SENDFILE_H 84#include <sys/sendfile.h> 85#endif 86 87#ifdef HAVE_SCHED_H 88#include <sched.h> 89#endif 90 91#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY) 92#undef HAVE_SCHED_SETAFFINITY 93#endif 94 95#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__) && !defined(__FreeBSD_kernel__) && !defined(__GNU__) 96#define USE_XATTRS 97#endif 98 99#ifdef USE_XATTRS 100#include <sys/xattr.h> 101#endif 102 103#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__) 104#ifdef HAVE_SYS_SOCKET_H 105#include <sys/socket.h> 106#endif 107#endif 108 109#ifdef HAVE_DLFCN_H 110#include <dlfcn.h> 111#endif 112 113#ifdef __hpux 114#include <sys/mpctl.h> 115#endif 116 117#if defined(__DragonFly__) || \ 118 defined(__OpenBSD__) || \ 119 defined(__FreeBSD__) || \ 120 defined(__NetBSD__) || \ 121 defined(__APPLE__) 122#include <sys/sysctl.h> 123#endif 124 125#if defined(MS_WINDOWS) 126# define TERMSIZE_USE_CONIO 127#elif defined(HAVE_SYS_IOCTL_H) 128# include <sys/ioctl.h> 129# if defined(HAVE_TERMIOS_H) 130# include <termios.h> 131# endif 132# if defined(TIOCGWINSZ) 133# define TERMSIZE_USE_IOCTL 134# endif 135#endif /* MS_WINDOWS */ 136 137/* Various compilers have only certain posix functions */ 138/* XXX Gosh I wish these were all moved into pyconfig.h */ 139#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */ 140#define HAVE_OPENDIR 1 141#define HAVE_SYSTEM 1 142#include <process.h> 143#else 144#ifdef __BORLANDC__ /* Borland compiler */ 145#define HAVE_EXECV 1 146#define HAVE_OPENDIR 1 147#define HAVE_PIPE 1 148#define HAVE_SYSTEM 1 149#define HAVE_WAIT 1 150#else 151#ifdef _MSC_VER /* Microsoft compiler */ 152#define HAVE_GETPPID 1 153#define HAVE_GETLOGIN 1 154#define HAVE_SPAWNV 1 155#define HAVE_EXECV 1 156#define HAVE_PIPE 1 157#define HAVE_SYSTEM 1 158#define HAVE_CWAIT 1 159#define HAVE_FSYNC 1 160#define fsync _commit 161#else 162/* Unix functions that the configure script doesn't check for */ 163#define HAVE_EXECV 1 164#define HAVE_FORK 1 165#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */ 166#define HAVE_FORK1 1 167#endif 168#define HAVE_GETEGID 1 169#define HAVE_GETEUID 1 170#define HAVE_GETGID 1 171#define HAVE_GETPPID 1 172#define HAVE_GETUID 1 173#define HAVE_KILL 1 174#define HAVE_OPENDIR 1 175#define HAVE_PIPE 1 176#define HAVE_SYSTEM 1 177#define HAVE_WAIT 1 178#define HAVE_TTYNAME 1 179#endif /* _MSC_VER */ 180#endif /* __BORLANDC__ */ 181#endif /* ! __WATCOMC__ || __QNX__ */ 182 183 184/*[clinic input] 185module os 186[clinic start generated code]*/ 187/*[clinic end generated code: output=da39a3ee5e6b4b0d input=8cff096d1133288f]*/ 188 189#ifndef _MSC_VER 190 191#if defined(__sgi)&&_COMPILER_VERSION>=700 192/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode 193 (default) */ 194extern char *ctermid_r(char *); 195#endif 196 197#ifndef HAVE_UNISTD_H 198#if defined(PYCC_VACPP) 199extern int mkdir(char *); 200#else 201#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__) 202extern int mkdir(const char *); 203#else 204extern int mkdir(const char *, mode_t); 205#endif 206#endif 207#if defined(__IBMC__) || defined(__IBMCPP__) 208extern int chdir(char *); 209extern int rmdir(char *); 210#else 211extern int chdir(const char *); 212extern int rmdir(const char *); 213#endif 214#ifdef __BORLANDC__ 215extern int chmod(const char *, int); 216#else 217extern int chmod(const char *, mode_t); 218#endif 219/*#ifdef HAVE_FCHMOD 220extern int fchmod(int, mode_t); 221#endif*/ 222/*#ifdef HAVE_LCHMOD 223extern int lchmod(const char *, mode_t); 224#endif*/ 225extern int chown(const char *, uid_t, gid_t); 226extern char *getcwd(char *, int); 227extern char *strerror(int); 228extern int link(const char *, const char *); 229extern int rename(const char *, const char *); 230extern int stat(const char *, struct stat *); 231extern int unlink(const char *); 232#ifdef HAVE_SYMLINK 233extern int symlink(const char *, const char *); 234#endif /* HAVE_SYMLINK */ 235#ifdef HAVE_LSTAT 236extern int lstat(const char *, struct stat *); 237#endif /* HAVE_LSTAT */ 238#endif /* !HAVE_UNISTD_H */ 239 240#endif /* !_MSC_VER */ 241 242#ifdef HAVE_UTIME_H 243#include <utime.h> 244#endif /* HAVE_UTIME_H */ 245 246#ifdef HAVE_SYS_UTIME_H 247#include <sys/utime.h> 248#define HAVE_UTIME_H /* pretend we do for the rest of this file */ 249#endif /* HAVE_SYS_UTIME_H */ 250 251#ifdef HAVE_SYS_TIMES_H 252#include <sys/times.h> 253#endif /* HAVE_SYS_TIMES_H */ 254 255#ifdef HAVE_SYS_PARAM_H 256#include <sys/param.h> 257#endif /* HAVE_SYS_PARAM_H */ 258 259#ifdef HAVE_SYS_UTSNAME_H 260#include <sys/utsname.h> 261#endif /* HAVE_SYS_UTSNAME_H */ 262 263#ifdef HAVE_DIRENT_H 264#include <dirent.h> 265#define NAMLEN(dirent) strlen((dirent)->d_name) 266#else 267#if defined(__WATCOMC__) && !defined(__QNX__) 268#include <direct.h> 269#define NAMLEN(dirent) strlen((dirent)->d_name) 270#else 271#define dirent direct 272#define NAMLEN(dirent) (dirent)->d_namlen 273#endif 274#ifdef HAVE_SYS_NDIR_H 275#include <sys/ndir.h> 276#endif 277#ifdef HAVE_SYS_DIR_H 278#include <sys/dir.h> 279#endif 280#ifdef HAVE_NDIR_H 281#include <ndir.h> 282#endif 283#endif 284 285#ifdef _MSC_VER 286#ifdef HAVE_DIRECT_H 287#include <direct.h> 288#endif 289#ifdef HAVE_IO_H 290#include <io.h> 291#endif 292#ifdef HAVE_PROCESS_H 293#include <process.h> 294#endif 295#ifndef VOLUME_NAME_DOS 296#define VOLUME_NAME_DOS 0x0 297#endif 298#ifndef VOLUME_NAME_NT 299#define VOLUME_NAME_NT 0x2 300#endif 301#ifndef IO_REPARSE_TAG_SYMLINK 302#define IO_REPARSE_TAG_SYMLINK (0xA000000CL) 303#endif 304#include "osdefs.h" 305#include <malloc.h> 306#include <windows.h> 307#include <shellapi.h> /* for ShellExecute() */ 308#include <lmcons.h> /* for UNLEN */ 309#ifdef SE_CREATE_SYMBOLIC_LINK_NAME /* Available starting with Vista */ 310#define HAVE_SYMLINK 311static int win32_can_symlink = 0; 312#endif 313#endif /* _MSC_VER */ 314 315#ifndef MAXPATHLEN 316#if defined(PATH_MAX) && PATH_MAX > 1024 317#define MAXPATHLEN PATH_MAX 318#else 319#define MAXPATHLEN 1024 320#endif 321#endif /* MAXPATHLEN */ 322 323#ifdef UNION_WAIT 324/* Emulate some macros on systems that have a union instead of macros */ 325 326#ifndef WIFEXITED 327#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump) 328#endif 329 330#ifndef WEXITSTATUS 331#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1) 332#endif 333 334#ifndef WTERMSIG 335#define WTERMSIG(u_wait) ((u_wait).w_termsig) 336#endif 337 338#define WAIT_TYPE union wait 339#define WAIT_STATUS_INT(s) (s.w_status) 340 341#else /* !UNION_WAIT */ 342#define WAIT_TYPE int 343#define WAIT_STATUS_INT(s) (s) 344#endif /* UNION_WAIT */ 345 346/* Don't use the "_r" form if we don't need it (also, won't have a 347 prototype for it, at least on Solaris -- maybe others as well?). */ 348#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD) 349#define USE_CTERMID_R 350#endif 351 352/* choose the appropriate stat and fstat functions and return structs */ 353#undef STAT 354#undef FSTAT 355#undef STRUCT_STAT 356#ifdef MS_WINDOWS 357# define STAT win32_stat 358# define LSTAT win32_lstat 359# define FSTAT win32_fstat 360# define STRUCT_STAT struct win32_stat 361#else 362# define STAT stat 363# define LSTAT lstat 364# define FSTAT fstat 365# define STRUCT_STAT struct stat 366#endif 367 368#if defined(MAJOR_IN_MKDEV) 369#include <sys/mkdev.h> 370#else 371#if defined(MAJOR_IN_SYSMACROS) 372#include <sys/sysmacros.h> 373#endif 374#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H) 375#include <sys/mkdev.h> 376#endif 377#endif 378 379#define DWORD_MAX 4294967295U 380 381 382#ifdef MS_WINDOWS 383static int 384win32_warn_bytes_api() 385{ 386 return PyErr_WarnEx(PyExc_DeprecationWarning, 387 "The Windows bytes API has been deprecated, " 388 "use Unicode filenames instead", 389 1); 390} 391#endif 392 393 394#ifndef MS_WINDOWS 395PyObject * 396_PyLong_FromUid(uid_t uid) 397{ 398 if (uid == (uid_t)-1) 399 return PyLong_FromLong(-1); 400 return PyLong_FromUnsignedLong(uid); 401} 402 403PyObject * 404_PyLong_FromGid(gid_t gid) 405{ 406 if (gid == (gid_t)-1) 407 return PyLong_FromLong(-1); 408 return PyLong_FromUnsignedLong(gid); 409} 410 411int 412_Py_Uid_Converter(PyObject *obj, void *p) 413{ 414 uid_t uid; 415 PyObject *index; 416 int overflow; 417 long result; 418 unsigned long uresult; 419 420 index = PyNumber_Index(obj); 421 if (index == NULL) { 422 PyErr_Format(PyExc_TypeError, 423 "uid should be integer, not %.200s", 424 Py_TYPE(obj)->tp_name); 425 return 0; 426 } 427 428 /* 429 * Handling uid_t is complicated for two reasons: 430 * * Although uid_t is (always?) unsigned, it still 431 * accepts -1. 432 * * We don't know its size in advance--it may be 433 * bigger than an int, or it may be smaller than 434 * a long. 435 * 436 * So a bit of defensive programming is in order. 437 * Start with interpreting the value passed 438 * in as a signed long and see if it works. 439 */ 440 441 result = PyLong_AsLongAndOverflow(index, &overflow); 442 443 if (!overflow) { 444 uid = (uid_t)result; 445 446 if (result == -1) { 447 if (PyErr_Occurred()) 448 goto fail; 449 /* It's a legitimate -1, we're done. */ 450 goto success; 451 } 452 453 /* Any other negative number is disallowed. */ 454 if (result < 0) 455 goto underflow; 456 457 /* Ensure the value wasn't truncated. */ 458 if (sizeof(uid_t) < sizeof(long) && 459 (long)uid != result) 460 goto underflow; 461 goto success; 462 } 463 464 if (overflow < 0) 465 goto underflow; 466 467 /* 468 * Okay, the value overflowed a signed long. If it 469 * fits in an *unsigned* long, it may still be okay, 470 * as uid_t may be unsigned long on this platform. 471 */ 472 uresult = PyLong_AsUnsignedLong(index); 473 if (PyErr_Occurred()) { 474 if (PyErr_ExceptionMatches(PyExc_OverflowError)) 475 goto overflow; 476 goto fail; 477 } 478 479 uid = (uid_t)uresult; 480 481 /* 482 * If uid == (uid_t)-1, the user actually passed in ULONG_MAX, 483 * but this value would get interpreted as (uid_t)-1 by chown 484 * and its siblings. That's not what the user meant! So we 485 * throw an overflow exception instead. (We already 486 * handled a real -1 with PyLong_AsLongAndOverflow() above.) 487 */ 488 if (uid == (uid_t)-1) 489 goto overflow; 490 491 /* Ensure the value wasn't truncated. */ 492 if (sizeof(uid_t) < sizeof(long) && 493 (unsigned long)uid != uresult) 494 goto overflow; 495 /* fallthrough */ 496 497success: 498 Py_DECREF(index); 499 *(uid_t *)p = uid; 500 return 1; 501 502underflow: 503 PyErr_SetString(PyExc_OverflowError, 504 "uid is less than minimum"); 505 goto fail; 506 507overflow: 508 PyErr_SetString(PyExc_OverflowError, 509 "uid is greater than maximum"); 510 /* fallthrough */ 511 512fail: 513 Py_DECREF(index); 514 return 0; 515} 516 517int 518_Py_Gid_Converter(PyObject *obj, void *p) 519{ 520 gid_t gid; 521 PyObject *index; 522 int overflow; 523 long result; 524 unsigned long uresult; 525 526 index = PyNumber_Index(obj); 527 if (index == NULL) { 528 PyErr_Format(PyExc_TypeError, 529 "gid should be integer, not %.200s", 530 Py_TYPE(obj)->tp_name); 531 return 0; 532 } 533 534 /* 535 * Handling gid_t is complicated for two reasons: 536 * * Although gid_t is (always?) unsigned, it still 537 * accepts -1. 538 * * We don't know its size in advance--it may be 539 * bigger than an int, or it may be smaller than 540 * a long. 541 * 542 * So a bit of defensive programming is in order. 543 * Start with interpreting the value passed 544 * in as a signed long and see if it works. 545 */ 546 547 result = PyLong_AsLongAndOverflow(index, &overflow); 548 549 if (!overflow) { 550 gid = (gid_t)result; 551 552 if (result == -1) { 553 if (PyErr_Occurred()) 554 goto fail; 555 /* It's a legitimate -1, we're done. */ 556 goto success; 557 } 558 559 /* Any other negative number is disallowed. */ 560 if (result < 0) { 561 goto underflow; 562 } 563 564 /* Ensure the value wasn't truncated. */ 565 if (sizeof(gid_t) < sizeof(long) && 566 (long)gid != result) 567 goto underflow; 568 goto success; 569 } 570 571 if (overflow < 0) 572 goto underflow; 573 574 /* 575 * Okay, the value overflowed a signed long. If it 576 * fits in an *unsigned* long, it may still be okay, 577 * as gid_t may be unsigned long on this platform. 578 */ 579 uresult = PyLong_AsUnsignedLong(index); 580 if (PyErr_Occurred()) { 581 if (PyErr_ExceptionMatches(PyExc_OverflowError)) 582 goto overflow; 583 goto fail; 584 } 585 586 gid = (gid_t)uresult; 587 588 /* 589 * If gid == (gid_t)-1, the user actually passed in ULONG_MAX, 590 * but this value would get interpreted as (gid_t)-1 by chown 591 * and its siblings. That's not what the user meant! So we 592 * throw an overflow exception instead. (We already 593 * handled a real -1 with PyLong_AsLongAndOverflow() above.) 594 */ 595 if (gid == (gid_t)-1) 596 goto overflow; 597 598 /* Ensure the value wasn't truncated. */ 599 if (sizeof(gid_t) < sizeof(long) && 600 (unsigned long)gid != uresult) 601 goto overflow; 602 /* fallthrough */ 603 604success: 605 Py_DECREF(index); 606 *(gid_t *)p = gid; 607 return 1; 608 609underflow: 610 PyErr_SetString(PyExc_OverflowError, 611 "gid is less than minimum"); 612 goto fail; 613 614overflow: 615 PyErr_SetString(PyExc_OverflowError, 616 "gid is greater than maximum"); 617 /* fallthrough */ 618 619fail: 620 Py_DECREF(index); 621 return 0; 622} 623#endif /* MS_WINDOWS */ 624 625 626#ifdef HAVE_LONG_LONG 627# define _PyLong_FromDev PyLong_FromLongLong 628#else 629# define _PyLong_FromDev PyLong_FromLong 630#endif 631 632 633#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) 634static int 635_Py_Dev_Converter(PyObject *obj, void *p) 636{ 637#ifdef HAVE_LONG_LONG 638 *((dev_t *)p) = PyLong_AsUnsignedLongLong(obj); 639#else 640 *((dev_t *)p) = PyLong_AsUnsignedLong(obj); 641#endif 642 if (PyErr_Occurred()) 643 return 0; 644 return 1; 645} 646#endif /* HAVE_MKNOD && HAVE_MAKEDEV */ 647 648 649#ifdef AT_FDCWD 650/* 651 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965); 652 * without the int cast, the value gets interpreted as uint (4291925331), 653 * which doesn't play nicely with all the initializer lines in this file that 654 * look like this: 655 * int dir_fd = DEFAULT_DIR_FD; 656 */ 657#define DEFAULT_DIR_FD (int)AT_FDCWD 658#else 659#define DEFAULT_DIR_FD (-100) 660#endif 661 662static int 663_fd_converter(PyObject *o, int *p, const char *allowed) 664{ 665 int overflow; 666 long long_value; 667 668 PyObject *index = PyNumber_Index(o); 669 if (index == NULL) { 670 PyErr_Format(PyExc_TypeError, 671 "argument should be %s, not %.200s", 672 allowed, Py_TYPE(o)->tp_name); 673 return 0; 674 } 675 676 long_value = PyLong_AsLongAndOverflow(index, &overflow); 677 Py_DECREF(index); 678 if (overflow > 0 || long_value > INT_MAX) { 679 PyErr_SetString(PyExc_OverflowError, 680 "fd is greater than maximum"); 681 return 0; 682 } 683 if (overflow < 0 || long_value < INT_MIN) { 684 PyErr_SetString(PyExc_OverflowError, 685 "fd is less than minimum"); 686 return 0; 687 } 688 689 *p = (int)long_value; 690 return 1; 691} 692 693static int 694dir_fd_converter(PyObject *o, void *p) 695{ 696 if (o == Py_None) { 697 *(int *)p = DEFAULT_DIR_FD; 698 return 1; 699 } 700 return _fd_converter(o, (int *)p, "integer"); 701} 702 703 704 705/* 706 * A PyArg_ParseTuple "converter" function 707 * that handles filesystem paths in the manner 708 * preferred by the os module. 709 * 710 * path_converter accepts (Unicode) strings and their 711 * subclasses, and bytes and their subclasses. What 712 * it does with the argument depends on the platform: 713 * 714 * * On Windows, if we get a (Unicode) string we 715 * extract the wchar_t * and return it; if we get 716 * bytes we extract the char * and return that. 717 * 718 * * On all other platforms, strings are encoded 719 * to bytes using PyUnicode_FSConverter, then we 720 * extract the char * from the bytes object and 721 * return that. 722 * 723 * path_converter also optionally accepts signed 724 * integers (representing open file descriptors) instead 725 * of path strings. 726 * 727 * Input fields: 728 * path.nullable 729 * If nonzero, the path is permitted to be None. 730 * path.allow_fd 731 * If nonzero, the path is permitted to be a file handle 732 * (a signed int) instead of a string. 733 * path.function_name 734 * If non-NULL, path_converter will use that as the name 735 * of the function in error messages. 736 * (If path.function_name is NULL it omits the function name.) 737 * path.argument_name 738 * If non-NULL, path_converter will use that as the name 739 * of the parameter in error messages. 740 * (If path.argument_name is NULL it uses "path".) 741 * 742 * Output fields: 743 * path.wide 744 * Points to the path if it was expressed as Unicode 745 * and was not encoded. (Only used on Windows.) 746 * path.narrow 747 * Points to the path if it was expressed as bytes, 748 * or it was Unicode and was encoded to bytes. 749 * path.fd 750 * Contains a file descriptor if path.accept_fd was true 751 * and the caller provided a signed integer instead of any 752 * sort of string. 753 * 754 * WARNING: if your "path" parameter is optional, and is 755 * unspecified, path_converter will never get called. 756 * So if you set allow_fd, you *MUST* initialize path.fd = -1 757 * yourself! 758 * path.length 759 * The length of the path in characters, if specified as 760 * a string. 761 * path.object 762 * The original object passed in. 763 * path.cleanup 764 * For internal use only. May point to a temporary object. 765 * (Pay no attention to the man behind the curtain.) 766 * 767 * At most one of path.wide or path.narrow will be non-NULL. 768 * If path was None and path.nullable was set, 769 * or if path was an integer and path.allow_fd was set, 770 * both path.wide and path.narrow will be NULL 771 * and path.length will be 0. 772 * 773 * path_converter takes care to not write to the path_t 774 * unless it's successful. However it must reset the 775 * "cleanup" field each time it's called. 776 * 777 * Use as follows: 778 * path_t path; 779 * memset(&path, 0, sizeof(path)); 780 * PyArg_ParseTuple(args, "O&", path_converter, &path); 781 * // ... use values from path ... 782 * path_cleanup(&path); 783 * 784 * (Note that if PyArg_Parse fails you don't need to call 785 * path_cleanup(). However it is safe to do so.) 786 */ 787typedef struct { 788 const char *function_name; 789 const char *argument_name; 790 int nullable; 791 int allow_fd; 792 wchar_t *wide; 793 char *narrow; 794 int fd; 795 Py_ssize_t length; 796 PyObject *object; 797 PyObject *cleanup; 798} path_t; 799 800#define PATH_T_INITIALIZE(function_name, nullable, allow_fd) \ 801 {function_name, NULL, nullable, allow_fd, NULL, NULL, 0, 0, NULL, NULL} 802 803static void 804path_cleanup(path_t *path) { 805 if (path->cleanup) { 806 Py_CLEAR(path->cleanup); 807 } 808} 809 810static int 811path_converter(PyObject *o, void *p) { 812 path_t *path = (path_t *)p; 813 PyObject *unicode, *bytes; 814 Py_ssize_t length; 815 char *narrow; 816 817#define FORMAT_EXCEPTION(exc, fmt) \ 818 PyErr_Format(exc, "%s%s" fmt, \ 819 path->function_name ? path->function_name : "", \ 820 path->function_name ? ": " : "", \ 821 path->argument_name ? path->argument_name : "path") 822 823 /* Py_CLEANUP_SUPPORTED support */ 824 if (o == NULL) { 825 path_cleanup(path); 826 return 1; 827 } 828 829 /* ensure it's always safe to call path_cleanup() */ 830 path->cleanup = NULL; 831 832 if (o == Py_None) { 833 if (!path->nullable) { 834 FORMAT_EXCEPTION(PyExc_TypeError, 835 "can't specify None for %s argument"); 836 return 0; 837 } 838 path->wide = NULL; 839 path->narrow = NULL; 840 path->length = 0; 841 path->object = o; 842 path->fd = -1; 843 return 1; 844 } 845 846 unicode = PyUnicode_FromObject(o); 847 if (unicode) { 848#ifdef MS_WINDOWS 849 wchar_t *wide; 850 851 wide = PyUnicode_AsUnicodeAndSize(unicode, &length); 852 if (!wide) { 853 Py_DECREF(unicode); 854 return 0; 855 } 856 if (length > 32767) { 857 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows"); 858 Py_DECREF(unicode); 859 return 0; 860 } 861 if (wcslen(wide) != length) { 862 FORMAT_EXCEPTION(PyExc_TypeError, "embedded null character"); 863 Py_DECREF(unicode); 864 return 0; 865 } 866 867 path->wide = wide; 868 path->narrow = NULL; 869 path->length = length; 870 path->object = o; 871 path->fd = -1; 872 path->cleanup = unicode; 873 return Py_CLEANUP_SUPPORTED; 874#else 875 int converted = PyUnicode_FSConverter(unicode, &bytes); 876 Py_DECREF(unicode); 877 if (!converted) 878 bytes = NULL; 879#endif 880 } 881 else { 882 PyErr_Clear(); 883 if (PyObject_CheckBuffer(o)) 884 bytes = PyBytes_FromObject(o); 885 else 886 bytes = NULL; 887 if (!bytes) { 888 PyErr_Clear(); 889 if (path->allow_fd) { 890 int fd; 891 int result = _fd_converter(o, &fd, 892 "string, bytes or integer"); 893 if (result) { 894 path->wide = NULL; 895 path->narrow = NULL; 896 path->length = 0; 897 path->object = o; 898 path->fd = fd; 899 return result; 900 } 901 } 902 } 903 } 904 905 if (!bytes) { 906 if (!PyErr_Occurred()) 907 FORMAT_EXCEPTION(PyExc_TypeError, "illegal type for %s parameter"); 908 return 0; 909 } 910 911#ifdef MS_WINDOWS 912 if (win32_warn_bytes_api()) { 913 Py_DECREF(bytes); 914 return 0; 915 } 916#endif 917 918 length = PyBytes_GET_SIZE(bytes); 919#ifdef MS_WINDOWS 920 if (length > MAX_PATH-1) { 921 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows"); 922 Py_DECREF(bytes); 923 return 0; 924 } 925#endif 926 927 narrow = PyBytes_AS_STRING(bytes); 928 if (length != strlen(narrow)) { 929 FORMAT_EXCEPTION(PyExc_ValueError, "embedded NUL character in %s"); 930 Py_DECREF(bytes); 931 return 0; 932 } 933 934 path->wide = NULL; 935 path->narrow = narrow; 936 path->length = length; 937 path->object = o; 938 path->fd = -1; 939 path->cleanup = bytes; 940 return Py_CLEANUP_SUPPORTED; 941} 942 943static void 944argument_unavailable_error(char *function_name, char *argument_name) { 945 PyErr_Format(PyExc_NotImplementedError, 946 "%s%s%s unavailable on this platform", 947 (function_name != NULL) ? function_name : "", 948 (function_name != NULL) ? ": ": "", 949 argument_name); 950} 951 952static int 953dir_fd_unavailable(PyObject *o, void *p) 954{ 955 int dir_fd; 956 if (!dir_fd_converter(o, &dir_fd)) 957 return 0; 958 if (dir_fd != DEFAULT_DIR_FD) { 959 argument_unavailable_error(NULL, "dir_fd"); 960 return 0; 961 } 962 *(int *)p = dir_fd; 963 return 1; 964} 965 966static int 967fd_specified(char *function_name, int fd) { 968 if (fd == -1) 969 return 0; 970 971 argument_unavailable_error(function_name, "fd"); 972 return 1; 973} 974 975static int 976follow_symlinks_specified(char *function_name, int follow_symlinks) { 977 if (follow_symlinks) 978 return 0; 979 980 argument_unavailable_error(function_name, "follow_symlinks"); 981 return 1; 982} 983 984static int 985path_and_dir_fd_invalid(char *function_name, path_t *path, int dir_fd) { 986 if (!path->narrow && !path->wide && (dir_fd != DEFAULT_DIR_FD)) { 987 PyErr_Format(PyExc_ValueError, 988 "%s: can't specify dir_fd without matching path", 989 function_name); 990 return 1; 991 } 992 return 0; 993} 994 995static int 996dir_fd_and_fd_invalid(char *function_name, int dir_fd, int fd) { 997 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) { 998 PyErr_Format(PyExc_ValueError, 999 "%s: can't specify both dir_fd and fd", 1000 function_name); 1001 return 1; 1002 } 1003 return 0; 1004} 1005 1006static int 1007fd_and_follow_symlinks_invalid(char *function_name, int fd, 1008 int follow_symlinks) { 1009 if ((fd > 0) && (!follow_symlinks)) { 1010 PyErr_Format(PyExc_ValueError, 1011 "%s: cannot use fd and follow_symlinks together", 1012 function_name); 1013 return 1; 1014 } 1015 return 0; 1016} 1017 1018static int 1019dir_fd_and_follow_symlinks_invalid(char *function_name, int dir_fd, 1020 int follow_symlinks) { 1021 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) { 1022 PyErr_Format(PyExc_ValueError, 1023 "%s: cannot use dir_fd and follow_symlinks together", 1024 function_name); 1025 return 1; 1026 } 1027 return 0; 1028} 1029 1030/* A helper used by a number of POSIX-only functions */ 1031#ifndef MS_WINDOWS 1032static int 1033_parse_off_t(PyObject* arg, void* addr) 1034{ 1035#if !defined(HAVE_LARGEFILE_SUPPORT) 1036 *((off_t*)addr) = PyLong_AsLong(arg); 1037#else 1038 *((off_t*)addr) = PyLong_AsLongLong(arg); 1039#endif 1040 if (PyErr_Occurred()) 1041 return 0; 1042 return 1; 1043} 1044#endif 1045 1046#if defined _MSC_VER && _MSC_VER >= 1400 1047/* Microsoft CRT in VS2005 and higher will verify that a filehandle is 1048 * valid and raise an assertion if it isn't. 1049 * Normally, an invalid fd is likely to be a C program error and therefore 1050 * an assertion can be useful, but it does contradict the POSIX standard 1051 * which for write(2) states: 1052 * "Otherwise, -1 shall be returned and errno set to indicate the error." 1053 * "[EBADF] The fildes argument is not a valid file descriptor open for 1054 * writing." 1055 * Furthermore, python allows the user to enter any old integer 1056 * as a fd and should merely raise a python exception on error. 1057 * The Microsoft CRT doesn't provide an official way to check for the 1058 * validity of a file descriptor, but we can emulate its internal behaviour 1059 * by using the exported __pinfo data member and knowledge of the 1060 * internal structures involved. 1061 * The structures below must be updated for each version of visual studio 1062 * according to the file internal.h in the CRT source, until MS comes 1063 * up with a less hacky way to do this. 1064 * (all of this is to avoid globally modifying the CRT behaviour using 1065 * _set_invalid_parameter_handler() and _CrtSetReportMode()) 1066 */ 1067/* The actual size of the structure is determined at runtime. 1068 * Only the first items must be present. 1069 */ 1070typedef struct { 1071 intptr_t osfhnd; 1072 char osfile; 1073} my_ioinfo; 1074 1075extern __declspec(dllimport) char * __pioinfo[]; 1076#define IOINFO_L2E 5 1077#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E) 1078#define IOINFO_ARRAYS 64 1079#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS) 1080#define FOPEN 0x01 1081#define _NO_CONSOLE_FILENO (intptr_t)-2 1082 1083/* This function emulates what the windows CRT does to validate file handles */ 1084int 1085_PyVerify_fd(int fd) 1086{ 1087 const int i1 = fd >> IOINFO_L2E; 1088 const int i2 = fd & ((1 << IOINFO_L2E) - 1); 1089 1090 static size_t sizeof_ioinfo = 0; 1091 1092 /* Determine the actual size of the ioinfo structure, 1093 * as used by the CRT loaded in memory 1094 */ 1095 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) { 1096 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS; 1097 } 1098 if (sizeof_ioinfo == 0) { 1099 /* This should not happen... */ 1100 goto fail; 1101 } 1102 1103 /* See that it isn't a special CLEAR fileno */ 1104 if (fd != _NO_CONSOLE_FILENO) { 1105 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead 1106 * we check pointer validity and other info 1107 */ 1108 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) { 1109 /* finally, check that the file is open */ 1110 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo); 1111 if (info->osfile & FOPEN) { 1112 return 1; 1113 } 1114 } 1115 } 1116 fail: 1117 errno = EBADF; 1118 return 0; 1119} 1120 1121/* the special case of checking dup2. The target fd must be in a sensible range */ 1122static int 1123_PyVerify_fd_dup2(int fd1, int fd2) 1124{ 1125 if (!_PyVerify_fd(fd1)) 1126 return 0; 1127 if (fd2 == _NO_CONSOLE_FILENO) 1128 return 0; 1129 if ((unsigned)fd2 < _NHANDLE_) 1130 return 1; 1131 else 1132 return 0; 1133} 1134#else 1135/* dummy version. _PyVerify_fd() is already defined in fileobject.h */ 1136#define _PyVerify_fd_dup2(A, B) (1) 1137#endif 1138 1139#ifdef MS_WINDOWS 1140/* The following structure was copied from 1141 http://msdn.microsoft.com/en-us/library/ms791514.aspx as the required 1142 include doesn't seem to be present in the Windows SDK (at least as included 1143 with Visual Studio Express). */ 1144typedef struct _REPARSE_DATA_BUFFER { 1145 ULONG ReparseTag; 1146 USHORT ReparseDataLength; 1147 USHORT Reserved; 1148 union { 1149 struct { 1150 USHORT SubstituteNameOffset; 1151 USHORT SubstituteNameLength; 1152 USHORT PrintNameOffset; 1153 USHORT PrintNameLength; 1154 ULONG Flags; 1155 WCHAR PathBuffer[1]; 1156 } SymbolicLinkReparseBuffer; 1157 1158 struct { 1159 USHORT SubstituteNameOffset; 1160 USHORT SubstituteNameLength; 1161 USHORT PrintNameOffset; 1162 USHORT PrintNameLength; 1163 WCHAR PathBuffer[1]; 1164 } MountPointReparseBuffer; 1165 1166 struct { 1167 UCHAR DataBuffer[1]; 1168 } GenericReparseBuffer; 1169 }; 1170} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER; 1171 1172#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER,\ 1173 GenericReparseBuffer) 1174#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 ) 1175 1176static int 1177win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag) 1178{ 1179 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; 1180 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer; 1181 DWORD n_bytes_returned; 1182 1183 if (0 == DeviceIoControl( 1184 reparse_point_handle, 1185 FSCTL_GET_REPARSE_POINT, 1186 NULL, 0, /* in buffer */ 1187 target_buffer, sizeof(target_buffer), 1188 &n_bytes_returned, 1189 NULL)) /* we're not using OVERLAPPED_IO */ 1190 return FALSE; 1191 1192 if (reparse_tag) 1193 *reparse_tag = rdb->ReparseTag; 1194 1195 return TRUE; 1196} 1197 1198#endif /* MS_WINDOWS */ 1199 1200/* Return a dictionary corresponding to the POSIX environment table */ 1201#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED)) 1202/* On Darwin/MacOSX a shared library or framework has no access to 1203** environ directly, we must obtain it with _NSGetEnviron(). See also 1204** man environ(7). 1205*/ 1206#include <crt_externs.h> 1207static char **environ; 1208#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) ) 1209extern char **environ; 1210#endif /* !_MSC_VER */ 1211 1212static PyObject * 1213convertenviron(void) 1214{ 1215 PyObject *d; 1216#ifdef MS_WINDOWS 1217 wchar_t **e; 1218#else 1219 char **e; 1220#endif 1221 1222 d = PyDict_New(); 1223 if (d == NULL) 1224 return NULL; 1225#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED)) 1226 if (environ == NULL) 1227 environ = *_NSGetEnviron(); 1228#endif 1229#ifdef MS_WINDOWS 1230 /* _wenviron must be initialized in this way if the program is started 1231 through main() instead of wmain(). */ 1232 _wgetenv(L""); 1233 if (_wenviron == NULL) 1234 return d; 1235 /* This part ignores errors */ 1236 for (e = _wenviron; *e != NULL; e++) { 1237 PyObject *k; 1238 PyObject *v; 1239 wchar_t *p = wcschr(*e, L'='); 1240 if (p == NULL) 1241 continue; 1242 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e)); 1243 if (k == NULL) { 1244 PyErr_Clear(); 1245 continue; 1246 } 1247 v = PyUnicode_FromWideChar(p+1, wcslen(p+1)); 1248 if (v == NULL) { 1249 PyErr_Clear(); 1250 Py_DECREF(k); 1251 continue; 1252 } 1253 if (PyDict_GetItem(d, k) == NULL) { 1254 if (PyDict_SetItem(d, k, v) != 0) 1255 PyErr_Clear(); 1256 } 1257 Py_DECREF(k); 1258 Py_DECREF(v); 1259 } 1260#else 1261 if (environ == NULL) 1262 return d; 1263 /* This part ignores errors */ 1264 for (e = environ; *e != NULL; e++) { 1265 PyObject *k; 1266 PyObject *v; 1267 char *p = strchr(*e, '='); 1268 if (p == NULL) 1269 continue; 1270 k = PyBytes_FromStringAndSize(*e, (int)(p-*e)); 1271 if (k == NULL) { 1272 PyErr_Clear(); 1273 continue; 1274 } 1275 v = PyBytes_FromStringAndSize(p+1, strlen(p+1)); 1276 if (v == NULL) { 1277 PyErr_Clear(); 1278 Py_DECREF(k); 1279 continue; 1280 } 1281 if (PyDict_GetItem(d, k) == NULL) { 1282 if (PyDict_SetItem(d, k, v) != 0) 1283 PyErr_Clear(); 1284 } 1285 Py_DECREF(k); 1286 Py_DECREF(v); 1287 } 1288#endif 1289 return d; 1290} 1291 1292/* Set a POSIX-specific error from errno, and return NULL */ 1293 1294static PyObject * 1295posix_error(void) 1296{ 1297 return PyErr_SetFromErrno(PyExc_OSError); 1298} 1299 1300#ifdef MS_WINDOWS 1301static PyObject * 1302win32_error(char* function, const char* filename) 1303{ 1304 /* XXX We should pass the function name along in the future. 1305 (winreg.c also wants to pass the function name.) 1306 This would however require an additional param to the 1307 Windows error object, which is non-trivial. 1308 */ 1309 errno = GetLastError(); 1310 if (filename) 1311 return PyErr_SetFromWindowsErrWithFilename(errno, filename); 1312 else 1313 return PyErr_SetFromWindowsErr(errno); 1314} 1315 1316static PyObject * 1317win32_error_object(char* function, PyObject* filename) 1318{ 1319 /* XXX - see win32_error for comments on 'function' */ 1320 errno = GetLastError(); 1321 if (filename) 1322 return PyErr_SetExcFromWindowsErrWithFilenameObject( 1323 PyExc_OSError, 1324 errno, 1325 filename); 1326 else 1327 return PyErr_SetFromWindowsErr(errno); 1328} 1329 1330#endif /* MS_WINDOWS */ 1331 1332static PyObject * 1333path_error(path_t *path) 1334{ 1335#ifdef MS_WINDOWS 1336 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError, 1337 0, path->object); 1338#else 1339 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object); 1340#endif 1341} 1342 1343 1344static PyObject * 1345path_error2(path_t *path, path_t *path2) 1346{ 1347#ifdef MS_WINDOWS 1348 return PyErr_SetExcFromWindowsErrWithFilenameObjects(PyExc_OSError, 1349 0, path->object, path2->object); 1350#else 1351 return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError, 1352 path->object, path2->object); 1353#endif 1354} 1355 1356 1357/* POSIX generic methods */ 1358 1359static PyObject * 1360posix_fildes(PyObject *fdobj, int (*func)(int)) 1361{ 1362 int fd; 1363 int res; 1364 fd = PyObject_AsFileDescriptor(fdobj); 1365 if (fd < 0) 1366 return NULL; 1367 if (!_PyVerify_fd(fd)) 1368 return posix_error(); 1369 Py_BEGIN_ALLOW_THREADS 1370 res = (*func)(fd); 1371 Py_END_ALLOW_THREADS 1372 if (res < 0) 1373 return posix_error(); 1374 Py_INCREF(Py_None); 1375 return Py_None; 1376} 1377 1378static PyObject * 1379posix_1str(const char *func_name, PyObject *args, char *format, 1380 int (*func)(const char*)) 1381{ 1382 path_t path; 1383 int res; 1384 memset(&path, 0, sizeof(path)); 1385 path.function_name = func_name; 1386 if (!PyArg_ParseTuple(args, format, 1387 path_converter, &path)) 1388 return NULL; 1389 Py_BEGIN_ALLOW_THREADS 1390 res = (*func)(path.narrow); 1391 Py_END_ALLOW_THREADS 1392 if (res < 0) { 1393 path_error(&path); 1394 path_cleanup(&path); 1395 return NULL; 1396 } 1397 path_cleanup(&path); 1398 Py_INCREF(Py_None); 1399 return Py_None; 1400} 1401 1402 1403#ifdef MS_WINDOWS 1404/* This is a reimplementation of the C library's chdir function, 1405 but one that produces Win32 errors instead of DOS error codes. 1406 chdir is essentially a wrapper around SetCurrentDirectory; however, 1407 it also needs to set "magic" environment variables indicating 1408 the per-drive current directory, which are of the form =<drive>: */ 1409static BOOL __stdcall 1410win32_chdir(LPCSTR path) 1411{ 1412 char new_path[MAX_PATH]; 1413 int result; 1414 char env[4] = "=x:"; 1415 1416 if(!SetCurrentDirectoryA(path)) 1417 return FALSE; 1418 result = GetCurrentDirectoryA(Py_ARRAY_LENGTH(new_path), new_path); 1419 if (!result) 1420 return FALSE; 1421 /* In the ANSI API, there should not be any paths longer 1422 than MAX_PATH-1 (not including the final null character). */ 1423 assert(result < Py_ARRAY_LENGTH(new_path)); 1424 if (strncmp(new_path, "\\\\", 2) == 0 || 1425 strncmp(new_path, "//", 2) == 0) 1426 /* UNC path, nothing to do. */ 1427 return TRUE; 1428 env[1] = new_path[0]; 1429 return SetEnvironmentVariableA(env, new_path); 1430} 1431 1432/* The Unicode version differs from the ANSI version 1433 since the current directory might exceed MAX_PATH characters */ 1434static BOOL __stdcall 1435win32_wchdir(LPCWSTR path) 1436{ 1437 wchar_t _new_path[MAX_PATH], *new_path = _new_path; 1438 int result; 1439 wchar_t env[4] = L"=x:"; 1440 1441 if(!SetCurrentDirectoryW(path)) 1442 return FALSE; 1443 result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(new_path), new_path); 1444 if (!result) 1445 return FALSE; 1446 if (result > Py_ARRAY_LENGTH(new_path)) { 1447 new_path = PyMem_RawMalloc(result * sizeof(wchar_t)); 1448 if (!new_path) { 1449 SetLastError(ERROR_OUTOFMEMORY); 1450 return FALSE; 1451 } 1452 result = GetCurrentDirectoryW(result, new_path); 1453 if (!result) { 1454 PyMem_RawFree(new_path); 1455 return FALSE; 1456 } 1457 } 1458 if (wcsncmp(new_path, L"\\\\", 2) == 0 || 1459 wcsncmp(new_path, L"//", 2) == 0) 1460 /* UNC path, nothing to do. */ 1461 return TRUE; 1462 env[1] = new_path[0]; 1463 result = SetEnvironmentVariableW(env, new_path); 1464 if (new_path != _new_path) 1465 PyMem_RawFree(new_path); 1466 return result; 1467} 1468#endif 1469 1470#ifdef MS_WINDOWS 1471/* The CRT of Windows has a number of flaws wrt. its stat() implementation: 1472 - time stamps are restricted to second resolution 1473 - file modification times suffer from forth-and-back conversions between 1474 UTC and local time 1475 Therefore, we implement our own stat, based on the Win32 API directly. 1476*/ 1477#define HAVE_STAT_NSEC 1 1478 1479struct win32_stat{ 1480 unsigned long st_dev; 1481 __int64 st_ino; 1482 unsigned short st_mode; 1483 int st_nlink; 1484 int st_uid; 1485 int st_gid; 1486 unsigned long st_rdev; 1487 __int64 st_size; 1488 time_t st_atime; 1489 int st_atime_nsec; 1490 time_t st_mtime; 1491 int st_mtime_nsec; 1492 time_t st_ctime; 1493 int st_ctime_nsec; 1494}; 1495 1496static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */ 1497 1498static void 1499FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, time_t *time_out, int* nsec_out) 1500{ 1501 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */ 1502 /* Cannot simply cast and dereference in_ptr, 1503 since it might not be aligned properly */ 1504 __int64 in; 1505 memcpy(&in, in_ptr, sizeof(in)); 1506 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */ 1507 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, time_t); 1508} 1509 1510static void 1511time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr) 1512{ 1513 /* XXX endianness */ 1514 __int64 out; 1515 out = time_in + secs_between_epochs; 1516 out = out * 10000000 + nsec_in / 100; 1517 memcpy(out_ptr, &out, sizeof(out)); 1518} 1519 1520/* Below, we *know* that ugo+r is 0444 */ 1521#if _S_IREAD != 0400 1522#error Unsupported C library 1523#endif 1524static int 1525attributes_to_mode(DWORD attr) 1526{ 1527 int m = 0; 1528 if (attr & FILE_ATTRIBUTE_DIRECTORY) 1529 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */ 1530 else 1531 m |= _S_IFREG; 1532 if (attr & FILE_ATTRIBUTE_READONLY) 1533 m |= 0444; 1534 else 1535 m |= 0666; 1536 return m; 1537} 1538 1539static int 1540attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag, struct win32_stat *result) 1541{ 1542 memset(result, 0, sizeof(*result)); 1543 result->st_mode = attributes_to_mode(info->dwFileAttributes); 1544 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow; 1545 result->st_dev = info->dwVolumeSerialNumber; 1546 result->st_rdev = result->st_dev; 1547 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec); 1548 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec); 1549 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec); 1550 result->st_nlink = info->nNumberOfLinks; 1551 result->st_ino = (((__int64)info->nFileIndexHigh)<<32) + info->nFileIndexLow; 1552 if (reparse_tag == IO_REPARSE_TAG_SYMLINK) { 1553 /* first clear the S_IFMT bits */ 1554 result->st_mode ^= (result->st_mode & S_IFMT); 1555 /* now set the bits that make this a symlink */ 1556 result->st_mode |= S_IFLNK; 1557 } 1558 1559 return 0; 1560} 1561 1562static BOOL 1563attributes_from_dir(LPCSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag) 1564{ 1565 HANDLE hFindFile; 1566 WIN32_FIND_DATAA FileData; 1567 hFindFile = FindFirstFileA(pszFile, &FileData); 1568 if (hFindFile == INVALID_HANDLE_VALUE) 1569 return FALSE; 1570 FindClose(hFindFile); 1571 memset(info, 0, sizeof(*info)); 1572 *reparse_tag = 0; 1573 info->dwFileAttributes = FileData.dwFileAttributes; 1574 info->ftCreationTime = FileData.ftCreationTime; 1575 info->ftLastAccessTime = FileData.ftLastAccessTime; 1576 info->ftLastWriteTime = FileData.ftLastWriteTime; 1577 info->nFileSizeHigh = FileData.nFileSizeHigh; 1578 info->nFileSizeLow = FileData.nFileSizeLow; 1579/* info->nNumberOfLinks = 1; */ 1580 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) 1581 *reparse_tag = FileData.dwReserved0; 1582 return TRUE; 1583} 1584 1585static BOOL 1586attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag) 1587{ 1588 HANDLE hFindFile; 1589 WIN32_FIND_DATAW FileData; 1590 hFindFile = FindFirstFileW(pszFile, &FileData); 1591 if (hFindFile == INVALID_HANDLE_VALUE) 1592 return FALSE; 1593 FindClose(hFindFile); 1594 memset(info, 0, sizeof(*info)); 1595 *reparse_tag = 0; 1596 info->dwFileAttributes = FileData.dwFileAttributes; 1597 info->ftCreationTime = FileData.ftCreationTime; 1598 info->ftLastAccessTime = FileData.ftLastAccessTime; 1599 info->ftLastWriteTime = FileData.ftLastWriteTime; 1600 info->nFileSizeHigh = FileData.nFileSizeHigh; 1601 info->nFileSizeLow = FileData.nFileSizeLow; 1602/* info->nNumberOfLinks = 1; */ 1603 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) 1604 *reparse_tag = FileData.dwReserved0; 1605 return TRUE; 1606} 1607 1608/* Grab GetFinalPathNameByHandle dynamically from kernel32 */ 1609static int has_GetFinalPathNameByHandle = -1; 1610static DWORD (CALLBACK *Py_GetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD, 1611 DWORD); 1612static int 1613check_GetFinalPathNameByHandle() 1614{ 1615 HINSTANCE hKernel32; 1616 DWORD (CALLBACK *Py_GetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD, 1617 DWORD); 1618 1619 /* only recheck */ 1620 if (-1 == has_GetFinalPathNameByHandle) 1621 { 1622 hKernel32 = GetModuleHandleW(L"KERNEL32"); 1623 *(FARPROC*)&Py_GetFinalPathNameByHandleA = GetProcAddress(hKernel32, 1624 "GetFinalPathNameByHandleA"); 1625 *(FARPROC*)&Py_GetFinalPathNameByHandleW = GetProcAddress(hKernel32, 1626 "GetFinalPathNameByHandleW"); 1627 has_GetFinalPathNameByHandle = Py_GetFinalPathNameByHandleA && 1628 Py_GetFinalPathNameByHandleW; 1629 } 1630 return has_GetFinalPathNameByHandle; 1631} 1632 1633static BOOL 1634get_target_path(HANDLE hdl, wchar_t **target_path) 1635{ 1636 int buf_size, result_length; 1637 wchar_t *buf; 1638 1639 /* We have a good handle to the target, use it to determine 1640 the target path name (then we'll call lstat on it). */ 1641 buf_size = Py_GetFinalPathNameByHandleW(hdl, 0, 0, 1642 VOLUME_NAME_DOS); 1643 if(!buf_size) 1644 return FALSE; 1645 1646 buf = PyMem_New(wchar_t, buf_size+1); 1647 if (!buf) { 1648 SetLastError(ERROR_OUTOFMEMORY); 1649 return FALSE; 1650 } 1651 1652 result_length = Py_GetFinalPathNameByHandleW(hdl, 1653 buf, buf_size, VOLUME_NAME_DOS); 1654 1655 if(!result_length) { 1656 PyMem_Free(buf); 1657 return FALSE; 1658 } 1659 1660 if(!CloseHandle(hdl)) { 1661 PyMem_Free(buf); 1662 return FALSE; 1663 } 1664 1665 buf[result_length] = 0; 1666 1667 *target_path = buf; 1668 return TRUE; 1669} 1670 1671static int 1672win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result, 1673 BOOL traverse); 1674static int 1675win32_xstat_impl(const char *path, struct win32_stat *result, 1676 BOOL traverse) 1677{ 1678 int code; 1679 HANDLE hFile, hFile2; 1680 BY_HANDLE_FILE_INFORMATION info; 1681 ULONG reparse_tag = 0; 1682 wchar_t *target_path; 1683 const char *dot; 1684 1685 if(!check_GetFinalPathNameByHandle()) { 1686 /* If the OS doesn't have GetFinalPathNameByHandle, don't 1687 traverse reparse point. */ 1688 traverse = FALSE; 1689 } 1690 1691 hFile = CreateFileA( 1692 path, 1693 FILE_READ_ATTRIBUTES, /* desired access */ 1694 0, /* share mode */ 1695 NULL, /* security attributes */ 1696 OPEN_EXISTING, 1697 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */ 1698 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink. 1699 Because of this, calls like GetFinalPathNameByHandle will return 1700 the symlink path again and not the actual final path. */ 1701 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS| 1702 FILE_FLAG_OPEN_REPARSE_POINT, 1703 NULL); 1704 1705 if (hFile == INVALID_HANDLE_VALUE) { 1706 /* Either the target doesn't exist, or we don't have access to 1707 get a handle to it. If the former, we need to return an error. 1708 If the latter, we can use attributes_from_dir. */ 1709 if (GetLastError() != ERROR_SHARING_VIOLATION) 1710 return -1; 1711 /* Could not get attributes on open file. Fall back to 1712 reading the directory. */ 1713 if (!attributes_from_dir(path, &info, &reparse_tag)) 1714 /* Very strange. This should not fail now */ 1715 return -1; 1716 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { 1717 if (traverse) { 1718 /* Should traverse, but could not open reparse point handle */ 1719 SetLastError(ERROR_SHARING_VIOLATION); 1720 return -1; 1721 } 1722 } 1723 } else { 1724 if (!GetFileInformationByHandle(hFile, &info)) { 1725 CloseHandle(hFile); 1726 return -1; 1727 } 1728 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { 1729 if (!win32_get_reparse_tag(hFile, &reparse_tag)) 1730 return -1; 1731 1732 /* Close the outer open file handle now that we're about to 1733 reopen it with different flags. */ 1734 if (!CloseHandle(hFile)) 1735 return -1; 1736 1737 if (traverse) { 1738 /* In order to call GetFinalPathNameByHandle we need to open 1739 the file without the reparse handling flag set. */ 1740 hFile2 = CreateFileA( 1741 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ, 1742 NULL, OPEN_EXISTING, 1743 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS, 1744 NULL); 1745 if (hFile2 == INVALID_HANDLE_VALUE) 1746 return -1; 1747 1748 if (!get_target_path(hFile2, &target_path)) 1749 return -1; 1750 1751 code = win32_xstat_impl_w(target_path, result, FALSE); 1752 PyMem_Free(target_path); 1753 return code; 1754 } 1755 } else 1756 CloseHandle(hFile); 1757 } 1758 attribute_data_to_stat(&info, reparse_tag, result); 1759 1760 /* Set S_IEXEC if it is an .exe, .bat, ... */ 1761 dot = strrchr(path, '.'); 1762 if (dot) { 1763 if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 || 1764 stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0) 1765 result->st_mode |= 0111; 1766 } 1767 return 0; 1768} 1769 1770static int 1771win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result, 1772 BOOL traverse) 1773{ 1774 int code; 1775 HANDLE hFile, hFile2; 1776 BY_HANDLE_FILE_INFORMATION info; 1777 ULONG reparse_tag = 0; 1778 wchar_t *target_path; 1779 const wchar_t *dot; 1780 1781 if(!check_GetFinalPathNameByHandle()) { 1782 /* If the OS doesn't have GetFinalPathNameByHandle, don't 1783 traverse reparse point. */ 1784 traverse = FALSE; 1785 } 1786 1787 hFile = CreateFileW( 1788 path, 1789 FILE_READ_ATTRIBUTES, /* desired access */ 1790 0, /* share mode */ 1791 NULL, /* security attributes */ 1792 OPEN_EXISTING, 1793 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */ 1794 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink. 1795 Because of this, calls like GetFinalPathNameByHandle will return 1796 the symlink path again and not the actual final path. */ 1797 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS| 1798 FILE_FLAG_OPEN_REPARSE_POINT, 1799 NULL); 1800 1801 if (hFile == INVALID_HANDLE_VALUE) { 1802 /* Either the target doesn't exist, or we don't have access to 1803 get a handle to it. If the former, we need to return an error. 1804 If the latter, we can use attributes_from_dir. */ 1805 if (GetLastError() != ERROR_SHARING_VIOLATION) 1806 return -1; 1807 /* Could not get attributes on open file. Fall back to 1808 reading the directory. */ 1809 if (!attributes_from_dir_w(path, &info, &reparse_tag)) 1810 /* Very strange. This should not fail now */ 1811 return -1; 1812 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { 1813 if (traverse) { 1814 /* Should traverse, but could not open reparse point handle */ 1815 SetLastError(ERROR_SHARING_VIOLATION); 1816 return -1; 1817 } 1818 } 1819 } else { 1820 if (!GetFileInformationByHandle(hFile, &info)) { 1821 CloseHandle(hFile); 1822 return -1; 1823 } 1824 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { 1825 if (!win32_get_reparse_tag(hFile, &reparse_tag)) 1826 return -1; 1827 1828 /* Close the outer open file handle now that we're about to 1829 reopen it with different flags. */ 1830 if (!CloseHandle(hFile)) 1831 return -1; 1832 1833 if (traverse) { 1834 /* In order to call GetFinalPathNameByHandle we need to open 1835 the file without the reparse handling flag set. */ 1836 hFile2 = CreateFileW( 1837 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ, 1838 NULL, OPEN_EXISTING, 1839 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS, 1840 NULL); 1841 if (hFile2 == INVALID_HANDLE_VALUE) 1842 return -1; 1843 1844 if (!get_target_path(hFile2, &target_path)) 1845 return -1; 1846 1847 code = win32_xstat_impl_w(target_path, result, FALSE); 1848 PyMem_Free(target_path); 1849 return code; 1850 } 1851 } else 1852 CloseHandle(hFile); 1853 } 1854 attribute_data_to_stat(&info, reparse_tag, result); 1855 1856 /* Set S_IEXEC if it is an .exe, .bat, ... */ 1857 dot = wcsrchr(path, '.'); 1858 if (dot) { 1859 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 || 1860 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0) 1861 result->st_mode |= 0111; 1862 } 1863 return 0; 1864} 1865 1866static int 1867win32_xstat(const char *path, struct win32_stat *result, BOOL traverse) 1868{ 1869 /* Protocol violation: we explicitly clear errno, instead of 1870 setting it to a POSIX error. Callers should use GetLastError. */ 1871 int code = win32_xstat_impl(path, result, traverse); 1872 errno = 0; 1873 return code; 1874} 1875 1876static int 1877win32_xstat_w(const wchar_t *path, struct win32_stat *result, BOOL traverse) 1878{ 1879 /* Protocol violation: we explicitly clear errno, instead of 1880 setting it to a POSIX error. Callers should use GetLastError. */ 1881 int code = win32_xstat_impl_w(path, result, traverse); 1882 errno = 0; 1883 return code; 1884} 1885/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w 1886 1887 In Posix, stat automatically traverses symlinks and returns the stat 1888 structure for the target. In Windows, the equivalent GetFileAttributes by 1889 default does not traverse symlinks and instead returns attributes for 1890 the symlink. 1891 1892 Therefore, win32_lstat will get the attributes traditionally, and 1893 win32_stat will first explicitly resolve the symlink target and then will 1894 call win32_lstat on that result. 1895 1896 The _w represent Unicode equivalents of the aforementioned ANSI functions. */ 1897 1898static int 1899win32_lstat(const char* path, struct win32_stat *result) 1900{ 1901 return win32_xstat(path, result, FALSE); 1902} 1903 1904static int 1905win32_lstat_w(const wchar_t* path, struct win32_stat *result) 1906{ 1907 return win32_xstat_w(path, result, FALSE); 1908} 1909 1910static int 1911win32_stat(const char* path, struct win32_stat *result) 1912{ 1913 return win32_xstat(path, result, TRUE); 1914} 1915 1916static int 1917win32_stat_w(const wchar_t* path, struct win32_stat *result) 1918{ 1919 return win32_xstat_w(path, result, TRUE); 1920} 1921 1922static int 1923win32_fstat(int file_number, struct win32_stat *result) 1924{ 1925 BY_HANDLE_FILE_INFORMATION info; 1926 HANDLE h; 1927 int type; 1928 1929 if (!_PyVerify_fd(file_number)) 1930 h = INVALID_HANDLE_VALUE; 1931 else 1932 h = (HANDLE)_get_osfhandle(file_number); 1933 1934 /* Protocol violation: we explicitly clear errno, instead of 1935 setting it to a POSIX error. Callers should use GetLastError. */ 1936 errno = 0; 1937 1938 if (h == INVALID_HANDLE_VALUE) { 1939 /* This is really a C library error (invalid file handle). 1940 We set the Win32 error to the closes one matching. */ 1941 SetLastError(ERROR_INVALID_HANDLE); 1942 return -1; 1943 } 1944 memset(result, 0, sizeof(*result)); 1945 1946 type = GetFileType(h); 1947 if (type == FILE_TYPE_UNKNOWN) { 1948 DWORD error = GetLastError(); 1949 if (error != 0) { 1950 return -1; 1951 } 1952 /* else: valid but unknown file */ 1953 } 1954 1955 if (type != FILE_TYPE_DISK) { 1956 if (type == FILE_TYPE_CHAR) 1957 result->st_mode = _S_IFCHR; 1958 else if (type == FILE_TYPE_PIPE) 1959 result->st_mode = _S_IFIFO; 1960 return 0; 1961 } 1962 1963 if (!GetFileInformationByHandle(h, &info)) { 1964 return -1; 1965 } 1966 1967 attribute_data_to_stat(&info, 0, result); 1968 /* specific to fstat() */ 1969 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow; 1970 return 0; 1971} 1972 1973#endif /* MS_WINDOWS */ 1974 1975PyDoc_STRVAR(stat_result__doc__, 1976"stat_result: Result from stat, fstat, or lstat.\n\n\ 1977This object may be accessed either as a tuple of\n\ 1978 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\ 1979or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\ 1980\n\ 1981Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\ 1982or st_flags, they are available as attributes only.\n\ 1983\n\ 1984See os.stat for more information."); 1985 1986static PyStructSequence_Field stat_result_fields[] = { 1987 {"st_mode", "protection bits"}, 1988 {"st_ino", "inode"}, 1989 {"st_dev", "device"}, 1990 {"st_nlink", "number of hard links"}, 1991 {"st_uid", "user ID of owner"}, 1992 {"st_gid", "group ID of owner"}, 1993 {"st_size", "total size, in bytes"}, 1994 /* The NULL is replaced with PyStructSequence_UnnamedField later. */ 1995 {NULL, "integer time of last access"}, 1996 {NULL, "integer time of last modification"}, 1997 {NULL, "integer time of last change"}, 1998 {"st_atime", "time of last access"}, 1999 {"st_mtime", "time of last modification"}, 2000 {"st_ctime", "time of last change"}, 2001 {"st_atime_ns", "time of last access in nanoseconds"}, 2002 {"st_mtime_ns", "time of last modification in nanoseconds"}, 2003 {"st_ctime_ns", "time of last change in nanoseconds"}, 2004#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE 2005 {"st_blksize", "blocksize for filesystem I/O"}, 2006#endif 2007#ifdef HAVE_STRUCT_STAT_ST_BLOCKS 2008 {"st_blocks", "number of blocks allocated"}, 2009#endif 2010#ifdef HAVE_STRUCT_STAT_ST_RDEV 2011 {"st_rdev", "device type (if inode device)"}, 2012#endif 2013#ifdef HAVE_STRUCT_STAT_ST_FLAGS 2014 {"st_flags", "user defined flags for file"}, 2015#endif 2016#ifdef HAVE_STRUCT_STAT_ST_GEN 2017 {"st_gen", "generation number"}, 2018#endif 2019#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME 2020 {"st_birthtime", "time of creation"}, 2021#endif 2022 {0} 2023}; 2024 2025#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE 2026#define ST_BLKSIZE_IDX 16 2027#else 2028#define ST_BLKSIZE_IDX 15 2029#endif 2030 2031#ifdef HAVE_STRUCT_STAT_ST_BLOCKS 2032#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1) 2033#else 2034#define ST_BLOCKS_IDX ST_BLKSIZE_IDX 2035#endif 2036 2037#ifdef HAVE_STRUCT_STAT_ST_RDEV 2038#define ST_RDEV_IDX (ST_BLOCKS_IDX+1) 2039#else 2040#define ST_RDEV_IDX ST_BLOCKS_IDX 2041#endif 2042 2043#ifdef HAVE_STRUCT_STAT_ST_FLAGS 2044#define ST_FLAGS_IDX (ST_RDEV_IDX+1) 2045#else 2046#define ST_FLAGS_IDX ST_RDEV_IDX 2047#endif 2048 2049#ifdef HAVE_STRUCT_STAT_ST_GEN 2050#define ST_GEN_IDX (ST_FLAGS_IDX+1) 2051#else 2052#define ST_GEN_IDX ST_FLAGS_IDX 2053#endif 2054 2055#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME 2056#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1) 2057#else 2058#define ST_BIRTHTIME_IDX ST_GEN_IDX 2059#endif 2060 2061static PyStructSequence_Desc stat_result_desc = { 2062 "stat_result", /* name */ 2063 stat_result__doc__, /* doc */ 2064 stat_result_fields, 2065 10 2066}; 2067 2068PyDoc_STRVAR(statvfs_result__doc__, 2069"statvfs_result: Result from statvfs or fstatvfs.\n\n\ 2070This object may be accessed either as a tuple of\n\ 2071 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\ 2072or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\ 2073\n\ 2074See os.statvfs for more information."); 2075 2076static PyStructSequence_Field statvfs_result_fields[] = { 2077 {"f_bsize", }, 2078 {"f_frsize", }, 2079 {"f_blocks", }, 2080 {"f_bfree", }, 2081 {"f_bavail", }, 2082 {"f_files", }, 2083 {"f_ffree", }, 2084 {"f_favail", }, 2085 {"f_flag", }, 2086 {"f_namemax",}, 2087 {0} 2088}; 2089 2090static PyStructSequence_Desc statvfs_result_desc = { 2091 "statvfs_result", /* name */ 2092 statvfs_result__doc__, /* doc */ 2093 statvfs_result_fields, 2094 10 2095}; 2096 2097#if defined(HAVE_WAITID) && !defined(__APPLE__) 2098PyDoc_STRVAR(waitid_result__doc__, 2099"waitid_result: Result from waitid.\n\n\ 2100This object may be accessed either as a tuple of\n\ 2101 (si_pid, si_uid, si_signo, si_status, si_code),\n\ 2102or via the attributes si_pid, si_uid, and so on.\n\ 2103\n\ 2104See os.waitid for more information."); 2105 2106static PyStructSequence_Field waitid_result_fields[] = { 2107 {"si_pid", }, 2108 {"si_uid", }, 2109 {"si_signo", }, 2110 {"si_status", }, 2111 {"si_code", }, 2112 {0} 2113}; 2114 2115static PyStructSequence_Desc waitid_result_desc = { 2116 "waitid_result", /* name */ 2117 waitid_result__doc__, /* doc */ 2118 waitid_result_fields, 2119 5 2120}; 2121static PyTypeObject WaitidResultType; 2122#endif 2123 2124static int initialized; 2125static PyTypeObject StatResultType; 2126static PyTypeObject StatVFSResultType; 2127#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) 2128static PyTypeObject SchedParamType; 2129#endif 2130static newfunc structseq_new; 2131 2132static PyObject * 2133statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds) 2134{ 2135 PyStructSequence *result; 2136 int i; 2137 2138 result = (PyStructSequence*)structseq_new(type, args, kwds); 2139 if (!result) 2140 return NULL; 2141 /* If we have been initialized from a tuple, 2142 st_?time might be set to None. Initialize it 2143 from the int slots. */ 2144 for (i = 7; i <= 9; i++) { 2145 if (result->ob_item[i+3] == Py_None) { 2146 Py_DECREF(Py_None); 2147 Py_INCREF(result->ob_item[i]); 2148 result->ob_item[i+3] = result->ob_item[i]; 2149 } 2150 } 2151 return (PyObject*)result; 2152} 2153 2154 2155 2156/* If true, st_?time is float. */ 2157static int _stat_float_times = 1; 2158 2159PyDoc_STRVAR(stat_float_times__doc__, 2160"stat_float_times([newval]) -> oldval\n\n\ 2161Determine whether os.[lf]stat represents time stamps as float objects.\n\ 2162If newval is True, future calls to stat() return floats, if it is False,\n\ 2163future calls return ints. \n\ 2164If newval is omitted, return the current setting.\n"); 2165 2166static PyObject* 2167stat_float_times(PyObject* self, PyObject *args) 2168{ 2169 int newval = -1; 2170 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval)) 2171 return NULL; 2172 if (PyErr_WarnEx(PyExc_DeprecationWarning, 2173 "stat_float_times() is deprecated", 2174 1)) 2175 return NULL; 2176 if (newval == -1) 2177 /* Return old value */ 2178 return PyBool_FromLong(_stat_float_times); 2179 _stat_float_times = newval; 2180 Py_INCREF(Py_None); 2181 return Py_None; 2182} 2183 2184static PyObject *billion = NULL; 2185 2186static void 2187fill_time(PyObject *v, int index, time_t sec, unsigned long nsec) 2188{ 2189 PyObject *s = _PyLong_FromTime_t(sec); 2190 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec); 2191 PyObject *s_in_ns = NULL; 2192 PyObject *ns_total = NULL; 2193 PyObject *float_s = NULL; 2194 2195 if (!(s && ns_fractional)) 2196 goto exit; 2197 2198 s_in_ns = PyNumber_Multiply(s, billion); 2199 if (!s_in_ns) 2200 goto exit; 2201 2202 ns_total = PyNumber_Add(s_in_ns, ns_fractional); 2203 if (!ns_total) 2204 goto exit; 2205 2206 if (_stat_float_times) { 2207 float_s = PyFloat_FromDouble(sec + 1e-9*nsec); 2208 if (!float_s) 2209 goto exit; 2210 } 2211 else { 2212 float_s = s; 2213 Py_INCREF(float_s); 2214 } 2215 2216 PyStructSequence_SET_ITEM(v, index, s); 2217 PyStructSequence_SET_ITEM(v, index+3, float_s); 2218 PyStructSequence_SET_ITEM(v, index+6, ns_total); 2219 s = NULL; 2220 float_s = NULL; 2221 ns_total = NULL; 2222exit: 2223 Py_XDECREF(s); 2224 Py_XDECREF(ns_fractional); 2225 Py_XDECREF(s_in_ns); 2226 Py_XDECREF(ns_total); 2227 Py_XDECREF(float_s); 2228} 2229 2230/* pack a system stat C structure into the Python stat tuple 2231 (used by posix_stat() and posix_fstat()) */ 2232static PyObject* 2233_pystat_fromstructstat(STRUCT_STAT *st) 2234{ 2235 unsigned long ansec, mnsec, cnsec; 2236 PyObject *v = PyStructSequence_New(&StatResultType); 2237 if (v == NULL) 2238 return NULL; 2239 2240 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode)); 2241#ifdef HAVE_LARGEFILE_SUPPORT 2242 PyStructSequence_SET_ITEM(v, 1, 2243 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino)); 2244#else 2245 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino)); 2246#endif 2247#ifdef MS_WINDOWS 2248 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev)); 2249#else 2250 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev)); 2251#endif 2252 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink)); 2253#if defined(MS_WINDOWS) 2254 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0)); 2255 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0)); 2256#else 2257 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid)); 2258 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid)); 2259#endif 2260#ifdef HAVE_LARGEFILE_SUPPORT 2261 PyStructSequence_SET_ITEM(v, 6, 2262 PyLong_FromLongLong((PY_LONG_LONG)st->st_size)); 2263#else 2264 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size)); 2265#endif 2266 2267#if defined(HAVE_STAT_TV_NSEC) 2268 ansec = st->st_atim.tv_nsec; 2269 mnsec = st->st_mtim.tv_nsec; 2270 cnsec = st->st_ctim.tv_nsec; 2271#elif defined(HAVE_STAT_TV_NSEC2) 2272 ansec = st->st_atimespec.tv_nsec; 2273 mnsec = st->st_mtimespec.tv_nsec; 2274 cnsec = st->st_ctimespec.tv_nsec; 2275#elif defined(HAVE_STAT_NSEC) 2276 ansec = st->st_atime_nsec; 2277 mnsec = st->st_mtime_nsec; 2278 cnsec = st->st_ctime_nsec; 2279#else 2280 ansec = mnsec = cnsec = 0; 2281#endif 2282 fill_time(v, 7, st->st_atime, ansec); 2283 fill_time(v, 8, st->st_mtime, mnsec); 2284 fill_time(v, 9, st->st_ctime, cnsec); 2285 2286#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE 2287 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX, 2288 PyLong_FromLong((long)st->st_blksize)); 2289#endif 2290#ifdef HAVE_STRUCT_STAT_ST_BLOCKS 2291 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX, 2292 PyLong_FromLong((long)st->st_blocks)); 2293#endif 2294#ifdef HAVE_STRUCT_STAT_ST_RDEV 2295 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX, 2296 PyLong_FromLong((long)st->st_rdev)); 2297#endif 2298#ifdef HAVE_STRUCT_STAT_ST_GEN 2299 PyStructSequence_SET_ITEM(v, ST_GEN_IDX, 2300 PyLong_FromLong((long)st->st_gen)); 2301#endif 2302#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME 2303 { 2304 PyObject *val; 2305 unsigned long bsec,bnsec; 2306 bsec = (long)st->st_birthtime; 2307#ifdef HAVE_STAT_TV_NSEC2 2308 bnsec = st->st_birthtimespec.tv_nsec; 2309#else 2310 bnsec = 0; 2311#endif 2312 if (_stat_float_times) { 2313 val = PyFloat_FromDouble(bsec + 1e-9*bnsec); 2314 } else { 2315 val = PyLong_FromLong((long)bsec); 2316 } 2317 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX, 2318 val); 2319 } 2320#endif 2321#ifdef HAVE_STRUCT_STAT_ST_FLAGS 2322 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX, 2323 PyLong_FromLong((long)st->st_flags)); 2324#endif 2325 2326 if (PyErr_Occurred()) { 2327 Py_DECREF(v); 2328 return NULL; 2329 } 2330 2331 return v; 2332} 2333 2334/* POSIX methods */ 2335 2336 2337static PyObject * 2338posix_do_stat(char *function_name, path_t *path, 2339 int dir_fd, int follow_symlinks) 2340{ 2341 STRUCT_STAT st; 2342 int result; 2343 2344#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT) 2345 if (follow_symlinks_specified(function_name, follow_symlinks)) 2346 return NULL; 2347#endif 2348 2349 if (path_and_dir_fd_invalid("stat", path, dir_fd) || 2350 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) || 2351 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks)) 2352 return NULL; 2353 2354 Py_BEGIN_ALLOW_THREADS 2355 if (path->fd != -1) 2356 result = FSTAT(path->fd, &st); 2357 else 2358#ifdef MS_WINDOWS 2359 if (path->wide) { 2360 if (follow_symlinks) 2361 result = win32_stat_w(path->wide, &st); 2362 else 2363 result = win32_lstat_w(path->wide, &st); 2364 } 2365 else 2366#endif 2367#if defined(HAVE_LSTAT) || defined(MS_WINDOWS) 2368 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD)) 2369 result = LSTAT(path->narrow, &st); 2370 else 2371#endif 2372#ifdef HAVE_FSTATAT 2373 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) 2374 result = fstatat(dir_fd, path->narrow, &st, 2375 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW); 2376 else 2377#endif 2378 result = STAT(path->narrow, &st); 2379 Py_END_ALLOW_THREADS 2380 2381 if (result != 0) { 2382 return path_error(path); 2383 } 2384 2385 return _pystat_fromstructstat(&st); 2386} 2387 2388#ifdef HAVE_FSTATAT 2389 #define OS_STAT_DIR_FD_CONVERTER dir_fd_converter 2390#else 2391 #define OS_STAT_DIR_FD_CONVERTER dir_fd_unavailable 2392#endif 2393 2394 2395/*[python input] 2396 2397class path_t_converter(CConverter): 2398 2399 type = "path_t" 2400 impl_by_reference = True 2401 parse_by_reference = True 2402 2403 converter = 'path_converter' 2404 2405 def converter_init(self, *, allow_fd=False, nullable=False): 2406 # right now path_t doesn't support default values. 2407 # to support a default value, you'll need to override initialize(). 2408 if self.default is not unspecified: 2409 fail("Can't specify a default to the path_t converter!") 2410 2411 if self.c_default is not None: 2412 fail("Can't specify a c_default to the path_t converter!") 2413 2414 self.nullable = nullable 2415 self.allow_fd = allow_fd 2416 2417 def pre_render(self): 2418 def strify(value): 2419 return str(int(bool(value))) 2420 2421 # add self.py_name here when merging with posixmodule conversion 2422 self.c_default = 'PATH_T_INITIALIZE("{}", {}, {})'.format( 2423 self.function.name, 2424 strify(self.nullable), 2425 strify(self.allow_fd), 2426 ) 2427 2428 def cleanup(self): 2429 return "path_cleanup(&" + self.name + ");\n" 2430 2431 2432class dir_fd_converter(CConverter): 2433 type = 'int' 2434 converter = 'OS_STAT_DIR_FD_CONVERTER' 2435 2436 def converter_init(self): 2437 if self.default in (unspecified, None): 2438 self.c_default = 'DEFAULT_DIR_FD' 2439 2440 2441[python start generated code]*/ 2442/*[python end generated code: output=da39a3ee5e6b4b0d input=5c9f456f53244fc3]*/ 2443 2444/*[clinic input] 2445 2446os.stat 2447 2448 path : path_t(allow_fd=True) 2449 Path to be examined; can be string, bytes, or open-file-descriptor int. 2450 2451 * 2452 2453 dir_fd : dir_fd = None 2454 If not None, it should be a file descriptor open to a directory, 2455 and path should be a relative string; path will then be relative to 2456 that directory. 2457 2458 follow_symlinks: bool = True 2459 If False, and the last element of the path is a symbolic link, 2460 stat will examine the symbolic link itself instead of the file 2461 the link points to. 2462 2463Perform a stat system call on the given path. 2464 2465dir_fd and follow_symlinks may not be implemented 2466 on your platform. If they are unavailable, using them will raise a 2467 NotImplementedError. 2468 2469It's an error to use dir_fd or follow_symlinks when specifying path as 2470 an open file descriptor. 2471 2472[clinic start generated code]*/ 2473 2474PyDoc_STRVAR(os_stat__doc__, 2475"stat($module, /, path, *, dir_fd=None, follow_symlinks=True)\n" 2476"--\n" 2477"\n" 2478"Perform a stat system call on the given path.\n" 2479"\n" 2480" path\n" 2481" Path to be examined; can be string, bytes, or open-file-descriptor int.\n" 2482" dir_fd\n" 2483" If not None, it should be a file descriptor open to a directory,\n" 2484" and path should be a relative string; path will then be relative to\n" 2485" that directory.\n" 2486" follow_symlinks\n" 2487" If False, and the last element of the path is a symbolic link,\n" 2488" stat will examine the symbolic link itself instead of the file\n" 2489" the link points to.\n" 2490"\n" 2491"dir_fd and follow_symlinks may not be implemented\n" 2492" on your platform. If they are unavailable, using them will raise a\n" 2493" NotImplementedError.\n" 2494"\n" 2495"It\'s an error to use dir_fd or follow_symlinks when specifying path as\n" 2496" an open file descriptor."); 2497 2498#define OS_STAT_METHODDEF \ 2499 {"stat", (PyCFunction)os_stat, METH_VARARGS|METH_KEYWORDS, os_stat__doc__}, 2500 2501static PyObject * 2502os_stat_impl(PyModuleDef *module, path_t *path, int dir_fd, int follow_symlinks); 2503 2504static PyObject * 2505os_stat(PyModuleDef *module, PyObject *args, PyObject *kwargs) 2506{ 2507 PyObject *return_value = NULL; 2508 static char *_keywords[] = {"path", "dir_fd", "follow_symlinks", NULL}; 2509 path_t path = PATH_T_INITIALIZE("stat", 0, 1); 2510 int dir_fd = DEFAULT_DIR_FD; 2511 int follow_symlinks = 1; 2512 2513 if (!PyArg_ParseTupleAndKeywords(args, kwargs, 2514 "O&|$O&p:stat", _keywords, 2515 path_converter, &path, OS_STAT_DIR_FD_CONVERTER, &dir_fd, &follow_symlinks)) 2516 goto exit; 2517 return_value = os_stat_impl(module, &path, dir_fd, follow_symlinks); 2518 2519exit: 2520 /* Cleanup for path */ 2521 path_cleanup(&path); 2522 2523 return return_value; 2524} 2525 2526static PyObject * 2527os_stat_impl(PyModuleDef *module, path_t *path, int dir_fd, int follow_symlinks) 2528/*[clinic end generated code: output=f1dcaa5e24db9882 input=5ae155bd475fd20a]*/ 2529{ 2530 return posix_do_stat("stat", path, dir_fd, follow_symlinks); 2531} 2532 2533PyDoc_STRVAR(posix_lstat__doc__, 2534"lstat(path, *, dir_fd=None) -> stat result\n\n\ 2535Like stat(), but do not follow symbolic links.\n\ 2536Equivalent to stat(path, follow_symlinks=False)."); 2537 2538static PyObject * 2539posix_lstat(PyObject *self, PyObject *args, PyObject *kwargs) 2540{ 2541 static char *keywords[] = {"path", "dir_fd", NULL}; 2542 path_t path; 2543 int dir_fd = DEFAULT_DIR_FD; 2544 int follow_symlinks = 0; 2545 PyObject *return_value; 2546 2547 memset(&path, 0, sizeof(path)); 2548 path.function_name = "lstat"; 2549 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:lstat", keywords, 2550 path_converter, &path, 2551#ifdef HAVE_FSTATAT 2552 dir_fd_converter, &dir_fd 2553#else 2554 dir_fd_unavailable, &dir_fd 2555#endif 2556 )) 2557 return NULL; 2558 return_value = posix_do_stat("lstat", &path, dir_fd, follow_symlinks); 2559 path_cleanup(&path); 2560 return return_value; 2561} 2562 2563 2564#ifdef HAVE_FACCESSAT 2565 #define OS_ACCESS_DIR_FD_CONVERTER dir_fd_converter 2566#else 2567 #define OS_ACCESS_DIR_FD_CONVERTER dir_fd_unavailable 2568#endif 2569/*[clinic input] 2570os.access 2571 2572 path: path_t(allow_fd=True) 2573 Path to be tested; can be string, bytes, or open-file-descriptor int. 2574 2575 mode: int 2576 Operating-system mode bitfield. Can be F_OK to test existence, 2577 or the inclusive-OR of R_OK, W_OK, and X_OK. 2578 2579 * 2580 2581 dir_fd : dir_fd = None 2582 If not None, it should be a file descriptor open to a directory, 2583 and path should be relative; path will then be relative to that 2584 directory. 2585 2586 effective_ids: bool = False 2587 If True, access will use the effective uid/gid instead of 2588 the real uid/gid. 2589 2590 follow_symlinks: bool = True 2591 If False, and the last element of the path is a symbolic link, 2592 access will examine the symbolic link itself instead of the file 2593 the link points to. 2594 2595Use the real uid/gid to test for access to a path. 2596 2597{parameters} 2598dir_fd, effective_ids, and follow_symlinks may not be implemented 2599 on your platform. If they are unavailable, using them will raise a 2600 NotImplementedError. 2601 2602Note that most operations will use the effective uid/gid, therefore this 2603 routine can be used in a suid/sgid environment to test if the invoking user 2604 has the specified access to the path. 2605 2606[clinic start generated code]*/ 2607 2608PyDoc_STRVAR(os_access__doc__, 2609"access($module, /, path, mode, *, dir_fd=None, effective_ids=False,\n" 2610" follow_symlinks=True)\n" 2611"--\n" 2612"\n" 2613"Use the real uid/gid to test for access to a path.\n" 2614"\n" 2615" path\n" 2616" Path to be tested; can be string, bytes, or open-file-descriptor int.\n" 2617" mode\n" 2618" Operating-system mode bitfield. Can be F_OK to test existence,\n" 2619" or the inclusive-OR of R_OK, W_OK, and X_OK.\n" 2620" dir_fd\n" 2621" If not None, it should be a file descriptor open to a directory,\n" 2622" and path should be relative; path will then be relative to that\n" 2623" directory.\n" 2624" effective_ids\n" 2625" If True, access will use the effective uid/gid instead of\n" 2626" the real uid/gid.\n" 2627" follow_symlinks\n" 2628" If False, and the last element of the path is a symbolic link,\n" 2629" access will examine the symbolic link itself instead of the file\n" 2630" the link points to.\n" 2631"\n" 2632"dir_fd, effective_ids, and follow_symlinks may not be implemented\n" 2633" on your platform. If they are unavailable, using them will raise a\n" 2634" NotImplementedError.\n" 2635"\n" 2636"Note that most operations will use the effective uid/gid, therefore this\n" 2637" routine can be used in a suid/sgid environment to test if the invoking user\n" 2638" has the specified access to the path."); 2639 2640#define OS_ACCESS_METHODDEF \ 2641 {"access", (PyCFunction)os_access, METH_VARARGS|METH_KEYWORDS, os_access__doc__}, 2642 2643static PyObject * 2644os_access_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd, int effective_ids, int follow_symlinks); 2645 2646static PyObject * 2647os_access(PyModuleDef *module, PyObject *args, PyObject *kwargs) 2648{ 2649 PyObject *return_value = NULL; 2650 static char *_keywords[] = {"path", "mode", "dir_fd", "effective_ids", "follow_symlinks", NULL}; 2651 path_t path = PATH_T_INITIALIZE("access", 0, 1); 2652 int mode; 2653 int dir_fd = DEFAULT_DIR_FD; 2654 int effective_ids = 0; 2655 int follow_symlinks = 1; 2656 2657 if (!PyArg_ParseTupleAndKeywords(args, kwargs, 2658 "O&i|$O&pp:access", _keywords, 2659 path_converter, &path, &mode, OS_STAT_DIR_FD_CONVERTER, &dir_fd, &effective_ids, &follow_symlinks)) 2660 goto exit; 2661 return_value = os_access_impl(module, &path, mode, dir_fd, effective_ids, follow_symlinks); 2662 2663exit: 2664 /* Cleanup for path */ 2665 path_cleanup(&path); 2666 2667 return return_value; 2668} 2669 2670static PyObject * 2671os_access_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd, int effective_ids, int follow_symlinks) 2672/*[clinic end generated code: output=a6ed4f151be9df0f input=2e2e7594371f5b7e]*/ 2673{ 2674 PyObject *return_value = NULL; 2675 2676#ifdef MS_WINDOWS 2677 DWORD attr; 2678#else 2679 int result; 2680#endif 2681 2682#ifndef HAVE_FACCESSAT 2683 if (follow_symlinks_specified("access", follow_symlinks)) 2684 goto exit; 2685 2686 if (effective_ids) { 2687 argument_unavailable_error("access", "effective_ids"); 2688 goto exit; 2689 } 2690#endif 2691 2692#ifdef MS_WINDOWS 2693 Py_BEGIN_ALLOW_THREADS 2694 if (path->wide != NULL) 2695 attr = GetFileAttributesW(path->wide); 2696 else 2697 attr = GetFileAttributesA(path->narrow); 2698 Py_END_ALLOW_THREADS 2699 2700 /* 2701 * Access is possible if 2702 * * we didn't get a -1, and 2703 * * write access wasn't requested, 2704 * * or the file isn't read-only, 2705 * * or it's a directory. 2706 * (Directories cannot be read-only on Windows.) 2707 */ 2708 return_value = PyBool_FromLong( 2709 (attr != INVALID_FILE_ATTRIBUTES) && 2710 (!(mode & 2) || 2711 !(attr & FILE_ATTRIBUTE_READONLY) || 2712 (attr & FILE_ATTRIBUTE_DIRECTORY))); 2713#else 2714 2715 Py_BEGIN_ALLOW_THREADS 2716#ifdef HAVE_FACCESSAT 2717 if ((dir_fd != DEFAULT_DIR_FD) || 2718 effective_ids || 2719 !follow_symlinks) { 2720 int flags = 0; 2721 if (!follow_symlinks) 2722 flags |= AT_SYMLINK_NOFOLLOW; 2723 if (effective_ids) 2724 flags |= AT_EACCESS; 2725 result = faccessat(dir_fd, path->narrow, mode, flags); 2726 } 2727 else 2728#endif 2729 result = access(path->narrow, mode); 2730 Py_END_ALLOW_THREADS 2731 return_value = PyBool_FromLong(!result); 2732#endif 2733 2734#ifndef HAVE_FACCESSAT 2735exit: 2736#endif 2737 return return_value; 2738} 2739 2740#ifndef F_OK 2741#define F_OK 0 2742#endif 2743#ifndef R_OK 2744#define R_OK 4 2745#endif 2746#ifndef W_OK 2747#define W_OK 2 2748#endif 2749#ifndef X_OK 2750#define X_OK 1 2751#endif 2752 2753 2754#ifdef HAVE_TTYNAME 2755 2756/*[clinic input] 2757os.ttyname -> DecodeFSDefault 2758 2759 fd: int 2760 Integer file descriptor handle. 2761 2762 / 2763 2764Return the name of the terminal device connected to 'fd'. 2765[clinic start generated code]*/ 2766 2767PyDoc_STRVAR(os_ttyname__doc__, 2768"ttyname($module, fd, /)\n" 2769"--\n" 2770"\n" 2771"Return the name of the terminal device connected to \'fd\'.\n" 2772"\n" 2773" fd\n" 2774" Integer file descriptor handle."); 2775 2776#define OS_TTYNAME_METHODDEF \ 2777 {"ttyname", (PyCFunction)os_ttyname, METH_VARARGS, os_ttyname__doc__}, 2778 2779static char * 2780os_ttyname_impl(PyModuleDef *module, int fd); 2781 2782static PyObject * 2783os_ttyname(PyModuleDef *module, PyObject *args) 2784{ 2785 PyObject *return_value = NULL; 2786 int fd; 2787 char *_return_value; 2788 2789 if (!PyArg_ParseTuple(args, 2790 "i:ttyname", 2791 &fd)) 2792 goto exit; 2793 _return_value = os_ttyname_impl(module, fd); 2794 if (_return_value == NULL) 2795 goto exit; 2796 return_value = PyUnicode_DecodeFSDefault(_return_value); 2797 2798exit: 2799 return return_value; 2800} 2801 2802static char * 2803os_ttyname_impl(PyModuleDef *module, int fd) 2804/*[clinic end generated code: output=cee7bc4cffec01a2 input=5f72ca83e76b3b45]*/ 2805{ 2806 char *ret; 2807 2808 ret = ttyname(fd); 2809 if (ret == NULL) 2810 posix_error(); 2811 return ret; 2812} 2813#else 2814#define OS_TTYNAME_METHODDEF 2815#endif 2816 2817#ifdef HAVE_CTERMID 2818PyDoc_STRVAR(posix_ctermid__doc__, 2819"ctermid() -> string\n\n\ 2820Return the name of the controlling terminal for this process."); 2821 2822static PyObject * 2823posix_ctermid(PyObject *self, PyObject *noargs) 2824{ 2825 char *ret; 2826 char buffer[L_ctermid]; 2827 2828#ifdef USE_CTERMID_R 2829 ret = ctermid_r(buffer); 2830#else 2831 ret = ctermid(buffer); 2832#endif 2833 if (ret == NULL) 2834 return posix_error(); 2835 return PyUnicode_DecodeFSDefault(buffer); 2836} 2837#endif 2838 2839PyDoc_STRVAR(posix_chdir__doc__, 2840"chdir(path)\n\n\ 2841Change the current working directory to the specified path.\n\ 2842\n\ 2843path may always be specified as a string.\n\ 2844On some platforms, path may also be specified as an open file descriptor.\n\ 2845 If this functionality is unavailable, using it raises an exception."); 2846 2847static PyObject * 2848posix_chdir(PyObject *self, PyObject *args, PyObject *kwargs) 2849{ 2850 path_t path; 2851 int result; 2852 PyObject *return_value = NULL; 2853 static char *keywords[] = {"path", NULL}; 2854 2855 memset(&path, 0, sizeof(path)); 2856 path.function_name = "chdir"; 2857#ifdef HAVE_FCHDIR 2858 path.allow_fd = 1; 2859#endif 2860 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:chdir", keywords, 2861 path_converter, &path 2862 )) 2863 return NULL; 2864 2865 Py_BEGIN_ALLOW_THREADS 2866#ifdef MS_WINDOWS 2867 if (path.wide) 2868 result = win32_wchdir(path.wide); 2869 else 2870 result = win32_chdir(path.narrow); 2871 result = !result; /* on unix, success = 0, on windows, success = !0 */ 2872#else 2873#ifdef HAVE_FCHDIR 2874 if (path.fd != -1) 2875 result = fchdir(path.fd); 2876 else 2877#endif 2878 result = chdir(path.narrow); 2879#endif 2880 Py_END_ALLOW_THREADS 2881 2882 if (result) { 2883 return_value = path_error(&path); 2884 goto exit; 2885 } 2886 2887 return_value = Py_None; 2888 Py_INCREF(Py_None); 2889 2890exit: 2891 path_cleanup(&path); 2892 return return_value; 2893} 2894 2895#ifdef HAVE_FCHDIR 2896PyDoc_STRVAR(posix_fchdir__doc__, 2897"fchdir(fd)\n\n\ 2898Change to the directory of the given file descriptor. fd must be\n\ 2899opened on a directory, not a file. Equivalent to os.chdir(fd)."); 2900 2901static PyObject * 2902posix_fchdir(PyObject *self, PyObject *fdobj) 2903{ 2904 return posix_fildes(fdobj, fchdir); 2905} 2906#endif /* HAVE_FCHDIR */ 2907 2908 2909PyDoc_STRVAR(posix_chmod__doc__, 2910"chmod(path, mode, *, dir_fd=None, follow_symlinks=True)\n\n\ 2911Change the access permissions of a file.\n\ 2912\n\ 2913path may always be specified as a string.\n\ 2914On some platforms, path may also be specified as an open file descriptor.\n\ 2915 If this functionality is unavailable, using it raises an exception.\n\ 2916If dir_fd is not None, it should be a file descriptor open to a directory,\n\ 2917 and path should be relative; path will then be relative to that directory.\n\ 2918If follow_symlinks is False, and the last element of the path is a symbolic\n\ 2919 link, chmod will modify the symbolic link itself instead of the file the\n\ 2920 link points to.\n\ 2921It is an error to use dir_fd or follow_symlinks when specifying path as\n\ 2922 an open file descriptor.\n\ 2923dir_fd and follow_symlinks may not be implemented on your platform.\n\ 2924 If they are unavailable, using them will raise a NotImplementedError."); 2925 2926static PyObject * 2927posix_chmod(PyObject *self, PyObject *args, PyObject *kwargs) 2928{ 2929 path_t path; 2930 int mode; 2931 int dir_fd = DEFAULT_DIR_FD; 2932 int follow_symlinks = 1; 2933 int result; 2934 PyObject *return_value = NULL; 2935 static char *keywords[] = {"path", "mode", "dir_fd", 2936 "follow_symlinks", NULL}; 2937 2938#ifdef MS_WINDOWS 2939 DWORD attr; 2940#endif 2941 2942#ifdef HAVE_FCHMODAT 2943 int fchmodat_nofollow_unsupported = 0; 2944#endif 2945 2946 memset(&path, 0, sizeof(path)); 2947 path.function_name = "chmod"; 2948#ifdef HAVE_FCHMOD 2949 path.allow_fd = 1; 2950#endif 2951 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|$O&p:chmod", keywords, 2952 path_converter, &path, 2953 &mode, 2954#ifdef HAVE_FCHMODAT 2955 dir_fd_converter, &dir_fd, 2956#else 2957 dir_fd_unavailable, &dir_fd, 2958#endif 2959 &follow_symlinks)) 2960 return NULL; 2961 2962#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD)) 2963 if (follow_symlinks_specified("chmod", follow_symlinks)) 2964 goto exit; 2965#endif 2966 2967#ifdef MS_WINDOWS 2968 Py_BEGIN_ALLOW_THREADS 2969 if (path.wide) 2970 attr = GetFileAttributesW(path.wide); 2971 else 2972 attr = GetFileAttributesA(path.narrow); 2973 if (attr == INVALID_FILE_ATTRIBUTES) 2974 result = 0; 2975 else { 2976 if (mode & _S_IWRITE) 2977 attr &= ~FILE_ATTRIBUTE_READONLY; 2978 else 2979 attr |= FILE_ATTRIBUTE_READONLY; 2980 if (path.wide) 2981 result = SetFileAttributesW(path.wide, attr); 2982 else 2983 result = SetFileAttributesA(path.narrow, attr); 2984 } 2985 Py_END_ALLOW_THREADS 2986 2987 if (!result) { 2988 return_value = path_error(&path); 2989 goto exit; 2990 } 2991#else /* MS_WINDOWS */ 2992 Py_BEGIN_ALLOW_THREADS 2993#ifdef HAVE_FCHMOD 2994 if (path.fd != -1) 2995 result = fchmod(path.fd, mode); 2996 else 2997#endif 2998#ifdef HAVE_LCHMOD 2999 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD)) 3000 result = lchmod(path.narrow, mode); 3001 else 3002#endif 3003#ifdef HAVE_FCHMODAT 3004 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) { 3005 /* 3006 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW! 3007 * The documentation specifically shows how to use it, 3008 * and then says it isn't implemented yet. 3009 * (true on linux with glibc 2.15, and openindiana 3.x) 3010 * 3011 * Once it is supported, os.chmod will automatically 3012 * support dir_fd and follow_symlinks=False. (Hopefully.) 3013 * Until then, we need to be careful what exception we raise. 3014 */ 3015 result = fchmodat(dir_fd, path.narrow, mode, 3016 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW); 3017 /* 3018 * But wait! We can't throw the exception without allowing threads, 3019 * and we can't do that in this nested scope. (Macro trickery, sigh.) 3020 */ 3021 fchmodat_nofollow_unsupported = 3022 result && 3023 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) && 3024 !follow_symlinks; 3025 } 3026 else 3027#endif 3028 result = chmod(path.narrow, mode); 3029 Py_END_ALLOW_THREADS 3030 3031 if (result) { 3032#ifdef HAVE_FCHMODAT 3033 if (fchmodat_nofollow_unsupported) { 3034 if (dir_fd != DEFAULT_DIR_FD) 3035 dir_fd_and_follow_symlinks_invalid("chmod", 3036 dir_fd, follow_symlinks); 3037 else 3038 follow_symlinks_specified("chmod", follow_symlinks); 3039 } 3040 else 3041#endif 3042 return_value = path_error(&path); 3043 goto exit; 3044 } 3045#endif 3046 3047 Py_INCREF(Py_None); 3048 return_value = Py_None; 3049exit: 3050 path_cleanup(&path); 3051 return return_value; 3052} 3053 3054 3055#ifdef HAVE_FCHMOD 3056PyDoc_STRVAR(posix_fchmod__doc__, 3057"fchmod(fd, mode)\n\n\ 3058Change the access permissions of the file given by file\n\ 3059descriptor fd. Equivalent to os.chmod(fd, mode)."); 3060 3061static PyObject * 3062posix_fchmod(PyObject *self, PyObject *args) 3063{ 3064 int fd, mode, res; 3065 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode)) 3066 return NULL; 3067 Py_BEGIN_ALLOW_THREADS 3068 res = fchmod(fd, mode); 3069 Py_END_ALLOW_THREADS 3070 if (res < 0) 3071 return posix_error(); 3072 Py_RETURN_NONE; 3073} 3074#endif /* HAVE_FCHMOD */ 3075 3076#ifdef HAVE_LCHMOD 3077PyDoc_STRVAR(posix_lchmod__doc__, 3078"lchmod(path, mode)\n\n\ 3079Change the access permissions of a file. If path is a symlink, this\n\ 3080affects the link itself rather than the target.\n\ 3081Equivalent to chmod(path, mode, follow_symlinks=False)."); 3082 3083static PyObject * 3084posix_lchmod(PyObject *self, PyObject *args) 3085{ 3086 path_t path; 3087 int i; 3088 int res; 3089 memset(&path, 0, sizeof(path)); 3090 path.function_name = "lchmod"; 3091 if (!PyArg_ParseTuple(args, "O&i:lchmod", 3092 path_converter, &path, &i)) 3093 return NULL; 3094 Py_BEGIN_ALLOW_THREADS 3095 res = lchmod(path.narrow, i); 3096 Py_END_ALLOW_THREADS 3097 if (res < 0) { 3098 path_error(&path); 3099 path_cleanup(&path); 3100 return NULL; 3101 } 3102 path_cleanup(&path); 3103 Py_RETURN_NONE; 3104} 3105#endif /* HAVE_LCHMOD */ 3106 3107 3108#ifdef HAVE_CHFLAGS 3109PyDoc_STRVAR(posix_chflags__doc__, 3110"chflags(path, flags, *, follow_symlinks=True)\n\n\ 3111Set file flags.\n\ 3112\n\ 3113If follow_symlinks is False, and the last element of the path is a symbolic\n\ 3114 link, chflags will change flags on the symbolic link itself instead of the\n\ 3115 file the link points to.\n\ 3116follow_symlinks may not be implemented on your platform. If it is\n\ 3117unavailable, using it will raise a NotImplementedError."); 3118 3119static PyObject * 3120posix_chflags(PyObject *self, PyObject *args, PyObject *kwargs) 3121{ 3122 path_t path; 3123 unsigned long flags; 3124 int follow_symlinks = 1; 3125 int result; 3126 PyObject *return_value = NULL; 3127 static char *keywords[] = {"path", "flags", "follow_symlinks", NULL}; 3128 3129 memset(&path, 0, sizeof(path)); 3130 path.function_name = "chflags"; 3131 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&k|$i:chflags", keywords, 3132 path_converter, &path, 3133 &flags, &follow_symlinks)) 3134 return NULL; 3135 3136#ifndef HAVE_LCHFLAGS 3137 if (follow_symlinks_specified("chflags", follow_symlinks)) 3138 goto exit; 3139#endif 3140 3141 Py_BEGIN_ALLOW_THREADS 3142#ifdef HAVE_LCHFLAGS 3143 if (!follow_symlinks) 3144 result = lchflags(path.narrow, flags); 3145 else 3146#endif 3147 result = chflags(path.narrow, flags); 3148 Py_END_ALLOW_THREADS 3149 3150 if (result) { 3151 return_value = path_error(&path); 3152 goto exit; 3153 } 3154 3155 return_value = Py_None; 3156 Py_INCREF(Py_None); 3157 3158exit: 3159 path_cleanup(&path); 3160 return return_value; 3161} 3162#endif /* HAVE_CHFLAGS */ 3163 3164#ifdef HAVE_LCHFLAGS 3165PyDoc_STRVAR(posix_lchflags__doc__, 3166"lchflags(path, flags)\n\n\ 3167Set file flags.\n\ 3168This function will not follow symbolic links.\n\ 3169Equivalent to chflags(path, flags, follow_symlinks=False)."); 3170 3171static PyObject * 3172posix_lchflags(PyObject *self, PyObject *args) 3173{ 3174 path_t path; 3175 unsigned long flags; 3176 int res; 3177 memset(&path, 0, sizeof(path)); 3178 path.function_name = "lchflags"; 3179 if (!PyArg_ParseTuple(args, "O&k:lchflags", 3180 path_converter, &path, &flags)) 3181 return NULL; 3182 Py_BEGIN_ALLOW_THREADS 3183 res = lchflags(path.narrow, flags); 3184 Py_END_ALLOW_THREADS 3185 if (res < 0) { 3186 path_error(&path); 3187 path_cleanup(&path); 3188 return NULL; 3189 } 3190 path_cleanup(&path); 3191 Py_RETURN_NONE; 3192} 3193#endif /* HAVE_LCHFLAGS */ 3194 3195#ifdef HAVE_CHROOT 3196PyDoc_STRVAR(posix_chroot__doc__, 3197"chroot(path)\n\n\ 3198Change root directory to path."); 3199 3200static PyObject * 3201posix_chroot(PyObject *self, PyObject *args) 3202{ 3203 return posix_1str("chroot", args, "O&:chroot", chroot); 3204} 3205#endif 3206 3207#ifdef HAVE_FSYNC 3208PyDoc_STRVAR(posix_fsync__doc__, 3209"fsync(fildes)\n\n\ 3210force write of file with filedescriptor to disk."); 3211 3212static PyObject * 3213posix_fsync(PyObject *self, PyObject *fdobj) 3214{ 3215 return posix_fildes(fdobj, fsync); 3216} 3217#endif /* HAVE_FSYNC */ 3218 3219#ifdef HAVE_SYNC 3220PyDoc_STRVAR(posix_sync__doc__, 3221"sync()\n\n\ 3222Force write of everything to disk."); 3223 3224static PyObject * 3225posix_sync(PyObject *self, PyObject *noargs) 3226{ 3227 Py_BEGIN_ALLOW_THREADS 3228 sync(); 3229 Py_END_ALLOW_THREADS 3230 Py_RETURN_NONE; 3231} 3232#endif 3233 3234#ifdef HAVE_FDATASYNC 3235 3236#ifdef __hpux 3237extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */ 3238#endif 3239 3240PyDoc_STRVAR(posix_fdatasync__doc__, 3241"fdatasync(fildes)\n\n\ 3242force write of file with filedescriptor to disk.\n\ 3243 does not force update of metadata."); 3244 3245static PyObject * 3246posix_fdatasync(PyObject *self, PyObject *fdobj) 3247{ 3248 return posix_fildes(fdobj, fdatasync); 3249} 3250#endif /* HAVE_FDATASYNC */ 3251 3252 3253#ifdef HAVE_CHOWN 3254PyDoc_STRVAR(posix_chown__doc__, 3255"chown(path, uid, gid, *, dir_fd=None, follow_symlinks=True)\n\n\ 3256Change the owner and group id of path to the numeric uid and gid.\n\ 3257\n\ 3258path may always be specified as a string.\n\ 3259On some platforms, path may also be specified as an open file descriptor.\n\ 3260 If this functionality is unavailable, using it raises an exception.\n\ 3261If dir_fd is not None, it should be a file descriptor open to a directory,\n\ 3262 and path should be relative; path will then be relative to that directory.\n\ 3263If follow_symlinks is False, and the last element of the path is a symbolic\n\ 3264 link, chown will modify the symbolic link itself instead of the file the\n\ 3265 link points to.\n\ 3266It is an error to use dir_fd or follow_symlinks when specifying path as\n\ 3267 an open file descriptor.\n\ 3268dir_fd and follow_symlinks may not be implemented on your platform.\n\ 3269 If they are unavailable, using them will raise a NotImplementedError."); 3270 3271static PyObject * 3272posix_chown(PyObject *self, PyObject *args, PyObject *kwargs) 3273{ 3274 path_t path; 3275 uid_t uid; 3276 gid_t gid; 3277 int dir_fd = DEFAULT_DIR_FD; 3278 int follow_symlinks = 1; 3279 int result; 3280 PyObject *return_value = NULL; 3281 static char *keywords[] = {"path", "uid", "gid", "dir_fd", 3282 "follow_symlinks", NULL}; 3283 3284 memset(&path, 0, sizeof(path)); 3285 path.function_name = "chown"; 3286#ifdef HAVE_FCHOWN 3287 path.allow_fd = 1; 3288#endif 3289 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&O&|$O&p:chown", keywords, 3290 path_converter, &path, 3291 _Py_Uid_Converter, &uid, 3292 _Py_Gid_Converter, &gid, 3293#ifdef HAVE_FCHOWNAT 3294 dir_fd_converter, &dir_fd, 3295#else 3296 dir_fd_unavailable, &dir_fd, 3297#endif 3298 &follow_symlinks)) 3299 return NULL; 3300 3301#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT)) 3302 if (follow_symlinks_specified("chown", follow_symlinks)) 3303 goto exit; 3304#endif 3305 if (dir_fd_and_fd_invalid("chown", dir_fd, path.fd) || 3306 fd_and_follow_symlinks_invalid("chown", path.fd, follow_symlinks)) 3307 goto exit; 3308 3309#ifdef __APPLE__ 3310 /* 3311 * This is for Mac OS X 10.3, which doesn't have lchown. 3312 * (But we still have an lchown symbol because of weak-linking.) 3313 * It doesn't have fchownat either. So there's no possibility 3314 * of a graceful failover. 3315 */ 3316 if ((!follow_symlinks) && (lchown == NULL)) { 3317 follow_symlinks_specified("chown", follow_symlinks); 3318 goto exit; 3319 } 3320#endif 3321 3322 Py_BEGIN_ALLOW_THREADS 3323#ifdef HAVE_FCHOWN 3324 if (path.fd != -1) 3325 result = fchown(path.fd, uid, gid); 3326 else 3327#endif 3328#ifdef HAVE_LCHOWN 3329 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD)) 3330 result = lchown(path.narrow, uid, gid); 3331 else 3332#endif 3333#ifdef HAVE_FCHOWNAT 3334 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks)) 3335 result = fchownat(dir_fd, path.narrow, uid, gid, 3336 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW); 3337 else 3338#endif 3339 result = chown(path.narrow, uid, gid); 3340 Py_END_ALLOW_THREADS 3341 3342 if (result) { 3343 return_value = path_error(&path); 3344 goto exit; 3345 } 3346 3347 return_value = Py_None; 3348 Py_INCREF(Py_None); 3349 3350exit: 3351 path_cleanup(&path); 3352 return return_value; 3353} 3354#endif /* HAVE_CHOWN */ 3355 3356#ifdef HAVE_FCHOWN 3357PyDoc_STRVAR(posix_fchown__doc__, 3358"fchown(fd, uid, gid)\n\n\ 3359Change the owner and group id of the file given by file descriptor\n\ 3360fd to the numeric uid and gid. Equivalent to os.chown(fd, uid, gid)."); 3361 3362static PyObject * 3363posix_fchown(PyObject *self, PyObject *args) 3364{ 3365 int fd; 3366 uid_t uid; 3367 gid_t gid; 3368 int res; 3369 if (!PyArg_ParseTuple(args, "iO&O&:fchown", &fd, 3370 _Py_Uid_Converter, &uid, 3371 _Py_Gid_Converter, &gid)) 3372 return NULL; 3373 Py_BEGIN_ALLOW_THREADS 3374 res = fchown(fd, uid, gid); 3375 Py_END_ALLOW_THREADS 3376 if (res < 0) 3377 return posix_error(); 3378 Py_RETURN_NONE; 3379} 3380#endif /* HAVE_FCHOWN */ 3381 3382#ifdef HAVE_LCHOWN 3383PyDoc_STRVAR(posix_lchown__doc__, 3384"lchown(path, uid, gid)\n\n\ 3385Change the owner and group id of path to the numeric uid and gid.\n\ 3386This function will not follow symbolic links.\n\ 3387Equivalent to os.chown(path, uid, gid, follow_symlinks=False)."); 3388 3389static PyObject * 3390posix_lchown(PyObject *self, PyObject *args) 3391{ 3392 path_t path; 3393 uid_t uid; 3394 gid_t gid; 3395 int res; 3396 memset(&path, 0, sizeof(path)); 3397 path.function_name = "lchown"; 3398 if (!PyArg_ParseTuple(args, "O&O&O&:lchown", 3399 path_converter, &path, 3400 _Py_Uid_Converter, &uid, 3401 _Py_Gid_Converter, &gid)) 3402 return NULL; 3403 Py_BEGIN_ALLOW_THREADS 3404 res = lchown(path.narrow, uid, gid); 3405 Py_END_ALLOW_THREADS 3406 if (res < 0) { 3407 path_error(&path); 3408 path_cleanup(&path); 3409 return NULL; 3410 } 3411 path_cleanup(&path); 3412 Py_INCREF(Py_None); 3413 return Py_None; 3414} 3415#endif /* HAVE_LCHOWN */ 3416 3417 3418static PyObject * 3419posix_getcwd(int use_bytes) 3420{ 3421 char *buf, *tmpbuf; 3422 char *cwd; 3423 const size_t chunk = 1024; 3424 size_t buflen = 0; 3425 PyObject *obj; 3426 3427#ifdef MS_WINDOWS 3428 if (!use_bytes) { 3429 wchar_t wbuf[MAXPATHLEN]; 3430 wchar_t *wbuf2 = wbuf; 3431 PyObject *resobj; 3432 DWORD len; 3433 Py_BEGIN_ALLOW_THREADS 3434 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf); 3435 /* If the buffer is large enough, len does not include the 3436 terminating \0. If the buffer is too small, len includes 3437 the space needed for the terminator. */ 3438 if (len >= Py_ARRAY_LENGTH(wbuf)) { 3439 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t)); 3440 if (wbuf2) 3441 len = GetCurrentDirectoryW(len, wbuf2); 3442 } 3443 Py_END_ALLOW_THREADS 3444 if (!wbuf2) { 3445 PyErr_NoMemory(); 3446 return NULL; 3447 } 3448 if (!len) { 3449 if (wbuf2 != wbuf) 3450 PyMem_RawFree(wbuf2); 3451 return PyErr_SetFromWindowsErr(0); 3452 } 3453 resobj = PyUnicode_FromWideChar(wbuf2, len); 3454 if (wbuf2 != wbuf) 3455 PyMem_RawFree(wbuf2); 3456 return resobj; 3457 } 3458 3459 if (win32_warn_bytes_api()) 3460 return NULL; 3461#endif 3462 3463 buf = cwd = NULL; 3464 Py_BEGIN_ALLOW_THREADS 3465 do { 3466 buflen += chunk; 3467 tmpbuf = PyMem_RawRealloc(buf, buflen); 3468 if (tmpbuf == NULL) 3469 break; 3470 3471 buf = tmpbuf; 3472 cwd = getcwd(buf, buflen); 3473 } while (cwd == NULL && errno == ERANGE); 3474 Py_END_ALLOW_THREADS 3475 3476 if (cwd == NULL) { 3477 PyMem_RawFree(buf); 3478 return posix_error(); 3479 } 3480 3481 if (use_bytes) 3482 obj = PyBytes_FromStringAndSize(buf, strlen(buf)); 3483 else 3484 obj = PyUnicode_DecodeFSDefault(buf); 3485 PyMem_RawFree(buf); 3486 3487 return obj; 3488} 3489 3490PyDoc_STRVAR(posix_getcwd__doc__, 3491"getcwd() -> path\n\n\ 3492Return a unicode string representing the current working directory."); 3493 3494static PyObject * 3495posix_getcwd_unicode(PyObject *self) 3496{ 3497 return posix_getcwd(0); 3498} 3499 3500PyDoc_STRVAR(posix_getcwdb__doc__, 3501"getcwdb() -> path\n\n\ 3502Return a bytes string representing the current working directory."); 3503 3504static PyObject * 3505posix_getcwd_bytes(PyObject *self) 3506{ 3507 return posix_getcwd(1); 3508} 3509 3510#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS)) 3511#define HAVE_LINK 1 3512#endif 3513 3514#ifdef HAVE_LINK 3515PyDoc_STRVAR(posix_link__doc__, 3516"link(src, dst, *, src_dir_fd=None, dst_dir_fd=None, follow_symlinks=True)\n\n\ 3517Create a hard link to a file.\n\ 3518\n\ 3519If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\ 3520 descriptor open to a directory, and the respective path string (src or dst)\n\ 3521 should be relative; the path will then be relative to that directory.\n\ 3522If follow_symlinks is False, and the last element of src is a symbolic\n\ 3523 link, link will create a link to the symbolic link itself instead of the\n\ 3524 file the link points to.\n\ 3525src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your\n\ 3526 platform. If they are unavailable, using them will raise a\n\ 3527 NotImplementedError."); 3528 3529static PyObject * 3530posix_link(PyObject *self, PyObject *args, PyObject *kwargs) 3531{ 3532 path_t src, dst; 3533 int src_dir_fd = DEFAULT_DIR_FD; 3534 int dst_dir_fd = DEFAULT_DIR_FD; 3535 int follow_symlinks = 1; 3536 PyObject *return_value = NULL; 3537 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", 3538 "follow_symlinks", NULL}; 3539#ifdef MS_WINDOWS 3540 BOOL result; 3541#else 3542 int result; 3543#endif 3544 3545 memset(&src, 0, sizeof(src)); 3546 memset(&dst, 0, sizeof(dst)); 3547 src.function_name = "link"; 3548 dst.function_name = "link"; 3549 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|O&O&p:link", keywords, 3550 path_converter, &src, 3551 path_converter, &dst, 3552 dir_fd_converter, &src_dir_fd, 3553 dir_fd_converter, &dst_dir_fd, 3554 &follow_symlinks)) 3555 return NULL; 3556 3557#ifndef HAVE_LINKAT 3558 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) { 3559 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd"); 3560 goto exit; 3561 } 3562#endif 3563 3564 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) { 3565 PyErr_SetString(PyExc_NotImplementedError, 3566 "link: src and dst must be the same type"); 3567 goto exit; 3568 } 3569 3570#ifdef MS_WINDOWS 3571 Py_BEGIN_ALLOW_THREADS 3572 if (src.wide) 3573 result = CreateHardLinkW(dst.wide, src.wide, NULL); 3574 else 3575 result = CreateHardLinkA(dst.narrow, src.narrow, NULL); 3576 Py_END_ALLOW_THREADS 3577 3578 if (!result) { 3579 return_value = path_error2(&src, &dst); 3580 goto exit; 3581 } 3582#else 3583 Py_BEGIN_ALLOW_THREADS 3584#ifdef HAVE_LINKAT 3585 if ((src_dir_fd != DEFAULT_DIR_FD) || 3586 (dst_dir_fd != DEFAULT_DIR_FD) || 3587 (!follow_symlinks)) 3588 result = linkat(src_dir_fd, src.narrow, 3589 dst_dir_fd, dst.narrow, 3590 follow_symlinks ? AT_SYMLINK_FOLLOW : 0); 3591 else 3592#endif 3593 result = link(src.narrow, dst.narrow); 3594 Py_END_ALLOW_THREADS 3595 3596 if (result) { 3597 return_value = path_error2(&src, &dst); 3598 goto exit; 3599 } 3600#endif 3601 3602 return_value = Py_None; 3603 Py_INCREF(Py_None); 3604 3605exit: 3606 path_cleanup(&src); 3607 path_cleanup(&dst); 3608 return return_value; 3609} 3610#endif 3611 3612 3613 3614PyDoc_STRVAR(posix_listdir__doc__, 3615"listdir(path='.') -> list_of_filenames\n\n\ 3616Return a list containing the names of the files in the directory.\n\ 3617The list is in arbitrary order. It does not include the special\n\ 3618entries '.' and '..' even if they are present in the directory.\n\ 3619\n\ 3620path can be specified as either str or bytes. If path is bytes,\n\ 3621 the filenames returned will also be bytes; in all other circumstances\n\ 3622 the filenames returned will be str.\n\ 3623On some platforms, path may also be specified as an open file descriptor;\n\ 3624 the file descriptor must refer to a directory.\n\ 3625 If this functionality is unavailable, using it raises NotImplementedError."); 3626 3627#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR) 3628static PyObject * 3629_listdir_windows_no_opendir(path_t *path, PyObject *list) 3630{ 3631 static char *keywords[] = {"path", NULL}; 3632 PyObject *v; 3633 HANDLE hFindFile = INVALID_HANDLE_VALUE; 3634 BOOL result; 3635 WIN32_FIND_DATA FileData; 3636 char namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */ 3637 char *bufptr = namebuf; 3638 /* only claim to have space for MAX_PATH */ 3639 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4; 3640 PyObject *po = NULL; 3641 wchar_t *wnamebuf = NULL; 3642 3643 if (!path->narrow) { 3644 WIN32_FIND_DATAW wFileData; 3645 wchar_t *po_wchars; 3646 3647 if (!path->wide) { /* Default arg: "." */ 3648 po_wchars = L"."; 3649 len = 1; 3650 } else { 3651 po_wchars = path->wide; 3652 len = wcslen(path->wide); 3653 } 3654 /* The +5 is so we can append "\\*.*\0" */ 3655 wnamebuf = PyMem_New(wchar_t, len + 5); 3656 if (!wnamebuf) { 3657 PyErr_NoMemory(); 3658 goto exit; 3659 } 3660 wcscpy(wnamebuf, po_wchars); 3661 if (len > 0) { 3662 wchar_t wch = wnamebuf[len-1]; 3663 if (wch != SEP && wch != ALTSEP && wch != L':') 3664 wnamebuf[len++] = SEP; 3665 wcscpy(wnamebuf + len, L"*.*"); 3666 } 3667 if ((list = PyList_New(0)) == NULL) { 3668 goto exit; 3669 } 3670 Py_BEGIN_ALLOW_THREADS 3671 hFindFile = FindFirstFileW(wnamebuf, &wFileData); 3672 Py_END_ALLOW_THREADS 3673 if (hFindFile == INVALID_HANDLE_VALUE) { 3674 int error = GetLastError(); 3675 if (error == ERROR_FILE_NOT_FOUND) 3676 goto exit; 3677 Py_DECREF(list); 3678 list = path_error(path); 3679 goto exit; 3680 } 3681 do { 3682 /* Skip over . and .. */ 3683 if (wcscmp(wFileData.cFileName, L".") != 0 && 3684 wcscmp(wFileData.cFileName, L"..") != 0) { 3685 v = PyUnicode_FromWideChar(wFileData.cFileName, 3686 wcslen(wFileData.cFileName)); 3687 if (v == NULL) { 3688 Py_DECREF(list); 3689 list = NULL; 3690 break; 3691 } 3692 if (PyList_Append(list, v) != 0) { 3693 Py_DECREF(v); 3694 Py_DECREF(list); 3695 list = NULL; 3696 break; 3697 } 3698 Py_DECREF(v); 3699 } 3700 Py_BEGIN_ALLOW_THREADS 3701 result = FindNextFileW(hFindFile, &wFileData); 3702 Py_END_ALLOW_THREADS 3703 /* FindNextFile sets error to ERROR_NO_MORE_FILES if 3704 it got to the end of the directory. */ 3705 if (!result && GetLastError() != ERROR_NO_MORE_FILES) { 3706 Py_DECREF(list); 3707 list = path_error(path); 3708 goto exit; 3709 } 3710 } while (result == TRUE); 3711 3712 goto exit; 3713 } 3714 strcpy(namebuf, path->narrow); 3715 len = path->length; 3716 if (len > 0) { 3717 char ch = namebuf[len-1]; 3718 if (ch != '\\' && ch != '/' && ch != ':') 3719 namebuf[len++] = '\\'; 3720 strcpy(namebuf + len, "*.*"); 3721 } 3722 3723 if ((list = PyList_New(0)) == NULL) 3724 return NULL; 3725 3726 Py_BEGIN_ALLOW_THREADS 3727 hFindFile = FindFirstFile(namebuf, &FileData); 3728 Py_END_ALLOW_THREADS 3729 if (hFindFile == INVALID_HANDLE_VALUE) { 3730 int error = GetLastError(); 3731 if (error == ERROR_FILE_NOT_FOUND) 3732 goto exit; 3733 Py_DECREF(list); 3734 list = path_error(path); 3735 goto exit; 3736 } 3737 do { 3738 /* Skip over . and .. */ 3739 if (strcmp(FileData.cFileName, ".") != 0 && 3740 strcmp(FileData.cFileName, "..") != 0) { 3741 v = PyBytes_FromString(FileData.cFileName); 3742 if (v == NULL) { 3743 Py_DECREF(list); 3744 list = NULL; 3745 break; 3746 } 3747 if (PyList_Append(list, v) != 0) { 3748 Py_DECREF(v); 3749 Py_DECREF(list); 3750 list = NULL; 3751 break; 3752 } 3753 Py_DECREF(v); 3754 } 3755 Py_BEGIN_ALLOW_THREADS 3756 result = FindNextFile(hFindFile, &FileData); 3757 Py_END_ALLOW_THREADS 3758 /* FindNextFile sets error to ERROR_NO_MORE_FILES if 3759 it got to the end of the directory. */ 3760 if (!result && GetLastError() != ERROR_NO_MORE_FILES) { 3761 Py_DECREF(list); 3762 list = path_error(path); 3763 goto exit; 3764 } 3765 } while (result == TRUE); 3766 3767exit: 3768 if (hFindFile != INVALID_HANDLE_VALUE) { 3769 if (FindClose(hFindFile) == FALSE) { 3770 if (list != NULL) { 3771 Py_DECREF(list); 3772 list = path_error(path); 3773 } 3774 } 3775 } 3776 PyMem_Free(wnamebuf); 3777 3778 return list; 3779} /* end of _listdir_windows_no_opendir */ 3780 3781#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */ 3782 3783static PyObject * 3784_posix_listdir(path_t *path, PyObject *list) 3785{ 3786 PyObject *v; 3787 DIR *dirp = NULL; 3788 struct dirent *ep; 3789 int return_str; /* if false, return bytes */ 3790#ifdef HAVE_FDOPENDIR 3791 int fd = -1; 3792#endif 3793 3794 errno = 0; 3795#ifdef HAVE_FDOPENDIR 3796 if (path->fd != -1) { 3797 /* closedir() closes the FD, so we duplicate it */ 3798 fd = _Py_dup(path->fd); 3799 if (fd == -1) 3800 return NULL; 3801 3802 return_str = 1; 3803 3804 Py_BEGIN_ALLOW_THREADS 3805 dirp = fdopendir(fd); 3806 Py_END_ALLOW_THREADS 3807 } 3808 else 3809#endif 3810 { 3811 char *name; 3812 if (path->narrow) { 3813 name = path->narrow; 3814 /* only return bytes if they specified a bytes object */ 3815 return_str = !(PyBytes_Check(path->object)); 3816 } 3817 else { 3818 name = "."; 3819 return_str = 1; 3820 } 3821 3822 Py_BEGIN_ALLOW_THREADS 3823 dirp = opendir(name); 3824 Py_END_ALLOW_THREADS 3825 } 3826 3827 if (dirp == NULL) { 3828 list = path_error(path); 3829#ifdef HAVE_FDOPENDIR 3830 if (fd != -1) { 3831 Py_BEGIN_ALLOW_THREADS 3832 close(fd); 3833 Py_END_ALLOW_THREADS 3834 } 3835#endif 3836 goto exit; 3837 } 3838 if ((list = PyList_New(0)) == NULL) { 3839 goto exit; 3840 } 3841 for (;;) { 3842 errno = 0; 3843 Py_BEGIN_ALLOW_THREADS 3844 ep = readdir(dirp); 3845 Py_END_ALLOW_THREADS 3846 if (ep == NULL) { 3847 if (errno == 0) { 3848 break; 3849 } else { 3850 Py_DECREF(list); 3851 list = path_error(path); 3852 goto exit; 3853 } 3854 } 3855 if (ep->d_name[0] == '.' && 3856 (NAMLEN(ep) == 1 || 3857 (ep->d_name[1] == '.' && NAMLEN(ep) == 2))) 3858 continue; 3859 if (return_str) 3860 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep)); 3861 else 3862 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep)); 3863 if (v == NULL) { 3864 Py_CLEAR(list); 3865 break; 3866 } 3867 if (PyList_Append(list, v) != 0) { 3868 Py_DECREF(v); 3869 Py_CLEAR(list); 3870 break; 3871 } 3872 Py_DECREF(v); 3873 } 3874 3875exit: 3876 if (dirp != NULL) { 3877 Py_BEGIN_ALLOW_THREADS 3878#ifdef HAVE_FDOPENDIR 3879 if (fd > -1) 3880 rewinddir(dirp); 3881#endif 3882 closedir(dirp); 3883 Py_END_ALLOW_THREADS 3884 } 3885 3886 return list; 3887} /* end of _posix_listdir */ 3888#endif /* which OS */ 3889 3890static PyObject * 3891posix_listdir(PyObject *self, PyObject *args, PyObject *kwargs) 3892{ 3893 path_t path; 3894 PyObject *list = NULL; 3895 static char *keywords[] = {"path", NULL}; 3896 PyObject *return_value; 3897 3898 memset(&path, 0, sizeof(path)); 3899 path.function_name = "listdir"; 3900 path.nullable = 1; 3901#ifdef HAVE_FDOPENDIR 3902 path.allow_fd = 1; 3903 path.fd = -1; 3904#endif 3905 3906 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:listdir", keywords, 3907 path_converter, &path)) { 3908 return NULL; 3909 } 3910 3911#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR) 3912 return_value = _listdir_windows_no_opendir(&path, list); 3913#else 3914 return_value = _posix_listdir(&path, list); 3915#endif 3916 path_cleanup(&path); 3917 return return_value; 3918} 3919 3920#ifdef MS_WINDOWS 3921/* A helper function for abspath on win32 */ 3922static PyObject * 3923posix__getfullpathname(PyObject *self, PyObject *args) 3924{ 3925 const char *path; 3926 char outbuf[MAX_PATH]; 3927 char *temp; 3928 PyObject *po; 3929 3930 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) 3931 { 3932 wchar_t *wpath; 3933 wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf; 3934 wchar_t *wtemp; 3935 DWORD result; 3936 PyObject *v; 3937 3938 wpath = PyUnicode_AsUnicode(po); 3939 if (wpath == NULL) 3940 return NULL; 3941 result = GetFullPathNameW(wpath, 3942 Py_ARRAY_LENGTH(woutbuf), 3943 woutbuf, &wtemp); 3944 if (result > Py_ARRAY_LENGTH(woutbuf)) { 3945 woutbufp = PyMem_New(wchar_t, result); 3946 if (!woutbufp) 3947 return PyErr_NoMemory(); 3948 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp); 3949 } 3950 if (result) 3951 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp)); 3952 else 3953 v = win32_error_object("GetFullPathNameW", po); 3954 if (woutbufp != woutbuf) 3955 PyMem_Free(woutbufp); 3956 return v; 3957 } 3958 /* Drop the argument parsing error as narrow strings 3959 are also valid. */ 3960 PyErr_Clear(); 3961 3962 if (!PyArg_ParseTuple (args, "y:_getfullpathname", 3963 &path)) 3964 return NULL; 3965 if (win32_warn_bytes_api()) 3966 return NULL; 3967 if (!GetFullPathName(path, Py_ARRAY_LENGTH(outbuf), 3968 outbuf, &temp)) { 3969 win32_error("GetFullPathName", path); 3970 return NULL; 3971 } 3972 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) { 3973 return PyUnicode_Decode(outbuf, strlen(outbuf), 3974 Py_FileSystemDefaultEncoding, NULL); 3975 } 3976 return PyBytes_FromString(outbuf); 3977} /* end of posix__getfullpathname */ 3978 3979 3980 3981/* A helper function for samepath on windows */ 3982static PyObject * 3983posix__getfinalpathname(PyObject *self, PyObject *args) 3984{ 3985 HANDLE hFile; 3986 int buf_size; 3987 wchar_t *target_path; 3988 int result_length; 3989 PyObject *po, *result; 3990 wchar_t *path; 3991 3992 if (!PyArg_ParseTuple(args, "U|:_getfinalpathname", &po)) 3993 return NULL; 3994 path = PyUnicode_AsUnicode(po); 3995 if (path == NULL) 3996 return NULL; 3997 3998 if(!check_GetFinalPathNameByHandle()) { 3999 /* If the OS doesn't have GetFinalPathNameByHandle, return a 4000 NotImplementedError. */ 4001 return PyErr_Format(PyExc_NotImplementedError, 4002 "GetFinalPathNameByHandle not available on this platform"); 4003 } 4004 4005 hFile = CreateFileW( 4006 path, 4007 0, /* desired access */ 4008 0, /* share mode */ 4009 NULL, /* security attributes */ 4010 OPEN_EXISTING, 4011 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */ 4012 FILE_FLAG_BACKUP_SEMANTICS, 4013 NULL); 4014 4015 if(hFile == INVALID_HANDLE_VALUE) 4016 return win32_error_object("CreateFileW", po); 4017 4018 /* We have a good handle to the target, use it to determine the 4019 target path name. */ 4020 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT); 4021 4022 if(!buf_size) 4023 return win32_error_object("GetFinalPathNameByHandle", po); 4024 4025 target_path = PyMem_New(wchar_t, buf_size+1); 4026 if(!target_path) 4027 return PyErr_NoMemory(); 4028 4029 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path, 4030 buf_size, VOLUME_NAME_DOS); 4031 if(!result_length) 4032 return win32_error_object("GetFinalPathNamyByHandle", po); 4033 4034 if(!CloseHandle(hFile)) 4035 return win32_error_object("CloseHandle", po); 4036 4037 target_path[result_length] = 0; 4038 result = PyUnicode_FromWideChar(target_path, result_length); 4039 PyMem_Free(target_path); 4040 return result; 4041 4042} /* end of posix__getfinalpathname */ 4043 4044PyDoc_STRVAR(posix__isdir__doc__, 4045"Return true if the pathname refers to an existing directory."); 4046 4047static PyObject * 4048posix__isdir(PyObject *self, PyObject *args) 4049{ 4050 const char *path; 4051 PyObject *po; 4052 DWORD attributes; 4053 4054 if (PyArg_ParseTuple(args, "U|:_isdir", &po)) { 4055 wchar_t *wpath = PyUnicode_AsUnicode(po); 4056 if (wpath == NULL) 4057 return NULL; 4058 4059 attributes = GetFileAttributesW(wpath); 4060 if (attributes == INVALID_FILE_ATTRIBUTES) 4061 Py_RETURN_FALSE; 4062 goto check; 4063 } 4064 /* Drop the argument parsing error as narrow strings 4065 are also valid. */ 4066 PyErr_Clear(); 4067 4068 if (!PyArg_ParseTuple(args, "y:_isdir", &path)) 4069 return NULL; 4070 if (win32_warn_bytes_api()) 4071 return NULL; 4072 attributes = GetFileAttributesA(path); 4073 if (attributes == INVALID_FILE_ATTRIBUTES) 4074 Py_RETURN_FALSE; 4075 4076check: 4077 if (attributes & FILE_ATTRIBUTE_DIRECTORY) 4078 Py_RETURN_TRUE; 4079 else 4080 Py_RETURN_FALSE; 4081} 4082 4083PyDoc_STRVAR(posix__getvolumepathname__doc__, 4084"Return volume mount point of the specified path."); 4085 4086/* A helper function for ismount on windows */ 4087static PyObject * 4088posix__getvolumepathname(PyObject *self, PyObject *args) 4089{ 4090 PyObject *po, *result; 4091 wchar_t *path, *mountpath=NULL; 4092 size_t buflen; 4093 BOOL ret; 4094 4095 if (!PyArg_ParseTuple(args, "U|:_getvolumepathname", &po)) 4096 return NULL; 4097 path = PyUnicode_AsUnicodeAndSize(po, &buflen); 4098 if (path == NULL) 4099 return NULL; 4100 buflen += 1; 4101 4102 /* Volume path should be shorter than entire path */ 4103 buflen = Py_MAX(buflen, MAX_PATH); 4104 4105 if (buflen > DWORD_MAX) { 4106 PyErr_SetString(PyExc_OverflowError, "path too long"); 4107 return NULL; 4108 } 4109 4110 mountpath = PyMem_New(wchar_t, buflen); 4111 if (mountpath == NULL) 4112 return PyErr_NoMemory(); 4113 4114 Py_BEGIN_ALLOW_THREADS 4115 ret = GetVolumePathNameW(path, mountpath, 4116 Py_SAFE_DOWNCAST(buflen, size_t, DWORD)); 4117 Py_END_ALLOW_THREADS 4118 4119 if (!ret) { 4120 result = win32_error_object("_getvolumepathname", po); 4121 goto exit; 4122 } 4123 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath)); 4124 4125exit: 4126 PyMem_Free(mountpath); 4127 return result; 4128} 4129/* end of posix__getvolumepathname */ 4130 4131#endif /* MS_WINDOWS */ 4132 4133PyDoc_STRVAR(posix_mkdir__doc__, 4134"mkdir(path, mode=0o777, *, dir_fd=None)\n\n\ 4135Create a directory.\n\ 4136\n\ 4137If dir_fd is not None, it should be a file descriptor open to a directory,\n\ 4138 and path should be relative; path will then be relative to that directory.\n\ 4139dir_fd may not be implemented on your platform.\n\ 4140 If it is unavailable, using it will raise a NotImplementedError.\n\ 4141\n\ 4142The mode argument is ignored on Windows."); 4143 4144static PyObject * 4145posix_mkdir(PyObject *self, PyObject *args, PyObject *kwargs) 4146{ 4147 path_t path; 4148 int mode = 0777; 4149 int dir_fd = DEFAULT_DIR_FD; 4150 static char *keywords[] = {"path", "mode", "dir_fd", NULL}; 4151 PyObject *return_value = NULL; 4152 int result; 4153 4154 memset(&path, 0, sizeof(path)); 4155 path.function_name = "mkdir"; 4156 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkdir", keywords, 4157 path_converter, &path, &mode, 4158#ifdef HAVE_MKDIRAT 4159 dir_fd_converter, &dir_fd 4160#else 4161 dir_fd_unavailable, &dir_fd 4162#endif 4163 )) 4164 return NULL; 4165 4166#ifdef MS_WINDOWS 4167 Py_BEGIN_ALLOW_THREADS 4168 if (path.wide) 4169 result = CreateDirectoryW(path.wide, NULL); 4170 else 4171 result = CreateDirectoryA(path.narrow, NULL); 4172 Py_END_ALLOW_THREADS 4173 4174 if (!result) { 4175 return_value = path_error(&path); 4176 goto exit; 4177 } 4178#else 4179 Py_BEGIN_ALLOW_THREADS 4180#if HAVE_MKDIRAT 4181 if (dir_fd != DEFAULT_DIR_FD) 4182 result = mkdirat(dir_fd, path.narrow, mode); 4183 else 4184#endif 4185#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__) 4186 result = mkdir(path.narrow); 4187#else 4188 result = mkdir(path.narrow, mode); 4189#endif 4190 Py_END_ALLOW_THREADS 4191 if (result < 0) { 4192 return_value = path_error(&path); 4193 goto exit; 4194 } 4195#endif 4196 return_value = Py_None; 4197 Py_INCREF(Py_None); 4198exit: 4199 path_cleanup(&path); 4200 return return_value; 4201} 4202 4203 4204/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */ 4205#if defined(HAVE_SYS_RESOURCE_H) 4206#include <sys/resource.h> 4207#endif 4208 4209 4210#ifdef HAVE_NICE 4211PyDoc_STRVAR(posix_nice__doc__, 4212"nice(inc) -> new_priority\n\n\ 4213Decrease the priority of process by inc and return the new priority."); 4214 4215static PyObject * 4216posix_nice(PyObject *self, PyObject *args) 4217{ 4218 int increment, value; 4219 4220 if (!PyArg_ParseTuple(args, "i:nice", &increment)) 4221 return NULL; 4222 4223 /* There are two flavours of 'nice': one that returns the new 4224 priority (as required by almost all standards out there) and the 4225 Linux/FreeBSD/BSDI one, which returns '0' on success and advices 4226 the use of getpriority() to get the new priority. 4227 4228 If we are of the nice family that returns the new priority, we 4229 need to clear errno before the call, and check if errno is filled 4230 before calling posix_error() on a returnvalue of -1, because the 4231 -1 may be the actual new priority! */ 4232 4233 errno = 0; 4234 value = nice(increment); 4235#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY) 4236 if (value == 0) 4237 value = getpriority(PRIO_PROCESS, 0); 4238#endif 4239 if (value == -1 && errno != 0) 4240 /* either nice() or getpriority() returned an error */ 4241 return posix_error(); 4242 return PyLong_FromLong((long) value); 4243} 4244#endif /* HAVE_NICE */ 4245 4246 4247#ifdef HAVE_GETPRIORITY 4248PyDoc_STRVAR(posix_getpriority__doc__, 4249"getpriority(which, who) -> current_priority\n\n\ 4250Get program scheduling priority."); 4251 4252static PyObject * 4253posix_getpriority(PyObject *self, PyObject *args) 4254{ 4255 int which, who, retval; 4256 4257 if (!PyArg_ParseTuple(args, "ii", &which, &who)) 4258 return NULL; 4259 errno = 0; 4260 retval = getpriority(which, who); 4261 if (errno != 0) 4262 return posix_error(); 4263 return PyLong_FromLong((long)retval); 4264} 4265#endif /* HAVE_GETPRIORITY */ 4266 4267 4268#ifdef HAVE_SETPRIORITY 4269PyDoc_STRVAR(posix_setpriority__doc__, 4270"setpriority(which, who, prio) -> None\n\n\ 4271Set program scheduling priority."); 4272 4273static PyObject * 4274posix_setpriority(PyObject *self, PyObject *args) 4275{ 4276 int which, who, prio, retval; 4277 4278 if (!PyArg_ParseTuple(args, "iii", &which, &who, &prio)) 4279 return NULL; 4280 retval = setpriority(which, who, prio); 4281 if (retval == -1) 4282 return posix_error(); 4283 Py_RETURN_NONE; 4284} 4285#endif /* HAVE_SETPRIORITY */ 4286 4287 4288static PyObject * 4289internal_rename(PyObject *args, PyObject *kwargs, int is_replace) 4290{ 4291 char *function_name = is_replace ? "replace" : "rename"; 4292 path_t src; 4293 path_t dst; 4294 int src_dir_fd = DEFAULT_DIR_FD; 4295 int dst_dir_fd = DEFAULT_DIR_FD; 4296 int dir_fd_specified; 4297 PyObject *return_value = NULL; 4298 char format[24]; 4299 static char *keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL}; 4300 4301#ifdef MS_WINDOWS 4302 BOOL result; 4303 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0; 4304#else 4305 int result; 4306#endif 4307 4308 memset(&src, 0, sizeof(src)); 4309 memset(&dst, 0, sizeof(dst)); 4310 src.function_name = function_name; 4311 dst.function_name = function_name; 4312 strcpy(format, "O&O&|$O&O&:"); 4313 strcat(format, function_name); 4314 if (!PyArg_ParseTupleAndKeywords(args, kwargs, format, keywords, 4315 path_converter, &src, 4316 path_converter, &dst, 4317 dir_fd_converter, &src_dir_fd, 4318 dir_fd_converter, &dst_dir_fd)) 4319 return NULL; 4320 4321 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) || 4322 (dst_dir_fd != DEFAULT_DIR_FD); 4323#ifndef HAVE_RENAMEAT 4324 if (dir_fd_specified) { 4325 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd"); 4326 goto exit; 4327 } 4328#endif 4329 4330 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) { 4331 PyErr_Format(PyExc_ValueError, 4332 "%s: src and dst must be the same type", function_name); 4333 goto exit; 4334 } 4335 4336#ifdef MS_WINDOWS 4337 Py_BEGIN_ALLOW_THREADS 4338 if (src.wide) 4339 result = MoveFileExW(src.wide, dst.wide, flags); 4340 else 4341 result = MoveFileExA(src.narrow, dst.narrow, flags); 4342 Py_END_ALLOW_THREADS 4343 4344 if (!result) { 4345 return_value = path_error2(&src, &dst); 4346 goto exit; 4347 } 4348 4349#else 4350 Py_BEGIN_ALLOW_THREADS 4351#ifdef HAVE_RENAMEAT 4352 if (dir_fd_specified) 4353 result = renameat(src_dir_fd, src.narrow, dst_dir_fd, dst.narrow); 4354 else 4355#endif 4356 result = rename(src.narrow, dst.narrow); 4357 Py_END_ALLOW_THREADS 4358 4359 if (result) { 4360 return_value = path_error2(&src, &dst); 4361 goto exit; 4362 } 4363#endif 4364 4365 Py_INCREF(Py_None); 4366 return_value = Py_None; 4367exit: 4368 path_cleanup(&src); 4369 path_cleanup(&dst); 4370 return return_value; 4371} 4372 4373PyDoc_STRVAR(posix_rename__doc__, 4374"rename(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\ 4375Rename a file or directory.\n\ 4376\n\ 4377If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\ 4378 descriptor open to a directory, and the respective path string (src or dst)\n\ 4379 should be relative; the path will then be relative to that directory.\n\ 4380src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\ 4381 If they are unavailable, using them will raise a NotImplementedError."); 4382 4383static PyObject * 4384posix_rename(PyObject *self, PyObject *args, PyObject *kwargs) 4385{ 4386 return internal_rename(args, kwargs, 0); 4387} 4388 4389PyDoc_STRVAR(posix_replace__doc__, 4390"replace(src, dst, *, src_dir_fd=None, dst_dir_fd=None)\n\n\ 4391Rename a file or directory, overwriting the destination.\n\ 4392\n\ 4393If either src_dir_fd or dst_dir_fd is not None, it should be a file\n\ 4394 descriptor open to a directory, and the respective path string (src or dst)\n\ 4395 should be relative; the path will then be relative to that directory.\n\ 4396src_dir_fd and dst_dir_fd, may not be implemented on your platform.\n\ 4397 If they are unavailable, using them will raise a NotImplementedError."); 4398 4399static PyObject * 4400posix_replace(PyObject *self, PyObject *args, PyObject *kwargs) 4401{ 4402 return internal_rename(args, kwargs, 1); 4403} 4404 4405PyDoc_STRVAR(posix_rmdir__doc__, 4406"rmdir(path, *, dir_fd=None)\n\n\ 4407Remove a directory.\n\ 4408\n\ 4409If dir_fd is not None, it should be a file descriptor open to a directory,\n\ 4410 and path should be relative; path will then be relative to that directory.\n\ 4411dir_fd may not be implemented on your platform.\n\ 4412 If it is unavailable, using it will raise a NotImplementedError."); 4413 4414static PyObject * 4415posix_rmdir(PyObject *self, PyObject *args, PyObject *kwargs) 4416{ 4417 path_t path; 4418 int dir_fd = DEFAULT_DIR_FD; 4419 static char *keywords[] = {"path", "dir_fd", NULL}; 4420 int result; 4421 PyObject *return_value = NULL; 4422 4423 memset(&path, 0, sizeof(path)); 4424 path.function_name = "rmdir"; 4425 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:rmdir", keywords, 4426 path_converter, &path, 4427#ifdef HAVE_UNLINKAT 4428 dir_fd_converter, &dir_fd 4429#else 4430 dir_fd_unavailable, &dir_fd 4431#endif 4432 )) 4433 return NULL; 4434 4435 Py_BEGIN_ALLOW_THREADS 4436#ifdef MS_WINDOWS 4437 if (path.wide) 4438 result = RemoveDirectoryW(path.wide); 4439 else 4440 result = RemoveDirectoryA(path.narrow); 4441 result = !result; /* Windows, success=1, UNIX, success=0 */ 4442#else 4443#ifdef HAVE_UNLINKAT 4444 if (dir_fd != DEFAULT_DIR_FD) 4445 result = unlinkat(dir_fd, path.narrow, AT_REMOVEDIR); 4446 else 4447#endif 4448 result = rmdir(path.narrow); 4449#endif 4450 Py_END_ALLOW_THREADS 4451 4452 if (result) { 4453 return_value = path_error(&path); 4454 goto exit; 4455 } 4456 4457 return_value = Py_None; 4458 Py_INCREF(Py_None); 4459 4460exit: 4461 path_cleanup(&path); 4462 return return_value; 4463} 4464 4465 4466#ifdef HAVE_SYSTEM 4467PyDoc_STRVAR(posix_system__doc__, 4468"system(command) -> exit_status\n\n\ 4469Execute the command (a string) in a subshell."); 4470 4471static PyObject * 4472posix_system(PyObject *self, PyObject *args) 4473{ 4474 long sts; 4475#ifdef MS_WINDOWS 4476 wchar_t *command; 4477 if (!PyArg_ParseTuple(args, "u:system", &command)) 4478 return NULL; 4479 4480 Py_BEGIN_ALLOW_THREADS 4481 sts = _wsystem(command); 4482 Py_END_ALLOW_THREADS 4483#else 4484 PyObject *command_obj; 4485 char *command; 4486 if (!PyArg_ParseTuple(args, "O&:system", 4487 PyUnicode_FSConverter, &command_obj)) 4488 return NULL; 4489 4490 command = PyBytes_AsString(command_obj); 4491 Py_BEGIN_ALLOW_THREADS 4492 sts = system(command); 4493 Py_END_ALLOW_THREADS 4494 Py_DECREF(command_obj); 4495#endif 4496 return PyLong_FromLong(sts); 4497} 4498#endif 4499 4500 4501PyDoc_STRVAR(posix_umask__doc__, 4502"umask(new_mask) -> old_mask\n\n\ 4503Set the current numeric umask and return the previous umask."); 4504 4505static PyObject * 4506posix_umask(PyObject *self, PyObject *args) 4507{ 4508 int i; 4509 if (!PyArg_ParseTuple(args, "i:umask", &i)) 4510 return NULL; 4511 i = (int)umask(i); 4512 if (i < 0) 4513 return posix_error(); 4514 return PyLong_FromLong((long)i); 4515} 4516 4517#ifdef MS_WINDOWS 4518 4519/* override the default DeleteFileW behavior so that directory 4520symlinks can be removed with this function, the same as with 4521Unix symlinks */ 4522BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName) 4523{ 4524 WIN32_FILE_ATTRIBUTE_DATA info; 4525 WIN32_FIND_DATAW find_data; 4526 HANDLE find_data_handle; 4527 int is_directory = 0; 4528 int is_link = 0; 4529 4530 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) { 4531 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY; 4532 4533 /* Get WIN32_FIND_DATA structure for the path to determine if 4534 it is a symlink */ 4535 if(is_directory && 4536 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { 4537 find_data_handle = FindFirstFileW(lpFileName, &find_data); 4538 4539 if(find_data_handle != INVALID_HANDLE_VALUE) { 4540 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK; 4541 FindClose(find_data_handle); 4542 } 4543 } 4544 } 4545 4546 if (is_directory && is_link) 4547 return RemoveDirectoryW(lpFileName); 4548 4549 return DeleteFileW(lpFileName); 4550} 4551#endif /* MS_WINDOWS */ 4552 4553PyDoc_STRVAR(posix_unlink__doc__, 4554"unlink(path, *, dir_fd=None)\n\n\ 4555Remove a file (same as remove()).\n\ 4556\n\ 4557If dir_fd is not None, it should be a file descriptor open to a directory,\n\ 4558 and path should be relative; path will then be relative to that directory.\n\ 4559dir_fd may not be implemented on your platform.\n\ 4560 If it is unavailable, using it will raise a NotImplementedError."); 4561 4562PyDoc_STRVAR(posix_remove__doc__, 4563"remove(path, *, dir_fd=None)\n\n\ 4564Remove a file (same as unlink()).\n\ 4565\n\ 4566If dir_fd is not None, it should be a file descriptor open to a directory,\n\ 4567 and path should be relative; path will then be relative to that directory.\n\ 4568dir_fd may not be implemented on your platform.\n\ 4569 If it is unavailable, using it will raise a NotImplementedError."); 4570 4571static PyObject * 4572posix_unlink(PyObject *self, PyObject *args, PyObject *kwargs) 4573{ 4574 path_t path; 4575 int dir_fd = DEFAULT_DIR_FD; 4576 static char *keywords[] = {"path", "dir_fd", NULL}; 4577 int result; 4578 PyObject *return_value = NULL; 4579 4580 memset(&path, 0, sizeof(path)); 4581 path.function_name = "unlink"; 4582 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:unlink", keywords, 4583 path_converter, &path, 4584#ifdef HAVE_UNLINKAT 4585 dir_fd_converter, &dir_fd 4586#else 4587 dir_fd_unavailable, &dir_fd 4588#endif 4589 )) 4590 return NULL; 4591 4592 Py_BEGIN_ALLOW_THREADS 4593#ifdef MS_WINDOWS 4594 if (path.wide) 4595 result = Py_DeleteFileW(path.wide); 4596 else 4597 result = DeleteFileA(path.narrow); 4598 result = !result; /* Windows, success=1, UNIX, success=0 */ 4599#else 4600#ifdef HAVE_UNLINKAT 4601 if (dir_fd != DEFAULT_DIR_FD) 4602 result = unlinkat(dir_fd, path.narrow, 0); 4603 else 4604#endif /* HAVE_UNLINKAT */ 4605 result = unlink(path.narrow); 4606#endif 4607 Py_END_ALLOW_THREADS 4608 4609 if (result) { 4610 return_value = path_error(&path); 4611 goto exit; 4612 } 4613 4614 return_value = Py_None; 4615 Py_INCREF(Py_None); 4616 4617exit: 4618 path_cleanup(&path); 4619 return return_value; 4620} 4621 4622 4623PyDoc_STRVAR(posix_uname__doc__, 4624"uname() -> uname_result\n\n\ 4625Return an object identifying the current operating system.\n\ 4626The object behaves like a named tuple with the following fields:\n\ 4627 (sysname, nodename, release, version, machine)"); 4628 4629static PyStructSequence_Field uname_result_fields[] = { 4630 {"sysname", "operating system name"}, 4631 {"nodename", "name of machine on network (implementation-defined)"}, 4632 {"release", "operating system release"}, 4633 {"version", "operating system version"}, 4634 {"machine", "hardware identifier"}, 4635 {NULL} 4636}; 4637 4638PyDoc_STRVAR(uname_result__doc__, 4639"uname_result: Result from os.uname().\n\n\ 4640This object may be accessed either as a tuple of\n\ 4641 (sysname, nodename, release, version, machine),\n\ 4642or via the attributes sysname, nodename, release, version, and machine.\n\ 4643\n\ 4644See os.uname for more information."); 4645 4646static PyStructSequence_Desc uname_result_desc = { 4647 "uname_result", /* name */ 4648 uname_result__doc__, /* doc */ 4649 uname_result_fields, 4650 5 4651}; 4652 4653static PyTypeObject UnameResultType; 4654 4655 4656#ifdef HAVE_UNAME 4657static PyObject * 4658posix_uname(PyObject *self, PyObject *noargs) 4659{ 4660 struct utsname u; 4661 int res; 4662 PyObject *value; 4663 4664 Py_BEGIN_ALLOW_THREADS 4665 res = uname(&u); 4666 Py_END_ALLOW_THREADS 4667 if (res < 0) 4668 return posix_error(); 4669 4670 value = PyStructSequence_New(&UnameResultType); 4671 if (value == NULL) 4672 return NULL; 4673 4674#define SET(i, field) \ 4675 { \ 4676 PyObject *o = PyUnicode_DecodeFSDefault(field); \ 4677 if (!o) { \ 4678 Py_DECREF(value); \ 4679 return NULL; \ 4680 } \ 4681 PyStructSequence_SET_ITEM(value, i, o); \ 4682 } \ 4683 4684 SET(0, u.sysname); 4685 SET(1, u.nodename); 4686 SET(2, u.release); 4687 SET(3, u.version); 4688 SET(4, u.machine); 4689 4690#undef SET 4691 4692 return value; 4693} 4694#endif /* HAVE_UNAME */ 4695 4696 4697PyDoc_STRVAR(posix_utime__doc__, 4698"utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\ 4699Set the access and modified time of path.\n\ 4700\n\ 4701path may always be specified as a string.\n\ 4702On some platforms, path may also be specified as an open file descriptor.\n\ 4703 If this functionality is unavailable, using it raises an exception.\n\ 4704\n\ 4705If times is not None, it must be a tuple (atime, mtime);\n\ 4706 atime and mtime should be expressed as float seconds since the epoch.\n\ 4707If ns is specified, it must be a tuple (atime_ns, mtime_ns);\n\ 4708 atime_ns and mtime_ns should be expressed as integer nanoseconds\n\ 4709 since the epoch.\n\ 4710If times is None and ns is unspecified, utime uses the current time.\n\ 4711Specifying tuples for both times and ns is an error.\n\ 4712\n\ 4713If dir_fd is not None, it should be a file descriptor open to a directory,\n\ 4714 and path should be relative; path will then be relative to that directory.\n\ 4715If follow_symlinks is False, and the last element of the path is a symbolic\n\ 4716 link, utime will modify the symbolic link itself instead of the file the\n\ 4717 link points to.\n\ 4718It is an error to use dir_fd or follow_symlinks when specifying path\n\ 4719 as an open file descriptor.\n\ 4720dir_fd and follow_symlinks may not be available on your platform.\n\ 4721 If they are unavailable, using them will raise a NotImplementedError."); 4722 4723typedef struct { 4724 int now; 4725 time_t atime_s; 4726 long atime_ns; 4727 time_t mtime_s; 4728 long mtime_ns; 4729} utime_t; 4730 4731/* 4732 * these macros assume that "ut" is a pointer to a utime_t 4733 * they also intentionally leak the declaration of a pointer named "time" 4734 */ 4735#define UTIME_TO_TIMESPEC \ 4736 struct timespec ts[2]; \ 4737 struct timespec *time; \ 4738 if (ut->now) \ 4739 time = NULL; \ 4740 else { \ 4741 ts[0].tv_sec = ut->atime_s; \ 4742 ts[0].tv_nsec = ut->atime_ns; \ 4743 ts[1].tv_sec = ut->mtime_s; \ 4744 ts[1].tv_nsec = ut->mtime_ns; \ 4745 time = ts; \ 4746 } \ 4747 4748#define UTIME_TO_TIMEVAL \ 4749 struct timeval tv[2]; \ 4750 struct timeval *time; \ 4751 if (ut->now) \ 4752 time = NULL; \ 4753 else { \ 4754 tv[0].tv_sec = ut->atime_s; \ 4755 tv[0].tv_usec = ut->atime_ns / 1000; \ 4756 tv[1].tv_sec = ut->mtime_s; \ 4757 tv[1].tv_usec = ut->mtime_ns / 1000; \ 4758 time = tv; \ 4759 } \ 4760 4761#define UTIME_TO_UTIMBUF \ 4762 struct utimbuf u; \ 4763 struct utimbuf *time; \ 4764 if (ut->now) \ 4765 time = NULL; \ 4766 else { \ 4767 u.actime = ut->atime_s; \ 4768 u.modtime = ut->mtime_s; \ 4769 time = &u; \ 4770 } 4771 4772#define UTIME_TO_TIME_T \ 4773 time_t timet[2]; \ 4774 time_t *time; \ 4775 if (ut->now) \ 4776 time = NULL; \ 4777 else { \ 4778 timet[0] = ut->atime_s; \ 4779 timet[1] = ut->mtime_s; \ 4780 time = timet; \ 4781 } \ 4782 4783 4784#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT) 4785 4786static int 4787utime_dir_fd(utime_t *ut, int dir_fd, char *path, int follow_symlinks) 4788{ 4789#ifdef HAVE_UTIMENSAT 4790 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW; 4791 UTIME_TO_TIMESPEC; 4792 return utimensat(dir_fd, path, time, flags); 4793#elif defined(HAVE_FUTIMESAT) 4794 UTIME_TO_TIMEVAL; 4795 /* 4796 * follow_symlinks will never be false here; 4797 * we only allow !follow_symlinks and dir_fd together 4798 * if we have utimensat() 4799 */ 4800 assert(follow_symlinks); 4801 return futimesat(dir_fd, path, time); 4802#endif 4803} 4804 4805#endif 4806 4807#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS) 4808 4809static int 4810utime_fd(utime_t *ut, int fd) 4811{ 4812#ifdef HAVE_FUTIMENS 4813 UTIME_TO_TIMESPEC; 4814 return futimens(fd, time); 4815#else 4816 UTIME_TO_TIMEVAL; 4817 return futimes(fd, time); 4818#endif 4819} 4820 4821#endif 4822 4823 4824#define UTIME_HAVE_NOFOLLOW_SYMLINKS \ 4825 (defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES)) 4826 4827#if UTIME_HAVE_NOFOLLOW_SYMLINKS 4828 4829static int 4830utime_nofollow_symlinks(utime_t *ut, char *path) 4831{ 4832#ifdef HAVE_UTIMENSAT 4833 UTIME_TO_TIMESPEC; 4834 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW); 4835#else 4836 UTIME_TO_TIMEVAL; 4837 return lutimes(path, time); 4838#endif 4839} 4840 4841#endif 4842 4843#ifndef MS_WINDOWS 4844 4845static int 4846utime_default(utime_t *ut, char *path) 4847{ 4848#ifdef HAVE_UTIMENSAT 4849 UTIME_TO_TIMESPEC; 4850 return utimensat(DEFAULT_DIR_FD, path, time, 0); 4851#elif defined(HAVE_UTIMES) 4852 UTIME_TO_TIMEVAL; 4853 return utimes(path, time); 4854#elif defined(HAVE_UTIME_H) 4855 UTIME_TO_UTIMBUF; 4856 return utime(path, time); 4857#else 4858 UTIME_TO_TIME_T; 4859 return utime(path, time); 4860#endif 4861} 4862 4863#endif 4864 4865static int 4866split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns) 4867{ 4868 int result = 0; 4869 PyObject *divmod; 4870 divmod = PyNumber_Divmod(py_long, billion); 4871 if (!divmod) 4872 goto exit; 4873 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0)); 4874 if ((*s == -1) && PyErr_Occurred()) 4875 goto exit; 4876 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1)); 4877 if ((*ns == -1) && PyErr_Occurred()) 4878 goto exit; 4879 4880 result = 1; 4881exit: 4882 Py_XDECREF(divmod); 4883 return result; 4884} 4885 4886static PyObject * 4887posix_utime(PyObject *self, PyObject *args, PyObject *kwargs) 4888{ 4889 path_t path; 4890 PyObject *times = NULL; 4891 PyObject *ns = NULL; 4892 int dir_fd = DEFAULT_DIR_FD; 4893 int follow_symlinks = 1; 4894 char *keywords[] = {"path", "times", "ns", "dir_fd", 4895 "follow_symlinks", NULL}; 4896 4897 utime_t utime; 4898 4899#ifdef MS_WINDOWS 4900 HANDLE hFile; 4901 FILETIME atime, mtime; 4902#else 4903 int result; 4904#endif 4905 4906 PyObject *return_value = NULL; 4907 4908 memset(&path, 0, sizeof(path)); 4909 path.function_name = "utime"; 4910 memset(&utime, 0, sizeof(utime_t)); 4911#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS) 4912 path.allow_fd = 1; 4913#endif 4914 if (!PyArg_ParseTupleAndKeywords(args, kwargs, 4915 "O&|O$OO&p:utime", keywords, 4916 path_converter, &path, 4917 ×, &ns, 4918#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT) 4919 dir_fd_converter, &dir_fd, 4920#else 4921 dir_fd_unavailable, &dir_fd, 4922#endif 4923 &follow_symlinks 4924 )) 4925 return NULL; 4926 4927 if (times && (times != Py_None) && ns) { 4928 PyErr_SetString(PyExc_ValueError, 4929 "utime: you may specify either 'times'" 4930 " or 'ns' but not both"); 4931 goto exit; 4932 } 4933 4934 if (times && (times != Py_None)) { 4935 time_t a_sec, m_sec; 4936 long a_nsec, m_nsec; 4937 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) { 4938 PyErr_SetString(PyExc_TypeError, 4939 "utime: 'times' must be either" 4940 " a tuple of two ints or None"); 4941 goto exit; 4942 } 4943 utime.now = 0; 4944 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0), 4945 &a_sec, &a_nsec, _PyTime_ROUND_DOWN) == -1 || 4946 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1), 4947 &m_sec, &m_nsec, _PyTime_ROUND_DOWN) == -1) { 4948 goto exit; 4949 } 4950 utime.atime_s = a_sec; 4951 utime.atime_ns = a_nsec; 4952 utime.mtime_s = m_sec; 4953 utime.mtime_ns = m_nsec; 4954 } 4955 else if (ns) { 4956 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) { 4957 PyErr_SetString(PyExc_TypeError, 4958 "utime: 'ns' must be a tuple of two ints"); 4959 goto exit; 4960 } 4961 utime.now = 0; 4962 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0), 4963 &utime.atime_s, &utime.atime_ns) || 4964 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1), 4965 &utime.mtime_s, &utime.mtime_ns)) { 4966 goto exit; 4967 } 4968 } 4969 else { 4970 /* times and ns are both None/unspecified. use "now". */ 4971 utime.now = 1; 4972 } 4973 4974#if !UTIME_HAVE_NOFOLLOW_SYMLINKS 4975 if (follow_symlinks_specified("utime", follow_symlinks)) 4976 goto exit; 4977#endif 4978 4979 if (path_and_dir_fd_invalid("utime", &path, dir_fd) || 4980 dir_fd_and_fd_invalid("utime", dir_fd, path.fd) || 4981 fd_and_follow_symlinks_invalid("utime", path.fd, follow_symlinks)) 4982 goto exit; 4983 4984#if !defined(HAVE_UTIMENSAT) 4985 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) { 4986 PyErr_SetString(PyExc_ValueError, 4987 "utime: cannot use dir_fd and follow_symlinks " 4988 "together on this platform"); 4989 goto exit; 4990 } 4991#endif 4992 4993#ifdef MS_WINDOWS 4994 Py_BEGIN_ALLOW_THREADS 4995 if (path.wide) 4996 hFile = CreateFileW(path.wide, FILE_WRITE_ATTRIBUTES, 0, 4997 NULL, OPEN_EXISTING, 4998 FILE_FLAG_BACKUP_SEMANTICS, NULL); 4999 else 5000 hFile = CreateFileA(path.narrow, FILE_WRITE_ATTRIBUTES, 0, 5001 NULL, OPEN_EXISTING, 5002 FILE_FLAG_BACKUP_SEMANTICS, NULL); 5003 Py_END_ALLOW_THREADS 5004 if (hFile == INVALID_HANDLE_VALUE) { 5005 path_error(&path); 5006 goto exit; 5007 } 5008 5009 if (utime.now) { 5010 GetSystemTimeAsFileTime(&mtime); 5011 atime = mtime; 5012 } 5013 else { 5014 time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime); 5015 time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime); 5016 } 5017 if (!SetFileTime(hFile, NULL, &atime, &mtime)) { 5018 /* Avoid putting the file name into the error here, 5019 as that may confuse the user into believing that 5020 something is wrong with the file, when it also 5021 could be the time stamp that gives a problem. */ 5022 PyErr_SetFromWindowsErr(0); 5023 goto exit; 5024 } 5025#else /* MS_WINDOWS */ 5026 Py_BEGIN_ALLOW_THREADS 5027 5028#if UTIME_HAVE_NOFOLLOW_SYMLINKS 5029 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD)) 5030 result = utime_nofollow_symlinks(&utime, path.narrow); 5031 else 5032#endif 5033 5034#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT) 5035 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks)) 5036 result = utime_dir_fd(&utime, dir_fd, path.narrow, follow_symlinks); 5037 else 5038#endif 5039 5040#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS) 5041 if (path.fd != -1) 5042 result = utime_fd(&utime, path.fd); 5043 else 5044#endif 5045 5046 result = utime_default(&utime, path.narrow); 5047 5048 Py_END_ALLOW_THREADS 5049 5050 if (result < 0) { 5051 /* see previous comment about not putting filename in error here */ 5052 return_value = posix_error(); 5053 goto exit; 5054 } 5055 5056#endif /* MS_WINDOWS */ 5057 5058 Py_INCREF(Py_None); 5059 return_value = Py_None; 5060 5061exit: 5062 path_cleanup(&path); 5063#ifdef MS_WINDOWS 5064 if (hFile != INVALID_HANDLE_VALUE) 5065 CloseHandle(hFile); 5066#endif 5067 return return_value; 5068} 5069 5070/* Process operations */ 5071 5072PyDoc_STRVAR(posix__exit__doc__, 5073"_exit(status)\n\n\ 5074Exit to the system with specified status, without normal exit processing."); 5075 5076static PyObject * 5077posix__exit(PyObject *self, PyObject *args) 5078{ 5079 int sts; 5080 if (!PyArg_ParseTuple(args, "i:_exit", &sts)) 5081 return NULL; 5082 _exit(sts); 5083 return NULL; /* Make gcc -Wall happy */ 5084} 5085 5086#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV) 5087static void 5088free_string_array(char **array, Py_ssize_t count) 5089{ 5090 Py_ssize_t i; 5091 for (i = 0; i < count; i++) 5092 PyMem_Free(array[i]); 5093 PyMem_DEL(array); 5094} 5095 5096static 5097int fsconvert_strdup(PyObject *o, char**out) 5098{ 5099 PyObject *bytes; 5100 Py_ssize_t size; 5101 if (!PyUnicode_FSConverter(o, &bytes)) 5102 return 0; 5103 size = PyBytes_GET_SIZE(bytes); 5104 *out = PyMem_Malloc(size+1); 5105 if (!*out) { 5106 PyErr_NoMemory(); 5107 return 0; 5108 } 5109 memcpy(*out, PyBytes_AsString(bytes), size+1); 5110 Py_DECREF(bytes); 5111 return 1; 5112} 5113#endif 5114 5115#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE) 5116static char** 5117parse_envlist(PyObject* env, Py_ssize_t *envc_ptr) 5118{ 5119 char **envlist; 5120 Py_ssize_t i, pos, envc; 5121 PyObject *keys=NULL, *vals=NULL; 5122 PyObject *key, *val, *key2, *val2; 5123 char *p, *k, *v; 5124 size_t len; 5125 5126 i = PyMapping_Size(env); 5127 if (i < 0) 5128 return NULL; 5129 envlist = PyMem_NEW(char *, i + 1); 5130 if (envlist == NULL) { 5131 PyErr_NoMemory(); 5132 return NULL; 5133 } 5134 envc = 0; 5135 keys = PyMapping_Keys(env); 5136 if (!keys) 5137 goto error; 5138 vals = PyMapping_Values(env); 5139 if (!vals) 5140 goto error; 5141 if (!PyList_Check(keys) || !PyList_Check(vals)) { 5142 PyErr_Format(PyExc_TypeError, 5143 "env.keys() or env.values() is not a list"); 5144 goto error; 5145 } 5146 5147 for (pos = 0; pos < i; pos++) { 5148 key = PyList_GetItem(keys, pos); 5149 val = PyList_GetItem(vals, pos); 5150 if (!key || !val) 5151 goto error; 5152 5153 if (PyUnicode_FSConverter(key, &key2) == 0) 5154 goto error; 5155 if (PyUnicode_FSConverter(val, &val2) == 0) { 5156 Py_DECREF(key2); 5157 goto error; 5158 } 5159 5160 k = PyBytes_AsString(key2); 5161 v = PyBytes_AsString(val2); 5162 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2; 5163 5164 p = PyMem_NEW(char, len); 5165 if (p == NULL) { 5166 PyErr_NoMemory(); 5167 Py_DECREF(key2); 5168 Py_DECREF(val2); 5169 goto error; 5170 } 5171 PyOS_snprintf(p, len, "%s=%s", k, v); 5172 envlist[envc++] = p; 5173 Py_DECREF(key2); 5174 Py_DECREF(val2); 5175 } 5176 Py_DECREF(vals); 5177 Py_DECREF(keys); 5178 5179 envlist[envc] = 0; 5180 *envc_ptr = envc; 5181 return envlist; 5182 5183error: 5184 Py_XDECREF(keys); 5185 Py_XDECREF(vals); 5186 while (--envc >= 0) 5187 PyMem_DEL(envlist[envc]); 5188 PyMem_DEL(envlist); 5189 return NULL; 5190} 5191 5192static char** 5193parse_arglist(PyObject* argv, Py_ssize_t *argc) 5194{ 5195 int i; 5196 char **argvlist = PyMem_NEW(char *, *argc+1); 5197 if (argvlist == NULL) { 5198 PyErr_NoMemory(); 5199 return NULL; 5200 } 5201 for (i = 0; i < *argc; i++) { 5202 PyObject* item = PySequence_ITEM(argv, i); 5203 if (item == NULL) 5204 goto fail; 5205 if (!fsconvert_strdup(item, &argvlist[i])) { 5206 Py_DECREF(item); 5207 goto fail; 5208 } 5209 Py_DECREF(item); 5210 } 5211 argvlist[*argc] = NULL; 5212 return argvlist; 5213fail: 5214 *argc = i; 5215 free_string_array(argvlist, *argc); 5216 return NULL; 5217} 5218#endif 5219 5220#ifdef HAVE_EXECV 5221PyDoc_STRVAR(posix_execv__doc__, 5222"execv(path, args)\n\n\ 5223Execute an executable path with arguments, replacing current process.\n\ 5224\n\ 5225 path: path of executable file\n\ 5226 args: tuple or list of strings"); 5227 5228static PyObject * 5229posix_execv(PyObject *self, PyObject *args) 5230{ 5231 PyObject *opath; 5232 char *path; 5233 PyObject *argv; 5234 char **argvlist; 5235 Py_ssize_t argc; 5236 5237 /* execv has two arguments: (path, argv), where 5238 argv is a list or tuple of strings. */ 5239 5240 if (!PyArg_ParseTuple(args, "O&O:execv", 5241 PyUnicode_FSConverter, 5242 &opath, &argv)) 5243 return NULL; 5244 path = PyBytes_AsString(opath); 5245 if (!PyList_Check(argv) && !PyTuple_Check(argv)) { 5246 PyErr_SetString(PyExc_TypeError, 5247 "execv() arg 2 must be a tuple or list"); 5248 Py_DECREF(opath); 5249 return NULL; 5250 } 5251 argc = PySequence_Size(argv); 5252 if (argc < 1) { 5253 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty"); 5254 Py_DECREF(opath); 5255 return NULL; 5256 } 5257 5258 argvlist = parse_arglist(argv, &argc); 5259 if (argvlist == NULL) { 5260 Py_DECREF(opath); 5261 return NULL; 5262 } 5263 5264 execv(path, argvlist); 5265 5266 /* If we get here it's definitely an error */ 5267 5268 free_string_array(argvlist, argc); 5269 Py_DECREF(opath); 5270 return posix_error(); 5271} 5272 5273PyDoc_STRVAR(posix_execve__doc__, 5274"execve(path, args, env)\n\n\ 5275Execute a path with arguments and environment, replacing current process.\n\ 5276\n\ 5277 path: path of executable file\n\ 5278 args: tuple or list of arguments\n\ 5279 env: dictionary of strings mapping to strings\n\ 5280\n\ 5281On some platforms, you may specify an open file descriptor for path;\n\ 5282 execve will execute the program the file descriptor is open to.\n\ 5283 If this functionality is unavailable, using it raises NotImplementedError."); 5284 5285static PyObject * 5286posix_execve(PyObject *self, PyObject *args, PyObject *kwargs) 5287{ 5288 path_t path; 5289 PyObject *argv, *env; 5290 char **argvlist = NULL; 5291 char **envlist; 5292 Py_ssize_t argc, envc; 5293 static char *keywords[] = {"path", "argv", "environment", NULL}; 5294 5295 /* execve has three arguments: (path, argv, env), where 5296 argv is a list or tuple of strings and env is a dictionary 5297 like posix.environ. */ 5298 5299 memset(&path, 0, sizeof(path)); 5300 path.function_name = "execve"; 5301#ifdef HAVE_FEXECVE 5302 path.allow_fd = 1; 5303#endif 5304 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&OO:execve", keywords, 5305 path_converter, &path, 5306 &argv, &env 5307 )) 5308 return NULL; 5309 5310 if (!PyList_Check(argv) && !PyTuple_Check(argv)) { 5311 PyErr_SetString(PyExc_TypeError, 5312 "execve: argv must be a tuple or list"); 5313 goto fail; 5314 } 5315 argc = PySequence_Size(argv); 5316 if (!PyMapping_Check(env)) { 5317 PyErr_SetString(PyExc_TypeError, 5318 "execve: environment must be a mapping object"); 5319 goto fail; 5320 } 5321 5322 argvlist = parse_arglist(argv, &argc); 5323 if (argvlist == NULL) { 5324 goto fail; 5325 } 5326 5327 envlist = parse_envlist(env, &envc); 5328 if (envlist == NULL) 5329 goto fail; 5330 5331#ifdef HAVE_FEXECVE 5332 if (path.fd > -1) 5333 fexecve(path.fd, argvlist, envlist); 5334 else 5335#endif 5336 execve(path.narrow, argvlist, envlist); 5337 5338 /* If we get here it's definitely an error */ 5339 5340 path_error(&path); 5341 5342 while (--envc >= 0) 5343 PyMem_DEL(envlist[envc]); 5344 PyMem_DEL(envlist); 5345 fail: 5346 if (argvlist) 5347 free_string_array(argvlist, argc); 5348 path_cleanup(&path); 5349 return NULL; 5350} 5351#endif /* HAVE_EXECV */ 5352 5353 5354#ifdef HAVE_SPAWNV 5355PyDoc_STRVAR(posix_spawnv__doc__, 5356"spawnv(mode, path, args)\n\n\ 5357Execute the program 'path' in a new process.\n\ 5358\n\ 5359 mode: mode of process creation\n\ 5360 path: path of executable file\n\ 5361 args: tuple or list of strings"); 5362 5363static PyObject * 5364posix_spawnv(PyObject *self, PyObject *args) 5365{ 5366 PyObject *opath; 5367 char *path; 5368 PyObject *argv; 5369 char **argvlist; 5370 int mode, i; 5371 Py_ssize_t argc; 5372 Py_intptr_t spawnval; 5373 PyObject *(*getitem)(PyObject *, Py_ssize_t); 5374 5375 /* spawnv has three arguments: (mode, path, argv), where 5376 argv is a list or tuple of strings. */ 5377 5378 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode, 5379 PyUnicode_FSConverter, 5380 &opath, &argv)) 5381 return NULL; 5382 path = PyBytes_AsString(opath); 5383 if (PyList_Check(argv)) { 5384 argc = PyList_Size(argv); 5385 getitem = PyList_GetItem; 5386 } 5387 else if (PyTuple_Check(argv)) { 5388 argc = PyTuple_Size(argv); 5389 getitem = PyTuple_GetItem; 5390 } 5391 else { 5392 PyErr_SetString(PyExc_TypeError, 5393 "spawnv() arg 2 must be a tuple or list"); 5394 Py_DECREF(opath); 5395 return NULL; 5396 } 5397 5398 argvlist = PyMem_NEW(char *, argc+1); 5399 if (argvlist == NULL) { 5400 Py_DECREF(opath); 5401 return PyErr_NoMemory(); 5402 } 5403 for (i = 0; i < argc; i++) { 5404 if (!fsconvert_strdup((*getitem)(argv, i), 5405 &argvlist[i])) { 5406 free_string_array(argvlist, i); 5407 PyErr_SetString( 5408 PyExc_TypeError, 5409 "spawnv() arg 2 must contain only strings"); 5410 Py_DECREF(opath); 5411 return NULL; 5412 } 5413 } 5414 argvlist[argc] = NULL; 5415 5416 if (mode == _OLD_P_OVERLAY) 5417 mode = _P_OVERLAY; 5418 5419 Py_BEGIN_ALLOW_THREADS 5420 spawnval = _spawnv(mode, path, argvlist); 5421 Py_END_ALLOW_THREADS 5422 5423 free_string_array(argvlist, argc); 5424 Py_DECREF(opath); 5425 5426 if (spawnval == -1) 5427 return posix_error(); 5428 else 5429 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval); 5430} 5431 5432 5433PyDoc_STRVAR(posix_spawnve__doc__, 5434"spawnve(mode, path, args, env)\n\n\ 5435Execute the program 'path' in a new process.\n\ 5436\n\ 5437 mode: mode of process creation\n\ 5438 path: path of executable file\n\ 5439 args: tuple or list of arguments\n\ 5440 env: dictionary of strings mapping to strings"); 5441 5442static PyObject * 5443posix_spawnve(PyObject *self, PyObject *args) 5444{ 5445 PyObject *opath; 5446 char *path; 5447 PyObject *argv, *env; 5448 char **argvlist; 5449 char **envlist; 5450 PyObject *res = NULL; 5451 int mode; 5452 Py_ssize_t argc, i, envc; 5453 Py_intptr_t spawnval; 5454 PyObject *(*getitem)(PyObject *, Py_ssize_t); 5455 Py_ssize_t lastarg = 0; 5456 5457 /* spawnve has four arguments: (mode, path, argv, env), where 5458 argv is a list or tuple of strings and env is a dictionary 5459 like posix.environ. */ 5460 5461 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode, 5462 PyUnicode_FSConverter, 5463 &opath, &argv, &env)) 5464 return NULL; 5465 path = PyBytes_AsString(opath); 5466 if (PyList_Check(argv)) { 5467 argc = PyList_Size(argv); 5468 getitem = PyList_GetItem; 5469 } 5470 else if (PyTuple_Check(argv)) { 5471 argc = PyTuple_Size(argv); 5472 getitem = PyTuple_GetItem; 5473 } 5474 else { 5475 PyErr_SetString(PyExc_TypeError, 5476 "spawnve() arg 2 must be a tuple or list"); 5477 goto fail_0; 5478 } 5479 if (!PyMapping_Check(env)) { 5480 PyErr_SetString(PyExc_TypeError, 5481 "spawnve() arg 3 must be a mapping object"); 5482 goto fail_0; 5483 } 5484 5485 argvlist = PyMem_NEW(char *, argc+1); 5486 if (argvlist == NULL) { 5487 PyErr_NoMemory(); 5488 goto fail_0; 5489 } 5490 for (i = 0; i < argc; i++) { 5491 if (!fsconvert_strdup((*getitem)(argv, i), 5492 &argvlist[i])) 5493 { 5494 lastarg = i; 5495 goto fail_1; 5496 } 5497 } 5498 lastarg = argc; 5499 argvlist[argc] = NULL; 5500 5501 envlist = parse_envlist(env, &envc); 5502 if (envlist == NULL) 5503 goto fail_1; 5504 5505 if (mode == _OLD_P_OVERLAY) 5506 mode = _P_OVERLAY; 5507 5508 Py_BEGIN_ALLOW_THREADS 5509 spawnval = _spawnve(mode, path, argvlist, envlist); 5510 Py_END_ALLOW_THREADS 5511 5512 if (spawnval == -1) 5513 (void) posix_error(); 5514 else 5515 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval); 5516 5517 while (--envc >= 0) 5518 PyMem_DEL(envlist[envc]); 5519 PyMem_DEL(envlist); 5520 fail_1: 5521 free_string_array(argvlist, lastarg); 5522 fail_0: 5523 Py_DECREF(opath); 5524 return res; 5525} 5526 5527#endif /* HAVE_SPAWNV */ 5528 5529 5530#ifdef HAVE_FORK1 5531PyDoc_STRVAR(posix_fork1__doc__, 5532"fork1() -> pid\n\n\ 5533Fork a child process with a single multiplexed (i.e., not bound) thread.\n\ 5534\n\ 5535Return 0 to child process and PID of child to parent process."); 5536 5537static PyObject * 5538posix_fork1(PyObject *self, PyObject *noargs) 5539{ 5540 pid_t pid; 5541 int result = 0; 5542 _PyImport_AcquireLock(); 5543 pid = fork1(); 5544 if (pid == 0) { 5545 /* child: this clobbers and resets the import lock. */ 5546 PyOS_AfterFork(); 5547 } else { 5548 /* parent: release the import lock. */ 5549 result = _PyImport_ReleaseLock(); 5550 } 5551 if (pid == -1) 5552 return posix_error(); 5553 if (result < 0) { 5554 /* Don't clobber the OSError if the fork failed. */ 5555 PyErr_SetString(PyExc_RuntimeError, 5556 "not holding the import lock"); 5557 return NULL; 5558 } 5559 return PyLong_FromPid(pid); 5560} 5561#endif 5562 5563 5564#ifdef HAVE_FORK 5565PyDoc_STRVAR(posix_fork__doc__, 5566"fork() -> pid\n\n\ 5567Fork a child process.\n\ 5568Return 0 to child process and PID of child to parent process."); 5569 5570static PyObject * 5571posix_fork(PyObject *self, PyObject *noargs) 5572{ 5573 pid_t pid; 5574 int result = 0; 5575 _PyImport_AcquireLock(); 5576 pid = fork(); 5577 if (pid == 0) { 5578 /* child: this clobbers and resets the import lock. */ 5579 PyOS_AfterFork(); 5580 } else { 5581 /* parent: release the import lock. */ 5582 result = _PyImport_ReleaseLock(); 5583 } 5584 if (pid == -1) 5585 return posix_error(); 5586 if (result < 0) { 5587 /* Don't clobber the OSError if the fork failed. */ 5588 PyErr_SetString(PyExc_RuntimeError, 5589 "not holding the import lock"); 5590 return NULL; 5591 } 5592 return PyLong_FromPid(pid); 5593} 5594#endif 5595 5596#ifdef HAVE_SCHED_H 5597 5598#ifdef HAVE_SCHED_GET_PRIORITY_MAX 5599 5600PyDoc_STRVAR(posix_sched_get_priority_max__doc__, 5601"sched_get_priority_max(policy)\n\n\ 5602Get the maximum scheduling priority for *policy*."); 5603 5604static PyObject * 5605posix_sched_get_priority_max(PyObject *self, PyObject *args) 5606{ 5607 int policy, max; 5608 5609 if (!PyArg_ParseTuple(args, "i:sched_get_priority_max", &policy)) 5610 return NULL; 5611 max = sched_get_priority_max(policy); 5612 if (max < 0) 5613 return posix_error(); 5614 return PyLong_FromLong(max); 5615} 5616 5617PyDoc_STRVAR(posix_sched_get_priority_min__doc__, 5618"sched_get_priority_min(policy)\n\n\ 5619Get the minimum scheduling priority for *policy*."); 5620 5621static PyObject * 5622posix_sched_get_priority_min(PyObject *self, PyObject *args) 5623{ 5624 int policy, min; 5625 5626 if (!PyArg_ParseTuple(args, "i:sched_get_priority_min", &policy)) 5627 return NULL; 5628 min = sched_get_priority_min(policy); 5629 if (min < 0) 5630 return posix_error(); 5631 return PyLong_FromLong(min); 5632} 5633 5634#endif /* HAVE_SCHED_GET_PRIORITY_MAX */ 5635 5636#ifdef HAVE_SCHED_SETSCHEDULER 5637 5638PyDoc_STRVAR(posix_sched_getscheduler__doc__, 5639"sched_getscheduler(pid)\n\n\ 5640Get the scheduling policy for the process with a PID of *pid*.\n\ 5641Passing a PID of 0 returns the scheduling policy for the calling process."); 5642 5643static PyObject * 5644posix_sched_getscheduler(PyObject *self, PyObject *args) 5645{ 5646 pid_t pid; 5647 int policy; 5648 5649 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getscheduler", &pid)) 5650 return NULL; 5651 policy = sched_getscheduler(pid); 5652 if (policy < 0) 5653 return posix_error(); 5654 return PyLong_FromLong(policy); 5655} 5656 5657#endif 5658 5659#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM) 5660 5661static PyObject * 5662sched_param_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) 5663{ 5664 PyObject *res, *priority; 5665 static char *kwlist[] = {"sched_priority", NULL}; 5666 5667 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:sched_param", kwlist, &priority)) 5668 return NULL; 5669 res = PyStructSequence_New(type); 5670 if (!res) 5671 return NULL; 5672 Py_INCREF(priority); 5673 PyStructSequence_SET_ITEM(res, 0, priority); 5674 return res; 5675} 5676 5677PyDoc_STRVAR(sched_param__doc__, 5678"sched_param(sched_priority): A scheduling parameter.\n\n\ 5679Current has only one field: sched_priority"); 5680 5681static PyStructSequence_Field sched_param_fields[] = { 5682 {"sched_priority", "the scheduling priority"}, 5683 {0} 5684}; 5685 5686static PyStructSequence_Desc sched_param_desc = { 5687 "sched_param", /* name */ 5688 sched_param__doc__, /* doc */ 5689 sched_param_fields, 5690 1 5691}; 5692 5693static int 5694convert_sched_param(PyObject *param, struct sched_param *res) 5695{ 5696 long priority; 5697 5698 if (Py_TYPE(param) != &SchedParamType) { 5699 PyErr_SetString(PyExc_TypeError, "must have a sched_param object"); 5700 return 0; 5701 } 5702 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0)); 5703 if (priority == -1 && PyErr_Occurred()) 5704 return 0; 5705 if (priority > INT_MAX || priority < INT_MIN) { 5706 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range"); 5707 return 0; 5708 } 5709 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int); 5710 return 1; 5711} 5712 5713#endif 5714 5715#ifdef HAVE_SCHED_SETSCHEDULER 5716 5717PyDoc_STRVAR(posix_sched_setscheduler__doc__, 5718"sched_setscheduler(pid, policy, param)\n\n\ 5719Set the scheduling policy, *policy*, for *pid*.\n\ 5720If *pid* is 0, the calling process is changed.\n\ 5721*param* is an instance of sched_param."); 5722 5723static PyObject * 5724posix_sched_setscheduler(PyObject *self, PyObject *args) 5725{ 5726 pid_t pid; 5727 int policy; 5728 struct sched_param param; 5729 5730 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "iO&:sched_setscheduler", 5731 &pid, &policy, &convert_sched_param, ¶m)) 5732 return NULL; 5733 5734 /* 5735 ** sched_setscheduler() returns 0 in Linux, but the previous 5736 ** scheduling policy under Solaris/Illumos, and others. 5737 ** On error, -1 is returned in all Operating Systems. 5738 */ 5739 if (sched_setscheduler(pid, policy, ¶m) == -1) 5740 return posix_error(); 5741 Py_RETURN_NONE; 5742} 5743 5744#endif 5745 5746#ifdef HAVE_SCHED_SETPARAM 5747 5748PyDoc_STRVAR(posix_sched_getparam__doc__, 5749"sched_getparam(pid) -> sched_param\n\n\ 5750Returns scheduling parameters for the process with *pid* as an instance of the\n\ 5751sched_param class. A PID of 0 means the calling process."); 5752 5753static PyObject * 5754posix_sched_getparam(PyObject *self, PyObject *args) 5755{ 5756 pid_t pid; 5757 struct sched_param param; 5758 PyObject *res, *priority; 5759 5760 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getparam", &pid)) 5761 return NULL; 5762 if (sched_getparam(pid, ¶m)) 5763 return posix_error(); 5764 res = PyStructSequence_New(&SchedParamType); 5765 if (!res) 5766 return NULL; 5767 priority = PyLong_FromLong(param.sched_priority); 5768 if (!priority) { 5769 Py_DECREF(res); 5770 return NULL; 5771 } 5772 PyStructSequence_SET_ITEM(res, 0, priority); 5773 return res; 5774} 5775 5776PyDoc_STRVAR(posix_sched_setparam__doc__, 5777"sched_setparam(pid, param)\n\n\ 5778Set scheduling parameters for a process with PID *pid*.\n\ 5779A PID of 0 means the calling process."); 5780 5781static PyObject * 5782posix_sched_setparam(PyObject *self, PyObject *args) 5783{ 5784 pid_t pid; 5785 struct sched_param param; 5786 5787 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O&:sched_setparam", 5788 &pid, &convert_sched_param, ¶m)) 5789 return NULL; 5790 if (sched_setparam(pid, ¶m)) 5791 return posix_error(); 5792 Py_RETURN_NONE; 5793} 5794 5795#endif 5796 5797#ifdef HAVE_SCHED_RR_GET_INTERVAL 5798 5799PyDoc_STRVAR(posix_sched_rr_get_interval__doc__, 5800"sched_rr_get_interval(pid) -> float\n\n\ 5801Return the round-robin quantum for the process with PID *pid* in seconds."); 5802 5803static PyObject * 5804posix_sched_rr_get_interval(PyObject *self, PyObject *args) 5805{ 5806 pid_t pid; 5807 struct timespec interval; 5808 5809 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_rr_get_interval", &pid)) 5810 return NULL; 5811 if (sched_rr_get_interval(pid, &interval)) 5812 return posix_error(); 5813 return PyFloat_FromDouble((double)interval.tv_sec + 1e-9*interval.tv_nsec); 5814} 5815 5816#endif 5817 5818PyDoc_STRVAR(posix_sched_yield__doc__, 5819"sched_yield()\n\n\ 5820Voluntarily relinquish the CPU."); 5821 5822static PyObject * 5823posix_sched_yield(PyObject *self, PyObject *noargs) 5824{ 5825 if (sched_yield()) 5826 return posix_error(); 5827 Py_RETURN_NONE; 5828} 5829 5830#ifdef HAVE_SCHED_SETAFFINITY 5831 5832/* The minimum number of CPUs allocated in a cpu_set_t */ 5833static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT; 5834 5835PyDoc_STRVAR(posix_sched_setaffinity__doc__, 5836"sched_setaffinity(pid, cpu_set)\n\n\ 5837Set the affinity of the process with PID *pid* to *cpu_set*."); 5838 5839static PyObject * 5840posix_sched_setaffinity(PyObject *self, PyObject *args) 5841{ 5842 pid_t pid; 5843 int ncpus; 5844 size_t setsize; 5845 cpu_set_t *mask = NULL; 5846 PyObject *iterable, *iterator = NULL, *item; 5847 5848 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "O:sched_setaffinity", 5849 &pid, &iterable)) 5850 return NULL; 5851 5852 iterator = PyObject_GetIter(iterable); 5853 if (iterator == NULL) 5854 return NULL; 5855 5856 ncpus = NCPUS_START; 5857 setsize = CPU_ALLOC_SIZE(ncpus); 5858 mask = CPU_ALLOC(ncpus); 5859 if (mask == NULL) { 5860 PyErr_NoMemory(); 5861 goto error; 5862 } 5863 CPU_ZERO_S(setsize, mask); 5864 5865 while ((item = PyIter_Next(iterator))) { 5866 long cpu; 5867 if (!PyLong_Check(item)) { 5868 PyErr_Format(PyExc_TypeError, 5869 "expected an iterator of ints, " 5870 "but iterator yielded %R", 5871 Py_TYPE(item)); 5872 Py_DECREF(item); 5873 goto error; 5874 } 5875 cpu = PyLong_AsLong(item); 5876 Py_DECREF(item); 5877 if (cpu < 0) { 5878 if (!PyErr_Occurred()) 5879 PyErr_SetString(PyExc_ValueError, "negative CPU number"); 5880 goto error; 5881 } 5882 if (cpu > INT_MAX - 1) { 5883 PyErr_SetString(PyExc_OverflowError, "CPU number too large"); 5884 goto error; 5885 } 5886 if (cpu >= ncpus) { 5887 /* Grow CPU mask to fit the CPU number */ 5888 int newncpus = ncpus; 5889 cpu_set_t *newmask; 5890 size_t newsetsize; 5891 while (newncpus <= cpu) { 5892 if (newncpus > INT_MAX / 2) 5893 newncpus = cpu + 1; 5894 else 5895 newncpus = newncpus * 2; 5896 } 5897 newmask = CPU_ALLOC(newncpus); 5898 if (newmask == NULL) { 5899 PyErr_NoMemory(); 5900 goto error; 5901 } 5902 newsetsize = CPU_ALLOC_SIZE(newncpus); 5903 CPU_ZERO_S(newsetsize, newmask); 5904 memcpy(newmask, mask, setsize); 5905 CPU_FREE(mask); 5906 setsize = newsetsize; 5907 mask = newmask; 5908 ncpus = newncpus; 5909 } 5910 CPU_SET_S(cpu, setsize, mask); 5911 } 5912 Py_CLEAR(iterator); 5913 5914 if (sched_setaffinity(pid, setsize, mask)) { 5915 posix_error(); 5916 goto error; 5917 } 5918 CPU_FREE(mask); 5919 Py_RETURN_NONE; 5920 5921error: 5922 if (mask) 5923 CPU_FREE(mask); 5924 Py_XDECREF(iterator); 5925 return NULL; 5926} 5927 5928PyDoc_STRVAR(posix_sched_getaffinity__doc__, 5929"sched_getaffinity(pid, ncpus) -> cpu_set\n\n\ 5930Return the affinity of the process with PID *pid*.\n\ 5931The returned cpu_set will be of size *ncpus*."); 5932 5933static PyObject * 5934posix_sched_getaffinity(PyObject *self, PyObject *args) 5935{ 5936 pid_t pid; 5937 int cpu, ncpus, count; 5938 size_t setsize; 5939 cpu_set_t *mask = NULL; 5940 PyObject *res = NULL; 5941 5942 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":sched_getaffinity", 5943 &pid)) 5944 return NULL; 5945 5946 ncpus = NCPUS_START; 5947 while (1) { 5948 setsize = CPU_ALLOC_SIZE(ncpus); 5949 mask = CPU_ALLOC(ncpus); 5950 if (mask == NULL) 5951 return PyErr_NoMemory(); 5952 if (sched_getaffinity(pid, setsize, mask) == 0) 5953 break; 5954 CPU_FREE(mask); 5955 if (errno != EINVAL) 5956 return posix_error(); 5957 if (ncpus > INT_MAX / 2) { 5958 PyErr_SetString(PyExc_OverflowError, "could not allocate " 5959 "a large enough CPU set"); 5960 return NULL; 5961 } 5962 ncpus = ncpus * 2; 5963 } 5964 5965 res = PySet_New(NULL); 5966 if (res == NULL) 5967 goto error; 5968 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) { 5969 if (CPU_ISSET_S(cpu, setsize, mask)) { 5970 PyObject *cpu_num = PyLong_FromLong(cpu); 5971 --count; 5972 if (cpu_num == NULL) 5973 goto error; 5974 if (PySet_Add(res, cpu_num)) { 5975 Py_DECREF(cpu_num); 5976 goto error; 5977 } 5978 Py_DECREF(cpu_num); 5979 } 5980 } 5981 CPU_FREE(mask); 5982 return res; 5983 5984error: 5985 if (mask) 5986 CPU_FREE(mask); 5987 Py_XDECREF(res); 5988 return NULL; 5989} 5990 5991#endif /* HAVE_SCHED_SETAFFINITY */ 5992 5993#endif /* HAVE_SCHED_H */ 5994 5995/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */ 5996/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */ 5997#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX) 5998#define DEV_PTY_FILE "/dev/ptc" 5999#define HAVE_DEV_PTMX 6000#else 6001#define DEV_PTY_FILE "/dev/ptmx" 6002#endif 6003 6004#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX) 6005#ifdef HAVE_PTY_H 6006#include <pty.h> 6007#else 6008#ifdef HAVE_LIBUTIL_H 6009#include <libutil.h> 6010#else 6011#ifdef HAVE_UTIL_H 6012#include <util.h> 6013#endif /* HAVE_UTIL_H */ 6014#endif /* HAVE_LIBUTIL_H */ 6015#endif /* HAVE_PTY_H */ 6016#ifdef HAVE_STROPTS_H 6017#include <stropts.h> 6018#endif 6019#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */ 6020 6021#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) 6022PyDoc_STRVAR(posix_openpty__doc__, 6023"openpty() -> (master_fd, slave_fd)\n\n\ 6024Open a pseudo-terminal, returning open fd's for both master and slave end.\n"); 6025 6026static PyObject * 6027posix_openpty(PyObject *self, PyObject *noargs) 6028{ 6029 int master_fd = -1, slave_fd = -1; 6030#ifndef HAVE_OPENPTY 6031 char * slave_name; 6032#endif 6033#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY) 6034 PyOS_sighandler_t sig_saved; 6035#ifdef sun 6036 extern char *ptsname(int fildes); 6037#endif 6038#endif 6039 6040#ifdef HAVE_OPENPTY 6041 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0) 6042 goto posix_error; 6043 6044 if (_Py_set_inheritable(master_fd, 0, NULL) < 0) 6045 goto error; 6046 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0) 6047 goto error; 6048 6049#elif defined(HAVE__GETPTY) 6050 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0); 6051 if (slave_name == NULL) 6052 goto posix_error; 6053 if (_Py_set_inheritable(master_fd, 0, NULL) < 0) 6054 goto error; 6055 6056 slave_fd = _Py_open(slave_name, O_RDWR); 6057 if (slave_fd < 0) 6058 goto posix_error; 6059 6060#else 6061 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */ 6062 if (master_fd < 0) 6063 goto posix_error; 6064 6065 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL); 6066 6067 /* change permission of slave */ 6068 if (grantpt(master_fd) < 0) { 6069 PyOS_setsig(SIGCHLD, sig_saved); 6070 goto posix_error; 6071 } 6072 6073 /* unlock slave */ 6074 if (unlockpt(master_fd) < 0) { 6075 PyOS_setsig(SIGCHLD, sig_saved); 6076 goto posix_error; 6077 } 6078 6079 PyOS_setsig(SIGCHLD, sig_saved); 6080 6081 slave_name = ptsname(master_fd); /* get name of slave */ 6082 if (slave_name == NULL) 6083 goto posix_error; 6084 6085 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */ 6086 if (slave_fd < 0) 6087 goto posix_error; 6088 6089 if (_Py_set_inheritable(master_fd, 0, NULL) < 0) 6090 goto posix_error; 6091 6092#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC) 6093 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */ 6094 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */ 6095#ifndef __hpux 6096 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */ 6097#endif /* __hpux */ 6098#endif /* HAVE_CYGWIN */ 6099#endif /* HAVE_OPENPTY */ 6100 6101 return Py_BuildValue("(ii)", master_fd, slave_fd); 6102 6103posix_error: 6104 posix_error(); 6105#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) 6106error: 6107#endif 6108 if (master_fd != -1) 6109 close(master_fd); 6110 if (slave_fd != -1) 6111 close(slave_fd); 6112 return NULL; 6113} 6114#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */ 6115 6116#ifdef HAVE_FORKPTY 6117PyDoc_STRVAR(posix_forkpty__doc__, 6118"forkpty() -> (pid, master_fd)\n\n\ 6119Fork a new process with a new pseudo-terminal as controlling tty.\n\n\ 6120Like fork(), return 0 as pid to child process, and PID of child to parent.\n\ 6121To both, return fd of newly opened pseudo-terminal.\n"); 6122 6123static PyObject * 6124posix_forkpty(PyObject *self, PyObject *noargs) 6125{ 6126 int master_fd = -1, result = 0; 6127 pid_t pid; 6128 6129 _PyImport_AcquireLock(); 6130 pid = forkpty(&master_fd, NULL, NULL, NULL); 6131 if (pid == 0) { 6132 /* child: this clobbers and resets the import lock. */ 6133 PyOS_AfterFork(); 6134 } else { 6135 /* parent: release the import lock. */ 6136 result = _PyImport_ReleaseLock(); 6137 } 6138 if (pid == -1) 6139 return posix_error(); 6140 if (result < 0) { 6141 /* Don't clobber the OSError if the fork failed. */ 6142 PyErr_SetString(PyExc_RuntimeError, 6143 "not holding the import lock"); 6144 return NULL; 6145 } 6146 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd); 6147} 6148#endif 6149 6150 6151#ifdef HAVE_GETEGID 6152PyDoc_STRVAR(posix_getegid__doc__, 6153"getegid() -> egid\n\n\ 6154Return the current process's effective group id."); 6155 6156static PyObject * 6157posix_getegid(PyObject *self, PyObject *noargs) 6158{ 6159 return _PyLong_FromGid(getegid()); 6160} 6161#endif 6162 6163 6164#ifdef HAVE_GETEUID 6165PyDoc_STRVAR(posix_geteuid__doc__, 6166"geteuid() -> euid\n\n\ 6167Return the current process's effective user id."); 6168 6169static PyObject * 6170posix_geteuid(PyObject *self, PyObject *noargs) 6171{ 6172 return _PyLong_FromUid(geteuid()); 6173} 6174#endif 6175 6176 6177#ifdef HAVE_GETGID 6178PyDoc_STRVAR(posix_getgid__doc__, 6179"getgid() -> gid\n\n\ 6180Return the current process's group id."); 6181 6182static PyObject * 6183posix_getgid(PyObject *self, PyObject *noargs) 6184{ 6185 return _PyLong_FromGid(getgid()); 6186} 6187#endif 6188 6189 6190PyDoc_STRVAR(posix_getpid__doc__, 6191"getpid() -> pid\n\n\ 6192Return the current process id"); 6193 6194static PyObject * 6195posix_getpid(PyObject *self, PyObject *noargs) 6196{ 6197 return PyLong_FromPid(getpid()); 6198} 6199 6200#ifdef HAVE_GETGROUPLIST 6201PyDoc_STRVAR(posix_getgrouplist__doc__, 6202"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\ 6203Returns a list of groups to which a user belongs.\n\n\ 6204 user: username to lookup\n\ 6205 group: base group id of the user"); 6206 6207static PyObject * 6208posix_getgrouplist(PyObject *self, PyObject *args) 6209{ 6210#ifdef NGROUPS_MAX 6211#define MAX_GROUPS NGROUPS_MAX 6212#else 6213 /* defined to be 16 on Solaris7, so this should be a small number */ 6214#define MAX_GROUPS 64 6215#endif 6216 6217 const char *user; 6218 int i, ngroups; 6219 PyObject *list; 6220#ifdef __APPLE__ 6221 int *groups, basegid; 6222#else 6223 gid_t *groups, basegid; 6224#endif 6225 ngroups = MAX_GROUPS; 6226 6227#ifdef __APPLE__ 6228 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid)) 6229 return NULL; 6230#else 6231 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user, 6232 _Py_Gid_Converter, &basegid)) 6233 return NULL; 6234#endif 6235 6236#ifdef __APPLE__ 6237 groups = PyMem_New(int, ngroups); 6238#else 6239 groups = PyMem_New(gid_t, ngroups); 6240#endif 6241 if (groups == NULL) 6242 return PyErr_NoMemory(); 6243 6244 if (getgrouplist(user, basegid, groups, &ngroups) == -1) { 6245 PyMem_Del(groups); 6246 return posix_error(); 6247 } 6248 6249 list = PyList_New(ngroups); 6250 if (list == NULL) { 6251 PyMem_Del(groups); 6252 return NULL; 6253 } 6254 6255 for (i = 0; i < ngroups; i++) { 6256#ifdef __APPLE__ 6257 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]); 6258#else 6259 PyObject *o = _PyLong_FromGid(groups[i]); 6260#endif 6261 if (o == NULL) { 6262 Py_DECREF(list); 6263 PyMem_Del(groups); 6264 return NULL; 6265 } 6266 PyList_SET_ITEM(list, i, o); 6267 } 6268 6269 PyMem_Del(groups); 6270 6271 return list; 6272} 6273#endif 6274 6275#ifdef HAVE_GETGROUPS 6276PyDoc_STRVAR(posix_getgroups__doc__, 6277"getgroups() -> list of group IDs\n\n\ 6278Return list of supplemental group IDs for the process."); 6279 6280static PyObject * 6281posix_getgroups(PyObject *self, PyObject *noargs) 6282{ 6283 PyObject *result = NULL; 6284 6285#ifdef NGROUPS_MAX 6286#define MAX_GROUPS NGROUPS_MAX 6287#else 6288 /* defined to be 16 on Solaris7, so this should be a small number */ 6289#define MAX_GROUPS 64 6290#endif 6291 gid_t grouplist[MAX_GROUPS]; 6292 6293 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results 6294 * This is a helper variable to store the intermediate result when 6295 * that happens. 6296 * 6297 * To keep the code readable the OSX behaviour is unconditional, 6298 * according to the POSIX spec this should be safe on all unix-y 6299 * systems. 6300 */ 6301 gid_t* alt_grouplist = grouplist; 6302 int n; 6303 6304#ifdef __APPLE__ 6305 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if 6306 * there are more groups than can fit in grouplist. Therefore, on OS X 6307 * always first call getgroups with length 0 to get the actual number 6308 * of groups. 6309 */ 6310 n = getgroups(0, NULL); 6311 if (n < 0) { 6312 return posix_error(); 6313 } else if (n <= MAX_GROUPS) { 6314 /* groups will fit in existing array */ 6315 alt_grouplist = grouplist; 6316 } else { 6317 alt_grouplist = PyMem_New(gid_t, n); 6318 if (alt_grouplist == NULL) { 6319 errno = EINVAL; 6320 return posix_error(); 6321 } 6322 } 6323 6324 n = getgroups(n, alt_grouplist); 6325 if (n == -1) { 6326 if (alt_grouplist != grouplist) { 6327 PyMem_Free(alt_grouplist); 6328 } 6329 return posix_error(); 6330 } 6331#else 6332 n = getgroups(MAX_GROUPS, grouplist); 6333 if (n < 0) { 6334 if (errno == EINVAL) { 6335 n = getgroups(0, NULL); 6336 if (n == -1) { 6337 return posix_error(); 6338 } 6339 if (n == 0) { 6340 /* Avoid malloc(0) */ 6341 alt_grouplist = grouplist; 6342 } else { 6343 alt_grouplist = PyMem_New(gid_t, n); 6344 if (alt_grouplist == NULL) { 6345 errno = EINVAL; 6346 return posix_error(); 6347 } 6348 n = getgroups(n, alt_grouplist); 6349 if (n == -1) { 6350 PyMem_Free(alt_grouplist); 6351 return posix_error(); 6352 } 6353 } 6354 } else { 6355 return posix_error(); 6356 } 6357 } 6358#endif 6359 6360 result = PyList_New(n); 6361 if (result != NULL) { 6362 int i; 6363 for (i = 0; i < n; ++i) { 6364 PyObject *o = _PyLong_FromGid(alt_grouplist[i]); 6365 if (o == NULL) { 6366 Py_DECREF(result); 6367 result = NULL; 6368 break; 6369 } 6370 PyList_SET_ITEM(result, i, o); 6371 } 6372 } 6373 6374 if (alt_grouplist != grouplist) { 6375 PyMem_Free(alt_grouplist); 6376 } 6377 6378 return result; 6379} 6380#endif 6381 6382#ifdef HAVE_INITGROUPS 6383PyDoc_STRVAR(posix_initgroups__doc__, 6384"initgroups(username, gid) -> None\n\n\ 6385Call the system initgroups() to initialize the group access list with all of\n\ 6386the groups of which the specified username is a member, plus the specified\n\ 6387group id."); 6388 6389static PyObject * 6390posix_initgroups(PyObject *self, PyObject *args) 6391{ 6392 PyObject *oname; 6393 char *username; 6394 int res; 6395#ifdef __APPLE__ 6396 int gid; 6397#else 6398 gid_t gid; 6399#endif 6400 6401#ifdef __APPLE__ 6402 if (!PyArg_ParseTuple(args, "O&i:initgroups", 6403 PyUnicode_FSConverter, &oname, 6404 &gid)) 6405#else 6406 if (!PyArg_ParseTuple(args, "O&O&:initgroups", 6407 PyUnicode_FSConverter, &oname, 6408 _Py_Gid_Converter, &gid)) 6409#endif 6410 return NULL; 6411 username = PyBytes_AS_STRING(oname); 6412 6413 res = initgroups(username, gid); 6414 Py_DECREF(oname); 6415 if (res == -1) 6416 return PyErr_SetFromErrno(PyExc_OSError); 6417 6418 Py_INCREF(Py_None); 6419 return Py_None; 6420} 6421#endif 6422 6423#ifdef HAVE_GETPGID 6424PyDoc_STRVAR(posix_getpgid__doc__, 6425"getpgid(pid) -> pgid\n\n\ 6426Call the system call getpgid()."); 6427 6428static PyObject * 6429posix_getpgid(PyObject *self, PyObject *args) 6430{ 6431 pid_t pid, pgid; 6432 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid)) 6433 return NULL; 6434 pgid = getpgid(pid); 6435 if (pgid < 0) 6436 return posix_error(); 6437 return PyLong_FromPid(pgid); 6438} 6439#endif /* HAVE_GETPGID */ 6440 6441 6442#ifdef HAVE_GETPGRP 6443PyDoc_STRVAR(posix_getpgrp__doc__, 6444"getpgrp() -> pgrp\n\n\ 6445Return the current process group id."); 6446 6447static PyObject * 6448posix_getpgrp(PyObject *self, PyObject *noargs) 6449{ 6450#ifdef GETPGRP_HAVE_ARG 6451 return PyLong_FromPid(getpgrp(0)); 6452#else /* GETPGRP_HAVE_ARG */ 6453 return PyLong_FromPid(getpgrp()); 6454#endif /* GETPGRP_HAVE_ARG */ 6455} 6456#endif /* HAVE_GETPGRP */ 6457 6458 6459#ifdef HAVE_SETPGRP 6460PyDoc_STRVAR(posix_setpgrp__doc__, 6461"setpgrp()\n\n\ 6462Make this process the process group leader."); 6463 6464static PyObject * 6465posix_setpgrp(PyObject *self, PyObject *noargs) 6466{ 6467#ifdef SETPGRP_HAVE_ARG 6468 if (setpgrp(0, 0) < 0) 6469#else /* SETPGRP_HAVE_ARG */ 6470 if (setpgrp() < 0) 6471#endif /* SETPGRP_HAVE_ARG */ 6472 return posix_error(); 6473 Py_INCREF(Py_None); 6474 return Py_None; 6475} 6476 6477#endif /* HAVE_SETPGRP */ 6478 6479#ifdef HAVE_GETPPID 6480 6481#ifdef MS_WINDOWS 6482#include <tlhelp32.h> 6483 6484static PyObject* 6485win32_getppid() 6486{ 6487 HANDLE snapshot; 6488 pid_t mypid; 6489 PyObject* result = NULL; 6490 BOOL have_record; 6491 PROCESSENTRY32 pe; 6492 6493 mypid = getpid(); /* This function never fails */ 6494 6495 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 6496 if (snapshot == INVALID_HANDLE_VALUE) 6497 return PyErr_SetFromWindowsErr(GetLastError()); 6498 6499 pe.dwSize = sizeof(pe); 6500 have_record = Process32First(snapshot, &pe); 6501 while (have_record) { 6502 if (mypid == (pid_t)pe.th32ProcessID) { 6503 /* We could cache the ulong value in a static variable. */ 6504 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID); 6505 break; 6506 } 6507 6508 have_record = Process32Next(snapshot, &pe); 6509 } 6510 6511 /* If our loop exits and our pid was not found (result will be NULL) 6512 * then GetLastError will return ERROR_NO_MORE_FILES. This is an 6513 * error anyway, so let's raise it. */ 6514 if (!result) 6515 result = PyErr_SetFromWindowsErr(GetLastError()); 6516 6517 CloseHandle(snapshot); 6518 6519 return result; 6520} 6521#endif /*MS_WINDOWS*/ 6522 6523PyDoc_STRVAR(posix_getppid__doc__, 6524"getppid() -> ppid\n\n\ 6525Return the parent's process id. If the parent process has already exited,\n\ 6526Windows machines will still return its id; others systems will return the id\n\ 6527of the 'init' process (1)."); 6528 6529static PyObject * 6530posix_getppid(PyObject *self, PyObject *noargs) 6531{ 6532#ifdef MS_WINDOWS 6533 return win32_getppid(); 6534#else 6535 return PyLong_FromPid(getppid()); 6536#endif 6537} 6538#endif /* HAVE_GETPPID */ 6539 6540 6541#ifdef HAVE_GETLOGIN 6542PyDoc_STRVAR(posix_getlogin__doc__, 6543"getlogin() -> string\n\n\ 6544Return the actual login name."); 6545 6546static PyObject * 6547posix_getlogin(PyObject *self, PyObject *noargs) 6548{ 6549 PyObject *result = NULL; 6550#ifdef MS_WINDOWS 6551 wchar_t user_name[UNLEN + 1]; 6552 DWORD num_chars = Py_ARRAY_LENGTH(user_name); 6553 6554 if (GetUserNameW(user_name, &num_chars)) { 6555 /* num_chars is the number of unicode chars plus null terminator */ 6556 result = PyUnicode_FromWideChar(user_name, num_chars - 1); 6557 } 6558 else 6559 result = PyErr_SetFromWindowsErr(GetLastError()); 6560#else 6561 char *name; 6562 int old_errno = errno; 6563 6564 errno = 0; 6565 name = getlogin(); 6566 if (name == NULL) { 6567 if (errno) 6568 posix_error(); 6569 else 6570 PyErr_SetString(PyExc_OSError, "unable to determine login name"); 6571 } 6572 else 6573 result = PyUnicode_DecodeFSDefault(name); 6574 errno = old_errno; 6575#endif 6576 return result; 6577} 6578#endif /* HAVE_GETLOGIN */ 6579 6580#ifdef HAVE_GETUID 6581PyDoc_STRVAR(posix_getuid__doc__, 6582"getuid() -> uid\n\n\ 6583Return the current process's user id."); 6584 6585static PyObject * 6586posix_getuid(PyObject *self, PyObject *noargs) 6587{ 6588 return _PyLong_FromUid(getuid()); 6589} 6590#endif 6591 6592 6593#ifdef HAVE_KILL 6594PyDoc_STRVAR(posix_kill__doc__, 6595"kill(pid, sig)\n\n\ 6596Kill a process with a signal."); 6597 6598static PyObject * 6599posix_kill(PyObject *self, PyObject *args) 6600{ 6601 pid_t pid; 6602 int sig; 6603 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig)) 6604 return NULL; 6605 if (kill(pid, sig) == -1) 6606 return posix_error(); 6607 Py_INCREF(Py_None); 6608 return Py_None; 6609} 6610#endif 6611 6612#ifdef HAVE_KILLPG 6613PyDoc_STRVAR(posix_killpg__doc__, 6614"killpg(pgid, sig)\n\n\ 6615Kill a process group with a signal."); 6616 6617static PyObject * 6618posix_killpg(PyObject *self, PyObject *args) 6619{ 6620 int sig; 6621 pid_t pgid; 6622 /* XXX some man pages make the `pgid` parameter an int, others 6623 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should 6624 take the same type. Moreover, pid_t is always at least as wide as 6625 int (else compilation of this module fails), which is safe. */ 6626 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig)) 6627 return NULL; 6628 if (killpg(pgid, sig) == -1) 6629 return posix_error(); 6630 Py_INCREF(Py_None); 6631 return Py_None; 6632} 6633#endif 6634 6635#ifdef MS_WINDOWS 6636PyDoc_STRVAR(win32_kill__doc__, 6637"kill(pid, sig)\n\n\ 6638Kill a process with a signal."); 6639 6640static PyObject * 6641win32_kill(PyObject *self, PyObject *args) 6642{ 6643 PyObject *result; 6644 pid_t pid; 6645 DWORD sig, err; 6646 HANDLE handle; 6647 6648 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "k:kill", &pid, &sig)) 6649 return NULL; 6650 6651 /* Console processes which share a common console can be sent CTRL+C or 6652 CTRL+BREAK events, provided they handle said events. */ 6653 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) { 6654 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) { 6655 err = GetLastError(); 6656 PyErr_SetFromWindowsErr(err); 6657 } 6658 else 6659 Py_RETURN_NONE; 6660 } 6661 6662 /* If the signal is outside of what GenerateConsoleCtrlEvent can use, 6663 attempt to open and terminate the process. */ 6664 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid); 6665 if (handle == NULL) { 6666 err = GetLastError(); 6667 return PyErr_SetFromWindowsErr(err); 6668 } 6669 6670 if (TerminateProcess(handle, sig) == 0) { 6671 err = GetLastError(); 6672 result = PyErr_SetFromWindowsErr(err); 6673 } else { 6674 Py_INCREF(Py_None); 6675 result = Py_None; 6676 } 6677 6678 CloseHandle(handle); 6679 return result; 6680} 6681#endif /* MS_WINDOWS */ 6682 6683#ifdef HAVE_PLOCK 6684 6685#ifdef HAVE_SYS_LOCK_H 6686#include <sys/lock.h> 6687#endif 6688 6689PyDoc_STRVAR(posix_plock__doc__, 6690"plock(op)\n\n\ 6691Lock program segments into memory."); 6692 6693static PyObject * 6694posix_plock(PyObject *self, PyObject *args) 6695{ 6696 int op; 6697 if (!PyArg_ParseTuple(args, "i:plock", &op)) 6698 return NULL; 6699 if (plock(op) == -1) 6700 return posix_error(); 6701 Py_INCREF(Py_None); 6702 return Py_None; 6703} 6704#endif 6705 6706#ifdef HAVE_SETUID 6707PyDoc_STRVAR(posix_setuid__doc__, 6708"setuid(uid)\n\n\ 6709Set the current process's user id."); 6710 6711static PyObject * 6712posix_setuid(PyObject *self, PyObject *args) 6713{ 6714 uid_t uid; 6715 if (!PyArg_ParseTuple(args, "O&:setuid", _Py_Uid_Converter, &uid)) 6716 return NULL; 6717 if (setuid(uid) < 0) 6718 return posix_error(); 6719 Py_INCREF(Py_None); 6720 return Py_None; 6721} 6722#endif /* HAVE_SETUID */ 6723 6724 6725#ifdef HAVE_SETEUID 6726PyDoc_STRVAR(posix_seteuid__doc__, 6727"seteuid(uid)\n\n\ 6728Set the current process's effective user id."); 6729 6730static PyObject * 6731posix_seteuid (PyObject *self, PyObject *args) 6732{ 6733 uid_t euid; 6734 if (!PyArg_ParseTuple(args, "O&:seteuid", _Py_Uid_Converter, &euid)) 6735 return NULL; 6736 if (seteuid(euid) < 0) { 6737 return posix_error(); 6738 } else { 6739 Py_INCREF(Py_None); 6740 return Py_None; 6741 } 6742} 6743#endif /* HAVE_SETEUID */ 6744 6745#ifdef HAVE_SETEGID 6746PyDoc_STRVAR(posix_setegid__doc__, 6747"setegid(gid)\n\n\ 6748Set the current process's effective group id."); 6749 6750static PyObject * 6751posix_setegid (PyObject *self, PyObject *args) 6752{ 6753 gid_t egid; 6754 if (!PyArg_ParseTuple(args, "O&:setegid", _Py_Gid_Converter, &egid)) 6755 return NULL; 6756 if (setegid(egid) < 0) { 6757 return posix_error(); 6758 } else { 6759 Py_INCREF(Py_None); 6760 return Py_None; 6761 } 6762} 6763#endif /* HAVE_SETEGID */ 6764 6765#ifdef HAVE_SETREUID 6766PyDoc_STRVAR(posix_setreuid__doc__, 6767"setreuid(ruid, euid)\n\n\ 6768Set the current process's real and effective user ids."); 6769 6770static PyObject * 6771posix_setreuid (PyObject *self, PyObject *args) 6772{ 6773 uid_t ruid, euid; 6774 if (!PyArg_ParseTuple(args, "O&O&:setreuid", 6775 _Py_Uid_Converter, &ruid, 6776 _Py_Uid_Converter, &euid)) 6777 return NULL; 6778 if (setreuid(ruid, euid) < 0) { 6779 return posix_error(); 6780 } else { 6781 Py_INCREF(Py_None); 6782 return Py_None; 6783 } 6784} 6785#endif /* HAVE_SETREUID */ 6786 6787#ifdef HAVE_SETREGID 6788PyDoc_STRVAR(posix_setregid__doc__, 6789"setregid(rgid, egid)\n\n\ 6790Set the current process's real and effective group ids."); 6791 6792static PyObject * 6793posix_setregid (PyObject *self, PyObject *args) 6794{ 6795 gid_t rgid, egid; 6796 if (!PyArg_ParseTuple(args, "O&O&:setregid", 6797 _Py_Gid_Converter, &rgid, 6798 _Py_Gid_Converter, &egid)) 6799 return NULL; 6800 if (setregid(rgid, egid) < 0) { 6801 return posix_error(); 6802 } else { 6803 Py_INCREF(Py_None); 6804 return Py_None; 6805 } 6806} 6807#endif /* HAVE_SETREGID */ 6808 6809#ifdef HAVE_SETGID 6810PyDoc_STRVAR(posix_setgid__doc__, 6811"setgid(gid)\n\n\ 6812Set the current process's group id."); 6813 6814static PyObject * 6815posix_setgid(PyObject *self, PyObject *args) 6816{ 6817 gid_t gid; 6818 if (!PyArg_ParseTuple(args, "O&:setgid", _Py_Gid_Converter, &gid)) 6819 return NULL; 6820 if (setgid(gid) < 0) 6821 return posix_error(); 6822 Py_INCREF(Py_None); 6823 return Py_None; 6824} 6825#endif /* HAVE_SETGID */ 6826 6827#ifdef HAVE_SETGROUPS 6828PyDoc_STRVAR(posix_setgroups__doc__, 6829"setgroups(list)\n\n\ 6830Set the groups of the current process to list."); 6831 6832static PyObject * 6833posix_setgroups(PyObject *self, PyObject *groups) 6834{ 6835 int i, len; 6836 gid_t grouplist[MAX_GROUPS]; 6837 6838 if (!PySequence_Check(groups)) { 6839 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence"); 6840 return NULL; 6841 } 6842 len = PySequence_Size(groups); 6843 if (len > MAX_GROUPS) { 6844 PyErr_SetString(PyExc_ValueError, "too many groups"); 6845 return NULL; 6846 } 6847 for(i = 0; i < len; i++) { 6848 PyObject *elem; 6849 elem = PySequence_GetItem(groups, i); 6850 if (!elem) 6851 return NULL; 6852 if (!PyLong_Check(elem)) { 6853 PyErr_SetString(PyExc_TypeError, 6854 "groups must be integers"); 6855 Py_DECREF(elem); 6856 return NULL; 6857 } else { 6858 if (!_Py_Gid_Converter(elem, &grouplist[i])) { 6859 Py_DECREF(elem); 6860 return NULL; 6861 } 6862 } 6863 Py_DECREF(elem); 6864 } 6865 6866 if (setgroups(len, grouplist) < 0) 6867 return posix_error(); 6868 Py_INCREF(Py_None); 6869 return Py_None; 6870} 6871#endif /* HAVE_SETGROUPS */ 6872 6873#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4) 6874static PyObject * 6875wait_helper(pid_t pid, int status, struct rusage *ru) 6876{ 6877 PyObject *result; 6878 static PyObject *struct_rusage; 6879 _Py_IDENTIFIER(struct_rusage); 6880 6881 if (pid == -1) 6882 return posix_error(); 6883 6884 if (struct_rusage == NULL) { 6885 PyObject *m = PyImport_ImportModuleNoBlock("resource"); 6886 if (m == NULL) 6887 return NULL; 6888 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage); 6889 Py_DECREF(m); 6890 if (struct_rusage == NULL) 6891 return NULL; 6892 } 6893 6894 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */ 6895 result = PyStructSequence_New((PyTypeObject*) struct_rusage); 6896 if (!result) 6897 return NULL; 6898 6899#ifndef doubletime 6900#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001) 6901#endif 6902 6903 PyStructSequence_SET_ITEM(result, 0, 6904 PyFloat_FromDouble(doubletime(ru->ru_utime))); 6905 PyStructSequence_SET_ITEM(result, 1, 6906 PyFloat_FromDouble(doubletime(ru->ru_stime))); 6907#define SET_INT(result, index, value)\ 6908 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value)) 6909 SET_INT(result, 2, ru->ru_maxrss); 6910 SET_INT(result, 3, ru->ru_ixrss); 6911 SET_INT(result, 4, ru->ru_idrss); 6912 SET_INT(result, 5, ru->ru_isrss); 6913 SET_INT(result, 6, ru->ru_minflt); 6914 SET_INT(result, 7, ru->ru_majflt); 6915 SET_INT(result, 8, ru->ru_nswap); 6916 SET_INT(result, 9, ru->ru_inblock); 6917 SET_INT(result, 10, ru->ru_oublock); 6918 SET_INT(result, 11, ru->ru_msgsnd); 6919 SET_INT(result, 12, ru->ru_msgrcv); 6920 SET_INT(result, 13, ru->ru_nsignals); 6921 SET_INT(result, 14, ru->ru_nvcsw); 6922 SET_INT(result, 15, ru->ru_nivcsw); 6923#undef SET_INT 6924 6925 if (PyErr_Occurred()) { 6926 Py_DECREF(result); 6927 return NULL; 6928 } 6929 6930 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result); 6931} 6932#endif /* HAVE_WAIT3 || HAVE_WAIT4 */ 6933 6934#ifdef HAVE_WAIT3 6935PyDoc_STRVAR(posix_wait3__doc__, 6936"wait3(options) -> (pid, status, rusage)\n\n\ 6937Wait for completion of a child process."); 6938 6939static PyObject * 6940posix_wait3(PyObject *self, PyObject *args) 6941{ 6942 pid_t pid; 6943 int options; 6944 struct rusage ru; 6945 WAIT_TYPE status; 6946 WAIT_STATUS_INT(status) = 0; 6947 6948 if (!PyArg_ParseTuple(args, "i:wait3", &options)) 6949 return NULL; 6950 6951 Py_BEGIN_ALLOW_THREADS 6952 pid = wait3(&status, options, &ru); 6953 Py_END_ALLOW_THREADS 6954 6955 return wait_helper(pid, WAIT_STATUS_INT(status), &ru); 6956} 6957#endif /* HAVE_WAIT3 */ 6958 6959#ifdef HAVE_WAIT4 6960PyDoc_STRVAR(posix_wait4__doc__, 6961"wait4(pid, options) -> (pid, status, rusage)\n\n\ 6962Wait for completion of a given child process."); 6963 6964static PyObject * 6965posix_wait4(PyObject *self, PyObject *args) 6966{ 6967 pid_t pid; 6968 int options; 6969 struct rusage ru; 6970 WAIT_TYPE status; 6971 WAIT_STATUS_INT(status) = 0; 6972 6973 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options)) 6974 return NULL; 6975 6976 Py_BEGIN_ALLOW_THREADS 6977 pid = wait4(pid, &status, options, &ru); 6978 Py_END_ALLOW_THREADS 6979 6980 return wait_helper(pid, WAIT_STATUS_INT(status), &ru); 6981} 6982#endif /* HAVE_WAIT4 */ 6983 6984#if defined(HAVE_WAITID) && !defined(__APPLE__) 6985PyDoc_STRVAR(posix_waitid__doc__, 6986"waitid(idtype, id, options) -> waitid_result\n\n\ 6987Wait for the completion of one or more child processes.\n\n\ 6988idtype can be P_PID, P_PGID or P_ALL.\n\ 6989id specifies the pid to wait on.\n\ 6990options is constructed from the ORing of one or more of WEXITED, WSTOPPED\n\ 6991or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.\n\ 6992Returns either waitid_result or None if WNOHANG is specified and there are\n\ 6993no children in a waitable state."); 6994 6995static PyObject * 6996posix_waitid(PyObject *self, PyObject *args) 6997{ 6998 PyObject *result; 6999 idtype_t idtype; 7000 id_t id; 7001 int options, res; 7002 siginfo_t si; 7003 si.si_pid = 0; 7004 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID "i:waitid", &idtype, &id, &options)) 7005 return NULL; 7006 Py_BEGIN_ALLOW_THREADS 7007 res = waitid(idtype, id, &si, options); 7008 Py_END_ALLOW_THREADS 7009 if (res == -1) 7010 return posix_error(); 7011 7012 if (si.si_pid == 0) 7013 Py_RETURN_NONE; 7014 7015 result = PyStructSequence_New(&WaitidResultType); 7016 if (!result) 7017 return NULL; 7018 7019 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid)); 7020 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid)); 7021 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo))); 7022 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status))); 7023 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code))); 7024 if (PyErr_Occurred()) { 7025 Py_DECREF(result); 7026 return NULL; 7027 } 7028 7029 return result; 7030} 7031#endif 7032 7033#ifdef HAVE_WAITPID 7034PyDoc_STRVAR(posix_waitpid__doc__, 7035"waitpid(pid, options) -> (pid, status)\n\n\ 7036Wait for completion of a given child process."); 7037 7038static PyObject * 7039posix_waitpid(PyObject *self, PyObject *args) 7040{ 7041 pid_t pid; 7042 int options; 7043 WAIT_TYPE status; 7044 WAIT_STATUS_INT(status) = 0; 7045 7046 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options)) 7047 return NULL; 7048 Py_BEGIN_ALLOW_THREADS 7049 pid = waitpid(pid, &status, options); 7050 Py_END_ALLOW_THREADS 7051 if (pid == -1) 7052 return posix_error(); 7053 7054 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status)); 7055} 7056 7057#elif defined(HAVE_CWAIT) 7058 7059/* MS C has a variant of waitpid() that's usable for most purposes. */ 7060PyDoc_STRVAR(posix_waitpid__doc__, 7061"waitpid(pid, options) -> (pid, status << 8)\n\n" 7062"Wait for completion of a given process. options is ignored on Windows."); 7063 7064static PyObject * 7065posix_waitpid(PyObject *self, PyObject *args) 7066{ 7067 Py_intptr_t pid; 7068 int status, options; 7069 7070 if (!PyArg_ParseTuple(args, _Py_PARSE_INTPTR "i:waitpid", &pid, &options)) 7071 return NULL; 7072 Py_BEGIN_ALLOW_THREADS 7073 pid = _cwait(&status, pid, options); 7074 Py_END_ALLOW_THREADS 7075 if (pid == -1) 7076 return posix_error(); 7077 7078 /* shift the status left a byte so this is more like the POSIX waitpid */ 7079 return Py_BuildValue(_Py_PARSE_INTPTR "i", pid, status << 8); 7080} 7081#endif /* HAVE_WAITPID || HAVE_CWAIT */ 7082 7083#ifdef HAVE_WAIT 7084PyDoc_STRVAR(posix_wait__doc__, 7085"wait() -> (pid, status)\n\n\ 7086Wait for completion of a child process."); 7087 7088static PyObject * 7089posix_wait(PyObject *self, PyObject *noargs) 7090{ 7091 pid_t pid; 7092 WAIT_TYPE status; 7093 WAIT_STATUS_INT(status) = 0; 7094 7095 Py_BEGIN_ALLOW_THREADS 7096 pid = wait(&status); 7097 Py_END_ALLOW_THREADS 7098 if (pid == -1) 7099 return posix_error(); 7100 7101 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status)); 7102} 7103#endif 7104 7105 7106#if defined(HAVE_READLINK) || defined(MS_WINDOWS) 7107PyDoc_STRVAR(readlink__doc__, 7108"readlink(path, *, dir_fd=None) -> path\n\n\ 7109Return a string representing the path to which the symbolic link points.\n\ 7110\n\ 7111If dir_fd is not None, it should be a file descriptor open to a directory,\n\ 7112 and path should be relative; path will then be relative to that directory.\n\ 7113dir_fd may not be implemented on your platform.\n\ 7114 If it is unavailable, using it will raise a NotImplementedError."); 7115#endif 7116 7117#ifdef HAVE_READLINK 7118 7119static PyObject * 7120posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs) 7121{ 7122 path_t path; 7123 int dir_fd = DEFAULT_DIR_FD; 7124 char buffer[MAXPATHLEN]; 7125 ssize_t length; 7126 PyObject *return_value = NULL; 7127 static char *keywords[] = {"path", "dir_fd", NULL}; 7128 7129 memset(&path, 0, sizeof(path)); 7130 path.function_name = "readlink"; 7131 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords, 7132 path_converter, &path, 7133#ifdef HAVE_READLINKAT 7134 dir_fd_converter, &dir_fd 7135#else 7136 dir_fd_unavailable, &dir_fd 7137#endif 7138 )) 7139 return NULL; 7140 7141 Py_BEGIN_ALLOW_THREADS 7142#ifdef HAVE_READLINKAT 7143 if (dir_fd != DEFAULT_DIR_FD) 7144 length = readlinkat(dir_fd, path.narrow, buffer, sizeof(buffer)); 7145 else 7146#endif 7147 length = readlink(path.narrow, buffer, sizeof(buffer)); 7148 Py_END_ALLOW_THREADS 7149 7150 if (length < 0) { 7151 return_value = path_error(&path); 7152 goto exit; 7153 } 7154 7155 if (PyUnicode_Check(path.object)) 7156 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length); 7157 else 7158 return_value = PyBytes_FromStringAndSize(buffer, length); 7159exit: 7160 path_cleanup(&path); 7161 return return_value; 7162} 7163 7164 7165#endif /* HAVE_READLINK */ 7166 7167 7168#ifdef HAVE_SYMLINK 7169PyDoc_STRVAR(posix_symlink__doc__, 7170"symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\ 7171Create a symbolic link pointing to src named dst.\n\n\ 7172target_is_directory is required on Windows if the target is to be\n\ 7173 interpreted as a directory. (On Windows, symlink requires\n\ 7174 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)\n\ 7175 target_is_directory is ignored on non-Windows platforms.\n\ 7176\n\ 7177If dir_fd is not None, it should be a file descriptor open to a directory,\n\ 7178 and path should be relative; path will then be relative to that directory.\n\ 7179dir_fd may not be implemented on your platform.\n\ 7180 If it is unavailable, using it will raise a NotImplementedError."); 7181 7182#if defined(MS_WINDOWS) 7183 7184/* Grab CreateSymbolicLinkW dynamically from kernel32 */ 7185static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD) = NULL; 7186static DWORD (CALLBACK *Py_CreateSymbolicLinkA)(LPSTR, LPSTR, DWORD) = NULL; 7187 7188static int 7189check_CreateSymbolicLink(void) 7190{ 7191 HINSTANCE hKernel32; 7192 /* only recheck */ 7193 if (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA) 7194 return 1; 7195 hKernel32 = GetModuleHandleW(L"KERNEL32"); 7196 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32, 7197 "CreateSymbolicLinkW"); 7198 *(FARPROC*)&Py_CreateSymbolicLinkA = GetProcAddress(hKernel32, 7199 "CreateSymbolicLinkA"); 7200 return (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA); 7201} 7202 7203/* Remove the last portion of the path */ 7204static void 7205_dirnameW(WCHAR *path) 7206{ 7207 WCHAR *ptr; 7208 7209 /* walk the path from the end until a backslash is encountered */ 7210 for(ptr = path + wcslen(path); ptr != path; ptr--) { 7211 if (*ptr == L'\\' || *ptr == L'/') 7212 break; 7213 } 7214 *ptr = 0; 7215} 7216 7217/* Remove the last portion of the path */ 7218static void 7219_dirnameA(char *path) 7220{ 7221 char *ptr; 7222 7223 /* walk the path from the end until a backslash is encountered */ 7224 for(ptr = path + strlen(path); ptr != path; ptr--) { 7225 if (*ptr == '\\' || *ptr == '/') 7226 break; 7227 } 7228 *ptr = 0; 7229} 7230 7231/* Is this path absolute? */ 7232static int 7233_is_absW(const WCHAR *path) 7234{ 7235 return path[0] == L'\\' || path[0] == L'/' || path[1] == L':'; 7236 7237} 7238 7239/* Is this path absolute? */ 7240static int 7241_is_absA(const char *path) 7242{ 7243 return path[0] == '\\' || path[0] == '/' || path[1] == ':'; 7244 7245} 7246 7247/* join root and rest with a backslash */ 7248static void 7249_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest) 7250{ 7251 size_t root_len; 7252 7253 if (_is_absW(rest)) { 7254 wcscpy(dest_path, rest); 7255 return; 7256 } 7257 7258 root_len = wcslen(root); 7259 7260 wcscpy(dest_path, root); 7261 if(root_len) { 7262 dest_path[root_len] = L'\\'; 7263 root_len++; 7264 } 7265 wcscpy(dest_path+root_len, rest); 7266} 7267 7268/* join root and rest with a backslash */ 7269static void 7270_joinA(char *dest_path, const char *root, const char *rest) 7271{ 7272 size_t root_len; 7273 7274 if (_is_absA(rest)) { 7275 strcpy(dest_path, rest); 7276 return; 7277 } 7278 7279 root_len = strlen(root); 7280 7281 strcpy(dest_path, root); 7282 if(root_len) { 7283 dest_path[root_len] = '\\'; 7284 root_len++; 7285 } 7286 strcpy(dest_path+root_len, rest); 7287} 7288 7289/* Return True if the path at src relative to dest is a directory */ 7290static int 7291_check_dirW(WCHAR *src, WCHAR *dest) 7292{ 7293 WIN32_FILE_ATTRIBUTE_DATA src_info; 7294 WCHAR dest_parent[MAX_PATH]; 7295 WCHAR src_resolved[MAX_PATH] = L""; 7296 7297 /* dest_parent = os.path.dirname(dest) */ 7298 wcscpy(dest_parent, dest); 7299 _dirnameW(dest_parent); 7300 /* src_resolved = os.path.join(dest_parent, src) */ 7301 _joinW(src_resolved, dest_parent, src); 7302 return ( 7303 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info) 7304 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY 7305 ); 7306} 7307 7308/* Return True if the path at src relative to dest is a directory */ 7309static int 7310_check_dirA(char *src, char *dest) 7311{ 7312 WIN32_FILE_ATTRIBUTE_DATA src_info; 7313 char dest_parent[MAX_PATH]; 7314 char src_resolved[MAX_PATH] = ""; 7315 7316 /* dest_parent = os.path.dirname(dest) */ 7317 strcpy(dest_parent, dest); 7318 _dirnameA(dest_parent); 7319 /* src_resolved = os.path.join(dest_parent, src) */ 7320 _joinA(src_resolved, dest_parent, src); 7321 return ( 7322 GetFileAttributesExA(src_resolved, GetFileExInfoStandard, &src_info) 7323 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY 7324 ); 7325} 7326 7327#endif 7328 7329static PyObject * 7330posix_symlink(PyObject *self, PyObject *args, PyObject *kwargs) 7331{ 7332 path_t src; 7333 path_t dst; 7334 int dir_fd = DEFAULT_DIR_FD; 7335 int target_is_directory = 0; 7336 static char *keywords[] = {"src", "dst", "target_is_directory", 7337 "dir_fd", NULL}; 7338 PyObject *return_value; 7339#ifdef MS_WINDOWS 7340 DWORD result; 7341#else 7342 int result; 7343#endif 7344 7345 memset(&src, 0, sizeof(src)); 7346 src.function_name = "symlink"; 7347 src.argument_name = "src"; 7348 memset(&dst, 0, sizeof(dst)); 7349 dst.function_name = "symlink"; 7350 dst.argument_name = "dst"; 7351 7352#ifdef MS_WINDOWS 7353 if (!check_CreateSymbolicLink()) { 7354 PyErr_SetString(PyExc_NotImplementedError, 7355 "CreateSymbolicLink functions not found"); 7356 return NULL; 7357 } 7358 if (!win32_can_symlink) { 7359 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held"); 7360 return NULL; 7361 } 7362#endif 7363 7364 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|i$O&:symlink", 7365 keywords, 7366 path_converter, &src, 7367 path_converter, &dst, 7368 &target_is_directory, 7369#ifdef HAVE_SYMLINKAT 7370 dir_fd_converter, &dir_fd 7371#else 7372 dir_fd_unavailable, &dir_fd 7373#endif 7374 )) 7375 return NULL; 7376 7377 if ((src.narrow && dst.wide) || (src.wide && dst.narrow)) { 7378 PyErr_SetString(PyExc_ValueError, 7379 "symlink: src and dst must be the same type"); 7380 return_value = NULL; 7381 goto exit; 7382 } 7383 7384#ifdef MS_WINDOWS 7385 7386 Py_BEGIN_ALLOW_THREADS 7387 if (dst.wide) { 7388 /* if src is a directory, ensure target_is_directory==1 */ 7389 target_is_directory |= _check_dirW(src.wide, dst.wide); 7390 result = Py_CreateSymbolicLinkW(dst.wide, src.wide, 7391 target_is_directory); 7392 } 7393 else { 7394 /* if src is a directory, ensure target_is_directory==1 */ 7395 target_is_directory |= _check_dirA(src.narrow, dst.narrow); 7396 result = Py_CreateSymbolicLinkA(dst.narrow, src.narrow, 7397 target_is_directory); 7398 } 7399 Py_END_ALLOW_THREADS 7400 7401 if (!result) { 7402 return_value = path_error2(&src, &dst); 7403 goto exit; 7404 } 7405 7406#else 7407 7408 Py_BEGIN_ALLOW_THREADS 7409#if HAVE_SYMLINKAT 7410 if (dir_fd != DEFAULT_DIR_FD) 7411 result = symlinkat(src.narrow, dir_fd, dst.narrow); 7412 else 7413#endif 7414 result = symlink(src.narrow, dst.narrow); 7415 Py_END_ALLOW_THREADS 7416 7417 if (result) { 7418 return_value = path_error2(&src, &dst); 7419 goto exit; 7420 } 7421#endif 7422 7423 return_value = Py_None; 7424 Py_INCREF(Py_None); 7425 goto exit; /* silence "unused label" warning */ 7426exit: 7427 path_cleanup(&src); 7428 path_cleanup(&dst); 7429 return return_value; 7430} 7431 7432#endif /* HAVE_SYMLINK */ 7433 7434 7435#if !defined(HAVE_READLINK) && defined(MS_WINDOWS) 7436 7437static PyObject * 7438win_readlink(PyObject *self, PyObject *args, PyObject *kwargs) 7439{ 7440 wchar_t *path; 7441 DWORD n_bytes_returned; 7442 DWORD io_result; 7443 PyObject *po, *result; 7444 int dir_fd; 7445 HANDLE reparse_point_handle; 7446 7447 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; 7448 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer; 7449 wchar_t *print_name; 7450 7451 static char *keywords[] = {"path", "dir_fd", NULL}; 7452 7453 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords, 7454 &po, 7455 dir_fd_unavailable, &dir_fd 7456 )) 7457 return NULL; 7458 7459 path = PyUnicode_AsUnicode(po); 7460 if (path == NULL) 7461 return NULL; 7462 7463 /* First get a handle to the reparse point */ 7464 Py_BEGIN_ALLOW_THREADS 7465 reparse_point_handle = CreateFileW( 7466 path, 7467 0, 7468 0, 7469 0, 7470 OPEN_EXISTING, 7471 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, 7472 0); 7473 Py_END_ALLOW_THREADS 7474 7475 if (reparse_point_handle==INVALID_HANDLE_VALUE) 7476 return win32_error_object("readlink", po); 7477 7478 Py_BEGIN_ALLOW_THREADS 7479 /* New call DeviceIoControl to read the reparse point */ 7480 io_result = DeviceIoControl( 7481 reparse_point_handle, 7482 FSCTL_GET_REPARSE_POINT, 7483 0, 0, /* in buffer */ 7484 target_buffer, sizeof(target_buffer), 7485 &n_bytes_returned, 7486 0 /* we're not using OVERLAPPED_IO */ 7487 ); 7488 CloseHandle(reparse_point_handle); 7489 Py_END_ALLOW_THREADS 7490 7491 if (io_result==0) 7492 return win32_error_object("readlink", po); 7493 7494 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK) 7495 { 7496 PyErr_SetString(PyExc_ValueError, 7497 "not a symbolic link"); 7498 return NULL; 7499 } 7500 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer + 7501 rdb->SymbolicLinkReparseBuffer.PrintNameOffset; 7502 7503 result = PyUnicode_FromWideChar(print_name, 7504 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2); 7505 return result; 7506} 7507 7508#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */ 7509 7510 7511static PyStructSequence_Field times_result_fields[] = { 7512 {"user", "user time"}, 7513 {"system", "system time"}, 7514 {"children_user", "user time of children"}, 7515 {"children_system", "system time of children"}, 7516 {"elapsed", "elapsed time since an arbitrary point in the past"}, 7517 {NULL} 7518}; 7519 7520PyDoc_STRVAR(times_result__doc__, 7521"times_result: Result from os.times().\n\n\ 7522This object may be accessed either as a tuple of\n\ 7523 (user, system, children_user, children_system, elapsed),\n\ 7524or via the attributes user, system, children_user, children_system,\n\ 7525and elapsed.\n\ 7526\n\ 7527See os.times for more information."); 7528 7529static PyStructSequence_Desc times_result_desc = { 7530 "times_result", /* name */ 7531 times_result__doc__, /* doc */ 7532 times_result_fields, 7533 5 7534}; 7535 7536static PyTypeObject TimesResultType; 7537 7538#ifdef MS_WINDOWS 7539#define HAVE_TIMES /* mandatory, for the method table */ 7540#endif 7541 7542#ifdef HAVE_TIMES 7543 7544static PyObject * 7545build_times_result(double user, double system, 7546 double children_user, double children_system, 7547 double elapsed) 7548{ 7549 PyObject *value = PyStructSequence_New(&TimesResultType); 7550 if (value == NULL) 7551 return NULL; 7552 7553#define SET(i, field) \ 7554 { \ 7555 PyObject *o = PyFloat_FromDouble(field); \ 7556 if (!o) { \ 7557 Py_DECREF(value); \ 7558 return NULL; \ 7559 } \ 7560 PyStructSequence_SET_ITEM(value, i, o); \ 7561 } \ 7562 7563 SET(0, user); 7564 SET(1, system); 7565 SET(2, children_user); 7566 SET(3, children_system); 7567 SET(4, elapsed); 7568 7569#undef SET 7570 7571 return value; 7572} 7573 7574PyDoc_STRVAR(posix_times__doc__, 7575"times() -> times_result\n\n\ 7576Return an object containing floating point numbers indicating process\n\ 7577times. The object behaves like a named tuple with these fields:\n\ 7578 (utime, stime, cutime, cstime, elapsed_time)"); 7579 7580#if defined(MS_WINDOWS) 7581static PyObject * 7582posix_times(PyObject *self, PyObject *noargs) 7583{ 7584 FILETIME create, exit, kernel, user; 7585 HANDLE hProc; 7586 hProc = GetCurrentProcess(); 7587 GetProcessTimes(hProc, &create, &exit, &kernel, &user); 7588 /* The fields of a FILETIME structure are the hi and lo part 7589 of a 64-bit value expressed in 100 nanosecond units. 7590 1e7 is one second in such units; 1e-7 the inverse. 7591 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7. 7592 */ 7593 return build_times_result( 7594 (double)(user.dwHighDateTime*429.4967296 + 7595 user.dwLowDateTime*1e-7), 7596 (double)(kernel.dwHighDateTime*429.4967296 + 7597 kernel.dwLowDateTime*1e-7), 7598 (double)0, 7599 (double)0, 7600 (double)0); 7601} 7602#else /* Not Windows */ 7603#define NEED_TICKS_PER_SECOND 7604static long ticks_per_second = -1; 7605static PyObject * 7606posix_times(PyObject *self, PyObject *noargs) 7607{ 7608 struct tms t; 7609 clock_t c; 7610 errno = 0; 7611 c = times(&t); 7612 if (c == (clock_t) -1) 7613 return posix_error(); 7614 return build_times_result( 7615 (double)t.tms_utime / ticks_per_second, 7616 (double)t.tms_stime / ticks_per_second, 7617 (double)t.tms_cutime / ticks_per_second, 7618 (double)t.tms_cstime / ticks_per_second, 7619 (double)c / ticks_per_second); 7620} 7621#endif 7622 7623#endif /* HAVE_TIMES */ 7624 7625 7626#ifdef HAVE_GETSID 7627PyDoc_STRVAR(posix_getsid__doc__, 7628"getsid(pid) -> sid\n\n\ 7629Call the system call getsid()."); 7630 7631static PyObject * 7632posix_getsid(PyObject *self, PyObject *args) 7633{ 7634 pid_t pid; 7635 int sid; 7636 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid)) 7637 return NULL; 7638 sid = getsid(pid); 7639 if (sid < 0) 7640 return posix_error(); 7641 return PyLong_FromLong((long)sid); 7642} 7643#endif /* HAVE_GETSID */ 7644 7645 7646#ifdef HAVE_SETSID 7647PyDoc_STRVAR(posix_setsid__doc__, 7648"setsid()\n\n\ 7649Call the system call setsid()."); 7650 7651static PyObject * 7652posix_setsid(PyObject *self, PyObject *noargs) 7653{ 7654 if (setsid() < 0) 7655 return posix_error(); 7656 Py_INCREF(Py_None); 7657 return Py_None; 7658} 7659#endif /* HAVE_SETSID */ 7660 7661#ifdef HAVE_SETPGID 7662PyDoc_STRVAR(posix_setpgid__doc__, 7663"setpgid(pid, pgrp)\n\n\ 7664Call the system call setpgid()."); 7665 7666static PyObject * 7667posix_setpgid(PyObject *self, PyObject *args) 7668{ 7669 pid_t pid; 7670 int pgrp; 7671 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp)) 7672 return NULL; 7673 if (setpgid(pid, pgrp) < 0) 7674 return posix_error(); 7675 Py_INCREF(Py_None); 7676 return Py_None; 7677} 7678#endif /* HAVE_SETPGID */ 7679 7680 7681#ifdef HAVE_TCGETPGRP 7682PyDoc_STRVAR(posix_tcgetpgrp__doc__, 7683"tcgetpgrp(fd) -> pgid\n\n\ 7684Return the process group associated with the terminal given by a fd."); 7685 7686static PyObject * 7687posix_tcgetpgrp(PyObject *self, PyObject *args) 7688{ 7689 int fd; 7690 pid_t pgid; 7691 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd)) 7692 return NULL; 7693 pgid = tcgetpgrp(fd); 7694 if (pgid < 0) 7695 return posix_error(); 7696 return PyLong_FromPid(pgid); 7697} 7698#endif /* HAVE_TCGETPGRP */ 7699 7700 7701#ifdef HAVE_TCSETPGRP 7702PyDoc_STRVAR(posix_tcsetpgrp__doc__, 7703"tcsetpgrp(fd, pgid)\n\n\ 7704Set the process group associated with the terminal given by a fd."); 7705 7706static PyObject * 7707posix_tcsetpgrp(PyObject *self, PyObject *args) 7708{ 7709 int fd; 7710 pid_t pgid; 7711 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid)) 7712 return NULL; 7713 if (tcsetpgrp(fd, pgid) < 0) 7714 return posix_error(); 7715 Py_INCREF(Py_None); 7716 return Py_None; 7717} 7718#endif /* HAVE_TCSETPGRP */ 7719 7720/* Functions acting on file descriptors */ 7721 7722#ifdef O_CLOEXEC 7723extern int _Py_open_cloexec_works; 7724#endif 7725 7726PyDoc_STRVAR(posix_open__doc__, 7727"open(path, flags, mode=0o777, *, dir_fd=None)\n\n\ 7728Open a file for low level IO. Returns a file handle (integer).\n\ 7729\n\ 7730If dir_fd is not None, it should be a file descriptor open to a directory,\n\ 7731 and path should be relative; path will then be relative to that directory.\n\ 7732dir_fd may not be implemented on your platform.\n\ 7733 If it is unavailable, using it will raise a NotImplementedError."); 7734 7735static PyObject * 7736posix_open(PyObject *self, PyObject *args, PyObject *kwargs) 7737{ 7738 path_t path; 7739 int flags; 7740 int mode = 0777; 7741 int dir_fd = DEFAULT_DIR_FD; 7742 int fd; 7743 PyObject *return_value = NULL; 7744 static char *keywords[] = {"path", "flags", "mode", "dir_fd", NULL}; 7745#ifdef O_CLOEXEC 7746 int *atomic_flag_works = &_Py_open_cloexec_works; 7747#elif !defined(MS_WINDOWS) 7748 int *atomic_flag_works = NULL; 7749#endif 7750 7751 memset(&path, 0, sizeof(path)); 7752 path.function_name = "open"; 7753 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&i|i$O&:open", keywords, 7754 path_converter, &path, 7755 &flags, &mode, 7756#ifdef HAVE_OPENAT 7757 dir_fd_converter, &dir_fd 7758#else 7759 dir_fd_unavailable, &dir_fd 7760#endif 7761 )) 7762 return NULL; 7763 7764#ifdef MS_WINDOWS 7765 flags |= O_NOINHERIT; 7766#elif defined(O_CLOEXEC) 7767 flags |= O_CLOEXEC; 7768#endif 7769 7770 Py_BEGIN_ALLOW_THREADS 7771#ifdef MS_WINDOWS 7772 if (path.wide) 7773 fd = _wopen(path.wide, flags, mode); 7774 else 7775#endif 7776#ifdef HAVE_OPENAT 7777 if (dir_fd != DEFAULT_DIR_FD) 7778 fd = openat(dir_fd, path.narrow, flags, mode); 7779 else 7780#endif 7781 fd = open(path.narrow, flags, mode); 7782 Py_END_ALLOW_THREADS 7783 7784 if (fd == -1) { 7785 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path.object); 7786 goto exit; 7787 } 7788 7789#ifndef MS_WINDOWS 7790 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) { 7791 close(fd); 7792 goto exit; 7793 } 7794#endif 7795 7796 return_value = PyLong_FromLong((long)fd); 7797 7798exit: 7799 path_cleanup(&path); 7800 return return_value; 7801} 7802 7803PyDoc_STRVAR(posix_close__doc__, 7804"close(fd)\n\n\ 7805Close a file descriptor (for low level IO)."); 7806 7807/* 7808The underscore at end of function name avoids a name clash with the libc 7809function posix_close. 7810*/ 7811static PyObject * 7812posix_close_(PyObject *self, PyObject *args) 7813{ 7814 int fd, res; 7815 if (!PyArg_ParseTuple(args, "i:close", &fd)) 7816 return NULL; 7817 if (!_PyVerify_fd(fd)) 7818 return posix_error(); 7819 Py_BEGIN_ALLOW_THREADS 7820 res = close(fd); 7821 Py_END_ALLOW_THREADS 7822 if (res < 0) 7823 return posix_error(); 7824 Py_INCREF(Py_None); 7825 return Py_None; 7826} 7827 7828 7829PyDoc_STRVAR(posix_closerange__doc__, 7830"closerange(fd_low, fd_high)\n\n\ 7831Closes all file descriptors in [fd_low, fd_high), ignoring errors."); 7832 7833static PyObject * 7834posix_closerange(PyObject *self, PyObject *args) 7835{ 7836 int fd_from, fd_to, i; 7837 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to)) 7838 return NULL; 7839 Py_BEGIN_ALLOW_THREADS 7840 for (i = fd_from; i < fd_to; i++) 7841 if (_PyVerify_fd(i)) 7842 close(i); 7843 Py_END_ALLOW_THREADS 7844 Py_RETURN_NONE; 7845} 7846 7847 7848PyDoc_STRVAR(posix_dup__doc__, 7849"dup(fd) -> fd2\n\n\ 7850Return a duplicate of a file descriptor."); 7851 7852static PyObject * 7853posix_dup(PyObject *self, PyObject *args) 7854{ 7855 int fd; 7856 7857 if (!PyArg_ParseTuple(args, "i:dup", &fd)) 7858 return NULL; 7859 7860 fd = _Py_dup(fd); 7861 if (fd == -1) 7862 return NULL; 7863 7864 return PyLong_FromLong((long)fd); 7865} 7866 7867 7868PyDoc_STRVAR(posix_dup2__doc__, 7869"dup2(old_fd, new_fd)\n\n\ 7870Duplicate file descriptor."); 7871 7872static PyObject * 7873posix_dup2(PyObject *self, PyObject *args, PyObject *kwargs) 7874{ 7875 static char *keywords[] = {"fd", "fd2", "inheritable", NULL}; 7876 int fd, fd2; 7877 int inheritable = 1; 7878 int res; 7879#if defined(HAVE_DUP3) && \ 7880 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)) 7881 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */ 7882 int dup3_works = -1; 7883#endif 7884 7885 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii|i:dup2", keywords, 7886 &fd, &fd2, &inheritable)) 7887 return NULL; 7888 7889 if (!_PyVerify_fd_dup2(fd, fd2)) 7890 return posix_error(); 7891 7892#ifdef MS_WINDOWS 7893 Py_BEGIN_ALLOW_THREADS 7894 res = dup2(fd, fd2); 7895 Py_END_ALLOW_THREADS 7896 if (res < 0) 7897 return posix_error(); 7898 7899 /* Character files like console cannot be make non-inheritable */ 7900 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) { 7901 close(fd2); 7902 return NULL; 7903 } 7904 7905#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC) 7906 Py_BEGIN_ALLOW_THREADS 7907 if (!inheritable) 7908 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2); 7909 else 7910 res = dup2(fd, fd2); 7911 Py_END_ALLOW_THREADS 7912 if (res < 0) 7913 return posix_error(); 7914 7915#else 7916 7917#ifdef HAVE_DUP3 7918 if (!inheritable && dup3_works != 0) { 7919 Py_BEGIN_ALLOW_THREADS 7920 res = dup3(fd, fd2, O_CLOEXEC); 7921 Py_END_ALLOW_THREADS 7922 if (res < 0) { 7923 if (dup3_works == -1) 7924 dup3_works = (errno != ENOSYS); 7925 if (dup3_works) 7926 return posix_error(); 7927 } 7928 } 7929 7930 if (inheritable || dup3_works == 0) 7931 { 7932#endif 7933 Py_BEGIN_ALLOW_THREADS 7934 res = dup2(fd, fd2); 7935 Py_END_ALLOW_THREADS 7936 if (res < 0) 7937 return posix_error(); 7938 7939 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) { 7940 close(fd2); 7941 return NULL; 7942 } 7943#ifdef HAVE_DUP3 7944 } 7945#endif 7946 7947#endif 7948 7949 Py_INCREF(Py_None); 7950 return Py_None; 7951} 7952 7953#ifdef HAVE_LOCKF 7954PyDoc_STRVAR(posix_lockf__doc__, 7955"lockf(fd, cmd, len)\n\n\ 7956Apply, test or remove a POSIX lock on an open file descriptor.\n\n\ 7957fd is an open file descriptor.\n\ 7958cmd specifies the command to use - one of F_LOCK, F_TLOCK, F_ULOCK or\n\ 7959F_TEST.\n\ 7960len specifies the section of the file to lock."); 7961 7962static PyObject * 7963posix_lockf(PyObject *self, PyObject *args) 7964{ 7965 int fd, cmd, res; 7966 off_t len; 7967 if (!PyArg_ParseTuple(args, "iiO&:lockf", 7968 &fd, &cmd, _parse_off_t, &len)) 7969 return NULL; 7970 7971 Py_BEGIN_ALLOW_THREADS 7972 res = lockf(fd, cmd, len); 7973 Py_END_ALLOW_THREADS 7974 7975 if (res < 0) 7976 return posix_error(); 7977 7978 Py_RETURN_NONE; 7979} 7980#endif 7981 7982 7983PyDoc_STRVAR(posix_lseek__doc__, 7984"lseek(fd, pos, how) -> newpos\n\n\ 7985Set the current position of a file descriptor.\n\ 7986Return the new cursor position in bytes, starting from the beginning."); 7987 7988static PyObject * 7989posix_lseek(PyObject *self, PyObject *args) 7990{ 7991 int fd, how; 7992#ifdef MS_WINDOWS 7993 PY_LONG_LONG pos, res; 7994#else 7995 off_t pos, res; 7996#endif 7997 PyObject *posobj; 7998 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how)) 7999 return NULL; 8000#ifdef SEEK_SET 8001 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */ 8002 switch (how) { 8003 case 0: how = SEEK_SET; break; 8004 case 1: how = SEEK_CUR; break; 8005 case 2: how = SEEK_END; break; 8006 } 8007#endif /* SEEK_END */ 8008 8009#if !defined(HAVE_LARGEFILE_SUPPORT) 8010 pos = PyLong_AsLong(posobj); 8011#else 8012 pos = PyLong_AsLongLong(posobj); 8013#endif 8014 if (PyErr_Occurred()) 8015 return NULL; 8016 8017 if (!_PyVerify_fd(fd)) 8018 return posix_error(); 8019 Py_BEGIN_ALLOW_THREADS 8020#ifdef MS_WINDOWS 8021 res = _lseeki64(fd, pos, how); 8022#else 8023 res = lseek(fd, pos, how); 8024#endif 8025 Py_END_ALLOW_THREADS 8026 if (res < 0) 8027 return posix_error(); 8028 8029#if !defined(HAVE_LARGEFILE_SUPPORT) 8030 return PyLong_FromLong(res); 8031#else 8032 return PyLong_FromLongLong(res); 8033#endif 8034} 8035 8036 8037PyDoc_STRVAR(posix_read__doc__, 8038"read(fd, buffersize) -> bytes\n\n\ 8039Read a file descriptor."); 8040 8041static PyObject * 8042posix_read(PyObject *self, PyObject *args) 8043{ 8044 int fd, size; 8045 Py_ssize_t n; 8046 PyObject *buffer; 8047 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size)) 8048 return NULL; 8049 if (size < 0) { 8050 errno = EINVAL; 8051 return posix_error(); 8052 } 8053 buffer = PyBytes_FromStringAndSize((char *)NULL, size); 8054 if (buffer == NULL) 8055 return NULL; 8056 if (!_PyVerify_fd(fd)) { 8057 Py_DECREF(buffer); 8058 return posix_error(); 8059 } 8060 Py_BEGIN_ALLOW_THREADS 8061 n = read(fd, PyBytes_AS_STRING(buffer), size); 8062 Py_END_ALLOW_THREADS 8063 if (n < 0) { 8064 Py_DECREF(buffer); 8065 return posix_error(); 8066 } 8067 if (n != size) 8068 _PyBytes_Resize(&buffer, n); 8069 return buffer; 8070} 8071 8072#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \ 8073 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV) 8074static Py_ssize_t 8075iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type) 8076{ 8077 int i, j; 8078 Py_ssize_t blen, total = 0; 8079 8080 *iov = PyMem_New(struct iovec, cnt); 8081 if (*iov == NULL) { 8082 PyErr_NoMemory(); 8083 return -1; 8084 } 8085 8086 *buf = PyMem_New(Py_buffer, cnt); 8087 if (*buf == NULL) { 8088 PyMem_Del(*iov); 8089 PyErr_NoMemory(); 8090 return -1; 8091 } 8092 8093 for (i = 0; i < cnt; i++) { 8094 PyObject *item = PySequence_GetItem(seq, i); 8095 if (item == NULL) 8096 goto fail; 8097 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) { 8098 Py_DECREF(item); 8099 goto fail; 8100 } 8101 Py_DECREF(item); 8102 (*iov)[i].iov_base = (*buf)[i].buf; 8103 blen = (*buf)[i].len; 8104 (*iov)[i].iov_len = blen; 8105 total += blen; 8106 } 8107 return total; 8108 8109fail: 8110 PyMem_Del(*iov); 8111 for (j = 0; j < i; j++) { 8112 PyBuffer_Release(&(*buf)[j]); 8113 } 8114 PyMem_Del(*buf); 8115 return -1; 8116} 8117 8118static void 8119iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt) 8120{ 8121 int i; 8122 PyMem_Del(iov); 8123 for (i = 0; i < cnt; i++) { 8124 PyBuffer_Release(&buf[i]); 8125 } 8126 PyMem_Del(buf); 8127} 8128#endif 8129 8130#ifdef HAVE_READV 8131PyDoc_STRVAR(posix_readv__doc__, 8132"readv(fd, buffers) -> bytesread\n\n\ 8133Read from a file descriptor fd into a number of mutable, bytes-like\n\ 8134objects (\"buffers\"). readv will transfer data into each buffer\n\ 8135until it is full and then move on to the next buffer in the sequence\n\ 8136to hold the rest of the data.\n\n\ 8137readv returns the total number of bytes read (which may be less than\n\ 8138the total capacity of all the buffers."); 8139 8140static PyObject * 8141posix_readv(PyObject *self, PyObject *args) 8142{ 8143 int fd, cnt; 8144 Py_ssize_t n; 8145 PyObject *seq; 8146 struct iovec *iov; 8147 Py_buffer *buf; 8148 8149 if (!PyArg_ParseTuple(args, "iO:readv", &fd, &seq)) 8150 return NULL; 8151 if (!PySequence_Check(seq)) { 8152 PyErr_SetString(PyExc_TypeError, 8153 "readv() arg 2 must be a sequence"); 8154 return NULL; 8155 } 8156 cnt = PySequence_Size(seq); 8157 8158 if (iov_setup(&iov, &buf, seq, cnt, PyBUF_WRITABLE) < 0) 8159 return NULL; 8160 8161 Py_BEGIN_ALLOW_THREADS 8162 n = readv(fd, iov, cnt); 8163 Py_END_ALLOW_THREADS 8164 8165 iov_cleanup(iov, buf, cnt); 8166 if (n < 0) 8167 return posix_error(); 8168 8169 return PyLong_FromSsize_t(n); 8170} 8171#endif 8172 8173#ifdef HAVE_PREAD 8174PyDoc_STRVAR(posix_pread__doc__, 8175"pread(fd, buffersize, offset) -> string\n\n\ 8176Read from a file descriptor, fd, at a position of offset. It will read up\n\ 8177to buffersize number of bytes. The file offset remains unchanged."); 8178 8179static PyObject * 8180posix_pread(PyObject *self, PyObject *args) 8181{ 8182 int fd, size; 8183 off_t offset; 8184 Py_ssize_t n; 8185 PyObject *buffer; 8186 if (!PyArg_ParseTuple(args, "iiO&:pread", &fd, &size, _parse_off_t, &offset)) 8187 return NULL; 8188 8189 if (size < 0) { 8190 errno = EINVAL; 8191 return posix_error(); 8192 } 8193 buffer = PyBytes_FromStringAndSize((char *)NULL, size); 8194 if (buffer == NULL) 8195 return NULL; 8196 if (!_PyVerify_fd(fd)) { 8197 Py_DECREF(buffer); 8198 return posix_error(); 8199 } 8200 Py_BEGIN_ALLOW_THREADS 8201 n = pread(fd, PyBytes_AS_STRING(buffer), size, offset); 8202 Py_END_ALLOW_THREADS 8203 if (n < 0) { 8204 Py_DECREF(buffer); 8205 return posix_error(); 8206 } 8207 if (n != size) 8208 _PyBytes_Resize(&buffer, n); 8209 return buffer; 8210} 8211#endif 8212 8213PyDoc_STRVAR(posix_write__doc__, 8214"write(fd, data) -> byteswritten\n\n\ 8215Write bytes to a file descriptor."); 8216 8217static PyObject * 8218posix_write(PyObject *self, PyObject *args) 8219{ 8220 Py_buffer pbuf; 8221 int fd; 8222 Py_ssize_t size, len; 8223 8224 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf)) 8225 return NULL; 8226 if (!_PyVerify_fd(fd)) { 8227 PyBuffer_Release(&pbuf); 8228 return posix_error(); 8229 } 8230 len = pbuf.len; 8231 Py_BEGIN_ALLOW_THREADS 8232#ifdef MS_WINDOWS 8233 if (len > INT_MAX) 8234 len = INT_MAX; 8235 size = write(fd, pbuf.buf, (int)len); 8236#else 8237 size = write(fd, pbuf.buf, len); 8238#endif 8239 Py_END_ALLOW_THREADS 8240 PyBuffer_Release(&pbuf); 8241 if (size < 0) 8242 return posix_error(); 8243 return PyLong_FromSsize_t(size); 8244} 8245 8246#ifdef HAVE_SENDFILE 8247PyDoc_STRVAR(posix_sendfile__doc__, 8248"sendfile(out, in, offset, count) -> byteswritten\n\ 8249sendfile(out, in, offset, count, headers=None, trailers=None, flags=0)\n\ 8250 -> byteswritten\n\ 8251Copy count bytes from file descriptor in to file descriptor out."); 8252 8253static PyObject * 8254posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict) 8255{ 8256 int in, out; 8257 Py_ssize_t ret; 8258 off_t offset; 8259 8260#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__) 8261#ifndef __APPLE__ 8262 Py_ssize_t len; 8263#endif 8264 PyObject *headers = NULL, *trailers = NULL; 8265 Py_buffer *hbuf, *tbuf; 8266 off_t sbytes; 8267 struct sf_hdtr sf; 8268 int flags = 0; 8269 /* Beware that "in" clashes with Python's own "in" operator keyword */ 8270 static char *keywords[] = {"out", "in", 8271 "offset", "count", 8272 "headers", "trailers", "flags", NULL}; 8273 8274 sf.headers = NULL; 8275 sf.trailers = NULL; 8276 8277#ifdef __APPLE__ 8278 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile", 8279 keywords, &out, &in, _parse_off_t, &offset, _parse_off_t, &sbytes, 8280#else 8281 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile", 8282 keywords, &out, &in, _parse_off_t, &offset, &len, 8283#endif 8284 &headers, &trailers, &flags)) 8285 return NULL; 8286 if (headers != NULL) { 8287 if (!PySequence_Check(headers)) { 8288 PyErr_SetString(PyExc_TypeError, 8289 "sendfile() headers must be a sequence or None"); 8290 return NULL; 8291 } else { 8292 Py_ssize_t i = 0; /* Avoid uninitialized warning */ 8293 sf.hdr_cnt = PySequence_Size(headers); 8294 if (sf.hdr_cnt > 0 && 8295 (i = iov_setup(&(sf.headers), &hbuf, 8296 headers, sf.hdr_cnt, PyBUF_SIMPLE)) < 0) 8297 return NULL; 8298#ifdef __APPLE__ 8299 sbytes += i; 8300#endif 8301 } 8302 } 8303 if (trailers != NULL) { 8304 if (!PySequence_Check(trailers)) { 8305 PyErr_SetString(PyExc_TypeError, 8306 "sendfile() trailers must be a sequence or None"); 8307 return NULL; 8308 } else { 8309 Py_ssize_t i = 0; /* Avoid uninitialized warning */ 8310 sf.trl_cnt = PySequence_Size(trailers); 8311 if (sf.trl_cnt > 0 && 8312 (i = iov_setup(&(sf.trailers), &tbuf, 8313 trailers, sf.trl_cnt, PyBUF_SIMPLE)) < 0) 8314 return NULL; 8315#ifdef __APPLE__ 8316 sbytes += i; 8317#endif 8318 } 8319 } 8320 8321 Py_BEGIN_ALLOW_THREADS 8322#ifdef __APPLE__ 8323 ret = sendfile(in, out, offset, &sbytes, &sf, flags); 8324#else 8325 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags); 8326#endif 8327 Py_END_ALLOW_THREADS 8328 8329 if (sf.headers != NULL) 8330 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt); 8331 if (sf.trailers != NULL) 8332 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt); 8333 8334 if (ret < 0) { 8335 if ((errno == EAGAIN) || (errno == EBUSY)) { 8336 if (sbytes != 0) { 8337 // some data has been sent 8338 goto done; 8339 } 8340 else { 8341 // no data has been sent; upper application is supposed 8342 // to retry on EAGAIN or EBUSY 8343 return posix_error(); 8344 } 8345 } 8346 return posix_error(); 8347 } 8348 goto done; 8349 8350done: 8351 #if !defined(HAVE_LARGEFILE_SUPPORT) 8352 return Py_BuildValue("l", sbytes); 8353 #else 8354 return Py_BuildValue("L", sbytes); 8355 #endif 8356 8357#else 8358 Py_ssize_t count; 8359 PyObject *offobj; 8360 static char *keywords[] = {"out", "in", 8361 "offset", "count", NULL}; 8362 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile", 8363 keywords, &out, &in, &offobj, &count)) 8364 return NULL; 8365#ifdef linux 8366 if (offobj == Py_None) { 8367 Py_BEGIN_ALLOW_THREADS 8368 ret = sendfile(out, in, NULL, count); 8369 Py_END_ALLOW_THREADS 8370 if (ret < 0) 8371 return posix_error(); 8372 return Py_BuildValue("n", ret); 8373 } 8374#endif 8375 if (!_parse_off_t(offobj, &offset)) 8376 return NULL; 8377 Py_BEGIN_ALLOW_THREADS 8378 ret = sendfile(out, in, &offset, count); 8379 Py_END_ALLOW_THREADS 8380 if (ret < 0) 8381 return posix_error(); 8382 return Py_BuildValue("n", ret); 8383#endif 8384} 8385#endif 8386 8387PyDoc_STRVAR(posix_fstat__doc__, 8388"fstat(fd) -> stat result\n\n\ 8389Like stat(), but for an open file descriptor.\n\ 8390Equivalent to stat(fd=fd)."); 8391 8392static PyObject * 8393posix_fstat(PyObject *self, PyObject *args) 8394{ 8395 int fd; 8396 STRUCT_STAT st; 8397 int res; 8398 if (!PyArg_ParseTuple(args, "i:fstat", &fd)) 8399 return NULL; 8400 Py_BEGIN_ALLOW_THREADS 8401 res = FSTAT(fd, &st); 8402 Py_END_ALLOW_THREADS 8403 if (res != 0) { 8404#ifdef MS_WINDOWS 8405 return PyErr_SetFromWindowsErr(0); 8406#else 8407 return posix_error(); 8408#endif 8409 } 8410 8411 return _pystat_fromstructstat(&st); 8412} 8413 8414PyDoc_STRVAR(posix_isatty__doc__, 8415"isatty(fd) -> bool\n\n\ 8416Return True if the file descriptor 'fd' is an open file descriptor\n\ 8417connected to the slave end of a terminal."); 8418 8419static PyObject * 8420posix_isatty(PyObject *self, PyObject *args) 8421{ 8422 int fd; 8423 if (!PyArg_ParseTuple(args, "i:isatty", &fd)) 8424 return NULL; 8425 if (!_PyVerify_fd(fd)) 8426 return PyBool_FromLong(0); 8427 return PyBool_FromLong(isatty(fd)); 8428} 8429 8430#ifdef HAVE_PIPE 8431PyDoc_STRVAR(posix_pipe__doc__, 8432"pipe() -> (read_end, write_end)\n\n\ 8433Create a pipe."); 8434 8435static PyObject * 8436posix_pipe(PyObject *self, PyObject *noargs) 8437{ 8438 int fds[2]; 8439#ifdef MS_WINDOWS 8440 HANDLE read, write; 8441 SECURITY_ATTRIBUTES attr; 8442 BOOL ok; 8443#else 8444 int res; 8445#endif 8446 8447#ifdef MS_WINDOWS 8448 attr.nLength = sizeof(attr); 8449 attr.lpSecurityDescriptor = NULL; 8450 attr.bInheritHandle = FALSE; 8451 8452 Py_BEGIN_ALLOW_THREADS 8453 ok = CreatePipe(&read, &write, &attr, 0); 8454 if (ok) { 8455 fds[0] = _open_osfhandle((Py_intptr_t)read, _O_RDONLY); 8456 fds[1] = _open_osfhandle((Py_intptr_t)write, _O_WRONLY); 8457 if (fds[0] == -1 || fds[1] == -1) { 8458 CloseHandle(read); 8459 CloseHandle(write); 8460 ok = 0; 8461 } 8462 } 8463 Py_END_ALLOW_THREADS 8464 8465 if (!ok) 8466 return PyErr_SetFromWindowsErr(0); 8467#else 8468 8469#ifdef HAVE_PIPE2 8470 Py_BEGIN_ALLOW_THREADS 8471 res = pipe2(fds, O_CLOEXEC); 8472 Py_END_ALLOW_THREADS 8473 8474 if (res != 0 && errno == ENOSYS) 8475 { 8476#endif 8477 Py_BEGIN_ALLOW_THREADS 8478 res = pipe(fds); 8479 Py_END_ALLOW_THREADS 8480 8481 if (res == 0) { 8482 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) { 8483 close(fds[0]); 8484 close(fds[1]); 8485 return NULL; 8486 } 8487 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) { 8488 close(fds[0]); 8489 close(fds[1]); 8490 return NULL; 8491 } 8492 } 8493#ifdef HAVE_PIPE2 8494 } 8495#endif 8496 8497 if (res != 0) 8498 return PyErr_SetFromErrno(PyExc_OSError); 8499#endif /* !MS_WINDOWS */ 8500 return Py_BuildValue("(ii)", fds[0], fds[1]); 8501} 8502#endif /* HAVE_PIPE */ 8503 8504#ifdef HAVE_PIPE2 8505PyDoc_STRVAR(posix_pipe2__doc__, 8506"pipe2(flags) -> (read_end, write_end)\n\n\ 8507Create a pipe with flags set atomically.\n\ 8508flags can be constructed by ORing together one or more of these values:\n\ 8509O_NONBLOCK, O_CLOEXEC.\n\ 8510"); 8511 8512static PyObject * 8513posix_pipe2(PyObject *self, PyObject *arg) 8514{ 8515 int flags; 8516 int fds[2]; 8517 int res; 8518 8519 flags = _PyLong_AsInt(arg); 8520 if (flags == -1 && PyErr_Occurred()) 8521 return NULL; 8522 8523 res = pipe2(fds, flags); 8524 if (res != 0) 8525 return posix_error(); 8526 return Py_BuildValue("(ii)", fds[0], fds[1]); 8527} 8528#endif /* HAVE_PIPE2 */ 8529 8530#ifdef HAVE_WRITEV 8531PyDoc_STRVAR(posix_writev__doc__, 8532"writev(fd, buffers) -> byteswritten\n\n\ 8533Write the contents of *buffers* to file descriptor *fd*. *buffers*\n\ 8534must be a sequence of bytes-like objects.\n\n\ 8535writev writes the contents of each object to the file descriptor\n\ 8536and returns the total number of bytes written."); 8537 8538static PyObject * 8539posix_writev(PyObject *self, PyObject *args) 8540{ 8541 int fd, cnt; 8542 Py_ssize_t res; 8543 PyObject *seq; 8544 struct iovec *iov; 8545 Py_buffer *buf; 8546 if (!PyArg_ParseTuple(args, "iO:writev", &fd, &seq)) 8547 return NULL; 8548 if (!PySequence_Check(seq)) { 8549 PyErr_SetString(PyExc_TypeError, 8550 "writev() arg 2 must be a sequence"); 8551 return NULL; 8552 } 8553 cnt = PySequence_Size(seq); 8554 8555 if (iov_setup(&iov, &buf, seq, cnt, PyBUF_SIMPLE) < 0) { 8556 return NULL; 8557 } 8558 8559 Py_BEGIN_ALLOW_THREADS 8560 res = writev(fd, iov, cnt); 8561 Py_END_ALLOW_THREADS 8562 8563 iov_cleanup(iov, buf, cnt); 8564 if (res < 0) 8565 return posix_error(); 8566 8567 return PyLong_FromSsize_t(res); 8568} 8569#endif 8570 8571#ifdef HAVE_PWRITE 8572PyDoc_STRVAR(posix_pwrite__doc__, 8573"pwrite(fd, string, offset) -> byteswritten\n\n\ 8574Write string to a file descriptor, fd, from offset, leaving the file\n\ 8575offset unchanged."); 8576 8577static PyObject * 8578posix_pwrite(PyObject *self, PyObject *args) 8579{ 8580 Py_buffer pbuf; 8581 int fd; 8582 off_t offset; 8583 Py_ssize_t size; 8584 8585 if (!PyArg_ParseTuple(args, "iy*O&:pwrite", &fd, &pbuf, _parse_off_t, &offset)) 8586 return NULL; 8587 8588 if (!_PyVerify_fd(fd)) { 8589 PyBuffer_Release(&pbuf); 8590 return posix_error(); 8591 } 8592 Py_BEGIN_ALLOW_THREADS 8593 size = pwrite(fd, pbuf.buf, (size_t)pbuf.len, offset); 8594 Py_END_ALLOW_THREADS 8595 PyBuffer_Release(&pbuf); 8596 if (size < 0) 8597 return posix_error(); 8598 return PyLong_FromSsize_t(size); 8599} 8600#endif 8601 8602#ifdef HAVE_MKFIFO 8603PyDoc_STRVAR(posix_mkfifo__doc__, 8604"mkfifo(path, mode=0o666, *, dir_fd=None)\n\n\ 8605Create a FIFO (a POSIX named pipe).\n\ 8606\n\ 8607If dir_fd is not None, it should be a file descriptor open to a directory,\n\ 8608 and path should be relative; path will then be relative to that directory.\n\ 8609dir_fd may not be implemented on your platform.\n\ 8610 If it is unavailable, using it will raise a NotImplementedError."); 8611 8612static PyObject * 8613posix_mkfifo(PyObject *self, PyObject *args, PyObject *kwargs) 8614{ 8615 path_t path; 8616 int mode = 0666; 8617 int dir_fd = DEFAULT_DIR_FD; 8618 int result; 8619 PyObject *return_value = NULL; 8620 static char *keywords[] = {"path", "mode", "dir_fd", NULL}; 8621 8622 memset(&path, 0, sizeof(path)); 8623 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|i$O&:mkfifo", keywords, 8624 path_converter, &path, 8625 &mode, 8626#ifdef HAVE_MKFIFOAT 8627 dir_fd_converter, &dir_fd 8628#else 8629 dir_fd_unavailable, &dir_fd 8630#endif 8631 )) 8632 return NULL; 8633 8634 Py_BEGIN_ALLOW_THREADS 8635#ifdef HAVE_MKFIFOAT 8636 if (dir_fd != DEFAULT_DIR_FD) 8637 result = mkfifoat(dir_fd, path.narrow, mode); 8638 else 8639#endif 8640 result = mkfifo(path.narrow, mode); 8641 Py_END_ALLOW_THREADS 8642 8643 if (result < 0) { 8644 return_value = posix_error(); 8645 goto exit; 8646 } 8647 8648 return_value = Py_None; 8649 Py_INCREF(Py_None); 8650 8651exit: 8652 path_cleanup(&path); 8653 return return_value; 8654} 8655#endif 8656 8657#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) 8658PyDoc_STRVAR(posix_mknod__doc__, 8659"mknod(path, mode=0o600, device=0, *, dir_fd=None)\n\n\ 8660Create a filesystem node (file, device special file or named pipe)\n\ 8661named path. mode specifies both the permissions to use and the\n\ 8662type of node to be created, being combined (bitwise OR) with one of\n\ 8663S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\ 8664device defines the newly created device special file (probably using\n\ 8665os.makedev()), otherwise it is ignored.\n\ 8666\n\ 8667If dir_fd is not None, it should be a file descriptor open to a directory,\n\ 8668 and path should be relative; path will then be relative to that directory.\n\ 8669dir_fd may not be implemented on your platform.\n\ 8670 If it is unavailable, using it will raise a NotImplementedError."); 8671 8672 8673static PyObject * 8674posix_mknod(PyObject *self, PyObject *args, PyObject *kwargs) 8675{ 8676 path_t path; 8677 int mode = 0666; 8678 dev_t device = 0; 8679 int dir_fd = DEFAULT_DIR_FD; 8680 int result; 8681 PyObject *return_value = NULL; 8682 static char *keywords[] = {"path", "mode", "device", "dir_fd", NULL}; 8683 8684 memset(&path, 0, sizeof(path)); 8685 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|iO&$O&:mknod", keywords, 8686 path_converter, &path, 8687 &mode, _Py_Dev_Converter, &device, 8688#ifdef HAVE_MKNODAT 8689 dir_fd_converter, &dir_fd 8690#else 8691 dir_fd_unavailable, &dir_fd 8692#endif 8693 )) 8694 return NULL; 8695 8696 Py_BEGIN_ALLOW_THREADS 8697#ifdef HAVE_MKNODAT 8698 if (dir_fd != DEFAULT_DIR_FD) 8699 result = mknodat(dir_fd, path.narrow, mode, device); 8700 else 8701#endif 8702 result = mknod(path.narrow, mode, device); 8703 Py_END_ALLOW_THREADS 8704 8705 if (result < 0) { 8706 return_value = posix_error(); 8707 goto exit; 8708 } 8709 8710 return_value = Py_None; 8711 Py_INCREF(Py_None); 8712 8713exit: 8714 path_cleanup(&path); 8715 return return_value; 8716} 8717#endif 8718 8719#ifdef HAVE_DEVICE_MACROS 8720PyDoc_STRVAR(posix_major__doc__, 8721"major(device) -> major number\n\ 8722Extracts a device major number from a raw device number."); 8723 8724static PyObject * 8725posix_major(PyObject *self, PyObject *args) 8726{ 8727 dev_t device; 8728 if (!PyArg_ParseTuple(args, "O&:major", _Py_Dev_Converter, &device)) 8729 return NULL; 8730 return PyLong_FromLong((long)major(device)); 8731} 8732 8733PyDoc_STRVAR(posix_minor__doc__, 8734"minor(device) -> minor number\n\ 8735Extracts a device minor number from a raw device number."); 8736 8737static PyObject * 8738posix_minor(PyObject *self, PyObject *args) 8739{ 8740 dev_t device; 8741 if (!PyArg_ParseTuple(args, "O&:minor", _Py_Dev_Converter, &device)) 8742 return NULL; 8743 return PyLong_FromLong((long)minor(device)); 8744} 8745 8746PyDoc_STRVAR(posix_makedev__doc__, 8747"makedev(major, minor) -> device number\n\ 8748Composes a raw device number from the major and minor device numbers."); 8749 8750static PyObject * 8751posix_makedev(PyObject *self, PyObject *args) 8752{ 8753 int major, minor; 8754 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor)) 8755 return NULL; 8756 return _PyLong_FromDev(makedev(major, minor)); 8757} 8758#endif /* device macros */ 8759 8760 8761#ifdef HAVE_FTRUNCATE 8762PyDoc_STRVAR(posix_ftruncate__doc__, 8763"ftruncate(fd, length)\n\n\ 8764Truncate a file to a specified length."); 8765 8766static PyObject * 8767posix_ftruncate(PyObject *self, PyObject *args) 8768{ 8769 int fd; 8770 off_t length; 8771 int res; 8772 8773 if (!PyArg_ParseTuple(args, "iO&:ftruncate", &fd, _parse_off_t, &length)) 8774 return NULL; 8775 8776 Py_BEGIN_ALLOW_THREADS 8777 res = ftruncate(fd, length); 8778 Py_END_ALLOW_THREADS 8779 if (res < 0) 8780 return posix_error(); 8781 Py_INCREF(Py_None); 8782 return Py_None; 8783} 8784#endif 8785 8786#ifdef HAVE_TRUNCATE 8787PyDoc_STRVAR(posix_truncate__doc__, 8788"truncate(path, length)\n\n\ 8789Truncate the file given by path to length bytes.\n\ 8790On some platforms, path may also be specified as an open file descriptor.\n\ 8791 If this functionality is unavailable, using it raises an exception."); 8792 8793static PyObject * 8794posix_truncate(PyObject *self, PyObject *args, PyObject *kwargs) 8795{ 8796 path_t path; 8797 off_t length; 8798 int res; 8799 PyObject *result = NULL; 8800 static char *keywords[] = {"path", "length", NULL}; 8801 8802 memset(&path, 0, sizeof(path)); 8803 path.function_name = "truncate"; 8804#ifdef HAVE_FTRUNCATE 8805 path.allow_fd = 1; 8806#endif 8807 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:truncate", keywords, 8808 path_converter, &path, 8809 _parse_off_t, &length)) 8810 return NULL; 8811 8812 Py_BEGIN_ALLOW_THREADS 8813#ifdef HAVE_FTRUNCATE 8814 if (path.fd != -1) 8815 res = ftruncate(path.fd, length); 8816 else 8817#endif 8818 res = truncate(path.narrow, length); 8819 Py_END_ALLOW_THREADS 8820 if (res < 0) 8821 result = path_error(&path); 8822 else { 8823 Py_INCREF(Py_None); 8824 result = Py_None; 8825 } 8826 path_cleanup(&path); 8827 return result; 8828} 8829#endif 8830 8831/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise() 8832 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is 8833 defined, which is the case in Python on AIX. AIX bug report: 8834 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */ 8835#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__) 8836# define POSIX_FADVISE_AIX_BUG 8837#endif 8838 8839#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG) 8840PyDoc_STRVAR(posix_posix_fallocate__doc__, 8841"posix_fallocate(fd, offset, len)\n\n\ 8842Ensures that enough disk space is allocated for the file specified by fd\n\ 8843starting from offset and continuing for len bytes."); 8844 8845static PyObject * 8846posix_posix_fallocate(PyObject *self, PyObject *args) 8847{ 8848 off_t len, offset; 8849 int res, fd; 8850 8851 if (!PyArg_ParseTuple(args, "iO&O&:posix_fallocate", 8852 &fd, _parse_off_t, &offset, _parse_off_t, &len)) 8853 return NULL; 8854 8855 Py_BEGIN_ALLOW_THREADS 8856 res = posix_fallocate(fd, offset, len); 8857 Py_END_ALLOW_THREADS 8858 if (res != 0) { 8859 errno = res; 8860 return posix_error(); 8861 } 8862 Py_RETURN_NONE; 8863} 8864#endif 8865 8866#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG) 8867PyDoc_STRVAR(posix_posix_fadvise__doc__, 8868"posix_fadvise(fd, offset, len, advice)\n\n\ 8869Announces an intention to access data in a specific pattern thus allowing\n\ 8870the kernel to make optimizations.\n\ 8871The advice applies to the region of the file specified by fd starting at\n\ 8872offset and continuing for len bytes.\n\ 8873advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,\n\ 8874POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED or\n\ 8875POSIX_FADV_DONTNEED."); 8876 8877static PyObject * 8878posix_posix_fadvise(PyObject *self, PyObject *args) 8879{ 8880 off_t len, offset; 8881 int res, fd, advice; 8882 8883 if (!PyArg_ParseTuple(args, "iO&O&i:posix_fadvise", 8884 &fd, _parse_off_t, &offset, _parse_off_t, &len, &advice)) 8885 return NULL; 8886 8887 Py_BEGIN_ALLOW_THREADS 8888 res = posix_fadvise(fd, offset, len, advice); 8889 Py_END_ALLOW_THREADS 8890 if (res != 0) { 8891 errno = res; 8892 return posix_error(); 8893 } 8894 Py_RETURN_NONE; 8895} 8896#endif 8897 8898#ifdef HAVE_PUTENV 8899PyDoc_STRVAR(posix_putenv__doc__, 8900"putenv(key, value)\n\n\ 8901Change or add an environment variable."); 8902 8903/* Save putenv() parameters as values here, so we can collect them when they 8904 * get re-set with another call for the same key. */ 8905static PyObject *posix_putenv_garbage; 8906 8907static PyObject * 8908posix_putenv(PyObject *self, PyObject *args) 8909{ 8910 PyObject *newstr = NULL; 8911#ifdef MS_WINDOWS 8912 PyObject *os1, *os2; 8913 wchar_t *newenv; 8914 8915 if (!PyArg_ParseTuple(args, 8916 "UU:putenv", 8917 &os1, &os2)) 8918 return NULL; 8919 8920 newstr = PyUnicode_FromFormat("%U=%U", os1, os2); 8921 if (newstr == NULL) { 8922 PyErr_NoMemory(); 8923 goto error; 8924 } 8925 if (_MAX_ENV < PyUnicode_GET_LENGTH(newstr)) { 8926 PyErr_Format(PyExc_ValueError, 8927 "the environment variable is longer than %u characters", 8928 _MAX_ENV); 8929 goto error; 8930 } 8931 8932 newenv = PyUnicode_AsUnicode(newstr); 8933 if (newenv == NULL) 8934 goto error; 8935 if (_wputenv(newenv)) { 8936 posix_error(); 8937 goto error; 8938 } 8939#else 8940 PyObject *os1, *os2; 8941 char *s1, *s2; 8942 char *newenv; 8943 8944 if (!PyArg_ParseTuple(args, 8945 "O&O&:putenv", 8946 PyUnicode_FSConverter, &os1, 8947 PyUnicode_FSConverter, &os2)) 8948 return NULL; 8949 s1 = PyBytes_AsString(os1); 8950 s2 = PyBytes_AsString(os2); 8951 8952 newstr = PyBytes_FromFormat("%s=%s", s1, s2); 8953 if (newstr == NULL) { 8954 PyErr_NoMemory(); 8955 goto error; 8956 } 8957 8958 newenv = PyBytes_AS_STRING(newstr); 8959 if (putenv(newenv)) { 8960 posix_error(); 8961 goto error; 8962 } 8963#endif 8964 8965 /* Install the first arg and newstr in posix_putenv_garbage; 8966 * this will cause previous value to be collected. This has to 8967 * happen after the real putenv() call because the old value 8968 * was still accessible until then. */ 8969 if (PyDict_SetItem(posix_putenv_garbage, os1, newstr)) { 8970 /* really not much we can do; just leak */ 8971 PyErr_Clear(); 8972 } 8973 else { 8974 Py_DECREF(newstr); 8975 } 8976 8977#ifndef MS_WINDOWS 8978 Py_DECREF(os1); 8979 Py_DECREF(os2); 8980#endif 8981 Py_RETURN_NONE; 8982 8983error: 8984#ifndef MS_WINDOWS 8985 Py_DECREF(os1); 8986 Py_DECREF(os2); 8987#endif 8988 Py_XDECREF(newstr); 8989 return NULL; 8990} 8991#endif /* putenv */ 8992 8993#ifdef HAVE_UNSETENV 8994PyDoc_STRVAR(posix_unsetenv__doc__, 8995"unsetenv(key)\n\n\ 8996Delete an environment variable."); 8997 8998static PyObject * 8999posix_unsetenv(PyObject *self, PyObject *args) 9000{ 9001 PyObject *name; 9002#ifndef HAVE_BROKEN_UNSETENV 9003 int err; 9004#endif 9005 9006 if (!PyArg_ParseTuple(args, "O&:unsetenv", 9007 9008 PyUnicode_FSConverter, &name)) 9009 return NULL; 9010 9011#ifdef HAVE_BROKEN_UNSETENV 9012 unsetenv(PyBytes_AS_STRING(name)); 9013#else 9014 err = unsetenv(PyBytes_AS_STRING(name)); 9015 if (err) { 9016 Py_DECREF(name); 9017 return posix_error(); 9018 } 9019#endif 9020 9021 /* Remove the key from posix_putenv_garbage; 9022 * this will cause it to be collected. This has to 9023 * happen after the real unsetenv() call because the 9024 * old value was still accessible until then. 9025 */ 9026 if (PyDict_DelItem(posix_putenv_garbage, name)) { 9027 /* really not much we can do; just leak */ 9028 PyErr_Clear(); 9029 } 9030 Py_DECREF(name); 9031 Py_RETURN_NONE; 9032} 9033#endif /* unsetenv */ 9034 9035PyDoc_STRVAR(posix_strerror__doc__, 9036"strerror(code) -> string\n\n\ 9037Translate an error code to a message string."); 9038 9039static PyObject * 9040posix_strerror(PyObject *self, PyObject *args) 9041{ 9042 int code; 9043 char *message; 9044 if (!PyArg_ParseTuple(args, "i:strerror", &code)) 9045 return NULL; 9046 message = strerror(code); 9047 if (message == NULL) { 9048 PyErr_SetString(PyExc_ValueError, 9049 "strerror() argument out of range"); 9050 return NULL; 9051 } 9052 return PyUnicode_DecodeLocale(message, "surrogateescape"); 9053} 9054 9055 9056#ifdef HAVE_SYS_WAIT_H 9057 9058#ifdef WCOREDUMP 9059PyDoc_STRVAR(posix_WCOREDUMP__doc__, 9060"WCOREDUMP(status) -> bool\n\n\ 9061Return True if the process returning 'status' was dumped to a core file."); 9062 9063static PyObject * 9064posix_WCOREDUMP(PyObject *self, PyObject *args) 9065{ 9066 WAIT_TYPE status; 9067 WAIT_STATUS_INT(status) = 0; 9068 9069 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status))) 9070 return NULL; 9071 9072 return PyBool_FromLong(WCOREDUMP(status)); 9073} 9074#endif /* WCOREDUMP */ 9075 9076#ifdef WIFCONTINUED 9077PyDoc_STRVAR(posix_WIFCONTINUED__doc__, 9078"WIFCONTINUED(status) -> bool\n\n\ 9079Return True if the process returning 'status' was continued from a\n\ 9080job control stop."); 9081 9082static PyObject * 9083posix_WIFCONTINUED(PyObject *self, PyObject *args) 9084{ 9085 WAIT_TYPE status; 9086 WAIT_STATUS_INT(status) = 0; 9087 9088 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status))) 9089 return NULL; 9090 9091 return PyBool_FromLong(WIFCONTINUED(status)); 9092} 9093#endif /* WIFCONTINUED */ 9094 9095#ifdef WIFSTOPPED 9096PyDoc_STRVAR(posix_WIFSTOPPED__doc__, 9097"WIFSTOPPED(status) -> bool\n\n\ 9098Return True if the process returning 'status' was stopped."); 9099 9100static PyObject * 9101posix_WIFSTOPPED(PyObject *self, PyObject *args) 9102{ 9103 WAIT_TYPE status; 9104 WAIT_STATUS_INT(status) = 0; 9105 9106 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status))) 9107 return NULL; 9108 9109 return PyBool_FromLong(WIFSTOPPED(status)); 9110} 9111#endif /* WIFSTOPPED */ 9112 9113#ifdef WIFSIGNALED 9114PyDoc_STRVAR(posix_WIFSIGNALED__doc__, 9115"WIFSIGNALED(status) -> bool\n\n\ 9116Return True if the process returning 'status' was terminated by a signal."); 9117 9118static PyObject * 9119posix_WIFSIGNALED(PyObject *self, PyObject *args) 9120{ 9121 WAIT_TYPE status; 9122 WAIT_STATUS_INT(status) = 0; 9123 9124 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status))) 9125 return NULL; 9126 9127 return PyBool_FromLong(WIFSIGNALED(status)); 9128} 9129#endif /* WIFSIGNALED */ 9130 9131#ifdef WIFEXITED 9132PyDoc_STRVAR(posix_WIFEXITED__doc__, 9133"WIFEXITED(status) -> bool\n\n\ 9134Return true if the process returning 'status' exited using the exit()\n\ 9135system call."); 9136 9137static PyObject * 9138posix_WIFEXITED(PyObject *self, PyObject *args) 9139{ 9140 WAIT_TYPE status; 9141 WAIT_STATUS_INT(status) = 0; 9142 9143 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status))) 9144 return NULL; 9145 9146 return PyBool_FromLong(WIFEXITED(status)); 9147} 9148#endif /* WIFEXITED */ 9149 9150#ifdef WEXITSTATUS 9151PyDoc_STRVAR(posix_WEXITSTATUS__doc__, 9152"WEXITSTATUS(status) -> integer\n\n\ 9153Return the process return code from 'status'."); 9154 9155static PyObject * 9156posix_WEXITSTATUS(PyObject *self, PyObject *args) 9157{ 9158 WAIT_TYPE status; 9159 WAIT_STATUS_INT(status) = 0; 9160 9161 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status))) 9162 return NULL; 9163 9164 return Py_BuildValue("i", WEXITSTATUS(status)); 9165} 9166#endif /* WEXITSTATUS */ 9167 9168#ifdef WTERMSIG 9169PyDoc_STRVAR(posix_WTERMSIG__doc__, 9170"WTERMSIG(status) -> integer\n\n\ 9171Return the signal that terminated the process that provided the 'status'\n\ 9172value."); 9173 9174static PyObject * 9175posix_WTERMSIG(PyObject *self, PyObject *args) 9176{ 9177 WAIT_TYPE status; 9178 WAIT_STATUS_INT(status) = 0; 9179 9180 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status))) 9181 return NULL; 9182 9183 return Py_BuildValue("i", WTERMSIG(status)); 9184} 9185#endif /* WTERMSIG */ 9186 9187#ifdef WSTOPSIG 9188PyDoc_STRVAR(posix_WSTOPSIG__doc__, 9189"WSTOPSIG(status) -> integer\n\n\ 9190Return the signal that stopped the process that provided\n\ 9191the 'status' value."); 9192 9193static PyObject * 9194posix_WSTOPSIG(PyObject *self, PyObject *args) 9195{ 9196 WAIT_TYPE status; 9197 WAIT_STATUS_INT(status) = 0; 9198 9199 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status))) 9200 return NULL; 9201 9202 return Py_BuildValue("i", WSTOPSIG(status)); 9203} 9204#endif /* WSTOPSIG */ 9205 9206#endif /* HAVE_SYS_WAIT_H */ 9207 9208 9209#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) 9210#ifdef _SCO_DS 9211/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the 9212 needed definitions in sys/statvfs.h */ 9213#define _SVID3 9214#endif 9215#include <sys/statvfs.h> 9216 9217static PyObject* 9218_pystatvfs_fromstructstatvfs(struct statvfs st) { 9219 PyObject *v = PyStructSequence_New(&StatVFSResultType); 9220 if (v == NULL) 9221 return NULL; 9222 9223#if !defined(HAVE_LARGEFILE_SUPPORT) 9224 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize)); 9225 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize)); 9226 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks)); 9227 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree)); 9228 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail)); 9229 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files)); 9230 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree)); 9231 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail)); 9232 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag)); 9233 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax)); 9234#else 9235 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize)); 9236 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize)); 9237 PyStructSequence_SET_ITEM(v, 2, 9238 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks)); 9239 PyStructSequence_SET_ITEM(v, 3, 9240 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree)); 9241 PyStructSequence_SET_ITEM(v, 4, 9242 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail)); 9243 PyStructSequence_SET_ITEM(v, 5, 9244 PyLong_FromLongLong((PY_LONG_LONG) st.f_files)); 9245 PyStructSequence_SET_ITEM(v, 6, 9246 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree)); 9247 PyStructSequence_SET_ITEM(v, 7, 9248 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail)); 9249 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag)); 9250 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax)); 9251#endif 9252 if (PyErr_Occurred()) { 9253 Py_DECREF(v); 9254 return NULL; 9255 } 9256 9257 return v; 9258} 9259 9260PyDoc_STRVAR(posix_fstatvfs__doc__, 9261"fstatvfs(fd) -> statvfs result\n\n\ 9262Perform an fstatvfs system call on the given fd.\n\ 9263Equivalent to statvfs(fd)."); 9264 9265static PyObject * 9266posix_fstatvfs(PyObject *self, PyObject *args) 9267{ 9268 int fd, res; 9269 struct statvfs st; 9270 9271 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd)) 9272 return NULL; 9273 Py_BEGIN_ALLOW_THREADS 9274 res = fstatvfs(fd, &st); 9275 Py_END_ALLOW_THREADS 9276 if (res != 0) 9277 return posix_error(); 9278 9279 return _pystatvfs_fromstructstatvfs(st); 9280} 9281#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */ 9282 9283 9284#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) 9285#include <sys/statvfs.h> 9286 9287PyDoc_STRVAR(posix_statvfs__doc__, 9288"statvfs(path)\n\n\ 9289Perform a statvfs system call on the given path.\n\ 9290\n\ 9291path may always be specified as a string.\n\ 9292On some platforms, path may also be specified as an open file descriptor.\n\ 9293 If this functionality is unavailable, using it raises an exception."); 9294 9295static PyObject * 9296posix_statvfs(PyObject *self, PyObject *args, PyObject *kwargs) 9297{ 9298 static char *keywords[] = {"path", NULL}; 9299 path_t path; 9300 int result; 9301 PyObject *return_value = NULL; 9302 struct statvfs st; 9303 9304 memset(&path, 0, sizeof(path)); 9305 path.function_name = "statvfs"; 9306#ifdef HAVE_FSTATVFS 9307 path.allow_fd = 1; 9308#endif 9309 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:statvfs", keywords, 9310 path_converter, &path 9311 )) 9312 return NULL; 9313 9314 Py_BEGIN_ALLOW_THREADS 9315#ifdef HAVE_FSTATVFS 9316 if (path.fd != -1) { 9317#ifdef __APPLE__ 9318 /* handle weak-linking on Mac OS X 10.3 */ 9319 if (fstatvfs == NULL) { 9320 fd_specified("statvfs", path.fd); 9321 goto exit; 9322 } 9323#endif 9324 result = fstatvfs(path.fd, &st); 9325 } 9326 else 9327#endif 9328 result = statvfs(path.narrow, &st); 9329 Py_END_ALLOW_THREADS 9330 9331 if (result) { 9332 return_value = path_error(&path); 9333 goto exit; 9334 } 9335 9336 return_value = _pystatvfs_fromstructstatvfs(st); 9337 9338exit: 9339 path_cleanup(&path); 9340 return return_value; 9341} 9342#endif /* HAVE_STATVFS */ 9343 9344#ifdef MS_WINDOWS 9345PyDoc_STRVAR(win32__getdiskusage__doc__, 9346"_getdiskusage(path) -> (total, free)\n\n\ 9347Return disk usage statistics about the given path as (total, free) tuple."); 9348 9349static PyObject * 9350win32__getdiskusage(PyObject *self, PyObject *args) 9351{ 9352 BOOL retval; 9353 ULARGE_INTEGER _, total, free; 9354 const wchar_t *path; 9355 9356 if (! PyArg_ParseTuple(args, "u", &path)) 9357 return NULL; 9358 9359 Py_BEGIN_ALLOW_THREADS 9360 retval = GetDiskFreeSpaceExW(path, &_, &total, &free); 9361 Py_END_ALLOW_THREADS 9362 if (retval == 0) 9363 return PyErr_SetFromWindowsErr(0); 9364 9365 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart); 9366} 9367#endif 9368 9369 9370/* This is used for fpathconf(), pathconf(), confstr() and sysconf(). 9371 * It maps strings representing configuration variable names to 9372 * integer values, allowing those functions to be called with the 9373 * magic names instead of polluting the module's namespace with tons of 9374 * rarely-used constants. There are three separate tables that use 9375 * these definitions. 9376 * 9377 * This code is always included, even if none of the interfaces that 9378 * need it are included. The #if hackery needed to avoid it would be 9379 * sufficiently pervasive that it's not worth the loss of readability. 9380 */ 9381struct constdef { 9382 char *name; 9383 long value; 9384}; 9385 9386static int 9387conv_confname(PyObject *arg, int *valuep, struct constdef *table, 9388 size_t tablesize) 9389{ 9390 if (PyLong_Check(arg)) { 9391 *valuep = PyLong_AS_LONG(arg); 9392 return 1; 9393 } 9394 else { 9395 /* look up the value in the table using a binary search */ 9396 size_t lo = 0; 9397 size_t mid; 9398 size_t hi = tablesize; 9399 int cmp; 9400 const char *confname; 9401 if (!PyUnicode_Check(arg)) { 9402 PyErr_SetString(PyExc_TypeError, 9403 "configuration names must be strings or integers"); 9404 return 0; 9405 } 9406 confname = _PyUnicode_AsString(arg); 9407 if (confname == NULL) 9408 return 0; 9409 while (lo < hi) { 9410 mid = (lo + hi) / 2; 9411 cmp = strcmp(confname, table[mid].name); 9412 if (cmp < 0) 9413 hi = mid; 9414 else if (cmp > 0) 9415 lo = mid + 1; 9416 else { 9417 *valuep = table[mid].value; 9418 return 1; 9419 } 9420 } 9421 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name"); 9422 return 0; 9423 } 9424} 9425 9426 9427#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF) 9428static struct constdef posix_constants_pathconf[] = { 9429#ifdef _PC_ABI_AIO_XFER_MAX 9430 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX}, 9431#endif 9432#ifdef _PC_ABI_ASYNC_IO 9433 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO}, 9434#endif 9435#ifdef _PC_ASYNC_IO 9436 {"PC_ASYNC_IO", _PC_ASYNC_IO}, 9437#endif 9438#ifdef _PC_CHOWN_RESTRICTED 9439 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED}, 9440#endif 9441#ifdef _PC_FILESIZEBITS 9442 {"PC_FILESIZEBITS", _PC_FILESIZEBITS}, 9443#endif 9444#ifdef _PC_LAST 9445 {"PC_LAST", _PC_LAST}, 9446#endif 9447#ifdef _PC_LINK_MAX 9448 {"PC_LINK_MAX", _PC_LINK_MAX}, 9449#endif 9450#ifdef _PC_MAX_CANON 9451 {"PC_MAX_CANON", _PC_MAX_CANON}, 9452#endif 9453#ifdef _PC_MAX_INPUT 9454 {"PC_MAX_INPUT", _PC_MAX_INPUT}, 9455#endif 9456#ifdef _PC_NAME_MAX 9457 {"PC_NAME_MAX", _PC_NAME_MAX}, 9458#endif 9459#ifdef _PC_NO_TRUNC 9460 {"PC_NO_TRUNC", _PC_NO_TRUNC}, 9461#endif 9462#ifdef _PC_PATH_MAX 9463 {"PC_PATH_MAX", _PC_PATH_MAX}, 9464#endif 9465#ifdef _PC_PIPE_BUF 9466 {"PC_PIPE_BUF", _PC_PIPE_BUF}, 9467#endif 9468#ifdef _PC_PRIO_IO 9469 {"PC_PRIO_IO", _PC_PRIO_IO}, 9470#endif 9471#ifdef _PC_SOCK_MAXBUF 9472 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF}, 9473#endif 9474#ifdef _PC_SYNC_IO 9475 {"PC_SYNC_IO", _PC_SYNC_IO}, 9476#endif 9477#ifdef _PC_VDISABLE 9478 {"PC_VDISABLE", _PC_VDISABLE}, 9479#endif 9480#ifdef _PC_ACL_ENABLED 9481 {"PC_ACL_ENABLED", _PC_ACL_ENABLED}, 9482#endif 9483#ifdef _PC_MIN_HOLE_SIZE 9484 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE}, 9485#endif 9486#ifdef _PC_ALLOC_SIZE_MIN 9487 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN}, 9488#endif 9489#ifdef _PC_REC_INCR_XFER_SIZE 9490 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE}, 9491#endif 9492#ifdef _PC_REC_MAX_XFER_SIZE 9493 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE}, 9494#endif 9495#ifdef _PC_REC_MIN_XFER_SIZE 9496 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE}, 9497#endif 9498#ifdef _PC_REC_XFER_ALIGN 9499 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN}, 9500#endif 9501#ifdef _PC_SYMLINK_MAX 9502 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX}, 9503#endif 9504#ifdef _PC_XATTR_ENABLED 9505 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED}, 9506#endif 9507#ifdef _PC_XATTR_EXISTS 9508 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS}, 9509#endif 9510#ifdef _PC_TIMESTAMP_RESOLUTION 9511 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION}, 9512#endif 9513}; 9514 9515static int 9516conv_path_confname(PyObject *arg, int *valuep) 9517{ 9518 return conv_confname(arg, valuep, posix_constants_pathconf, 9519 sizeof(posix_constants_pathconf) 9520 / sizeof(struct constdef)); 9521} 9522#endif 9523 9524#ifdef HAVE_FPATHCONF 9525PyDoc_STRVAR(posix_fpathconf__doc__, 9526"fpathconf(fd, name) -> integer\n\n\ 9527Return the configuration limit name for the file descriptor fd.\n\ 9528If there is no limit, return -1."); 9529 9530static PyObject * 9531posix_fpathconf(PyObject *self, PyObject *args) 9532{ 9533 PyObject *result = NULL; 9534 int name, fd; 9535 9536 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd, 9537 conv_path_confname, &name)) { 9538 long limit; 9539 9540 errno = 0; 9541 limit = fpathconf(fd, name); 9542 if (limit == -1 && errno != 0) 9543 posix_error(); 9544 else 9545 result = PyLong_FromLong(limit); 9546 } 9547 return result; 9548} 9549#endif 9550 9551 9552#ifdef HAVE_PATHCONF 9553PyDoc_STRVAR(posix_pathconf__doc__, 9554"pathconf(path, name) -> integer\n\n\ 9555Return the configuration limit name for the file or directory path.\n\ 9556If there is no limit, return -1.\n\ 9557On some platforms, path may also be specified as an open file descriptor.\n\ 9558 If this functionality is unavailable, using it raises an exception."); 9559 9560static PyObject * 9561posix_pathconf(PyObject *self, PyObject *args, PyObject *kwargs) 9562{ 9563 path_t path; 9564 PyObject *result = NULL; 9565 int name; 9566 static char *keywords[] = {"path", "name", NULL}; 9567 9568 memset(&path, 0, sizeof(path)); 9569 path.function_name = "pathconf"; 9570#ifdef HAVE_FPATHCONF 9571 path.allow_fd = 1; 9572#endif 9573 if (PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:pathconf", keywords, 9574 path_converter, &path, 9575 conv_path_confname, &name)) { 9576 long limit; 9577 9578 errno = 0; 9579#ifdef HAVE_FPATHCONF 9580 if (path.fd != -1) 9581 limit = fpathconf(path.fd, name); 9582 else 9583#endif 9584 limit = pathconf(path.narrow, name); 9585 if (limit == -1 && errno != 0) { 9586 if (errno == EINVAL) 9587 /* could be a path or name problem */ 9588 posix_error(); 9589 else 9590 result = path_error(&path); 9591 } 9592 else 9593 result = PyLong_FromLong(limit); 9594 } 9595 path_cleanup(&path); 9596 return result; 9597} 9598#endif 9599 9600#ifdef HAVE_CONFSTR 9601static struct constdef posix_constants_confstr[] = { 9602#ifdef _CS_ARCHITECTURE 9603 {"CS_ARCHITECTURE", _CS_ARCHITECTURE}, 9604#endif 9605#ifdef _CS_GNU_LIBC_VERSION 9606 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION}, 9607#endif 9608#ifdef _CS_GNU_LIBPTHREAD_VERSION 9609 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION}, 9610#endif 9611#ifdef _CS_HOSTNAME 9612 {"CS_HOSTNAME", _CS_HOSTNAME}, 9613#endif 9614#ifdef _CS_HW_PROVIDER 9615 {"CS_HW_PROVIDER", _CS_HW_PROVIDER}, 9616#endif 9617#ifdef _CS_HW_SERIAL 9618 {"CS_HW_SERIAL", _CS_HW_SERIAL}, 9619#endif 9620#ifdef _CS_INITTAB_NAME 9621 {"CS_INITTAB_NAME", _CS_INITTAB_NAME}, 9622#endif 9623#ifdef _CS_LFS64_CFLAGS 9624 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS}, 9625#endif 9626#ifdef _CS_LFS64_LDFLAGS 9627 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS}, 9628#endif 9629#ifdef _CS_LFS64_LIBS 9630 {"CS_LFS64_LIBS", _CS_LFS64_LIBS}, 9631#endif 9632#ifdef _CS_LFS64_LINTFLAGS 9633 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS}, 9634#endif 9635#ifdef _CS_LFS_CFLAGS 9636 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS}, 9637#endif 9638#ifdef _CS_LFS_LDFLAGS 9639 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS}, 9640#endif 9641#ifdef _CS_LFS_LIBS 9642 {"CS_LFS_LIBS", _CS_LFS_LIBS}, 9643#endif 9644#ifdef _CS_LFS_LINTFLAGS 9645 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS}, 9646#endif 9647#ifdef _CS_MACHINE 9648 {"CS_MACHINE", _CS_MACHINE}, 9649#endif 9650#ifdef _CS_PATH 9651 {"CS_PATH", _CS_PATH}, 9652#endif 9653#ifdef _CS_RELEASE 9654 {"CS_RELEASE", _CS_RELEASE}, 9655#endif 9656#ifdef _CS_SRPC_DOMAIN 9657 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN}, 9658#endif 9659#ifdef _CS_SYSNAME 9660 {"CS_SYSNAME", _CS_SYSNAME}, 9661#endif 9662#ifdef _CS_VERSION 9663 {"CS_VERSION", _CS_VERSION}, 9664#endif 9665#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS 9666 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS}, 9667#endif 9668#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS 9669 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS}, 9670#endif 9671#ifdef _CS_XBS5_ILP32_OFF32_LIBS 9672 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS}, 9673#endif 9674#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS 9675 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS}, 9676#endif 9677#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS 9678 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS}, 9679#endif 9680#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS 9681 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS}, 9682#endif 9683#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS 9684 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS}, 9685#endif 9686#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS 9687 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS}, 9688#endif 9689#ifdef _CS_XBS5_LP64_OFF64_CFLAGS 9690 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS}, 9691#endif 9692#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS 9693 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS}, 9694#endif 9695#ifdef _CS_XBS5_LP64_OFF64_LIBS 9696 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS}, 9697#endif 9698#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS 9699 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS}, 9700#endif 9701#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS 9702 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS}, 9703#endif 9704#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS 9705 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS}, 9706#endif 9707#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS 9708 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS}, 9709#endif 9710#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS 9711 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS}, 9712#endif 9713#ifdef _MIPS_CS_AVAIL_PROCESSORS 9714 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS}, 9715#endif 9716#ifdef _MIPS_CS_BASE 9717 {"MIPS_CS_BASE", _MIPS_CS_BASE}, 9718#endif 9719#ifdef _MIPS_CS_HOSTID 9720 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID}, 9721#endif 9722#ifdef _MIPS_CS_HW_NAME 9723 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME}, 9724#endif 9725#ifdef _MIPS_CS_NUM_PROCESSORS 9726 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS}, 9727#endif 9728#ifdef _MIPS_CS_OSREL_MAJ 9729 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ}, 9730#endif 9731#ifdef _MIPS_CS_OSREL_MIN 9732 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN}, 9733#endif 9734#ifdef _MIPS_CS_OSREL_PATCH 9735 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH}, 9736#endif 9737#ifdef _MIPS_CS_OS_NAME 9738 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME}, 9739#endif 9740#ifdef _MIPS_CS_OS_PROVIDER 9741 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER}, 9742#endif 9743#ifdef _MIPS_CS_PROCESSORS 9744 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS}, 9745#endif 9746#ifdef _MIPS_CS_SERIAL 9747 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL}, 9748#endif 9749#ifdef _MIPS_CS_VENDOR 9750 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR}, 9751#endif 9752}; 9753 9754static int 9755conv_confstr_confname(PyObject *arg, int *valuep) 9756{ 9757 return conv_confname(arg, valuep, posix_constants_confstr, 9758 sizeof(posix_constants_confstr) 9759 / sizeof(struct constdef)); 9760} 9761 9762PyDoc_STRVAR(posix_confstr__doc__, 9763"confstr(name) -> string\n\n\ 9764Return a string-valued system configuration variable."); 9765 9766static PyObject * 9767posix_confstr(PyObject *self, PyObject *args) 9768{ 9769 PyObject *result = NULL; 9770 int name; 9771 char buffer[255]; 9772 size_t len; 9773 9774 if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) 9775 return NULL; 9776 9777 errno = 0; 9778 len = confstr(name, buffer, sizeof(buffer)); 9779 if (len == 0) { 9780 if (errno) { 9781 posix_error(); 9782 return NULL; 9783 } 9784 else { 9785 Py_RETURN_NONE; 9786 } 9787 } 9788 9789 if (len >= sizeof(buffer)) { 9790 char *buf = PyMem_Malloc(len); 9791 if (buf == NULL) 9792 return PyErr_NoMemory(); 9793 confstr(name, buf, len); 9794 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1); 9795 PyMem_Free(buf); 9796 } 9797 else 9798 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1); 9799 return result; 9800} 9801#endif 9802 9803 9804#ifdef HAVE_SYSCONF 9805static struct constdef posix_constants_sysconf[] = { 9806#ifdef _SC_2_CHAR_TERM 9807 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM}, 9808#endif 9809#ifdef _SC_2_C_BIND 9810 {"SC_2_C_BIND", _SC_2_C_BIND}, 9811#endif 9812#ifdef _SC_2_C_DEV 9813 {"SC_2_C_DEV", _SC_2_C_DEV}, 9814#endif 9815#ifdef _SC_2_C_VERSION 9816 {"SC_2_C_VERSION", _SC_2_C_VERSION}, 9817#endif 9818#ifdef _SC_2_FORT_DEV 9819 {"SC_2_FORT_DEV", _SC_2_FORT_DEV}, 9820#endif 9821#ifdef _SC_2_FORT_RUN 9822 {"SC_2_FORT_RUN", _SC_2_FORT_RUN}, 9823#endif 9824#ifdef _SC_2_LOCALEDEF 9825 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF}, 9826#endif 9827#ifdef _SC_2_SW_DEV 9828 {"SC_2_SW_DEV", _SC_2_SW_DEV}, 9829#endif 9830#ifdef _SC_2_UPE 9831 {"SC_2_UPE", _SC_2_UPE}, 9832#endif 9833#ifdef _SC_2_VERSION 9834 {"SC_2_VERSION", _SC_2_VERSION}, 9835#endif 9836#ifdef _SC_ABI_ASYNCHRONOUS_IO 9837 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO}, 9838#endif 9839#ifdef _SC_ACL 9840 {"SC_ACL", _SC_ACL}, 9841#endif 9842#ifdef _SC_AIO_LISTIO_MAX 9843 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX}, 9844#endif 9845#ifdef _SC_AIO_MAX 9846 {"SC_AIO_MAX", _SC_AIO_MAX}, 9847#endif 9848#ifdef _SC_AIO_PRIO_DELTA_MAX 9849 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX}, 9850#endif 9851#ifdef _SC_ARG_MAX 9852 {"SC_ARG_MAX", _SC_ARG_MAX}, 9853#endif 9854#ifdef _SC_ASYNCHRONOUS_IO 9855 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO}, 9856#endif 9857#ifdef _SC_ATEXIT_MAX 9858 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX}, 9859#endif 9860#ifdef _SC_AUDIT 9861 {"SC_AUDIT", _SC_AUDIT}, 9862#endif 9863#ifdef _SC_AVPHYS_PAGES 9864 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES}, 9865#endif 9866#ifdef _SC_BC_BASE_MAX 9867 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX}, 9868#endif 9869#ifdef _SC_BC_DIM_MAX 9870 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX}, 9871#endif 9872#ifdef _SC_BC_SCALE_MAX 9873 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX}, 9874#endif 9875#ifdef _SC_BC_STRING_MAX 9876 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX}, 9877#endif 9878#ifdef _SC_CAP 9879 {"SC_CAP", _SC_CAP}, 9880#endif 9881#ifdef _SC_CHARCLASS_NAME_MAX 9882 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX}, 9883#endif 9884#ifdef _SC_CHAR_BIT 9885 {"SC_CHAR_BIT", _SC_CHAR_BIT}, 9886#endif 9887#ifdef _SC_CHAR_MAX 9888 {"SC_CHAR_MAX", _SC_CHAR_MAX}, 9889#endif 9890#ifdef _SC_CHAR_MIN 9891 {"SC_CHAR_MIN", _SC_CHAR_MIN}, 9892#endif 9893#ifdef _SC_CHILD_MAX 9894 {"SC_CHILD_MAX", _SC_CHILD_MAX}, 9895#endif 9896#ifdef _SC_CLK_TCK 9897 {"SC_CLK_TCK", _SC_CLK_TCK}, 9898#endif 9899#ifdef _SC_COHER_BLKSZ 9900 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ}, 9901#endif 9902#ifdef _SC_COLL_WEIGHTS_MAX 9903 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX}, 9904#endif 9905#ifdef _SC_DCACHE_ASSOC 9906 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC}, 9907#endif 9908#ifdef _SC_DCACHE_BLKSZ 9909 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ}, 9910#endif 9911#ifdef _SC_DCACHE_LINESZ 9912 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ}, 9913#endif 9914#ifdef _SC_DCACHE_SZ 9915 {"SC_DCACHE_SZ", _SC_DCACHE_SZ}, 9916#endif 9917#ifdef _SC_DCACHE_TBLKSZ 9918 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ}, 9919#endif 9920#ifdef _SC_DELAYTIMER_MAX 9921 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX}, 9922#endif 9923#ifdef _SC_EQUIV_CLASS_MAX 9924 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX}, 9925#endif 9926#ifdef _SC_EXPR_NEST_MAX 9927 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX}, 9928#endif 9929#ifdef _SC_FSYNC 9930 {"SC_FSYNC", _SC_FSYNC}, 9931#endif 9932#ifdef _SC_GETGR_R_SIZE_MAX 9933 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX}, 9934#endif 9935#ifdef _SC_GETPW_R_SIZE_MAX 9936 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX}, 9937#endif 9938#ifdef _SC_ICACHE_ASSOC 9939 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC}, 9940#endif 9941#ifdef _SC_ICACHE_BLKSZ 9942 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ}, 9943#endif 9944#ifdef _SC_ICACHE_LINESZ 9945 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ}, 9946#endif 9947#ifdef _SC_ICACHE_SZ 9948 {"SC_ICACHE_SZ", _SC_ICACHE_SZ}, 9949#endif 9950#ifdef _SC_INF 9951 {"SC_INF", _SC_INF}, 9952#endif 9953#ifdef _SC_INT_MAX 9954 {"SC_INT_MAX", _SC_INT_MAX}, 9955#endif 9956#ifdef _SC_INT_MIN 9957 {"SC_INT_MIN", _SC_INT_MIN}, 9958#endif 9959#ifdef _SC_IOV_MAX 9960 {"SC_IOV_MAX", _SC_IOV_MAX}, 9961#endif 9962#ifdef _SC_IP_SECOPTS 9963 {"SC_IP_SECOPTS", _SC_IP_SECOPTS}, 9964#endif 9965#ifdef _SC_JOB_CONTROL 9966 {"SC_JOB_CONTROL", _SC_JOB_CONTROL}, 9967#endif 9968#ifdef _SC_KERN_POINTERS 9969 {"SC_KERN_POINTERS", _SC_KERN_POINTERS}, 9970#endif 9971#ifdef _SC_KERN_SIM 9972 {"SC_KERN_SIM", _SC_KERN_SIM}, 9973#endif 9974#ifdef _SC_LINE_MAX 9975 {"SC_LINE_MAX", _SC_LINE_MAX}, 9976#endif 9977#ifdef _SC_LOGIN_NAME_MAX 9978 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX}, 9979#endif 9980#ifdef _SC_LOGNAME_MAX 9981 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX}, 9982#endif 9983#ifdef _SC_LONG_BIT 9984 {"SC_LONG_BIT", _SC_LONG_BIT}, 9985#endif 9986#ifdef _SC_MAC 9987 {"SC_MAC", _SC_MAC}, 9988#endif 9989#ifdef _SC_MAPPED_FILES 9990 {"SC_MAPPED_FILES", _SC_MAPPED_FILES}, 9991#endif 9992#ifdef _SC_MAXPID 9993 {"SC_MAXPID", _SC_MAXPID}, 9994#endif 9995#ifdef _SC_MB_LEN_MAX 9996 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX}, 9997#endif 9998#ifdef _SC_MEMLOCK 9999 {"SC_MEMLOCK", _SC_MEMLOCK}, 10000#endif 10001#ifdef _SC_MEMLOCK_RANGE 10002 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE}, 10003#endif 10004#ifdef _SC_MEMORY_PROTECTION 10005 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION}, 10006#endif 10007#ifdef _SC_MESSAGE_PASSING 10008 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING}, 10009#endif 10010#ifdef _SC_MMAP_FIXED_ALIGNMENT 10011 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT}, 10012#endif 10013#ifdef _SC_MQ_OPEN_MAX 10014 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX}, 10015#endif 10016#ifdef _SC_MQ_PRIO_MAX 10017 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX}, 10018#endif 10019#ifdef _SC_NACLS_MAX 10020 {"SC_NACLS_MAX", _SC_NACLS_MAX}, 10021#endif 10022#ifdef _SC_NGROUPS_MAX 10023 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX}, 10024#endif 10025#ifdef _SC_NL_ARGMAX 10026 {"SC_NL_ARGMAX", _SC_NL_ARGMAX}, 10027#endif 10028#ifdef _SC_NL_LANGMAX 10029 {"SC_NL_LANGMAX", _SC_NL_LANGMAX}, 10030#endif 10031#ifdef _SC_NL_MSGMAX 10032 {"SC_NL_MSGMAX", _SC_NL_MSGMAX}, 10033#endif 10034#ifdef _SC_NL_NMAX 10035 {"SC_NL_NMAX", _SC_NL_NMAX}, 10036#endif 10037#ifdef _SC_NL_SETMAX 10038 {"SC_NL_SETMAX", _SC_NL_SETMAX}, 10039#endif 10040#ifdef _SC_NL_TEXTMAX 10041 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX}, 10042#endif 10043#ifdef _SC_NPROCESSORS_CONF 10044 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF}, 10045#endif 10046#ifdef _SC_NPROCESSORS_ONLN 10047 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN}, 10048#endif 10049#ifdef _SC_NPROC_CONF 10050 {"SC_NPROC_CONF", _SC_NPROC_CONF}, 10051#endif 10052#ifdef _SC_NPROC_ONLN 10053 {"SC_NPROC_ONLN", _SC_NPROC_ONLN}, 10054#endif 10055#ifdef _SC_NZERO 10056 {"SC_NZERO", _SC_NZERO}, 10057#endif 10058#ifdef _SC_OPEN_MAX 10059 {"SC_OPEN_MAX", _SC_OPEN_MAX}, 10060#endif 10061#ifdef _SC_PAGESIZE 10062 {"SC_PAGESIZE", _SC_PAGESIZE}, 10063#endif 10064#ifdef _SC_PAGE_SIZE 10065 {"SC_PAGE_SIZE", _SC_PAGE_SIZE}, 10066#endif 10067#ifdef _SC_PASS_MAX 10068 {"SC_PASS_MAX", _SC_PASS_MAX}, 10069#endif 10070#ifdef _SC_PHYS_PAGES 10071 {"SC_PHYS_PAGES", _SC_PHYS_PAGES}, 10072#endif 10073#ifdef _SC_PII 10074 {"SC_PII", _SC_PII}, 10075#endif 10076#ifdef _SC_PII_INTERNET 10077 {"SC_PII_INTERNET", _SC_PII_INTERNET}, 10078#endif 10079#ifdef _SC_PII_INTERNET_DGRAM 10080 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM}, 10081#endif 10082#ifdef _SC_PII_INTERNET_STREAM 10083 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM}, 10084#endif 10085#ifdef _SC_PII_OSI 10086 {"SC_PII_OSI", _SC_PII_OSI}, 10087#endif 10088#ifdef _SC_PII_OSI_CLTS 10089 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS}, 10090#endif 10091#ifdef _SC_PII_OSI_COTS 10092 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS}, 10093#endif 10094#ifdef _SC_PII_OSI_M 10095 {"SC_PII_OSI_M", _SC_PII_OSI_M}, 10096#endif 10097#ifdef _SC_PII_SOCKET 10098 {"SC_PII_SOCKET", _SC_PII_SOCKET}, 10099#endif 10100#ifdef _SC_PII_XTI 10101 {"SC_PII_XTI", _SC_PII_XTI}, 10102#endif 10103#ifdef _SC_POLL 10104 {"SC_POLL", _SC_POLL}, 10105#endif 10106#ifdef _SC_PRIORITIZED_IO 10107 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO}, 10108#endif 10109#ifdef _SC_PRIORITY_SCHEDULING 10110 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING}, 10111#endif 10112#ifdef _SC_REALTIME_SIGNALS 10113 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS}, 10114#endif 10115#ifdef _SC_RE_DUP_MAX 10116 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX}, 10117#endif 10118#ifdef _SC_RTSIG_MAX 10119 {"SC_RTSIG_MAX", _SC_RTSIG_MAX}, 10120#endif 10121#ifdef _SC_SAVED_IDS 10122 {"SC_SAVED_IDS", _SC_SAVED_IDS}, 10123#endif 10124#ifdef _SC_SCHAR_MAX 10125 {"SC_SCHAR_MAX", _SC_SCHAR_MAX}, 10126#endif 10127#ifdef _SC_SCHAR_MIN 10128 {"SC_SCHAR_MIN", _SC_SCHAR_MIN}, 10129#endif 10130#ifdef _SC_SELECT 10131 {"SC_SELECT", _SC_SELECT}, 10132#endif 10133#ifdef _SC_SEMAPHORES 10134 {"SC_SEMAPHORES", _SC_SEMAPHORES}, 10135#endif 10136#ifdef _SC_SEM_NSEMS_MAX 10137 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX}, 10138#endif 10139#ifdef _SC_SEM_VALUE_MAX 10140 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX}, 10141#endif 10142#ifdef _SC_SHARED_MEMORY_OBJECTS 10143 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS}, 10144#endif 10145#ifdef _SC_SHRT_MAX 10146 {"SC_SHRT_MAX", _SC_SHRT_MAX}, 10147#endif 10148#ifdef _SC_SHRT_MIN 10149 {"SC_SHRT_MIN", _SC_SHRT_MIN}, 10150#endif 10151#ifdef _SC_SIGQUEUE_MAX 10152 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX}, 10153#endif 10154#ifdef _SC_SIGRT_MAX 10155 {"SC_SIGRT_MAX", _SC_SIGRT_MAX}, 10156#endif 10157#ifdef _SC_SIGRT_MIN 10158 {"SC_SIGRT_MIN", _SC_SIGRT_MIN}, 10159#endif 10160#ifdef _SC_SOFTPOWER 10161 {"SC_SOFTPOWER", _SC_SOFTPOWER}, 10162#endif 10163#ifdef _SC_SPLIT_CACHE 10164 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE}, 10165#endif 10166#ifdef _SC_SSIZE_MAX 10167 {"SC_SSIZE_MAX", _SC_SSIZE_MAX}, 10168#endif 10169#ifdef _SC_STACK_PROT 10170 {"SC_STACK_PROT", _SC_STACK_PROT}, 10171#endif 10172#ifdef _SC_STREAM_MAX 10173 {"SC_STREAM_MAX", _SC_STREAM_MAX}, 10174#endif 10175#ifdef _SC_SYNCHRONIZED_IO 10176 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO}, 10177#endif 10178#ifdef _SC_THREADS 10179 {"SC_THREADS", _SC_THREADS}, 10180#endif 10181#ifdef _SC_THREAD_ATTR_STACKADDR 10182 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR}, 10183#endif 10184#ifdef _SC_THREAD_ATTR_STACKSIZE 10185 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE}, 10186#endif 10187#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS 10188 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS}, 10189#endif 10190#ifdef _SC_THREAD_KEYS_MAX 10191 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX}, 10192#endif 10193#ifdef _SC_THREAD_PRIORITY_SCHEDULING 10194 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING}, 10195#endif 10196#ifdef _SC_THREAD_PRIO_INHERIT 10197 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT}, 10198#endif 10199#ifdef _SC_THREAD_PRIO_PROTECT 10200 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT}, 10201#endif 10202#ifdef _SC_THREAD_PROCESS_SHARED 10203 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED}, 10204#endif 10205#ifdef _SC_THREAD_SAFE_FUNCTIONS 10206 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS}, 10207#endif 10208#ifdef _SC_THREAD_STACK_MIN 10209 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN}, 10210#endif 10211#ifdef _SC_THREAD_THREADS_MAX 10212 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX}, 10213#endif 10214#ifdef _SC_TIMERS 10215 {"SC_TIMERS", _SC_TIMERS}, 10216#endif 10217#ifdef _SC_TIMER_MAX 10218 {"SC_TIMER_MAX", _SC_TIMER_MAX}, 10219#endif 10220#ifdef _SC_TTY_NAME_MAX 10221 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX}, 10222#endif 10223#ifdef _SC_TZNAME_MAX 10224 {"SC_TZNAME_MAX", _SC_TZNAME_MAX}, 10225#endif 10226#ifdef _SC_T_IOV_MAX 10227 {"SC_T_IOV_MAX", _SC_T_IOV_MAX}, 10228#endif 10229#ifdef _SC_UCHAR_MAX 10230 {"SC_UCHAR_MAX", _SC_UCHAR_MAX}, 10231#endif 10232#ifdef _SC_UINT_MAX 10233 {"SC_UINT_MAX", _SC_UINT_MAX}, 10234#endif 10235#ifdef _SC_UIO_MAXIOV 10236 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV}, 10237#endif 10238#ifdef _SC_ULONG_MAX 10239 {"SC_ULONG_MAX", _SC_ULONG_MAX}, 10240#endif 10241#ifdef _SC_USHRT_MAX 10242 {"SC_USHRT_MAX", _SC_USHRT_MAX}, 10243#endif 10244#ifdef _SC_VERSION 10245 {"SC_VERSION", _SC_VERSION}, 10246#endif 10247#ifdef _SC_WORD_BIT 10248 {"SC_WORD_BIT", _SC_WORD_BIT}, 10249#endif 10250#ifdef _SC_XBS5_ILP32_OFF32 10251 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32}, 10252#endif 10253#ifdef _SC_XBS5_ILP32_OFFBIG 10254 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG}, 10255#endif 10256#ifdef _SC_XBS5_LP64_OFF64 10257 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64}, 10258#endif 10259#ifdef _SC_XBS5_LPBIG_OFFBIG 10260 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG}, 10261#endif 10262#ifdef _SC_XOPEN_CRYPT 10263 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT}, 10264#endif 10265#ifdef _SC_XOPEN_ENH_I18N 10266 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N}, 10267#endif 10268#ifdef _SC_XOPEN_LEGACY 10269 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY}, 10270#endif 10271#ifdef _SC_XOPEN_REALTIME 10272 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME}, 10273#endif 10274#ifdef _SC_XOPEN_REALTIME_THREADS 10275 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS}, 10276#endif 10277#ifdef _SC_XOPEN_SHM 10278 {"SC_XOPEN_SHM", _SC_XOPEN_SHM}, 10279#endif 10280#ifdef _SC_XOPEN_UNIX 10281 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX}, 10282#endif 10283#ifdef _SC_XOPEN_VERSION 10284 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION}, 10285#endif 10286#ifdef _SC_XOPEN_XCU_VERSION 10287 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION}, 10288#endif 10289#ifdef _SC_XOPEN_XPG2 10290 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2}, 10291#endif 10292#ifdef _SC_XOPEN_XPG3 10293 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3}, 10294#endif 10295#ifdef _SC_XOPEN_XPG4 10296 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4}, 10297#endif 10298}; 10299 10300static int 10301conv_sysconf_confname(PyObject *arg, int *valuep) 10302{ 10303 return conv_confname(arg, valuep, posix_constants_sysconf, 10304 sizeof(posix_constants_sysconf) 10305 / sizeof(struct constdef)); 10306} 10307 10308PyDoc_STRVAR(posix_sysconf__doc__, 10309"sysconf(name) -> integer\n\n\ 10310Return an integer-valued system configuration variable."); 10311 10312static PyObject * 10313posix_sysconf(PyObject *self, PyObject *args) 10314{ 10315 PyObject *result = NULL; 10316 int name; 10317 10318 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) { 10319 long value; 10320 10321 errno = 0; 10322 value = sysconf(name); 10323 if (value == -1 && errno != 0) 10324 posix_error(); 10325 else 10326 result = PyLong_FromLong(value); 10327 } 10328 return result; 10329} 10330#endif 10331 10332 10333/* This code is used to ensure that the tables of configuration value names 10334 * are in sorted order as required by conv_confname(), and also to build 10335 * the exported dictionaries that are used to publish information about the 10336 * names available on the host platform. 10337 * 10338 * Sorting the table at runtime ensures that the table is properly ordered 10339 * when used, even for platforms we're not able to test on. It also makes 10340 * it easier to add additional entries to the tables. 10341 */ 10342 10343static int 10344cmp_constdefs(const void *v1, const void *v2) 10345{ 10346 const struct constdef *c1 = 10347 (const struct constdef *) v1; 10348 const struct constdef *c2 = 10349 (const struct constdef *) v2; 10350 10351 return strcmp(c1->name, c2->name); 10352} 10353 10354static int 10355setup_confname_table(struct constdef *table, size_t tablesize, 10356 char *tablename, PyObject *module) 10357{ 10358 PyObject *d = NULL; 10359 size_t i; 10360 10361 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs); 10362 d = PyDict_New(); 10363 if (d == NULL) 10364 return -1; 10365 10366 for (i=0; i < tablesize; ++i) { 10367 PyObject *o = PyLong_FromLong(table[i].value); 10368 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) { 10369 Py_XDECREF(o); 10370 Py_DECREF(d); 10371 return -1; 10372 } 10373 Py_DECREF(o); 10374 } 10375 return PyModule_AddObject(module, tablename, d); 10376} 10377 10378/* Return -1 on failure, 0 on success. */ 10379static int 10380setup_confname_tables(PyObject *module) 10381{ 10382#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF) 10383 if (setup_confname_table(posix_constants_pathconf, 10384 sizeof(posix_constants_pathconf) 10385 / sizeof(struct constdef), 10386 "pathconf_names", module)) 10387 return -1; 10388#endif 10389#ifdef HAVE_CONFSTR 10390 if (setup_confname_table(posix_constants_confstr, 10391 sizeof(posix_constants_confstr) 10392 / sizeof(struct constdef), 10393 "confstr_names", module)) 10394 return -1; 10395#endif 10396#ifdef HAVE_SYSCONF 10397 if (setup_confname_table(posix_constants_sysconf, 10398 sizeof(posix_constants_sysconf) 10399 / sizeof(struct constdef), 10400 "sysconf_names", module)) 10401 return -1; 10402#endif 10403 return 0; 10404} 10405 10406 10407PyDoc_STRVAR(posix_abort__doc__, 10408"abort() -> does not return!\n\n\ 10409Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\ 10410in the hardest way possible on the hosting operating system."); 10411 10412static PyObject * 10413posix_abort(PyObject *self, PyObject *noargs) 10414{ 10415 abort(); 10416 /*NOTREACHED*/ 10417 Py_FatalError("abort() called from Python code didn't abort!"); 10418 return NULL; 10419} 10420 10421#ifdef MS_WINDOWS 10422PyDoc_STRVAR(win32_startfile__doc__, 10423"startfile(filepath [, operation]) - Start a file with its associated\n\ 10424application.\n\ 10425\n\ 10426When \"operation\" is not specified or \"open\", this acts like\n\ 10427double-clicking the file in Explorer, or giving the file name as an\n\ 10428argument to the DOS \"start\" command: the file is opened with whatever\n\ 10429application (if any) its extension is associated.\n\ 10430When another \"operation\" is given, it specifies what should be done with\n\ 10431the file. A typical operation is \"print\".\n\ 10432\n\ 10433startfile returns as soon as the associated application is launched.\n\ 10434There is no option to wait for the application to close, and no way\n\ 10435to retrieve the application's exit status.\n\ 10436\n\ 10437The filepath is relative to the current directory. If you want to use\n\ 10438an absolute path, make sure the first character is not a slash (\"/\");\n\ 10439the underlying Win32 ShellExecute function doesn't work if it is."); 10440 10441static PyObject * 10442win32_startfile(PyObject *self, PyObject *args) 10443{ 10444 PyObject *ofilepath; 10445 char *filepath; 10446 char *operation = NULL; 10447 wchar_t *wpath, *woperation; 10448 HINSTANCE rc; 10449 10450 PyObject *unipath, *uoperation = NULL; 10451 if (!PyArg_ParseTuple(args, "U|s:startfile", 10452 &unipath, &operation)) { 10453 PyErr_Clear(); 10454 goto normal; 10455 } 10456 10457 if (operation) { 10458 uoperation = PyUnicode_DecodeASCII(operation, 10459 strlen(operation), NULL); 10460 if (!uoperation) { 10461 PyErr_Clear(); 10462 operation = NULL; 10463 goto normal; 10464 } 10465 } 10466 10467 wpath = PyUnicode_AsUnicode(unipath); 10468 if (wpath == NULL) 10469 goto normal; 10470 if (uoperation) { 10471 woperation = PyUnicode_AsUnicode(uoperation); 10472 if (woperation == NULL) 10473 goto normal; 10474 } 10475 else 10476 woperation = NULL; 10477 10478 Py_BEGIN_ALLOW_THREADS 10479 rc = ShellExecuteW((HWND)0, woperation, wpath, 10480 NULL, NULL, SW_SHOWNORMAL); 10481 Py_END_ALLOW_THREADS 10482 10483 Py_XDECREF(uoperation); 10484 if (rc <= (HINSTANCE)32) { 10485 win32_error_object("startfile", unipath); 10486 return NULL; 10487 } 10488 Py_INCREF(Py_None); 10489 return Py_None; 10490 10491normal: 10492 if (!PyArg_ParseTuple(args, "O&|s:startfile", 10493 PyUnicode_FSConverter, &ofilepath, 10494 &operation)) 10495 return NULL; 10496 if (win32_warn_bytes_api()) { 10497 Py_DECREF(ofilepath); 10498 return NULL; 10499 } 10500 filepath = PyBytes_AsString(ofilepath); 10501 Py_BEGIN_ALLOW_THREADS 10502 rc = ShellExecute((HWND)0, operation, filepath, 10503 NULL, NULL, SW_SHOWNORMAL); 10504 Py_END_ALLOW_THREADS 10505 if (rc <= (HINSTANCE)32) { 10506 PyObject *errval = win32_error("startfile", filepath); 10507 Py_DECREF(ofilepath); 10508 return errval; 10509 } 10510 Py_DECREF(ofilepath); 10511 Py_INCREF(Py_None); 10512 return Py_None; 10513} 10514#endif 10515 10516#ifdef HAVE_GETLOADAVG 10517PyDoc_STRVAR(posix_getloadavg__doc__, 10518"getloadavg() -> (float, float, float)\n\n\ 10519Return the number of processes in the system run queue averaged over\n\ 10520the last 1, 5, and 15 minutes or raises OSError if the load average\n\ 10521was unobtainable"); 10522 10523static PyObject * 10524posix_getloadavg(PyObject *self, PyObject *noargs) 10525{ 10526 double loadavg[3]; 10527 if (getloadavg(loadavg, 3)!=3) { 10528 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable"); 10529 return NULL; 10530 } else 10531 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]); 10532} 10533#endif 10534 10535PyDoc_STRVAR(device_encoding__doc__, 10536"device_encoding(fd) -> str\n\n\ 10537Return a string describing the encoding of the device\n\ 10538if the output is a terminal; else return None."); 10539 10540static PyObject * 10541device_encoding(PyObject *self, PyObject *args) 10542{ 10543 int fd; 10544 10545 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd)) 10546 return NULL; 10547 10548 return _Py_device_encoding(fd); 10549} 10550 10551#ifdef HAVE_SETRESUID 10552PyDoc_STRVAR(posix_setresuid__doc__, 10553"setresuid(ruid, euid, suid)\n\n\ 10554Set the current process's real, effective, and saved user ids."); 10555 10556static PyObject* 10557posix_setresuid (PyObject *self, PyObject *args) 10558{ 10559 /* We assume uid_t is no larger than a long. */ 10560 uid_t ruid, euid, suid; 10561 if (!PyArg_ParseTuple(args, "O&O&O&:setresuid", 10562 _Py_Uid_Converter, &ruid, 10563 _Py_Uid_Converter, &euid, 10564 _Py_Uid_Converter, &suid)) 10565 return NULL; 10566 if (setresuid(ruid, euid, suid) < 0) 10567 return posix_error(); 10568 Py_RETURN_NONE; 10569} 10570#endif 10571 10572#ifdef HAVE_SETRESGID 10573PyDoc_STRVAR(posix_setresgid__doc__, 10574"setresgid(rgid, egid, sgid)\n\n\ 10575Set the current process's real, effective, and saved group ids."); 10576 10577static PyObject* 10578posix_setresgid (PyObject *self, PyObject *args) 10579{ 10580 gid_t rgid, egid, sgid; 10581 if (!PyArg_ParseTuple(args, "O&O&O&:setresgid", 10582 _Py_Gid_Converter, &rgid, 10583 _Py_Gid_Converter, &egid, 10584 _Py_Gid_Converter, &sgid)) 10585 return NULL; 10586 if (setresgid(rgid, egid, sgid) < 0) 10587 return posix_error(); 10588 Py_RETURN_NONE; 10589} 10590#endif 10591 10592#ifdef HAVE_GETRESUID 10593PyDoc_STRVAR(posix_getresuid__doc__, 10594"getresuid() -> (ruid, euid, suid)\n\n\ 10595Get tuple of the current process's real, effective, and saved user ids."); 10596 10597static PyObject* 10598posix_getresuid (PyObject *self, PyObject *noargs) 10599{ 10600 uid_t ruid, euid, suid; 10601 if (getresuid(&ruid, &euid, &suid) < 0) 10602 return posix_error(); 10603 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid), 10604 _PyLong_FromUid(euid), 10605 _PyLong_FromUid(suid)); 10606} 10607#endif 10608 10609#ifdef HAVE_GETRESGID 10610PyDoc_STRVAR(posix_getresgid__doc__, 10611"getresgid() -> (rgid, egid, sgid)\n\n\ 10612Get tuple of the current process's real, effective, and saved group ids."); 10613 10614static PyObject* 10615posix_getresgid (PyObject *self, PyObject *noargs) 10616{ 10617 uid_t rgid, egid, sgid; 10618 if (getresgid(&rgid, &egid, &sgid) < 0) 10619 return posix_error(); 10620 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid), 10621 _PyLong_FromGid(egid), 10622 _PyLong_FromGid(sgid)); 10623} 10624#endif 10625 10626#ifdef USE_XATTRS 10627 10628PyDoc_STRVAR(posix_getxattr__doc__, 10629"getxattr(path, attribute, *, follow_symlinks=True) -> value\n\n\ 10630Return the value of extended attribute attribute on path.\n\ 10631\n\ 10632path may be either a string or an open file descriptor.\n\ 10633If follow_symlinks is False, and the last element of the path is a symbolic\n\ 10634 link, getxattr will examine the symbolic link itself instead of the file\n\ 10635 the link points to."); 10636 10637static PyObject * 10638posix_getxattr(PyObject *self, PyObject *args, PyObject *kwargs) 10639{ 10640 path_t path; 10641 path_t attribute; 10642 int follow_symlinks = 1; 10643 PyObject *buffer = NULL; 10644 int i; 10645 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL}; 10646 10647 memset(&path, 0, sizeof(path)); 10648 memset(&attribute, 0, sizeof(attribute)); 10649 path.function_name = "getxattr"; 10650 attribute.function_name = "getxattr"; 10651 path.allow_fd = 1; 10652 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:getxattr", keywords, 10653 path_converter, &path, 10654 path_converter, &attribute, 10655 &follow_symlinks)) 10656 return NULL; 10657 10658 if (fd_and_follow_symlinks_invalid("getxattr", path.fd, follow_symlinks)) 10659 goto exit; 10660 10661 for (i = 0; ; i++) { 10662 void *ptr; 10663 ssize_t result; 10664 static Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0}; 10665 Py_ssize_t buffer_size = buffer_sizes[i]; 10666 if (!buffer_size) { 10667 path_error(&path); 10668 goto exit; 10669 } 10670 buffer = PyBytes_FromStringAndSize(NULL, buffer_size); 10671 if (!buffer) 10672 goto exit; 10673 ptr = PyBytes_AS_STRING(buffer); 10674 10675 Py_BEGIN_ALLOW_THREADS; 10676 if (path.fd >= 0) 10677 result = fgetxattr(path.fd, attribute.narrow, ptr, buffer_size); 10678 else if (follow_symlinks) 10679 result = getxattr(path.narrow, attribute.narrow, ptr, buffer_size); 10680 else 10681 result = lgetxattr(path.narrow, attribute.narrow, ptr, buffer_size); 10682 Py_END_ALLOW_THREADS; 10683 10684 if (result < 0) { 10685 Py_DECREF(buffer); 10686 buffer = NULL; 10687 if (errno == ERANGE) 10688 continue; 10689 path_error(&path); 10690 goto exit; 10691 } 10692 10693 if (result != buffer_size) { 10694 /* Can only shrink. */ 10695 _PyBytes_Resize(&buffer, result); 10696 } 10697 break; 10698 } 10699 10700exit: 10701 path_cleanup(&path); 10702 path_cleanup(&attribute); 10703 return buffer; 10704} 10705 10706PyDoc_STRVAR(posix_setxattr__doc__, 10707"setxattr(path, attribute, value, flags=0, *, follow_symlinks=True)\n\n\ 10708Set extended attribute attribute on path to value.\n\ 10709path may be either a string or an open file descriptor.\n\ 10710If follow_symlinks is False, and the last element of the path is a symbolic\n\ 10711 link, setxattr will modify the symbolic link itself instead of the file\n\ 10712 the link points to."); 10713 10714static PyObject * 10715posix_setxattr(PyObject *self, PyObject *args, PyObject *kwargs) 10716{ 10717 path_t path; 10718 path_t attribute; 10719 Py_buffer value; 10720 int flags = 0; 10721 int follow_symlinks = 1; 10722 int result; 10723 PyObject *return_value = NULL; 10724 static char *keywords[] = {"path", "attribute", "value", 10725 "flags", "follow_symlinks", NULL}; 10726 10727 memset(&path, 0, sizeof(path)); 10728 path.function_name = "setxattr"; 10729 path.allow_fd = 1; 10730 memset(&attribute, 0, sizeof(attribute)); 10731 memset(&value, 0, sizeof(value)); 10732 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&y*|i$p:setxattr", 10733 keywords, 10734 path_converter, &path, 10735 path_converter, &attribute, 10736 &value, &flags, 10737 &follow_symlinks)) 10738 return NULL; 10739 10740 if (fd_and_follow_symlinks_invalid("setxattr", path.fd, follow_symlinks)) 10741 goto exit; 10742 10743 Py_BEGIN_ALLOW_THREADS; 10744 if (path.fd > -1) 10745 result = fsetxattr(path.fd, attribute.narrow, 10746 value.buf, value.len, flags); 10747 else if (follow_symlinks) 10748 result = setxattr(path.narrow, attribute.narrow, 10749 value.buf, value.len, flags); 10750 else 10751 result = lsetxattr(path.narrow, attribute.narrow, 10752 value.buf, value.len, flags); 10753 Py_END_ALLOW_THREADS; 10754 10755 if (result) { 10756 return_value = path_error(&path); 10757 goto exit; 10758 } 10759 10760 return_value = Py_None; 10761 Py_INCREF(return_value); 10762 10763exit: 10764 path_cleanup(&path); 10765 path_cleanup(&attribute); 10766 PyBuffer_Release(&value); 10767 10768 return return_value; 10769} 10770 10771PyDoc_STRVAR(posix_removexattr__doc__, 10772"removexattr(path, attribute, *, follow_symlinks=True)\n\n\ 10773Remove extended attribute attribute on path.\n\ 10774path may be either a string or an open file descriptor.\n\ 10775If follow_symlinks is False, and the last element of the path is a symbolic\n\ 10776 link, removexattr will modify the symbolic link itself instead of the file\n\ 10777 the link points to."); 10778 10779static PyObject * 10780posix_removexattr(PyObject *self, PyObject *args, PyObject *kwargs) 10781{ 10782 path_t path; 10783 path_t attribute; 10784 int follow_symlinks = 1; 10785 int result; 10786 PyObject *return_value = NULL; 10787 static char *keywords[] = {"path", "attribute", "follow_symlinks", NULL}; 10788 10789 memset(&path, 0, sizeof(path)); 10790 path.function_name = "removexattr"; 10791 memset(&attribute, 0, sizeof(attribute)); 10792 attribute.function_name = "removexattr"; 10793 path.allow_fd = 1; 10794 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&|$p:removexattr", 10795 keywords, 10796 path_converter, &path, 10797 path_converter, &attribute, 10798 &follow_symlinks)) 10799 return NULL; 10800 10801 if (fd_and_follow_symlinks_invalid("removexattr", path.fd, follow_symlinks)) 10802 goto exit; 10803 10804 Py_BEGIN_ALLOW_THREADS; 10805 if (path.fd > -1) 10806 result = fremovexattr(path.fd, attribute.narrow); 10807 else if (follow_symlinks) 10808 result = removexattr(path.narrow, attribute.narrow); 10809 else 10810 result = lremovexattr(path.narrow, attribute.narrow); 10811 Py_END_ALLOW_THREADS; 10812 10813 if (result) { 10814 return_value = path_error(&path); 10815 goto exit; 10816 } 10817 10818 return_value = Py_None; 10819 Py_INCREF(return_value); 10820 10821exit: 10822 path_cleanup(&path); 10823 path_cleanup(&attribute); 10824 10825 return return_value; 10826} 10827 10828PyDoc_STRVAR(posix_listxattr__doc__, 10829"listxattr(path='.', *, follow_symlinks=True)\n\n\ 10830Return a list of extended attributes on path.\n\ 10831\n\ 10832path may be either None, a string, or an open file descriptor.\n\ 10833if path is None, listxattr will examine the current directory.\n\ 10834If follow_symlinks is False, and the last element of the path is a symbolic\n\ 10835 link, listxattr will examine the symbolic link itself instead of the file\n\ 10836 the link points to."); 10837 10838static PyObject * 10839posix_listxattr(PyObject *self, PyObject *args, PyObject *kwargs) 10840{ 10841 path_t path; 10842 int follow_symlinks = 1; 10843 Py_ssize_t i; 10844 PyObject *result = NULL; 10845 char *buffer = NULL; 10846 char *name; 10847 static char *keywords[] = {"path", "follow_symlinks", NULL}; 10848 10849 memset(&path, 0, sizeof(path)); 10850 path.function_name = "listxattr"; 10851 path.allow_fd = 1; 10852 path.fd = -1; 10853 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&$p:listxattr", keywords, 10854 path_converter, &path, 10855 &follow_symlinks)) 10856 return NULL; 10857 10858 if (fd_and_follow_symlinks_invalid("listxattr", path.fd, follow_symlinks)) 10859 goto exit; 10860 10861 name = path.narrow ? path.narrow : "."; 10862 for (i = 0; ; i++) { 10863 char *start, *trace, *end; 10864 ssize_t length; 10865 static Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 }; 10866 Py_ssize_t buffer_size = buffer_sizes[i]; 10867 if (!buffer_size) { 10868 /* ERANGE */ 10869 path_error(&path); 10870 break; 10871 } 10872 buffer = PyMem_MALLOC(buffer_size); 10873 if (!buffer) { 10874 PyErr_NoMemory(); 10875 break; 10876 } 10877 10878 Py_BEGIN_ALLOW_THREADS; 10879 if (path.fd > -1) 10880 length = flistxattr(path.fd, buffer, buffer_size); 10881 else if (follow_symlinks) 10882 length = listxattr(name, buffer, buffer_size); 10883 else 10884 length = llistxattr(name, buffer, buffer_size); 10885 Py_END_ALLOW_THREADS; 10886 10887 if (length < 0) { 10888 if (errno == ERANGE) { 10889 PyMem_FREE(buffer); 10890 buffer = NULL; 10891 continue; 10892 } 10893 path_error(&path); 10894 break; 10895 } 10896 10897 result = PyList_New(0); 10898 if (!result) { 10899 goto exit; 10900 } 10901 10902 end = buffer + length; 10903 for (trace = start = buffer; trace != end; trace++) { 10904 if (!*trace) { 10905 int error; 10906 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start, 10907 trace - start); 10908 if (!attribute) { 10909 Py_DECREF(result); 10910 result = NULL; 10911 goto exit; 10912 } 10913 error = PyList_Append(result, attribute); 10914 Py_DECREF(attribute); 10915 if (error) { 10916 Py_DECREF(result); 10917 result = NULL; 10918 goto exit; 10919 } 10920 start = trace + 1; 10921 } 10922 } 10923 break; 10924 } 10925exit: 10926 path_cleanup(&path); 10927 if (buffer) 10928 PyMem_FREE(buffer); 10929 return result; 10930} 10931 10932#endif /* USE_XATTRS */ 10933 10934 10935PyDoc_STRVAR(posix_urandom__doc__, 10936"urandom(n) -> str\n\n\ 10937Return n random bytes suitable for cryptographic use."); 10938 10939static PyObject * 10940posix_urandom(PyObject *self, PyObject *args) 10941{ 10942 Py_ssize_t size; 10943 PyObject *result; 10944 int ret; 10945 10946 /* Read arguments */ 10947 if (!PyArg_ParseTuple(args, "n:urandom", &size)) 10948 return NULL; 10949 if (size < 0) 10950 return PyErr_Format(PyExc_ValueError, 10951 "negative argument not allowed"); 10952 result = PyBytes_FromStringAndSize(NULL, size); 10953 if (result == NULL) 10954 return NULL; 10955 10956 ret = _PyOS_URandom(PyBytes_AS_STRING(result), 10957 PyBytes_GET_SIZE(result)); 10958 if (ret == -1) { 10959 Py_DECREF(result); 10960 return NULL; 10961 } 10962 return result; 10963} 10964 10965/* Terminal size querying */ 10966 10967static PyTypeObject TerminalSizeType; 10968 10969PyDoc_STRVAR(TerminalSize_docstring, 10970 "A tuple of (columns, lines) for holding terminal window size"); 10971 10972static PyStructSequence_Field TerminalSize_fields[] = { 10973 {"columns", "width of the terminal window in characters"}, 10974 {"lines", "height of the terminal window in characters"}, 10975 {NULL, NULL} 10976}; 10977 10978static PyStructSequence_Desc TerminalSize_desc = { 10979 "os.terminal_size", 10980 TerminalSize_docstring, 10981 TerminalSize_fields, 10982 2, 10983}; 10984 10985#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) 10986PyDoc_STRVAR(termsize__doc__, 10987 "Return the size of the terminal window as (columns, lines).\n" \ 10988 "\n" \ 10989 "The optional argument fd (default standard output) specifies\n" \ 10990 "which file descriptor should be queried.\n" \ 10991 "\n" \ 10992 "If the file descriptor is not connected to a terminal, an OSError\n" \ 10993 "is thrown.\n" \ 10994 "\n" \ 10995 "This function will only be defined if an implementation is\n" \ 10996 "available for this system.\n" \ 10997 "\n" \ 10998 "shutil.get_terminal_size is the high-level function which should \n" \ 10999 "normally be used, os.get_terminal_size is the low-level implementation."); 11000 11001static PyObject* 11002get_terminal_size(PyObject *self, PyObject *args) 11003{ 11004 int columns, lines; 11005 PyObject *termsize; 11006 11007 int fd = fileno(stdout); 11008 /* Under some conditions stdout may not be connected and 11009 * fileno(stdout) may point to an invalid file descriptor. For example 11010 * GUI apps don't have valid standard streams by default. 11011 * 11012 * If this happens, and the optional fd argument is not present, 11013 * the ioctl below will fail returning EBADF. This is what we want. 11014 */ 11015 11016 if (!PyArg_ParseTuple(args, "|i", &fd)) 11017 return NULL; 11018 11019#ifdef TERMSIZE_USE_IOCTL 11020 { 11021 struct winsize w; 11022 if (ioctl(fd, TIOCGWINSZ, &w)) 11023 return PyErr_SetFromErrno(PyExc_OSError); 11024 columns = w.ws_col; 11025 lines = w.ws_row; 11026 } 11027#endif /* TERMSIZE_USE_IOCTL */ 11028 11029#ifdef TERMSIZE_USE_CONIO 11030 { 11031 DWORD nhandle; 11032 HANDLE handle; 11033 CONSOLE_SCREEN_BUFFER_INFO csbi; 11034 switch (fd) { 11035 case 0: nhandle = STD_INPUT_HANDLE; 11036 break; 11037 case 1: nhandle = STD_OUTPUT_HANDLE; 11038 break; 11039 case 2: nhandle = STD_ERROR_HANDLE; 11040 break; 11041 default: 11042 return PyErr_Format(PyExc_ValueError, "bad file descriptor"); 11043 } 11044 handle = GetStdHandle(nhandle); 11045 if (handle == NULL) 11046 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved"); 11047 if (handle == INVALID_HANDLE_VALUE) 11048 return PyErr_SetFromWindowsErr(0); 11049 11050 if (!GetConsoleScreenBufferInfo(handle, &csbi)) 11051 return PyErr_SetFromWindowsErr(0); 11052 11053 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1; 11054 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1; 11055 } 11056#endif /* TERMSIZE_USE_CONIO */ 11057 11058 termsize = PyStructSequence_New(&TerminalSizeType); 11059 if (termsize == NULL) 11060 return NULL; 11061 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns)); 11062 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines)); 11063 if (PyErr_Occurred()) { 11064 Py_DECREF(termsize); 11065 return NULL; 11066 } 11067 return termsize; 11068} 11069#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */ 11070 11071PyDoc_STRVAR(posix_cpu_count__doc__, 11072"cpu_count() -> integer\n\n\ 11073Return the number of CPUs in the system, or None if this value cannot be\n\ 11074established."); 11075 11076static PyObject * 11077posix_cpu_count(PyObject *self) 11078{ 11079 int ncpu = 0; 11080#ifdef MS_WINDOWS 11081 SYSTEM_INFO sysinfo; 11082 GetSystemInfo(&sysinfo); 11083 ncpu = sysinfo.dwNumberOfProcessors; 11084#elif defined(__hpux) 11085 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL); 11086#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN) 11087 ncpu = sysconf(_SC_NPROCESSORS_ONLN); 11088#elif defined(__DragonFly__) || \ 11089 defined(__OpenBSD__) || \ 11090 defined(__FreeBSD__) || \ 11091 defined(__NetBSD__) || \ 11092 defined(__APPLE__) 11093 int mib[2]; 11094 size_t len = sizeof(ncpu); 11095 mib[0] = CTL_HW; 11096 mib[1] = HW_NCPU; 11097 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0) 11098 ncpu = 0; 11099#endif 11100 if (ncpu >= 1) 11101 return PyLong_FromLong(ncpu); 11102 else 11103 Py_RETURN_NONE; 11104} 11105 11106PyDoc_STRVAR(get_inheritable__doc__, 11107 "get_inheritable(fd) -> bool\n" \ 11108 "\n" \ 11109 "Get the close-on-exe flag of the specified file descriptor."); 11110 11111static PyObject* 11112posix_get_inheritable(PyObject *self, PyObject *args) 11113{ 11114 int fd; 11115 int inheritable; 11116 11117 if (!PyArg_ParseTuple(args, "i:get_inheritable", &fd)) 11118 return NULL; 11119 11120 if (!_PyVerify_fd(fd)) 11121 return posix_error(); 11122 11123 inheritable = _Py_get_inheritable(fd); 11124 if (inheritable < 0) 11125 return NULL; 11126 return PyBool_FromLong(inheritable); 11127} 11128 11129PyDoc_STRVAR(set_inheritable__doc__, 11130 "set_inheritable(fd, inheritable)\n" \ 11131 "\n" \ 11132 "Set the inheritable flag of the specified file descriptor."); 11133 11134static PyObject* 11135posix_set_inheritable(PyObject *self, PyObject *args) 11136{ 11137 int fd, inheritable; 11138 11139 if (!PyArg_ParseTuple(args, "ii:set_inheritable", &fd, &inheritable)) 11140 return NULL; 11141 11142 if (!_PyVerify_fd(fd)) 11143 return posix_error(); 11144 11145 if (_Py_set_inheritable(fd, inheritable, NULL) < 0) 11146 return NULL; 11147 Py_RETURN_NONE; 11148} 11149 11150 11151#ifdef MS_WINDOWS 11152PyDoc_STRVAR(get_handle_inheritable__doc__, 11153 "get_handle_inheritable(fd) -> bool\n" \ 11154 "\n" \ 11155 "Get the close-on-exe flag of the specified file descriptor."); 11156 11157static PyObject* 11158posix_get_handle_inheritable(PyObject *self, PyObject *args) 11159{ 11160 Py_intptr_t handle; 11161 DWORD flags; 11162 11163 if (!PyArg_ParseTuple(args, _Py_PARSE_INTPTR ":get_handle_inheritable", &handle)) 11164 return NULL; 11165 11166 if (!GetHandleInformation((HANDLE)handle, &flags)) { 11167 PyErr_SetFromWindowsErr(0); 11168 return NULL; 11169 } 11170 11171 return PyBool_FromLong(flags & HANDLE_FLAG_INHERIT); 11172} 11173 11174PyDoc_STRVAR(set_handle_inheritable__doc__, 11175 "set_handle_inheritable(fd, inheritable)\n" \ 11176 "\n" \ 11177 "Set the inheritable flag of the specified handle."); 11178 11179static PyObject* 11180posix_set_handle_inheritable(PyObject *self, PyObject *args) 11181{ 11182 int inheritable = 1; 11183 Py_intptr_t handle; 11184 DWORD flags; 11185 11186 if (!PyArg_ParseTuple(args, _Py_PARSE_INTPTR "i:set_handle_inheritable", 11187 &handle, &inheritable)) 11188 return NULL; 11189 11190 if (inheritable) 11191 flags = HANDLE_FLAG_INHERIT; 11192 else 11193 flags = 0; 11194 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) { 11195 PyErr_SetFromWindowsErr(0); 11196 return NULL; 11197 } 11198 Py_RETURN_NONE; 11199} 11200#endif /* MS_WINDOWS */ 11201 11202 11203/*[clinic input] 11204dump buffer 11205[clinic start generated code]*/ 11206 11207#ifndef OS_TTYNAME_METHODDEF 11208 #define OS_TTYNAME_METHODDEF 11209#endif /* !defined(OS_TTYNAME_METHODDEF) */ 11210/*[clinic end generated code: output=5d071bbc8f49ea12 input=524ce2e021e4eba6]*/ 11211 11212 11213static PyMethodDef posix_methods[] = { 11214 11215 OS_STAT_METHODDEF 11216 OS_ACCESS_METHODDEF 11217 OS_TTYNAME_METHODDEF 11218 11219 {"chdir", (PyCFunction)posix_chdir, 11220 METH_VARARGS | METH_KEYWORDS, 11221 posix_chdir__doc__}, 11222#ifdef HAVE_CHFLAGS 11223 {"chflags", (PyCFunction)posix_chflags, 11224 METH_VARARGS | METH_KEYWORDS, 11225 posix_chflags__doc__}, 11226#endif /* HAVE_CHFLAGS */ 11227 {"chmod", (PyCFunction)posix_chmod, 11228 METH_VARARGS | METH_KEYWORDS, 11229 posix_chmod__doc__}, 11230#ifdef HAVE_FCHMOD 11231 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__}, 11232#endif /* HAVE_FCHMOD */ 11233#ifdef HAVE_CHOWN 11234 {"chown", (PyCFunction)posix_chown, 11235 METH_VARARGS | METH_KEYWORDS, 11236 posix_chown__doc__}, 11237#endif /* HAVE_CHOWN */ 11238#ifdef HAVE_LCHMOD 11239 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__}, 11240#endif /* HAVE_LCHMOD */ 11241#ifdef HAVE_FCHOWN 11242 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__}, 11243#endif /* HAVE_FCHOWN */ 11244#ifdef HAVE_LCHFLAGS 11245 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__}, 11246#endif /* HAVE_LCHFLAGS */ 11247#ifdef HAVE_LCHOWN 11248 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__}, 11249#endif /* HAVE_LCHOWN */ 11250#ifdef HAVE_CHROOT 11251 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__}, 11252#endif 11253#ifdef HAVE_CTERMID 11254 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__}, 11255#endif 11256 {"getcwd", (PyCFunction)posix_getcwd_unicode, 11257 METH_NOARGS, posix_getcwd__doc__}, 11258 {"getcwdb", (PyCFunction)posix_getcwd_bytes, 11259 METH_NOARGS, posix_getcwdb__doc__}, 11260#if defined(HAVE_LINK) || defined(MS_WINDOWS) 11261 {"link", (PyCFunction)posix_link, 11262 METH_VARARGS | METH_KEYWORDS, 11263 posix_link__doc__}, 11264#endif /* HAVE_LINK */ 11265 {"listdir", (PyCFunction)posix_listdir, 11266 METH_VARARGS | METH_KEYWORDS, 11267 posix_listdir__doc__}, 11268 {"lstat", (PyCFunction)posix_lstat, 11269 METH_VARARGS | METH_KEYWORDS, 11270 posix_lstat__doc__}, 11271 {"mkdir", (PyCFunction)posix_mkdir, 11272 METH_VARARGS | METH_KEYWORDS, 11273 posix_mkdir__doc__}, 11274#ifdef HAVE_NICE 11275 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__}, 11276#endif /* HAVE_NICE */ 11277#ifdef HAVE_GETPRIORITY 11278 {"getpriority", posix_getpriority, METH_VARARGS, posix_getpriority__doc__}, 11279#endif /* HAVE_GETPRIORITY */ 11280#ifdef HAVE_SETPRIORITY 11281 {"setpriority", posix_setpriority, METH_VARARGS, posix_setpriority__doc__}, 11282#endif /* HAVE_SETPRIORITY */ 11283#ifdef HAVE_READLINK 11284 {"readlink", (PyCFunction)posix_readlink, 11285 METH_VARARGS | METH_KEYWORDS, 11286 readlink__doc__}, 11287#endif /* HAVE_READLINK */ 11288#if !defined(HAVE_READLINK) && defined(MS_WINDOWS) 11289 {"readlink", (PyCFunction)win_readlink, 11290 METH_VARARGS | METH_KEYWORDS, 11291 readlink__doc__}, 11292#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */ 11293 {"rename", (PyCFunction)posix_rename, 11294 METH_VARARGS | METH_KEYWORDS, 11295 posix_rename__doc__}, 11296 {"replace", (PyCFunction)posix_replace, 11297 METH_VARARGS | METH_KEYWORDS, 11298 posix_replace__doc__}, 11299 {"rmdir", (PyCFunction)posix_rmdir, 11300 METH_VARARGS | METH_KEYWORDS, 11301 posix_rmdir__doc__}, 11302 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__}, 11303#if defined(HAVE_SYMLINK) 11304 {"symlink", (PyCFunction)posix_symlink, 11305 METH_VARARGS | METH_KEYWORDS, 11306 posix_symlink__doc__}, 11307#endif /* HAVE_SYMLINK */ 11308#ifdef HAVE_SYSTEM 11309 {"system", posix_system, METH_VARARGS, posix_system__doc__}, 11310#endif 11311 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__}, 11312#ifdef HAVE_UNAME 11313 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__}, 11314#endif /* HAVE_UNAME */ 11315 {"unlink", (PyCFunction)posix_unlink, 11316 METH_VARARGS | METH_KEYWORDS, 11317 posix_unlink__doc__}, 11318 {"remove", (PyCFunction)posix_unlink, 11319 METH_VARARGS | METH_KEYWORDS, 11320 posix_remove__doc__}, 11321 {"utime", (PyCFunction)posix_utime, 11322 METH_VARARGS | METH_KEYWORDS, posix_utime__doc__}, 11323#ifdef HAVE_TIMES 11324 {"times", posix_times, METH_NOARGS, posix_times__doc__}, 11325#endif /* HAVE_TIMES */ 11326 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__}, 11327#ifdef HAVE_EXECV 11328 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__}, 11329 {"execve", (PyCFunction)posix_execve, 11330 METH_VARARGS | METH_KEYWORDS, 11331 posix_execve__doc__}, 11332#endif /* HAVE_EXECV */ 11333#ifdef HAVE_SPAWNV 11334 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__}, 11335 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__}, 11336#endif /* HAVE_SPAWNV */ 11337#ifdef HAVE_FORK1 11338 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__}, 11339#endif /* HAVE_FORK1 */ 11340#ifdef HAVE_FORK 11341 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__}, 11342#endif /* HAVE_FORK */ 11343#ifdef HAVE_SCHED_H 11344#ifdef HAVE_SCHED_GET_PRIORITY_MAX 11345 {"sched_get_priority_max", posix_sched_get_priority_max, METH_VARARGS, posix_sched_get_priority_max__doc__}, 11346 {"sched_get_priority_min", posix_sched_get_priority_min, METH_VARARGS, posix_sched_get_priority_min__doc__}, 11347#endif 11348#ifdef HAVE_SCHED_SETPARAM 11349 {"sched_getparam", posix_sched_getparam, METH_VARARGS, posix_sched_getparam__doc__}, 11350#endif 11351#ifdef HAVE_SCHED_SETSCHEDULER 11352 {"sched_getscheduler", posix_sched_getscheduler, METH_VARARGS, posix_sched_getscheduler__doc__}, 11353#endif 11354#ifdef HAVE_SCHED_RR_GET_INTERVAL 11355 {"sched_rr_get_interval", posix_sched_rr_get_interval, METH_VARARGS, posix_sched_rr_get_interval__doc__}, 11356#endif 11357#ifdef HAVE_SCHED_SETPARAM 11358 {"sched_setparam", posix_sched_setparam, METH_VARARGS, posix_sched_setparam__doc__}, 11359#endif 11360#ifdef HAVE_SCHED_SETSCHEDULER 11361 {"sched_setscheduler", posix_sched_setscheduler, METH_VARARGS, posix_sched_setscheduler__doc__}, 11362#endif 11363 {"sched_yield", posix_sched_yield, METH_NOARGS, posix_sched_yield__doc__}, 11364#ifdef HAVE_SCHED_SETAFFINITY 11365 {"sched_setaffinity", posix_sched_setaffinity, METH_VARARGS, posix_sched_setaffinity__doc__}, 11366 {"sched_getaffinity", posix_sched_getaffinity, METH_VARARGS, posix_sched_getaffinity__doc__}, 11367#endif 11368#endif /* HAVE_SCHED_H */ 11369#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) 11370 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__}, 11371#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */ 11372#ifdef HAVE_FORKPTY 11373 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__}, 11374#endif /* HAVE_FORKPTY */ 11375#ifdef HAVE_GETEGID 11376 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__}, 11377#endif /* HAVE_GETEGID */ 11378#ifdef HAVE_GETEUID 11379 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__}, 11380#endif /* HAVE_GETEUID */ 11381#ifdef HAVE_GETGID 11382 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__}, 11383#endif /* HAVE_GETGID */ 11384#ifdef HAVE_GETGROUPLIST 11385 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__}, 11386#endif 11387#ifdef HAVE_GETGROUPS 11388 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__}, 11389#endif 11390 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__}, 11391#ifdef HAVE_GETPGRP 11392 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__}, 11393#endif /* HAVE_GETPGRP */ 11394#ifdef HAVE_GETPPID 11395 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__}, 11396#endif /* HAVE_GETPPID */ 11397#ifdef HAVE_GETUID 11398 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__}, 11399#endif /* HAVE_GETUID */ 11400#ifdef HAVE_GETLOGIN 11401 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__}, 11402#endif 11403#ifdef HAVE_KILL 11404 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__}, 11405#endif /* HAVE_KILL */ 11406#ifdef HAVE_KILLPG 11407 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__}, 11408#endif /* HAVE_KILLPG */ 11409#ifdef HAVE_PLOCK 11410 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__}, 11411#endif /* HAVE_PLOCK */ 11412#ifdef MS_WINDOWS 11413 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__}, 11414 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__}, 11415#endif 11416#ifdef HAVE_SETUID 11417 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__}, 11418#endif /* HAVE_SETUID */ 11419#ifdef HAVE_SETEUID 11420 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__}, 11421#endif /* HAVE_SETEUID */ 11422#ifdef HAVE_SETEGID 11423 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__}, 11424#endif /* HAVE_SETEGID */ 11425#ifdef HAVE_SETREUID 11426 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__}, 11427#endif /* HAVE_SETREUID */ 11428#ifdef HAVE_SETREGID 11429 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__}, 11430#endif /* HAVE_SETREGID */ 11431#ifdef HAVE_SETGID 11432 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__}, 11433#endif /* HAVE_SETGID */ 11434#ifdef HAVE_SETGROUPS 11435 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__}, 11436#endif /* HAVE_SETGROUPS */ 11437#ifdef HAVE_INITGROUPS 11438 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__}, 11439#endif /* HAVE_INITGROUPS */ 11440#ifdef HAVE_GETPGID 11441 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__}, 11442#endif /* HAVE_GETPGID */ 11443#ifdef HAVE_SETPGRP 11444 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__}, 11445#endif /* HAVE_SETPGRP */ 11446#ifdef HAVE_WAIT 11447 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__}, 11448#endif /* HAVE_WAIT */ 11449#ifdef HAVE_WAIT3 11450 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__}, 11451#endif /* HAVE_WAIT3 */ 11452#ifdef HAVE_WAIT4 11453 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__}, 11454#endif /* HAVE_WAIT4 */ 11455#if defined(HAVE_WAITID) && !defined(__APPLE__) 11456 {"waitid", posix_waitid, METH_VARARGS, posix_waitid__doc__}, 11457#endif 11458#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT) 11459 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__}, 11460#endif /* HAVE_WAITPID */ 11461#ifdef HAVE_GETSID 11462 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__}, 11463#endif /* HAVE_GETSID */ 11464#ifdef HAVE_SETSID 11465 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__}, 11466#endif /* HAVE_SETSID */ 11467#ifdef HAVE_SETPGID 11468 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__}, 11469#endif /* HAVE_SETPGID */ 11470#ifdef HAVE_TCGETPGRP 11471 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__}, 11472#endif /* HAVE_TCGETPGRP */ 11473#ifdef HAVE_TCSETPGRP 11474 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__}, 11475#endif /* HAVE_TCSETPGRP */ 11476 {"open", (PyCFunction)posix_open,\ 11477 METH_VARARGS | METH_KEYWORDS, 11478 posix_open__doc__}, 11479 {"close", posix_close_, METH_VARARGS, posix_close__doc__}, 11480 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__}, 11481 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__}, 11482 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__}, 11483 {"dup2", (PyCFunction)posix_dup2, 11484 METH_VARARGS | METH_KEYWORDS, posix_dup2__doc__}, 11485#ifdef HAVE_LOCKF 11486 {"lockf", posix_lockf, METH_VARARGS, posix_lockf__doc__}, 11487#endif 11488 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__}, 11489 {"read", posix_read, METH_VARARGS, posix_read__doc__}, 11490#ifdef HAVE_READV 11491 {"readv", posix_readv, METH_VARARGS, posix_readv__doc__}, 11492#endif 11493#ifdef HAVE_PREAD 11494 {"pread", posix_pread, METH_VARARGS, posix_pread__doc__}, 11495#endif 11496 {"write", posix_write, METH_VARARGS, posix_write__doc__}, 11497#ifdef HAVE_WRITEV 11498 {"writev", posix_writev, METH_VARARGS, posix_writev__doc__}, 11499#endif 11500#ifdef HAVE_PWRITE 11501 {"pwrite", posix_pwrite, METH_VARARGS, posix_pwrite__doc__}, 11502#endif 11503#ifdef HAVE_SENDFILE 11504 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS, 11505 posix_sendfile__doc__}, 11506#endif 11507 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__}, 11508 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__}, 11509#ifdef HAVE_PIPE 11510 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__}, 11511#endif 11512#ifdef HAVE_PIPE2 11513 {"pipe2", posix_pipe2, METH_O, posix_pipe2__doc__}, 11514#endif 11515#ifdef HAVE_MKFIFO 11516 {"mkfifo", (PyCFunction)posix_mkfifo, 11517 METH_VARARGS | METH_KEYWORDS, 11518 posix_mkfifo__doc__}, 11519#endif 11520#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) 11521 {"mknod", (PyCFunction)posix_mknod, 11522 METH_VARARGS | METH_KEYWORDS, 11523 posix_mknod__doc__}, 11524#endif 11525#ifdef HAVE_DEVICE_MACROS 11526 {"major", posix_major, METH_VARARGS, posix_major__doc__}, 11527 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__}, 11528 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__}, 11529#endif 11530#ifdef HAVE_FTRUNCATE 11531 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__}, 11532#endif 11533#ifdef HAVE_TRUNCATE 11534 {"truncate", (PyCFunction)posix_truncate, 11535 METH_VARARGS | METH_KEYWORDS, 11536 posix_truncate__doc__}, 11537#endif 11538#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG) 11539 {"posix_fallocate", posix_posix_fallocate, METH_VARARGS, posix_posix_fallocate__doc__}, 11540#endif 11541#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG) 11542 {"posix_fadvise", posix_posix_fadvise, METH_VARARGS, posix_posix_fadvise__doc__}, 11543#endif 11544#ifdef HAVE_PUTENV 11545 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__}, 11546#endif 11547#ifdef HAVE_UNSETENV 11548 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__}, 11549#endif 11550 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__}, 11551#ifdef HAVE_FCHDIR 11552 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__}, 11553#endif 11554#ifdef HAVE_FSYNC 11555 {"fsync", posix_fsync, METH_O, posix_fsync__doc__}, 11556#endif 11557#ifdef HAVE_SYNC 11558 {"sync", posix_sync, METH_NOARGS, posix_sync__doc__}, 11559#endif 11560#ifdef HAVE_FDATASYNC 11561 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__}, 11562#endif 11563#ifdef HAVE_SYS_WAIT_H 11564#ifdef WCOREDUMP 11565 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__}, 11566#endif /* WCOREDUMP */ 11567#ifdef WIFCONTINUED 11568 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__}, 11569#endif /* WIFCONTINUED */ 11570#ifdef WIFSTOPPED 11571 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__}, 11572#endif /* WIFSTOPPED */ 11573#ifdef WIFSIGNALED 11574 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__}, 11575#endif /* WIFSIGNALED */ 11576#ifdef WIFEXITED 11577 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__}, 11578#endif /* WIFEXITED */ 11579#ifdef WEXITSTATUS 11580 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__}, 11581#endif /* WEXITSTATUS */ 11582#ifdef WTERMSIG 11583 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__}, 11584#endif /* WTERMSIG */ 11585#ifdef WSTOPSIG 11586 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__}, 11587#endif /* WSTOPSIG */ 11588#endif /* HAVE_SYS_WAIT_H */ 11589#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) 11590 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__}, 11591#endif 11592#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) 11593 {"statvfs", (PyCFunction)posix_statvfs, 11594 METH_VARARGS | METH_KEYWORDS, 11595 posix_statvfs__doc__}, 11596#endif 11597#ifdef HAVE_CONFSTR 11598 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__}, 11599#endif 11600#ifdef HAVE_SYSCONF 11601 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__}, 11602#endif 11603#ifdef HAVE_FPATHCONF 11604 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__}, 11605#endif 11606#ifdef HAVE_PATHCONF 11607 {"pathconf", (PyCFunction)posix_pathconf, 11608 METH_VARARGS | METH_KEYWORDS, 11609 posix_pathconf__doc__}, 11610#endif 11611 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__}, 11612#ifdef MS_WINDOWS 11613 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL}, 11614 {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL}, 11615 {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__}, 11616 {"_getdiskusage", win32__getdiskusage, METH_VARARGS, win32__getdiskusage__doc__}, 11617 {"_getvolumepathname", posix__getvolumepathname, METH_VARARGS, posix__getvolumepathname__doc__}, 11618#endif 11619#ifdef HAVE_GETLOADAVG 11620 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__}, 11621#endif 11622 {"urandom", posix_urandom, METH_VARARGS, posix_urandom__doc__}, 11623#ifdef HAVE_SETRESUID 11624 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__}, 11625#endif 11626#ifdef HAVE_SETRESGID 11627 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__}, 11628#endif 11629#ifdef HAVE_GETRESUID 11630 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__}, 11631#endif 11632#ifdef HAVE_GETRESGID 11633 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__}, 11634#endif 11635 11636#ifdef USE_XATTRS 11637 {"setxattr", (PyCFunction)posix_setxattr, 11638 METH_VARARGS | METH_KEYWORDS, 11639 posix_setxattr__doc__}, 11640 {"getxattr", (PyCFunction)posix_getxattr, 11641 METH_VARARGS | METH_KEYWORDS, 11642 posix_getxattr__doc__}, 11643 {"removexattr", (PyCFunction)posix_removexattr, 11644 METH_VARARGS | METH_KEYWORDS, 11645 posix_removexattr__doc__}, 11646 {"listxattr", (PyCFunction)posix_listxattr, 11647 METH_VARARGS | METH_KEYWORDS, 11648 posix_listxattr__doc__}, 11649#endif 11650#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) 11651 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__}, 11652#endif 11653 {"cpu_count", (PyCFunction)posix_cpu_count, 11654 METH_NOARGS, posix_cpu_count__doc__}, 11655 {"get_inheritable", posix_get_inheritable, METH_VARARGS, get_inheritable__doc__}, 11656 {"set_inheritable", posix_set_inheritable, METH_VARARGS, set_inheritable__doc__}, 11657#ifdef MS_WINDOWS 11658 {"get_handle_inheritable", posix_get_handle_inheritable, 11659 METH_VARARGS, get_handle_inheritable__doc__}, 11660 {"set_handle_inheritable", posix_set_handle_inheritable, 11661 METH_VARARGS, set_handle_inheritable__doc__}, 11662#endif 11663 {NULL, NULL} /* Sentinel */ 11664}; 11665 11666 11667#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS) 11668static int 11669enable_symlink() 11670{ 11671 HANDLE tok; 11672 TOKEN_PRIVILEGES tok_priv; 11673 LUID luid; 11674 int meth_idx = 0; 11675 11676 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok)) 11677 return 0; 11678 11679 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid)) 11680 return 0; 11681 11682 tok_priv.PrivilegeCount = 1; 11683 tok_priv.Privileges[0].Luid = luid; 11684 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 11685 11686 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv, 11687 sizeof(TOKEN_PRIVILEGES), 11688 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL)) 11689 return 0; 11690 11691 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */ 11692 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1; 11693} 11694#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */ 11695 11696static int 11697all_ins(PyObject *m) 11698{ 11699#ifdef F_OK 11700 if (PyModule_AddIntMacro(m, F_OK)) return -1; 11701#endif 11702#ifdef R_OK 11703 if (PyModule_AddIntMacro(m, R_OK)) return -1; 11704#endif 11705#ifdef W_OK 11706 if (PyModule_AddIntMacro(m, W_OK)) return -1; 11707#endif 11708#ifdef X_OK 11709 if (PyModule_AddIntMacro(m, X_OK)) return -1; 11710#endif 11711#ifdef NGROUPS_MAX 11712 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1; 11713#endif 11714#ifdef TMP_MAX 11715 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1; 11716#endif 11717#ifdef WCONTINUED 11718 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1; 11719#endif 11720#ifdef WNOHANG 11721 if (PyModule_AddIntMacro(m, WNOHANG)) return -1; 11722#endif 11723#ifdef WUNTRACED 11724 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1; 11725#endif 11726#ifdef O_RDONLY 11727 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1; 11728#endif 11729#ifdef O_WRONLY 11730 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1; 11731#endif 11732#ifdef O_RDWR 11733 if (PyModule_AddIntMacro(m, O_RDWR)) return -1; 11734#endif 11735#ifdef O_NDELAY 11736 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1; 11737#endif 11738#ifdef O_NONBLOCK 11739 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1; 11740#endif 11741#ifdef O_APPEND 11742 if (PyModule_AddIntMacro(m, O_APPEND)) return -1; 11743#endif 11744#ifdef O_DSYNC 11745 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1; 11746#endif 11747#ifdef O_RSYNC 11748 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1; 11749#endif 11750#ifdef O_SYNC 11751 if (PyModule_AddIntMacro(m, O_SYNC)) return -1; 11752#endif 11753#ifdef O_NOCTTY 11754 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1; 11755#endif 11756#ifdef O_CREAT 11757 if (PyModule_AddIntMacro(m, O_CREAT)) return -1; 11758#endif 11759#ifdef O_EXCL 11760 if (PyModule_AddIntMacro(m, O_EXCL)) return -1; 11761#endif 11762#ifdef O_TRUNC 11763 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1; 11764#endif 11765#ifdef O_BINARY 11766 if (PyModule_AddIntMacro(m, O_BINARY)) return -1; 11767#endif 11768#ifdef O_TEXT 11769 if (PyModule_AddIntMacro(m, O_TEXT)) return -1; 11770#endif 11771#ifdef O_XATTR 11772 if (PyModule_AddIntMacro(m, O_XATTR)) return -1; 11773#endif 11774#ifdef O_LARGEFILE 11775 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1; 11776#endif 11777#ifdef O_SHLOCK 11778 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1; 11779#endif 11780#ifdef O_EXLOCK 11781 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1; 11782#endif 11783#ifdef O_EXEC 11784 if (PyModule_AddIntMacro(m, O_EXEC)) return -1; 11785#endif 11786#ifdef O_SEARCH 11787 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1; 11788#endif 11789#ifdef O_PATH 11790 if (PyModule_AddIntMacro(m, O_PATH)) return -1; 11791#endif 11792#ifdef O_TTY_INIT 11793 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1; 11794#endif 11795#ifdef O_TMPFILE 11796 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1; 11797#endif 11798#ifdef PRIO_PROCESS 11799 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1; 11800#endif 11801#ifdef PRIO_PGRP 11802 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1; 11803#endif 11804#ifdef PRIO_USER 11805 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1; 11806#endif 11807#ifdef O_CLOEXEC 11808 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1; 11809#endif 11810#ifdef O_ACCMODE 11811 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1; 11812#endif 11813 11814 11815#ifdef SEEK_HOLE 11816 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1; 11817#endif 11818#ifdef SEEK_DATA 11819 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1; 11820#endif 11821 11822/* MS Windows */ 11823#ifdef O_NOINHERIT 11824 /* Don't inherit in child processes. */ 11825 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1; 11826#endif 11827#ifdef _O_SHORT_LIVED 11828 /* Optimize for short life (keep in memory). */ 11829 /* MS forgot to define this one with a non-underscore form too. */ 11830 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1; 11831#endif 11832#ifdef O_TEMPORARY 11833 /* Automatically delete when last handle is closed. */ 11834 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1; 11835#endif 11836#ifdef O_RANDOM 11837 /* Optimize for random access. */ 11838 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1; 11839#endif 11840#ifdef O_SEQUENTIAL 11841 /* Optimize for sequential access. */ 11842 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1; 11843#endif 11844 11845/* GNU extensions. */ 11846#ifdef O_ASYNC 11847 /* Send a SIGIO signal whenever input or output 11848 becomes available on file descriptor */ 11849 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1; 11850#endif 11851#ifdef O_DIRECT 11852 /* Direct disk access. */ 11853 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1; 11854#endif 11855#ifdef O_DIRECTORY 11856 /* Must be a directory. */ 11857 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1; 11858#endif 11859#ifdef O_NOFOLLOW 11860 /* Do not follow links. */ 11861 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1; 11862#endif 11863#ifdef O_NOLINKS 11864 /* Fails if link count of the named file is greater than 1 */ 11865 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1; 11866#endif 11867#ifdef O_NOATIME 11868 /* Do not update the access time. */ 11869 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1; 11870#endif 11871 11872 /* These come from sysexits.h */ 11873#ifdef EX_OK 11874 if (PyModule_AddIntMacro(m, EX_OK)) return -1; 11875#endif /* EX_OK */ 11876#ifdef EX_USAGE 11877 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1; 11878#endif /* EX_USAGE */ 11879#ifdef EX_DATAERR 11880 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1; 11881#endif /* EX_DATAERR */ 11882#ifdef EX_NOINPUT 11883 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1; 11884#endif /* EX_NOINPUT */ 11885#ifdef EX_NOUSER 11886 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1; 11887#endif /* EX_NOUSER */ 11888#ifdef EX_NOHOST 11889 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1; 11890#endif /* EX_NOHOST */ 11891#ifdef EX_UNAVAILABLE 11892 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1; 11893#endif /* EX_UNAVAILABLE */ 11894#ifdef EX_SOFTWARE 11895 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1; 11896#endif /* EX_SOFTWARE */ 11897#ifdef EX_OSERR 11898 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1; 11899#endif /* EX_OSERR */ 11900#ifdef EX_OSFILE 11901 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1; 11902#endif /* EX_OSFILE */ 11903#ifdef EX_CANTCREAT 11904 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1; 11905#endif /* EX_CANTCREAT */ 11906#ifdef EX_IOERR 11907 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1; 11908#endif /* EX_IOERR */ 11909#ifdef EX_TEMPFAIL 11910 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1; 11911#endif /* EX_TEMPFAIL */ 11912#ifdef EX_PROTOCOL 11913 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1; 11914#endif /* EX_PROTOCOL */ 11915#ifdef EX_NOPERM 11916 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1; 11917#endif /* EX_NOPERM */ 11918#ifdef EX_CONFIG 11919 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1; 11920#endif /* EX_CONFIG */ 11921#ifdef EX_NOTFOUND 11922 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1; 11923#endif /* EX_NOTFOUND */ 11924 11925 /* statvfs */ 11926#ifdef ST_RDONLY 11927 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1; 11928#endif /* ST_RDONLY */ 11929#ifdef ST_NOSUID 11930 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1; 11931#endif /* ST_NOSUID */ 11932 11933 /* GNU extensions */ 11934#ifdef ST_NODEV 11935 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1; 11936#endif /* ST_NODEV */ 11937#ifdef ST_NOEXEC 11938 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1; 11939#endif /* ST_NOEXEC */ 11940#ifdef ST_SYNCHRONOUS 11941 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1; 11942#endif /* ST_SYNCHRONOUS */ 11943#ifdef ST_MANDLOCK 11944 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1; 11945#endif /* ST_MANDLOCK */ 11946#ifdef ST_WRITE 11947 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1; 11948#endif /* ST_WRITE */ 11949#ifdef ST_APPEND 11950 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1; 11951#endif /* ST_APPEND */ 11952#ifdef ST_NOATIME 11953 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1; 11954#endif /* ST_NOATIME */ 11955#ifdef ST_NODIRATIME 11956 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1; 11957#endif /* ST_NODIRATIME */ 11958#ifdef ST_RELATIME 11959 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1; 11960#endif /* ST_RELATIME */ 11961 11962 /* FreeBSD sendfile() constants */ 11963#ifdef SF_NODISKIO 11964 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1; 11965#endif 11966#ifdef SF_MNOWAIT 11967 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1; 11968#endif 11969#ifdef SF_SYNC 11970 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1; 11971#endif 11972 11973 /* constants for posix_fadvise */ 11974#ifdef POSIX_FADV_NORMAL 11975 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1; 11976#endif 11977#ifdef POSIX_FADV_SEQUENTIAL 11978 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1; 11979#endif 11980#ifdef POSIX_FADV_RANDOM 11981 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1; 11982#endif 11983#ifdef POSIX_FADV_NOREUSE 11984 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1; 11985#endif 11986#ifdef POSIX_FADV_WILLNEED 11987 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1; 11988#endif 11989#ifdef POSIX_FADV_DONTNEED 11990 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1; 11991#endif 11992 11993 /* constants for waitid */ 11994#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID) 11995 if (PyModule_AddIntMacro(m, P_PID)) return -1; 11996 if (PyModule_AddIntMacro(m, P_PGID)) return -1; 11997 if (PyModule_AddIntMacro(m, P_ALL)) return -1; 11998#endif 11999#ifdef WEXITED 12000 if (PyModule_AddIntMacro(m, WEXITED)) return -1; 12001#endif 12002#ifdef WNOWAIT 12003 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1; 12004#endif 12005#ifdef WSTOPPED 12006 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1; 12007#endif 12008#ifdef CLD_EXITED 12009 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1; 12010#endif 12011#ifdef CLD_DUMPED 12012 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1; 12013#endif 12014#ifdef CLD_TRAPPED 12015 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1; 12016#endif 12017#ifdef CLD_CONTINUED 12018 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1; 12019#endif 12020 12021 /* constants for lockf */ 12022#ifdef F_LOCK 12023 if (PyModule_AddIntMacro(m, F_LOCK)) return -1; 12024#endif 12025#ifdef F_TLOCK 12026 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1; 12027#endif 12028#ifdef F_ULOCK 12029 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1; 12030#endif 12031#ifdef F_TEST 12032 if (PyModule_AddIntMacro(m, F_TEST)) return -1; 12033#endif 12034 12035#ifdef HAVE_SPAWNV 12036 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1; 12037 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1; 12038 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1; 12039 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1; 12040 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1; 12041#endif 12042 12043#ifdef HAVE_SCHED_H 12044 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1; 12045 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1; 12046 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1; 12047#ifdef SCHED_SPORADIC 12048 if (PyModule_AddIntMacro(m, SCHED_SPORADIC) return -1; 12049#endif 12050#ifdef SCHED_BATCH 12051 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1; 12052#endif 12053#ifdef SCHED_IDLE 12054 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1; 12055#endif 12056#ifdef SCHED_RESET_ON_FORK 12057 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1; 12058#endif 12059#ifdef SCHED_SYS 12060 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1; 12061#endif 12062#ifdef SCHED_IA 12063 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1; 12064#endif 12065#ifdef SCHED_FSS 12066 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1; 12067#endif 12068#ifdef SCHED_FX 12069 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1; 12070#endif 12071#endif 12072 12073#ifdef USE_XATTRS 12074 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1; 12075 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1; 12076 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1; 12077#endif 12078 12079#ifdef RTLD_LAZY 12080 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1; 12081#endif 12082#ifdef RTLD_NOW 12083 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1; 12084#endif 12085#ifdef RTLD_GLOBAL 12086 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1; 12087#endif 12088#ifdef RTLD_LOCAL 12089 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1; 12090#endif 12091#ifdef RTLD_NODELETE 12092 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1; 12093#endif 12094#ifdef RTLD_NOLOAD 12095 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1; 12096#endif 12097#ifdef RTLD_DEEPBIND 12098 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1; 12099#endif 12100 12101 return 0; 12102} 12103 12104 12105#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__) 12106#define INITFUNC PyInit_nt 12107#define MODNAME "nt" 12108 12109#else 12110#define INITFUNC PyInit_posix 12111#define MODNAME "posix" 12112#endif 12113 12114static struct PyModuleDef posixmodule = { 12115 PyModuleDef_HEAD_INIT, 12116 MODNAME, 12117 posix__doc__, 12118 -1, 12119 posix_methods, 12120 NULL, 12121 NULL, 12122 NULL, 12123 NULL 12124}; 12125 12126 12127static char *have_functions[] = { 12128 12129#ifdef HAVE_FACCESSAT 12130 "HAVE_FACCESSAT", 12131#endif 12132 12133#ifdef HAVE_FCHDIR 12134 "HAVE_FCHDIR", 12135#endif 12136 12137#ifdef HAVE_FCHMOD 12138 "HAVE_FCHMOD", 12139#endif 12140 12141#ifdef HAVE_FCHMODAT 12142 "HAVE_FCHMODAT", 12143#endif 12144 12145#ifdef HAVE_FCHOWN 12146 "HAVE_FCHOWN", 12147#endif 12148 12149#ifdef HAVE_FCHOWNAT 12150 "HAVE_FCHOWNAT", 12151#endif 12152 12153#ifdef HAVE_FEXECVE 12154 "HAVE_FEXECVE", 12155#endif 12156 12157#ifdef HAVE_FDOPENDIR 12158 "HAVE_FDOPENDIR", 12159#endif 12160 12161#ifdef HAVE_FPATHCONF 12162 "HAVE_FPATHCONF", 12163#endif 12164 12165#ifdef HAVE_FSTATAT 12166 "HAVE_FSTATAT", 12167#endif 12168 12169#ifdef HAVE_FSTATVFS 12170 "HAVE_FSTATVFS", 12171#endif 12172 12173#ifdef HAVE_FTRUNCATE 12174 "HAVE_FTRUNCATE", 12175#endif 12176 12177#ifdef HAVE_FUTIMENS 12178 "HAVE_FUTIMENS", 12179#endif 12180 12181#ifdef HAVE_FUTIMES 12182 "HAVE_FUTIMES", 12183#endif 12184 12185#ifdef HAVE_FUTIMESAT 12186 "HAVE_FUTIMESAT", 12187#endif 12188 12189#ifdef HAVE_LINKAT 12190 "HAVE_LINKAT", 12191#endif 12192 12193#ifdef HAVE_LCHFLAGS 12194 "HAVE_LCHFLAGS", 12195#endif 12196 12197#ifdef HAVE_LCHMOD 12198 "HAVE_LCHMOD", 12199#endif 12200 12201#ifdef HAVE_LCHOWN 12202 "HAVE_LCHOWN", 12203#endif 12204 12205#ifdef HAVE_LSTAT 12206 "HAVE_LSTAT", 12207#endif 12208 12209#ifdef HAVE_LUTIMES 12210 "HAVE_LUTIMES", 12211#endif 12212 12213#ifdef HAVE_MKDIRAT 12214 "HAVE_MKDIRAT", 12215#endif 12216 12217#ifdef HAVE_MKFIFOAT 12218 "HAVE_MKFIFOAT", 12219#endif 12220 12221#ifdef HAVE_MKNODAT 12222 "HAVE_MKNODAT", 12223#endif 12224 12225#ifdef HAVE_OPENAT 12226 "HAVE_OPENAT", 12227#endif 12228 12229#ifdef HAVE_READLINKAT 12230 "HAVE_READLINKAT", 12231#endif 12232 12233#ifdef HAVE_RENAMEAT 12234 "HAVE_RENAMEAT", 12235#endif 12236 12237#ifdef HAVE_SYMLINKAT 12238 "HAVE_SYMLINKAT", 12239#endif 12240 12241#ifdef HAVE_UNLINKAT 12242 "HAVE_UNLINKAT", 12243#endif 12244 12245#ifdef HAVE_UTIMENSAT 12246 "HAVE_UTIMENSAT", 12247#endif 12248 12249#ifdef MS_WINDOWS 12250 "MS_WINDOWS", 12251#endif 12252 12253 NULL 12254}; 12255 12256 12257PyMODINIT_FUNC 12258INITFUNC(void) 12259{ 12260 PyObject *m, *v; 12261 PyObject *list; 12262 char **trace; 12263 12264#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS) 12265 win32_can_symlink = enable_symlink(); 12266#endif 12267 12268 m = PyModule_Create(&posixmodule); 12269 if (m == NULL) 12270 return NULL; 12271 12272 /* Initialize environ dictionary */ 12273 v = convertenviron(); 12274 Py_XINCREF(v); 12275 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0) 12276 return NULL; 12277 Py_DECREF(v); 12278 12279 if (all_ins(m)) 12280 return NULL; 12281 12282 if (setup_confname_tables(m)) 12283 return NULL; 12284 12285 Py_INCREF(PyExc_OSError); 12286 PyModule_AddObject(m, "error", PyExc_OSError); 12287 12288#ifdef HAVE_PUTENV 12289 if (posix_putenv_garbage == NULL) 12290 posix_putenv_garbage = PyDict_New(); 12291#endif 12292 12293 if (!initialized) { 12294#if defined(HAVE_WAITID) && !defined(__APPLE__) 12295 waitid_result_desc.name = MODNAME ".waitid_result"; 12296 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0) 12297 return NULL; 12298#endif 12299 12300 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */ 12301 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField; 12302 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField; 12303 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField; 12304 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0) 12305 return NULL; 12306 structseq_new = StatResultType.tp_new; 12307 StatResultType.tp_new = statresult_new; 12308 12309 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */ 12310 if (PyStructSequence_InitType2(&StatVFSResultType, 12311 &statvfs_result_desc) < 0) 12312 return NULL; 12313#ifdef NEED_TICKS_PER_SECOND 12314# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK) 12315 ticks_per_second = sysconf(_SC_CLK_TCK); 12316# elif defined(HZ) 12317 ticks_per_second = HZ; 12318# else 12319 ticks_per_second = 60; /* magic fallback value; may be bogus */ 12320# endif 12321#endif 12322 12323#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) 12324 sched_param_desc.name = MODNAME ".sched_param"; 12325 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0) 12326 return NULL; 12327 SchedParamType.tp_new = sched_param_new; 12328#endif 12329 12330 /* initialize TerminalSize_info */ 12331 if (PyStructSequence_InitType2(&TerminalSizeType, 12332 &TerminalSize_desc) < 0) 12333 return NULL; 12334 } 12335#if defined(HAVE_WAITID) && !defined(__APPLE__) 12336 Py_INCREF((PyObject*) &WaitidResultType); 12337 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType); 12338#endif 12339 Py_INCREF((PyObject*) &StatResultType); 12340 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType); 12341 Py_INCREF((PyObject*) &StatVFSResultType); 12342 PyModule_AddObject(m, "statvfs_result", 12343 (PyObject*) &StatVFSResultType); 12344 12345#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) 12346 Py_INCREF(&SchedParamType); 12347 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType); 12348#endif 12349 12350 times_result_desc.name = MODNAME ".times_result"; 12351 if (PyStructSequence_InitType2(&TimesResultType, ×_result_desc) < 0) 12352 return NULL; 12353 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType); 12354 12355 uname_result_desc.name = MODNAME ".uname_result"; 12356 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0) 12357 return NULL; 12358 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType); 12359 12360#ifdef __APPLE__ 12361 /* 12362 * Step 2 of weak-linking support on Mac OS X. 12363 * 12364 * The code below removes functions that are not available on the 12365 * currently active platform. 12366 * 12367 * This block allow one to use a python binary that was build on 12368 * OSX 10.4 on OSX 10.3, without losing access to new APIs on 12369 * OSX 10.4. 12370 */ 12371#ifdef HAVE_FSTATVFS 12372 if (fstatvfs == NULL) { 12373 if (PyObject_DelAttrString(m, "fstatvfs") == -1) { 12374 return NULL; 12375 } 12376 } 12377#endif /* HAVE_FSTATVFS */ 12378 12379#ifdef HAVE_STATVFS 12380 if (statvfs == NULL) { 12381 if (PyObject_DelAttrString(m, "statvfs") == -1) { 12382 return NULL; 12383 } 12384 } 12385#endif /* HAVE_STATVFS */ 12386 12387# ifdef HAVE_LCHOWN 12388 if (lchown == NULL) { 12389 if (PyObject_DelAttrString(m, "lchown") == -1) { 12390 return NULL; 12391 } 12392 } 12393#endif /* HAVE_LCHOWN */ 12394 12395 12396#endif /* __APPLE__ */ 12397 12398 Py_INCREF(&TerminalSizeType); 12399 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType); 12400 12401 billion = PyLong_FromLong(1000000000); 12402 if (!billion) 12403 return NULL; 12404 12405 /* suppress "function not used" warnings */ 12406 { 12407 int ignored; 12408 fd_specified("", -1); 12409 follow_symlinks_specified("", 1); 12410 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1); 12411 dir_fd_converter(Py_None, &ignored); 12412 dir_fd_unavailable(Py_None, &ignored); 12413 } 12414 12415 /* 12416 * provide list of locally available functions 12417 * so os.py can populate support_* lists 12418 */ 12419 list = PyList_New(0); 12420 if (!list) 12421 return NULL; 12422 for (trace = have_functions; *trace; trace++) { 12423 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL); 12424 if (!unicode) 12425 return NULL; 12426 if (PyList_Append(list, unicode)) 12427 return NULL; 12428 Py_DECREF(unicode); 12429 } 12430 PyModule_AddObject(m, "_have_functions", list); 12431 12432 initialized = 1; 12433 12434 return m; 12435} 12436 12437#ifdef __cplusplus 12438} 12439#endif 12440