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