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