posixmodule.c revision c9c2c8b034ee9fb61ee8487545e9711ac2bbcf61
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/* See also ../Dos/dosmodule.c */ 15 16#ifdef __APPLE__ 17 /* 18 * Step 1 of support for weak-linking a number of symbols existing on 19 * OSX 10.4 and later, see the comment in the #ifdef __APPLE__ block 20 * at the end of this file for more information. 21 */ 22# pragma weak lchown 23# pragma weak statvfs 24# pragma weak fstatvfs 25 26#endif /* __APPLE__ */ 27 28#define PY_SSIZE_T_CLEAN 29 30#include "Python.h" 31 32#if defined(__VMS) 33# include <unixio.h> 34#endif /* defined(__VMS) */ 35 36#ifdef __cplusplus 37extern "C" { 38#endif 39 40PyDoc_STRVAR(posix__doc__, 41"This module provides access to operating system functionality that is\n\ 42standardized by the C Standard and the POSIX standard (a thinly\n\ 43disguised Unix interface). Refer to the library manual and\n\ 44corresponding Unix manual entries for more information on calls."); 45 46 47#if defined(PYOS_OS2) 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_TYPES_H 63#include <sys/types.h> 64#endif /* HAVE_SYS_TYPES_H */ 65 66#ifdef HAVE_SYS_STAT_H 67#include <sys/stat.h> 68#endif /* HAVE_SYS_STAT_H */ 69 70#ifdef HAVE_SYS_WAIT_H 71#include <sys/wait.h> /* For WNOHANG */ 72#endif 73 74#ifdef HAVE_SIGNAL_H 75#include <signal.h> 76#endif 77 78#ifdef HAVE_FCNTL_H 79#include <fcntl.h> 80#endif /* HAVE_FCNTL_H */ 81 82#ifdef HAVE_GRP_H 83#include <grp.h> 84#endif 85 86#ifdef HAVE_SYSEXITS_H 87#include <sysexits.h> 88#endif /* HAVE_SYSEXITS_H */ 89 90#ifdef HAVE_SYS_LOADAVG_H 91#include <sys/loadavg.h> 92#endif 93 94#ifdef HAVE_LANGINFO_H 95#include <langinfo.h> 96#endif 97 98#ifdef HAVE_SYS_SENDFILE_H 99#include <sys/sendfile.h> 100#endif 101 102#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__) 103#ifdef HAVE_SYS_SOCKET_H 104#include <sys/socket.h> 105#endif 106 107#ifdef HAVE_SYS_UIO_H 108#include <sys/uio.h> 109#endif 110#endif 111 112/* Various compilers have only certain posix functions */ 113/* XXX Gosh I wish these were all moved into pyconfig.h */ 114#if defined(PYCC_VACPP) && defined(PYOS_OS2) 115#include <process.h> 116#else 117#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */ 118#define HAVE_GETCWD 1 119#define HAVE_OPENDIR 1 120#define HAVE_SYSTEM 1 121#if defined(__OS2__) 122#define HAVE_EXECV 1 123#define HAVE_WAIT 1 124#endif 125#include <process.h> 126#else 127#ifdef __BORLANDC__ /* Borland compiler */ 128#define HAVE_EXECV 1 129#define HAVE_GETCWD 1 130#define HAVE_OPENDIR 1 131#define HAVE_PIPE 1 132#define HAVE_SYSTEM 1 133#define HAVE_WAIT 1 134#else 135#ifdef _MSC_VER /* Microsoft compiler */ 136#define HAVE_GETCWD 1 137#define HAVE_GETPPID 1 138#define HAVE_GETLOGIN 1 139#define HAVE_SPAWNV 1 140#define HAVE_EXECV 1 141#define HAVE_PIPE 1 142#define HAVE_SYSTEM 1 143#define HAVE_CWAIT 1 144#define HAVE_FSYNC 1 145#define fsync _commit 146#else 147#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS) 148/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */ 149#else /* all other compilers */ 150/* Unix functions that the configure script doesn't check for */ 151#define HAVE_EXECV 1 152#define HAVE_FORK 1 153#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */ 154#define HAVE_FORK1 1 155#endif 156#define HAVE_GETCWD 1 157#define HAVE_GETEGID 1 158#define HAVE_GETEUID 1 159#define HAVE_GETGID 1 160#define HAVE_GETPPID 1 161#define HAVE_GETUID 1 162#define HAVE_KILL 1 163#define HAVE_OPENDIR 1 164#define HAVE_PIPE 1 165#define HAVE_SYSTEM 1 166#define HAVE_WAIT 1 167#define HAVE_TTYNAME 1 168#endif /* PYOS_OS2 && PYCC_GCC && __VMS */ 169#endif /* _MSC_VER */ 170#endif /* __BORLANDC__ */ 171#endif /* ! __WATCOMC__ || __QNX__ */ 172#endif /* ! __IBMC__ */ 173 174#ifndef _MSC_VER 175 176#if defined(__sgi)&&_COMPILER_VERSION>=700 177/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode 178 (default) */ 179extern char *ctermid_r(char *); 180#endif 181 182#ifndef HAVE_UNISTD_H 183#if defined(PYCC_VACPP) 184extern int mkdir(char *); 185#else 186#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__) 187extern int mkdir(const char *); 188#else 189extern int mkdir(const char *, mode_t); 190#endif 191#endif 192#if defined(__IBMC__) || defined(__IBMCPP__) 193extern int chdir(char *); 194extern int rmdir(char *); 195#else 196extern int chdir(const char *); 197extern int rmdir(const char *); 198#endif 199#ifdef __BORLANDC__ 200extern int chmod(const char *, int); 201#else 202extern int chmod(const char *, mode_t); 203#endif 204/*#ifdef HAVE_FCHMOD 205extern int fchmod(int, mode_t); 206#endif*/ 207/*#ifdef HAVE_LCHMOD 208extern int lchmod(const char *, mode_t); 209#endif*/ 210extern int chown(const char *, uid_t, gid_t); 211extern char *getcwd(char *, int); 212extern char *strerror(int); 213extern int link(const char *, const char *); 214extern int rename(const char *, const char *); 215extern int stat(const char *, struct stat *); 216extern int unlink(const char *); 217#ifdef HAVE_SYMLINK 218extern int symlink(const char *, const char *); 219#endif /* HAVE_SYMLINK */ 220#ifdef HAVE_LSTAT 221extern int lstat(const char *, struct stat *); 222#endif /* HAVE_LSTAT */ 223#endif /* !HAVE_UNISTD_H */ 224 225#endif /* !_MSC_VER */ 226 227#ifdef HAVE_UTIME_H 228#include <utime.h> 229#endif /* HAVE_UTIME_H */ 230 231#ifdef HAVE_SYS_UTIME_H 232#include <sys/utime.h> 233#define HAVE_UTIME_H /* pretend we do for the rest of this file */ 234#endif /* HAVE_SYS_UTIME_H */ 235 236#ifdef HAVE_SYS_TIMES_H 237#include <sys/times.h> 238#endif /* HAVE_SYS_TIMES_H */ 239 240#ifdef HAVE_SYS_PARAM_H 241#include <sys/param.h> 242#endif /* HAVE_SYS_PARAM_H */ 243 244#ifdef HAVE_SYS_UTSNAME_H 245#include <sys/utsname.h> 246#endif /* HAVE_SYS_UTSNAME_H */ 247 248#ifdef HAVE_DIRENT_H 249#include <dirent.h> 250#define NAMLEN(dirent) strlen((dirent)->d_name) 251#else 252#if defined(__WATCOMC__) && !defined(__QNX__) 253#include <direct.h> 254#define NAMLEN(dirent) strlen((dirent)->d_name) 255#else 256#define dirent direct 257#define NAMLEN(dirent) (dirent)->d_namlen 258#endif 259#ifdef HAVE_SYS_NDIR_H 260#include <sys/ndir.h> 261#endif 262#ifdef HAVE_SYS_DIR_H 263#include <sys/dir.h> 264#endif 265#ifdef HAVE_NDIR_H 266#include <ndir.h> 267#endif 268#endif 269 270#ifdef _MSC_VER 271#ifdef HAVE_DIRECT_H 272#include <direct.h> 273#endif 274#ifdef HAVE_IO_H 275#include <io.h> 276#endif 277#ifdef HAVE_PROCESS_H 278#include <process.h> 279#endif 280#ifndef VOLUME_NAME_DOS 281#define VOLUME_NAME_DOS 0x0 282#endif 283#ifndef VOLUME_NAME_NT 284#define VOLUME_NAME_NT 0x2 285#endif 286#ifndef IO_REPARSE_TAG_SYMLINK 287#define IO_REPARSE_TAG_SYMLINK (0xA000000CL) 288#endif 289#include "osdefs.h" 290#include <malloc.h> 291#include <windows.h> 292#include <shellapi.h> /* for ShellExecute() */ 293#include <lmcons.h> /* for UNLEN */ 294#ifdef SE_CREATE_SYMBOLIC_LINK_NAME /* Available starting with Vista */ 295#define HAVE_SYMLINK 296static int win32_can_symlink = 0; 297#endif 298#endif /* _MSC_VER */ 299 300#if defined(PYCC_VACPP) && defined(PYOS_OS2) 301#include <io.h> 302#endif /* OS2 */ 303 304#ifndef MAXPATHLEN 305#if defined(PATH_MAX) && PATH_MAX > 1024 306#define MAXPATHLEN PATH_MAX 307#else 308#define MAXPATHLEN 1024 309#endif 310#endif /* MAXPATHLEN */ 311 312#ifdef UNION_WAIT 313/* Emulate some macros on systems that have a union instead of macros */ 314 315#ifndef WIFEXITED 316#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump) 317#endif 318 319#ifndef WEXITSTATUS 320#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1) 321#endif 322 323#ifndef WTERMSIG 324#define WTERMSIG(u_wait) ((u_wait).w_termsig) 325#endif 326 327#define WAIT_TYPE union wait 328#define WAIT_STATUS_INT(s) (s.w_status) 329 330#else /* !UNION_WAIT */ 331#define WAIT_TYPE int 332#define WAIT_STATUS_INT(s) (s) 333#endif /* UNION_WAIT */ 334 335/* Don't use the "_r" form if we don't need it (also, won't have a 336 prototype for it, at least on Solaris -- maybe others as well?). */ 337#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD) 338#define USE_CTERMID_R 339#endif 340 341/* choose the appropriate stat and fstat functions and return structs */ 342#undef STAT 343#undef FSTAT 344#undef STRUCT_STAT 345#if defined(MS_WIN64) || defined(MS_WINDOWS) 346# define STAT win32_stat 347# define FSTAT win32_fstat 348# define STRUCT_STAT struct win32_stat 349#else 350# define STAT stat 351# define FSTAT fstat 352# define STRUCT_STAT struct stat 353#endif 354 355#if defined(MAJOR_IN_MKDEV) 356#include <sys/mkdev.h> 357#else 358#if defined(MAJOR_IN_SYSMACROS) 359#include <sys/sysmacros.h> 360#endif 361#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H) 362#include <sys/mkdev.h> 363#endif 364#endif 365 366int 367PyParse_off_t(PyObject* arg, void* addr) 368{ 369#if !defined(HAVE_LARGEFILE_SUPPORT) 370 *((off_t*)addr) = PyLong_AsLong(arg); 371#else 372 *((off_t*)addr) = PyLong_Check(arg) ? PyLong_AsLongLong(arg) 373 : PyLong_AsLong(arg); 374#endif 375 if (PyErr_Occurred()) 376 return 0; 377 return 1; 378} 379 380#if defined _MSC_VER && _MSC_VER >= 1400 381/* Microsoft CRT in VS2005 and higher will verify that a filehandle is 382 * valid and throw an assertion if it isn't. 383 * Normally, an invalid fd is likely to be a C program error and therefore 384 * an assertion can be useful, but it does contradict the POSIX standard 385 * which for write(2) states: 386 * "Otherwise, -1 shall be returned and errno set to indicate the error." 387 * "[EBADF] The fildes argument is not a valid file descriptor open for 388 * writing." 389 * Furthermore, python allows the user to enter any old integer 390 * as a fd and should merely raise a python exception on error. 391 * The Microsoft CRT doesn't provide an official way to check for the 392 * validity of a file descriptor, but we can emulate its internal behaviour 393 * by using the exported __pinfo data member and knowledge of the 394 * internal structures involved. 395 * The structures below must be updated for each version of visual studio 396 * according to the file internal.h in the CRT source, until MS comes 397 * up with a less hacky way to do this. 398 * (all of this is to avoid globally modifying the CRT behaviour using 399 * _set_invalid_parameter_handler() and _CrtSetReportMode()) 400 */ 401/* The actual size of the structure is determined at runtime. 402 * Only the first items must be present. 403 */ 404typedef struct { 405 intptr_t osfhnd; 406 char osfile; 407} my_ioinfo; 408 409extern __declspec(dllimport) char * __pioinfo[]; 410#define IOINFO_L2E 5 411#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E) 412#define IOINFO_ARRAYS 64 413#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS) 414#define FOPEN 0x01 415#define _NO_CONSOLE_FILENO (intptr_t)-2 416 417/* This function emulates what the windows CRT does to validate file handles */ 418int 419_PyVerify_fd(int fd) 420{ 421 const int i1 = fd >> IOINFO_L2E; 422 const int i2 = fd & ((1 << IOINFO_L2E) - 1); 423 424 static size_t sizeof_ioinfo = 0; 425 426 /* Determine the actual size of the ioinfo structure, 427 * as used by the CRT loaded in memory 428 */ 429 if (sizeof_ioinfo == 0 && __pioinfo[0] != NULL) { 430 sizeof_ioinfo = _msize(__pioinfo[0]) / IOINFO_ARRAY_ELTS; 431 } 432 if (sizeof_ioinfo == 0) { 433 /* This should not happen... */ 434 goto fail; 435 } 436 437 /* See that it isn't a special CLEAR fileno */ 438 if (fd != _NO_CONSOLE_FILENO) { 439 /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that. Instead 440 * we check pointer validity and other info 441 */ 442 if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) { 443 /* finally, check that the file is open */ 444 my_ioinfo* info = (my_ioinfo*)(__pioinfo[i1] + i2 * sizeof_ioinfo); 445 if (info->osfile & FOPEN) { 446 return 1; 447 } 448 } 449 } 450 fail: 451 errno = EBADF; 452 return 0; 453} 454 455/* the special case of checking dup2. The target fd must be in a sensible range */ 456static int 457_PyVerify_fd_dup2(int fd1, int fd2) 458{ 459 if (!_PyVerify_fd(fd1)) 460 return 0; 461 if (fd2 == _NO_CONSOLE_FILENO) 462 return 0; 463 if ((unsigned)fd2 < _NHANDLE_) 464 return 1; 465 else 466 return 0; 467} 468#else 469/* dummy version. _PyVerify_fd() is already defined in fileobject.h */ 470#define _PyVerify_fd_dup2(A, B) (1) 471#endif 472 473#ifdef MS_WINDOWS 474/* The following structure was copied from 475 http://msdn.microsoft.com/en-us/library/ms791514.aspx as the required 476 include doesn't seem to be present in the Windows SDK (at least as included 477 with Visual Studio Express). */ 478typedef struct _REPARSE_DATA_BUFFER { 479 ULONG ReparseTag; 480 USHORT ReparseDataLength; 481 USHORT Reserved; 482 union { 483 struct { 484 USHORT SubstituteNameOffset; 485 USHORT SubstituteNameLength; 486 USHORT PrintNameOffset; 487 USHORT PrintNameLength; 488 ULONG Flags; 489 WCHAR PathBuffer[1]; 490 } SymbolicLinkReparseBuffer; 491 492 struct { 493 USHORT SubstituteNameOffset; 494 USHORT SubstituteNameLength; 495 USHORT PrintNameOffset; 496 USHORT PrintNameLength; 497 WCHAR PathBuffer[1]; 498 } MountPointReparseBuffer; 499 500 struct { 501 UCHAR DataBuffer[1]; 502 } GenericReparseBuffer; 503 }; 504} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER; 505 506#define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER,\ 507 GenericReparseBuffer) 508#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 ) 509 510static int 511win32_read_link(HANDLE reparse_point_handle, ULONG *reparse_tag, wchar_t **target_path) 512{ 513 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; 514 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer; 515 DWORD n_bytes_returned; 516 const wchar_t *ptr; 517 wchar_t *buf; 518 size_t len; 519 520 if (0 == DeviceIoControl( 521 reparse_point_handle, 522 FSCTL_GET_REPARSE_POINT, 523 NULL, 0, /* in buffer */ 524 target_buffer, sizeof(target_buffer), 525 &n_bytes_returned, 526 NULL)) /* we're not using OVERLAPPED_IO */ 527 return -1; 528 529 if (reparse_tag) 530 *reparse_tag = rdb->ReparseTag; 531 532 if (target_path) { 533 switch (rdb->ReparseTag) { 534 case IO_REPARSE_TAG_SYMLINK: 535 /* XXX: Maybe should use SubstituteName? */ 536 ptr = rdb->SymbolicLinkReparseBuffer.PathBuffer + 537 rdb->SymbolicLinkReparseBuffer.PrintNameOffset/sizeof(WCHAR); 538 len = rdb->SymbolicLinkReparseBuffer.PrintNameLength/sizeof(WCHAR); 539 break; 540 case IO_REPARSE_TAG_MOUNT_POINT: 541 ptr = rdb->MountPointReparseBuffer.PathBuffer + 542 rdb->MountPointReparseBuffer.SubstituteNameOffset/sizeof(WCHAR); 543 len = rdb->MountPointReparseBuffer.SubstituteNameLength/sizeof(WCHAR); 544 break; 545 default: 546 SetLastError(ERROR_REPARSE_TAG_MISMATCH); /* XXX: Proper error code? */ 547 return -1; 548 } 549 buf = (wchar_t *)malloc(sizeof(wchar_t)*(len+1)); 550 if (!buf) { 551 SetLastError(ERROR_OUTOFMEMORY); 552 return -1; 553 } 554 wcsncpy(buf, ptr, len); 555 buf[len] = L'\0'; 556 if (wcsncmp(buf, L"\\??\\", 4) == 0) 557 buf[1] = L'\\'; 558 *target_path = buf; 559 } 560 561 return 0; 562} 563#endif /* MS_WINDOWS */ 564 565/* Return a dictionary corresponding to the POSIX environment table */ 566#ifdef WITH_NEXT_FRAMEWORK 567/* On Darwin/MacOSX a shared library or framework has no access to 568** environ directly, we must obtain it with _NSGetEnviron(). 569*/ 570#include <crt_externs.h> 571static char **environ; 572#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) ) 573extern char **environ; 574#endif /* !_MSC_VER */ 575 576static PyObject * 577convertenviron(void) 578{ 579 PyObject *d; 580#ifdef MS_WINDOWS 581 wchar_t **e; 582#else 583 char **e; 584#endif 585#if defined(PYOS_OS2) 586 APIRET rc; 587 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */ 588#endif 589 590 d = PyDict_New(); 591 if (d == NULL) 592 return NULL; 593#ifdef WITH_NEXT_FRAMEWORK 594 if (environ == NULL) 595 environ = *_NSGetEnviron(); 596#endif 597#ifdef MS_WINDOWS 598 /* _wenviron must be initialized in this way if the program is started 599 through main() instead of wmain(). */ 600 _wgetenv(L""); 601 if (_wenviron == NULL) 602 return d; 603 /* This part ignores errors */ 604 for (e = _wenviron; *e != NULL; e++) { 605 PyObject *k; 606 PyObject *v; 607 wchar_t *p = wcschr(*e, L'='); 608 if (p == NULL) 609 continue; 610 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e)); 611 if (k == NULL) { 612 PyErr_Clear(); 613 continue; 614 } 615 v = PyUnicode_FromWideChar(p+1, wcslen(p+1)); 616 if (v == NULL) { 617 PyErr_Clear(); 618 Py_DECREF(k); 619 continue; 620 } 621 if (PyDict_GetItem(d, k) == NULL) { 622 if (PyDict_SetItem(d, k, v) != 0) 623 PyErr_Clear(); 624 } 625 Py_DECREF(k); 626 Py_DECREF(v); 627 } 628#else 629 if (environ == NULL) 630 return d; 631 /* This part ignores errors */ 632 for (e = environ; *e != NULL; e++) { 633 PyObject *k; 634 PyObject *v; 635 char *p = strchr(*e, '='); 636 if (p == NULL) 637 continue; 638 k = PyBytes_FromStringAndSize(*e, (int)(p-*e)); 639 if (k == NULL) { 640 PyErr_Clear(); 641 continue; 642 } 643 v = PyBytes_FromStringAndSize(p+1, strlen(p+1)); 644 if (v == NULL) { 645 PyErr_Clear(); 646 Py_DECREF(k); 647 continue; 648 } 649 if (PyDict_GetItem(d, k) == NULL) { 650 if (PyDict_SetItem(d, k, v) != 0) 651 PyErr_Clear(); 652 } 653 Py_DECREF(k); 654 Py_DECREF(v); 655 } 656#endif 657#if defined(PYOS_OS2) 658 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH); 659 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */ 660 PyObject *v = PyBytes_FromString(buffer); 661 PyDict_SetItemString(d, "BEGINLIBPATH", v); 662 Py_DECREF(v); 663 } 664 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH); 665 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */ 666 PyObject *v = PyBytes_FromString(buffer); 667 PyDict_SetItemString(d, "ENDLIBPATH", v); 668 Py_DECREF(v); 669 } 670#endif 671 return d; 672} 673 674/* Set a POSIX-specific error from errno, and return NULL */ 675 676static PyObject * 677posix_error(void) 678{ 679 return PyErr_SetFromErrno(PyExc_OSError); 680} 681static PyObject * 682posix_error_with_filename(char* name) 683{ 684 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name); 685} 686 687 688static PyObject * 689posix_error_with_allocated_filename(PyObject* name) 690{ 691 PyObject *name_str, *rc; 692 name_str = PyUnicode_DecodeFSDefaultAndSize(PyBytes_AsString(name), 693 PyBytes_GET_SIZE(name)); 694 Py_DECREF(name); 695 rc = PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, 696 name_str); 697 Py_XDECREF(name_str); 698 return rc; 699} 700 701#ifdef MS_WINDOWS 702static PyObject * 703win32_error(char* function, const char* filename) 704{ 705 /* XXX We should pass the function name along in the future. 706 (winreg.c also wants to pass the function name.) 707 This would however require an additional param to the 708 Windows error object, which is non-trivial. 709 */ 710 errno = GetLastError(); 711 if (filename) 712 return PyErr_SetFromWindowsErrWithFilename(errno, filename); 713 else 714 return PyErr_SetFromWindowsErr(errno); 715} 716 717static PyObject * 718win32_error_unicode(char* function, Py_UNICODE* filename) 719{ 720 /* XXX - see win32_error for comments on 'function' */ 721 errno = GetLastError(); 722 if (filename) 723 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, 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_FromUnicode(PyUnicode_AS_UNICODE(*param), 737 PyUnicode_GET_SIZE(*param)); 738 else 739 *param = PyUnicode_FromEncodedObject(*param, 740 Py_FileSystemDefaultEncoding, 741 "strict"); 742 return (*param) != NULL; 743} 744 745#endif /* MS_WINDOWS */ 746 747#if defined(PYOS_OS2) 748/********************************************************************** 749 * Helper Function to Trim and Format OS/2 Messages 750 **********************************************************************/ 751static void 752os2_formatmsg(char *msgbuf, int msglen, char *reason) 753{ 754 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */ 755 756 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */ 757 char *lastc = &msgbuf[ strlen(msgbuf)-1 ]; 758 759 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc))) 760 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */ 761 } 762 763 /* Add Optional Reason Text */ 764 if (reason) { 765 strcat(msgbuf, " : "); 766 strcat(msgbuf, reason); 767 } 768} 769 770/********************************************************************** 771 * Decode an OS/2 Operating System Error Code 772 * 773 * A convenience function to lookup an OS/2 error code and return a 774 * text message we can use to raise a Python exception. 775 * 776 * Notes: 777 * The messages for errors returned from the OS/2 kernel reside in 778 * the file OSO001.MSG in the \OS2 directory hierarchy. 779 * 780 **********************************************************************/ 781static char * 782os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason) 783{ 784 APIRET rc; 785 ULONG msglen; 786 787 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */ 788 Py_BEGIN_ALLOW_THREADS 789 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen, 790 errorcode, "oso001.msg", &msglen); 791 Py_END_ALLOW_THREADS 792 793 if (rc == NO_ERROR) 794 os2_formatmsg(msgbuf, msglen, reason); 795 else 796 PyOS_snprintf(msgbuf, msgbuflen, 797 "unknown OS error #%d", errorcode); 798 799 return msgbuf; 800} 801 802/* Set an OS/2-specific error and return NULL. OS/2 kernel 803 errors are not in a global variable e.g. 'errno' nor are 804 they congruent with posix error numbers. */ 805 806static PyObject * 807os2_error(int code) 808{ 809 char text[1024]; 810 PyObject *v; 811 812 os2_strerror(text, sizeof(text), code, ""); 813 814 v = Py_BuildValue("(is)", code, text); 815 if (v != NULL) { 816 PyErr_SetObject(PyExc_OSError, v); 817 Py_DECREF(v); 818 } 819 return NULL; /* Signal to Python that an Exception is Pending */ 820} 821 822#endif /* OS2 */ 823 824/* POSIX generic methods */ 825 826static PyObject * 827posix_fildes(PyObject *fdobj, int (*func)(int)) 828{ 829 int fd; 830 int res; 831 fd = PyObject_AsFileDescriptor(fdobj); 832 if (fd < 0) 833 return NULL; 834 if (!_PyVerify_fd(fd)) 835 return posix_error(); 836 Py_BEGIN_ALLOW_THREADS 837 res = (*func)(fd); 838 Py_END_ALLOW_THREADS 839 if (res < 0) 840 return posix_error(); 841 Py_INCREF(Py_None); 842 return Py_None; 843} 844 845static PyObject * 846posix_1str(PyObject *args, char *format, int (*func)(const char*)) 847{ 848 PyObject *opath1 = NULL; 849 char *path1; 850 int res; 851 if (!PyArg_ParseTuple(args, format, 852 PyUnicode_FSConverter, &opath1)) 853 return NULL; 854 path1 = PyBytes_AsString(opath1); 855 Py_BEGIN_ALLOW_THREADS 856 res = (*func)(path1); 857 Py_END_ALLOW_THREADS 858 if (res < 0) 859 return posix_error_with_allocated_filename(opath1); 860 Py_DECREF(opath1); 861 Py_INCREF(Py_None); 862 return Py_None; 863} 864 865static PyObject * 866posix_2str(PyObject *args, 867 char *format, 868 int (*func)(const char *, const char *)) 869{ 870 PyObject *opath1 = NULL, *opath2 = NULL; 871 char *path1, *path2; 872 int res; 873 if (!PyArg_ParseTuple(args, format, 874 PyUnicode_FSConverter, &opath1, 875 PyUnicode_FSConverter, &opath2)) { 876 return NULL; 877 } 878 path1 = PyBytes_AsString(opath1); 879 path2 = PyBytes_AsString(opath2); 880 Py_BEGIN_ALLOW_THREADS 881 res = (*func)(path1, path2); 882 Py_END_ALLOW_THREADS 883 Py_DECREF(opath1); 884 Py_DECREF(opath2); 885 if (res != 0) 886 /* XXX how to report both path1 and path2??? */ 887 return posix_error(); 888 Py_INCREF(Py_None); 889 return Py_None; 890} 891 892#ifdef MS_WINDOWS 893static PyObject* 894win32_1str(PyObject* args, char* func, 895 char* format, BOOL (__stdcall *funcA)(LPCSTR), 896 char* wformat, BOOL (__stdcall *funcW)(LPWSTR)) 897{ 898 PyObject *uni; 899 char *ansi; 900 BOOL result; 901 902 if (!PyArg_ParseTuple(args, wformat, &uni)) 903 PyErr_Clear(); 904 else { 905 Py_BEGIN_ALLOW_THREADS 906 result = funcW(PyUnicode_AsUnicode(uni)); 907 Py_END_ALLOW_THREADS 908 if (!result) 909 return win32_error_unicode(func, PyUnicode_AsUnicode(uni)); 910 Py_INCREF(Py_None); 911 return Py_None; 912 } 913 if (!PyArg_ParseTuple(args, format, &ansi)) 914 return NULL; 915 Py_BEGIN_ALLOW_THREADS 916 result = funcA(ansi); 917 Py_END_ALLOW_THREADS 918 if (!result) 919 return win32_error(func, ansi); 920 Py_INCREF(Py_None); 921 return Py_None; 922 923} 924 925/* This is a reimplementation of the C library's chdir function, 926 but one that produces Win32 errors instead of DOS error codes. 927 chdir is essentially a wrapper around SetCurrentDirectory; however, 928 it also needs to set "magic" environment variables indicating 929 the per-drive current directory, which are of the form =<drive>: */ 930static BOOL __stdcall 931win32_chdir(LPCSTR path) 932{ 933 char new_path[MAX_PATH+1]; 934 int result; 935 char env[4] = "=x:"; 936 937 if(!SetCurrentDirectoryA(path)) 938 return FALSE; 939 result = GetCurrentDirectoryA(MAX_PATH+1, new_path); 940 if (!result) 941 return FALSE; 942 /* In the ANSI API, there should not be any paths longer 943 than MAX_PATH. */ 944 assert(result <= MAX_PATH+1); 945 if (strncmp(new_path, "\\\\", 2) == 0 || 946 strncmp(new_path, "//", 2) == 0) 947 /* UNC path, nothing to do. */ 948 return TRUE; 949 env[1] = new_path[0]; 950 return SetEnvironmentVariableA(env, new_path); 951} 952 953/* The Unicode version differs from the ANSI version 954 since the current directory might exceed MAX_PATH characters */ 955static BOOL __stdcall 956win32_wchdir(LPCWSTR path) 957{ 958 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path; 959 int result; 960 wchar_t env[4] = L"=x:"; 961 962 if(!SetCurrentDirectoryW(path)) 963 return FALSE; 964 result = GetCurrentDirectoryW(MAX_PATH+1, new_path); 965 if (!result) 966 return FALSE; 967 if (result > MAX_PATH+1) { 968 new_path = malloc(result * sizeof(wchar_t)); 969 if (!new_path) { 970 SetLastError(ERROR_OUTOFMEMORY); 971 return FALSE; 972 } 973 result = GetCurrentDirectoryW(result, new_path); 974 if (!result) { 975 free(new_path); 976 return FALSE; 977 } 978 } 979 if (wcsncmp(new_path, L"\\\\", 2) == 0 || 980 wcsncmp(new_path, L"//", 2) == 0) 981 /* UNC path, nothing to do. */ 982 return TRUE; 983 env[1] = new_path[0]; 984 result = SetEnvironmentVariableW(env, new_path); 985 if (new_path != _new_path) 986 free(new_path); 987 return result; 988} 989#endif 990 991#ifdef MS_WINDOWS 992/* The CRT of Windows has a number of flaws wrt. its stat() implementation: 993 - time stamps are restricted to second resolution 994 - file modification times suffer from forth-and-back conversions between 995 UTC and local time 996 Therefore, we implement our own stat, based on the Win32 API directly. 997*/ 998#define HAVE_STAT_NSEC 1 999 1000struct win32_stat{ 1001 int st_dev; 1002 __int64 st_ino; 1003 unsigned short st_mode; 1004 int st_nlink; 1005 int st_uid; 1006 int st_gid; 1007 int st_rdev; 1008 __int64 st_size; 1009 time_t st_atime; 1010 int st_atime_nsec; 1011 time_t st_mtime; 1012 int st_mtime_nsec; 1013 time_t st_ctime; 1014 int st_ctime_nsec; 1015}; 1016 1017static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */ 1018 1019static void 1020FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, time_t *time_out, int* nsec_out) 1021{ 1022 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */ 1023 /* Cannot simply cast and dereference in_ptr, 1024 since it might not be aligned properly */ 1025 __int64 in; 1026 memcpy(&in, in_ptr, sizeof(in)); 1027 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */ 1028 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, time_t); 1029} 1030 1031static void 1032time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr) 1033{ 1034 /* XXX endianness */ 1035 __int64 out; 1036 out = time_in + secs_between_epochs; 1037 out = out * 10000000 + nsec_in / 100; 1038 memcpy(out_ptr, &out, sizeof(out)); 1039} 1040 1041/* Below, we *know* that ugo+r is 0444 */ 1042#if _S_IREAD != 0400 1043#error Unsupported C library 1044#endif 1045static int 1046attributes_to_mode(DWORD attr) 1047{ 1048 int m = 0; 1049 if (attr & FILE_ATTRIBUTE_DIRECTORY) 1050 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */ 1051 else 1052 m |= _S_IFREG; 1053 if (attr & FILE_ATTRIBUTE_READONLY) 1054 m |= 0444; 1055 else 1056 m |= 0666; 1057 return m; 1058} 1059 1060static int 1061attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag, struct win32_stat *result) 1062{ 1063 memset(result, 0, sizeof(*result)); 1064 result->st_mode = attributes_to_mode(info->dwFileAttributes); 1065 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow; 1066 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec); 1067 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec); 1068 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec); 1069 result->st_nlink = info->nNumberOfLinks; 1070 result->st_ino = (((__int64)info->nFileIndexHigh)<<32) + info->nFileIndexLow; 1071 if (reparse_tag == IO_REPARSE_TAG_SYMLINK) { 1072 /* first clear the S_IFMT bits */ 1073 result->st_mode ^= (result->st_mode & 0170000); 1074 /* now set the bits that make this a symlink */ 1075 result->st_mode |= 0120000; 1076 } 1077 1078 return 0; 1079} 1080 1081static BOOL 1082attributes_from_dir(LPCSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag) 1083{ 1084 HANDLE hFindFile; 1085 WIN32_FIND_DATAA FileData; 1086 hFindFile = FindFirstFileA(pszFile, &FileData); 1087 if (hFindFile == INVALID_HANDLE_VALUE) 1088 return FALSE; 1089 FindClose(hFindFile); 1090 memset(info, 0, sizeof(*info)); 1091 *reparse_tag = 0; 1092 info->dwFileAttributes = FileData.dwFileAttributes; 1093 info->ftCreationTime = FileData.ftCreationTime; 1094 info->ftLastAccessTime = FileData.ftLastAccessTime; 1095 info->ftLastWriteTime = FileData.ftLastWriteTime; 1096 info->nFileSizeHigh = FileData.nFileSizeHigh; 1097 info->nFileSizeLow = FileData.nFileSizeLow; 1098/* info->nNumberOfLinks = 1; */ 1099 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) 1100 *reparse_tag = FileData.dwReserved0; 1101 return TRUE; 1102} 1103 1104static BOOL 1105attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag) 1106{ 1107 HANDLE hFindFile; 1108 WIN32_FIND_DATAW FileData; 1109 hFindFile = FindFirstFileW(pszFile, &FileData); 1110 if (hFindFile == INVALID_HANDLE_VALUE) 1111 return FALSE; 1112 FindClose(hFindFile); 1113 memset(info, 0, sizeof(*info)); 1114 *reparse_tag = 0; 1115 info->dwFileAttributes = FileData.dwFileAttributes; 1116 info->ftCreationTime = FileData.ftCreationTime; 1117 info->ftLastAccessTime = FileData.ftLastAccessTime; 1118 info->ftLastWriteTime = FileData.ftLastWriteTime; 1119 info->nFileSizeHigh = FileData.nFileSizeHigh; 1120 info->nFileSizeLow = FileData.nFileSizeLow; 1121/* info->nNumberOfLinks = 1; */ 1122 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) 1123 *reparse_tag = FileData.dwReserved0; 1124 return TRUE; 1125} 1126 1127#ifndef SYMLOOP_MAX 1128#define SYMLOOP_MAX ( 88 ) 1129#endif 1130 1131static int 1132win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result, BOOL traverse, int depth); 1133 1134static int 1135win32_xstat_impl(const char *path, struct win32_stat *result, BOOL traverse, int depth) 1136{ 1137 int code; 1138 HANDLE hFile; 1139 BY_HANDLE_FILE_INFORMATION info; 1140 ULONG reparse_tag = 0; 1141 wchar_t *target_path; 1142 const char *dot; 1143 1144 if (depth > SYMLOOP_MAX) { 1145 SetLastError(ERROR_CANT_RESOLVE_FILENAME); /* XXX: ELOOP? */ 1146 return -1; 1147 } 1148 1149 hFile = CreateFileA( 1150 path, 1151 0, /* desired access */ 1152 0, /* share mode */ 1153 NULL, /* security attributes */ 1154 OPEN_EXISTING, 1155 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */ 1156 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_OPEN_REPARSE_POINT, 1157 NULL); 1158 1159 if (hFile == INVALID_HANDLE_VALUE) { 1160 /* Either the target doesn't exist, or we don't have access to 1161 get a handle to it. If the former, we need to return an error. 1162 If the latter, we can use attributes_from_dir. */ 1163 if (GetLastError() != ERROR_SHARING_VIOLATION) 1164 return -1; 1165 /* Could not get attributes on open file. Fall back to 1166 reading the directory. */ 1167 if (!attributes_from_dir(path, &info, &reparse_tag)) 1168 /* Very strange. This should not fail now */ 1169 return -1; 1170 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { 1171 if (traverse) { 1172 /* Should traverse, but could not open reparse point handle */ 1173 SetLastError(ERROR_SHARING_VIOLATION); 1174 return -1; 1175 } 1176 } 1177 } else { 1178 if (!GetFileInformationByHandle(hFile, &info)) { 1179 CloseHandle(hFile); 1180 return -1;; 1181 } 1182 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { 1183 code = win32_read_link(hFile, &reparse_tag, traverse ? &target_path : NULL); 1184 CloseHandle(hFile); 1185 if (code < 0) 1186 return code; 1187 if (traverse) { 1188 code = win32_xstat_impl_w(target_path, result, traverse, depth + 1); 1189 free(target_path); 1190 return code; 1191 } 1192 } else 1193 CloseHandle(hFile); 1194 } 1195 attribute_data_to_stat(&info, reparse_tag, result); 1196 1197 /* Set S_IEXEC if it is an .exe, .bat, ... */ 1198 dot = strrchr(path, '.'); 1199 if (dot) { 1200 if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 || 1201 stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0) 1202 result->st_mode |= 0111; 1203 } 1204 return 0; 1205} 1206 1207static int 1208win32_xstat_impl_w(const wchar_t *path, struct win32_stat *result, BOOL traverse, int depth) 1209{ 1210 int code; 1211 HANDLE hFile; 1212 BY_HANDLE_FILE_INFORMATION info; 1213 ULONG reparse_tag = 0; 1214 wchar_t *target_path; 1215 const wchar_t *dot; 1216 1217 if (depth > SYMLOOP_MAX) { 1218 SetLastError(ERROR_CANT_RESOLVE_FILENAME); /* XXX: ELOOP? */ 1219 return -1; 1220 } 1221 1222 hFile = CreateFileW( 1223 path, 1224 0, /* desired access */ 1225 0, /* share mode */ 1226 NULL, /* security attributes */ 1227 OPEN_EXISTING, 1228 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */ 1229 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_OPEN_REPARSE_POINT, 1230 NULL); 1231 1232 if (hFile == INVALID_HANDLE_VALUE) { 1233 /* Either the target doesn't exist, or we don't have access to 1234 get a handle to it. If the former, we need to return an error. 1235 If the latter, we can use attributes_from_dir. */ 1236 if (GetLastError() != ERROR_SHARING_VIOLATION) 1237 return -1; 1238 /* Could not get attributes on open file. Fall back to 1239 reading the directory. */ 1240 if (!attributes_from_dir_w(path, &info, &reparse_tag)) 1241 /* Very strange. This should not fail now */ 1242 return -1; 1243 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { 1244 if (traverse) { 1245 /* Should traverse, but could not open reparse point handle */ 1246 SetLastError(ERROR_SHARING_VIOLATION); 1247 return -1; 1248 } 1249 } 1250 } else { 1251 if (!GetFileInformationByHandle(hFile, &info)) { 1252 CloseHandle(hFile); 1253 return -1;; 1254 } 1255 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { 1256 code = win32_read_link(hFile, &reparse_tag, traverse ? &target_path : NULL); 1257 CloseHandle(hFile); 1258 if (code < 0) 1259 return code; 1260 if (traverse) { 1261 code = win32_xstat_impl_w(target_path, result, traverse, depth + 1); 1262 free(target_path); 1263 return code; 1264 } 1265 } else 1266 CloseHandle(hFile); 1267 } 1268 attribute_data_to_stat(&info, reparse_tag, result); 1269 1270 /* Set S_IEXEC if it is an .exe, .bat, ... */ 1271 dot = wcsrchr(path, '.'); 1272 if (dot) { 1273 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 || 1274 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0) 1275 result->st_mode |= 0111; 1276 } 1277 return 0; 1278} 1279 1280static int 1281win32_xstat(const char *path, struct win32_stat *result, BOOL traverse) 1282{ 1283 /* Protocol violation: we explicitly clear errno, instead of 1284 setting it to a POSIX error. Callers should use GetLastError. */ 1285 int code = win32_xstat_impl(path, result, traverse, 0); 1286 errno = 0; 1287 return code; 1288} 1289 1290static int 1291win32_xstat_w(const wchar_t *path, struct win32_stat *result, BOOL traverse) 1292{ 1293 /* Protocol violation: we explicitly clear errno, instead of 1294 setting it to a POSIX error. Callers should use GetLastError. */ 1295 int code = win32_xstat_impl_w(path, result, traverse, 0); 1296 errno = 0; 1297 return code; 1298} 1299 1300/* About the following functions: win32_lstat, win32_lstat_w, win32_stat, 1301 win32_stat_w 1302 1303 In Posix, stat automatically traverses symlinks and returns the stat 1304 structure for the target. In Windows, the equivalent GetFileAttributes by 1305 default does not traverse symlinks and instead returns attributes for 1306 the symlink. 1307 1308 Therefore, win32_lstat will get the attributes traditionally, and 1309 win32_stat will first explicitly resolve the symlink target and then will 1310 call win32_lstat on that result. 1311 1312 The _w represent Unicode equivalents of the aformentioned ANSI functions. */ 1313 1314static int 1315win32_lstat(const char* path, struct win32_stat *result) 1316{ 1317 return win32_xstat(path, result, FALSE); 1318} 1319 1320static int 1321win32_lstat_w(const wchar_t* path, struct win32_stat *result) 1322{ 1323 return win32_xstat_w(path, result, FALSE); 1324} 1325 1326static int 1327win32_stat(const char* path, struct win32_stat *result) 1328{ 1329 return win32_xstat(path, result, TRUE); 1330} 1331 1332static int 1333win32_stat_w(const wchar_t* path, struct win32_stat *result) 1334{ 1335 return win32_xstat_w(path, result, TRUE); 1336} 1337 1338static int 1339win32_fstat(int file_number, struct win32_stat *result) 1340{ 1341 BY_HANDLE_FILE_INFORMATION info; 1342 HANDLE h; 1343 int type; 1344 1345 h = (HANDLE)_get_osfhandle(file_number); 1346 1347 /* Protocol violation: we explicitly clear errno, instead of 1348 setting it to a POSIX error. Callers should use GetLastError. */ 1349 errno = 0; 1350 1351 if (h == INVALID_HANDLE_VALUE) { 1352 /* This is really a C library error (invalid file handle). 1353 We set the Win32 error to the closes one matching. */ 1354 SetLastError(ERROR_INVALID_HANDLE); 1355 return -1; 1356 } 1357 memset(result, 0, sizeof(*result)); 1358 1359 type = GetFileType(h); 1360 if (type == FILE_TYPE_UNKNOWN) { 1361 DWORD error = GetLastError(); 1362 if (error != 0) { 1363 return -1; 1364 } 1365 /* else: valid but unknown file */ 1366 } 1367 1368 if (type != FILE_TYPE_DISK) { 1369 if (type == FILE_TYPE_CHAR) 1370 result->st_mode = _S_IFCHR; 1371 else if (type == FILE_TYPE_PIPE) 1372 result->st_mode = _S_IFIFO; 1373 return 0; 1374 } 1375 1376 if (!GetFileInformationByHandle(h, &info)) { 1377 return -1; 1378 } 1379 1380 attribute_data_to_stat(&info, 0, result); 1381 /* specific to fstat() */ 1382 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow; 1383 return 0; 1384} 1385 1386#endif /* MS_WINDOWS */ 1387 1388PyDoc_STRVAR(stat_result__doc__, 1389"stat_result: Result from stat or lstat.\n\n\ 1390This object may be accessed either as a tuple of\n\ 1391 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\ 1392or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\ 1393\n\ 1394Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\ 1395or st_flags, they are available as attributes only.\n\ 1396\n\ 1397See os.stat for more information."); 1398 1399static PyStructSequence_Field stat_result_fields[] = { 1400 {"st_mode", "protection bits"}, 1401 {"st_ino", "inode"}, 1402 {"st_dev", "device"}, 1403 {"st_nlink", "number of hard links"}, 1404 {"st_uid", "user ID of owner"}, 1405 {"st_gid", "group ID of owner"}, 1406 {"st_size", "total size, in bytes"}, 1407 /* The NULL is replaced with PyStructSequence_UnnamedField later. */ 1408 {NULL, "integer time of last access"}, 1409 {NULL, "integer time of last modification"}, 1410 {NULL, "integer time of last change"}, 1411 {"st_atime", "time of last access"}, 1412 {"st_mtime", "time of last modification"}, 1413 {"st_ctime", "time of last change"}, 1414#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE 1415 {"st_blksize", "blocksize for filesystem I/O"}, 1416#endif 1417#ifdef HAVE_STRUCT_STAT_ST_BLOCKS 1418 {"st_blocks", "number of blocks allocated"}, 1419#endif 1420#ifdef HAVE_STRUCT_STAT_ST_RDEV 1421 {"st_rdev", "device type (if inode device)"}, 1422#endif 1423#ifdef HAVE_STRUCT_STAT_ST_FLAGS 1424 {"st_flags", "user defined flags for file"}, 1425#endif 1426#ifdef HAVE_STRUCT_STAT_ST_GEN 1427 {"st_gen", "generation number"}, 1428#endif 1429#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME 1430 {"st_birthtime", "time of creation"}, 1431#endif 1432 {0} 1433}; 1434 1435#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE 1436#define ST_BLKSIZE_IDX 13 1437#else 1438#define ST_BLKSIZE_IDX 12 1439#endif 1440 1441#ifdef HAVE_STRUCT_STAT_ST_BLOCKS 1442#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1) 1443#else 1444#define ST_BLOCKS_IDX ST_BLKSIZE_IDX 1445#endif 1446 1447#ifdef HAVE_STRUCT_STAT_ST_RDEV 1448#define ST_RDEV_IDX (ST_BLOCKS_IDX+1) 1449#else 1450#define ST_RDEV_IDX ST_BLOCKS_IDX 1451#endif 1452 1453#ifdef HAVE_STRUCT_STAT_ST_FLAGS 1454#define ST_FLAGS_IDX (ST_RDEV_IDX+1) 1455#else 1456#define ST_FLAGS_IDX ST_RDEV_IDX 1457#endif 1458 1459#ifdef HAVE_STRUCT_STAT_ST_GEN 1460#define ST_GEN_IDX (ST_FLAGS_IDX+1) 1461#else 1462#define ST_GEN_IDX ST_FLAGS_IDX 1463#endif 1464 1465#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME 1466#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1) 1467#else 1468#define ST_BIRTHTIME_IDX ST_GEN_IDX 1469#endif 1470 1471static PyStructSequence_Desc stat_result_desc = { 1472 "stat_result", /* name */ 1473 stat_result__doc__, /* doc */ 1474 stat_result_fields, 1475 10 1476}; 1477 1478PyDoc_STRVAR(statvfs_result__doc__, 1479"statvfs_result: Result from statvfs or fstatvfs.\n\n\ 1480This object may be accessed either as a tuple of\n\ 1481 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\ 1482or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\ 1483\n\ 1484See os.statvfs for more information."); 1485 1486static PyStructSequence_Field statvfs_result_fields[] = { 1487 {"f_bsize", }, 1488 {"f_frsize", }, 1489 {"f_blocks", }, 1490 {"f_bfree", }, 1491 {"f_bavail", }, 1492 {"f_files", }, 1493 {"f_ffree", }, 1494 {"f_favail", }, 1495 {"f_flag", }, 1496 {"f_namemax",}, 1497 {0} 1498}; 1499 1500static PyStructSequence_Desc statvfs_result_desc = { 1501 "statvfs_result", /* name */ 1502 statvfs_result__doc__, /* doc */ 1503 statvfs_result_fields, 1504 10 1505}; 1506 1507static int initialized; 1508static PyTypeObject StatResultType; 1509static PyTypeObject StatVFSResultType; 1510static newfunc structseq_new; 1511 1512static PyObject * 1513statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds) 1514{ 1515 PyStructSequence *result; 1516 int i; 1517 1518 result = (PyStructSequence*)structseq_new(type, args, kwds); 1519 if (!result) 1520 return NULL; 1521 /* If we have been initialized from a tuple, 1522 st_?time might be set to None. Initialize it 1523 from the int slots. */ 1524 for (i = 7; i <= 9; i++) { 1525 if (result->ob_item[i+3] == Py_None) { 1526 Py_DECREF(Py_None); 1527 Py_INCREF(result->ob_item[i]); 1528 result->ob_item[i+3] = result->ob_item[i]; 1529 } 1530 } 1531 return (PyObject*)result; 1532} 1533 1534 1535 1536/* If true, st_?time is float. */ 1537static int _stat_float_times = 1; 1538 1539PyDoc_STRVAR(stat_float_times__doc__, 1540"stat_float_times([newval]) -> oldval\n\n\ 1541Determine whether os.[lf]stat represents time stamps as float objects.\n\ 1542If newval is True, future calls to stat() return floats, if it is False,\n\ 1543future calls return ints. \n\ 1544If newval is omitted, return the current setting.\n"); 1545 1546static PyObject* 1547stat_float_times(PyObject* self, PyObject *args) 1548{ 1549 int newval = -1; 1550 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval)) 1551 return NULL; 1552 if (newval == -1) 1553 /* Return old value */ 1554 return PyBool_FromLong(_stat_float_times); 1555 _stat_float_times = newval; 1556 Py_INCREF(Py_None); 1557 return Py_None; 1558} 1559 1560static void 1561fill_time(PyObject *v, int index, time_t sec, unsigned long nsec) 1562{ 1563 PyObject *fval,*ival; 1564#if SIZEOF_TIME_T > SIZEOF_LONG 1565 ival = PyLong_FromLongLong((PY_LONG_LONG)sec); 1566#else 1567 ival = PyLong_FromLong((long)sec); 1568#endif 1569 if (!ival) 1570 return; 1571 if (_stat_float_times) { 1572 fval = PyFloat_FromDouble(sec + 1e-9*nsec); 1573 } else { 1574 fval = ival; 1575 Py_INCREF(fval); 1576 } 1577 PyStructSequence_SET_ITEM(v, index, ival); 1578 PyStructSequence_SET_ITEM(v, index+3, fval); 1579} 1580 1581/* pack a system stat C structure into the Python stat tuple 1582 (used by posix_stat() and posix_fstat()) */ 1583static PyObject* 1584_pystat_fromstructstat(STRUCT_STAT *st) 1585{ 1586 unsigned long ansec, mnsec, cnsec; 1587 PyObject *v = PyStructSequence_New(&StatResultType); 1588 if (v == NULL) 1589 return NULL; 1590 1591 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode)); 1592#ifdef HAVE_LARGEFILE_SUPPORT 1593 PyStructSequence_SET_ITEM(v, 1, 1594 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino)); 1595#else 1596 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino)); 1597#endif 1598#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS) 1599 PyStructSequence_SET_ITEM(v, 2, 1600 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev)); 1601#else 1602 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev)); 1603#endif 1604 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink)); 1605 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long)st->st_uid)); 1606 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long)st->st_gid)); 1607#ifdef HAVE_LARGEFILE_SUPPORT 1608 PyStructSequence_SET_ITEM(v, 6, 1609 PyLong_FromLongLong((PY_LONG_LONG)st->st_size)); 1610#else 1611 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size)); 1612#endif 1613 1614#if defined(HAVE_STAT_TV_NSEC) 1615 ansec = st->st_atim.tv_nsec; 1616 mnsec = st->st_mtim.tv_nsec; 1617 cnsec = st->st_ctim.tv_nsec; 1618#elif defined(HAVE_STAT_TV_NSEC2) 1619 ansec = st->st_atimespec.tv_nsec; 1620 mnsec = st->st_mtimespec.tv_nsec; 1621 cnsec = st->st_ctimespec.tv_nsec; 1622#elif defined(HAVE_STAT_NSEC) 1623 ansec = st->st_atime_nsec; 1624 mnsec = st->st_mtime_nsec; 1625 cnsec = st->st_ctime_nsec; 1626#else 1627 ansec = mnsec = cnsec = 0; 1628#endif 1629 fill_time(v, 7, st->st_atime, ansec); 1630 fill_time(v, 8, st->st_mtime, mnsec); 1631 fill_time(v, 9, st->st_ctime, cnsec); 1632 1633#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE 1634 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX, 1635 PyLong_FromLong((long)st->st_blksize)); 1636#endif 1637#ifdef HAVE_STRUCT_STAT_ST_BLOCKS 1638 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX, 1639 PyLong_FromLong((long)st->st_blocks)); 1640#endif 1641#ifdef HAVE_STRUCT_STAT_ST_RDEV 1642 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX, 1643 PyLong_FromLong((long)st->st_rdev)); 1644#endif 1645#ifdef HAVE_STRUCT_STAT_ST_GEN 1646 PyStructSequence_SET_ITEM(v, ST_GEN_IDX, 1647 PyLong_FromLong((long)st->st_gen)); 1648#endif 1649#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME 1650 { 1651 PyObject *val; 1652 unsigned long bsec,bnsec; 1653 bsec = (long)st->st_birthtime; 1654#ifdef HAVE_STAT_TV_NSEC2 1655 bnsec = st->st_birthtimespec.tv_nsec; 1656#else 1657 bnsec = 0; 1658#endif 1659 if (_stat_float_times) { 1660 val = PyFloat_FromDouble(bsec + 1e-9*bnsec); 1661 } else { 1662 val = PyLong_FromLong((long)bsec); 1663 } 1664 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX, 1665 val); 1666 } 1667#endif 1668#ifdef HAVE_STRUCT_STAT_ST_FLAGS 1669 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX, 1670 PyLong_FromLong((long)st->st_flags)); 1671#endif 1672 1673 if (PyErr_Occurred()) { 1674 Py_DECREF(v); 1675 return NULL; 1676 } 1677 1678 return v; 1679} 1680 1681static PyObject * 1682posix_do_stat(PyObject *self, PyObject *args, 1683 char *format, 1684#ifdef __VMS 1685 int (*statfunc)(const char *, STRUCT_STAT *, ...), 1686#else 1687 int (*statfunc)(const char *, STRUCT_STAT *), 1688#endif 1689 char *wformat, 1690 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *)) 1691{ 1692 STRUCT_STAT st; 1693 PyObject *opath; 1694 char *path; 1695 int res; 1696 PyObject *result; 1697 1698#ifdef MS_WINDOWS 1699 PyUnicodeObject *po; 1700 if (PyArg_ParseTuple(args, wformat, &po)) { 1701 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po); 1702 1703 Py_BEGIN_ALLOW_THREADS 1704 /* PyUnicode_AS_UNICODE result OK without 1705 thread lock as it is a simple dereference. */ 1706 res = wstatfunc(wpath, &st); 1707 Py_END_ALLOW_THREADS 1708 1709 if (res != 0) 1710 return win32_error_unicode("stat", wpath); 1711 return _pystat_fromstructstat(&st); 1712 } 1713 /* Drop the argument parsing error as narrow strings 1714 are also valid. */ 1715 PyErr_Clear(); 1716#endif 1717 1718 if (!PyArg_ParseTuple(args, format, 1719 PyUnicode_FSConverter, &opath)) 1720 return NULL; 1721 path = PyBytes_AsString(opath); 1722 Py_BEGIN_ALLOW_THREADS 1723 res = (*statfunc)(path, &st); 1724 Py_END_ALLOW_THREADS 1725 1726 if (res != 0) { 1727#ifdef MS_WINDOWS 1728 result = win32_error("stat", path); 1729#else 1730 result = posix_error_with_filename(path); 1731#endif 1732 } 1733 else 1734 result = _pystat_fromstructstat(&st); 1735 1736 Py_DECREF(opath); 1737 return result; 1738} 1739 1740/* POSIX methods */ 1741 1742PyDoc_STRVAR(posix_access__doc__, 1743"access(path, mode) -> True if granted, False otherwise\n\n\ 1744Use the real uid/gid to test for access to a path. Note that most\n\ 1745operations will use the effective uid/gid, therefore this routine can\n\ 1746be used in a suid/sgid environment to test if the invoking user has the\n\ 1747specified access to the path. The mode argument can be F_OK to test\n\ 1748existence, or the inclusive-OR of R_OK, W_OK, and X_OK."); 1749 1750static PyObject * 1751posix_access(PyObject *self, PyObject *args) 1752{ 1753 PyObject *opath; 1754 char *path; 1755 int mode; 1756 1757#ifdef MS_WINDOWS 1758 DWORD attr; 1759 PyUnicodeObject *po; 1760 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) { 1761 Py_BEGIN_ALLOW_THREADS 1762 /* PyUnicode_AS_UNICODE OK without thread lock as 1763 it is a simple dereference. */ 1764 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po)); 1765 Py_END_ALLOW_THREADS 1766 goto finish; 1767 } 1768 /* Drop the argument parsing error as narrow strings 1769 are also valid. */ 1770 PyErr_Clear(); 1771 if (!PyArg_ParseTuple(args, "O&i:access", 1772 PyUnicode_FSConverter, &opath, &mode)) 1773 return NULL; 1774 path = PyBytes_AsString(opath); 1775 Py_BEGIN_ALLOW_THREADS 1776 attr = GetFileAttributesA(path); 1777 Py_END_ALLOW_THREADS 1778 Py_DECREF(opath); 1779finish: 1780 if (attr == 0xFFFFFFFF) 1781 /* File does not exist, or cannot read attributes */ 1782 return PyBool_FromLong(0); 1783 /* Access is possible if either write access wasn't requested, or 1784 the file isn't read-only, or if it's a directory, as there are 1785 no read-only directories on Windows. */ 1786 return PyBool_FromLong(!(mode & 2) 1787 || !(attr & FILE_ATTRIBUTE_READONLY) 1788 || (attr & FILE_ATTRIBUTE_DIRECTORY)); 1789#else 1790 int res; 1791 if (!PyArg_ParseTuple(args, "O&i:access", 1792 PyUnicode_FSConverter, &opath, &mode)) 1793 return NULL; 1794 path = PyBytes_AsString(opath); 1795 Py_BEGIN_ALLOW_THREADS 1796 res = access(path, mode); 1797 Py_END_ALLOW_THREADS 1798 Py_DECREF(opath); 1799 return PyBool_FromLong(res == 0); 1800#endif 1801} 1802 1803#ifndef F_OK 1804#define F_OK 0 1805#endif 1806#ifndef R_OK 1807#define R_OK 4 1808#endif 1809#ifndef W_OK 1810#define W_OK 2 1811#endif 1812#ifndef X_OK 1813#define X_OK 1 1814#endif 1815 1816#ifdef HAVE_TTYNAME 1817PyDoc_STRVAR(posix_ttyname__doc__, 1818"ttyname(fd) -> string\n\n\ 1819Return the name of the terminal device connected to 'fd'."); 1820 1821static PyObject * 1822posix_ttyname(PyObject *self, PyObject *args) 1823{ 1824 int id; 1825 char *ret; 1826 1827 if (!PyArg_ParseTuple(args, "i:ttyname", &id)) 1828 return NULL; 1829 1830#if defined(__VMS) 1831 /* file descriptor 0 only, the default input device (stdin) */ 1832 if (id == 0) { 1833 ret = ttyname(); 1834 } 1835 else { 1836 ret = NULL; 1837 } 1838#else 1839 ret = ttyname(id); 1840#endif 1841 if (ret == NULL) 1842 return posix_error(); 1843 return PyUnicode_DecodeFSDefault(ret); 1844} 1845#endif 1846 1847#ifdef HAVE_CTERMID 1848PyDoc_STRVAR(posix_ctermid__doc__, 1849"ctermid() -> string\n\n\ 1850Return the name of the controlling terminal for this process."); 1851 1852static PyObject * 1853posix_ctermid(PyObject *self, PyObject *noargs) 1854{ 1855 char *ret; 1856 char buffer[L_ctermid]; 1857 1858#ifdef USE_CTERMID_R 1859 ret = ctermid_r(buffer); 1860#else 1861 ret = ctermid(buffer); 1862#endif 1863 if (ret == NULL) 1864 return posix_error(); 1865 return PyUnicode_DecodeFSDefault(buffer); 1866} 1867#endif 1868 1869PyDoc_STRVAR(posix_chdir__doc__, 1870"chdir(path)\n\n\ 1871Change the current working directory to the specified path."); 1872 1873static PyObject * 1874posix_chdir(PyObject *self, PyObject *args) 1875{ 1876#ifdef MS_WINDOWS 1877 return win32_1str(args, "chdir", "y:chdir", win32_chdir, "U:chdir", win32_wchdir); 1878#elif defined(PYOS_OS2) && defined(PYCC_GCC) 1879 return posix_1str(args, "O&:chdir", _chdir2); 1880#elif defined(__VMS) 1881 return posix_1str(args, "O&:chdir", (int (*)(const char *))chdir); 1882#else 1883 return posix_1str(args, "O&:chdir", chdir); 1884#endif 1885} 1886 1887#ifdef HAVE_FCHDIR 1888PyDoc_STRVAR(posix_fchdir__doc__, 1889"fchdir(fildes)\n\n\ 1890Change to the directory of the given file descriptor. fildes must be\n\ 1891opened on a directory, not a file."); 1892 1893static PyObject * 1894posix_fchdir(PyObject *self, PyObject *fdobj) 1895{ 1896 return posix_fildes(fdobj, fchdir); 1897} 1898#endif /* HAVE_FCHDIR */ 1899 1900 1901PyDoc_STRVAR(posix_chmod__doc__, 1902"chmod(path, mode)\n\n\ 1903Change the access permissions of a file."); 1904 1905static PyObject * 1906posix_chmod(PyObject *self, PyObject *args) 1907{ 1908 PyObject *opath = NULL; 1909 char *path = NULL; 1910 int i; 1911 int res; 1912#ifdef MS_WINDOWS 1913 DWORD attr; 1914 PyUnicodeObject *po; 1915 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) { 1916 Py_BEGIN_ALLOW_THREADS 1917 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po)); 1918 if (attr != 0xFFFFFFFF) { 1919 if (i & _S_IWRITE) 1920 attr &= ~FILE_ATTRIBUTE_READONLY; 1921 else 1922 attr |= FILE_ATTRIBUTE_READONLY; 1923 res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr); 1924 } 1925 else 1926 res = 0; 1927 Py_END_ALLOW_THREADS 1928 if (!res) 1929 return win32_error_unicode("chmod", 1930 PyUnicode_AS_UNICODE(po)); 1931 Py_INCREF(Py_None); 1932 return Py_None; 1933 } 1934 /* Drop the argument parsing error as narrow strings 1935 are also valid. */ 1936 PyErr_Clear(); 1937 1938 if (!PyArg_ParseTuple(args, "O&i:chmod", PyUnicode_FSConverter, 1939 &opath, &i)) 1940 return NULL; 1941 path = PyBytes_AsString(opath); 1942 Py_BEGIN_ALLOW_THREADS 1943 attr = GetFileAttributesA(path); 1944 if (attr != 0xFFFFFFFF) { 1945 if (i & _S_IWRITE) 1946 attr &= ~FILE_ATTRIBUTE_READONLY; 1947 else 1948 attr |= FILE_ATTRIBUTE_READONLY; 1949 res = SetFileAttributesA(path, attr); 1950 } 1951 else 1952 res = 0; 1953 Py_END_ALLOW_THREADS 1954 if (!res) { 1955 win32_error("chmod", path); 1956 Py_DECREF(opath); 1957 return NULL; 1958 } 1959 Py_DECREF(opath); 1960 Py_INCREF(Py_None); 1961 return Py_None; 1962#else /* MS_WINDOWS */ 1963 if (!PyArg_ParseTuple(args, "O&i:chmod", PyUnicode_FSConverter, 1964 &opath, &i)) 1965 return NULL; 1966 path = PyBytes_AsString(opath); 1967 Py_BEGIN_ALLOW_THREADS 1968 res = chmod(path, i); 1969 Py_END_ALLOW_THREADS 1970 if (res < 0) 1971 return posix_error_with_allocated_filename(opath); 1972 Py_DECREF(opath); 1973 Py_INCREF(Py_None); 1974 return Py_None; 1975#endif 1976} 1977 1978#ifdef HAVE_FCHMOD 1979PyDoc_STRVAR(posix_fchmod__doc__, 1980"fchmod(fd, mode)\n\n\ 1981Change the access permissions of the file given by file\n\ 1982descriptor fd."); 1983 1984static PyObject * 1985posix_fchmod(PyObject *self, PyObject *args) 1986{ 1987 int fd, mode, res; 1988 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode)) 1989 return NULL; 1990 Py_BEGIN_ALLOW_THREADS 1991 res = fchmod(fd, mode); 1992 Py_END_ALLOW_THREADS 1993 if (res < 0) 1994 return posix_error(); 1995 Py_RETURN_NONE; 1996} 1997#endif /* HAVE_FCHMOD */ 1998 1999#ifdef HAVE_LCHMOD 2000PyDoc_STRVAR(posix_lchmod__doc__, 2001"lchmod(path, mode)\n\n\ 2002Change the access permissions of a file. If path is a symlink, this\n\ 2003affects the link itself rather than the target."); 2004 2005static PyObject * 2006posix_lchmod(PyObject *self, PyObject *args) 2007{ 2008 PyObject *opath; 2009 char *path; 2010 int i; 2011 int res; 2012 if (!PyArg_ParseTuple(args, "O&i:lchmod", PyUnicode_FSConverter, 2013 &opath, &i)) 2014 return NULL; 2015 path = PyBytes_AsString(opath); 2016 Py_BEGIN_ALLOW_THREADS 2017 res = lchmod(path, i); 2018 Py_END_ALLOW_THREADS 2019 if (res < 0) 2020 return posix_error_with_allocated_filename(opath); 2021 Py_DECREF(opath); 2022 Py_RETURN_NONE; 2023} 2024#endif /* HAVE_LCHMOD */ 2025 2026 2027#ifdef HAVE_CHFLAGS 2028PyDoc_STRVAR(posix_chflags__doc__, 2029"chflags(path, flags)\n\n\ 2030Set file flags."); 2031 2032static PyObject * 2033posix_chflags(PyObject *self, PyObject *args) 2034{ 2035 PyObject *opath; 2036 char *path; 2037 unsigned long flags; 2038 int res; 2039 if (!PyArg_ParseTuple(args, "O&k:chflags", 2040 PyUnicode_FSConverter, &opath, &flags)) 2041 return NULL; 2042 path = PyBytes_AsString(opath); 2043 Py_BEGIN_ALLOW_THREADS 2044 res = chflags(path, flags); 2045 Py_END_ALLOW_THREADS 2046 if (res < 0) 2047 return posix_error_with_allocated_filename(opath); 2048 Py_DECREF(opath); 2049 Py_INCREF(Py_None); 2050 return Py_None; 2051} 2052#endif /* HAVE_CHFLAGS */ 2053 2054#ifdef HAVE_LCHFLAGS 2055PyDoc_STRVAR(posix_lchflags__doc__, 2056"lchflags(path, flags)\n\n\ 2057Set file flags.\n\ 2058This function will not follow symbolic links."); 2059 2060static PyObject * 2061posix_lchflags(PyObject *self, PyObject *args) 2062{ 2063 PyObject *opath; 2064 char *path; 2065 unsigned long flags; 2066 int res; 2067 if (!PyArg_ParseTuple(args, "O&k:lchflags", 2068 PyUnicode_FSConverter, &opath, &flags)) 2069 return NULL; 2070 path = PyBytes_AsString(opath); 2071 Py_BEGIN_ALLOW_THREADS 2072 res = lchflags(path, flags); 2073 Py_END_ALLOW_THREADS 2074 if (res < 0) 2075 return posix_error_with_allocated_filename(opath); 2076 Py_DECREF(opath); 2077 Py_INCREF(Py_None); 2078 return Py_None; 2079} 2080#endif /* HAVE_LCHFLAGS */ 2081 2082#ifdef HAVE_CHROOT 2083PyDoc_STRVAR(posix_chroot__doc__, 2084"chroot(path)\n\n\ 2085Change root directory to path."); 2086 2087static PyObject * 2088posix_chroot(PyObject *self, PyObject *args) 2089{ 2090 return posix_1str(args, "O&:chroot", chroot); 2091} 2092#endif 2093 2094#ifdef HAVE_FSYNC 2095PyDoc_STRVAR(posix_fsync__doc__, 2096"fsync(fildes)\n\n\ 2097force write of file with filedescriptor to disk."); 2098 2099static PyObject * 2100posix_fsync(PyObject *self, PyObject *fdobj) 2101{ 2102 return posix_fildes(fdobj, fsync); 2103} 2104#endif /* HAVE_FSYNC */ 2105 2106#ifdef HAVE_FDATASYNC 2107 2108#ifdef __hpux 2109extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */ 2110#endif 2111 2112PyDoc_STRVAR(posix_fdatasync__doc__, 2113"fdatasync(fildes)\n\n\ 2114force write of file with filedescriptor to disk.\n\ 2115 does not force update of metadata."); 2116 2117static PyObject * 2118posix_fdatasync(PyObject *self, PyObject *fdobj) 2119{ 2120 return posix_fildes(fdobj, fdatasync); 2121} 2122#endif /* HAVE_FDATASYNC */ 2123 2124 2125#ifdef HAVE_CHOWN 2126PyDoc_STRVAR(posix_chown__doc__, 2127"chown(path, uid, gid)\n\n\ 2128Change the owner and group id of path to the numeric uid and gid."); 2129 2130static PyObject * 2131posix_chown(PyObject *self, PyObject *args) 2132{ 2133 PyObject *opath; 2134 char *path; 2135 long uid, gid; 2136 int res; 2137 if (!PyArg_ParseTuple(args, "O&ll:chown", 2138 PyUnicode_FSConverter, &opath, 2139 &uid, &gid)) 2140 return NULL; 2141 path = PyBytes_AsString(opath); 2142 Py_BEGIN_ALLOW_THREADS 2143 res = chown(path, (uid_t) uid, (gid_t) gid); 2144 Py_END_ALLOW_THREADS 2145 if (res < 0) 2146 return posix_error_with_allocated_filename(opath); 2147 Py_DECREF(opath); 2148 Py_INCREF(Py_None); 2149 return Py_None; 2150} 2151#endif /* HAVE_CHOWN */ 2152 2153#ifdef HAVE_FCHOWN 2154PyDoc_STRVAR(posix_fchown__doc__, 2155"fchown(fd, uid, gid)\n\n\ 2156Change the owner and group id of the file given by file descriptor\n\ 2157fd to the numeric uid and gid."); 2158 2159static PyObject * 2160posix_fchown(PyObject *self, PyObject *args) 2161{ 2162 int fd; 2163 long uid, gid; 2164 int res; 2165 if (!PyArg_ParseTuple(args, "ill:chown", &fd, &uid, &gid)) 2166 return NULL; 2167 Py_BEGIN_ALLOW_THREADS 2168 res = fchown(fd, (uid_t) uid, (gid_t) gid); 2169 Py_END_ALLOW_THREADS 2170 if (res < 0) 2171 return posix_error(); 2172 Py_RETURN_NONE; 2173} 2174#endif /* HAVE_FCHOWN */ 2175 2176#ifdef HAVE_LCHOWN 2177PyDoc_STRVAR(posix_lchown__doc__, 2178"lchown(path, uid, gid)\n\n\ 2179Change the owner and group id of path to the numeric uid and gid.\n\ 2180This function will not follow symbolic links."); 2181 2182static PyObject * 2183posix_lchown(PyObject *self, PyObject *args) 2184{ 2185 PyObject *opath; 2186 char *path; 2187 long uid, gid; 2188 int res; 2189 if (!PyArg_ParseTuple(args, "O&ll:lchown", 2190 PyUnicode_FSConverter, &opath, 2191 &uid, &gid)) 2192 return NULL; 2193 path = PyBytes_AsString(opath); 2194 Py_BEGIN_ALLOW_THREADS 2195 res = lchown(path, (uid_t) uid, (gid_t) gid); 2196 Py_END_ALLOW_THREADS 2197 if (res < 0) 2198 return posix_error_with_allocated_filename(opath); 2199 Py_DECREF(opath); 2200 Py_INCREF(Py_None); 2201 return Py_None; 2202} 2203#endif /* HAVE_LCHOWN */ 2204 2205 2206#ifdef HAVE_GETCWD 2207static PyObject * 2208posix_getcwd(int use_bytes) 2209{ 2210 char buf[1026]; 2211 char *res; 2212 2213#ifdef MS_WINDOWS 2214 if (!use_bytes) { 2215 wchar_t wbuf[1026]; 2216 wchar_t *wbuf2 = wbuf; 2217 PyObject *resobj; 2218 DWORD len; 2219 Py_BEGIN_ALLOW_THREADS 2220 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf); 2221 /* If the buffer is large enough, len does not include the 2222 terminating \0. If the buffer is too small, len includes 2223 the space needed for the terminator. */ 2224 if (len >= sizeof wbuf/ sizeof wbuf[0]) { 2225 wbuf2 = malloc(len * sizeof(wchar_t)); 2226 if (wbuf2) 2227 len = GetCurrentDirectoryW(len, wbuf2); 2228 } 2229 Py_END_ALLOW_THREADS 2230 if (!wbuf2) { 2231 PyErr_NoMemory(); 2232 return NULL; 2233 } 2234 if (!len) { 2235 if (wbuf2 != wbuf) free(wbuf2); 2236 return win32_error("getcwdu", NULL); 2237 } 2238 resobj = PyUnicode_FromWideChar(wbuf2, len); 2239 if (wbuf2 != wbuf) free(wbuf2); 2240 return resobj; 2241 } 2242#endif 2243 2244 Py_BEGIN_ALLOW_THREADS 2245#if defined(PYOS_OS2) && defined(PYCC_GCC) 2246 res = _getcwd2(buf, sizeof buf); 2247#else 2248 res = getcwd(buf, sizeof buf); 2249#endif 2250 Py_END_ALLOW_THREADS 2251 if (res == NULL) 2252 return posix_error(); 2253 if (use_bytes) 2254 return PyBytes_FromStringAndSize(buf, strlen(buf)); 2255 return PyUnicode_DecodeFSDefault(buf); 2256} 2257 2258PyDoc_STRVAR(posix_getcwd__doc__, 2259"getcwd() -> path\n\n\ 2260Return a unicode string representing the current working directory."); 2261 2262static PyObject * 2263posix_getcwd_unicode(PyObject *self) 2264{ 2265 return posix_getcwd(0); 2266} 2267 2268PyDoc_STRVAR(posix_getcwdb__doc__, 2269"getcwdb() -> path\n\n\ 2270Return a bytes string representing the current working directory."); 2271 2272static PyObject * 2273posix_getcwd_bytes(PyObject *self) 2274{ 2275 return posix_getcwd(1); 2276} 2277#endif 2278 2279 2280#ifdef HAVE_LINK 2281PyDoc_STRVAR(posix_link__doc__, 2282"link(src, dst)\n\n\ 2283Create a hard link to a file."); 2284 2285static PyObject * 2286posix_link(PyObject *self, PyObject *args) 2287{ 2288 return posix_2str(args, "O&O&:link", link); 2289} 2290#endif /* HAVE_LINK */ 2291 2292#ifdef MS_WINDOWS 2293PyDoc_STRVAR(win32_link__doc__, 2294"link(src, dst)\n\n\ 2295Create a hard link to a file."); 2296 2297static PyObject * 2298win32_link(PyObject *self, PyObject *args) 2299{ 2300 PyObject *osrc, *odst; 2301 char *src, *dst; 2302 BOOL rslt; 2303 2304 PyUnicodeObject *usrc, *udst; 2305 if (PyArg_ParseTuple(args, "UU:link", &usrc, &udst)) { 2306 Py_BEGIN_ALLOW_THREADS 2307 rslt = CreateHardLinkW(PyUnicode_AS_UNICODE(udst), 2308 PyUnicode_AS_UNICODE(usrc), NULL); 2309 Py_END_ALLOW_THREADS 2310 2311 if (rslt == 0) 2312 return win32_error("link", NULL); 2313 2314 Py_RETURN_NONE; 2315 } 2316 2317 /* Narrow strings also valid. */ 2318 PyErr_Clear(); 2319 2320 if (!PyArg_ParseTuple(args, "O&O&:link", PyUnicode_FSConverter, &osrc, 2321 PyUnicode_FSConverter, &odst)) 2322 return NULL; 2323 2324 src = PyBytes_AsString(osrc); 2325 dst = PyBytes_AsString(odst); 2326 2327 Py_BEGIN_ALLOW_THREADS 2328 rslt = CreateHardLinkA(dst, src, NULL); 2329 Py_END_ALLOW_THREADS 2330 2331 Py_DECREF(osrc); 2332 Py_DECREF(odst); 2333 if (rslt == 0) 2334 return win32_error("link", NULL); 2335 2336 Py_RETURN_NONE; 2337} 2338#endif /* MS_WINDOWS */ 2339 2340 2341PyDoc_STRVAR(posix_listdir__doc__, 2342"listdir([path]) -> list_of_strings\n\n\ 2343Return a list containing the names of the entries in the directory.\n\ 2344\n\ 2345 path: path of directory to list (default: '.')\n\ 2346\n\ 2347The list is in arbitrary order. It does not include the special\n\ 2348entries '.' and '..' even if they are present in the directory."); 2349 2350static PyObject * 2351posix_listdir(PyObject *self, PyObject *args) 2352{ 2353 /* XXX Should redo this putting the (now four) versions of opendir 2354 in separate files instead of having them all here... */ 2355#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR) 2356 2357 PyObject *d, *v; 2358 HANDLE hFindFile; 2359 BOOL result; 2360 WIN32_FIND_DATA FileData; 2361 PyObject *opath; 2362 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */ 2363 char *bufptr = namebuf; 2364 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */ 2365 2366 PyObject *po = NULL; 2367 if (PyArg_ParseTuple(args, "|U:listdir", &po)) { 2368 WIN32_FIND_DATAW wFileData; 2369 Py_UNICODE *wnamebuf, *po_wchars; 2370 2371 if (po == NULL) { /* Default arg: "." */ 2372 po_wchars = L"."; 2373 len = 1; 2374 } else { 2375 po_wchars = PyUnicode_AS_UNICODE(po); 2376 len = PyUnicode_GET_SIZE(po); 2377 } 2378 /* Overallocate for \\*.*\0 */ 2379 wnamebuf = malloc((len + 5) * sizeof(wchar_t)); 2380 if (!wnamebuf) { 2381 PyErr_NoMemory(); 2382 return NULL; 2383 } 2384 wcscpy(wnamebuf, po_wchars); 2385 if (len > 0) { 2386 Py_UNICODE wch = wnamebuf[len-1]; 2387 if (wch != L'/' && wch != L'\\' && wch != L':') 2388 wnamebuf[len++] = L'\\'; 2389 wcscpy(wnamebuf + len, L"*.*"); 2390 } 2391 if ((d = PyList_New(0)) == NULL) { 2392 free(wnamebuf); 2393 return NULL; 2394 } 2395 Py_BEGIN_ALLOW_THREADS 2396 hFindFile = FindFirstFileW(wnamebuf, &wFileData); 2397 Py_END_ALLOW_THREADS 2398 if (hFindFile == INVALID_HANDLE_VALUE) { 2399 int error = GetLastError(); 2400 if (error == ERROR_FILE_NOT_FOUND) { 2401 free(wnamebuf); 2402 return d; 2403 } 2404 Py_DECREF(d); 2405 win32_error_unicode("FindFirstFileW", wnamebuf); 2406 free(wnamebuf); 2407 return NULL; 2408 } 2409 do { 2410 /* Skip over . and .. */ 2411 if (wcscmp(wFileData.cFileName, L".") != 0 && 2412 wcscmp(wFileData.cFileName, L"..") != 0) { 2413 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName)); 2414 if (v == NULL) { 2415 Py_DECREF(d); 2416 d = NULL; 2417 break; 2418 } 2419 if (PyList_Append(d, v) != 0) { 2420 Py_DECREF(v); 2421 Py_DECREF(d); 2422 d = NULL; 2423 break; 2424 } 2425 Py_DECREF(v); 2426 } 2427 Py_BEGIN_ALLOW_THREADS 2428 result = FindNextFileW(hFindFile, &wFileData); 2429 Py_END_ALLOW_THREADS 2430 /* FindNextFile sets error to ERROR_NO_MORE_FILES if 2431 it got to the end of the directory. */ 2432 if (!result && GetLastError() != ERROR_NO_MORE_FILES) { 2433 Py_DECREF(d); 2434 win32_error_unicode("FindNextFileW", wnamebuf); 2435 FindClose(hFindFile); 2436 free(wnamebuf); 2437 return NULL; 2438 } 2439 } while (result == TRUE); 2440 2441 if (FindClose(hFindFile) == FALSE) { 2442 Py_DECREF(d); 2443 win32_error_unicode("FindClose", wnamebuf); 2444 free(wnamebuf); 2445 return NULL; 2446 } 2447 free(wnamebuf); 2448 return d; 2449 } 2450 /* Drop the argument parsing error as narrow strings 2451 are also valid. */ 2452 PyErr_Clear(); 2453 2454 if (!PyArg_ParseTuple(args, "O&:listdir", 2455 PyUnicode_FSConverter, &opath)) 2456 return NULL; 2457 if (PyBytes_GET_SIZE(opath)+1 > MAX_PATH) { 2458 PyErr_SetString(PyExc_ValueError, "path too long"); 2459 Py_DECREF(opath); 2460 return NULL; 2461 } 2462 strcpy(namebuf, PyBytes_AsString(opath)); 2463 len = PyObject_Size(opath); 2464 Py_DECREF(opath); 2465 if (len > 0) { 2466 char ch = namebuf[len-1]; 2467 if (ch != SEP && ch != ALTSEP && ch != ':') 2468 namebuf[len++] = '/'; 2469 strcpy(namebuf + len, "*.*"); 2470 } 2471 2472 if ((d = PyList_New(0)) == NULL) 2473 return NULL; 2474 2475 Py_BEGIN_ALLOW_THREADS 2476 hFindFile = FindFirstFile(namebuf, &FileData); 2477 Py_END_ALLOW_THREADS 2478 if (hFindFile == INVALID_HANDLE_VALUE) { 2479 int error = GetLastError(); 2480 if (error == ERROR_FILE_NOT_FOUND) 2481 return d; 2482 Py_DECREF(d); 2483 return win32_error("FindFirstFile", namebuf); 2484 } 2485 do { 2486 /* Skip over . and .. */ 2487 if (strcmp(FileData.cFileName, ".") != 0 && 2488 strcmp(FileData.cFileName, "..") != 0) { 2489 v = PyBytes_FromString(FileData.cFileName); 2490 if (v == NULL) { 2491 Py_DECREF(d); 2492 d = NULL; 2493 break; 2494 } 2495 if (PyList_Append(d, v) != 0) { 2496 Py_DECREF(v); 2497 Py_DECREF(d); 2498 d = NULL; 2499 break; 2500 } 2501 Py_DECREF(v); 2502 } 2503 Py_BEGIN_ALLOW_THREADS 2504 result = FindNextFile(hFindFile, &FileData); 2505 Py_END_ALLOW_THREADS 2506 /* FindNextFile sets error to ERROR_NO_MORE_FILES if 2507 it got to the end of the directory. */ 2508 if (!result && GetLastError() != ERROR_NO_MORE_FILES) { 2509 Py_DECREF(d); 2510 win32_error("FindNextFile", namebuf); 2511 FindClose(hFindFile); 2512 return NULL; 2513 } 2514 } while (result == TRUE); 2515 2516 if (FindClose(hFindFile) == FALSE) { 2517 Py_DECREF(d); 2518 return win32_error("FindClose", namebuf); 2519 } 2520 2521 return d; 2522 2523#elif defined(PYOS_OS2) 2524 2525#ifndef MAX_PATH 2526#define MAX_PATH CCHMAXPATH 2527#endif 2528 PyObject *oname; 2529 char *name, *pt; 2530 Py_ssize_t len; 2531 PyObject *d, *v; 2532 char namebuf[MAX_PATH+5]; 2533 HDIR hdir = 1; 2534 ULONG srchcnt = 1; 2535 FILEFINDBUF3 ep; 2536 APIRET rc; 2537 2538 if (!PyArg_ParseTuple(args, "O&:listdir", 2539 PyUnicode_FSConverter, &oname)) 2540 return NULL; 2541 name = PyBytes_AsString(oname); 2542 len = PyBytes_GET_SIZE(oname); 2543 if (len >= MAX_PATH) { 2544 Py_DECREF(oname); 2545 PyErr_SetString(PyExc_ValueError, "path too long"); 2546 return NULL; 2547 } 2548 strcpy(namebuf, name); 2549 for (pt = namebuf; *pt; pt++) 2550 if (*pt == ALTSEP) 2551 *pt = SEP; 2552 if (namebuf[len-1] != SEP) 2553 namebuf[len++] = SEP; 2554 strcpy(namebuf + len, "*.*"); 2555 2556 if ((d = PyList_New(0)) == NULL) { 2557 Py_DECREF(oname); 2558 return NULL; 2559 } 2560 2561 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */ 2562 &hdir, /* Handle to Use While Search Directory */ 2563 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY, 2564 &ep, sizeof(ep), /* Structure to Receive Directory Entry */ 2565 &srchcnt, /* Max and Actual Count of Entries Per Iteration */ 2566 FIL_STANDARD); /* Format of Entry (EAs or Not) */ 2567 2568 if (rc != NO_ERROR) { 2569 errno = ENOENT; 2570 return posix_error_with_allocated_filename(oname); 2571 } 2572 2573 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */ 2574 do { 2575 if (ep.achName[0] == '.' 2576 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0'))) 2577 continue; /* Skip Over "." and ".." Names */ 2578 2579 strcpy(namebuf, ep.achName); 2580 2581 /* Leave Case of Name Alone -- In Native Form */ 2582 /* (Removed Forced Lowercasing Code) */ 2583 2584 v = PyBytes_FromString(namebuf); 2585 if (v == NULL) { 2586 Py_DECREF(d); 2587 d = NULL; 2588 break; 2589 } 2590 if (PyList_Append(d, v) != 0) { 2591 Py_DECREF(v); 2592 Py_DECREF(d); 2593 d = NULL; 2594 break; 2595 } 2596 Py_DECREF(v); 2597 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0); 2598 } 2599 2600 Py_DECREF(oname); 2601 return d; 2602#else 2603 PyObject *oname; 2604 char *name; 2605 PyObject *d, *v; 2606 DIR *dirp; 2607 struct dirent *ep; 2608 int arg_is_unicode = 1; 2609 2610 errno = 0; 2611 /* v is never read, so it does not need to be initialized yet. */ 2612 if (!PyArg_ParseTuple(args, "|U:listdir", &v)) { 2613 arg_is_unicode = 0; 2614 PyErr_Clear(); 2615 } 2616 oname = NULL; 2617 if (!PyArg_ParseTuple(args, "|O&:listdir", PyUnicode_FSConverter, &oname)) 2618 return NULL; 2619 if (oname == NULL) { /* Default arg: "." */ 2620 oname = PyBytes_FromString("."); 2621 } 2622 name = PyBytes_AsString(oname); 2623 Py_BEGIN_ALLOW_THREADS 2624 dirp = opendir(name); 2625 Py_END_ALLOW_THREADS 2626 if (dirp == NULL) { 2627 return posix_error_with_allocated_filename(oname); 2628 } 2629 if ((d = PyList_New(0)) == NULL) { 2630 Py_BEGIN_ALLOW_THREADS 2631 closedir(dirp); 2632 Py_END_ALLOW_THREADS 2633 Py_DECREF(oname); 2634 return NULL; 2635 } 2636 for (;;) { 2637 errno = 0; 2638 Py_BEGIN_ALLOW_THREADS 2639 ep = readdir(dirp); 2640 Py_END_ALLOW_THREADS 2641 if (ep == NULL) { 2642 if (errno == 0) { 2643 break; 2644 } else { 2645 Py_BEGIN_ALLOW_THREADS 2646 closedir(dirp); 2647 Py_END_ALLOW_THREADS 2648 Py_DECREF(d); 2649 return posix_error_with_allocated_filename(oname); 2650 } 2651 } 2652 if (ep->d_name[0] == '.' && 2653 (NAMLEN(ep) == 1 || 2654 (ep->d_name[1] == '.' && NAMLEN(ep) == 2))) 2655 continue; 2656 if (arg_is_unicode) 2657 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep)); 2658 else 2659 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep)); 2660 if (v == NULL) { 2661 Py_CLEAR(d); 2662 break; 2663 } 2664 if (PyList_Append(d, v) != 0) { 2665 Py_DECREF(v); 2666 Py_CLEAR(d); 2667 break; 2668 } 2669 Py_DECREF(v); 2670 } 2671 Py_BEGIN_ALLOW_THREADS 2672 closedir(dirp); 2673 Py_END_ALLOW_THREADS 2674 Py_DECREF(oname); 2675 2676 return d; 2677 2678#endif /* which OS */ 2679} /* end of posix_listdir */ 2680 2681#ifdef MS_WINDOWS 2682/* A helper function for abspath on win32 */ 2683static PyObject * 2684posix__getfullpathname(PyObject *self, PyObject *args) 2685{ 2686 PyObject *opath; 2687 char *path; 2688 char outbuf[MAX_PATH*2]; 2689 char *temp; 2690#ifdef MS_WINDOWS 2691 PyUnicodeObject *po; 2692 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) { 2693 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po); 2694 Py_UNICODE woutbuf[MAX_PATH*2], *woutbufp = woutbuf; 2695 Py_UNICODE *wtemp; 2696 DWORD result; 2697 PyObject *v; 2698 result = GetFullPathNameW(wpath, 2699 sizeof(woutbuf)/sizeof(woutbuf[0]), 2700 woutbuf, &wtemp); 2701 if (result > sizeof(woutbuf)/sizeof(woutbuf[0])) { 2702 woutbufp = malloc(result * sizeof(Py_UNICODE)); 2703 if (!woutbufp) 2704 return PyErr_NoMemory(); 2705 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp); 2706 } 2707 if (result) 2708 v = PyUnicode_FromUnicode(woutbufp, wcslen(woutbufp)); 2709 else 2710 v = win32_error_unicode("GetFullPathNameW", wpath); 2711 if (woutbufp != woutbuf) 2712 free(woutbufp); 2713 return v; 2714 } 2715 /* Drop the argument parsing error as narrow strings 2716 are also valid. */ 2717 PyErr_Clear(); 2718 2719#endif 2720 if (!PyArg_ParseTuple (args, "O&:_getfullpathname", 2721 PyUnicode_FSConverter, &opath)) 2722 return NULL; 2723 path = PyBytes_AsString(opath); 2724 if (!GetFullPathName(path, sizeof(outbuf)/sizeof(outbuf[0]), 2725 outbuf, &temp)) { 2726 win32_error("GetFullPathName", path); 2727 Py_DECREF(opath); 2728 return NULL; 2729 } 2730 Py_DECREF(opath); 2731 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) { 2732 return PyUnicode_Decode(outbuf, strlen(outbuf), 2733 Py_FileSystemDefaultEncoding, NULL); 2734 } 2735 return PyBytes_FromString(outbuf); 2736} /* end of posix__getfullpathname */ 2737 2738/* Grab GetFinalPathNameByHandle dynamically from kernel32 */ 2739static int has_GetFinalPathNameByHandle = 0; 2740static DWORD (CALLBACK *Py_GetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD, 2741 DWORD); 2742static DWORD (CALLBACK *Py_GetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD, 2743 DWORD); 2744static int 2745check_GetFinalPathNameByHandle() 2746{ 2747 HINSTANCE hKernel32; 2748 /* only recheck */ 2749 if (!has_GetFinalPathNameByHandle) 2750 { 2751 hKernel32 = GetModuleHandle("KERNEL32"); 2752 *(FARPROC*)&Py_GetFinalPathNameByHandleA = GetProcAddress(hKernel32, 2753 "GetFinalPathNameByHandleA"); 2754 *(FARPROC*)&Py_GetFinalPathNameByHandleW = GetProcAddress(hKernel32, 2755 "GetFinalPathNameByHandleW"); 2756 has_GetFinalPathNameByHandle = Py_GetFinalPathNameByHandleA && 2757 Py_GetFinalPathNameByHandleW; 2758 } 2759 return has_GetFinalPathNameByHandle; 2760} 2761 2762/* A helper function for samepath on windows */ 2763static PyObject * 2764posix__getfinalpathname(PyObject *self, PyObject *args) 2765{ 2766 HANDLE hFile; 2767 int buf_size; 2768 wchar_t *target_path; 2769 int result_length; 2770 PyObject *result; 2771 wchar_t *path; 2772 2773 if (!PyArg_ParseTuple(args, "u|:_getfinalpathname", &path)) { 2774 return NULL; 2775 } 2776 2777 if(!check_GetFinalPathNameByHandle()) { 2778 /* If the OS doesn't have GetFinalPathNameByHandle, return a 2779 NotImplementedError. */ 2780 return PyErr_Format(PyExc_NotImplementedError, 2781 "GetFinalPathNameByHandle not available on this platform"); 2782 } 2783 2784 hFile = CreateFileW( 2785 path, 2786 0, /* desired access */ 2787 0, /* share mode */ 2788 NULL, /* security attributes */ 2789 OPEN_EXISTING, 2790 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */ 2791 FILE_FLAG_BACKUP_SEMANTICS, 2792 NULL); 2793 2794 if(hFile == INVALID_HANDLE_VALUE) { 2795 return win32_error_unicode("GetFinalPathNamyByHandle", path); 2796 return PyErr_Format(PyExc_RuntimeError, 2797 "Could not get a handle to file."); 2798 } 2799 2800 /* We have a good handle to the target, use it to determine the 2801 target path name. */ 2802 buf_size = Py_GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT); 2803 2804 if(!buf_size) 2805 return win32_error_unicode("GetFinalPathNameByHandle", path); 2806 2807 target_path = (wchar_t *)malloc((buf_size+1)*sizeof(wchar_t)); 2808 if(!target_path) 2809 return PyErr_NoMemory(); 2810 2811 result_length = Py_GetFinalPathNameByHandleW(hFile, target_path, 2812 buf_size, VOLUME_NAME_DOS); 2813 if(!result_length) 2814 return win32_error_unicode("GetFinalPathNamyByHandle", path); 2815 2816 if(!CloseHandle(hFile)) 2817 return win32_error_unicode("GetFinalPathNameByHandle", path); 2818 2819 target_path[result_length] = 0; 2820 result = PyUnicode_FromUnicode(target_path, result_length); 2821 free(target_path); 2822 return result; 2823 2824} /* end of posix__getfinalpathname */ 2825 2826static PyObject * 2827posix__getfileinformation(PyObject *self, PyObject *args) 2828{ 2829 HANDLE hFile; 2830 BY_HANDLE_FILE_INFORMATION info; 2831 int fd; 2832 2833 if (!PyArg_ParseTuple(args, "i:_getfileinformation", &fd)) 2834 return NULL; 2835 2836 if (!_PyVerify_fd(fd)) 2837 return posix_error(); 2838 2839 hFile = (HANDLE)_get_osfhandle(fd); 2840 if (hFile == INVALID_HANDLE_VALUE) 2841 return posix_error(); 2842 2843 if (!GetFileInformationByHandle(hFile, &info)) 2844 return win32_error("_getfileinformation", NULL); 2845 2846 return Py_BuildValue("iii", info.dwVolumeSerialNumber, 2847 info.nFileIndexHigh, 2848 info.nFileIndexLow); 2849} 2850#endif /* MS_WINDOWS */ 2851 2852PyDoc_STRVAR(posix_mkdir__doc__, 2853"mkdir(path [, mode=0777])\n\n\ 2854Create a directory."); 2855 2856static PyObject * 2857posix_mkdir(PyObject *self, PyObject *args) 2858{ 2859 int res; 2860 PyObject *opath; 2861 char *path; 2862 int mode = 0777; 2863 2864#ifdef MS_WINDOWS 2865 PyUnicodeObject *po; 2866 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) { 2867 Py_BEGIN_ALLOW_THREADS 2868 /* PyUnicode_AS_UNICODE OK without thread lock as 2869 it is a simple dereference. */ 2870 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL); 2871 Py_END_ALLOW_THREADS 2872 if (!res) 2873 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po)); 2874 Py_INCREF(Py_None); 2875 return Py_None; 2876 } 2877 /* Drop the argument parsing error as narrow strings 2878 are also valid. */ 2879 PyErr_Clear(); 2880 if (!PyArg_ParseTuple(args, "O&|i:mkdir", 2881 PyUnicode_FSConverter, &opath, &mode)) 2882 return NULL; 2883 path = PyBytes_AsString(opath); 2884 Py_BEGIN_ALLOW_THREADS 2885 /* PyUnicode_AS_UNICODE OK without thread lock as 2886 it is a simple dereference. */ 2887 res = CreateDirectoryA(path, NULL); 2888 Py_END_ALLOW_THREADS 2889 if (!res) { 2890 win32_error("mkdir", path); 2891 Py_DECREF(opath); 2892 return NULL; 2893 } 2894 Py_DECREF(opath); 2895 Py_INCREF(Py_None); 2896 return Py_None; 2897#else 2898 2899 if (!PyArg_ParseTuple(args, "O&|i:mkdir", 2900 PyUnicode_FSConverter, &opath, &mode)) 2901 return NULL; 2902 path = PyBytes_AsString(opath); 2903 Py_BEGIN_ALLOW_THREADS 2904#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__) 2905 res = mkdir(path); 2906#else 2907 res = mkdir(path, mode); 2908#endif 2909 Py_END_ALLOW_THREADS 2910 if (res < 0) 2911 return posix_error_with_allocated_filename(opath); 2912 Py_DECREF(opath); 2913 Py_INCREF(Py_None); 2914 return Py_None; 2915#endif 2916} 2917 2918 2919/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */ 2920#if defined(HAVE_SYS_RESOURCE_H) 2921#include <sys/resource.h> 2922#endif 2923 2924 2925#ifdef HAVE_NICE 2926PyDoc_STRVAR(posix_nice__doc__, 2927"nice(inc) -> new_priority\n\n\ 2928Decrease the priority of process by inc and return the new priority."); 2929 2930static PyObject * 2931posix_nice(PyObject *self, PyObject *args) 2932{ 2933 int increment, value; 2934 2935 if (!PyArg_ParseTuple(args, "i:nice", &increment)) 2936 return NULL; 2937 2938 /* There are two flavours of 'nice': one that returns the new 2939 priority (as required by almost all standards out there) and the 2940 Linux/FreeBSD/BSDI one, which returns '0' on success and advices 2941 the use of getpriority() to get the new priority. 2942 2943 If we are of the nice family that returns the new priority, we 2944 need to clear errno before the call, and check if errno is filled 2945 before calling posix_error() on a returnvalue of -1, because the 2946 -1 may be the actual new priority! */ 2947 2948 errno = 0; 2949 value = nice(increment); 2950#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY) 2951 if (value == 0) 2952 value = getpriority(PRIO_PROCESS, 0); 2953#endif 2954 if (value == -1 && errno != 0) 2955 /* either nice() or getpriority() returned an error */ 2956 return posix_error(); 2957 return PyLong_FromLong((long) value); 2958} 2959#endif /* HAVE_NICE */ 2960 2961PyDoc_STRVAR(posix_rename__doc__, 2962"rename(old, new)\n\n\ 2963Rename a file or directory."); 2964 2965static PyObject * 2966posix_rename(PyObject *self, PyObject *args) 2967{ 2968#ifdef MS_WINDOWS 2969 PyObject *o1, *o2; 2970 char *p1, *p2; 2971 BOOL result; 2972 if (!PyArg_ParseTuple(args, "OO:rename", &o1, &o2)) 2973 goto error; 2974 if (!convert_to_unicode(&o1)) 2975 goto error; 2976 if (!convert_to_unicode(&o2)) { 2977 Py_DECREF(o1); 2978 goto error; 2979 } 2980 Py_BEGIN_ALLOW_THREADS 2981 result = MoveFileW(PyUnicode_AsUnicode(o1), 2982 PyUnicode_AsUnicode(o2)); 2983 Py_END_ALLOW_THREADS 2984 Py_DECREF(o1); 2985 Py_DECREF(o2); 2986 if (!result) 2987 return win32_error("rename", NULL); 2988 Py_INCREF(Py_None); 2989 return Py_None; 2990error: 2991 PyErr_Clear(); 2992 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2)) 2993 return NULL; 2994 Py_BEGIN_ALLOW_THREADS 2995 result = MoveFileA(p1, p2); 2996 Py_END_ALLOW_THREADS 2997 if (!result) 2998 return win32_error("rename", NULL); 2999 Py_INCREF(Py_None); 3000 return Py_None; 3001#else 3002 return posix_2str(args, "O&O&:rename", rename); 3003#endif 3004} 3005 3006 3007PyDoc_STRVAR(posix_rmdir__doc__, 3008"rmdir(path)\n\n\ 3009Remove a directory."); 3010 3011static PyObject * 3012posix_rmdir(PyObject *self, PyObject *args) 3013{ 3014#ifdef MS_WINDOWS 3015 return win32_1str(args, "rmdir", "y:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW); 3016#else 3017 return posix_1str(args, "O&:rmdir", rmdir); 3018#endif 3019} 3020 3021 3022PyDoc_STRVAR(posix_stat__doc__, 3023"stat(path) -> stat result\n\n\ 3024Perform a stat system call on the given path."); 3025 3026static PyObject * 3027posix_stat(PyObject *self, PyObject *args) 3028{ 3029#ifdef MS_WINDOWS 3030 return posix_do_stat(self, args, "O&:stat", STAT, "U:stat", win32_stat_w); 3031#else 3032 return posix_do_stat(self, args, "O&:stat", STAT, NULL, NULL); 3033#endif 3034} 3035 3036 3037#ifdef HAVE_SYSTEM 3038PyDoc_STRVAR(posix_system__doc__, 3039"system(command) -> exit_status\n\n\ 3040Execute the command (a string) in a subshell."); 3041 3042static PyObject * 3043posix_system(PyObject *self, PyObject *args) 3044{ 3045 long sts; 3046#ifdef MS_WINDOWS 3047 wchar_t *command; 3048 if (!PyArg_ParseTuple(args, "u:system", &command)) 3049 return NULL; 3050 3051 Py_BEGIN_ALLOW_THREADS 3052 sts = _wsystem(command); 3053 Py_END_ALLOW_THREADS 3054#else 3055 PyObject *command_obj; 3056 char *command; 3057 if (!PyArg_ParseTuple(args, "O&:system", 3058 PyUnicode_FSConverter, &command_obj)) 3059 return NULL; 3060 3061 command = PyBytes_AsString(command_obj); 3062 Py_BEGIN_ALLOW_THREADS 3063 sts = system(command); 3064 Py_END_ALLOW_THREADS 3065 Py_DECREF(command_obj); 3066#endif 3067 return PyLong_FromLong(sts); 3068} 3069#endif 3070 3071 3072PyDoc_STRVAR(posix_umask__doc__, 3073"umask(new_mask) -> old_mask\n\n\ 3074Set the current numeric umask and return the previous umask."); 3075 3076static PyObject * 3077posix_umask(PyObject *self, PyObject *args) 3078{ 3079 int i; 3080 if (!PyArg_ParseTuple(args, "i:umask", &i)) 3081 return NULL; 3082 i = (int)umask(i); 3083 if (i < 0) 3084 return posix_error(); 3085 return PyLong_FromLong((long)i); 3086} 3087 3088#ifdef MS_WINDOWS 3089 3090/* override the default DeleteFileW behavior so that directory 3091symlinks can be removed with this function, the same as with 3092Unix symlinks */ 3093BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName) 3094{ 3095 WIN32_FILE_ATTRIBUTE_DATA info; 3096 WIN32_FIND_DATAW find_data; 3097 HANDLE find_data_handle; 3098 int is_directory = 0; 3099 int is_link = 0; 3100 3101 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) { 3102 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY; 3103 3104 /* Get WIN32_FIND_DATA structure for the path to determine if 3105 it is a symlink */ 3106 if(is_directory && 3107 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { 3108 find_data_handle = FindFirstFileW(lpFileName, &find_data); 3109 3110 if(find_data_handle != INVALID_HANDLE_VALUE) { 3111 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK; 3112 FindClose(find_data_handle); 3113 } 3114 } 3115 } 3116 3117 if (is_directory && is_link) 3118 return RemoveDirectoryW(lpFileName); 3119 3120 return DeleteFileW(lpFileName); 3121} 3122#endif /* MS_WINDOWS */ 3123 3124PyDoc_STRVAR(posix_unlink__doc__, 3125"unlink(path)\n\n\ 3126Remove a file (same as remove(path))."); 3127 3128PyDoc_STRVAR(posix_remove__doc__, 3129"remove(path)\n\n\ 3130Remove a file (same as unlink(path))."); 3131 3132static PyObject * 3133posix_unlink(PyObject *self, PyObject *args) 3134{ 3135#ifdef MS_WINDOWS 3136 return win32_1str(args, "remove", "y:remove", DeleteFileA, 3137 "U:remove", Py_DeleteFileW); 3138#else 3139 return posix_1str(args, "O&:remove", unlink); 3140#endif 3141} 3142 3143 3144#ifdef HAVE_UNAME 3145PyDoc_STRVAR(posix_uname__doc__, 3146"uname() -> (sysname, nodename, release, version, machine)\n\n\ 3147Return a tuple identifying the current operating system."); 3148 3149static PyObject * 3150posix_uname(PyObject *self, PyObject *noargs) 3151{ 3152 struct utsname u; 3153 int res; 3154 3155 Py_BEGIN_ALLOW_THREADS 3156 res = uname(&u); 3157 Py_END_ALLOW_THREADS 3158 if (res < 0) 3159 return posix_error(); 3160 return Py_BuildValue("(sssss)", 3161 u.sysname, 3162 u.nodename, 3163 u.release, 3164 u.version, 3165 u.machine); 3166} 3167#endif /* HAVE_UNAME */ 3168 3169static int 3170extract_time(PyObject *t, time_t* sec, long* usec) 3171{ 3172 time_t intval; 3173 if (PyFloat_Check(t)) { 3174 double tval = PyFloat_AsDouble(t); 3175 PyObject *intobj = PyNumber_Long(t); 3176 if (!intobj) 3177 return -1; 3178#if SIZEOF_TIME_T > SIZEOF_LONG 3179 intval = PyLong_AsUnsignedLongLongMask(intobj); 3180#else 3181 intval = PyLong_AsLong(intobj); 3182#endif 3183 Py_DECREF(intobj); 3184 if (intval == -1 && PyErr_Occurred()) 3185 return -1; 3186 *sec = intval; 3187 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */ 3188 if (*usec < 0) 3189 /* If rounding gave us a negative number, 3190 truncate. */ 3191 *usec = 0; 3192 return 0; 3193 } 3194#if SIZEOF_TIME_T > SIZEOF_LONG 3195 intval = PyLong_AsUnsignedLongLongMask(t); 3196#else 3197 intval = PyLong_AsLong(t); 3198#endif 3199 if (intval == -1 && PyErr_Occurred()) 3200 return -1; 3201 *sec = intval; 3202 *usec = 0; 3203 return 0; 3204} 3205 3206PyDoc_STRVAR(posix_utime__doc__, 3207"utime(path, (atime, mtime))\n\ 3208utime(path, None)\n\n\ 3209Set the access and modified time of the file to the given values. If the\n\ 3210second form is used, set the access and modified times to the current time."); 3211 3212static PyObject * 3213posix_utime(PyObject *self, PyObject *args) 3214{ 3215#ifdef MS_WINDOWS 3216 PyObject *arg; 3217 PyUnicodeObject *obwpath; 3218 wchar_t *wpath = NULL; 3219 PyObject *oapath; 3220 char *apath; 3221 HANDLE hFile; 3222 time_t atimesec, mtimesec; 3223 long ausec, musec; 3224 FILETIME atime, mtime; 3225 PyObject *result = NULL; 3226 3227 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) { 3228 wpath = PyUnicode_AS_UNICODE(obwpath); 3229 Py_BEGIN_ALLOW_THREADS 3230 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0, 3231 NULL, OPEN_EXISTING, 3232 FILE_FLAG_BACKUP_SEMANTICS, NULL); 3233 Py_END_ALLOW_THREADS 3234 if (hFile == INVALID_HANDLE_VALUE) 3235 return win32_error_unicode("utime", wpath); 3236 } else 3237 /* Drop the argument parsing error as narrow strings 3238 are also valid. */ 3239 PyErr_Clear(); 3240 3241 if (!wpath) { 3242 if (!PyArg_ParseTuple(args, "O&O:utime", 3243 PyUnicode_FSConverter, &oapath, &arg)) 3244 return NULL; 3245 apath = PyBytes_AsString(oapath); 3246 Py_BEGIN_ALLOW_THREADS 3247 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0, 3248 NULL, OPEN_EXISTING, 3249 FILE_FLAG_BACKUP_SEMANTICS, NULL); 3250 Py_END_ALLOW_THREADS 3251 if (hFile == INVALID_HANDLE_VALUE) { 3252 win32_error("utime", apath); 3253 Py_DECREF(oapath); 3254 return NULL; 3255 } 3256 Py_DECREF(oapath); 3257 } 3258 3259 if (arg == Py_None) { 3260 SYSTEMTIME now; 3261 GetSystemTime(&now); 3262 if (!SystemTimeToFileTime(&now, &mtime) || 3263 !SystemTimeToFileTime(&now, &atime)) { 3264 win32_error("utime", NULL); 3265 goto done; 3266 } 3267 } 3268 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) { 3269 PyErr_SetString(PyExc_TypeError, 3270 "utime() arg 2 must be a tuple (atime, mtime)"); 3271 goto done; 3272 } 3273 else { 3274 if (extract_time(PyTuple_GET_ITEM(arg, 0), 3275 &atimesec, &ausec) == -1) 3276 goto done; 3277 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime); 3278 if (extract_time(PyTuple_GET_ITEM(arg, 1), 3279 &mtimesec, &musec) == -1) 3280 goto done; 3281 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime); 3282 } 3283 if (!SetFileTime(hFile, NULL, &atime, &mtime)) { 3284 /* Avoid putting the file name into the error here, 3285 as that may confuse the user into believing that 3286 something is wrong with the file, when it also 3287 could be the time stamp that gives a problem. */ 3288 win32_error("utime", NULL); 3289 goto done; 3290 } 3291 Py_INCREF(Py_None); 3292 result = Py_None; 3293done: 3294 CloseHandle(hFile); 3295 return result; 3296#else /* MS_WINDOWS */ 3297 3298 PyObject *opath; 3299 char *path; 3300 time_t atime, mtime; 3301 long ausec, musec; 3302 int res; 3303 PyObject* arg; 3304 3305#if defined(HAVE_UTIMES) 3306 struct timeval buf[2]; 3307#define ATIME buf[0].tv_sec 3308#define MTIME buf[1].tv_sec 3309#elif defined(HAVE_UTIME_H) 3310/* XXX should define struct utimbuf instead, above */ 3311 struct utimbuf buf; 3312#define ATIME buf.actime 3313#define MTIME buf.modtime 3314#define UTIME_ARG &buf 3315#else /* HAVE_UTIMES */ 3316 time_t buf[2]; 3317#define ATIME buf[0] 3318#define MTIME buf[1] 3319#define UTIME_ARG buf 3320#endif /* HAVE_UTIMES */ 3321 3322 3323 if (!PyArg_ParseTuple(args, "O&O:utime", 3324 PyUnicode_FSConverter, &opath, &arg)) 3325 return NULL; 3326 path = PyBytes_AsString(opath); 3327 if (arg == Py_None) { 3328 /* optional time values not given */ 3329 Py_BEGIN_ALLOW_THREADS 3330 res = utime(path, NULL); 3331 Py_END_ALLOW_THREADS 3332 } 3333 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) { 3334 PyErr_SetString(PyExc_TypeError, 3335 "utime() arg 2 must be a tuple (atime, mtime)"); 3336 Py_DECREF(opath); 3337 return NULL; 3338 } 3339 else { 3340 if (extract_time(PyTuple_GET_ITEM(arg, 0), 3341 &atime, &ausec) == -1) { 3342 Py_DECREF(opath); 3343 return NULL; 3344 } 3345 if (extract_time(PyTuple_GET_ITEM(arg, 1), 3346 &mtime, &musec) == -1) { 3347 Py_DECREF(opath); 3348 return NULL; 3349 } 3350 ATIME = atime; 3351 MTIME = mtime; 3352#ifdef HAVE_UTIMES 3353 buf[0].tv_usec = ausec; 3354 buf[1].tv_usec = musec; 3355 Py_BEGIN_ALLOW_THREADS 3356 res = utimes(path, buf); 3357 Py_END_ALLOW_THREADS 3358#else 3359 Py_BEGIN_ALLOW_THREADS 3360 res = utime(path, UTIME_ARG); 3361 Py_END_ALLOW_THREADS 3362#endif /* HAVE_UTIMES */ 3363 } 3364 if (res < 0) { 3365 return posix_error_with_allocated_filename(opath); 3366 } 3367 Py_DECREF(opath); 3368 Py_INCREF(Py_None); 3369 return Py_None; 3370#undef UTIME_ARG 3371#undef ATIME 3372#undef MTIME 3373#endif /* MS_WINDOWS */ 3374} 3375 3376 3377/* Process operations */ 3378 3379PyDoc_STRVAR(posix__exit__doc__, 3380"_exit(status)\n\n\ 3381Exit to the system with specified status, without normal exit processing."); 3382 3383static PyObject * 3384posix__exit(PyObject *self, PyObject *args) 3385{ 3386 int sts; 3387 if (!PyArg_ParseTuple(args, "i:_exit", &sts)) 3388 return NULL; 3389 _exit(sts); 3390 return NULL; /* Make gcc -Wall happy */ 3391} 3392 3393#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV) 3394static void 3395free_string_array(char **array, Py_ssize_t count) 3396{ 3397 Py_ssize_t i; 3398 for (i = 0; i < count; i++) 3399 PyMem_Free(array[i]); 3400 PyMem_DEL(array); 3401} 3402 3403static 3404int fsconvert_strdup(PyObject *o, char**out) 3405{ 3406 PyObject *bytes; 3407 Py_ssize_t size; 3408 if (!PyUnicode_FSConverter(o, &bytes)) 3409 return 0; 3410 size = PyBytes_GET_SIZE(bytes); 3411 *out = PyMem_Malloc(size+1); 3412 if (!*out) 3413 return 0; 3414 memcpy(*out, PyBytes_AsString(bytes), size+1); 3415 Py_DECREF(bytes); 3416 return 1; 3417} 3418#endif 3419 3420 3421#ifdef HAVE_EXECV 3422PyDoc_STRVAR(posix_execv__doc__, 3423"execv(path, args)\n\n\ 3424Execute an executable path with arguments, replacing current process.\n\ 3425\n\ 3426 path: path of executable file\n\ 3427 args: tuple or list of strings"); 3428 3429static PyObject * 3430posix_execv(PyObject *self, PyObject *args) 3431{ 3432 PyObject *opath; 3433 char *path; 3434 PyObject *argv; 3435 char **argvlist; 3436 Py_ssize_t i, argc; 3437 PyObject *(*getitem)(PyObject *, Py_ssize_t); 3438 3439 /* execv has two arguments: (path, argv), where 3440 argv is a list or tuple of strings. */ 3441 3442 if (!PyArg_ParseTuple(args, "O&O:execv", 3443 PyUnicode_FSConverter, 3444 &opath, &argv)) 3445 return NULL; 3446 path = PyBytes_AsString(opath); 3447 if (PyList_Check(argv)) { 3448 argc = PyList_Size(argv); 3449 getitem = PyList_GetItem; 3450 } 3451 else if (PyTuple_Check(argv)) { 3452 argc = PyTuple_Size(argv); 3453 getitem = PyTuple_GetItem; 3454 } 3455 else { 3456 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list"); 3457 Py_DECREF(opath); 3458 return NULL; 3459 } 3460 if (argc < 1) { 3461 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty"); 3462 Py_DECREF(opath); 3463 return NULL; 3464 } 3465 3466 argvlist = PyMem_NEW(char *, argc+1); 3467 if (argvlist == NULL) { 3468 Py_DECREF(opath); 3469 return PyErr_NoMemory(); 3470 } 3471 for (i = 0; i < argc; i++) { 3472 if (!fsconvert_strdup((*getitem)(argv, i), 3473 &argvlist[i])) { 3474 free_string_array(argvlist, i); 3475 PyErr_SetString(PyExc_TypeError, 3476 "execv() arg 2 must contain only strings"); 3477 Py_DECREF(opath); 3478 return NULL; 3479 3480 } 3481 } 3482 argvlist[argc] = NULL; 3483 3484 execv(path, argvlist); 3485 3486 /* If we get here it's definitely an error */ 3487 3488 free_string_array(argvlist, argc); 3489 Py_DECREF(opath); 3490 return posix_error(); 3491} 3492 3493static char** 3494parse_envlist(PyObject* env, Py_ssize_t *envc_ptr) 3495{ 3496 char **envlist; 3497 Py_ssize_t i, pos, envc; 3498 PyObject *keys=NULL, *vals=NULL; 3499 PyObject *key, *val, *key2, *val2; 3500 char *p, *k, *v; 3501 size_t len; 3502 3503 i = PyMapping_Size(env); 3504 if (i < 0) 3505 return NULL; 3506 envlist = PyMem_NEW(char *, i + 1); 3507 if (envlist == NULL) { 3508 PyErr_NoMemory(); 3509 return NULL; 3510 } 3511 envc = 0; 3512 keys = PyMapping_Keys(env); 3513 vals = PyMapping_Values(env); 3514 if (!keys || !vals) 3515 goto error; 3516 if (!PyList_Check(keys) || !PyList_Check(vals)) { 3517 PyErr_Format(PyExc_TypeError, 3518 "env.keys() or env.values() is not a list"); 3519 goto error; 3520 } 3521 3522 for (pos = 0; pos < i; pos++) { 3523 key = PyList_GetItem(keys, pos); 3524 val = PyList_GetItem(vals, pos); 3525 if (!key || !val) 3526 goto error; 3527 3528 if (PyUnicode_FSConverter(key, &key2) == 0) 3529 goto error; 3530 if (PyUnicode_FSConverter(val, &val2) == 0) { 3531 Py_DECREF(key2); 3532 goto error; 3533 } 3534 3535#if defined(PYOS_OS2) 3536 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */ 3537 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) { 3538#endif 3539 k = PyBytes_AsString(key2); 3540 v = PyBytes_AsString(val2); 3541 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2; 3542 3543 p = PyMem_NEW(char, len); 3544 if (p == NULL) { 3545 PyErr_NoMemory(); 3546 Py_DECREF(key2); 3547 Py_DECREF(val2); 3548 goto error; 3549 } 3550 PyOS_snprintf(p, len, "%s=%s", k, v); 3551 envlist[envc++] = p; 3552 Py_DECREF(key2); 3553 Py_DECREF(val2); 3554#if defined(PYOS_OS2) 3555 } 3556#endif 3557 } 3558 Py_DECREF(vals); 3559 Py_DECREF(keys); 3560 3561 envlist[envc] = 0; 3562 *envc_ptr = envc; 3563 return envlist; 3564 3565error: 3566 Py_XDECREF(keys); 3567 Py_XDECREF(vals); 3568 while (--envc >= 0) 3569 PyMem_DEL(envlist[envc]); 3570 PyMem_DEL(envlist); 3571 return NULL; 3572} 3573 3574PyDoc_STRVAR(posix_execve__doc__, 3575"execve(path, args, env)\n\n\ 3576Execute a path with arguments and environment, replacing current process.\n\ 3577\n\ 3578 path: path of executable file\n\ 3579 args: tuple or list of arguments\n\ 3580 env: dictionary of strings mapping to strings"); 3581 3582static PyObject * 3583posix_execve(PyObject *self, PyObject *args) 3584{ 3585 PyObject *opath; 3586 char *path; 3587 PyObject *argv, *env; 3588 char **argvlist; 3589 char **envlist; 3590 Py_ssize_t i, argc, envc; 3591 PyObject *(*getitem)(PyObject *, Py_ssize_t); 3592 Py_ssize_t lastarg = 0; 3593 3594 /* execve has three arguments: (path, argv, env), where 3595 argv is a list or tuple of strings and env is a dictionary 3596 like posix.environ. */ 3597 3598 if (!PyArg_ParseTuple(args, "O&OO:execve", 3599 PyUnicode_FSConverter, 3600 &opath, &argv, &env)) 3601 return NULL; 3602 path = PyBytes_AsString(opath); 3603 if (PyList_Check(argv)) { 3604 argc = PyList_Size(argv); 3605 getitem = PyList_GetItem; 3606 } 3607 else if (PyTuple_Check(argv)) { 3608 argc = PyTuple_Size(argv); 3609 getitem = PyTuple_GetItem; 3610 } 3611 else { 3612 PyErr_SetString(PyExc_TypeError, 3613 "execve() arg 2 must be a tuple or list"); 3614 goto fail_0; 3615 } 3616 if (!PyMapping_Check(env)) { 3617 PyErr_SetString(PyExc_TypeError, 3618 "execve() arg 3 must be a mapping object"); 3619 goto fail_0; 3620 } 3621 3622 argvlist = PyMem_NEW(char *, argc+1); 3623 if (argvlist == NULL) { 3624 PyErr_NoMemory(); 3625 goto fail_0; 3626 } 3627 for (i = 0; i < argc; i++) { 3628 if (!fsconvert_strdup((*getitem)(argv, i), 3629 &argvlist[i])) 3630 { 3631 lastarg = i; 3632 goto fail_1; 3633 } 3634 } 3635 lastarg = argc; 3636 argvlist[argc] = NULL; 3637 3638 envlist = parse_envlist(env, &envc); 3639 if (envlist == NULL) 3640 goto fail_1; 3641 3642 execve(path, argvlist, envlist); 3643 3644 /* If we get here it's definitely an error */ 3645 3646 (void) posix_error(); 3647 3648 while (--envc >= 0) 3649 PyMem_DEL(envlist[envc]); 3650 PyMem_DEL(envlist); 3651 fail_1: 3652 free_string_array(argvlist, lastarg); 3653 fail_0: 3654 Py_DECREF(opath); 3655 return NULL; 3656} 3657#endif /* HAVE_EXECV */ 3658 3659 3660#ifdef HAVE_SPAWNV 3661PyDoc_STRVAR(posix_spawnv__doc__, 3662"spawnv(mode, path, args)\n\n\ 3663Execute the program 'path' in a new process.\n\ 3664\n\ 3665 mode: mode of process creation\n\ 3666 path: path of executable file\n\ 3667 args: tuple or list of strings"); 3668 3669static PyObject * 3670posix_spawnv(PyObject *self, PyObject *args) 3671{ 3672 PyObject *opath; 3673 char *path; 3674 PyObject *argv; 3675 char **argvlist; 3676 int mode, i; 3677 Py_ssize_t argc; 3678 Py_intptr_t spawnval; 3679 PyObject *(*getitem)(PyObject *, Py_ssize_t); 3680 3681 /* spawnv has three arguments: (mode, path, argv), where 3682 argv is a list or tuple of strings. */ 3683 3684 if (!PyArg_ParseTuple(args, "iO&O:spawnv", &mode, 3685 PyUnicode_FSConverter, 3686 &opath, &argv)) 3687 return NULL; 3688 path = PyBytes_AsString(opath); 3689 if (PyList_Check(argv)) { 3690 argc = PyList_Size(argv); 3691 getitem = PyList_GetItem; 3692 } 3693 else if (PyTuple_Check(argv)) { 3694 argc = PyTuple_Size(argv); 3695 getitem = PyTuple_GetItem; 3696 } 3697 else { 3698 PyErr_SetString(PyExc_TypeError, 3699 "spawnv() arg 2 must be a tuple or list"); 3700 Py_DECREF(opath); 3701 return NULL; 3702 } 3703 3704 argvlist = PyMem_NEW(char *, argc+1); 3705 if (argvlist == NULL) { 3706 Py_DECREF(opath); 3707 return PyErr_NoMemory(); 3708 } 3709 for (i = 0; i < argc; i++) { 3710 if (!fsconvert_strdup((*getitem)(argv, i), 3711 &argvlist[i])) { 3712 free_string_array(argvlist, i); 3713 PyErr_SetString( 3714 PyExc_TypeError, 3715 "spawnv() arg 2 must contain only strings"); 3716 Py_DECREF(opath); 3717 return NULL; 3718 } 3719 } 3720 argvlist[argc] = NULL; 3721 3722#if defined(PYOS_OS2) && defined(PYCC_GCC) 3723 Py_BEGIN_ALLOW_THREADS 3724 spawnval = spawnv(mode, path, argvlist); 3725 Py_END_ALLOW_THREADS 3726#else 3727 if (mode == _OLD_P_OVERLAY) 3728 mode = _P_OVERLAY; 3729 3730 Py_BEGIN_ALLOW_THREADS 3731 spawnval = _spawnv(mode, path, argvlist); 3732 Py_END_ALLOW_THREADS 3733#endif 3734 3735 free_string_array(argvlist, argc); 3736 Py_DECREF(opath); 3737 3738 if (spawnval == -1) 3739 return posix_error(); 3740 else 3741#if SIZEOF_LONG == SIZEOF_VOID_P 3742 return Py_BuildValue("l", (long) spawnval); 3743#else 3744 return Py_BuildValue("L", (PY_LONG_LONG) spawnval); 3745#endif 3746} 3747 3748 3749PyDoc_STRVAR(posix_spawnve__doc__, 3750"spawnve(mode, path, args, env)\n\n\ 3751Execute the program 'path' in a new process.\n\ 3752\n\ 3753 mode: mode of process creation\n\ 3754 path: path of executable file\n\ 3755 args: tuple or list of arguments\n\ 3756 env: dictionary of strings mapping to strings"); 3757 3758static PyObject * 3759posix_spawnve(PyObject *self, PyObject *args) 3760{ 3761 PyObject *opath; 3762 char *path; 3763 PyObject *argv, *env; 3764 char **argvlist; 3765 char **envlist; 3766 PyObject *res = NULL; 3767 int mode; 3768 Py_ssize_t argc, i, envc; 3769 Py_intptr_t spawnval; 3770 PyObject *(*getitem)(PyObject *, Py_ssize_t); 3771 Py_ssize_t lastarg = 0; 3772 3773 /* spawnve has four arguments: (mode, path, argv, env), where 3774 argv is a list or tuple of strings and env is a dictionary 3775 like posix.environ. */ 3776 3777 if (!PyArg_ParseTuple(args, "iO&OO:spawnve", &mode, 3778 PyUnicode_FSConverter, 3779 &opath, &argv, &env)) 3780 return NULL; 3781 path = PyBytes_AsString(opath); 3782 if (PyList_Check(argv)) { 3783 argc = PyList_Size(argv); 3784 getitem = PyList_GetItem; 3785 } 3786 else if (PyTuple_Check(argv)) { 3787 argc = PyTuple_Size(argv); 3788 getitem = PyTuple_GetItem; 3789 } 3790 else { 3791 PyErr_SetString(PyExc_TypeError, 3792 "spawnve() arg 2 must be a tuple or list"); 3793 goto fail_0; 3794 } 3795 if (!PyMapping_Check(env)) { 3796 PyErr_SetString(PyExc_TypeError, 3797 "spawnve() arg 3 must be a mapping object"); 3798 goto fail_0; 3799 } 3800 3801 argvlist = PyMem_NEW(char *, argc+1); 3802 if (argvlist == NULL) { 3803 PyErr_NoMemory(); 3804 goto fail_0; 3805 } 3806 for (i = 0; i < argc; i++) { 3807 if (!fsconvert_strdup((*getitem)(argv, i), 3808 &argvlist[i])) 3809 { 3810 lastarg = i; 3811 goto fail_1; 3812 } 3813 } 3814 lastarg = argc; 3815 argvlist[argc] = NULL; 3816 3817 envlist = parse_envlist(env, &envc); 3818 if (envlist == NULL) 3819 goto fail_1; 3820 3821#if defined(PYOS_OS2) && defined(PYCC_GCC) 3822 Py_BEGIN_ALLOW_THREADS 3823 spawnval = spawnve(mode, path, argvlist, envlist); 3824 Py_END_ALLOW_THREADS 3825#else 3826 if (mode == _OLD_P_OVERLAY) 3827 mode = _P_OVERLAY; 3828 3829 Py_BEGIN_ALLOW_THREADS 3830 spawnval = _spawnve(mode, path, argvlist, envlist); 3831 Py_END_ALLOW_THREADS 3832#endif 3833 3834 if (spawnval == -1) 3835 (void) posix_error(); 3836 else 3837#if SIZEOF_LONG == SIZEOF_VOID_P 3838 res = Py_BuildValue("l", (long) spawnval); 3839#else 3840 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval); 3841#endif 3842 3843 while (--envc >= 0) 3844 PyMem_DEL(envlist[envc]); 3845 PyMem_DEL(envlist); 3846 fail_1: 3847 free_string_array(argvlist, lastarg); 3848 fail_0: 3849 Py_DECREF(opath); 3850 return res; 3851} 3852 3853/* OS/2 supports spawnvp & spawnvpe natively */ 3854#if defined(PYOS_OS2) 3855PyDoc_STRVAR(posix_spawnvp__doc__, 3856"spawnvp(mode, file, args)\n\n\ 3857Execute the program 'file' in a new process, using the environment\n\ 3858search path to find the file.\n\ 3859\n\ 3860 mode: mode of process creation\n\ 3861 file: executable file name\n\ 3862 args: tuple or list of strings"); 3863 3864static PyObject * 3865posix_spawnvp(PyObject *self, PyObject *args) 3866{ 3867 PyObject *opath; 3868 char *path; 3869 PyObject *argv; 3870 char **argvlist; 3871 int mode, i, argc; 3872 Py_intptr_t spawnval; 3873 PyObject *(*getitem)(PyObject *, Py_ssize_t); 3874 3875 /* spawnvp has three arguments: (mode, path, argv), where 3876 argv is a list or tuple of strings. */ 3877 3878 if (!PyArg_ParseTuple(args, "iO&O:spawnvp", &mode, 3879 PyUnicode_FSConverter, 3880 &opath, &argv)) 3881 return NULL; 3882 path = PyBytes_AsString(opath); 3883 if (PyList_Check(argv)) { 3884 argc = PyList_Size(argv); 3885 getitem = PyList_GetItem; 3886 } 3887 else if (PyTuple_Check(argv)) { 3888 argc = PyTuple_Size(argv); 3889 getitem = PyTuple_GetItem; 3890 } 3891 else { 3892 PyErr_SetString(PyExc_TypeError, 3893 "spawnvp() arg 2 must be a tuple or list"); 3894 Py_DECREF(opath); 3895 return NULL; 3896 } 3897 3898 argvlist = PyMem_NEW(char *, argc+1); 3899 if (argvlist == NULL) { 3900 Py_DECREF(opath); 3901 return PyErr_NoMemory(); 3902 } 3903 for (i = 0; i < argc; i++) { 3904 if (!fsconvert_strdup((*getitem)(argv, i), 3905 &argvlist[i])) { 3906 free_string_array(argvlist, i); 3907 PyErr_SetString( 3908 PyExc_TypeError, 3909 "spawnvp() arg 2 must contain only strings"); 3910 Py_DECREF(opath); 3911 return NULL; 3912 } 3913 } 3914 argvlist[argc] = NULL; 3915 3916 Py_BEGIN_ALLOW_THREADS 3917#if defined(PYCC_GCC) 3918 spawnval = spawnvp(mode, path, argvlist); 3919#else 3920 spawnval = _spawnvp(mode, path, argvlist); 3921#endif 3922 Py_END_ALLOW_THREADS 3923 3924 free_string_array(argvlist, argc); 3925 Py_DECREF(opath); 3926 3927 if (spawnval == -1) 3928 return posix_error(); 3929 else 3930 return Py_BuildValue("l", (long) spawnval); 3931} 3932 3933 3934PyDoc_STRVAR(posix_spawnvpe__doc__, 3935"spawnvpe(mode, file, args, env)\n\n\ 3936Execute the program 'file' in a new process, using the environment\n\ 3937search path to find the file.\n\ 3938\n\ 3939 mode: mode of process creation\n\ 3940 file: executable file name\n\ 3941 args: tuple or list of arguments\n\ 3942 env: dictionary of strings mapping to strings"); 3943 3944static PyObject * 3945posix_spawnvpe(PyObject *self, PyObject *args) 3946{ 3947 PyObject *opath 3948 char *path; 3949 PyObject *argv, *env; 3950 char **argvlist; 3951 char **envlist; 3952 PyObject *res=NULL; 3953 int mode; 3954 Py_ssize_t argc, i, envc; 3955 Py_intptr_t spawnval; 3956 PyObject *(*getitem)(PyObject *, Py_ssize_t); 3957 int lastarg = 0; 3958 3959 /* spawnvpe has four arguments: (mode, path, argv, env), where 3960 argv is a list or tuple of strings and env is a dictionary 3961 like posix.environ. */ 3962 3963 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode, 3964 PyUnicode_FSConverter, 3965 &opath, &argv, &env)) 3966 return NULL; 3967 path = PyBytes_AsString(opath); 3968 if (PyList_Check(argv)) { 3969 argc = PyList_Size(argv); 3970 getitem = PyList_GetItem; 3971 } 3972 else if (PyTuple_Check(argv)) { 3973 argc = PyTuple_Size(argv); 3974 getitem = PyTuple_GetItem; 3975 } 3976 else { 3977 PyErr_SetString(PyExc_TypeError, 3978 "spawnvpe() arg 2 must be a tuple or list"); 3979 goto fail_0; 3980 } 3981 if (!PyMapping_Check(env)) { 3982 PyErr_SetString(PyExc_TypeError, 3983 "spawnvpe() arg 3 must be a mapping object"); 3984 goto fail_0; 3985 } 3986 3987 argvlist = PyMem_NEW(char *, argc+1); 3988 if (argvlist == NULL) { 3989 PyErr_NoMemory(); 3990 goto fail_0; 3991 } 3992 for (i = 0; i < argc; i++) { 3993 if (!fsconvert_strdup((*getitem)(argv, i), 3994 &argvlist[i])) 3995 { 3996 lastarg = i; 3997 goto fail_1; 3998 } 3999 } 4000 lastarg = argc; 4001 argvlist[argc] = NULL; 4002 4003 envlist = parse_envlist(env, &envc); 4004 if (envlist == NULL) 4005 goto fail_1; 4006 4007 Py_BEGIN_ALLOW_THREADS 4008#if defined(PYCC_GCC) 4009 spawnval = spawnvpe(mode, path, argvlist, envlist); 4010#else 4011 spawnval = _spawnvpe(mode, path, argvlist, envlist); 4012#endif 4013 Py_END_ALLOW_THREADS 4014 4015 if (spawnval == -1) 4016 (void) posix_error(); 4017 else 4018 res = Py_BuildValue("l", (long) spawnval); 4019 4020 while (--envc >= 0) 4021 PyMem_DEL(envlist[envc]); 4022 PyMem_DEL(envlist); 4023 fail_1: 4024 free_string_array(argvlist, lastarg); 4025 fail_0: 4026 Py_DECREF(opath); 4027 return res; 4028} 4029#endif /* PYOS_OS2 */ 4030#endif /* HAVE_SPAWNV */ 4031 4032 4033#ifdef HAVE_FORK1 4034PyDoc_STRVAR(posix_fork1__doc__, 4035"fork1() -> pid\n\n\ 4036Fork a child process with a single multiplexed (i.e., not bound) thread.\n\ 4037\n\ 4038Return 0 to child process and PID of child to parent process."); 4039 4040static PyObject * 4041posix_fork1(PyObject *self, PyObject *noargs) 4042{ 4043 pid_t pid; 4044 int result = 0; 4045 _PyImport_AcquireLock(); 4046 pid = fork1(); 4047 if (pid == 0) { 4048 /* child: this clobbers and resets the import lock. */ 4049 PyOS_AfterFork(); 4050 } else { 4051 /* parent: release the import lock. */ 4052 result = _PyImport_ReleaseLock(); 4053 } 4054 if (pid == -1) 4055 return posix_error(); 4056 if (result < 0) { 4057 /* Don't clobber the OSError if the fork failed. */ 4058 PyErr_SetString(PyExc_RuntimeError, 4059 "not holding the import lock"); 4060 return NULL; 4061 } 4062 return PyLong_FromPid(pid); 4063} 4064#endif 4065 4066 4067#ifdef HAVE_FORK 4068PyDoc_STRVAR(posix_fork__doc__, 4069"fork() -> pid\n\n\ 4070Fork a child process.\n\ 4071Return 0 to child process and PID of child to parent process."); 4072 4073static PyObject * 4074posix_fork(PyObject *self, PyObject *noargs) 4075{ 4076 pid_t pid; 4077 int result = 0; 4078 _PyImport_AcquireLock(); 4079 pid = fork(); 4080 if (pid == 0) { 4081 /* child: this clobbers and resets the import lock. */ 4082 PyOS_AfterFork(); 4083 } else { 4084 /* parent: release the import lock. */ 4085 result = _PyImport_ReleaseLock(); 4086 } 4087 if (pid == -1) 4088 return posix_error(); 4089 if (result < 0) { 4090 /* Don't clobber the OSError if the fork failed. */ 4091 PyErr_SetString(PyExc_RuntimeError, 4092 "not holding the import lock"); 4093 return NULL; 4094 } 4095 return PyLong_FromPid(pid); 4096} 4097#endif 4098 4099/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */ 4100/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */ 4101#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX) 4102#define DEV_PTY_FILE "/dev/ptc" 4103#define HAVE_DEV_PTMX 4104#else 4105#define DEV_PTY_FILE "/dev/ptmx" 4106#endif 4107 4108#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX) 4109#ifdef HAVE_PTY_H 4110#include <pty.h> 4111#else 4112#ifdef HAVE_LIBUTIL_H 4113#include <libutil.h> 4114#else 4115#ifdef HAVE_UTIL_H 4116#include <util.h> 4117#endif /* HAVE_UTIL_H */ 4118#endif /* HAVE_LIBUTIL_H */ 4119#endif /* HAVE_PTY_H */ 4120#ifdef HAVE_STROPTS_H 4121#include <stropts.h> 4122#endif 4123#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */ 4124 4125#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) 4126PyDoc_STRVAR(posix_openpty__doc__, 4127"openpty() -> (master_fd, slave_fd)\n\n\ 4128Open a pseudo-terminal, returning open fd's for both master and slave end.\n"); 4129 4130static PyObject * 4131posix_openpty(PyObject *self, PyObject *noargs) 4132{ 4133 int master_fd, slave_fd; 4134#ifndef HAVE_OPENPTY 4135 char * slave_name; 4136#endif 4137#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY) 4138 PyOS_sighandler_t sig_saved; 4139#ifdef sun 4140 extern char *ptsname(int fildes); 4141#endif 4142#endif 4143 4144#ifdef HAVE_OPENPTY 4145 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0) 4146 return posix_error(); 4147#elif defined(HAVE__GETPTY) 4148 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0); 4149 if (slave_name == NULL) 4150 return posix_error(); 4151 4152 slave_fd = open(slave_name, O_RDWR); 4153 if (slave_fd < 0) 4154 return posix_error(); 4155#else 4156 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */ 4157 if (master_fd < 0) 4158 return posix_error(); 4159 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL); 4160 /* change permission of slave */ 4161 if (grantpt(master_fd) < 0) { 4162 PyOS_setsig(SIGCHLD, sig_saved); 4163 return posix_error(); 4164 } 4165 /* unlock slave */ 4166 if (unlockpt(master_fd) < 0) { 4167 PyOS_setsig(SIGCHLD, sig_saved); 4168 return posix_error(); 4169 } 4170 PyOS_setsig(SIGCHLD, sig_saved); 4171 slave_name = ptsname(master_fd); /* get name of slave */ 4172 if (slave_name == NULL) 4173 return posix_error(); 4174 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */ 4175 if (slave_fd < 0) 4176 return posix_error(); 4177#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC) 4178 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */ 4179 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */ 4180#ifndef __hpux 4181 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */ 4182#endif /* __hpux */ 4183#endif /* HAVE_CYGWIN */ 4184#endif /* HAVE_OPENPTY */ 4185 4186 return Py_BuildValue("(ii)", master_fd, slave_fd); 4187 4188} 4189#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */ 4190 4191#ifdef HAVE_FORKPTY 4192PyDoc_STRVAR(posix_forkpty__doc__, 4193"forkpty() -> (pid, master_fd)\n\n\ 4194Fork a new process with a new pseudo-terminal as controlling tty.\n\n\ 4195Like fork(), return 0 as pid to child process, and PID of child to parent.\n\ 4196To both, return fd of newly opened pseudo-terminal.\n"); 4197 4198static PyObject * 4199posix_forkpty(PyObject *self, PyObject *noargs) 4200{ 4201 int master_fd = -1, result = 0; 4202 pid_t pid; 4203 4204 _PyImport_AcquireLock(); 4205 pid = forkpty(&master_fd, NULL, NULL, NULL); 4206 if (pid == 0) { 4207 /* child: this clobbers and resets the import lock. */ 4208 PyOS_AfterFork(); 4209 } else { 4210 /* parent: release the import lock. */ 4211 result = _PyImport_ReleaseLock(); 4212 } 4213 if (pid == -1) 4214 return posix_error(); 4215 if (result < 0) { 4216 /* Don't clobber the OSError if the fork failed. */ 4217 PyErr_SetString(PyExc_RuntimeError, 4218 "not holding the import lock"); 4219 return NULL; 4220 } 4221 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd); 4222} 4223#endif 4224 4225#ifdef HAVE_GETEGID 4226PyDoc_STRVAR(posix_getegid__doc__, 4227"getegid() -> egid\n\n\ 4228Return the current process's effective group id."); 4229 4230static PyObject * 4231posix_getegid(PyObject *self, PyObject *noargs) 4232{ 4233 return PyLong_FromLong((long)getegid()); 4234} 4235#endif 4236 4237 4238#ifdef HAVE_GETEUID 4239PyDoc_STRVAR(posix_geteuid__doc__, 4240"geteuid() -> euid\n\n\ 4241Return the current process's effective user id."); 4242 4243static PyObject * 4244posix_geteuid(PyObject *self, PyObject *noargs) 4245{ 4246 return PyLong_FromLong((long)geteuid()); 4247} 4248#endif 4249 4250 4251#ifdef HAVE_GETGID 4252PyDoc_STRVAR(posix_getgid__doc__, 4253"getgid() -> gid\n\n\ 4254Return the current process's group id."); 4255 4256static PyObject * 4257posix_getgid(PyObject *self, PyObject *noargs) 4258{ 4259 return PyLong_FromLong((long)getgid()); 4260} 4261#endif 4262 4263 4264PyDoc_STRVAR(posix_getpid__doc__, 4265"getpid() -> pid\n\n\ 4266Return the current process id"); 4267 4268static PyObject * 4269posix_getpid(PyObject *self, PyObject *noargs) 4270{ 4271 return PyLong_FromPid(getpid()); 4272} 4273 4274 4275#ifdef HAVE_GETGROUPS 4276PyDoc_STRVAR(posix_getgroups__doc__, 4277"getgroups() -> list of group IDs\n\n\ 4278Return list of supplemental group IDs for the process."); 4279 4280static PyObject * 4281posix_getgroups(PyObject *self, PyObject *noargs) 4282{ 4283 PyObject *result = NULL; 4284 4285#ifdef NGROUPS_MAX 4286#define MAX_GROUPS NGROUPS_MAX 4287#else 4288 /* defined to be 16 on Solaris7, so this should be a small number */ 4289#define MAX_GROUPS 64 4290#endif 4291 gid_t grouplist[MAX_GROUPS]; 4292 4293 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results 4294 * This is a helper variable to store the intermediate result when 4295 * that happens. 4296 * 4297 * To keep the code readable the OSX behaviour is unconditional, 4298 * according to the POSIX spec this should be safe on all unix-y 4299 * systems. 4300 */ 4301 gid_t* alt_grouplist = grouplist; 4302 int n; 4303 4304 n = getgroups(MAX_GROUPS, grouplist); 4305 if (n < 0) { 4306 if (errno == EINVAL) { 4307 n = getgroups(0, NULL); 4308 if (n == -1) { 4309 return posix_error(); 4310 } 4311 if (n == 0) { 4312 /* Avoid malloc(0) */ 4313 alt_grouplist = grouplist; 4314 } else { 4315 alt_grouplist = PyMem_Malloc(n * sizeof(gid_t)); 4316 if (alt_grouplist == NULL) { 4317 errno = EINVAL; 4318 return posix_error(); 4319 } 4320 n = getgroups(n, alt_grouplist); 4321 if (n == -1) { 4322 PyMem_Free(alt_grouplist); 4323 return posix_error(); 4324 } 4325 } 4326 } else { 4327 return posix_error(); 4328 } 4329 } 4330 result = PyList_New(n); 4331 if (result != NULL) { 4332 int i; 4333 for (i = 0; i < n; ++i) { 4334 PyObject *o = PyLong_FromLong((long)alt_grouplist[i]); 4335 if (o == NULL) { 4336 Py_DECREF(result); 4337 result = NULL; 4338 break; 4339 } 4340 PyList_SET_ITEM(result, i, o); 4341 } 4342 } 4343 4344 if (alt_grouplist != grouplist) { 4345 PyMem_Free(alt_grouplist); 4346 } 4347 4348 return result; 4349} 4350#endif 4351 4352#ifdef HAVE_INITGROUPS 4353PyDoc_STRVAR(posix_initgroups__doc__, 4354"initgroups(username, gid) -> None\n\n\ 4355Call the system initgroups() to initialize the group access list with all of\n\ 4356the groups of which the specified username is a member, plus the specified\n\ 4357group id."); 4358 4359static PyObject * 4360posix_initgroups(PyObject *self, PyObject *args) 4361{ 4362 PyObject *oname; 4363 char *username; 4364 int res; 4365 long gid; 4366 4367 if (!PyArg_ParseTuple(args, "O&l:initgroups", 4368 PyUnicode_FSConverter, &oname, &gid)) 4369 return NULL; 4370 username = PyBytes_AS_STRING(oname); 4371 4372 res = initgroups(username, (gid_t) gid); 4373 Py_DECREF(oname); 4374 if (res == -1) 4375 return PyErr_SetFromErrno(PyExc_OSError); 4376 4377 Py_INCREF(Py_None); 4378 return Py_None; 4379} 4380#endif 4381 4382#ifdef HAVE_GETPGID 4383PyDoc_STRVAR(posix_getpgid__doc__, 4384"getpgid(pid) -> pgid\n\n\ 4385Call the system call getpgid()."); 4386 4387static PyObject * 4388posix_getpgid(PyObject *self, PyObject *args) 4389{ 4390 pid_t pid, pgid; 4391 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getpgid", &pid)) 4392 return NULL; 4393 pgid = getpgid(pid); 4394 if (pgid < 0) 4395 return posix_error(); 4396 return PyLong_FromPid(pgid); 4397} 4398#endif /* HAVE_GETPGID */ 4399 4400 4401#ifdef HAVE_GETPGRP 4402PyDoc_STRVAR(posix_getpgrp__doc__, 4403"getpgrp() -> pgrp\n\n\ 4404Return the current process group id."); 4405 4406static PyObject * 4407posix_getpgrp(PyObject *self, PyObject *noargs) 4408{ 4409#ifdef GETPGRP_HAVE_ARG 4410 return PyLong_FromPid(getpgrp(0)); 4411#else /* GETPGRP_HAVE_ARG */ 4412 return PyLong_FromPid(getpgrp()); 4413#endif /* GETPGRP_HAVE_ARG */ 4414} 4415#endif /* HAVE_GETPGRP */ 4416 4417 4418#ifdef HAVE_SETPGRP 4419PyDoc_STRVAR(posix_setpgrp__doc__, 4420"setpgrp()\n\n\ 4421Make this process the process group leader."); 4422 4423static PyObject * 4424posix_setpgrp(PyObject *self, PyObject *noargs) 4425{ 4426#ifdef SETPGRP_HAVE_ARG 4427 if (setpgrp(0, 0) < 0) 4428#else /* SETPGRP_HAVE_ARG */ 4429 if (setpgrp() < 0) 4430#endif /* SETPGRP_HAVE_ARG */ 4431 return posix_error(); 4432 Py_INCREF(Py_None); 4433 return Py_None; 4434} 4435 4436#endif /* HAVE_SETPGRP */ 4437 4438#ifdef HAVE_GETPPID 4439 4440#ifdef MS_WINDOWS 4441#include <tlhelp32.h> 4442 4443static PyObject* 4444win32_getppid() 4445{ 4446 HANDLE snapshot; 4447 pid_t mypid; 4448 PyObject* result = NULL; 4449 BOOL have_record; 4450 PROCESSENTRY32 pe; 4451 4452 mypid = getpid(); /* This function never fails */ 4453 4454 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 4455 if (snapshot == INVALID_HANDLE_VALUE) 4456 return PyErr_SetFromWindowsErr(GetLastError()); 4457 4458 pe.dwSize = sizeof(pe); 4459 have_record = Process32First(snapshot, &pe); 4460 while (have_record) { 4461 if (mypid == (pid_t)pe.th32ProcessID) { 4462 /* We could cache the ulong value in a static variable. */ 4463 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID); 4464 break; 4465 } 4466 4467 have_record = Process32Next(snapshot, &pe); 4468 } 4469 4470 /* If our loop exits and our pid was not found (result will be NULL) 4471 * then GetLastError will return ERROR_NO_MORE_FILES. This is an 4472 * error anyway, so let's raise it. */ 4473 if (!result) 4474 result = PyErr_SetFromWindowsErr(GetLastError()); 4475 4476 CloseHandle(snapshot); 4477 4478 return result; 4479} 4480#endif /*MS_WINDOWS*/ 4481 4482PyDoc_STRVAR(posix_getppid__doc__, 4483"getppid() -> ppid\n\n\ 4484Return the parent's process id. If the parent process has already exited,\n\ 4485Windows machines will still return its id; others systems will return the id\n\ 4486of the 'init' process (1)."); 4487 4488static PyObject * 4489posix_getppid(PyObject *self, PyObject *noargs) 4490{ 4491#ifdef MS_WINDOWS 4492 return win32_getppid(); 4493#else 4494 return PyLong_FromPid(getppid()); 4495#endif 4496} 4497#endif /* HAVE_GETPPID */ 4498 4499 4500#ifdef HAVE_GETLOGIN 4501PyDoc_STRVAR(posix_getlogin__doc__, 4502"getlogin() -> string\n\n\ 4503Return the actual login name."); 4504 4505static PyObject * 4506posix_getlogin(PyObject *self, PyObject *noargs) 4507{ 4508 PyObject *result = NULL; 4509#ifdef MS_WINDOWS 4510 wchar_t user_name[UNLEN + 1]; 4511 DWORD num_chars = sizeof(user_name)/sizeof(user_name[0]); 4512 4513 if (GetUserNameW(user_name, &num_chars)) { 4514 /* num_chars is the number of unicode chars plus null terminator */ 4515 result = PyUnicode_FromWideChar(user_name, num_chars - 1); 4516 } 4517 else 4518 result = PyErr_SetFromWindowsErr(GetLastError()); 4519#else 4520 char *name; 4521 int old_errno = errno; 4522 4523 errno = 0; 4524 name = getlogin(); 4525 if (name == NULL) { 4526 if (errno) 4527 posix_error(); 4528 else 4529 PyErr_SetString(PyExc_OSError, "unable to determine login name"); 4530 } 4531 else 4532 result = PyUnicode_DecodeFSDefault(name); 4533 errno = old_errno; 4534#endif 4535 return result; 4536} 4537#endif /* HAVE_GETLOGIN */ 4538 4539#ifdef HAVE_GETUID 4540PyDoc_STRVAR(posix_getuid__doc__, 4541"getuid() -> uid\n\n\ 4542Return the current process's user id."); 4543 4544static PyObject * 4545posix_getuid(PyObject *self, PyObject *noargs) 4546{ 4547 return PyLong_FromLong((long)getuid()); 4548} 4549#endif 4550 4551 4552#ifdef HAVE_KILL 4553PyDoc_STRVAR(posix_kill__doc__, 4554"kill(pid, sig)\n\n\ 4555Kill a process with a signal."); 4556 4557static PyObject * 4558posix_kill(PyObject *self, PyObject *args) 4559{ 4560 pid_t pid; 4561 int sig; 4562 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:kill", &pid, &sig)) 4563 return NULL; 4564#if defined(PYOS_OS2) && !defined(PYCC_GCC) 4565 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) { 4566 APIRET rc; 4567 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR) 4568 return os2_error(rc); 4569 4570 } else if (sig == XCPT_SIGNAL_KILLPROC) { 4571 APIRET rc; 4572 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR) 4573 return os2_error(rc); 4574 4575 } else 4576 return NULL; /* Unrecognized Signal Requested */ 4577#else 4578 if (kill(pid, sig) == -1) 4579 return posix_error(); 4580#endif 4581 Py_INCREF(Py_None); 4582 return Py_None; 4583} 4584#endif 4585 4586#ifdef HAVE_KILLPG 4587PyDoc_STRVAR(posix_killpg__doc__, 4588"killpg(pgid, sig)\n\n\ 4589Kill a process group with a signal."); 4590 4591static PyObject * 4592posix_killpg(PyObject *self, PyObject *args) 4593{ 4594 int sig; 4595 pid_t pgid; 4596 /* XXX some man pages make the `pgid` parameter an int, others 4597 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should 4598 take the same type. Moreover, pid_t is always at least as wide as 4599 int (else compilation of this module fails), which is safe. */ 4600 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:killpg", &pgid, &sig)) 4601 return NULL; 4602 if (killpg(pgid, sig) == -1) 4603 return posix_error(); 4604 Py_INCREF(Py_None); 4605 return Py_None; 4606} 4607#endif 4608 4609#ifdef MS_WINDOWS 4610PyDoc_STRVAR(win32_kill__doc__, 4611"kill(pid, sig)\n\n\ 4612Kill a process with a signal."); 4613 4614static PyObject * 4615win32_kill(PyObject *self, PyObject *args) 4616{ 4617 PyObject *result; 4618 DWORD pid, sig, err; 4619 HANDLE handle; 4620 4621 if (!PyArg_ParseTuple(args, "kk:kill", &pid, &sig)) 4622 return NULL; 4623 4624 /* Console processes which share a common console can be sent CTRL+C or 4625 CTRL+BREAK events, provided they handle said events. */ 4626 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) { 4627 if (GenerateConsoleCtrlEvent(sig, pid) == 0) { 4628 err = GetLastError(); 4629 PyErr_SetFromWindowsErr(err); 4630 } 4631 else 4632 Py_RETURN_NONE; 4633 } 4634 4635 /* If the signal is outside of what GenerateConsoleCtrlEvent can use, 4636 attempt to open and terminate the process. */ 4637 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid); 4638 if (handle == NULL) { 4639 err = GetLastError(); 4640 return PyErr_SetFromWindowsErr(err); 4641 } 4642 4643 if (TerminateProcess(handle, sig) == 0) { 4644 err = GetLastError(); 4645 result = PyErr_SetFromWindowsErr(err); 4646 } else { 4647 Py_INCREF(Py_None); 4648 result = Py_None; 4649 } 4650 4651 CloseHandle(handle); 4652 return result; 4653} 4654#endif /* MS_WINDOWS */ 4655 4656#ifdef HAVE_PLOCK 4657 4658#ifdef HAVE_SYS_LOCK_H 4659#include <sys/lock.h> 4660#endif 4661 4662PyDoc_STRVAR(posix_plock__doc__, 4663"plock(op)\n\n\ 4664Lock program segments into memory."); 4665 4666static PyObject * 4667posix_plock(PyObject *self, PyObject *args) 4668{ 4669 int op; 4670 if (!PyArg_ParseTuple(args, "i:plock", &op)) 4671 return NULL; 4672 if (plock(op) == -1) 4673 return posix_error(); 4674 Py_INCREF(Py_None); 4675 return Py_None; 4676} 4677#endif 4678 4679#ifdef HAVE_SETUID 4680PyDoc_STRVAR(posix_setuid__doc__, 4681"setuid(uid)\n\n\ 4682Set the current process's user id."); 4683 4684static PyObject * 4685posix_setuid(PyObject *self, PyObject *args) 4686{ 4687 long uid_arg; 4688 uid_t uid; 4689 if (!PyArg_ParseTuple(args, "l:setuid", &uid_arg)) 4690 return NULL; 4691 uid = uid_arg; 4692 if (uid != uid_arg) { 4693 PyErr_SetString(PyExc_OverflowError, "user id too big"); 4694 return NULL; 4695 } 4696 if (setuid(uid) < 0) 4697 return posix_error(); 4698 Py_INCREF(Py_None); 4699 return Py_None; 4700} 4701#endif /* HAVE_SETUID */ 4702 4703 4704#ifdef HAVE_SETEUID 4705PyDoc_STRVAR(posix_seteuid__doc__, 4706"seteuid(uid)\n\n\ 4707Set the current process's effective user id."); 4708 4709static PyObject * 4710posix_seteuid (PyObject *self, PyObject *args) 4711{ 4712 long euid_arg; 4713 uid_t euid; 4714 if (!PyArg_ParseTuple(args, "l", &euid_arg)) 4715 return NULL; 4716 euid = euid_arg; 4717 if (euid != euid_arg) { 4718 PyErr_SetString(PyExc_OverflowError, "user id too big"); 4719 return NULL; 4720 } 4721 if (seteuid(euid) < 0) { 4722 return posix_error(); 4723 } else { 4724 Py_INCREF(Py_None); 4725 return Py_None; 4726 } 4727} 4728#endif /* HAVE_SETEUID */ 4729 4730#ifdef HAVE_SETEGID 4731PyDoc_STRVAR(posix_setegid__doc__, 4732"setegid(gid)\n\n\ 4733Set the current process's effective group id."); 4734 4735static PyObject * 4736posix_setegid (PyObject *self, PyObject *args) 4737{ 4738 long egid_arg; 4739 gid_t egid; 4740 if (!PyArg_ParseTuple(args, "l", &egid_arg)) 4741 return NULL; 4742 egid = egid_arg; 4743 if (egid != egid_arg) { 4744 PyErr_SetString(PyExc_OverflowError, "group id too big"); 4745 return NULL; 4746 } 4747 if (setegid(egid) < 0) { 4748 return posix_error(); 4749 } else { 4750 Py_INCREF(Py_None); 4751 return Py_None; 4752 } 4753} 4754#endif /* HAVE_SETEGID */ 4755 4756#ifdef HAVE_SETREUID 4757PyDoc_STRVAR(posix_setreuid__doc__, 4758"setreuid(ruid, euid)\n\n\ 4759Set the current process's real and effective user ids."); 4760 4761static PyObject * 4762posix_setreuid (PyObject *self, PyObject *args) 4763{ 4764 long ruid_arg, euid_arg; 4765 uid_t ruid, euid; 4766 if (!PyArg_ParseTuple(args, "ll", &ruid_arg, &euid_arg)) 4767 return NULL; 4768 if (ruid_arg == -1) 4769 ruid = (uid_t)-1; /* let the compiler choose how -1 fits */ 4770 else 4771 ruid = ruid_arg; /* otherwise, assign from our long */ 4772 if (euid_arg == -1) 4773 euid = (uid_t)-1; 4774 else 4775 euid = euid_arg; 4776 if ((euid_arg != -1 && euid != euid_arg) || 4777 (ruid_arg != -1 && ruid != ruid_arg)) { 4778 PyErr_SetString(PyExc_OverflowError, "user id too big"); 4779 return NULL; 4780 } 4781 if (setreuid(ruid, euid) < 0) { 4782 return posix_error(); 4783 } else { 4784 Py_INCREF(Py_None); 4785 return Py_None; 4786 } 4787} 4788#endif /* HAVE_SETREUID */ 4789 4790#ifdef HAVE_SETREGID 4791PyDoc_STRVAR(posix_setregid__doc__, 4792"setregid(rgid, egid)\n\n\ 4793Set the current process's real and effective group ids."); 4794 4795static PyObject * 4796posix_setregid (PyObject *self, PyObject *args) 4797{ 4798 long rgid_arg, egid_arg; 4799 gid_t rgid, egid; 4800 if (!PyArg_ParseTuple(args, "ll", &rgid_arg, &egid_arg)) 4801 return NULL; 4802 if (rgid_arg == -1) 4803 rgid = (gid_t)-1; /* let the compiler choose how -1 fits */ 4804 else 4805 rgid = rgid_arg; /* otherwise, assign from our long */ 4806 if (egid_arg == -1) 4807 egid = (gid_t)-1; 4808 else 4809 egid = egid_arg; 4810 if ((egid_arg != -1 && egid != egid_arg) || 4811 (rgid_arg != -1 && rgid != rgid_arg)) { 4812 PyErr_SetString(PyExc_OverflowError, "group id too big"); 4813 return NULL; 4814 } 4815 if (setregid(rgid, egid) < 0) { 4816 return posix_error(); 4817 } else { 4818 Py_INCREF(Py_None); 4819 return Py_None; 4820 } 4821} 4822#endif /* HAVE_SETREGID */ 4823 4824#ifdef HAVE_SETGID 4825PyDoc_STRVAR(posix_setgid__doc__, 4826"setgid(gid)\n\n\ 4827Set the current process's group id."); 4828 4829static PyObject * 4830posix_setgid(PyObject *self, PyObject *args) 4831{ 4832 long gid_arg; 4833 gid_t gid; 4834 if (!PyArg_ParseTuple(args, "l:setgid", &gid_arg)) 4835 return NULL; 4836 gid = gid_arg; 4837 if (gid != gid_arg) { 4838 PyErr_SetString(PyExc_OverflowError, "group id too big"); 4839 return NULL; 4840 } 4841 if (setgid(gid) < 0) 4842 return posix_error(); 4843 Py_INCREF(Py_None); 4844 return Py_None; 4845} 4846#endif /* HAVE_SETGID */ 4847 4848#ifdef HAVE_SETGROUPS 4849PyDoc_STRVAR(posix_setgroups__doc__, 4850"setgroups(list)\n\n\ 4851Set the groups of the current process to list."); 4852 4853static PyObject * 4854posix_setgroups(PyObject *self, PyObject *groups) 4855{ 4856 int i, len; 4857 gid_t grouplist[MAX_GROUPS]; 4858 4859 if (!PySequence_Check(groups)) { 4860 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence"); 4861 return NULL; 4862 } 4863 len = PySequence_Size(groups); 4864 if (len > MAX_GROUPS) { 4865 PyErr_SetString(PyExc_ValueError, "too many groups"); 4866 return NULL; 4867 } 4868 for(i = 0; i < len; i++) { 4869 PyObject *elem; 4870 elem = PySequence_GetItem(groups, i); 4871 if (!elem) 4872 return NULL; 4873 if (!PyLong_Check(elem)) { 4874 PyErr_SetString(PyExc_TypeError, 4875 "groups must be integers"); 4876 Py_DECREF(elem); 4877 return NULL; 4878 } else { 4879 unsigned long x = PyLong_AsUnsignedLong(elem); 4880 if (PyErr_Occurred()) { 4881 PyErr_SetString(PyExc_TypeError, 4882 "group id too big"); 4883 Py_DECREF(elem); 4884 return NULL; 4885 } 4886 grouplist[i] = x; 4887 /* read back the value to see if it fitted in gid_t */ 4888 if (grouplist[i] != x) { 4889 PyErr_SetString(PyExc_TypeError, 4890 "group id too big"); 4891 Py_DECREF(elem); 4892 return NULL; 4893 } 4894 } 4895 Py_DECREF(elem); 4896 } 4897 4898 if (setgroups(len, grouplist) < 0) 4899 return posix_error(); 4900 Py_INCREF(Py_None); 4901 return Py_None; 4902} 4903#endif /* HAVE_SETGROUPS */ 4904 4905#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4) 4906static PyObject * 4907wait_helper(pid_t pid, int status, struct rusage *ru) 4908{ 4909 PyObject *result; 4910 static PyObject *struct_rusage; 4911 4912 if (pid == -1) 4913 return posix_error(); 4914 4915 if (struct_rusage == NULL) { 4916 PyObject *m = PyImport_ImportModuleNoBlock("resource"); 4917 if (m == NULL) 4918 return NULL; 4919 struct_rusage = PyObject_GetAttrString(m, "struct_rusage"); 4920 Py_DECREF(m); 4921 if (struct_rusage == NULL) 4922 return NULL; 4923 } 4924 4925 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */ 4926 result = PyStructSequence_New((PyTypeObject*) struct_rusage); 4927 if (!result) 4928 return NULL; 4929 4930#ifndef doubletime 4931#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001) 4932#endif 4933 4934 PyStructSequence_SET_ITEM(result, 0, 4935 PyFloat_FromDouble(doubletime(ru->ru_utime))); 4936 PyStructSequence_SET_ITEM(result, 1, 4937 PyFloat_FromDouble(doubletime(ru->ru_stime))); 4938#define SET_INT(result, index, value)\ 4939 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value)) 4940 SET_INT(result, 2, ru->ru_maxrss); 4941 SET_INT(result, 3, ru->ru_ixrss); 4942 SET_INT(result, 4, ru->ru_idrss); 4943 SET_INT(result, 5, ru->ru_isrss); 4944 SET_INT(result, 6, ru->ru_minflt); 4945 SET_INT(result, 7, ru->ru_majflt); 4946 SET_INT(result, 8, ru->ru_nswap); 4947 SET_INT(result, 9, ru->ru_inblock); 4948 SET_INT(result, 10, ru->ru_oublock); 4949 SET_INT(result, 11, ru->ru_msgsnd); 4950 SET_INT(result, 12, ru->ru_msgrcv); 4951 SET_INT(result, 13, ru->ru_nsignals); 4952 SET_INT(result, 14, ru->ru_nvcsw); 4953 SET_INT(result, 15, ru->ru_nivcsw); 4954#undef SET_INT 4955 4956 if (PyErr_Occurred()) { 4957 Py_DECREF(result); 4958 return NULL; 4959 } 4960 4961 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result); 4962} 4963#endif /* HAVE_WAIT3 || HAVE_WAIT4 */ 4964 4965#ifdef HAVE_WAIT3 4966PyDoc_STRVAR(posix_wait3__doc__, 4967"wait3(options) -> (pid, status, rusage)\n\n\ 4968Wait for completion of a child process."); 4969 4970static PyObject * 4971posix_wait3(PyObject *self, PyObject *args) 4972{ 4973 pid_t pid; 4974 int options; 4975 struct rusage ru; 4976 WAIT_TYPE status; 4977 WAIT_STATUS_INT(status) = 0; 4978 4979 if (!PyArg_ParseTuple(args, "i:wait3", &options)) 4980 return NULL; 4981 4982 Py_BEGIN_ALLOW_THREADS 4983 pid = wait3(&status, options, &ru); 4984 Py_END_ALLOW_THREADS 4985 4986 return wait_helper(pid, WAIT_STATUS_INT(status), &ru); 4987} 4988#endif /* HAVE_WAIT3 */ 4989 4990#ifdef HAVE_WAIT4 4991PyDoc_STRVAR(posix_wait4__doc__, 4992"wait4(pid, options) -> (pid, status, rusage)\n\n\ 4993Wait for completion of a given child process."); 4994 4995static PyObject * 4996posix_wait4(PyObject *self, PyObject *args) 4997{ 4998 pid_t pid; 4999 int options; 5000 struct rusage ru; 5001 WAIT_TYPE status; 5002 WAIT_STATUS_INT(status) = 0; 5003 5004 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options)) 5005 return NULL; 5006 5007 Py_BEGIN_ALLOW_THREADS 5008 pid = wait4(pid, &status, options, &ru); 5009 Py_END_ALLOW_THREADS 5010 5011 return wait_helper(pid, WAIT_STATUS_INT(status), &ru); 5012} 5013#endif /* HAVE_WAIT4 */ 5014 5015#ifdef HAVE_WAITPID 5016PyDoc_STRVAR(posix_waitpid__doc__, 5017"waitpid(pid, options) -> (pid, status)\n\n\ 5018Wait for completion of a given child process."); 5019 5020static PyObject * 5021posix_waitpid(PyObject *self, PyObject *args) 5022{ 5023 pid_t pid; 5024 int options; 5025 WAIT_TYPE status; 5026 WAIT_STATUS_INT(status) = 0; 5027 5028 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options)) 5029 return NULL; 5030 Py_BEGIN_ALLOW_THREADS 5031 pid = waitpid(pid, &status, options); 5032 Py_END_ALLOW_THREADS 5033 if (pid == -1) 5034 return posix_error(); 5035 5036 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status)); 5037} 5038 5039#elif defined(HAVE_CWAIT) 5040 5041/* MS C has a variant of waitpid() that's usable for most purposes. */ 5042PyDoc_STRVAR(posix_waitpid__doc__, 5043"waitpid(pid, options) -> (pid, status << 8)\n\n" 5044"Wait for completion of a given process. options is ignored on Windows."); 5045 5046static PyObject * 5047posix_waitpid(PyObject *self, PyObject *args) 5048{ 5049 Py_intptr_t pid; 5050 int status, options; 5051 5052 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:waitpid", &pid, &options)) 5053 return NULL; 5054 Py_BEGIN_ALLOW_THREADS 5055 pid = _cwait(&status, pid, options); 5056 Py_END_ALLOW_THREADS 5057 if (pid == -1) 5058 return posix_error(); 5059 5060 /* shift the status left a byte so this is more like the POSIX waitpid */ 5061 return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8); 5062} 5063#endif /* HAVE_WAITPID || HAVE_CWAIT */ 5064 5065#ifdef HAVE_WAIT 5066PyDoc_STRVAR(posix_wait__doc__, 5067"wait() -> (pid, status)\n\n\ 5068Wait for completion of a child process."); 5069 5070static PyObject * 5071posix_wait(PyObject *self, PyObject *noargs) 5072{ 5073 pid_t pid; 5074 WAIT_TYPE status; 5075 WAIT_STATUS_INT(status) = 0; 5076 5077 Py_BEGIN_ALLOW_THREADS 5078 pid = wait(&status); 5079 Py_END_ALLOW_THREADS 5080 if (pid == -1) 5081 return posix_error(); 5082 5083 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status)); 5084} 5085#endif 5086 5087 5088PyDoc_STRVAR(posix_lstat__doc__, 5089"lstat(path) -> stat result\n\n\ 5090Like stat(path), but do not follow symbolic links."); 5091 5092static PyObject * 5093posix_lstat(PyObject *self, PyObject *args) 5094{ 5095#ifdef HAVE_LSTAT 5096 return posix_do_stat(self, args, "O&:lstat", lstat, NULL, NULL); 5097#else /* !HAVE_LSTAT */ 5098#ifdef MS_WINDOWS 5099 return posix_do_stat(self, args, "O&:lstat", STAT, "U:lstat", 5100 win32_lstat_w); 5101#else 5102 return posix_do_stat(self, args, "O&:lstat", STAT, NULL, NULL); 5103#endif 5104#endif /* !HAVE_LSTAT */ 5105} 5106 5107 5108#ifdef HAVE_READLINK 5109PyDoc_STRVAR(posix_readlink__doc__, 5110"readlink(path) -> path\n\n\ 5111Return a string representing the path to which the symbolic link points."); 5112 5113static PyObject * 5114posix_readlink(PyObject *self, PyObject *args) 5115{ 5116 PyObject* v; 5117 char buf[MAXPATHLEN]; 5118 PyObject *opath; 5119 char *path; 5120 int n; 5121 int arg_is_unicode = 0; 5122 5123 if (!PyArg_ParseTuple(args, "O&:readlink", 5124 PyUnicode_FSConverter, &opath)) 5125 return NULL; 5126 path = PyBytes_AsString(opath); 5127 v = PySequence_GetItem(args, 0); 5128 if (v == NULL) { 5129 Py_DECREF(opath); 5130 return NULL; 5131 } 5132 5133 if (PyUnicode_Check(v)) { 5134 arg_is_unicode = 1; 5135 } 5136 Py_DECREF(v); 5137 5138 Py_BEGIN_ALLOW_THREADS 5139 n = readlink(path, buf, (int) sizeof buf); 5140 Py_END_ALLOW_THREADS 5141 if (n < 0) 5142 return posix_error_with_allocated_filename(opath); 5143 5144 Py_DECREF(opath); 5145 if (arg_is_unicode) 5146 return PyUnicode_DecodeFSDefaultAndSize(buf, n); 5147 else 5148 return PyBytes_FromStringAndSize(buf, n); 5149} 5150#endif /* HAVE_READLINK */ 5151 5152 5153#if defined(HAVE_SYMLINK) && !defined(MS_WINDOWS) 5154PyDoc_STRVAR(posix_symlink__doc__, 5155"symlink(src, dst)\n\n\ 5156Create a symbolic link pointing to src named dst."); 5157 5158static PyObject * 5159posix_symlink(PyObject *self, PyObject *args) 5160{ 5161 return posix_2str(args, "O&O&:symlink", symlink); 5162} 5163#endif /* HAVE_SYMLINK */ 5164 5165#if !defined(HAVE_READLINK) && defined(MS_WINDOWS) 5166 5167PyDoc_STRVAR(win_readlink__doc__, 5168"readlink(path) -> path\n\n\ 5169Return a string representing the path to which the symbolic link points."); 5170 5171/* Windows readlink implementation */ 5172static PyObject * 5173win_readlink(PyObject *self, PyObject *args) 5174{ 5175 wchar_t *path; 5176 DWORD n_bytes_returned; 5177 DWORD io_result; 5178 PyObject *result; 5179 HANDLE reparse_point_handle; 5180 5181 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; 5182 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer; 5183 wchar_t *print_name; 5184 5185 if (!PyArg_ParseTuple(args, 5186 "u:readlink", 5187 &path)) 5188 return NULL; 5189 5190 /* First get a handle to the reparse point */ 5191 Py_BEGIN_ALLOW_THREADS 5192 reparse_point_handle = CreateFileW( 5193 path, 5194 0, 5195 0, 5196 0, 5197 OPEN_EXISTING, 5198 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, 5199 0); 5200 Py_END_ALLOW_THREADS 5201 5202 if (reparse_point_handle==INVALID_HANDLE_VALUE) 5203 { 5204 return win32_error_unicode("readlink", path); 5205 } 5206 5207 Py_BEGIN_ALLOW_THREADS 5208 /* New call DeviceIoControl to read the reparse point */ 5209 io_result = DeviceIoControl( 5210 reparse_point_handle, 5211 FSCTL_GET_REPARSE_POINT, 5212 0, 0, /* in buffer */ 5213 target_buffer, sizeof(target_buffer), 5214 &n_bytes_returned, 5215 0 /* we're not using OVERLAPPED_IO */ 5216 ); 5217 CloseHandle(reparse_point_handle); 5218 Py_END_ALLOW_THREADS 5219 5220 if (io_result==0) 5221 { 5222 return win32_error_unicode("readlink", path); 5223 } 5224 5225 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK) 5226 { 5227 PyErr_SetString(PyExc_ValueError, 5228 "not a symbolic link"); 5229 return NULL; 5230 } 5231 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer + 5232 rdb->SymbolicLinkReparseBuffer.PrintNameOffset; 5233 5234 result = PyUnicode_FromWideChar(print_name, 5235 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2); 5236 return result; 5237} 5238 5239#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */ 5240 5241#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS) 5242 5243/* Grab CreateSymbolicLinkW dynamically from kernel32 */ 5244static int has_CreateSymbolicLinkW = 0; 5245static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD); 5246static int 5247check_CreateSymbolicLinkW() 5248{ 5249 HINSTANCE hKernel32; 5250 /* only recheck */ 5251 if (has_CreateSymbolicLinkW) 5252 return has_CreateSymbolicLinkW; 5253 hKernel32 = GetModuleHandle("KERNEL32"); 5254 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32, 5255 "CreateSymbolicLinkW"); 5256 if (Py_CreateSymbolicLinkW) 5257 has_CreateSymbolicLinkW = 1; 5258 return has_CreateSymbolicLinkW; 5259} 5260 5261PyDoc_STRVAR(win_symlink__doc__, 5262"symlink(src, dst, target_is_directory=False)\n\n\ 5263Create a symbolic link pointing to src named dst.\n\ 5264target_is_directory is required if the target is to be interpreted as\n\ 5265a directory.\n\ 5266This function requires Windows 6.0 or greater, and raises a\n\ 5267NotImplementedError otherwise."); 5268 5269static PyObject * 5270win_symlink(PyObject *self, PyObject *args, PyObject *kwargs) 5271{ 5272 static char *kwlist[] = {"src", "dest", "target_is_directory", NULL}; 5273 PyObject *src, *dest; 5274 int target_is_directory = 0; 5275 DWORD res; 5276 WIN32_FILE_ATTRIBUTE_DATA src_info; 5277 5278 if (!check_CreateSymbolicLinkW()) 5279 { 5280 /* raise NotImplementedError */ 5281 return PyErr_Format(PyExc_NotImplementedError, 5282 "CreateSymbolicLinkW not found"); 5283 } 5284 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|i:symlink", 5285 kwlist, &src, &dest, &target_is_directory)) 5286 return NULL; 5287 5288 if (win32_can_symlink == 0) 5289 return PyErr_Format(PyExc_OSError, "symbolic link privilege not held"); 5290 5291 if (!convert_to_unicode(&src)) { return NULL; } 5292 if (!convert_to_unicode(&dest)) { 5293 Py_DECREF(src); 5294 return NULL; 5295 } 5296 5297 /* if src is a directory, ensure target_is_directory==1 */ 5298 if( 5299 GetFileAttributesExW( 5300 PyUnicode_AsUnicode(src), GetFileExInfoStandard, &src_info 5301 )) 5302 { 5303 target_is_directory = target_is_directory || 5304 (src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY); 5305 } 5306 5307 Py_BEGIN_ALLOW_THREADS 5308 res = Py_CreateSymbolicLinkW( 5309 PyUnicode_AsUnicode(dest), 5310 PyUnicode_AsUnicode(src), 5311 target_is_directory); 5312 Py_END_ALLOW_THREADS 5313 Py_DECREF(src); 5314 Py_DECREF(dest); 5315 if (!res) 5316 { 5317 return win32_error_unicode("symlink", PyUnicode_AsUnicode(src)); 5318 } 5319 5320 Py_INCREF(Py_None); 5321 return Py_None; 5322} 5323#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */ 5324 5325#ifdef HAVE_TIMES 5326#if defined(PYCC_VACPP) && defined(PYOS_OS2) 5327static long 5328system_uptime(void) 5329{ 5330 ULONG value = 0; 5331 5332 Py_BEGIN_ALLOW_THREADS 5333 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value)); 5334 Py_END_ALLOW_THREADS 5335 5336 return value; 5337} 5338 5339static PyObject * 5340posix_times(PyObject *self, PyObject *noargs) 5341{ 5342 /* Currently Only Uptime is Provided -- Others Later */ 5343 return Py_BuildValue("ddddd", 5344 (double)0 /* t.tms_utime / HZ */, 5345 (double)0 /* t.tms_stime / HZ */, 5346 (double)0 /* t.tms_cutime / HZ */, 5347 (double)0 /* t.tms_cstime / HZ */, 5348 (double)system_uptime() / 1000); 5349} 5350#else /* not OS2 */ 5351#define NEED_TICKS_PER_SECOND 5352static long ticks_per_second = -1; 5353static PyObject * 5354posix_times(PyObject *self, PyObject *noargs) 5355{ 5356 struct tms t; 5357 clock_t c; 5358 errno = 0; 5359 c = times(&t); 5360 if (c == (clock_t) -1) 5361 return posix_error(); 5362 return Py_BuildValue("ddddd", 5363 (double)t.tms_utime / ticks_per_second, 5364 (double)t.tms_stime / ticks_per_second, 5365 (double)t.tms_cutime / ticks_per_second, 5366 (double)t.tms_cstime / ticks_per_second, 5367 (double)c / ticks_per_second); 5368} 5369#endif /* not OS2 */ 5370#endif /* HAVE_TIMES */ 5371 5372 5373#ifdef MS_WINDOWS 5374#define HAVE_TIMES /* so the method table will pick it up */ 5375static PyObject * 5376posix_times(PyObject *self, PyObject *noargs) 5377{ 5378 FILETIME create, exit, kernel, user; 5379 HANDLE hProc; 5380 hProc = GetCurrentProcess(); 5381 GetProcessTimes(hProc, &create, &exit, &kernel, &user); 5382 /* The fields of a FILETIME structure are the hi and lo part 5383 of a 64-bit value expressed in 100 nanosecond units. 5384 1e7 is one second in such units; 1e-7 the inverse. 5385 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7. 5386 */ 5387 return Py_BuildValue( 5388 "ddddd", 5389 (double)(user.dwHighDateTime*429.4967296 + 5390 user.dwLowDateTime*1e-7), 5391 (double)(kernel.dwHighDateTime*429.4967296 + 5392 kernel.dwLowDateTime*1e-7), 5393 (double)0, 5394 (double)0, 5395 (double)0); 5396} 5397#endif /* MS_WINDOWS */ 5398 5399#ifdef HAVE_TIMES 5400PyDoc_STRVAR(posix_times__doc__, 5401"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\ 5402Return a tuple of floating point numbers indicating process times."); 5403#endif 5404 5405 5406#ifdef HAVE_GETSID 5407PyDoc_STRVAR(posix_getsid__doc__, 5408"getsid(pid) -> sid\n\n\ 5409Call the system call getsid()."); 5410 5411static PyObject * 5412posix_getsid(PyObject *self, PyObject *args) 5413{ 5414 pid_t pid; 5415 int sid; 5416 if (!PyArg_ParseTuple(args, _Py_PARSE_PID ":getsid", &pid)) 5417 return NULL; 5418 sid = getsid(pid); 5419 if (sid < 0) 5420 return posix_error(); 5421 return PyLong_FromLong((long)sid); 5422} 5423#endif /* HAVE_GETSID */ 5424 5425 5426#ifdef HAVE_SETSID 5427PyDoc_STRVAR(posix_setsid__doc__, 5428"setsid()\n\n\ 5429Call the system call setsid()."); 5430 5431static PyObject * 5432posix_setsid(PyObject *self, PyObject *noargs) 5433{ 5434 if (setsid() < 0) 5435 return posix_error(); 5436 Py_INCREF(Py_None); 5437 return Py_None; 5438} 5439#endif /* HAVE_SETSID */ 5440 5441#ifdef HAVE_SETPGID 5442PyDoc_STRVAR(posix_setpgid__doc__, 5443"setpgid(pid, pgrp)\n\n\ 5444Call the system call setpgid()."); 5445 5446static PyObject * 5447posix_setpgid(PyObject *self, PyObject *args) 5448{ 5449 pid_t pid; 5450 int pgrp; 5451 if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:setpgid", &pid, &pgrp)) 5452 return NULL; 5453 if (setpgid(pid, pgrp) < 0) 5454 return posix_error(); 5455 Py_INCREF(Py_None); 5456 return Py_None; 5457} 5458#endif /* HAVE_SETPGID */ 5459 5460 5461#ifdef HAVE_TCGETPGRP 5462PyDoc_STRVAR(posix_tcgetpgrp__doc__, 5463"tcgetpgrp(fd) -> pgid\n\n\ 5464Return the process group associated with the terminal given by a fd."); 5465 5466static PyObject * 5467posix_tcgetpgrp(PyObject *self, PyObject *args) 5468{ 5469 int fd; 5470 pid_t pgid; 5471 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd)) 5472 return NULL; 5473 pgid = tcgetpgrp(fd); 5474 if (pgid < 0) 5475 return posix_error(); 5476 return PyLong_FromPid(pgid); 5477} 5478#endif /* HAVE_TCGETPGRP */ 5479 5480 5481#ifdef HAVE_TCSETPGRP 5482PyDoc_STRVAR(posix_tcsetpgrp__doc__, 5483"tcsetpgrp(fd, pgid)\n\n\ 5484Set the process group associated with the terminal given by a fd."); 5485 5486static PyObject * 5487posix_tcsetpgrp(PyObject *self, PyObject *args) 5488{ 5489 int fd; 5490 pid_t pgid; 5491 if (!PyArg_ParseTuple(args, "i" _Py_PARSE_PID ":tcsetpgrp", &fd, &pgid)) 5492 return NULL; 5493 if (tcsetpgrp(fd, pgid) < 0) 5494 return posix_error(); 5495 Py_INCREF(Py_None); 5496 return Py_None; 5497} 5498#endif /* HAVE_TCSETPGRP */ 5499 5500/* Functions acting on file descriptors */ 5501 5502PyDoc_STRVAR(posix_open__doc__, 5503"open(filename, flag [, mode=0777]) -> fd\n\n\ 5504Open a file (for low level IO)."); 5505 5506static PyObject * 5507posix_open(PyObject *self, PyObject *args) 5508{ 5509 PyObject *ofile; 5510 char *file; 5511 int flag; 5512 int mode = 0777; 5513 int fd; 5514 5515#ifdef MS_WINDOWS 5516 PyUnicodeObject *po; 5517 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) { 5518 Py_BEGIN_ALLOW_THREADS 5519 /* PyUnicode_AS_UNICODE OK without thread 5520 lock as it is a simple dereference. */ 5521 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode); 5522 Py_END_ALLOW_THREADS 5523 if (fd < 0) 5524 return posix_error(); 5525 return PyLong_FromLong((long)fd); 5526 } 5527 /* Drop the argument parsing error as narrow strings 5528 are also valid. */ 5529 PyErr_Clear(); 5530#endif 5531 5532 if (!PyArg_ParseTuple(args, "O&i|i", 5533 PyUnicode_FSConverter, &ofile, 5534 &flag, &mode)) 5535 return NULL; 5536 file = PyBytes_AsString(ofile); 5537 Py_BEGIN_ALLOW_THREADS 5538 fd = open(file, flag, mode); 5539 Py_END_ALLOW_THREADS 5540 if (fd < 0) 5541 return posix_error_with_allocated_filename(ofile); 5542 Py_DECREF(ofile); 5543 return PyLong_FromLong((long)fd); 5544} 5545 5546 5547PyDoc_STRVAR(posix_close__doc__, 5548"close(fd)\n\n\ 5549Close a file descriptor (for low level IO)."); 5550 5551static PyObject * 5552posix_close(PyObject *self, PyObject *args) 5553{ 5554 int fd, res; 5555 if (!PyArg_ParseTuple(args, "i:close", &fd)) 5556 return NULL; 5557 if (!_PyVerify_fd(fd)) 5558 return posix_error(); 5559 Py_BEGIN_ALLOW_THREADS 5560 res = close(fd); 5561 Py_END_ALLOW_THREADS 5562 if (res < 0) 5563 return posix_error(); 5564 Py_INCREF(Py_None); 5565 return Py_None; 5566} 5567 5568 5569PyDoc_STRVAR(posix_closerange__doc__, 5570"closerange(fd_low, fd_high)\n\n\ 5571Closes all file descriptors in [fd_low, fd_high), ignoring errors."); 5572 5573static PyObject * 5574posix_closerange(PyObject *self, PyObject *args) 5575{ 5576 int fd_from, fd_to, i; 5577 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to)) 5578 return NULL; 5579 Py_BEGIN_ALLOW_THREADS 5580 for (i = fd_from; i < fd_to; i++) 5581 if (_PyVerify_fd(i)) 5582 close(i); 5583 Py_END_ALLOW_THREADS 5584 Py_RETURN_NONE; 5585} 5586 5587 5588PyDoc_STRVAR(posix_dup__doc__, 5589"dup(fd) -> fd2\n\n\ 5590Return a duplicate of a file descriptor."); 5591 5592static PyObject * 5593posix_dup(PyObject *self, PyObject *args) 5594{ 5595 int fd; 5596 if (!PyArg_ParseTuple(args, "i:dup", &fd)) 5597 return NULL; 5598 if (!_PyVerify_fd(fd)) 5599 return posix_error(); 5600 Py_BEGIN_ALLOW_THREADS 5601 fd = dup(fd); 5602 Py_END_ALLOW_THREADS 5603 if (fd < 0) 5604 return posix_error(); 5605 return PyLong_FromLong((long)fd); 5606} 5607 5608 5609PyDoc_STRVAR(posix_dup2__doc__, 5610"dup2(old_fd, new_fd)\n\n\ 5611Duplicate file descriptor."); 5612 5613static PyObject * 5614posix_dup2(PyObject *self, PyObject *args) 5615{ 5616 int fd, fd2, res; 5617 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2)) 5618 return NULL; 5619 if (!_PyVerify_fd_dup2(fd, fd2)) 5620 return posix_error(); 5621 Py_BEGIN_ALLOW_THREADS 5622 res = dup2(fd, fd2); 5623 Py_END_ALLOW_THREADS 5624 if (res < 0) 5625 return posix_error(); 5626 Py_INCREF(Py_None); 5627 return Py_None; 5628} 5629 5630 5631PyDoc_STRVAR(posix_lseek__doc__, 5632"lseek(fd, pos, how) -> newpos\n\n\ 5633Set the current position of a file descriptor."); 5634 5635static PyObject * 5636posix_lseek(PyObject *self, PyObject *args) 5637{ 5638 int fd, how; 5639#if defined(MS_WIN64) || defined(MS_WINDOWS) 5640 PY_LONG_LONG pos, res; 5641#else 5642 off_t pos, res; 5643#endif 5644 PyObject *posobj; 5645 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how)) 5646 return NULL; 5647#ifdef SEEK_SET 5648 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */ 5649 switch (how) { 5650 case 0: how = SEEK_SET; break; 5651 case 1: how = SEEK_CUR; break; 5652 case 2: how = SEEK_END; break; 5653 } 5654#endif /* SEEK_END */ 5655 5656#if !defined(HAVE_LARGEFILE_SUPPORT) 5657 pos = PyLong_AsLong(posobj); 5658#else 5659 pos = PyLong_Check(posobj) ? 5660 PyLong_AsLongLong(posobj) : PyLong_AsLong(posobj); 5661#endif 5662 if (PyErr_Occurred()) 5663 return NULL; 5664 5665 if (!_PyVerify_fd(fd)) 5666 return posix_error(); 5667 Py_BEGIN_ALLOW_THREADS 5668#if defined(MS_WIN64) || defined(MS_WINDOWS) 5669 res = _lseeki64(fd, pos, how); 5670#else 5671 res = lseek(fd, pos, how); 5672#endif 5673 Py_END_ALLOW_THREADS 5674 if (res < 0) 5675 return posix_error(); 5676 5677#if !defined(HAVE_LARGEFILE_SUPPORT) 5678 return PyLong_FromLong(res); 5679#else 5680 return PyLong_FromLongLong(res); 5681#endif 5682} 5683 5684 5685PyDoc_STRVAR(posix_read__doc__, 5686"read(fd, buffersize) -> string\n\n\ 5687Read a file descriptor."); 5688 5689static PyObject * 5690posix_read(PyObject *self, PyObject *args) 5691{ 5692 int fd, size; 5693 Py_ssize_t n; 5694 PyObject *buffer; 5695 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size)) 5696 return NULL; 5697 if (size < 0) { 5698 errno = EINVAL; 5699 return posix_error(); 5700 } 5701 buffer = PyBytes_FromStringAndSize((char *)NULL, size); 5702 if (buffer == NULL) 5703 return NULL; 5704 if (!_PyVerify_fd(fd)) { 5705 Py_DECREF(buffer); 5706 return posix_error(); 5707 } 5708 Py_BEGIN_ALLOW_THREADS 5709 n = read(fd, PyBytes_AS_STRING(buffer), size); 5710 Py_END_ALLOW_THREADS 5711 if (n < 0) { 5712 Py_DECREF(buffer); 5713 return posix_error(); 5714 } 5715 if (n != size) 5716 _PyBytes_Resize(&buffer, n); 5717 return buffer; 5718} 5719 5720 5721PyDoc_STRVAR(posix_write__doc__, 5722"write(fd, string) -> byteswritten\n\n\ 5723Write a string to a file descriptor."); 5724 5725static PyObject * 5726posix_write(PyObject *self, PyObject *args) 5727{ 5728 Py_buffer pbuf; 5729 int fd; 5730 Py_ssize_t size, len; 5731 5732 if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf)) 5733 return NULL; 5734 if (!_PyVerify_fd(fd)) { 5735 PyBuffer_Release(&pbuf); 5736 return posix_error(); 5737 } 5738 len = pbuf.len; 5739 Py_BEGIN_ALLOW_THREADS 5740#if defined(MS_WIN64) || defined(MS_WINDOWS) 5741 if (len > INT_MAX) 5742 len = INT_MAX; 5743 size = write(fd, pbuf.buf, (int)len); 5744#else 5745 size = write(fd, pbuf.buf, len); 5746#endif 5747 Py_END_ALLOW_THREADS 5748 PyBuffer_Release(&pbuf); 5749 if (size < 0) 5750 return posix_error(); 5751 return PyLong_FromSsize_t(size); 5752} 5753 5754#ifdef HAVE_SENDFILE 5755#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__) 5756static int 5757iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type) 5758{ 5759 int i, j; 5760 *iov = PyMem_New(struct iovec, cnt); 5761 if (*iov == NULL) { 5762 PyErr_NoMemory(); 5763 return 0; 5764 } 5765 *buf = PyMem_New(Py_buffer, cnt); 5766 if (*buf == NULL) { 5767 PyMem_Del(*iov); 5768 PyErr_NoMemory(); 5769 return 0; 5770 } 5771 5772 for (i = 0; i < cnt; i++) { 5773 if (PyObject_GetBuffer(PySequence_GetItem(seq, i), &(*buf)[i], 5774 type) == -1) { 5775 PyMem_Del(*iov); 5776 for (j = 0; j < i; j++) { 5777 PyBuffer_Release(&(*buf)[j]); 5778 } 5779 PyMem_Del(*buf); 5780 return 0; 5781 } 5782 (*iov)[i].iov_base = (*buf)[i].buf; 5783 (*iov)[i].iov_len = (*buf)[i].len; 5784 } 5785 return 1; 5786} 5787 5788static void 5789iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt) 5790{ 5791 int i; 5792 PyMem_Del(iov); 5793 for (i = 0; i < cnt; i++) { 5794 PyBuffer_Release(&buf[i]); 5795 } 5796 PyMem_Del(buf); 5797} 5798#endif 5799 5800PyDoc_STRVAR(posix_sendfile__doc__, 5801"sendfile(out, in, offset, nbytes) -> byteswritten\n\ 5802sendfile(out, in, offset, nbytes, headers=None, trailers=None, flags=0)\n\ 5803 -> byteswritten\n\ 5804Copy nbytes bytes from file descriptor in to file descriptor out."); 5805 5806static PyObject * 5807posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict) 5808{ 5809 int in, out; 5810 Py_ssize_t ret; 5811 off_t offset; 5812 5813#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__) 5814#ifndef __APPLE__ 5815 Py_ssize_t len; 5816#endif 5817 PyObject *headers = NULL, *trailers = NULL; 5818 Py_buffer *hbuf, *tbuf; 5819 off_t sbytes; 5820 struct sf_hdtr sf; 5821 int flags = 0; 5822 sf.headers = NULL; 5823 sf.trailers = NULL; 5824 static char *keywords[] = {"out", "in", 5825 "offset", "count", 5826 "headers", "trailers", "flags", NULL}; 5827 5828#ifdef __APPLE__ 5829 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile", 5830 keywords, &out, &in, PyParse_off_t, &offset, PyParse_off_t, &sbytes, 5831#else 5832 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile", 5833 keywords, &out, &in, PyParse_off_t, &offset, &len, 5834#endif 5835 &headers, &trailers, &flags)) 5836 return NULL; 5837 if (headers != NULL) { 5838 if (!PySequence_Check(headers)) { 5839 PyErr_SetString(PyExc_TypeError, 5840 "sendfile() headers must be a sequence or None"); 5841 return NULL; 5842 } else { 5843 sf.hdr_cnt = PySequence_Size(headers); 5844 if (sf.hdr_cnt > 0 && !iov_setup(&(sf.headers), &hbuf, 5845 headers, sf.hdr_cnt, PyBUF_SIMPLE)) 5846 return NULL; 5847 } 5848 } 5849 if (trailers != NULL) { 5850 if (!PySequence_Check(trailers)) { 5851 PyErr_SetString(PyExc_TypeError, 5852 "sendfile() trailers must be a sequence or None"); 5853 return NULL; 5854 } else { 5855 sf.trl_cnt = PySequence_Size(trailers); 5856 if (sf.trl_cnt > 0 && !iov_setup(&(sf.trailers), &tbuf, 5857 trailers, sf.trl_cnt, PyBUF_SIMPLE)) 5858 return NULL; 5859 } 5860 } 5861 5862 Py_BEGIN_ALLOW_THREADS 5863#ifdef __APPLE__ 5864 ret = sendfile(in, out, offset, &sbytes, &sf, flags); 5865#else 5866 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags); 5867#endif 5868 Py_END_ALLOW_THREADS 5869 5870 if (sf.headers != NULL) 5871 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt); 5872 if (sf.trailers != NULL) 5873 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt); 5874 5875 if (ret < 0) { 5876 if ((errno == EAGAIN) || (errno == EBUSY)) { 5877 if (sbytes != 0) { 5878 // some data has been sent 5879 goto done; 5880 } 5881 else { 5882 // no data has been sent; upper application is supposed 5883 // to retry on EAGAIN or EBUSY 5884 return posix_error(); 5885 } 5886 } 5887 return posix_error(); 5888 } 5889 goto done; 5890 5891done: 5892 #if !defined(HAVE_LARGEFILE_SUPPORT) 5893 return Py_BuildValue("l", sbytes); 5894 #else 5895 return Py_BuildValue("L", sbytes); 5896 #endif 5897 5898#else 5899 Py_ssize_t count; 5900 PyObject *offobj; 5901 static char *keywords[] = {"out", "in", 5902 "offset", "count", NULL}; 5903 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile", 5904 keywords, &out, &in, &offobj, &count)) 5905 return NULL; 5906#ifdef linux 5907 if (offobj == Py_None) { 5908 Py_BEGIN_ALLOW_THREADS 5909 ret = sendfile(out, in, NULL, count); 5910 Py_END_ALLOW_THREADS 5911 if (ret < 0) 5912 return posix_error(); 5913 Py_INCREF(Py_None); 5914 return Py_BuildValue("nO", ret, Py_None); 5915 } 5916#endif 5917 PyParse_off_t(offobj, &offset); 5918 Py_BEGIN_ALLOW_THREADS 5919 ret = sendfile(out, in, &offset, count); 5920 Py_END_ALLOW_THREADS 5921 if (ret < 0) 5922 return posix_error(); 5923 return Py_BuildValue("n", ret); 5924#endif 5925} 5926#endif 5927 5928PyDoc_STRVAR(posix_fstat__doc__, 5929"fstat(fd) -> stat result\n\n\ 5930Like stat(), but for an open file descriptor."); 5931 5932static PyObject * 5933posix_fstat(PyObject *self, PyObject *args) 5934{ 5935 int fd; 5936 STRUCT_STAT st; 5937 int res; 5938 if (!PyArg_ParseTuple(args, "i:fstat", &fd)) 5939 return NULL; 5940#ifdef __VMS 5941 /* on OpenVMS we must ensure that all bytes are written to the file */ 5942 fsync(fd); 5943#endif 5944 if (!_PyVerify_fd(fd)) 5945 return posix_error(); 5946 Py_BEGIN_ALLOW_THREADS 5947 res = FSTAT(fd, &st); 5948 Py_END_ALLOW_THREADS 5949 if (res != 0) { 5950#ifdef MS_WINDOWS 5951 return win32_error("fstat", NULL); 5952#else 5953 return posix_error(); 5954#endif 5955 } 5956 5957 return _pystat_fromstructstat(&st); 5958} 5959 5960PyDoc_STRVAR(posix_isatty__doc__, 5961"isatty(fd) -> bool\n\n\ 5962Return True if the file descriptor 'fd' is an open file descriptor\n\ 5963connected to the slave end of a terminal."); 5964 5965static PyObject * 5966posix_isatty(PyObject *self, PyObject *args) 5967{ 5968 int fd; 5969 if (!PyArg_ParseTuple(args, "i:isatty", &fd)) 5970 return NULL; 5971 if (!_PyVerify_fd(fd)) 5972 return PyBool_FromLong(0); 5973 return PyBool_FromLong(isatty(fd)); 5974} 5975 5976#ifdef HAVE_PIPE 5977PyDoc_STRVAR(posix_pipe__doc__, 5978"pipe() -> (read_end, write_end)\n\n\ 5979Create a pipe."); 5980 5981static PyObject * 5982posix_pipe(PyObject *self, PyObject *noargs) 5983{ 5984#if defined(PYOS_OS2) 5985 HFILE read, write; 5986 APIRET rc; 5987 5988 Py_BEGIN_ALLOW_THREADS 5989 rc = DosCreatePipe( &read, &write, 4096); 5990 Py_END_ALLOW_THREADS 5991 if (rc != NO_ERROR) 5992 return os2_error(rc); 5993 5994 return Py_BuildValue("(ii)", read, write); 5995#else 5996#if !defined(MS_WINDOWS) 5997 int fds[2]; 5998 int res; 5999 Py_BEGIN_ALLOW_THREADS 6000 res = pipe(fds); 6001 Py_END_ALLOW_THREADS 6002 if (res != 0) 6003 return posix_error(); 6004 return Py_BuildValue("(ii)", fds[0], fds[1]); 6005#else /* MS_WINDOWS */ 6006 HANDLE read, write; 6007 int read_fd, write_fd; 6008 BOOL ok; 6009 Py_BEGIN_ALLOW_THREADS 6010 ok = CreatePipe(&read, &write, NULL, 0); 6011 Py_END_ALLOW_THREADS 6012 if (!ok) 6013 return win32_error("CreatePipe", NULL); 6014 read_fd = _open_osfhandle((Py_intptr_t)read, 0); 6015 write_fd = _open_osfhandle((Py_intptr_t)write, 1); 6016 return Py_BuildValue("(ii)", read_fd, write_fd); 6017#endif /* MS_WINDOWS */ 6018#endif 6019} 6020#endif /* HAVE_PIPE */ 6021 6022 6023#ifdef HAVE_MKFIFO 6024PyDoc_STRVAR(posix_mkfifo__doc__, 6025"mkfifo(filename [, mode=0666])\n\n\ 6026Create a FIFO (a POSIX named pipe)."); 6027 6028static PyObject * 6029posix_mkfifo(PyObject *self, PyObject *args) 6030{ 6031 PyObject *opath; 6032 char *filename; 6033 int mode = 0666; 6034 int res; 6035 if (!PyArg_ParseTuple(args, "O&|i:mkfifo", PyUnicode_FSConverter, &opath, 6036 &mode)) 6037 return NULL; 6038 filename = PyBytes_AS_STRING(opath); 6039 Py_BEGIN_ALLOW_THREADS 6040 res = mkfifo(filename, mode); 6041 Py_END_ALLOW_THREADS 6042 Py_DECREF(opath); 6043 if (res < 0) 6044 return posix_error(); 6045 Py_INCREF(Py_None); 6046 return Py_None; 6047} 6048#endif 6049 6050 6051#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) 6052PyDoc_STRVAR(posix_mknod__doc__, 6053"mknod(filename [, mode=0600, device])\n\n\ 6054Create a filesystem node (file, device special file or named pipe)\n\ 6055named filename. mode specifies both the permissions to use and the\n\ 6056type of node to be created, being combined (bitwise OR) with one of\n\ 6057S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\ 6058device defines the newly created device special file (probably using\n\ 6059os.makedev()), otherwise it is ignored."); 6060 6061 6062static PyObject * 6063posix_mknod(PyObject *self, PyObject *args) 6064{ 6065 PyObject *opath; 6066 char *filename; 6067 int mode = 0600; 6068 int device = 0; 6069 int res; 6070 if (!PyArg_ParseTuple(args, "O&|ii:mknod", PyUnicode_FSConverter, &opath, 6071 &mode, &device)) 6072 return NULL; 6073 filename = PyBytes_AS_STRING(opath); 6074 Py_BEGIN_ALLOW_THREADS 6075 res = mknod(filename, mode, device); 6076 Py_END_ALLOW_THREADS 6077 Py_DECREF(opath); 6078 if (res < 0) 6079 return posix_error(); 6080 Py_INCREF(Py_None); 6081 return Py_None; 6082} 6083#endif 6084 6085#ifdef HAVE_DEVICE_MACROS 6086PyDoc_STRVAR(posix_major__doc__, 6087"major(device) -> major number\n\ 6088Extracts a device major number from a raw device number."); 6089 6090static PyObject * 6091posix_major(PyObject *self, PyObject *args) 6092{ 6093 int device; 6094 if (!PyArg_ParseTuple(args, "i:major", &device)) 6095 return NULL; 6096 return PyLong_FromLong((long)major(device)); 6097} 6098 6099PyDoc_STRVAR(posix_minor__doc__, 6100"minor(device) -> minor number\n\ 6101Extracts a device minor number from a raw device number."); 6102 6103static PyObject * 6104posix_minor(PyObject *self, PyObject *args) 6105{ 6106 int device; 6107 if (!PyArg_ParseTuple(args, "i:minor", &device)) 6108 return NULL; 6109 return PyLong_FromLong((long)minor(device)); 6110} 6111 6112PyDoc_STRVAR(posix_makedev__doc__, 6113"makedev(major, minor) -> device number\n\ 6114Composes a raw device number from the major and minor device numbers."); 6115 6116static PyObject * 6117posix_makedev(PyObject *self, PyObject *args) 6118{ 6119 int major, minor; 6120 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor)) 6121 return NULL; 6122 return PyLong_FromLong((long)makedev(major, minor)); 6123} 6124#endif /* device macros */ 6125 6126 6127#ifdef HAVE_FTRUNCATE 6128PyDoc_STRVAR(posix_ftruncate__doc__, 6129"ftruncate(fd, length)\n\n\ 6130Truncate a file to a specified length."); 6131 6132static PyObject * 6133posix_ftruncate(PyObject *self, PyObject *args) 6134{ 6135 int fd; 6136 off_t length; 6137 int res; 6138 PyObject *lenobj; 6139 6140 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj)) 6141 return NULL; 6142 6143#if !defined(HAVE_LARGEFILE_SUPPORT) 6144 length = PyLong_AsLong(lenobj); 6145#else 6146 length = PyLong_Check(lenobj) ? 6147 PyLong_AsLongLong(lenobj) : PyLong_AsLong(lenobj); 6148#endif 6149 if (PyErr_Occurred()) 6150 return NULL; 6151 6152 Py_BEGIN_ALLOW_THREADS 6153 res = ftruncate(fd, length); 6154 Py_END_ALLOW_THREADS 6155 if (res < 0) 6156 return posix_error(); 6157 Py_INCREF(Py_None); 6158 return Py_None; 6159} 6160#endif 6161 6162#ifdef HAVE_PUTENV 6163PyDoc_STRVAR(posix_putenv__doc__, 6164"putenv(key, value)\n\n\ 6165Change or add an environment variable."); 6166 6167/* Save putenv() parameters as values here, so we can collect them when they 6168 * get re-set with another call for the same key. */ 6169static PyObject *posix_putenv_garbage; 6170 6171static PyObject * 6172posix_putenv(PyObject *self, PyObject *args) 6173{ 6174#ifdef MS_WINDOWS 6175 wchar_t *s1, *s2; 6176 wchar_t *newenv; 6177#else 6178 PyObject *os1, *os2; 6179 char *s1, *s2; 6180 char *newenv; 6181#endif 6182 PyObject *newstr = NULL; 6183 size_t len; 6184 6185#ifdef MS_WINDOWS 6186 if (!PyArg_ParseTuple(args, 6187 "uu:putenv", 6188 &s1, &s2)) 6189 return NULL; 6190#else 6191 if (!PyArg_ParseTuple(args, 6192 "O&O&:putenv", 6193 PyUnicode_FSConverter, &os1, 6194 PyUnicode_FSConverter, &os2)) 6195 return NULL; 6196 s1 = PyBytes_AsString(os1); 6197 s2 = PyBytes_AsString(os2); 6198#endif 6199 6200#if defined(PYOS_OS2) 6201 if (stricmp(s1, "BEGINLIBPATH") == 0) { 6202 APIRET rc; 6203 6204 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH); 6205 if (rc != NO_ERROR) { 6206 os2_error(rc); 6207 goto error; 6208 } 6209 6210 } else if (stricmp(s1, "ENDLIBPATH") == 0) { 6211 APIRET rc; 6212 6213 rc = DosSetExtLIBPATH(s2, END_LIBPATH); 6214 if (rc != NO_ERROR) { 6215 os2_error(rc); 6216 goto error; 6217 } 6218 } else { 6219#endif 6220 /* XXX This can leak memory -- not easy to fix :-( */ 6221 /* len includes space for a trailing \0; the size arg to 6222 PyBytes_FromStringAndSize does not count that */ 6223#ifdef MS_WINDOWS 6224 len = wcslen(s1) + wcslen(s2) + 2; 6225 newstr = PyUnicode_FromUnicode(NULL, (int)len - 1); 6226#else 6227 len = PyBytes_GET_SIZE(os1) + PyBytes_GET_SIZE(os2) + 2; 6228 newstr = PyBytes_FromStringAndSize(NULL, (int)len - 1); 6229#endif 6230 if (newstr == NULL) { 6231 PyErr_NoMemory(); 6232 goto error; 6233 } 6234#ifdef MS_WINDOWS 6235 newenv = PyUnicode_AsUnicode(newstr); 6236 _snwprintf(newenv, len, L"%s=%s", s1, s2); 6237 if (_wputenv(newenv)) { 6238 posix_error(); 6239 goto error; 6240 } 6241#else 6242 newenv = PyBytes_AS_STRING(newstr); 6243 PyOS_snprintf(newenv, len, "%s=%s", s1, s2); 6244 if (putenv(newenv)) { 6245 posix_error(); 6246 goto error; 6247 } 6248#endif 6249 6250 /* Install the first arg and newstr in posix_putenv_garbage; 6251 * this will cause previous value to be collected. This has to 6252 * happen after the real putenv() call because the old value 6253 * was still accessible until then. */ 6254 if (PyDict_SetItem(posix_putenv_garbage, 6255#ifdef MS_WINDOWS 6256 PyTuple_GET_ITEM(args, 0), 6257#else 6258 os1, 6259#endif 6260 newstr)) { 6261 /* really not much we can do; just leak */ 6262 PyErr_Clear(); 6263 } 6264 else { 6265 Py_DECREF(newstr); 6266 } 6267 6268#if defined(PYOS_OS2) 6269 } 6270#endif 6271 6272#ifndef MS_WINDOWS 6273 Py_DECREF(os1); 6274 Py_DECREF(os2); 6275#endif 6276 Py_RETURN_NONE; 6277 6278error: 6279#ifndef MS_WINDOWS 6280 Py_DECREF(os1); 6281 Py_DECREF(os2); 6282#endif 6283 Py_XDECREF(newstr); 6284 return NULL; 6285} 6286#endif /* putenv */ 6287 6288#ifdef HAVE_UNSETENV 6289PyDoc_STRVAR(posix_unsetenv__doc__, 6290"unsetenv(key)\n\n\ 6291Delete an environment variable."); 6292 6293static PyObject * 6294posix_unsetenv(PyObject *self, PyObject *args) 6295{ 6296#ifdef MS_WINDOWS 6297 char *s1; 6298 6299 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1)) 6300 return NULL; 6301#else 6302 PyObject *os1; 6303 char *s1; 6304 6305 if (!PyArg_ParseTuple(args, "O&:unsetenv", 6306 PyUnicode_FSConverter, &os1)) 6307 return NULL; 6308 s1 = PyBytes_AsString(os1); 6309#endif 6310 6311 unsetenv(s1); 6312 6313 /* Remove the key from posix_putenv_garbage; 6314 * this will cause it to be collected. This has to 6315 * happen after the real unsetenv() call because the 6316 * old value was still accessible until then. 6317 */ 6318 if (PyDict_DelItem(posix_putenv_garbage, 6319#ifdef MS_WINDOWS 6320 PyTuple_GET_ITEM(args, 0) 6321#else 6322 os1 6323#endif 6324 )) { 6325 /* really not much we can do; just leak */ 6326 PyErr_Clear(); 6327 } 6328 6329#ifndef MS_WINDOWS 6330 Py_DECREF(os1); 6331#endif 6332 Py_RETURN_NONE; 6333} 6334#endif /* unsetenv */ 6335 6336PyDoc_STRVAR(posix_strerror__doc__, 6337"strerror(code) -> string\n\n\ 6338Translate an error code to a message string."); 6339 6340static PyObject * 6341posix_strerror(PyObject *self, PyObject *args) 6342{ 6343 int code; 6344 char *message; 6345 if (!PyArg_ParseTuple(args, "i:strerror", &code)) 6346 return NULL; 6347 message = strerror(code); 6348 if (message == NULL) { 6349 PyErr_SetString(PyExc_ValueError, 6350 "strerror() argument out of range"); 6351 return NULL; 6352 } 6353 return PyUnicode_FromString(message); 6354} 6355 6356 6357#ifdef HAVE_SYS_WAIT_H 6358 6359#ifdef WCOREDUMP 6360PyDoc_STRVAR(posix_WCOREDUMP__doc__, 6361"WCOREDUMP(status) -> bool\n\n\ 6362Return True if the process returning 'status' was dumped to a core file."); 6363 6364static PyObject * 6365posix_WCOREDUMP(PyObject *self, PyObject *args) 6366{ 6367 WAIT_TYPE status; 6368 WAIT_STATUS_INT(status) = 0; 6369 6370 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status))) 6371 return NULL; 6372 6373 return PyBool_FromLong(WCOREDUMP(status)); 6374} 6375#endif /* WCOREDUMP */ 6376 6377#ifdef WIFCONTINUED 6378PyDoc_STRVAR(posix_WIFCONTINUED__doc__, 6379"WIFCONTINUED(status) -> bool\n\n\ 6380Return True if the process returning 'status' was continued from a\n\ 6381job control stop."); 6382 6383static PyObject * 6384posix_WIFCONTINUED(PyObject *self, PyObject *args) 6385{ 6386 WAIT_TYPE status; 6387 WAIT_STATUS_INT(status) = 0; 6388 6389 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status))) 6390 return NULL; 6391 6392 return PyBool_FromLong(WIFCONTINUED(status)); 6393} 6394#endif /* WIFCONTINUED */ 6395 6396#ifdef WIFSTOPPED 6397PyDoc_STRVAR(posix_WIFSTOPPED__doc__, 6398"WIFSTOPPED(status) -> bool\n\n\ 6399Return True if the process returning 'status' was stopped."); 6400 6401static PyObject * 6402posix_WIFSTOPPED(PyObject *self, PyObject *args) 6403{ 6404 WAIT_TYPE status; 6405 WAIT_STATUS_INT(status) = 0; 6406 6407 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status))) 6408 return NULL; 6409 6410 return PyBool_FromLong(WIFSTOPPED(status)); 6411} 6412#endif /* WIFSTOPPED */ 6413 6414#ifdef WIFSIGNALED 6415PyDoc_STRVAR(posix_WIFSIGNALED__doc__, 6416"WIFSIGNALED(status) -> bool\n\n\ 6417Return True if the process returning 'status' was terminated by a signal."); 6418 6419static PyObject * 6420posix_WIFSIGNALED(PyObject *self, PyObject *args) 6421{ 6422 WAIT_TYPE status; 6423 WAIT_STATUS_INT(status) = 0; 6424 6425 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status))) 6426 return NULL; 6427 6428 return PyBool_FromLong(WIFSIGNALED(status)); 6429} 6430#endif /* WIFSIGNALED */ 6431 6432#ifdef WIFEXITED 6433PyDoc_STRVAR(posix_WIFEXITED__doc__, 6434"WIFEXITED(status) -> bool\n\n\ 6435Return true if the process returning 'status' exited using the exit()\n\ 6436system call."); 6437 6438static PyObject * 6439posix_WIFEXITED(PyObject *self, PyObject *args) 6440{ 6441 WAIT_TYPE status; 6442 WAIT_STATUS_INT(status) = 0; 6443 6444 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status))) 6445 return NULL; 6446 6447 return PyBool_FromLong(WIFEXITED(status)); 6448} 6449#endif /* WIFEXITED */ 6450 6451#ifdef WEXITSTATUS 6452PyDoc_STRVAR(posix_WEXITSTATUS__doc__, 6453"WEXITSTATUS(status) -> integer\n\n\ 6454Return the process return code from 'status'."); 6455 6456static PyObject * 6457posix_WEXITSTATUS(PyObject *self, PyObject *args) 6458{ 6459 WAIT_TYPE status; 6460 WAIT_STATUS_INT(status) = 0; 6461 6462 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status))) 6463 return NULL; 6464 6465 return Py_BuildValue("i", WEXITSTATUS(status)); 6466} 6467#endif /* WEXITSTATUS */ 6468 6469#ifdef WTERMSIG 6470PyDoc_STRVAR(posix_WTERMSIG__doc__, 6471"WTERMSIG(status) -> integer\n\n\ 6472Return the signal that terminated the process that provided the 'status'\n\ 6473value."); 6474 6475static PyObject * 6476posix_WTERMSIG(PyObject *self, PyObject *args) 6477{ 6478 WAIT_TYPE status; 6479 WAIT_STATUS_INT(status) = 0; 6480 6481 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status))) 6482 return NULL; 6483 6484 return Py_BuildValue("i", WTERMSIG(status)); 6485} 6486#endif /* WTERMSIG */ 6487 6488#ifdef WSTOPSIG 6489PyDoc_STRVAR(posix_WSTOPSIG__doc__, 6490"WSTOPSIG(status) -> integer\n\n\ 6491Return the signal that stopped the process that provided\n\ 6492the 'status' value."); 6493 6494static PyObject * 6495posix_WSTOPSIG(PyObject *self, PyObject *args) 6496{ 6497 WAIT_TYPE status; 6498 WAIT_STATUS_INT(status) = 0; 6499 6500 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status))) 6501 return NULL; 6502 6503 return Py_BuildValue("i", WSTOPSIG(status)); 6504} 6505#endif /* WSTOPSIG */ 6506 6507#endif /* HAVE_SYS_WAIT_H */ 6508 6509 6510#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) 6511#ifdef _SCO_DS 6512/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the 6513 needed definitions in sys/statvfs.h */ 6514#define _SVID3 6515#endif 6516#include <sys/statvfs.h> 6517 6518static PyObject* 6519_pystatvfs_fromstructstatvfs(struct statvfs st) { 6520 PyObject *v = PyStructSequence_New(&StatVFSResultType); 6521 if (v == NULL) 6522 return NULL; 6523 6524#if !defined(HAVE_LARGEFILE_SUPPORT) 6525 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize)); 6526 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize)); 6527 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks)); 6528 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree)); 6529 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail)); 6530 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files)); 6531 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree)); 6532 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail)); 6533 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag)); 6534 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax)); 6535#else 6536 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize)); 6537 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize)); 6538 PyStructSequence_SET_ITEM(v, 2, 6539 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks)); 6540 PyStructSequence_SET_ITEM(v, 3, 6541 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree)); 6542 PyStructSequence_SET_ITEM(v, 4, 6543 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail)); 6544 PyStructSequence_SET_ITEM(v, 5, 6545 PyLong_FromLongLong((PY_LONG_LONG) st.f_files)); 6546 PyStructSequence_SET_ITEM(v, 6, 6547 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree)); 6548 PyStructSequence_SET_ITEM(v, 7, 6549 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail)); 6550 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag)); 6551 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax)); 6552#endif 6553 6554 return v; 6555} 6556 6557PyDoc_STRVAR(posix_fstatvfs__doc__, 6558"fstatvfs(fd) -> statvfs result\n\n\ 6559Perform an fstatvfs system call on the given fd."); 6560 6561static PyObject * 6562posix_fstatvfs(PyObject *self, PyObject *args) 6563{ 6564 int fd, res; 6565 struct statvfs st; 6566 6567 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd)) 6568 return NULL; 6569 Py_BEGIN_ALLOW_THREADS 6570 res = fstatvfs(fd, &st); 6571 Py_END_ALLOW_THREADS 6572 if (res != 0) 6573 return posix_error(); 6574 6575 return _pystatvfs_fromstructstatvfs(st); 6576} 6577#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */ 6578 6579 6580#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) 6581#include <sys/statvfs.h> 6582 6583PyDoc_STRVAR(posix_statvfs__doc__, 6584"statvfs(path) -> statvfs result\n\n\ 6585Perform a statvfs system call on the given path."); 6586 6587static PyObject * 6588posix_statvfs(PyObject *self, PyObject *args) 6589{ 6590 char *path; 6591 int res; 6592 struct statvfs st; 6593 if (!PyArg_ParseTuple(args, "s:statvfs", &path)) 6594 return NULL; 6595 Py_BEGIN_ALLOW_THREADS 6596 res = statvfs(path, &st); 6597 Py_END_ALLOW_THREADS 6598 if (res != 0) 6599 return posix_error_with_filename(path); 6600 6601 return _pystatvfs_fromstructstatvfs(st); 6602} 6603#endif /* HAVE_STATVFS */ 6604 6605/* This is used for fpathconf(), pathconf(), confstr() and sysconf(). 6606 * It maps strings representing configuration variable names to 6607 * integer values, allowing those functions to be called with the 6608 * magic names instead of polluting the module's namespace with tons of 6609 * rarely-used constants. There are three separate tables that use 6610 * these definitions. 6611 * 6612 * This code is always included, even if none of the interfaces that 6613 * need it are included. The #if hackery needed to avoid it would be 6614 * sufficiently pervasive that it's not worth the loss of readability. 6615 */ 6616struct constdef { 6617 char *name; 6618 long value; 6619}; 6620 6621static int 6622conv_confname(PyObject *arg, int *valuep, struct constdef *table, 6623 size_t tablesize) 6624{ 6625 if (PyLong_Check(arg)) { 6626 *valuep = PyLong_AS_LONG(arg); 6627 return 1; 6628 } 6629 else { 6630 /* look up the value in the table using a binary search */ 6631 size_t lo = 0; 6632 size_t mid; 6633 size_t hi = tablesize; 6634 int cmp; 6635 const char *confname; 6636 if (!PyUnicode_Check(arg)) { 6637 PyErr_SetString(PyExc_TypeError, 6638 "configuration names must be strings or integers"); 6639 return 0; 6640 } 6641 confname = _PyUnicode_AsString(arg); 6642 if (confname == NULL) 6643 return 0; 6644 while (lo < hi) { 6645 mid = (lo + hi) / 2; 6646 cmp = strcmp(confname, table[mid].name); 6647 if (cmp < 0) 6648 hi = mid; 6649 else if (cmp > 0) 6650 lo = mid + 1; 6651 else { 6652 *valuep = table[mid].value; 6653 return 1; 6654 } 6655 } 6656 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name"); 6657 return 0; 6658 } 6659} 6660 6661 6662#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF) 6663static struct constdef posix_constants_pathconf[] = { 6664#ifdef _PC_ABI_AIO_XFER_MAX 6665 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX}, 6666#endif 6667#ifdef _PC_ABI_ASYNC_IO 6668 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO}, 6669#endif 6670#ifdef _PC_ASYNC_IO 6671 {"PC_ASYNC_IO", _PC_ASYNC_IO}, 6672#endif 6673#ifdef _PC_CHOWN_RESTRICTED 6674 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED}, 6675#endif 6676#ifdef _PC_FILESIZEBITS 6677 {"PC_FILESIZEBITS", _PC_FILESIZEBITS}, 6678#endif 6679#ifdef _PC_LAST 6680 {"PC_LAST", _PC_LAST}, 6681#endif 6682#ifdef _PC_LINK_MAX 6683 {"PC_LINK_MAX", _PC_LINK_MAX}, 6684#endif 6685#ifdef _PC_MAX_CANON 6686 {"PC_MAX_CANON", _PC_MAX_CANON}, 6687#endif 6688#ifdef _PC_MAX_INPUT 6689 {"PC_MAX_INPUT", _PC_MAX_INPUT}, 6690#endif 6691#ifdef _PC_NAME_MAX 6692 {"PC_NAME_MAX", _PC_NAME_MAX}, 6693#endif 6694#ifdef _PC_NO_TRUNC 6695 {"PC_NO_TRUNC", _PC_NO_TRUNC}, 6696#endif 6697#ifdef _PC_PATH_MAX 6698 {"PC_PATH_MAX", _PC_PATH_MAX}, 6699#endif 6700#ifdef _PC_PIPE_BUF 6701 {"PC_PIPE_BUF", _PC_PIPE_BUF}, 6702#endif 6703#ifdef _PC_PRIO_IO 6704 {"PC_PRIO_IO", _PC_PRIO_IO}, 6705#endif 6706#ifdef _PC_SOCK_MAXBUF 6707 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF}, 6708#endif 6709#ifdef _PC_SYNC_IO 6710 {"PC_SYNC_IO", _PC_SYNC_IO}, 6711#endif 6712#ifdef _PC_VDISABLE 6713 {"PC_VDISABLE", _PC_VDISABLE}, 6714#endif 6715#ifdef _PC_ACL_ENABLED 6716 {"PC_ACL_ENABLED", _PC_ACL_ENABLED}, 6717#endif 6718#ifdef _PC_MIN_HOLE_SIZE 6719 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE}, 6720#endif 6721#ifdef _PC_ALLOC_SIZE_MIN 6722 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN}, 6723#endif 6724#ifdef _PC_REC_INCR_XFER_SIZE 6725 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE}, 6726#endif 6727#ifdef _PC_REC_MAX_XFER_SIZE 6728 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE}, 6729#endif 6730#ifdef _PC_REC_MIN_XFER_SIZE 6731 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE}, 6732#endif 6733#ifdef _PC_REC_XFER_ALIGN 6734 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN}, 6735#endif 6736#ifdef _PC_SYMLINK_MAX 6737 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX}, 6738#endif 6739#ifdef _PC_XATTR_ENABLED 6740 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED}, 6741#endif 6742#ifdef _PC_XATTR_EXISTS 6743 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS}, 6744#endif 6745#ifdef _PC_TIMESTAMP_RESOLUTION 6746 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION}, 6747#endif 6748}; 6749 6750static int 6751conv_path_confname(PyObject *arg, int *valuep) 6752{ 6753 return conv_confname(arg, valuep, posix_constants_pathconf, 6754 sizeof(posix_constants_pathconf) 6755 / sizeof(struct constdef)); 6756} 6757#endif 6758 6759#ifdef HAVE_FPATHCONF 6760PyDoc_STRVAR(posix_fpathconf__doc__, 6761"fpathconf(fd, name) -> integer\n\n\ 6762Return the configuration limit name for the file descriptor fd.\n\ 6763If there is no limit, return -1."); 6764 6765static PyObject * 6766posix_fpathconf(PyObject *self, PyObject *args) 6767{ 6768 PyObject *result = NULL; 6769 int name, fd; 6770 6771 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd, 6772 conv_path_confname, &name)) { 6773 long limit; 6774 6775 errno = 0; 6776 limit = fpathconf(fd, name); 6777 if (limit == -1 && errno != 0) 6778 posix_error(); 6779 else 6780 result = PyLong_FromLong(limit); 6781 } 6782 return result; 6783} 6784#endif 6785 6786 6787#ifdef HAVE_PATHCONF 6788PyDoc_STRVAR(posix_pathconf__doc__, 6789"pathconf(path, name) -> integer\n\n\ 6790Return the configuration limit name for the file or directory path.\n\ 6791If there is no limit, return -1."); 6792 6793static PyObject * 6794posix_pathconf(PyObject *self, PyObject *args) 6795{ 6796 PyObject *result = NULL; 6797 int name; 6798 char *path; 6799 6800 if (PyArg_ParseTuple(args, "sO&:pathconf", &path, 6801 conv_path_confname, &name)) { 6802 long limit; 6803 6804 errno = 0; 6805 limit = pathconf(path, name); 6806 if (limit == -1 && errno != 0) { 6807 if (errno == EINVAL) 6808 /* could be a path or name problem */ 6809 posix_error(); 6810 else 6811 posix_error_with_filename(path); 6812 } 6813 else 6814 result = PyLong_FromLong(limit); 6815 } 6816 return result; 6817} 6818#endif 6819 6820#ifdef HAVE_CONFSTR 6821static struct constdef posix_constants_confstr[] = { 6822#ifdef _CS_ARCHITECTURE 6823 {"CS_ARCHITECTURE", _CS_ARCHITECTURE}, 6824#endif 6825#ifdef _CS_GNU_LIBC_VERSION 6826 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION}, 6827#endif 6828#ifdef _CS_GNU_LIBPTHREAD_VERSION 6829 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION}, 6830#endif 6831#ifdef _CS_HOSTNAME 6832 {"CS_HOSTNAME", _CS_HOSTNAME}, 6833#endif 6834#ifdef _CS_HW_PROVIDER 6835 {"CS_HW_PROVIDER", _CS_HW_PROVIDER}, 6836#endif 6837#ifdef _CS_HW_SERIAL 6838 {"CS_HW_SERIAL", _CS_HW_SERIAL}, 6839#endif 6840#ifdef _CS_INITTAB_NAME 6841 {"CS_INITTAB_NAME", _CS_INITTAB_NAME}, 6842#endif 6843#ifdef _CS_LFS64_CFLAGS 6844 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS}, 6845#endif 6846#ifdef _CS_LFS64_LDFLAGS 6847 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS}, 6848#endif 6849#ifdef _CS_LFS64_LIBS 6850 {"CS_LFS64_LIBS", _CS_LFS64_LIBS}, 6851#endif 6852#ifdef _CS_LFS64_LINTFLAGS 6853 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS}, 6854#endif 6855#ifdef _CS_LFS_CFLAGS 6856 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS}, 6857#endif 6858#ifdef _CS_LFS_LDFLAGS 6859 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS}, 6860#endif 6861#ifdef _CS_LFS_LIBS 6862 {"CS_LFS_LIBS", _CS_LFS_LIBS}, 6863#endif 6864#ifdef _CS_LFS_LINTFLAGS 6865 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS}, 6866#endif 6867#ifdef _CS_MACHINE 6868 {"CS_MACHINE", _CS_MACHINE}, 6869#endif 6870#ifdef _CS_PATH 6871 {"CS_PATH", _CS_PATH}, 6872#endif 6873#ifdef _CS_RELEASE 6874 {"CS_RELEASE", _CS_RELEASE}, 6875#endif 6876#ifdef _CS_SRPC_DOMAIN 6877 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN}, 6878#endif 6879#ifdef _CS_SYSNAME 6880 {"CS_SYSNAME", _CS_SYSNAME}, 6881#endif 6882#ifdef _CS_VERSION 6883 {"CS_VERSION", _CS_VERSION}, 6884#endif 6885#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS 6886 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS}, 6887#endif 6888#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS 6889 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS}, 6890#endif 6891#ifdef _CS_XBS5_ILP32_OFF32_LIBS 6892 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS}, 6893#endif 6894#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS 6895 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS}, 6896#endif 6897#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS 6898 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS}, 6899#endif 6900#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS 6901 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS}, 6902#endif 6903#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS 6904 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS}, 6905#endif 6906#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS 6907 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS}, 6908#endif 6909#ifdef _CS_XBS5_LP64_OFF64_CFLAGS 6910 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS}, 6911#endif 6912#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS 6913 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS}, 6914#endif 6915#ifdef _CS_XBS5_LP64_OFF64_LIBS 6916 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS}, 6917#endif 6918#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS 6919 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS}, 6920#endif 6921#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS 6922 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS}, 6923#endif 6924#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS 6925 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS}, 6926#endif 6927#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS 6928 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS}, 6929#endif 6930#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS 6931 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS}, 6932#endif 6933#ifdef _MIPS_CS_AVAIL_PROCESSORS 6934 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS}, 6935#endif 6936#ifdef _MIPS_CS_BASE 6937 {"MIPS_CS_BASE", _MIPS_CS_BASE}, 6938#endif 6939#ifdef _MIPS_CS_HOSTID 6940 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID}, 6941#endif 6942#ifdef _MIPS_CS_HW_NAME 6943 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME}, 6944#endif 6945#ifdef _MIPS_CS_NUM_PROCESSORS 6946 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS}, 6947#endif 6948#ifdef _MIPS_CS_OSREL_MAJ 6949 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ}, 6950#endif 6951#ifdef _MIPS_CS_OSREL_MIN 6952 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN}, 6953#endif 6954#ifdef _MIPS_CS_OSREL_PATCH 6955 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH}, 6956#endif 6957#ifdef _MIPS_CS_OS_NAME 6958 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME}, 6959#endif 6960#ifdef _MIPS_CS_OS_PROVIDER 6961 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER}, 6962#endif 6963#ifdef _MIPS_CS_PROCESSORS 6964 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS}, 6965#endif 6966#ifdef _MIPS_CS_SERIAL 6967 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL}, 6968#endif 6969#ifdef _MIPS_CS_VENDOR 6970 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR}, 6971#endif 6972}; 6973 6974static int 6975conv_confstr_confname(PyObject *arg, int *valuep) 6976{ 6977 return conv_confname(arg, valuep, posix_constants_confstr, 6978 sizeof(posix_constants_confstr) 6979 / sizeof(struct constdef)); 6980} 6981 6982PyDoc_STRVAR(posix_confstr__doc__, 6983"confstr(name) -> string\n\n\ 6984Return a string-valued system configuration variable."); 6985 6986static PyObject * 6987posix_confstr(PyObject *self, PyObject *args) 6988{ 6989 PyObject *result = NULL; 6990 int name; 6991 char buffer[255]; 6992 int len; 6993 6994 if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) 6995 return NULL; 6996 6997 errno = 0; 6998 len = confstr(name, buffer, sizeof(buffer)); 6999 if (len == 0) { 7000 if (errno) { 7001 posix_error(); 7002 return NULL; 7003 } 7004 else { 7005 Py_RETURN_NONE; 7006 } 7007 } 7008 7009 if ((unsigned int)len >= sizeof(buffer)) { 7010 char *buf = PyMem_Malloc(len); 7011 if (buf == NULL) 7012 return PyErr_NoMemory(); 7013 confstr(name, buf, len); 7014 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1); 7015 PyMem_Free(buf); 7016 } 7017 else 7018 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1); 7019 return result; 7020} 7021#endif 7022 7023 7024#ifdef HAVE_SYSCONF 7025static struct constdef posix_constants_sysconf[] = { 7026#ifdef _SC_2_CHAR_TERM 7027 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM}, 7028#endif 7029#ifdef _SC_2_C_BIND 7030 {"SC_2_C_BIND", _SC_2_C_BIND}, 7031#endif 7032#ifdef _SC_2_C_DEV 7033 {"SC_2_C_DEV", _SC_2_C_DEV}, 7034#endif 7035#ifdef _SC_2_C_VERSION 7036 {"SC_2_C_VERSION", _SC_2_C_VERSION}, 7037#endif 7038#ifdef _SC_2_FORT_DEV 7039 {"SC_2_FORT_DEV", _SC_2_FORT_DEV}, 7040#endif 7041#ifdef _SC_2_FORT_RUN 7042 {"SC_2_FORT_RUN", _SC_2_FORT_RUN}, 7043#endif 7044#ifdef _SC_2_LOCALEDEF 7045 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF}, 7046#endif 7047#ifdef _SC_2_SW_DEV 7048 {"SC_2_SW_DEV", _SC_2_SW_DEV}, 7049#endif 7050#ifdef _SC_2_UPE 7051 {"SC_2_UPE", _SC_2_UPE}, 7052#endif 7053#ifdef _SC_2_VERSION 7054 {"SC_2_VERSION", _SC_2_VERSION}, 7055#endif 7056#ifdef _SC_ABI_ASYNCHRONOUS_IO 7057 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO}, 7058#endif 7059#ifdef _SC_ACL 7060 {"SC_ACL", _SC_ACL}, 7061#endif 7062#ifdef _SC_AIO_LISTIO_MAX 7063 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX}, 7064#endif 7065#ifdef _SC_AIO_MAX 7066 {"SC_AIO_MAX", _SC_AIO_MAX}, 7067#endif 7068#ifdef _SC_AIO_PRIO_DELTA_MAX 7069 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX}, 7070#endif 7071#ifdef _SC_ARG_MAX 7072 {"SC_ARG_MAX", _SC_ARG_MAX}, 7073#endif 7074#ifdef _SC_ASYNCHRONOUS_IO 7075 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO}, 7076#endif 7077#ifdef _SC_ATEXIT_MAX 7078 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX}, 7079#endif 7080#ifdef _SC_AUDIT 7081 {"SC_AUDIT", _SC_AUDIT}, 7082#endif 7083#ifdef _SC_AVPHYS_PAGES 7084 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES}, 7085#endif 7086#ifdef _SC_BC_BASE_MAX 7087 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX}, 7088#endif 7089#ifdef _SC_BC_DIM_MAX 7090 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX}, 7091#endif 7092#ifdef _SC_BC_SCALE_MAX 7093 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX}, 7094#endif 7095#ifdef _SC_BC_STRING_MAX 7096 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX}, 7097#endif 7098#ifdef _SC_CAP 7099 {"SC_CAP", _SC_CAP}, 7100#endif 7101#ifdef _SC_CHARCLASS_NAME_MAX 7102 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX}, 7103#endif 7104#ifdef _SC_CHAR_BIT 7105 {"SC_CHAR_BIT", _SC_CHAR_BIT}, 7106#endif 7107#ifdef _SC_CHAR_MAX 7108 {"SC_CHAR_MAX", _SC_CHAR_MAX}, 7109#endif 7110#ifdef _SC_CHAR_MIN 7111 {"SC_CHAR_MIN", _SC_CHAR_MIN}, 7112#endif 7113#ifdef _SC_CHILD_MAX 7114 {"SC_CHILD_MAX", _SC_CHILD_MAX}, 7115#endif 7116#ifdef _SC_CLK_TCK 7117 {"SC_CLK_TCK", _SC_CLK_TCK}, 7118#endif 7119#ifdef _SC_COHER_BLKSZ 7120 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ}, 7121#endif 7122#ifdef _SC_COLL_WEIGHTS_MAX 7123 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX}, 7124#endif 7125#ifdef _SC_DCACHE_ASSOC 7126 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC}, 7127#endif 7128#ifdef _SC_DCACHE_BLKSZ 7129 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ}, 7130#endif 7131#ifdef _SC_DCACHE_LINESZ 7132 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ}, 7133#endif 7134#ifdef _SC_DCACHE_SZ 7135 {"SC_DCACHE_SZ", _SC_DCACHE_SZ}, 7136#endif 7137#ifdef _SC_DCACHE_TBLKSZ 7138 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ}, 7139#endif 7140#ifdef _SC_DELAYTIMER_MAX 7141 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX}, 7142#endif 7143#ifdef _SC_EQUIV_CLASS_MAX 7144 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX}, 7145#endif 7146#ifdef _SC_EXPR_NEST_MAX 7147 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX}, 7148#endif 7149#ifdef _SC_FSYNC 7150 {"SC_FSYNC", _SC_FSYNC}, 7151#endif 7152#ifdef _SC_GETGR_R_SIZE_MAX 7153 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX}, 7154#endif 7155#ifdef _SC_GETPW_R_SIZE_MAX 7156 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX}, 7157#endif 7158#ifdef _SC_ICACHE_ASSOC 7159 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC}, 7160#endif 7161#ifdef _SC_ICACHE_BLKSZ 7162 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ}, 7163#endif 7164#ifdef _SC_ICACHE_LINESZ 7165 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ}, 7166#endif 7167#ifdef _SC_ICACHE_SZ 7168 {"SC_ICACHE_SZ", _SC_ICACHE_SZ}, 7169#endif 7170#ifdef _SC_INF 7171 {"SC_INF", _SC_INF}, 7172#endif 7173#ifdef _SC_INT_MAX 7174 {"SC_INT_MAX", _SC_INT_MAX}, 7175#endif 7176#ifdef _SC_INT_MIN 7177 {"SC_INT_MIN", _SC_INT_MIN}, 7178#endif 7179#ifdef _SC_IOV_MAX 7180 {"SC_IOV_MAX", _SC_IOV_MAX}, 7181#endif 7182#ifdef _SC_IP_SECOPTS 7183 {"SC_IP_SECOPTS", _SC_IP_SECOPTS}, 7184#endif 7185#ifdef _SC_JOB_CONTROL 7186 {"SC_JOB_CONTROL", _SC_JOB_CONTROL}, 7187#endif 7188#ifdef _SC_KERN_POINTERS 7189 {"SC_KERN_POINTERS", _SC_KERN_POINTERS}, 7190#endif 7191#ifdef _SC_KERN_SIM 7192 {"SC_KERN_SIM", _SC_KERN_SIM}, 7193#endif 7194#ifdef _SC_LINE_MAX 7195 {"SC_LINE_MAX", _SC_LINE_MAX}, 7196#endif 7197#ifdef _SC_LOGIN_NAME_MAX 7198 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX}, 7199#endif 7200#ifdef _SC_LOGNAME_MAX 7201 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX}, 7202#endif 7203#ifdef _SC_LONG_BIT 7204 {"SC_LONG_BIT", _SC_LONG_BIT}, 7205#endif 7206#ifdef _SC_MAC 7207 {"SC_MAC", _SC_MAC}, 7208#endif 7209#ifdef _SC_MAPPED_FILES 7210 {"SC_MAPPED_FILES", _SC_MAPPED_FILES}, 7211#endif 7212#ifdef _SC_MAXPID 7213 {"SC_MAXPID", _SC_MAXPID}, 7214#endif 7215#ifdef _SC_MB_LEN_MAX 7216 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX}, 7217#endif 7218#ifdef _SC_MEMLOCK 7219 {"SC_MEMLOCK", _SC_MEMLOCK}, 7220#endif 7221#ifdef _SC_MEMLOCK_RANGE 7222 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE}, 7223#endif 7224#ifdef _SC_MEMORY_PROTECTION 7225 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION}, 7226#endif 7227#ifdef _SC_MESSAGE_PASSING 7228 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING}, 7229#endif 7230#ifdef _SC_MMAP_FIXED_ALIGNMENT 7231 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT}, 7232#endif 7233#ifdef _SC_MQ_OPEN_MAX 7234 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX}, 7235#endif 7236#ifdef _SC_MQ_PRIO_MAX 7237 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX}, 7238#endif 7239#ifdef _SC_NACLS_MAX 7240 {"SC_NACLS_MAX", _SC_NACLS_MAX}, 7241#endif 7242#ifdef _SC_NGROUPS_MAX 7243 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX}, 7244#endif 7245#ifdef _SC_NL_ARGMAX 7246 {"SC_NL_ARGMAX", _SC_NL_ARGMAX}, 7247#endif 7248#ifdef _SC_NL_LANGMAX 7249 {"SC_NL_LANGMAX", _SC_NL_LANGMAX}, 7250#endif 7251#ifdef _SC_NL_MSGMAX 7252 {"SC_NL_MSGMAX", _SC_NL_MSGMAX}, 7253#endif 7254#ifdef _SC_NL_NMAX 7255 {"SC_NL_NMAX", _SC_NL_NMAX}, 7256#endif 7257#ifdef _SC_NL_SETMAX 7258 {"SC_NL_SETMAX", _SC_NL_SETMAX}, 7259#endif 7260#ifdef _SC_NL_TEXTMAX 7261 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX}, 7262#endif 7263#ifdef _SC_NPROCESSORS_CONF 7264 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF}, 7265#endif 7266#ifdef _SC_NPROCESSORS_ONLN 7267 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN}, 7268#endif 7269#ifdef _SC_NPROC_CONF 7270 {"SC_NPROC_CONF", _SC_NPROC_CONF}, 7271#endif 7272#ifdef _SC_NPROC_ONLN 7273 {"SC_NPROC_ONLN", _SC_NPROC_ONLN}, 7274#endif 7275#ifdef _SC_NZERO 7276 {"SC_NZERO", _SC_NZERO}, 7277#endif 7278#ifdef _SC_OPEN_MAX 7279 {"SC_OPEN_MAX", _SC_OPEN_MAX}, 7280#endif 7281#ifdef _SC_PAGESIZE 7282 {"SC_PAGESIZE", _SC_PAGESIZE}, 7283#endif 7284#ifdef _SC_PAGE_SIZE 7285 {"SC_PAGE_SIZE", _SC_PAGE_SIZE}, 7286#endif 7287#ifdef _SC_PASS_MAX 7288 {"SC_PASS_MAX", _SC_PASS_MAX}, 7289#endif 7290#ifdef _SC_PHYS_PAGES 7291 {"SC_PHYS_PAGES", _SC_PHYS_PAGES}, 7292#endif 7293#ifdef _SC_PII 7294 {"SC_PII", _SC_PII}, 7295#endif 7296#ifdef _SC_PII_INTERNET 7297 {"SC_PII_INTERNET", _SC_PII_INTERNET}, 7298#endif 7299#ifdef _SC_PII_INTERNET_DGRAM 7300 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM}, 7301#endif 7302#ifdef _SC_PII_INTERNET_STREAM 7303 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM}, 7304#endif 7305#ifdef _SC_PII_OSI 7306 {"SC_PII_OSI", _SC_PII_OSI}, 7307#endif 7308#ifdef _SC_PII_OSI_CLTS 7309 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS}, 7310#endif 7311#ifdef _SC_PII_OSI_COTS 7312 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS}, 7313#endif 7314#ifdef _SC_PII_OSI_M 7315 {"SC_PII_OSI_M", _SC_PII_OSI_M}, 7316#endif 7317#ifdef _SC_PII_SOCKET 7318 {"SC_PII_SOCKET", _SC_PII_SOCKET}, 7319#endif 7320#ifdef _SC_PII_XTI 7321 {"SC_PII_XTI", _SC_PII_XTI}, 7322#endif 7323#ifdef _SC_POLL 7324 {"SC_POLL", _SC_POLL}, 7325#endif 7326#ifdef _SC_PRIORITIZED_IO 7327 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO}, 7328#endif 7329#ifdef _SC_PRIORITY_SCHEDULING 7330 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING}, 7331#endif 7332#ifdef _SC_REALTIME_SIGNALS 7333 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS}, 7334#endif 7335#ifdef _SC_RE_DUP_MAX 7336 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX}, 7337#endif 7338#ifdef _SC_RTSIG_MAX 7339 {"SC_RTSIG_MAX", _SC_RTSIG_MAX}, 7340#endif 7341#ifdef _SC_SAVED_IDS 7342 {"SC_SAVED_IDS", _SC_SAVED_IDS}, 7343#endif 7344#ifdef _SC_SCHAR_MAX 7345 {"SC_SCHAR_MAX", _SC_SCHAR_MAX}, 7346#endif 7347#ifdef _SC_SCHAR_MIN 7348 {"SC_SCHAR_MIN", _SC_SCHAR_MIN}, 7349#endif 7350#ifdef _SC_SELECT 7351 {"SC_SELECT", _SC_SELECT}, 7352#endif 7353#ifdef _SC_SEMAPHORES 7354 {"SC_SEMAPHORES", _SC_SEMAPHORES}, 7355#endif 7356#ifdef _SC_SEM_NSEMS_MAX 7357 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX}, 7358#endif 7359#ifdef _SC_SEM_VALUE_MAX 7360 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX}, 7361#endif 7362#ifdef _SC_SHARED_MEMORY_OBJECTS 7363 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS}, 7364#endif 7365#ifdef _SC_SHRT_MAX 7366 {"SC_SHRT_MAX", _SC_SHRT_MAX}, 7367#endif 7368#ifdef _SC_SHRT_MIN 7369 {"SC_SHRT_MIN", _SC_SHRT_MIN}, 7370#endif 7371#ifdef _SC_SIGQUEUE_MAX 7372 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX}, 7373#endif 7374#ifdef _SC_SIGRT_MAX 7375 {"SC_SIGRT_MAX", _SC_SIGRT_MAX}, 7376#endif 7377#ifdef _SC_SIGRT_MIN 7378 {"SC_SIGRT_MIN", _SC_SIGRT_MIN}, 7379#endif 7380#ifdef _SC_SOFTPOWER 7381 {"SC_SOFTPOWER", _SC_SOFTPOWER}, 7382#endif 7383#ifdef _SC_SPLIT_CACHE 7384 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE}, 7385#endif 7386#ifdef _SC_SSIZE_MAX 7387 {"SC_SSIZE_MAX", _SC_SSIZE_MAX}, 7388#endif 7389#ifdef _SC_STACK_PROT 7390 {"SC_STACK_PROT", _SC_STACK_PROT}, 7391#endif 7392#ifdef _SC_STREAM_MAX 7393 {"SC_STREAM_MAX", _SC_STREAM_MAX}, 7394#endif 7395#ifdef _SC_SYNCHRONIZED_IO 7396 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO}, 7397#endif 7398#ifdef _SC_THREADS 7399 {"SC_THREADS", _SC_THREADS}, 7400#endif 7401#ifdef _SC_THREAD_ATTR_STACKADDR 7402 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR}, 7403#endif 7404#ifdef _SC_THREAD_ATTR_STACKSIZE 7405 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE}, 7406#endif 7407#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS 7408 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS}, 7409#endif 7410#ifdef _SC_THREAD_KEYS_MAX 7411 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX}, 7412#endif 7413#ifdef _SC_THREAD_PRIORITY_SCHEDULING 7414 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING}, 7415#endif 7416#ifdef _SC_THREAD_PRIO_INHERIT 7417 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT}, 7418#endif 7419#ifdef _SC_THREAD_PRIO_PROTECT 7420 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT}, 7421#endif 7422#ifdef _SC_THREAD_PROCESS_SHARED 7423 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED}, 7424#endif 7425#ifdef _SC_THREAD_SAFE_FUNCTIONS 7426 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS}, 7427#endif 7428#ifdef _SC_THREAD_STACK_MIN 7429 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN}, 7430#endif 7431#ifdef _SC_THREAD_THREADS_MAX 7432 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX}, 7433#endif 7434#ifdef _SC_TIMERS 7435 {"SC_TIMERS", _SC_TIMERS}, 7436#endif 7437#ifdef _SC_TIMER_MAX 7438 {"SC_TIMER_MAX", _SC_TIMER_MAX}, 7439#endif 7440#ifdef _SC_TTY_NAME_MAX 7441 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX}, 7442#endif 7443#ifdef _SC_TZNAME_MAX 7444 {"SC_TZNAME_MAX", _SC_TZNAME_MAX}, 7445#endif 7446#ifdef _SC_T_IOV_MAX 7447 {"SC_T_IOV_MAX", _SC_T_IOV_MAX}, 7448#endif 7449#ifdef _SC_UCHAR_MAX 7450 {"SC_UCHAR_MAX", _SC_UCHAR_MAX}, 7451#endif 7452#ifdef _SC_UINT_MAX 7453 {"SC_UINT_MAX", _SC_UINT_MAX}, 7454#endif 7455#ifdef _SC_UIO_MAXIOV 7456 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV}, 7457#endif 7458#ifdef _SC_ULONG_MAX 7459 {"SC_ULONG_MAX", _SC_ULONG_MAX}, 7460#endif 7461#ifdef _SC_USHRT_MAX 7462 {"SC_USHRT_MAX", _SC_USHRT_MAX}, 7463#endif 7464#ifdef _SC_VERSION 7465 {"SC_VERSION", _SC_VERSION}, 7466#endif 7467#ifdef _SC_WORD_BIT 7468 {"SC_WORD_BIT", _SC_WORD_BIT}, 7469#endif 7470#ifdef _SC_XBS5_ILP32_OFF32 7471 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32}, 7472#endif 7473#ifdef _SC_XBS5_ILP32_OFFBIG 7474 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG}, 7475#endif 7476#ifdef _SC_XBS5_LP64_OFF64 7477 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64}, 7478#endif 7479#ifdef _SC_XBS5_LPBIG_OFFBIG 7480 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG}, 7481#endif 7482#ifdef _SC_XOPEN_CRYPT 7483 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT}, 7484#endif 7485#ifdef _SC_XOPEN_ENH_I18N 7486 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N}, 7487#endif 7488#ifdef _SC_XOPEN_LEGACY 7489 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY}, 7490#endif 7491#ifdef _SC_XOPEN_REALTIME 7492 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME}, 7493#endif 7494#ifdef _SC_XOPEN_REALTIME_THREADS 7495 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS}, 7496#endif 7497#ifdef _SC_XOPEN_SHM 7498 {"SC_XOPEN_SHM", _SC_XOPEN_SHM}, 7499#endif 7500#ifdef _SC_XOPEN_UNIX 7501 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX}, 7502#endif 7503#ifdef _SC_XOPEN_VERSION 7504 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION}, 7505#endif 7506#ifdef _SC_XOPEN_XCU_VERSION 7507 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION}, 7508#endif 7509#ifdef _SC_XOPEN_XPG2 7510 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2}, 7511#endif 7512#ifdef _SC_XOPEN_XPG3 7513 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3}, 7514#endif 7515#ifdef _SC_XOPEN_XPG4 7516 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4}, 7517#endif 7518}; 7519 7520static int 7521conv_sysconf_confname(PyObject *arg, int *valuep) 7522{ 7523 return conv_confname(arg, valuep, posix_constants_sysconf, 7524 sizeof(posix_constants_sysconf) 7525 / sizeof(struct constdef)); 7526} 7527 7528PyDoc_STRVAR(posix_sysconf__doc__, 7529"sysconf(name) -> integer\n\n\ 7530Return an integer-valued system configuration variable."); 7531 7532static PyObject * 7533posix_sysconf(PyObject *self, PyObject *args) 7534{ 7535 PyObject *result = NULL; 7536 int name; 7537 7538 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) { 7539 int value; 7540 7541 errno = 0; 7542 value = sysconf(name); 7543 if (value == -1 && errno != 0) 7544 posix_error(); 7545 else 7546 result = PyLong_FromLong(value); 7547 } 7548 return result; 7549} 7550#endif 7551 7552 7553/* This code is used to ensure that the tables of configuration value names 7554 * are in sorted order as required by conv_confname(), and also to build the 7555 * the exported dictionaries that are used to publish information about the 7556 * names available on the host platform. 7557 * 7558 * Sorting the table at runtime ensures that the table is properly ordered 7559 * when used, even for platforms we're not able to test on. It also makes 7560 * it easier to add additional entries to the tables. 7561 */ 7562 7563static int 7564cmp_constdefs(const void *v1, const void *v2) 7565{ 7566 const struct constdef *c1 = 7567 (const struct constdef *) v1; 7568 const struct constdef *c2 = 7569 (const struct constdef *) v2; 7570 7571 return strcmp(c1->name, c2->name); 7572} 7573 7574static int 7575setup_confname_table(struct constdef *table, size_t tablesize, 7576 char *tablename, PyObject *module) 7577{ 7578 PyObject *d = NULL; 7579 size_t i; 7580 7581 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs); 7582 d = PyDict_New(); 7583 if (d == NULL) 7584 return -1; 7585 7586 for (i=0; i < tablesize; ++i) { 7587 PyObject *o = PyLong_FromLong(table[i].value); 7588 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) { 7589 Py_XDECREF(o); 7590 Py_DECREF(d); 7591 return -1; 7592 } 7593 Py_DECREF(o); 7594 } 7595 return PyModule_AddObject(module, tablename, d); 7596} 7597 7598/* Return -1 on failure, 0 on success. */ 7599static int 7600setup_confname_tables(PyObject *module) 7601{ 7602#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF) 7603 if (setup_confname_table(posix_constants_pathconf, 7604 sizeof(posix_constants_pathconf) 7605 / sizeof(struct constdef), 7606 "pathconf_names", module)) 7607 return -1; 7608#endif 7609#ifdef HAVE_CONFSTR 7610 if (setup_confname_table(posix_constants_confstr, 7611 sizeof(posix_constants_confstr) 7612 / sizeof(struct constdef), 7613 "confstr_names", module)) 7614 return -1; 7615#endif 7616#ifdef HAVE_SYSCONF 7617 if (setup_confname_table(posix_constants_sysconf, 7618 sizeof(posix_constants_sysconf) 7619 / sizeof(struct constdef), 7620 "sysconf_names", module)) 7621 return -1; 7622#endif 7623 return 0; 7624} 7625 7626 7627PyDoc_STRVAR(posix_abort__doc__, 7628"abort() -> does not return!\n\n\ 7629Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\ 7630in the hardest way possible on the hosting operating system."); 7631 7632static PyObject * 7633posix_abort(PyObject *self, PyObject *noargs) 7634{ 7635 abort(); 7636 /*NOTREACHED*/ 7637 Py_FatalError("abort() called from Python code didn't abort!"); 7638 return NULL; 7639} 7640 7641#ifdef MS_WINDOWS 7642PyDoc_STRVAR(win32_startfile__doc__, 7643"startfile(filepath [, operation]) - Start a file with its associated\n\ 7644application.\n\ 7645\n\ 7646When \"operation\" is not specified or \"open\", this acts like\n\ 7647double-clicking the file in Explorer, or giving the file name as an\n\ 7648argument to the DOS \"start\" command: the file is opened with whatever\n\ 7649application (if any) its extension is associated.\n\ 7650When another \"operation\" is given, it specifies what should be done with\n\ 7651the file. A typical operation is \"print\".\n\ 7652\n\ 7653startfile returns as soon as the associated application is launched.\n\ 7654There is no option to wait for the application to close, and no way\n\ 7655to retrieve the application's exit status.\n\ 7656\n\ 7657The filepath is relative to the current directory. If you want to use\n\ 7658an absolute path, make sure the first character is not a slash (\"/\");\n\ 7659the underlying Win32 ShellExecute function doesn't work if it is."); 7660 7661static PyObject * 7662win32_startfile(PyObject *self, PyObject *args) 7663{ 7664 PyObject *ofilepath; 7665 char *filepath; 7666 char *operation = NULL; 7667 HINSTANCE rc; 7668 7669 PyObject *unipath, *woperation = NULL; 7670 if (!PyArg_ParseTuple(args, "U|s:startfile", 7671 &unipath, &operation)) { 7672 PyErr_Clear(); 7673 goto normal; 7674 } 7675 7676 if (operation) { 7677 woperation = PyUnicode_DecodeASCII(operation, 7678 strlen(operation), NULL); 7679 if (!woperation) { 7680 PyErr_Clear(); 7681 operation = NULL; 7682 goto normal; 7683 } 7684 } 7685 7686 Py_BEGIN_ALLOW_THREADS 7687 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0, 7688 PyUnicode_AS_UNICODE(unipath), 7689 NULL, NULL, SW_SHOWNORMAL); 7690 Py_END_ALLOW_THREADS 7691 7692 Py_XDECREF(woperation); 7693 if (rc <= (HINSTANCE)32) { 7694 PyObject *errval = win32_error_unicode("startfile", 7695 PyUnicode_AS_UNICODE(unipath)); 7696 return errval; 7697 } 7698 Py_INCREF(Py_None); 7699 return Py_None; 7700 7701normal: 7702 if (!PyArg_ParseTuple(args, "O&|s:startfile", 7703 PyUnicode_FSConverter, &ofilepath, 7704 &operation)) 7705 return NULL; 7706 filepath = PyBytes_AsString(ofilepath); 7707 Py_BEGIN_ALLOW_THREADS 7708 rc = ShellExecute((HWND)0, operation, filepath, 7709 NULL, NULL, SW_SHOWNORMAL); 7710 Py_END_ALLOW_THREADS 7711 if (rc <= (HINSTANCE)32) { 7712 PyObject *errval = win32_error("startfile", filepath); 7713 Py_DECREF(ofilepath); 7714 return errval; 7715 } 7716 Py_DECREF(ofilepath); 7717 Py_INCREF(Py_None); 7718 return Py_None; 7719} 7720#endif 7721 7722#ifdef HAVE_GETLOADAVG 7723PyDoc_STRVAR(posix_getloadavg__doc__, 7724"getloadavg() -> (float, float, float)\n\n\ 7725Return the number of processes in the system run queue averaged over\n\ 7726the last 1, 5, and 15 minutes or raises OSError if the load average\n\ 7727was unobtainable"); 7728 7729static PyObject * 7730posix_getloadavg(PyObject *self, PyObject *noargs) 7731{ 7732 double loadavg[3]; 7733 if (getloadavg(loadavg, 3)!=3) { 7734 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable"); 7735 return NULL; 7736 } else 7737 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]); 7738} 7739#endif 7740 7741#ifdef MS_WINDOWS 7742 7743PyDoc_STRVAR(win32_urandom__doc__, 7744"urandom(n) -> str\n\n\ 7745Return n random bytes suitable for cryptographic use."); 7746 7747typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\ 7748 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\ 7749 DWORD dwFlags ); 7750typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\ 7751 BYTE *pbBuffer ); 7752 7753static CRYPTGENRANDOM pCryptGenRandom = NULL; 7754/* This handle is never explicitly released. Instead, the operating 7755 system will release it when the process terminates. */ 7756static HCRYPTPROV hCryptProv = 0; 7757 7758static PyObject* 7759win32_urandom(PyObject *self, PyObject *args) 7760{ 7761 int howMany; 7762 PyObject* result; 7763 7764 /* Read arguments */ 7765 if (! PyArg_ParseTuple(args, "i:urandom", &howMany)) 7766 return NULL; 7767 if (howMany < 0) 7768 return PyErr_Format(PyExc_ValueError, 7769 "negative argument not allowed"); 7770 7771 if (hCryptProv == 0) { 7772 HINSTANCE hAdvAPI32 = NULL; 7773 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL; 7774 7775 /* Obtain handle to the DLL containing CryptoAPI 7776 This should not fail */ 7777 hAdvAPI32 = GetModuleHandle("advapi32.dll"); 7778 if(hAdvAPI32 == NULL) 7779 return win32_error("GetModuleHandle", NULL); 7780 7781 /* Obtain pointers to the CryptoAPI functions 7782 This will fail on some early versions of Win95 */ 7783 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress( 7784 hAdvAPI32, 7785 "CryptAcquireContextA"); 7786 if (pCryptAcquireContext == NULL) 7787 return PyErr_Format(PyExc_NotImplementedError, 7788 "CryptAcquireContextA not found"); 7789 7790 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress( 7791 hAdvAPI32, "CryptGenRandom"); 7792 if (pCryptGenRandom == NULL) 7793 return PyErr_Format(PyExc_NotImplementedError, 7794 "CryptGenRandom not found"); 7795 7796 /* Acquire context */ 7797 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL, 7798 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) 7799 return win32_error("CryptAcquireContext", NULL); 7800 } 7801 7802 /* Allocate bytes */ 7803 result = PyBytes_FromStringAndSize(NULL, howMany); 7804 if (result != NULL) { 7805 /* Get random data */ 7806 memset(PyBytes_AS_STRING(result), 0, howMany); /* zero seed */ 7807 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*) 7808 PyBytes_AS_STRING(result))) { 7809 Py_DECREF(result); 7810 return win32_error("CryptGenRandom", NULL); 7811 } 7812 } 7813 return result; 7814} 7815#endif 7816 7817PyDoc_STRVAR(device_encoding__doc__, 7818"device_encoding(fd) -> str\n\n\ 7819Return a string describing the encoding of the device\n\ 7820if the output is a terminal; else return None."); 7821 7822static PyObject * 7823device_encoding(PyObject *self, PyObject *args) 7824{ 7825 int fd; 7826 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd)) 7827 return NULL; 7828 if (!_PyVerify_fd(fd) || !isatty(fd)) { 7829 Py_INCREF(Py_None); 7830 return Py_None; 7831 } 7832#if defined(MS_WINDOWS) || defined(MS_WIN64) 7833 if (fd == 0) { 7834 char buf[100]; 7835 sprintf(buf, "cp%d", GetConsoleCP()); 7836 return PyUnicode_FromString(buf); 7837 } 7838 if (fd == 1 || fd == 2) { 7839 char buf[100]; 7840 sprintf(buf, "cp%d", GetConsoleOutputCP()); 7841 return PyUnicode_FromString(buf); 7842 } 7843#elif defined(CODESET) 7844 { 7845 char *codeset = nl_langinfo(CODESET); 7846 if (codeset != NULL && codeset[0] != 0) 7847 return PyUnicode_FromString(codeset); 7848 } 7849#endif 7850 Py_INCREF(Py_None); 7851 return Py_None; 7852} 7853 7854#ifdef __VMS 7855/* Use openssl random routine */ 7856#include <openssl/rand.h> 7857PyDoc_STRVAR(vms_urandom__doc__, 7858"urandom(n) -> str\n\n\ 7859Return n random bytes suitable for cryptographic use."); 7860 7861static PyObject* 7862vms_urandom(PyObject *self, PyObject *args) 7863{ 7864 int howMany; 7865 PyObject* result; 7866 7867 /* Read arguments */ 7868 if (! PyArg_ParseTuple(args, "i:urandom", &howMany)) 7869 return NULL; 7870 if (howMany < 0) 7871 return PyErr_Format(PyExc_ValueError, 7872 "negative argument not allowed"); 7873 7874 /* Allocate bytes */ 7875 result = PyBytes_FromStringAndSize(NULL, howMany); 7876 if (result != NULL) { 7877 /* Get random data */ 7878 if (RAND_pseudo_bytes((unsigned char*) 7879 PyBytes_AS_STRING(result), 7880 howMany) < 0) { 7881 Py_DECREF(result); 7882 return PyErr_Format(PyExc_ValueError, 7883 "RAND_pseudo_bytes"); 7884 } 7885 } 7886 return result; 7887} 7888#endif 7889 7890#ifdef HAVE_SETRESUID 7891PyDoc_STRVAR(posix_setresuid__doc__, 7892"setresuid(ruid, euid, suid)\n\n\ 7893Set the current process's real, effective, and saved user ids."); 7894 7895static PyObject* 7896posix_setresuid (PyObject *self, PyObject *args) 7897{ 7898 /* We assume uid_t is no larger than a long. */ 7899 long ruid, euid, suid; 7900 if (!PyArg_ParseTuple(args, "lll", &ruid, &euid, &suid)) 7901 return NULL; 7902 if (setresuid(ruid, euid, suid) < 0) 7903 return posix_error(); 7904 Py_RETURN_NONE; 7905} 7906#endif 7907 7908#ifdef HAVE_SETRESGID 7909PyDoc_STRVAR(posix_setresgid__doc__, 7910"setresgid(rgid, egid, sgid)\n\n\ 7911Set the current process's real, effective, and saved group ids."); 7912 7913static PyObject* 7914posix_setresgid (PyObject *self, PyObject *args) 7915{ 7916 /* We assume uid_t is no larger than a long. */ 7917 long rgid, egid, sgid; 7918 if (!PyArg_ParseTuple(args, "lll", &rgid, &egid, &sgid)) 7919 return NULL; 7920 if (setresgid(rgid, egid, sgid) < 0) 7921 return posix_error(); 7922 Py_RETURN_NONE; 7923} 7924#endif 7925 7926#ifdef HAVE_GETRESUID 7927PyDoc_STRVAR(posix_getresuid__doc__, 7928"getresuid() -> (ruid, euid, suid)\n\n\ 7929Get tuple of the current process's real, effective, and saved user ids."); 7930 7931static PyObject* 7932posix_getresuid (PyObject *self, PyObject *noargs) 7933{ 7934 uid_t ruid, euid, suid; 7935 long l_ruid, l_euid, l_suid; 7936 if (getresuid(&ruid, &euid, &suid) < 0) 7937 return posix_error(); 7938 /* Force the values into long's as we don't know the size of uid_t. */ 7939 l_ruid = ruid; 7940 l_euid = euid; 7941 l_suid = suid; 7942 return Py_BuildValue("(lll)", l_ruid, l_euid, l_suid); 7943} 7944#endif 7945 7946#ifdef HAVE_GETRESGID 7947PyDoc_STRVAR(posix_getresgid__doc__, 7948"getresgid() -> (rgid, egid, sgid)\n\n\ 7949Get tuple of the current process's real, effective, and saved group ids."); 7950 7951static PyObject* 7952posix_getresgid (PyObject *self, PyObject *noargs) 7953{ 7954 uid_t rgid, egid, sgid; 7955 long l_rgid, l_egid, l_sgid; 7956 if (getresgid(&rgid, &egid, &sgid) < 0) 7957 return posix_error(); 7958 /* Force the values into long's as we don't know the size of uid_t. */ 7959 l_rgid = rgid; 7960 l_egid = egid; 7961 l_sgid = sgid; 7962 return Py_BuildValue("(lll)", l_rgid, l_egid, l_sgid); 7963} 7964#endif 7965 7966static PyMethodDef posix_methods[] = { 7967 {"access", posix_access, METH_VARARGS, posix_access__doc__}, 7968#ifdef HAVE_TTYNAME 7969 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__}, 7970#endif 7971 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__}, 7972#ifdef HAVE_CHFLAGS 7973 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__}, 7974#endif /* HAVE_CHFLAGS */ 7975 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__}, 7976#ifdef HAVE_FCHMOD 7977 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__}, 7978#endif /* HAVE_FCHMOD */ 7979#ifdef HAVE_CHOWN 7980 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__}, 7981#endif /* HAVE_CHOWN */ 7982#ifdef HAVE_LCHMOD 7983 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__}, 7984#endif /* HAVE_LCHMOD */ 7985#ifdef HAVE_FCHOWN 7986 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__}, 7987#endif /* HAVE_FCHOWN */ 7988#ifdef HAVE_LCHFLAGS 7989 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__}, 7990#endif /* HAVE_LCHFLAGS */ 7991#ifdef HAVE_LCHOWN 7992 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__}, 7993#endif /* HAVE_LCHOWN */ 7994#ifdef HAVE_CHROOT 7995 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__}, 7996#endif 7997#ifdef HAVE_CTERMID 7998 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__}, 7999#endif 8000#ifdef HAVE_GETCWD 8001 {"getcwd", (PyCFunction)posix_getcwd_unicode, 8002 METH_NOARGS, posix_getcwd__doc__}, 8003 {"getcwdb", (PyCFunction)posix_getcwd_bytes, 8004 METH_NOARGS, posix_getcwdb__doc__}, 8005#endif 8006#ifdef HAVE_LINK 8007 {"link", posix_link, METH_VARARGS, posix_link__doc__}, 8008#endif /* HAVE_LINK */ 8009 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__}, 8010 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__}, 8011 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__}, 8012#ifdef HAVE_NICE 8013 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__}, 8014#endif /* HAVE_NICE */ 8015#ifdef HAVE_READLINK 8016 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__}, 8017#endif /* HAVE_READLINK */ 8018#if !defined(HAVE_READLINK) && defined(MS_WINDOWS) 8019 {"readlink", win_readlink, METH_VARARGS, win_readlink__doc__}, 8020#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */ 8021 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__}, 8022 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__}, 8023 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__}, 8024 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__}, 8025#if defined(HAVE_SYMLINK) && !defined(MS_WINDOWS) 8026 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__}, 8027#endif /* HAVE_SYMLINK */ 8028#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS) 8029 {"symlink", (PyCFunction)win_symlink, METH_VARARGS | METH_KEYWORDS, 8030 win_symlink__doc__}, 8031#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */ 8032#ifdef HAVE_SYSTEM 8033 {"system", posix_system, METH_VARARGS, posix_system__doc__}, 8034#endif 8035 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__}, 8036#ifdef HAVE_UNAME 8037 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__}, 8038#endif /* HAVE_UNAME */ 8039 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__}, 8040 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__}, 8041 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__}, 8042#ifdef HAVE_TIMES 8043 {"times", posix_times, METH_NOARGS, posix_times__doc__}, 8044#endif /* HAVE_TIMES */ 8045 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__}, 8046#ifdef HAVE_EXECV 8047 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__}, 8048 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__}, 8049#endif /* HAVE_EXECV */ 8050#ifdef HAVE_SPAWNV 8051 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__}, 8052 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__}, 8053#if defined(PYOS_OS2) 8054 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__}, 8055 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__}, 8056#endif /* PYOS_OS2 */ 8057#endif /* HAVE_SPAWNV */ 8058#ifdef HAVE_FORK1 8059 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__}, 8060#endif /* HAVE_FORK1 */ 8061#ifdef HAVE_FORK 8062 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__}, 8063#endif /* HAVE_FORK */ 8064#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) 8065 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__}, 8066#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */ 8067#ifdef HAVE_FORKPTY 8068 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__}, 8069#endif /* HAVE_FORKPTY */ 8070#ifdef HAVE_GETEGID 8071 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__}, 8072#endif /* HAVE_GETEGID */ 8073#ifdef HAVE_GETEUID 8074 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__}, 8075#endif /* HAVE_GETEUID */ 8076#ifdef HAVE_GETGID 8077 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__}, 8078#endif /* HAVE_GETGID */ 8079#ifdef HAVE_GETGROUPS 8080 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__}, 8081#endif 8082 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__}, 8083#ifdef HAVE_GETPGRP 8084 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__}, 8085#endif /* HAVE_GETPGRP */ 8086#ifdef HAVE_GETPPID 8087 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__}, 8088#endif /* HAVE_GETPPID */ 8089#ifdef HAVE_GETUID 8090 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__}, 8091#endif /* HAVE_GETUID */ 8092#ifdef HAVE_GETLOGIN 8093 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__}, 8094#endif 8095#ifdef HAVE_KILL 8096 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__}, 8097#endif /* HAVE_KILL */ 8098#ifdef HAVE_KILLPG 8099 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__}, 8100#endif /* HAVE_KILLPG */ 8101#ifdef HAVE_PLOCK 8102 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__}, 8103#endif /* HAVE_PLOCK */ 8104#ifdef MS_WINDOWS 8105 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__}, 8106 {"kill", win32_kill, METH_VARARGS, win32_kill__doc__}, 8107 {"link", win32_link, METH_VARARGS, win32_link__doc__}, 8108#endif 8109#ifdef HAVE_SETUID 8110 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__}, 8111#endif /* HAVE_SETUID */ 8112#ifdef HAVE_SETEUID 8113 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__}, 8114#endif /* HAVE_SETEUID */ 8115#ifdef HAVE_SETEGID 8116 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__}, 8117#endif /* HAVE_SETEGID */ 8118#ifdef HAVE_SETREUID 8119 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__}, 8120#endif /* HAVE_SETREUID */ 8121#ifdef HAVE_SETREGID 8122 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__}, 8123#endif /* HAVE_SETREGID */ 8124#ifdef HAVE_SETGID 8125 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__}, 8126#endif /* HAVE_SETGID */ 8127#ifdef HAVE_SETGROUPS 8128 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__}, 8129#endif /* HAVE_SETGROUPS */ 8130#ifdef HAVE_INITGROUPS 8131 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__}, 8132#endif /* HAVE_INITGROUPS */ 8133#ifdef HAVE_GETPGID 8134 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__}, 8135#endif /* HAVE_GETPGID */ 8136#ifdef HAVE_SETPGRP 8137 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__}, 8138#endif /* HAVE_SETPGRP */ 8139#ifdef HAVE_WAIT 8140 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__}, 8141#endif /* HAVE_WAIT */ 8142#ifdef HAVE_WAIT3 8143 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__}, 8144#endif /* HAVE_WAIT3 */ 8145#ifdef HAVE_WAIT4 8146 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__}, 8147#endif /* HAVE_WAIT4 */ 8148#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT) 8149 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__}, 8150#endif /* HAVE_WAITPID */ 8151#ifdef HAVE_GETSID 8152 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__}, 8153#endif /* HAVE_GETSID */ 8154#ifdef HAVE_SETSID 8155 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__}, 8156#endif /* HAVE_SETSID */ 8157#ifdef HAVE_SETPGID 8158 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__}, 8159#endif /* HAVE_SETPGID */ 8160#ifdef HAVE_TCGETPGRP 8161 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__}, 8162#endif /* HAVE_TCGETPGRP */ 8163#ifdef HAVE_TCSETPGRP 8164 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__}, 8165#endif /* HAVE_TCSETPGRP */ 8166 {"open", posix_open, METH_VARARGS, posix_open__doc__}, 8167 {"close", posix_close, METH_VARARGS, posix_close__doc__}, 8168 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__}, 8169 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__}, 8170 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__}, 8171 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__}, 8172 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__}, 8173 {"read", posix_read, METH_VARARGS, posix_read__doc__}, 8174 {"write", posix_write, METH_VARARGS, posix_write__doc__}, 8175#ifdef HAVE_SENDFILE 8176 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS, 8177 posix_sendfile__doc__}, 8178#endif 8179 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__}, 8180 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__}, 8181#ifdef HAVE_PIPE 8182 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__}, 8183#endif 8184#ifdef HAVE_MKFIFO 8185 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__}, 8186#endif 8187#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) 8188 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__}, 8189#endif 8190#ifdef HAVE_DEVICE_MACROS 8191 {"major", posix_major, METH_VARARGS, posix_major__doc__}, 8192 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__}, 8193 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__}, 8194#endif 8195#ifdef HAVE_FTRUNCATE 8196 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__}, 8197#endif 8198#ifdef HAVE_PUTENV 8199 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__}, 8200#endif 8201#ifdef HAVE_UNSETENV 8202 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__}, 8203#endif 8204 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__}, 8205#ifdef HAVE_FCHDIR 8206 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__}, 8207#endif 8208#ifdef HAVE_FSYNC 8209 {"fsync", posix_fsync, METH_O, posix_fsync__doc__}, 8210#endif 8211#ifdef HAVE_FDATASYNC 8212 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__}, 8213#endif 8214#ifdef HAVE_SYS_WAIT_H 8215#ifdef WCOREDUMP 8216 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__}, 8217#endif /* WCOREDUMP */ 8218#ifdef WIFCONTINUED 8219 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__}, 8220#endif /* WIFCONTINUED */ 8221#ifdef WIFSTOPPED 8222 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__}, 8223#endif /* WIFSTOPPED */ 8224#ifdef WIFSIGNALED 8225 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__}, 8226#endif /* WIFSIGNALED */ 8227#ifdef WIFEXITED 8228 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__}, 8229#endif /* WIFEXITED */ 8230#ifdef WEXITSTATUS 8231 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__}, 8232#endif /* WEXITSTATUS */ 8233#ifdef WTERMSIG 8234 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__}, 8235#endif /* WTERMSIG */ 8236#ifdef WSTOPSIG 8237 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__}, 8238#endif /* WSTOPSIG */ 8239#endif /* HAVE_SYS_WAIT_H */ 8240#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) 8241 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__}, 8242#endif 8243#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) 8244 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__}, 8245#endif 8246#ifdef HAVE_CONFSTR 8247 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__}, 8248#endif 8249#ifdef HAVE_SYSCONF 8250 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__}, 8251#endif 8252#ifdef HAVE_FPATHCONF 8253 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__}, 8254#endif 8255#ifdef HAVE_PATHCONF 8256 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__}, 8257#endif 8258 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__}, 8259#ifdef MS_WINDOWS 8260 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL}, 8261 {"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL}, 8262 {"_getfileinformation", posix__getfileinformation, METH_VARARGS, NULL}, 8263#endif 8264#ifdef HAVE_GETLOADAVG 8265 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__}, 8266#endif 8267 #ifdef MS_WINDOWS 8268 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__}, 8269 #endif 8270 #ifdef __VMS 8271 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__}, 8272 #endif 8273#ifdef HAVE_SETRESUID 8274 {"setresuid", posix_setresuid, METH_VARARGS, posix_setresuid__doc__}, 8275#endif 8276#ifdef HAVE_SETRESGID 8277 {"setresgid", posix_setresgid, METH_VARARGS, posix_setresgid__doc__}, 8278#endif 8279#ifdef HAVE_GETRESUID 8280 {"getresuid", posix_getresuid, METH_NOARGS, posix_getresuid__doc__}, 8281#endif 8282#ifdef HAVE_GETRESGID 8283 {"getresgid", posix_getresgid, METH_NOARGS, posix_getresgid__doc__}, 8284#endif 8285 8286 {NULL, NULL} /* Sentinel */ 8287}; 8288 8289 8290static int 8291ins(PyObject *module, char *symbol, long value) 8292{ 8293 return PyModule_AddIntConstant(module, symbol, value); 8294} 8295 8296#if defined(PYOS_OS2) 8297/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */ 8298static int insertvalues(PyObject *module) 8299{ 8300 APIRET rc; 8301 ULONG values[QSV_MAX+1]; 8302 PyObject *v; 8303 char *ver, tmp[50]; 8304 8305 Py_BEGIN_ALLOW_THREADS 8306 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX); 8307 Py_END_ALLOW_THREADS 8308 8309 if (rc != NO_ERROR) { 8310 os2_error(rc); 8311 return -1; 8312 } 8313 8314 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1; 8315 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1; 8316 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1; 8317 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1; 8318 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1; 8319 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1; 8320 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1; 8321 8322 switch (values[QSV_VERSION_MINOR]) { 8323 case 0: ver = "2.00"; break; 8324 case 10: ver = "2.10"; break; 8325 case 11: ver = "2.11"; break; 8326 case 30: ver = "3.00"; break; 8327 case 40: ver = "4.00"; break; 8328 case 50: ver = "5.00"; break; 8329 default: 8330 PyOS_snprintf(tmp, sizeof(tmp), 8331 "%d-%d", values[QSV_VERSION_MAJOR], 8332 values[QSV_VERSION_MINOR]); 8333 ver = &tmp[0]; 8334 } 8335 8336 /* Add Indicator of the Version of the Operating System */ 8337 if (PyModule_AddStringConstant(module, "version", tmp) < 0) 8338 return -1; 8339 8340 /* Add Indicator of Which Drive was Used to Boot the System */ 8341 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1; 8342 tmp[1] = ':'; 8343 tmp[2] = '\0'; 8344 8345 return PyModule_AddStringConstant(module, "bootdrive", tmp); 8346} 8347#endif 8348 8349#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS) 8350static int 8351enable_symlink() 8352{ 8353 HANDLE tok; 8354 TOKEN_PRIVILEGES tok_priv; 8355 LUID luid; 8356 int meth_idx = 0; 8357 8358 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok)) 8359 return 0; 8360 8361 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid)) 8362 return 0; 8363 8364 tok_priv.PrivilegeCount = 1; 8365 tok_priv.Privileges[0].Luid = luid; 8366 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 8367 8368 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv, 8369 sizeof(TOKEN_PRIVILEGES), 8370 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL)) 8371 return 0; 8372 8373 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */ 8374 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1; 8375} 8376#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */ 8377 8378static int 8379all_ins(PyObject *d) 8380{ 8381#ifdef F_OK 8382 if (ins(d, "F_OK", (long)F_OK)) return -1; 8383#endif 8384#ifdef R_OK 8385 if (ins(d, "R_OK", (long)R_OK)) return -1; 8386#endif 8387#ifdef W_OK 8388 if (ins(d, "W_OK", (long)W_OK)) return -1; 8389#endif 8390#ifdef X_OK 8391 if (ins(d, "X_OK", (long)X_OK)) return -1; 8392#endif 8393#ifdef NGROUPS_MAX 8394 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1; 8395#endif 8396#ifdef TMP_MAX 8397 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1; 8398#endif 8399#ifdef WCONTINUED 8400 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1; 8401#endif 8402#ifdef WNOHANG 8403 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1; 8404#endif 8405#ifdef WUNTRACED 8406 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1; 8407#endif 8408#ifdef O_RDONLY 8409 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1; 8410#endif 8411#ifdef O_WRONLY 8412 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1; 8413#endif 8414#ifdef O_RDWR 8415 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1; 8416#endif 8417#ifdef O_NDELAY 8418 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1; 8419#endif 8420#ifdef O_NONBLOCK 8421 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1; 8422#endif 8423#ifdef O_APPEND 8424 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1; 8425#endif 8426#ifdef O_DSYNC 8427 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1; 8428#endif 8429#ifdef O_RSYNC 8430 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1; 8431#endif 8432#ifdef O_SYNC 8433 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1; 8434#endif 8435#ifdef O_NOCTTY 8436 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1; 8437#endif 8438#ifdef O_CREAT 8439 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1; 8440#endif 8441#ifdef O_EXCL 8442 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1; 8443#endif 8444#ifdef O_TRUNC 8445 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1; 8446#endif 8447#ifdef O_BINARY 8448 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1; 8449#endif 8450#ifdef O_TEXT 8451 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1; 8452#endif 8453#ifdef O_LARGEFILE 8454 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1; 8455#endif 8456#ifdef O_SHLOCK 8457 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1; 8458#endif 8459#ifdef O_EXLOCK 8460 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1; 8461#endif 8462 8463/* MS Windows */ 8464#ifdef O_NOINHERIT 8465 /* Don't inherit in child processes. */ 8466 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1; 8467#endif 8468#ifdef _O_SHORT_LIVED 8469 /* Optimize for short life (keep in memory). */ 8470 /* MS forgot to define this one with a non-underscore form too. */ 8471 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1; 8472#endif 8473#ifdef O_TEMPORARY 8474 /* Automatically delete when last handle is closed. */ 8475 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1; 8476#endif 8477#ifdef O_RANDOM 8478 /* Optimize for random access. */ 8479 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1; 8480#endif 8481#ifdef O_SEQUENTIAL 8482 /* Optimize for sequential access. */ 8483 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1; 8484#endif 8485 8486/* GNU extensions. */ 8487#ifdef O_ASYNC 8488 /* Send a SIGIO signal whenever input or output 8489 becomes available on file descriptor */ 8490 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1; 8491#endif 8492#ifdef O_DIRECT 8493 /* Direct disk access. */ 8494 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1; 8495#endif 8496#ifdef O_DIRECTORY 8497 /* Must be a directory. */ 8498 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1; 8499#endif 8500#ifdef O_NOFOLLOW 8501 /* Do not follow links. */ 8502 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1; 8503#endif 8504#ifdef O_NOATIME 8505 /* Do not update the access time. */ 8506 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1; 8507#endif 8508 8509 /* These come from sysexits.h */ 8510#ifdef EX_OK 8511 if (ins(d, "EX_OK", (long)EX_OK)) return -1; 8512#endif /* EX_OK */ 8513#ifdef EX_USAGE 8514 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1; 8515#endif /* EX_USAGE */ 8516#ifdef EX_DATAERR 8517 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1; 8518#endif /* EX_DATAERR */ 8519#ifdef EX_NOINPUT 8520 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1; 8521#endif /* EX_NOINPUT */ 8522#ifdef EX_NOUSER 8523 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1; 8524#endif /* EX_NOUSER */ 8525#ifdef EX_NOHOST 8526 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1; 8527#endif /* EX_NOHOST */ 8528#ifdef EX_UNAVAILABLE 8529 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1; 8530#endif /* EX_UNAVAILABLE */ 8531#ifdef EX_SOFTWARE 8532 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1; 8533#endif /* EX_SOFTWARE */ 8534#ifdef EX_OSERR 8535 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1; 8536#endif /* EX_OSERR */ 8537#ifdef EX_OSFILE 8538 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1; 8539#endif /* EX_OSFILE */ 8540#ifdef EX_CANTCREAT 8541 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1; 8542#endif /* EX_CANTCREAT */ 8543#ifdef EX_IOERR 8544 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1; 8545#endif /* EX_IOERR */ 8546#ifdef EX_TEMPFAIL 8547 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1; 8548#endif /* EX_TEMPFAIL */ 8549#ifdef EX_PROTOCOL 8550 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1; 8551#endif /* EX_PROTOCOL */ 8552#ifdef EX_NOPERM 8553 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1; 8554#endif /* EX_NOPERM */ 8555#ifdef EX_CONFIG 8556 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1; 8557#endif /* EX_CONFIG */ 8558#ifdef EX_NOTFOUND 8559 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1; 8560#endif /* EX_NOTFOUND */ 8561 8562 /* statvfs */ 8563#ifdef ST_RDONLY 8564 if (ins(d, "ST_RDONLY", (long)ST_RDONLY)) return -1; 8565#endif /* ST_RDONLY */ 8566#ifdef ST_NOSUID 8567 if (ins(d, "ST_NOSUID", (long)ST_NOSUID)) return -1; 8568#endif /* ST_NOSUID */ 8569 8570 /* FreeBSD sendfile() constants */ 8571#ifdef SF_NODISKIO 8572 if (ins(d, "SF_NODISKIO", (long)SF_NODISKIO)) return -1; 8573#endif 8574#ifdef SF_MNOWAIT 8575 if (ins(d, "SF_MNOWAIT", (long)SF_MNOWAIT)) return -1; 8576#endif 8577#ifdef SF_SYNC 8578 if (ins(d, "SF_SYNC", (long)SF_SYNC)) return -1; 8579#endif 8580 8581#ifdef HAVE_SPAWNV 8582#if defined(PYOS_OS2) && defined(PYCC_GCC) 8583 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1; 8584 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1; 8585 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1; 8586 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1; 8587 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1; 8588 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1; 8589 if (ins(d, "P_PM", (long)P_PM)) return -1; 8590 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1; 8591 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1; 8592 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1; 8593 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1; 8594 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1; 8595 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1; 8596 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1; 8597 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1; 8598 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1; 8599 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1; 8600 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1; 8601 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1; 8602 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1; 8603#else 8604 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1; 8605 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1; 8606 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1; 8607 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1; 8608 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1; 8609#endif 8610#endif 8611 8612#if defined(PYOS_OS2) 8613 if (insertvalues(d)) return -1; 8614#endif 8615 return 0; 8616} 8617 8618 8619#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__) 8620#define INITFUNC PyInit_nt 8621#define MODNAME "nt" 8622 8623#elif defined(PYOS_OS2) 8624#define INITFUNC PyInit_os2 8625#define MODNAME "os2" 8626 8627#else 8628#define INITFUNC PyInit_posix 8629#define MODNAME "posix" 8630#endif 8631 8632static struct PyModuleDef posixmodule = { 8633 PyModuleDef_HEAD_INIT, 8634 MODNAME, 8635 posix__doc__, 8636 -1, 8637 posix_methods, 8638 NULL, 8639 NULL, 8640 NULL, 8641 NULL 8642}; 8643 8644 8645PyMODINIT_FUNC 8646INITFUNC(void) 8647{ 8648 PyObject *m, *v; 8649 8650#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS) 8651 win32_can_symlink = enable_symlink(); 8652#endif 8653 8654 m = PyModule_Create(&posixmodule); 8655 if (m == NULL) 8656 return NULL; 8657 8658 /* Initialize environ dictionary */ 8659 v = convertenviron(); 8660 Py_XINCREF(v); 8661 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0) 8662 return NULL; 8663 Py_DECREF(v); 8664 8665 if (all_ins(m)) 8666 return NULL; 8667 8668 if (setup_confname_tables(m)) 8669 return NULL; 8670 8671 Py_INCREF(PyExc_OSError); 8672 PyModule_AddObject(m, "error", PyExc_OSError); 8673 8674#ifdef HAVE_PUTENV 8675 if (posix_putenv_garbage == NULL) 8676 posix_putenv_garbage = PyDict_New(); 8677#endif 8678 8679 if (!initialized) { 8680 stat_result_desc.name = MODNAME ".stat_result"; 8681 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField; 8682 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField; 8683 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField; 8684 PyStructSequence_InitType(&StatResultType, &stat_result_desc); 8685 structseq_new = StatResultType.tp_new; 8686 StatResultType.tp_new = statresult_new; 8687 8688 statvfs_result_desc.name = MODNAME ".statvfs_result"; 8689 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc); 8690#ifdef NEED_TICKS_PER_SECOND 8691# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK) 8692 ticks_per_second = sysconf(_SC_CLK_TCK); 8693# elif defined(HZ) 8694 ticks_per_second = HZ; 8695# else 8696 ticks_per_second = 60; /* magic fallback value; may be bogus */ 8697# endif 8698#endif 8699 } 8700 Py_INCREF((PyObject*) &StatResultType); 8701 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType); 8702 Py_INCREF((PyObject*) &StatVFSResultType); 8703 PyModule_AddObject(m, "statvfs_result", 8704 (PyObject*) &StatVFSResultType); 8705 initialized = 1; 8706 8707#ifdef __APPLE__ 8708 /* 8709 * Step 2 of weak-linking support on Mac OS X. 8710 * 8711 * The code below removes functions that are not available on the 8712 * currently active platform. 8713 * 8714 * This block allow one to use a python binary that was build on 8715 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on 8716 * OSX 10.4. 8717 */ 8718#ifdef HAVE_FSTATVFS 8719 if (fstatvfs == NULL) { 8720 if (PyObject_DelAttrString(m, "fstatvfs") == -1) { 8721 return NULL; 8722 } 8723 } 8724#endif /* HAVE_FSTATVFS */ 8725 8726#ifdef HAVE_STATVFS 8727 if (statvfs == NULL) { 8728 if (PyObject_DelAttrString(m, "statvfs") == -1) { 8729 return NULL; 8730 } 8731 } 8732#endif /* HAVE_STATVFS */ 8733 8734# ifdef HAVE_LCHOWN 8735 if (lchown == NULL) { 8736 if (PyObject_DelAttrString(m, "lchown") == -1) { 8737 return NULL; 8738 } 8739 } 8740#endif /* HAVE_LCHOWN */ 8741 8742 8743#endif /* __APPLE__ */ 8744 return m; 8745 8746} 8747 8748#ifdef __cplusplus 8749} 8750#endif 8751