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