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