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