posixmodule.c revision a05ada3128f5cbe00ef5c51e6317cc984b102c40
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 Py_BEGIN_ALLOW_THREADS 2354 ep = readdir(dirp); 2355 Py_END_ALLOW_THREADS 2356 if (ep == NULL) 2357 break; 2358 if (ep->d_name[0] == '.' && 2359 (NAMLEN(ep) == 1 || 2360 (ep->d_name[1] == '.' && NAMLEN(ep) == 2))) 2361 continue; 2362 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep)); 2363 if (v == NULL) { 2364 Py_DECREF(d); 2365 d = NULL; 2366 break; 2367 } 2368 if (arg_is_unicode) { 2369 PyObject *w; 2370 2371 w = PyUnicode_FromEncodedObject(v, 2372 Py_FileSystemDefaultEncoding, 2373 "strict"); 2374 if (w != NULL) { 2375 Py_DECREF(v); 2376 v = w; 2377 } 2378 else { 2379 /* fall back to the original byte string, as 2380 discussed in patch #683592 */ 2381 PyErr_Clear(); 2382 } 2383 } 2384 if (PyList_Append(d, v) != 0) { 2385 Py_DECREF(v); 2386 Py_DECREF(d); 2387 d = NULL; 2388 break; 2389 } 2390 Py_DECREF(v); 2391 } 2392 if (errno != 0 && d != NULL) { 2393 /* readdir() returned NULL and set errno */ 2394 closedir(dirp); 2395 Py_DECREF(d); 2396 return posix_error_with_allocated_filename(name); 2397 } 2398 closedir(dirp); 2399 PyMem_Free(name); 2400 2401 return d; 2402 2403#endif /* which OS */ 2404} /* end of posix_listdir */ 2405 2406#ifdef MS_WINDOWS 2407/* A helper function for abspath on win32 */ 2408static PyObject * 2409posix__getfullpathname(PyObject *self, PyObject *args) 2410{ 2411 /* assume encoded strings wont more than double no of chars */ 2412 char inbuf[MAX_PATH*2]; 2413 char *inbufp = inbuf; 2414 Py_ssize_t insize = sizeof(inbuf); 2415 char outbuf[MAX_PATH*2]; 2416 char *temp; 2417#ifdef Py_WIN_WIDE_FILENAMES 2418 if (unicode_file_names()) { 2419 PyUnicodeObject *po; 2420 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) { 2421 Py_UNICODE woutbuf[MAX_PATH*2]; 2422 Py_UNICODE *wtemp; 2423 if (!GetFullPathNameW(PyUnicode_AS_UNICODE(po), 2424 sizeof(woutbuf)/sizeof(woutbuf[0]), 2425 woutbuf, &wtemp)) 2426 return win32_error("GetFullPathName", ""); 2427 return PyUnicode_FromUnicode(woutbuf, wcslen(woutbuf)); 2428 } 2429 /* Drop the argument parsing error as narrow strings 2430 are also valid. */ 2431 PyErr_Clear(); 2432 } 2433#endif 2434 if (!PyArg_ParseTuple (args, "et#:_getfullpathname", 2435 Py_FileSystemDefaultEncoding, &inbufp, 2436 &insize)) 2437 return NULL; 2438 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]), 2439 outbuf, &temp)) 2440 return win32_error("GetFullPathName", inbuf); 2441 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) { 2442 return PyUnicode_Decode(outbuf, strlen(outbuf), 2443 Py_FileSystemDefaultEncoding, NULL); 2444 } 2445 return PyBytes_FromString(outbuf); 2446} /* end of posix__getfullpathname */ 2447#endif /* MS_WINDOWS */ 2448 2449PyDoc_STRVAR(posix_mkdir__doc__, 2450"mkdir(path [, mode=0777])\n\n\ 2451Create a directory."); 2452 2453static PyObject * 2454posix_mkdir(PyObject *self, PyObject *args) 2455{ 2456 int res; 2457 char *path = NULL; 2458 int mode = 0777; 2459 2460#ifdef Py_WIN_WIDE_FILENAMES 2461 if (unicode_file_names()) { 2462 PyUnicodeObject *po; 2463 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) { 2464 Py_BEGIN_ALLOW_THREADS 2465 /* PyUnicode_AS_UNICODE OK without thread lock as 2466 it is a simple dereference. */ 2467 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL); 2468 Py_END_ALLOW_THREADS 2469 if (!res) 2470 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po)); 2471 Py_INCREF(Py_None); 2472 return Py_None; 2473 } 2474 /* Drop the argument parsing error as narrow strings 2475 are also valid. */ 2476 PyErr_Clear(); 2477 } 2478 if (!PyArg_ParseTuple(args, "et|i:mkdir", 2479 Py_FileSystemDefaultEncoding, &path, &mode)) 2480 return NULL; 2481 Py_BEGIN_ALLOW_THREADS 2482 /* PyUnicode_AS_UNICODE OK without thread lock as 2483 it is a simple dereference. */ 2484 res = CreateDirectoryA(path, NULL); 2485 Py_END_ALLOW_THREADS 2486 if (!res) { 2487 win32_error("mkdir", path); 2488 PyMem_Free(path); 2489 return NULL; 2490 } 2491 PyMem_Free(path); 2492 Py_INCREF(Py_None); 2493 return Py_None; 2494#else 2495 2496 if (!PyArg_ParseTuple(args, "et|i:mkdir", 2497 Py_FileSystemDefaultEncoding, &path, &mode)) 2498 return NULL; 2499 Py_BEGIN_ALLOW_THREADS 2500#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__) 2501 res = mkdir(path); 2502#else 2503 res = mkdir(path, mode); 2504#endif 2505 Py_END_ALLOW_THREADS 2506 if (res < 0) 2507 return posix_error_with_allocated_filename(path); 2508 PyMem_Free(path); 2509 Py_INCREF(Py_None); 2510 return Py_None; 2511#endif 2512} 2513 2514 2515/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */ 2516#if defined(HAVE_SYS_RESOURCE_H) 2517#include <sys/resource.h> 2518#endif 2519 2520 2521#ifdef HAVE_NICE 2522PyDoc_STRVAR(posix_nice__doc__, 2523"nice(inc) -> new_priority\n\n\ 2524Decrease the priority of process by inc and return the new priority."); 2525 2526static PyObject * 2527posix_nice(PyObject *self, PyObject *args) 2528{ 2529 int increment, value; 2530 2531 if (!PyArg_ParseTuple(args, "i:nice", &increment)) 2532 return NULL; 2533 2534 /* There are two flavours of 'nice': one that returns the new 2535 priority (as required by almost all standards out there) and the 2536 Linux/FreeBSD/BSDI one, which returns '0' on success and advices 2537 the use of getpriority() to get the new priority. 2538 2539 If we are of the nice family that returns the new priority, we 2540 need to clear errno before the call, and check if errno is filled 2541 before calling posix_error() on a returnvalue of -1, because the 2542 -1 may be the actual new priority! */ 2543 2544 errno = 0; 2545 value = nice(increment); 2546#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY) 2547 if (value == 0) 2548 value = getpriority(PRIO_PROCESS, 0); 2549#endif 2550 if (value == -1 && errno != 0) 2551 /* either nice() or getpriority() returned an error */ 2552 return posix_error(); 2553 return PyLong_FromLong((long) value); 2554} 2555#endif /* HAVE_NICE */ 2556 2557PyDoc_STRVAR(posix_rename__doc__, 2558"rename(old, new)\n\n\ 2559Rename a file or directory."); 2560 2561static PyObject * 2562posix_rename(PyObject *self, PyObject *args) 2563{ 2564#ifdef MS_WINDOWS 2565 PyObject *o1, *o2; 2566 char *p1, *p2; 2567 BOOL result; 2568 if (unicode_file_names()) { 2569 if (!PyArg_ParseTuple(args, "O&O&:rename", 2570 convert_to_unicode, &o1, 2571 convert_to_unicode, &o2)) 2572 PyErr_Clear(); 2573 else { 2574 Py_BEGIN_ALLOW_THREADS 2575 result = MoveFileW(PyUnicode_AsUnicode(o1), 2576 PyUnicode_AsUnicode(o2)); 2577 Py_END_ALLOW_THREADS 2578 Py_DECREF(o1); 2579 Py_DECREF(o2); 2580 if (!result) 2581 return win32_error("rename", NULL); 2582 Py_INCREF(Py_None); 2583 return Py_None; 2584 } 2585 } 2586 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2)) 2587 return NULL; 2588 Py_BEGIN_ALLOW_THREADS 2589 result = MoveFileA(p1, p2); 2590 Py_END_ALLOW_THREADS 2591 if (!result) 2592 return win32_error("rename", NULL); 2593 Py_INCREF(Py_None); 2594 return Py_None; 2595#else 2596 return posix_2str(args, "etet:rename", rename); 2597#endif 2598} 2599 2600 2601PyDoc_STRVAR(posix_rmdir__doc__, 2602"rmdir(path)\n\n\ 2603Remove a directory."); 2604 2605static PyObject * 2606posix_rmdir(PyObject *self, PyObject *args) 2607{ 2608#ifdef MS_WINDOWS 2609 return win32_1str(args, "rmdir", "s:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW); 2610#else 2611 return posix_1str(args, "et:rmdir", rmdir); 2612#endif 2613} 2614 2615 2616PyDoc_STRVAR(posix_stat__doc__, 2617"stat(path) -> stat result\n\n\ 2618Perform a stat system call on the given path."); 2619 2620static PyObject * 2621posix_stat(PyObject *self, PyObject *args) 2622{ 2623#ifdef MS_WINDOWS 2624 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", win32_wstat); 2625#else 2626 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL); 2627#endif 2628} 2629 2630 2631#ifdef HAVE_SYSTEM 2632PyDoc_STRVAR(posix_system__doc__, 2633"system(command) -> exit_status\n\n\ 2634Execute the command (a string) in a subshell."); 2635 2636static PyObject * 2637posix_system(PyObject *self, PyObject *args) 2638{ 2639 long sts; 2640#ifdef MS_WINDOWS 2641 wchar_t *command; 2642 if (!PyArg_ParseTuple(args, "u:system", &command)) 2643 return NULL; 2644#else 2645 char *command; 2646 if (!PyArg_ParseTuple(args, "s:system", &command)) 2647 return NULL; 2648#endif 2649 Py_BEGIN_ALLOW_THREADS 2650#ifdef MS_WINDOWS 2651 sts = _wsystem(command); 2652#else 2653 sts = system(command); 2654#endif 2655 Py_END_ALLOW_THREADS 2656 return PyLong_FromLong(sts); 2657} 2658#endif 2659 2660 2661PyDoc_STRVAR(posix_umask__doc__, 2662"umask(new_mask) -> old_mask\n\n\ 2663Set the current numeric umask and return the previous umask."); 2664 2665static PyObject * 2666posix_umask(PyObject *self, PyObject *args) 2667{ 2668 int i; 2669 if (!PyArg_ParseTuple(args, "i:umask", &i)) 2670 return NULL; 2671 i = (int)umask(i); 2672 if (i < 0) 2673 return posix_error(); 2674 return PyLong_FromLong((long)i); 2675} 2676 2677 2678PyDoc_STRVAR(posix_unlink__doc__, 2679"unlink(path)\n\n\ 2680Remove a file (same as remove(path))."); 2681 2682PyDoc_STRVAR(posix_remove__doc__, 2683"remove(path)\n\n\ 2684Remove a file (same as unlink(path))."); 2685 2686static PyObject * 2687posix_unlink(PyObject *self, PyObject *args) 2688{ 2689#ifdef MS_WINDOWS 2690 return win32_1str(args, "remove", "s:remove", DeleteFileA, "U:remove", DeleteFileW); 2691#else 2692 return posix_1str(args, "et:remove", unlink); 2693#endif 2694} 2695 2696 2697#ifdef HAVE_UNAME 2698PyDoc_STRVAR(posix_uname__doc__, 2699"uname() -> (sysname, nodename, release, version, machine)\n\n\ 2700Return a tuple identifying the current operating system."); 2701 2702static PyObject * 2703posix_uname(PyObject *self, PyObject *noargs) 2704{ 2705 struct utsname u; 2706 int res; 2707 2708 Py_BEGIN_ALLOW_THREADS 2709 res = uname(&u); 2710 Py_END_ALLOW_THREADS 2711 if (res < 0) 2712 return posix_error(); 2713 return Py_BuildValue("(sssss)", 2714 u.sysname, 2715 u.nodename, 2716 u.release, 2717 u.version, 2718 u.machine); 2719} 2720#endif /* HAVE_UNAME */ 2721 2722static int 2723extract_time(PyObject *t, long* sec, long* usec) 2724{ 2725 long intval; 2726 if (PyFloat_Check(t)) { 2727 double tval = PyFloat_AsDouble(t); 2728 PyObject *intobj = Py_TYPE(t)->tp_as_number->nb_int(t); 2729 if (!intobj) 2730 return -1; 2731 intval = PyLong_AsLong(intobj); 2732 Py_DECREF(intobj); 2733 if (intval == -1 && PyErr_Occurred()) 2734 return -1; 2735 *sec = intval; 2736 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */ 2737 if (*usec < 0) 2738 /* If rounding gave us a negative number, 2739 truncate. */ 2740 *usec = 0; 2741 return 0; 2742 } 2743 intval = PyLong_AsLong(t); 2744 if (intval == -1 && PyErr_Occurred()) 2745 return -1; 2746 *sec = intval; 2747 *usec = 0; 2748 return 0; 2749} 2750 2751PyDoc_STRVAR(posix_utime__doc__, 2752"utime(path, (atime, mtime))\n\ 2753utime(path, None)\n\n\ 2754Set the access and modified time of the file to the given values. If the\n\ 2755second form is used, set the access and modified times to the current time."); 2756 2757static PyObject * 2758posix_utime(PyObject *self, PyObject *args) 2759{ 2760#ifdef Py_WIN_WIDE_FILENAMES 2761 PyObject *arg; 2762 PyUnicodeObject *obwpath; 2763 wchar_t *wpath = NULL; 2764 char *apath = NULL; 2765 HANDLE hFile; 2766 long atimesec, mtimesec, ausec, musec; 2767 FILETIME atime, mtime; 2768 PyObject *result = NULL; 2769 2770 if (unicode_file_names()) { 2771 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) { 2772 wpath = PyUnicode_AS_UNICODE(obwpath); 2773 Py_BEGIN_ALLOW_THREADS 2774 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0, 2775 NULL, OPEN_EXISTING, 2776 FILE_FLAG_BACKUP_SEMANTICS, NULL); 2777 Py_END_ALLOW_THREADS 2778 if (hFile == INVALID_HANDLE_VALUE) 2779 return win32_error_unicode("utime", wpath); 2780 } else 2781 /* Drop the argument parsing error as narrow strings 2782 are also valid. */ 2783 PyErr_Clear(); 2784 } 2785 if (!wpath) { 2786 if (!PyArg_ParseTuple(args, "etO:utime", 2787 Py_FileSystemDefaultEncoding, &apath, &arg)) 2788 return NULL; 2789 Py_BEGIN_ALLOW_THREADS 2790 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0, 2791 NULL, OPEN_EXISTING, 2792 FILE_FLAG_BACKUP_SEMANTICS, NULL); 2793 Py_END_ALLOW_THREADS 2794 if (hFile == INVALID_HANDLE_VALUE) { 2795 win32_error("utime", apath); 2796 PyMem_Free(apath); 2797 return NULL; 2798 } 2799 PyMem_Free(apath); 2800 } 2801 2802 if (arg == Py_None) { 2803 SYSTEMTIME now; 2804 GetSystemTime(&now); 2805 if (!SystemTimeToFileTime(&now, &mtime) || 2806 !SystemTimeToFileTime(&now, &atime)) { 2807 win32_error("utime", NULL); 2808 goto done; 2809 } 2810 } 2811 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) { 2812 PyErr_SetString(PyExc_TypeError, 2813 "utime() arg 2 must be a tuple (atime, mtime)"); 2814 goto done; 2815 } 2816 else { 2817 if (extract_time(PyTuple_GET_ITEM(arg, 0), 2818 &atimesec, &ausec) == -1) 2819 goto done; 2820 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime); 2821 if (extract_time(PyTuple_GET_ITEM(arg, 1), 2822 &mtimesec, &musec) == -1) 2823 goto done; 2824 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime); 2825 } 2826 if (!SetFileTime(hFile, NULL, &atime, &mtime)) { 2827 /* Avoid putting the file name into the error here, 2828 as that may confuse the user into believing that 2829 something is wrong with the file, when it also 2830 could be the time stamp that gives a problem. */ 2831 win32_error("utime", NULL); 2832 } 2833 Py_INCREF(Py_None); 2834 result = Py_None; 2835done: 2836 CloseHandle(hFile); 2837 return result; 2838#else /* Py_WIN_WIDE_FILENAMES */ 2839 2840 char *path = NULL; 2841 long atime, mtime, ausec, musec; 2842 int res; 2843 PyObject* arg; 2844 2845#if defined(HAVE_UTIMES) 2846 struct timeval buf[2]; 2847#define ATIME buf[0].tv_sec 2848#define MTIME buf[1].tv_sec 2849#elif defined(HAVE_UTIME_H) 2850/* XXX should define struct utimbuf instead, above */ 2851 struct utimbuf buf; 2852#define ATIME buf.actime 2853#define MTIME buf.modtime 2854#define UTIME_ARG &buf 2855#else /* HAVE_UTIMES */ 2856 time_t buf[2]; 2857#define ATIME buf[0] 2858#define MTIME buf[1] 2859#define UTIME_ARG buf 2860#endif /* HAVE_UTIMES */ 2861 2862 2863 if (!PyArg_ParseTuple(args, "etO:utime", 2864 Py_FileSystemDefaultEncoding, &path, &arg)) 2865 return NULL; 2866 if (arg == Py_None) { 2867 /* optional time values not given */ 2868 Py_BEGIN_ALLOW_THREADS 2869 res = utime(path, NULL); 2870 Py_END_ALLOW_THREADS 2871 } 2872 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) { 2873 PyErr_SetString(PyExc_TypeError, 2874 "utime() arg 2 must be a tuple (atime, mtime)"); 2875 PyMem_Free(path); 2876 return NULL; 2877 } 2878 else { 2879 if (extract_time(PyTuple_GET_ITEM(arg, 0), 2880 &atime, &ausec) == -1) { 2881 PyMem_Free(path); 2882 return NULL; 2883 } 2884 if (extract_time(PyTuple_GET_ITEM(arg, 1), 2885 &mtime, &musec) == -1) { 2886 PyMem_Free(path); 2887 return NULL; 2888 } 2889 ATIME = atime; 2890 MTIME = mtime; 2891#ifdef HAVE_UTIMES 2892 buf[0].tv_usec = ausec; 2893 buf[1].tv_usec = musec; 2894 Py_BEGIN_ALLOW_THREADS 2895 res = utimes(path, buf); 2896 Py_END_ALLOW_THREADS 2897#else 2898 Py_BEGIN_ALLOW_THREADS 2899 res = utime(path, UTIME_ARG); 2900 Py_END_ALLOW_THREADS 2901#endif /* HAVE_UTIMES */ 2902 } 2903 if (res < 0) { 2904 return posix_error_with_allocated_filename(path); 2905 } 2906 PyMem_Free(path); 2907 Py_INCREF(Py_None); 2908 return Py_None; 2909#undef UTIME_ARG 2910#undef ATIME 2911#undef MTIME 2912#endif /* Py_WIN_WIDE_FILENAMES */ 2913} 2914 2915 2916/* Process operations */ 2917 2918PyDoc_STRVAR(posix__exit__doc__, 2919"_exit(status)\n\n\ 2920Exit to the system with specified status, without normal exit processing."); 2921 2922static PyObject * 2923posix__exit(PyObject *self, PyObject *args) 2924{ 2925 int sts; 2926 if (!PyArg_ParseTuple(args, "i:_exit", &sts)) 2927 return NULL; 2928 _exit(sts); 2929 return NULL; /* Make gcc -Wall happy */ 2930} 2931 2932#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV) 2933static void 2934free_string_array(char **array, Py_ssize_t count) 2935{ 2936 Py_ssize_t i; 2937 for (i = 0; i < count; i++) 2938 PyMem_Free(array[i]); 2939 PyMem_DEL(array); 2940} 2941#endif 2942 2943 2944#ifdef HAVE_EXECV 2945PyDoc_STRVAR(posix_execv__doc__, 2946"execv(path, args)\n\n\ 2947Execute an executable path with arguments, replacing current process.\n\ 2948\n\ 2949 path: path of executable file\n\ 2950 args: tuple or list of strings"); 2951 2952static PyObject * 2953posix_execv(PyObject *self, PyObject *args) 2954{ 2955 char *path; 2956 PyObject *argv; 2957 char **argvlist; 2958 Py_ssize_t i, argc; 2959 PyObject *(*getitem)(PyObject *, Py_ssize_t); 2960 2961 /* execv has two arguments: (path, argv), where 2962 argv is a list or tuple of strings. */ 2963 2964 if (!PyArg_ParseTuple(args, "etO:execv", 2965 Py_FileSystemDefaultEncoding, 2966 &path, &argv)) 2967 return NULL; 2968 if (PyList_Check(argv)) { 2969 argc = PyList_Size(argv); 2970 getitem = PyList_GetItem; 2971 } 2972 else if (PyTuple_Check(argv)) { 2973 argc = PyTuple_Size(argv); 2974 getitem = PyTuple_GetItem; 2975 } 2976 else { 2977 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list"); 2978 PyMem_Free(path); 2979 return NULL; 2980 } 2981 if (argc < 1) { 2982 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty"); 2983 PyMem_Free(path); 2984 return NULL; 2985 } 2986 2987 argvlist = PyMem_NEW(char *, argc+1); 2988 if (argvlist == NULL) { 2989 PyMem_Free(path); 2990 return PyErr_NoMemory(); 2991 } 2992 for (i = 0; i < argc; i++) { 2993 if (!PyArg_Parse((*getitem)(argv, i), "et", 2994 Py_FileSystemDefaultEncoding, 2995 &argvlist[i])) { 2996 free_string_array(argvlist, i); 2997 PyErr_SetString(PyExc_TypeError, 2998 "execv() arg 2 must contain only strings"); 2999 PyMem_Free(path); 3000 return NULL; 3001 3002 } 3003 } 3004 argvlist[argc] = NULL; 3005 3006 execv(path, argvlist); 3007 3008 /* If we get here it's definitely an error */ 3009 3010 free_string_array(argvlist, argc); 3011 PyMem_Free(path); 3012 return posix_error(); 3013} 3014 3015 3016PyDoc_STRVAR(posix_execve__doc__, 3017"execve(path, args, env)\n\n\ 3018Execute a path with arguments and environment, replacing current process.\n\ 3019\n\ 3020 path: path of executable file\n\ 3021 args: tuple or list of arguments\n\ 3022 env: dictionary of strings mapping to strings"); 3023 3024static PyObject * 3025posix_execve(PyObject *self, PyObject *args) 3026{ 3027 char *path; 3028 PyObject *argv, *env; 3029 char **argvlist; 3030 char **envlist; 3031 PyObject *key, *val, *keys=NULL, *vals=NULL; 3032 Py_ssize_t i, pos, argc, envc; 3033 PyObject *(*getitem)(PyObject *, Py_ssize_t); 3034 Py_ssize_t lastarg = 0; 3035 3036 /* execve has three arguments: (path, argv, env), where 3037 argv is a list or tuple of strings and env is a dictionary 3038 like posix.environ. */ 3039 3040 if (!PyArg_ParseTuple(args, "etOO:execve", 3041 Py_FileSystemDefaultEncoding, 3042 &path, &argv, &env)) 3043 return NULL; 3044 if (PyList_Check(argv)) { 3045 argc = PyList_Size(argv); 3046 getitem = PyList_GetItem; 3047 } 3048 else if (PyTuple_Check(argv)) { 3049 argc = PyTuple_Size(argv); 3050 getitem = PyTuple_GetItem; 3051 } 3052 else { 3053 PyErr_SetString(PyExc_TypeError, 3054 "execve() arg 2 must be a tuple or list"); 3055 goto fail_0; 3056 } 3057 if (!PyMapping_Check(env)) { 3058 PyErr_SetString(PyExc_TypeError, 3059 "execve() arg 3 must be a mapping object"); 3060 goto fail_0; 3061 } 3062 3063 argvlist = PyMem_NEW(char *, argc+1); 3064 if (argvlist == NULL) { 3065 PyErr_NoMemory(); 3066 goto fail_0; 3067 } 3068 for (i = 0; i < argc; i++) { 3069 if (!PyArg_Parse((*getitem)(argv, i), 3070 "et;execve() arg 2 must contain only strings", 3071 Py_FileSystemDefaultEncoding, 3072 &argvlist[i])) 3073 { 3074 lastarg = i; 3075 goto fail_1; 3076 } 3077 } 3078 lastarg = argc; 3079 argvlist[argc] = NULL; 3080 3081 i = PyMapping_Size(env); 3082 if (i < 0) 3083 goto fail_1; 3084 envlist = PyMem_NEW(char *, i + 1); 3085 if (envlist == NULL) { 3086 PyErr_NoMemory(); 3087 goto fail_1; 3088 } 3089 envc = 0; 3090 keys = PyMapping_Keys(env); 3091 vals = PyMapping_Values(env); 3092 if (!keys || !vals) 3093 goto fail_2; 3094 if (!PyList_Check(keys) || !PyList_Check(vals)) { 3095 PyErr_SetString(PyExc_TypeError, 3096 "execve(): env.keys() or env.values() is not a list"); 3097 goto fail_2; 3098 } 3099 3100 for (pos = 0; pos < i; pos++) { 3101 char *p, *k, *v; 3102 size_t len; 3103 3104 key = PyList_GetItem(keys, pos); 3105 val = PyList_GetItem(vals, pos); 3106 if (!key || !val) 3107 goto fail_2; 3108 3109 if (!PyArg_Parse( 3110 key, 3111 "s;execve() arg 3 contains a non-string key", 3112 &k) || 3113 !PyArg_Parse( 3114 val, 3115 "s;execve() arg 3 contains a non-string value", 3116 &v)) 3117 { 3118 goto fail_2; 3119 } 3120 3121#if defined(PYOS_OS2) 3122 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */ 3123 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) { 3124#endif 3125 len = PyUnicode_GetSize(key) + PyUnicode_GetSize(val) + 2; 3126 p = PyMem_NEW(char, len); 3127 if (p == NULL) { 3128 PyErr_NoMemory(); 3129 goto fail_2; 3130 } 3131 PyOS_snprintf(p, len, "%s=%s", k, v); 3132 envlist[envc++] = p; 3133#if defined(PYOS_OS2) 3134 } 3135#endif 3136 } 3137 envlist[envc] = 0; 3138 3139 execve(path, argvlist, envlist); 3140 3141 /* If we get here it's definitely an error */ 3142 3143 (void) posix_error(); 3144 3145 fail_2: 3146 while (--envc >= 0) 3147 PyMem_DEL(envlist[envc]); 3148 PyMem_DEL(envlist); 3149 fail_1: 3150 free_string_array(argvlist, lastarg); 3151 Py_XDECREF(vals); 3152 Py_XDECREF(keys); 3153 fail_0: 3154 PyMem_Free(path); 3155 return NULL; 3156} 3157#endif /* HAVE_EXECV */ 3158 3159 3160#ifdef HAVE_SPAWNV 3161PyDoc_STRVAR(posix_spawnv__doc__, 3162"spawnv(mode, path, args)\n\n\ 3163Execute the program 'path' in a new process.\n\ 3164\n\ 3165 mode: mode of process creation\n\ 3166 path: path of executable file\n\ 3167 args: tuple or list of strings"); 3168 3169static PyObject * 3170posix_spawnv(PyObject *self, PyObject *args) 3171{ 3172 char *path; 3173 PyObject *argv; 3174 char **argvlist; 3175 int mode, i; 3176 Py_ssize_t argc; 3177 Py_intptr_t spawnval; 3178 PyObject *(*getitem)(PyObject *, Py_ssize_t); 3179 3180 /* spawnv has three arguments: (mode, path, argv), where 3181 argv is a list or tuple of strings. */ 3182 3183 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode, 3184 Py_FileSystemDefaultEncoding, 3185 &path, &argv)) 3186 return NULL; 3187 if (PyList_Check(argv)) { 3188 argc = PyList_Size(argv); 3189 getitem = PyList_GetItem; 3190 } 3191 else if (PyTuple_Check(argv)) { 3192 argc = PyTuple_Size(argv); 3193 getitem = PyTuple_GetItem; 3194 } 3195 else { 3196 PyErr_SetString(PyExc_TypeError, 3197 "spawnv() arg 2 must be a tuple or list"); 3198 PyMem_Free(path); 3199 return NULL; 3200 } 3201 3202 argvlist = PyMem_NEW(char *, argc+1); 3203 if (argvlist == NULL) { 3204 PyMem_Free(path); 3205 return PyErr_NoMemory(); 3206 } 3207 for (i = 0; i < argc; i++) { 3208 if (!PyArg_Parse((*getitem)(argv, i), "et", 3209 Py_FileSystemDefaultEncoding, 3210 &argvlist[i])) { 3211 free_string_array(argvlist, i); 3212 PyErr_SetString( 3213 PyExc_TypeError, 3214 "spawnv() arg 2 must contain only strings"); 3215 PyMem_Free(path); 3216 return NULL; 3217 } 3218 } 3219 argvlist[argc] = NULL; 3220 3221#if defined(PYOS_OS2) && defined(PYCC_GCC) 3222 Py_BEGIN_ALLOW_THREADS 3223 spawnval = spawnv(mode, path, argvlist); 3224 Py_END_ALLOW_THREADS 3225#else 3226 if (mode == _OLD_P_OVERLAY) 3227 mode = _P_OVERLAY; 3228 3229 Py_BEGIN_ALLOW_THREADS 3230 spawnval = _spawnv(mode, path, argvlist); 3231 Py_END_ALLOW_THREADS 3232#endif 3233 3234 free_string_array(argvlist, argc); 3235 PyMem_Free(path); 3236 3237 if (spawnval == -1) 3238 return posix_error(); 3239 else 3240#if SIZEOF_LONG == SIZEOF_VOID_P 3241 return Py_BuildValue("l", (long) spawnval); 3242#else 3243 return Py_BuildValue("L", (PY_LONG_LONG) spawnval); 3244#endif 3245} 3246 3247 3248PyDoc_STRVAR(posix_spawnve__doc__, 3249"spawnve(mode, path, args, env)\n\n\ 3250Execute the program 'path' in a new process.\n\ 3251\n\ 3252 mode: mode of process creation\n\ 3253 path: path of executable file\n\ 3254 args: tuple or list of arguments\n\ 3255 env: dictionary of strings mapping to strings"); 3256 3257static PyObject * 3258posix_spawnve(PyObject *self, PyObject *args) 3259{ 3260 char *path; 3261 PyObject *argv, *env; 3262 char **argvlist; 3263 char **envlist; 3264 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL; 3265 int mode, pos, envc; 3266 Py_ssize_t argc, i; 3267 Py_intptr_t spawnval; 3268 PyObject *(*getitem)(PyObject *, Py_ssize_t); 3269 Py_ssize_t lastarg = 0; 3270 3271 /* spawnve has four arguments: (mode, path, argv, env), where 3272 argv is a list or tuple of strings and env is a dictionary 3273 like posix.environ. */ 3274 3275 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode, 3276 Py_FileSystemDefaultEncoding, 3277 &path, &argv, &env)) 3278 return NULL; 3279 if (PyList_Check(argv)) { 3280 argc = PyList_Size(argv); 3281 getitem = PyList_GetItem; 3282 } 3283 else if (PyTuple_Check(argv)) { 3284 argc = PyTuple_Size(argv); 3285 getitem = PyTuple_GetItem; 3286 } 3287 else { 3288 PyErr_SetString(PyExc_TypeError, 3289 "spawnve() arg 2 must be a tuple or list"); 3290 goto fail_0; 3291 } 3292 if (!PyMapping_Check(env)) { 3293 PyErr_SetString(PyExc_TypeError, 3294 "spawnve() arg 3 must be a mapping object"); 3295 goto fail_0; 3296 } 3297 3298 argvlist = PyMem_NEW(char *, argc+1); 3299 if (argvlist == NULL) { 3300 PyErr_NoMemory(); 3301 goto fail_0; 3302 } 3303 for (i = 0; i < argc; i++) { 3304 if (!PyArg_Parse((*getitem)(argv, i), 3305 "et;spawnve() arg 2 must contain only strings", 3306 Py_FileSystemDefaultEncoding, 3307 &argvlist[i])) 3308 { 3309 lastarg = i; 3310 goto fail_1; 3311 } 3312 } 3313 lastarg = argc; 3314 argvlist[argc] = NULL; 3315 3316 i = PyMapping_Size(env); 3317 if (i < 0) 3318 goto fail_1; 3319 envlist = PyMem_NEW(char *, i + 1); 3320 if (envlist == NULL) { 3321 PyErr_NoMemory(); 3322 goto fail_1; 3323 } 3324 envc = 0; 3325 keys = PyMapping_Keys(env); 3326 vals = PyMapping_Values(env); 3327 if (!keys || !vals) 3328 goto fail_2; 3329 if (!PyList_Check(keys) || !PyList_Check(vals)) { 3330 PyErr_SetString(PyExc_TypeError, 3331 "spawnve(): env.keys() or env.values() is not a list"); 3332 goto fail_2; 3333 } 3334 3335 for (pos = 0; pos < i; pos++) { 3336 char *p, *k, *v; 3337 size_t len; 3338 3339 key = PyList_GetItem(keys, pos); 3340 val = PyList_GetItem(vals, pos); 3341 if (!key || !val) 3342 goto fail_2; 3343 3344 if (!PyArg_Parse( 3345 key, 3346 "s;spawnve() arg 3 contains a non-string key", 3347 &k) || 3348 !PyArg_Parse( 3349 val, 3350 "s;spawnve() arg 3 contains a non-string value", 3351 &v)) 3352 { 3353 goto fail_2; 3354 } 3355 len = PyUnicode_GetSize(key) + PyUnicode_GetSize(val) + 2; 3356 p = PyMem_NEW(char, len); 3357 if (p == NULL) { 3358 PyErr_NoMemory(); 3359 goto fail_2; 3360 } 3361 PyOS_snprintf(p, len, "%s=%s", k, v); 3362 envlist[envc++] = p; 3363 } 3364 envlist[envc] = 0; 3365 3366#if defined(PYOS_OS2) && defined(PYCC_GCC) 3367 Py_BEGIN_ALLOW_THREADS 3368 spawnval = spawnve(mode, path, argvlist, envlist); 3369 Py_END_ALLOW_THREADS 3370#else 3371 if (mode == _OLD_P_OVERLAY) 3372 mode = _P_OVERLAY; 3373 3374 Py_BEGIN_ALLOW_THREADS 3375 spawnval = _spawnve(mode, path, argvlist, envlist); 3376 Py_END_ALLOW_THREADS 3377#endif 3378 3379 if (spawnval == -1) 3380 (void) posix_error(); 3381 else 3382#if SIZEOF_LONG == SIZEOF_VOID_P 3383 res = Py_BuildValue("l", (long) spawnval); 3384#else 3385 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval); 3386#endif 3387 3388 fail_2: 3389 while (--envc >= 0) 3390 PyMem_DEL(envlist[envc]); 3391 PyMem_DEL(envlist); 3392 fail_1: 3393 free_string_array(argvlist, lastarg); 3394 Py_XDECREF(vals); 3395 Py_XDECREF(keys); 3396 fail_0: 3397 PyMem_Free(path); 3398 return res; 3399} 3400 3401/* OS/2 supports spawnvp & spawnvpe natively */ 3402#if defined(PYOS_OS2) 3403PyDoc_STRVAR(posix_spawnvp__doc__, 3404"spawnvp(mode, file, args)\n\n\ 3405Execute the program 'file' in a new process, using the environment\n\ 3406search path to find the file.\n\ 3407\n\ 3408 mode: mode of process creation\n\ 3409 file: executable file name\n\ 3410 args: tuple or list of strings"); 3411 3412static PyObject * 3413posix_spawnvp(PyObject *self, PyObject *args) 3414{ 3415 char *path; 3416 PyObject *argv; 3417 char **argvlist; 3418 int mode, i, argc; 3419 Py_intptr_t spawnval; 3420 PyObject *(*getitem)(PyObject *, Py_ssize_t); 3421 3422 /* spawnvp has three arguments: (mode, path, argv), where 3423 argv is a list or tuple of strings. */ 3424 3425 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode, 3426 Py_FileSystemDefaultEncoding, 3427 &path, &argv)) 3428 return NULL; 3429 if (PyList_Check(argv)) { 3430 argc = PyList_Size(argv); 3431 getitem = PyList_GetItem; 3432 } 3433 else if (PyTuple_Check(argv)) { 3434 argc = PyTuple_Size(argv); 3435 getitem = PyTuple_GetItem; 3436 } 3437 else { 3438 PyErr_SetString(PyExc_TypeError, 3439 "spawnvp() arg 2 must be a tuple or list"); 3440 PyMem_Free(path); 3441 return NULL; 3442 } 3443 3444 argvlist = PyMem_NEW(char *, argc+1); 3445 if (argvlist == NULL) { 3446 PyMem_Free(path); 3447 return PyErr_NoMemory(); 3448 } 3449 for (i = 0; i < argc; i++) { 3450 if (!PyArg_Parse((*getitem)(argv, i), "et", 3451 Py_FileSystemDefaultEncoding, 3452 &argvlist[i])) { 3453 free_string_array(argvlist, i); 3454 PyErr_SetString( 3455 PyExc_TypeError, 3456 "spawnvp() arg 2 must contain only strings"); 3457 PyMem_Free(path); 3458 return NULL; 3459 } 3460 } 3461 argvlist[argc] = NULL; 3462 3463 Py_BEGIN_ALLOW_THREADS 3464#if defined(PYCC_GCC) 3465 spawnval = spawnvp(mode, path, argvlist); 3466#else 3467 spawnval = _spawnvp(mode, path, argvlist); 3468#endif 3469 Py_END_ALLOW_THREADS 3470 3471 free_string_array(argvlist, argc); 3472 PyMem_Free(path); 3473 3474 if (spawnval == -1) 3475 return posix_error(); 3476 else 3477 return Py_BuildValue("l", (long) spawnval); 3478} 3479 3480 3481PyDoc_STRVAR(posix_spawnvpe__doc__, 3482"spawnvpe(mode, file, args, env)\n\n\ 3483Execute the program 'file' in a new process, using the environment\n\ 3484search path to find the file.\n\ 3485\n\ 3486 mode: mode of process creation\n\ 3487 file: executable file name\n\ 3488 args: tuple or list of arguments\n\ 3489 env: dictionary of strings mapping to strings"); 3490 3491static PyObject * 3492posix_spawnvpe(PyObject *self, PyObject *args) 3493{ 3494 char *path; 3495 PyObject *argv, *env; 3496 char **argvlist; 3497 char **envlist; 3498 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL; 3499 int mode, i, pos, argc, envc; 3500 Py_intptr_t spawnval; 3501 PyObject *(*getitem)(PyObject *, Py_ssize_t); 3502 int lastarg = 0; 3503 3504 /* spawnvpe has four arguments: (mode, path, argv, env), where 3505 argv is a list or tuple of strings and env is a dictionary 3506 like posix.environ. */ 3507 3508 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode, 3509 Py_FileSystemDefaultEncoding, 3510 &path, &argv, &env)) 3511 return NULL; 3512 if (PyList_Check(argv)) { 3513 argc = PyList_Size(argv); 3514 getitem = PyList_GetItem; 3515 } 3516 else if (PyTuple_Check(argv)) { 3517 argc = PyTuple_Size(argv); 3518 getitem = PyTuple_GetItem; 3519 } 3520 else { 3521 PyErr_SetString(PyExc_TypeError, 3522 "spawnvpe() arg 2 must be a tuple or list"); 3523 goto fail_0; 3524 } 3525 if (!PyMapping_Check(env)) { 3526 PyErr_SetString(PyExc_TypeError, 3527 "spawnvpe() arg 3 must be a mapping object"); 3528 goto fail_0; 3529 } 3530 3531 argvlist = PyMem_NEW(char *, argc+1); 3532 if (argvlist == NULL) { 3533 PyErr_NoMemory(); 3534 goto fail_0; 3535 } 3536 for (i = 0; i < argc; i++) { 3537 if (!PyArg_Parse((*getitem)(argv, i), 3538 "et;spawnvpe() arg 2 must contain only strings", 3539 Py_FileSystemDefaultEncoding, 3540 &argvlist[i])) 3541 { 3542 lastarg = i; 3543 goto fail_1; 3544 } 3545 } 3546 lastarg = argc; 3547 argvlist[argc] = NULL; 3548 3549 i = PyMapping_Size(env); 3550 if (i < 0) 3551 goto fail_1; 3552 envlist = PyMem_NEW(char *, i + 1); 3553 if (envlist == NULL) { 3554 PyErr_NoMemory(); 3555 goto fail_1; 3556 } 3557 envc = 0; 3558 keys = PyMapping_Keys(env); 3559 vals = PyMapping_Values(env); 3560 if (!keys || !vals) 3561 goto fail_2; 3562 if (!PyList_Check(keys) || !PyList_Check(vals)) { 3563 PyErr_SetString(PyExc_TypeError, 3564 "spawnvpe(): env.keys() or env.values() is not a list"); 3565 goto fail_2; 3566 } 3567 3568 for (pos = 0; pos < i; pos++) { 3569 char *p, *k, *v; 3570 size_t len; 3571 3572 key = PyList_GetItem(keys, pos); 3573 val = PyList_GetItem(vals, pos); 3574 if (!key || !val) 3575 goto fail_2; 3576 3577 if (!PyArg_Parse( 3578 key, 3579 "s;spawnvpe() arg 3 contains a non-string key", 3580 &k) || 3581 !PyArg_Parse( 3582 val, 3583 "s;spawnvpe() arg 3 contains a non-string value", 3584 &v)) 3585 { 3586 goto fail_2; 3587 } 3588 len = PyUnicode_GetSize(key) + PyUnicode_GetSize(val) + 2; 3589 p = PyMem_NEW(char, len); 3590 if (p == NULL) { 3591 PyErr_NoMemory(); 3592 goto fail_2; 3593 } 3594 PyOS_snprintf(p, len, "%s=%s", k, v); 3595 envlist[envc++] = p; 3596 } 3597 envlist[envc] = 0; 3598 3599 Py_BEGIN_ALLOW_THREADS 3600#if defined(PYCC_GCC) 3601 spawnval = spawnvpe(mode, path, argvlist, envlist); 3602#else 3603 spawnval = _spawnvpe(mode, path, argvlist, envlist); 3604#endif 3605 Py_END_ALLOW_THREADS 3606 3607 if (spawnval == -1) 3608 (void) posix_error(); 3609 else 3610 res = Py_BuildValue("l", (long) spawnval); 3611 3612 fail_2: 3613 while (--envc >= 0) 3614 PyMem_DEL(envlist[envc]); 3615 PyMem_DEL(envlist); 3616 fail_1: 3617 free_string_array(argvlist, lastarg); 3618 Py_XDECREF(vals); 3619 Py_XDECREF(keys); 3620 fail_0: 3621 PyMem_Free(path); 3622 return res; 3623} 3624#endif /* PYOS_OS2 */ 3625#endif /* HAVE_SPAWNV */ 3626 3627 3628#ifdef HAVE_FORK1 3629PyDoc_STRVAR(posix_fork1__doc__, 3630"fork1() -> pid\n\n\ 3631Fork a child process with a single multiplexed (i.e., not bound) thread.\n\ 3632\n\ 3633Return 0 to child process and PID of child to parent process."); 3634 3635static PyObject * 3636posix_fork1(PyObject *self, PyObject *noargs) 3637{ 3638 pid_t pid = fork1(); 3639 if (pid == -1) 3640 return posix_error(); 3641 if (pid == 0) 3642 PyOS_AfterFork(); 3643 return PyLong_FromLong(pid); 3644} 3645#endif 3646 3647 3648#ifdef HAVE_FORK 3649PyDoc_STRVAR(posix_fork__doc__, 3650"fork() -> pid\n\n\ 3651Fork a child process.\n\ 3652Return 0 to child process and PID of child to parent process."); 3653 3654static PyObject * 3655posix_fork(PyObject *self, PyObject *noargs) 3656{ 3657 pid_t pid = fork(); 3658 if (pid == -1) 3659 return posix_error(); 3660 if (pid == 0) 3661 PyOS_AfterFork(); 3662 return PyLong_FromLong(pid); 3663} 3664#endif 3665 3666/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */ 3667/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */ 3668#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX) 3669#define DEV_PTY_FILE "/dev/ptc" 3670#define HAVE_DEV_PTMX 3671#else 3672#define DEV_PTY_FILE "/dev/ptmx" 3673#endif 3674 3675#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX) 3676#ifdef HAVE_PTY_H 3677#include <pty.h> 3678#else 3679#ifdef HAVE_LIBUTIL_H 3680#include <libutil.h> 3681#endif /* HAVE_LIBUTIL_H */ 3682#endif /* HAVE_PTY_H */ 3683#ifdef HAVE_STROPTS_H 3684#include <stropts.h> 3685#endif 3686#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */ 3687 3688#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) 3689PyDoc_STRVAR(posix_openpty__doc__, 3690"openpty() -> (master_fd, slave_fd)\n\n\ 3691Open a pseudo-terminal, returning open fd's for both master and slave end.\n"); 3692 3693static PyObject * 3694posix_openpty(PyObject *self, PyObject *noargs) 3695{ 3696 int master_fd, slave_fd; 3697#ifndef HAVE_OPENPTY 3698 char * slave_name; 3699#endif 3700#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY) 3701 PyOS_sighandler_t sig_saved; 3702#ifdef sun 3703 extern char *ptsname(int fildes); 3704#endif 3705#endif 3706 3707#ifdef HAVE_OPENPTY 3708 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0) 3709 return posix_error(); 3710#elif defined(HAVE__GETPTY) 3711 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0); 3712 if (slave_name == NULL) 3713 return posix_error(); 3714 3715 slave_fd = open(slave_name, O_RDWR); 3716 if (slave_fd < 0) 3717 return posix_error(); 3718#else 3719 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */ 3720 if (master_fd < 0) 3721 return posix_error(); 3722 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL); 3723 /* change permission of slave */ 3724 if (grantpt(master_fd) < 0) { 3725 PyOS_setsig(SIGCHLD, sig_saved); 3726 return posix_error(); 3727 } 3728 /* unlock slave */ 3729 if (unlockpt(master_fd) < 0) { 3730 PyOS_setsig(SIGCHLD, sig_saved); 3731 return posix_error(); 3732 } 3733 PyOS_setsig(SIGCHLD, sig_saved); 3734 slave_name = ptsname(master_fd); /* get name of slave */ 3735 if (slave_name == NULL) 3736 return posix_error(); 3737 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */ 3738 if (slave_fd < 0) 3739 return posix_error(); 3740#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC) 3741 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */ 3742 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */ 3743#ifndef __hpux 3744 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */ 3745#endif /* __hpux */ 3746#endif /* HAVE_CYGWIN */ 3747#endif /* HAVE_OPENPTY */ 3748 3749 return Py_BuildValue("(ii)", master_fd, slave_fd); 3750 3751} 3752#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */ 3753 3754#ifdef HAVE_FORKPTY 3755PyDoc_STRVAR(posix_forkpty__doc__, 3756"forkpty() -> (pid, master_fd)\n\n\ 3757Fork a new process with a new pseudo-terminal as controlling tty.\n\n\ 3758Like fork(), return 0 as pid to child process, and PID of child to parent.\n\ 3759To both, return fd of newly opened pseudo-terminal.\n"); 3760 3761static PyObject * 3762posix_forkpty(PyObject *self, PyObject *noargs) 3763{ 3764 int master_fd = -1; 3765 pid_t pid; 3766 3767 pid = forkpty(&master_fd, NULL, NULL, NULL); 3768 if (pid == -1) 3769 return posix_error(); 3770 if (pid == 0) 3771 PyOS_AfterFork(); 3772 return Py_BuildValue("(li)", pid, master_fd); 3773} 3774#endif 3775 3776#ifdef HAVE_GETEGID 3777PyDoc_STRVAR(posix_getegid__doc__, 3778"getegid() -> egid\n\n\ 3779Return the current process's effective group id."); 3780 3781static PyObject * 3782posix_getegid(PyObject *self, PyObject *noargs) 3783{ 3784 return PyLong_FromLong((long)getegid()); 3785} 3786#endif 3787 3788 3789#ifdef HAVE_GETEUID 3790PyDoc_STRVAR(posix_geteuid__doc__, 3791"geteuid() -> euid\n\n\ 3792Return the current process's effective user id."); 3793 3794static PyObject * 3795posix_geteuid(PyObject *self, PyObject *noargs) 3796{ 3797 return PyLong_FromLong((long)geteuid()); 3798} 3799#endif 3800 3801 3802#ifdef HAVE_GETGID 3803PyDoc_STRVAR(posix_getgid__doc__, 3804"getgid() -> gid\n\n\ 3805Return the current process's group id."); 3806 3807static PyObject * 3808posix_getgid(PyObject *self, PyObject *noargs) 3809{ 3810 return PyLong_FromLong((long)getgid()); 3811} 3812#endif 3813 3814 3815PyDoc_STRVAR(posix_getpid__doc__, 3816"getpid() -> pid\n\n\ 3817Return the current process id"); 3818 3819static PyObject * 3820posix_getpid(PyObject *self, PyObject *noargs) 3821{ 3822 return PyLong_FromLong((long)getpid()); 3823} 3824 3825 3826#ifdef HAVE_GETGROUPS 3827PyDoc_STRVAR(posix_getgroups__doc__, 3828"getgroups() -> list of group IDs\n\n\ 3829Return list of supplemental group IDs for the process."); 3830 3831static PyObject * 3832posix_getgroups(PyObject *self, PyObject *noargs) 3833{ 3834 PyObject *result = NULL; 3835 3836#ifdef NGROUPS_MAX 3837#define MAX_GROUPS NGROUPS_MAX 3838#else 3839 /* defined to be 16 on Solaris7, so this should be a small number */ 3840#define MAX_GROUPS 64 3841#endif 3842 gid_t grouplist[MAX_GROUPS]; 3843 int n; 3844 3845 n = getgroups(MAX_GROUPS, grouplist); 3846 if (n < 0) 3847 posix_error(); 3848 else { 3849 result = PyList_New(n); 3850 if (result != NULL) { 3851 int i; 3852 for (i = 0; i < n; ++i) { 3853 PyObject *o = PyLong_FromLong((long)grouplist[i]); 3854 if (o == NULL) { 3855 Py_DECREF(result); 3856 result = NULL; 3857 break; 3858 } 3859 PyList_SET_ITEM(result, i, o); 3860 } 3861 } 3862 } 3863 3864 return result; 3865} 3866#endif 3867 3868#ifdef HAVE_GETPGID 3869PyDoc_STRVAR(posix_getpgid__doc__, 3870"getpgid(pid) -> pgid\n\n\ 3871Call the system call getpgid()."); 3872 3873static PyObject * 3874posix_getpgid(PyObject *self, PyObject *args) 3875{ 3876 int pid, pgid; 3877 if (!PyArg_ParseTuple(args, "i:getpgid", &pid)) 3878 return NULL; 3879 pgid = getpgid(pid); 3880 if (pgid < 0) 3881 return posix_error(); 3882 return PyLong_FromLong((long)pgid); 3883} 3884#endif /* HAVE_GETPGID */ 3885 3886 3887#ifdef HAVE_GETPGRP 3888PyDoc_STRVAR(posix_getpgrp__doc__, 3889"getpgrp() -> pgrp\n\n\ 3890Return the current process group id."); 3891 3892static PyObject * 3893posix_getpgrp(PyObject *self, PyObject *noargs) 3894{ 3895#ifdef GETPGRP_HAVE_ARG 3896 return PyLong_FromLong((long)getpgrp(0)); 3897#else /* GETPGRP_HAVE_ARG */ 3898 return PyLong_FromLong((long)getpgrp()); 3899#endif /* GETPGRP_HAVE_ARG */ 3900} 3901#endif /* HAVE_GETPGRP */ 3902 3903 3904#ifdef HAVE_SETPGRP 3905PyDoc_STRVAR(posix_setpgrp__doc__, 3906"setpgrp()\n\n\ 3907Make this process a session leader."); 3908 3909static PyObject * 3910posix_setpgrp(PyObject *self, PyObject *noargs) 3911{ 3912#ifdef SETPGRP_HAVE_ARG 3913 if (setpgrp(0, 0) < 0) 3914#else /* SETPGRP_HAVE_ARG */ 3915 if (setpgrp() < 0) 3916#endif /* SETPGRP_HAVE_ARG */ 3917 return posix_error(); 3918 Py_INCREF(Py_None); 3919 return Py_None; 3920} 3921 3922#endif /* HAVE_SETPGRP */ 3923 3924#ifdef HAVE_GETPPID 3925PyDoc_STRVAR(posix_getppid__doc__, 3926"getppid() -> ppid\n\n\ 3927Return the parent's process id."); 3928 3929static PyObject * 3930posix_getppid(PyObject *self, PyObject *noargs) 3931{ 3932 return PyLong_FromLong((long)getppid()); 3933} 3934#endif 3935 3936 3937#ifdef HAVE_GETLOGIN 3938PyDoc_STRVAR(posix_getlogin__doc__, 3939"getlogin() -> string\n\n\ 3940Return the actual login name."); 3941 3942static PyObject * 3943posix_getlogin(PyObject *self, PyObject *noargs) 3944{ 3945 PyObject *result = NULL; 3946 char *name; 3947 int old_errno = errno; 3948 3949 errno = 0; 3950 name = getlogin(); 3951 if (name == NULL) { 3952 if (errno) 3953 posix_error(); 3954 else 3955 PyErr_SetString(PyExc_OSError, 3956 "unable to determine login name"); 3957 } 3958 else 3959 result = PyUnicode_FromString(name); 3960 errno = old_errno; 3961 3962 return result; 3963} 3964#endif 3965 3966#ifdef HAVE_GETUID 3967PyDoc_STRVAR(posix_getuid__doc__, 3968"getuid() -> uid\n\n\ 3969Return the current process's user id."); 3970 3971static PyObject * 3972posix_getuid(PyObject *self, PyObject *noargs) 3973{ 3974 return PyLong_FromLong((long)getuid()); 3975} 3976#endif 3977 3978 3979#ifdef HAVE_KILL 3980PyDoc_STRVAR(posix_kill__doc__, 3981"kill(pid, sig)\n\n\ 3982Kill a process with a signal."); 3983 3984static PyObject * 3985posix_kill(PyObject *self, PyObject *args) 3986{ 3987 pid_t pid; 3988 int sig; 3989 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig)) 3990 return NULL; 3991#if defined(PYOS_OS2) && !defined(PYCC_GCC) 3992 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) { 3993 APIRET rc; 3994 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR) 3995 return os2_error(rc); 3996 3997 } else if (sig == XCPT_SIGNAL_KILLPROC) { 3998 APIRET rc; 3999 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR) 4000 return os2_error(rc); 4001 4002 } else 4003 return NULL; /* Unrecognized Signal Requested */ 4004#else 4005 if (kill(pid, sig) == -1) 4006 return posix_error(); 4007#endif 4008 Py_INCREF(Py_None); 4009 return Py_None; 4010} 4011#endif 4012 4013#ifdef HAVE_KILLPG 4014PyDoc_STRVAR(posix_killpg__doc__, 4015"killpg(pgid, sig)\n\n\ 4016Kill a process group with a signal."); 4017 4018static PyObject * 4019posix_killpg(PyObject *self, PyObject *args) 4020{ 4021 int pgid, sig; 4022 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig)) 4023 return NULL; 4024 if (killpg(pgid, sig) == -1) 4025 return posix_error(); 4026 Py_INCREF(Py_None); 4027 return Py_None; 4028} 4029#endif 4030 4031#ifdef HAVE_PLOCK 4032 4033#ifdef HAVE_SYS_LOCK_H 4034#include <sys/lock.h> 4035#endif 4036 4037PyDoc_STRVAR(posix_plock__doc__, 4038"plock(op)\n\n\ 4039Lock program segments into memory."); 4040 4041static PyObject * 4042posix_plock(PyObject *self, PyObject *args) 4043{ 4044 int op; 4045 if (!PyArg_ParseTuple(args, "i:plock", &op)) 4046 return NULL; 4047 if (plock(op) == -1) 4048 return posix_error(); 4049 Py_INCREF(Py_None); 4050 return Py_None; 4051} 4052#endif 4053 4054 4055 4056 4057#ifdef HAVE_SETUID 4058PyDoc_STRVAR(posix_setuid__doc__, 4059"setuid(uid)\n\n\ 4060Set the current process's user id."); 4061 4062static PyObject * 4063posix_setuid(PyObject *self, PyObject *args) 4064{ 4065 int uid; 4066 if (!PyArg_ParseTuple(args, "i:setuid", &uid)) 4067 return NULL; 4068 if (setuid(uid) < 0) 4069 return posix_error(); 4070 Py_INCREF(Py_None); 4071 return Py_None; 4072} 4073#endif /* HAVE_SETUID */ 4074 4075 4076#ifdef HAVE_SETEUID 4077PyDoc_STRVAR(posix_seteuid__doc__, 4078"seteuid(uid)\n\n\ 4079Set the current process's effective user id."); 4080 4081static PyObject * 4082posix_seteuid (PyObject *self, PyObject *args) 4083{ 4084 int euid; 4085 if (!PyArg_ParseTuple(args, "i", &euid)) { 4086 return NULL; 4087 } else if (seteuid(euid) < 0) { 4088 return posix_error(); 4089 } else { 4090 Py_INCREF(Py_None); 4091 return Py_None; 4092 } 4093} 4094#endif /* HAVE_SETEUID */ 4095 4096#ifdef HAVE_SETEGID 4097PyDoc_STRVAR(posix_setegid__doc__, 4098"setegid(gid)\n\n\ 4099Set the current process's effective group id."); 4100 4101static PyObject * 4102posix_setegid (PyObject *self, PyObject *args) 4103{ 4104 int egid; 4105 if (!PyArg_ParseTuple(args, "i", &egid)) { 4106 return NULL; 4107 } else if (setegid(egid) < 0) { 4108 return posix_error(); 4109 } else { 4110 Py_INCREF(Py_None); 4111 return Py_None; 4112 } 4113} 4114#endif /* HAVE_SETEGID */ 4115 4116#ifdef HAVE_SETREUID 4117PyDoc_STRVAR(posix_setreuid__doc__, 4118"setreuid(ruid, euid)\n\n\ 4119Set the current process's real and effective user ids."); 4120 4121static PyObject * 4122posix_setreuid (PyObject *self, PyObject *args) 4123{ 4124 int ruid, euid; 4125 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) { 4126 return NULL; 4127 } else if (setreuid(ruid, euid) < 0) { 4128 return posix_error(); 4129 } else { 4130 Py_INCREF(Py_None); 4131 return Py_None; 4132 } 4133} 4134#endif /* HAVE_SETREUID */ 4135 4136#ifdef HAVE_SETREGID 4137PyDoc_STRVAR(posix_setregid__doc__, 4138"setregid(rgid, egid)\n\n\ 4139Set the current process's real and effective group ids."); 4140 4141static PyObject * 4142posix_setregid (PyObject *self, PyObject *args) 4143{ 4144 int rgid, egid; 4145 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) { 4146 return NULL; 4147 } else if (setregid(rgid, egid) < 0) { 4148 return posix_error(); 4149 } else { 4150 Py_INCREF(Py_None); 4151 return Py_None; 4152 } 4153} 4154#endif /* HAVE_SETREGID */ 4155 4156#ifdef HAVE_SETGID 4157PyDoc_STRVAR(posix_setgid__doc__, 4158"setgid(gid)\n\n\ 4159Set the current process's group id."); 4160 4161static PyObject * 4162posix_setgid(PyObject *self, PyObject *args) 4163{ 4164 int gid; 4165 if (!PyArg_ParseTuple(args, "i:setgid", &gid)) 4166 return NULL; 4167 if (setgid(gid) < 0) 4168 return posix_error(); 4169 Py_INCREF(Py_None); 4170 return Py_None; 4171} 4172#endif /* HAVE_SETGID */ 4173 4174#ifdef HAVE_SETGROUPS 4175PyDoc_STRVAR(posix_setgroups__doc__, 4176"setgroups(list)\n\n\ 4177Set the groups of the current process to list."); 4178 4179static PyObject * 4180posix_setgroups(PyObject *self, PyObject *groups) 4181{ 4182 int i, len; 4183 gid_t grouplist[MAX_GROUPS]; 4184 4185 if (!PySequence_Check(groups)) { 4186 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence"); 4187 return NULL; 4188 } 4189 len = PySequence_Size(groups); 4190 if (len > MAX_GROUPS) { 4191 PyErr_SetString(PyExc_ValueError, "too many groups"); 4192 return NULL; 4193 } 4194 for(i = 0; i < len; i++) { 4195 PyObject *elem; 4196 elem = PySequence_GetItem(groups, i); 4197 if (!elem) 4198 return NULL; 4199 if (!PyLong_Check(elem)) { 4200 PyErr_SetString(PyExc_TypeError, 4201 "groups must be integers"); 4202 Py_DECREF(elem); 4203 return NULL; 4204 } else { 4205 unsigned long x = PyLong_AsUnsignedLong(elem); 4206 if (PyErr_Occurred()) { 4207 PyErr_SetString(PyExc_TypeError, 4208 "group id too big"); 4209 Py_DECREF(elem); 4210 return NULL; 4211 } 4212 grouplist[i] = x; 4213 /* read back the value to see if it fitted in gid_t */ 4214 if (grouplist[i] != x) { 4215 PyErr_SetString(PyExc_TypeError, 4216 "group id too big"); 4217 Py_DECREF(elem); 4218 return NULL; 4219 } 4220 } 4221 Py_DECREF(elem); 4222 } 4223 4224 if (setgroups(len, grouplist) < 0) 4225 return posix_error(); 4226 Py_INCREF(Py_None); 4227 return Py_None; 4228} 4229#endif /* HAVE_SETGROUPS */ 4230 4231#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4) 4232static PyObject * 4233wait_helper(pid_t pid, int status, struct rusage *ru) 4234{ 4235 PyObject *result; 4236 static PyObject *struct_rusage; 4237 4238 if (pid == -1) 4239 return posix_error(); 4240 4241 if (struct_rusage == NULL) { 4242 PyObject *m = PyImport_ImportModuleNoBlock("resource"); 4243 if (m == NULL) 4244 return NULL; 4245 struct_rusage = PyObject_GetAttrString(m, "struct_rusage"); 4246 Py_DECREF(m); 4247 if (struct_rusage == NULL) 4248 return NULL; 4249 } 4250 4251 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */ 4252 result = PyStructSequence_New((PyTypeObject*) struct_rusage); 4253 if (!result) 4254 return NULL; 4255 4256#ifndef doubletime 4257#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001) 4258#endif 4259 4260 PyStructSequence_SET_ITEM(result, 0, 4261 PyFloat_FromDouble(doubletime(ru->ru_utime))); 4262 PyStructSequence_SET_ITEM(result, 1, 4263 PyFloat_FromDouble(doubletime(ru->ru_stime))); 4264#define SET_INT(result, index, value)\ 4265 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value)) 4266 SET_INT(result, 2, ru->ru_maxrss); 4267 SET_INT(result, 3, ru->ru_ixrss); 4268 SET_INT(result, 4, ru->ru_idrss); 4269 SET_INT(result, 5, ru->ru_isrss); 4270 SET_INT(result, 6, ru->ru_minflt); 4271 SET_INT(result, 7, ru->ru_majflt); 4272 SET_INT(result, 8, ru->ru_nswap); 4273 SET_INT(result, 9, ru->ru_inblock); 4274 SET_INT(result, 10, ru->ru_oublock); 4275 SET_INT(result, 11, ru->ru_msgsnd); 4276 SET_INT(result, 12, ru->ru_msgrcv); 4277 SET_INT(result, 13, ru->ru_nsignals); 4278 SET_INT(result, 14, ru->ru_nvcsw); 4279 SET_INT(result, 15, ru->ru_nivcsw); 4280#undef SET_INT 4281 4282 if (PyErr_Occurred()) { 4283 Py_DECREF(result); 4284 return NULL; 4285 } 4286 4287 return Py_BuildValue("iiN", pid, status, result); 4288} 4289#endif /* HAVE_WAIT3 || HAVE_WAIT4 */ 4290 4291#ifdef HAVE_WAIT3 4292PyDoc_STRVAR(posix_wait3__doc__, 4293"wait3(options) -> (pid, status, rusage)\n\n\ 4294Wait for completion of a child process."); 4295 4296static PyObject * 4297posix_wait3(PyObject *self, PyObject *args) 4298{ 4299 pid_t pid; 4300 int options; 4301 struct rusage ru; 4302 WAIT_TYPE status; 4303 WAIT_STATUS_INT(status) = 0; 4304 4305 if (!PyArg_ParseTuple(args, "i:wait3", &options)) 4306 return NULL; 4307 4308 Py_BEGIN_ALLOW_THREADS 4309 pid = wait3(&status, options, &ru); 4310 Py_END_ALLOW_THREADS 4311 4312 return wait_helper(pid, WAIT_STATUS_INT(status), &ru); 4313} 4314#endif /* HAVE_WAIT3 */ 4315 4316#ifdef HAVE_WAIT4 4317PyDoc_STRVAR(posix_wait4__doc__, 4318"wait4(pid, options) -> (pid, status, rusage)\n\n\ 4319Wait for completion of a given child process."); 4320 4321static PyObject * 4322posix_wait4(PyObject *self, PyObject *args) 4323{ 4324 pid_t pid; 4325 int options; 4326 struct rusage ru; 4327 WAIT_TYPE status; 4328 WAIT_STATUS_INT(status) = 0; 4329 4330 if (!PyArg_ParseTuple(args, "ii:wait4", &pid, &options)) 4331 return NULL; 4332 4333 Py_BEGIN_ALLOW_THREADS 4334 pid = wait4(pid, &status, options, &ru); 4335 Py_END_ALLOW_THREADS 4336 4337 return wait_helper(pid, WAIT_STATUS_INT(status), &ru); 4338} 4339#endif /* HAVE_WAIT4 */ 4340 4341#ifdef HAVE_WAITPID 4342PyDoc_STRVAR(posix_waitpid__doc__, 4343"waitpid(pid, options) -> (pid, status)\n\n\ 4344Wait for completion of a given child process."); 4345 4346static PyObject * 4347posix_waitpid(PyObject *self, PyObject *args) 4348{ 4349 pid_t pid; 4350 int options; 4351 WAIT_TYPE status; 4352 WAIT_STATUS_INT(status) = 0; 4353 4354 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options)) 4355 return NULL; 4356 Py_BEGIN_ALLOW_THREADS 4357 pid = waitpid(pid, &status, options); 4358 Py_END_ALLOW_THREADS 4359 if (pid == -1) 4360 return posix_error(); 4361 4362 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status)); 4363} 4364 4365#elif defined(HAVE_CWAIT) 4366 4367/* MS C has a variant of waitpid() that's usable for most purposes. */ 4368PyDoc_STRVAR(posix_waitpid__doc__, 4369"waitpid(pid, options) -> (pid, status << 8)\n\n" 4370"Wait for completion of a given process. options is ignored on Windows."); 4371 4372static PyObject * 4373posix_waitpid(PyObject *self, PyObject *args) 4374{ 4375 Py_intptr_t pid; 4376 int status, options; 4377 4378 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options)) 4379 return NULL; 4380 Py_BEGIN_ALLOW_THREADS 4381 pid = _cwait(&status, pid, options); 4382 Py_END_ALLOW_THREADS 4383 if (pid == -1) 4384 return posix_error(); 4385 4386 /* shift the status left a byte so this is more like the POSIX waitpid */ 4387 return Py_BuildValue("ii", pid, status << 8); 4388} 4389#endif /* HAVE_WAITPID || HAVE_CWAIT */ 4390 4391#ifdef HAVE_WAIT 4392PyDoc_STRVAR(posix_wait__doc__, 4393"wait() -> (pid, status)\n\n\ 4394Wait for completion of a child process."); 4395 4396static PyObject * 4397posix_wait(PyObject *self, PyObject *noargs) 4398{ 4399 pid_t pid; 4400 WAIT_TYPE status; 4401 WAIT_STATUS_INT(status) = 0; 4402 4403 Py_BEGIN_ALLOW_THREADS 4404 pid = wait(&status); 4405 Py_END_ALLOW_THREADS 4406 if (pid == -1) 4407 return posix_error(); 4408 4409 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status)); 4410} 4411#endif 4412 4413 4414PyDoc_STRVAR(posix_lstat__doc__, 4415"lstat(path) -> stat result\n\n\ 4416Like stat(path), but do not follow symbolic links."); 4417 4418static PyObject * 4419posix_lstat(PyObject *self, PyObject *args) 4420{ 4421#ifdef HAVE_LSTAT 4422 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL); 4423#else /* !HAVE_LSTAT */ 4424#ifdef MS_WINDOWS 4425 return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", win32_wstat); 4426#else 4427 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL); 4428#endif 4429#endif /* !HAVE_LSTAT */ 4430} 4431 4432 4433#ifdef HAVE_READLINK 4434PyDoc_STRVAR(posix_readlink__doc__, 4435"readlink(path) -> path\n\n\ 4436Return a string representing the path to which the symbolic link points."); 4437 4438static PyObject * 4439posix_readlink(PyObject *self, PyObject *args) 4440{ 4441 PyObject* v; 4442 char buf[MAXPATHLEN]; 4443 char *path; 4444 int n; 4445 int arg_is_unicode = 0; 4446 4447 if (!PyArg_ParseTuple(args, "et:readlink", 4448 Py_FileSystemDefaultEncoding, &path)) 4449 return NULL; 4450 v = PySequence_GetItem(args, 0); 4451 if (v == NULL) { 4452 PyMem_Free(path); 4453 return NULL; 4454 } 4455 4456 if (PyUnicode_Check(v)) { 4457 arg_is_unicode = 1; 4458 } 4459 Py_DECREF(v); 4460 4461 Py_BEGIN_ALLOW_THREADS 4462 n = readlink(path, buf, (int) sizeof buf); 4463 Py_END_ALLOW_THREADS 4464 if (n < 0) 4465 return posix_error_with_allocated_filename(path); 4466 4467 PyMem_Free(path); 4468 v = PyBytes_FromStringAndSize(buf, n); 4469 if (arg_is_unicode) { 4470 PyObject *w; 4471 4472 w = PyUnicode_FromEncodedObject(v, 4473 Py_FileSystemDefaultEncoding, 4474 "strict"); 4475 if (w != NULL) { 4476 Py_DECREF(v); 4477 v = w; 4478 } 4479 else { 4480 /* fall back to the original byte string, as 4481 discussed in patch #683592 */ 4482 PyErr_Clear(); 4483 } 4484 } 4485 return v; 4486} 4487#endif /* HAVE_READLINK */ 4488 4489 4490#ifdef HAVE_SYMLINK 4491PyDoc_STRVAR(posix_symlink__doc__, 4492"symlink(src, dst)\n\n\ 4493Create a symbolic link pointing to src named dst."); 4494 4495static PyObject * 4496posix_symlink(PyObject *self, PyObject *args) 4497{ 4498 return posix_2str(args, "etet:symlink", symlink); 4499} 4500#endif /* HAVE_SYMLINK */ 4501 4502 4503#ifdef HAVE_TIMES 4504#ifndef HZ 4505#define HZ 60 /* Universal constant :-) */ 4506#endif /* HZ */ 4507 4508#if defined(PYCC_VACPP) && defined(PYOS_OS2) 4509static long 4510system_uptime(void) 4511{ 4512 ULONG value = 0; 4513 4514 Py_BEGIN_ALLOW_THREADS 4515 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value)); 4516 Py_END_ALLOW_THREADS 4517 4518 return value; 4519} 4520 4521static PyObject * 4522posix_times(PyObject *self, PyObject *noargs) 4523{ 4524 /* Currently Only Uptime is Provided -- Others Later */ 4525 return Py_BuildValue("ddddd", 4526 (double)0 /* t.tms_utime / HZ */, 4527 (double)0 /* t.tms_stime / HZ */, 4528 (double)0 /* t.tms_cutime / HZ */, 4529 (double)0 /* t.tms_cstime / HZ */, 4530 (double)system_uptime() / 1000); 4531} 4532#else /* not OS2 */ 4533static PyObject * 4534posix_times(PyObject *self, PyObject *noargs) 4535{ 4536 struct tms t; 4537 clock_t c; 4538 errno = 0; 4539 c = times(&t); 4540 if (c == (clock_t) -1) 4541 return posix_error(); 4542 return Py_BuildValue("ddddd", 4543 (double)t.tms_utime / HZ, 4544 (double)t.tms_stime / HZ, 4545 (double)t.tms_cutime / HZ, 4546 (double)t.tms_cstime / HZ, 4547 (double)c / HZ); 4548} 4549#endif /* not OS2 */ 4550#endif /* HAVE_TIMES */ 4551 4552 4553#ifdef MS_WINDOWS 4554#define HAVE_TIMES /* so the method table will pick it up */ 4555static PyObject * 4556posix_times(PyObject *self, PyObject *noargs) 4557{ 4558 FILETIME create, exit, kernel, user; 4559 HANDLE hProc; 4560 hProc = GetCurrentProcess(); 4561 GetProcessTimes(hProc, &create, &exit, &kernel, &user); 4562 /* The fields of a FILETIME structure are the hi and lo part 4563 of a 64-bit value expressed in 100 nanosecond units. 4564 1e7 is one second in such units; 1e-7 the inverse. 4565 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7. 4566 */ 4567 return Py_BuildValue( 4568 "ddddd", 4569 (double)(user.dwHighDateTime*429.4967296 + 4570 user.dwLowDateTime*1e-7), 4571 (double)(kernel.dwHighDateTime*429.4967296 + 4572 kernel.dwLowDateTime*1e-7), 4573 (double)0, 4574 (double)0, 4575 (double)0); 4576} 4577#endif /* MS_WINDOWS */ 4578 4579#ifdef HAVE_TIMES 4580PyDoc_STRVAR(posix_times__doc__, 4581"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\ 4582Return a tuple of floating point numbers indicating process times."); 4583#endif 4584 4585 4586#ifdef HAVE_GETSID 4587PyDoc_STRVAR(posix_getsid__doc__, 4588"getsid(pid) -> sid\n\n\ 4589Call the system call getsid()."); 4590 4591static PyObject * 4592posix_getsid(PyObject *self, PyObject *args) 4593{ 4594 pid_t pid; 4595 int sid; 4596 if (!PyArg_ParseTuple(args, "i:getsid", &pid)) 4597 return NULL; 4598 sid = getsid(pid); 4599 if (sid < 0) 4600 return posix_error(); 4601 return PyLong_FromLong((long)sid); 4602} 4603#endif /* HAVE_GETSID */ 4604 4605 4606#ifdef HAVE_SETSID 4607PyDoc_STRVAR(posix_setsid__doc__, 4608"setsid()\n\n\ 4609Call the system call setsid()."); 4610 4611static PyObject * 4612posix_setsid(PyObject *self, PyObject *noargs) 4613{ 4614 if (setsid() < 0) 4615 return posix_error(); 4616 Py_INCREF(Py_None); 4617 return Py_None; 4618} 4619#endif /* HAVE_SETSID */ 4620 4621#ifdef HAVE_SETPGID 4622PyDoc_STRVAR(posix_setpgid__doc__, 4623"setpgid(pid, pgrp)\n\n\ 4624Call the system call setpgid()."); 4625 4626static PyObject * 4627posix_setpgid(PyObject *self, PyObject *args) 4628{ 4629 pid_t pid; 4630 int pgrp; 4631 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp)) 4632 return NULL; 4633 if (setpgid(pid, pgrp) < 0) 4634 return posix_error(); 4635 Py_INCREF(Py_None); 4636 return Py_None; 4637} 4638#endif /* HAVE_SETPGID */ 4639 4640 4641#ifdef HAVE_TCGETPGRP 4642PyDoc_STRVAR(posix_tcgetpgrp__doc__, 4643"tcgetpgrp(fd) -> pgid\n\n\ 4644Return the process group associated with the terminal given by a fd."); 4645 4646static PyObject * 4647posix_tcgetpgrp(PyObject *self, PyObject *args) 4648{ 4649 int fd; 4650 pid_t pgid; 4651 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd)) 4652 return NULL; 4653 pgid = tcgetpgrp(fd); 4654 if (pgid < 0) 4655 return posix_error(); 4656 return PyLong_FromLong((long)pgid); 4657} 4658#endif /* HAVE_TCGETPGRP */ 4659 4660 4661#ifdef HAVE_TCSETPGRP 4662PyDoc_STRVAR(posix_tcsetpgrp__doc__, 4663"tcsetpgrp(fd, pgid)\n\n\ 4664Set the process group associated with the terminal given by a fd."); 4665 4666static PyObject * 4667posix_tcsetpgrp(PyObject *self, PyObject *args) 4668{ 4669 int fd, pgid; 4670 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid)) 4671 return NULL; 4672 if (tcsetpgrp(fd, pgid) < 0) 4673 return posix_error(); 4674 Py_INCREF(Py_None); 4675 return Py_None; 4676} 4677#endif /* HAVE_TCSETPGRP */ 4678 4679/* Functions acting on file descriptors */ 4680 4681PyDoc_STRVAR(posix_open__doc__, 4682"open(filename, flag [, mode=0777]) -> fd\n\n\ 4683Open a file (for low level IO)."); 4684 4685static PyObject * 4686posix_open(PyObject *self, PyObject *args) 4687{ 4688 char *file = NULL; 4689 int flag; 4690 int mode = 0777; 4691 int fd; 4692 4693#ifdef MS_WINDOWS 4694 if (unicode_file_names()) { 4695 PyUnicodeObject *po; 4696 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) { 4697 Py_BEGIN_ALLOW_THREADS 4698 /* PyUnicode_AS_UNICODE OK without thread 4699 lock as it is a simple dereference. */ 4700 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode); 4701 Py_END_ALLOW_THREADS 4702 if (fd < 0) 4703 return posix_error(); 4704 return PyLong_FromLong((long)fd); 4705 } 4706 /* Drop the argument parsing error as narrow strings 4707 are also valid. */ 4708 PyErr_Clear(); 4709 } 4710#endif 4711 4712 if (!PyArg_ParseTuple(args, "eti|i", 4713 Py_FileSystemDefaultEncoding, &file, 4714 &flag, &mode)) 4715 return NULL; 4716 4717 Py_BEGIN_ALLOW_THREADS 4718 fd = open(file, flag, mode); 4719 Py_END_ALLOW_THREADS 4720 if (fd < 0) 4721 return posix_error_with_allocated_filename(file); 4722 PyMem_Free(file); 4723 return PyLong_FromLong((long)fd); 4724} 4725 4726 4727PyDoc_STRVAR(posix_close__doc__, 4728"close(fd)\n\n\ 4729Close a file descriptor (for low level IO)."); 4730 4731static PyObject * 4732posix_close(PyObject *self, PyObject *args) 4733{ 4734 int fd, res; 4735 if (!PyArg_ParseTuple(args, "i:close", &fd)) 4736 return NULL; 4737 Py_BEGIN_ALLOW_THREADS 4738 res = close(fd); 4739 Py_END_ALLOW_THREADS 4740 if (res < 0) 4741 return posix_error(); 4742 Py_INCREF(Py_None); 4743 return Py_None; 4744} 4745 4746 4747PyDoc_STRVAR(posix_closerange__doc__, 4748"closerange(fd_low, fd_high)\n\n\ 4749Closes all file descriptors in [fd_low, fd_high), ignoring errors."); 4750 4751static PyObject * 4752posix_closerange(PyObject *self, PyObject *args) 4753{ 4754 int fd_from, fd_to, i; 4755 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to)) 4756 return NULL; 4757 Py_BEGIN_ALLOW_THREADS 4758 for (i = fd_from; i < fd_to; i++) 4759 close(i); 4760 Py_END_ALLOW_THREADS 4761 Py_RETURN_NONE; 4762} 4763 4764 4765PyDoc_STRVAR(posix_dup__doc__, 4766"dup(fd) -> fd2\n\n\ 4767Return a duplicate of a file descriptor."); 4768 4769static PyObject * 4770posix_dup(PyObject *self, PyObject *args) 4771{ 4772 int fd; 4773 if (!PyArg_ParseTuple(args, "i:dup", &fd)) 4774 return NULL; 4775 Py_BEGIN_ALLOW_THREADS 4776 fd = dup(fd); 4777 Py_END_ALLOW_THREADS 4778 if (fd < 0) 4779 return posix_error(); 4780 return PyLong_FromLong((long)fd); 4781} 4782 4783 4784PyDoc_STRVAR(posix_dup2__doc__, 4785"dup2(old_fd, new_fd)\n\n\ 4786Duplicate file descriptor."); 4787 4788static PyObject * 4789posix_dup2(PyObject *self, PyObject *args) 4790{ 4791 int fd, fd2, res; 4792 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2)) 4793 return NULL; 4794 Py_BEGIN_ALLOW_THREADS 4795 res = dup2(fd, fd2); 4796 Py_END_ALLOW_THREADS 4797 if (res < 0) 4798 return posix_error(); 4799 Py_INCREF(Py_None); 4800 return Py_None; 4801} 4802 4803 4804PyDoc_STRVAR(posix_lseek__doc__, 4805"lseek(fd, pos, how) -> newpos\n\n\ 4806Set the current position of a file descriptor."); 4807 4808static PyObject * 4809posix_lseek(PyObject *self, PyObject *args) 4810{ 4811 int fd, how; 4812#if defined(MS_WIN64) || defined(MS_WINDOWS) 4813 PY_LONG_LONG pos, res; 4814#else 4815 off_t pos, res; 4816#endif 4817 PyObject *posobj; 4818 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how)) 4819 return NULL; 4820#ifdef SEEK_SET 4821 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */ 4822 switch (how) { 4823 case 0: how = SEEK_SET; break; 4824 case 1: how = SEEK_CUR; break; 4825 case 2: how = SEEK_END; break; 4826 } 4827#endif /* SEEK_END */ 4828 4829#if !defined(HAVE_LARGEFILE_SUPPORT) 4830 pos = PyLong_AsLong(posobj); 4831#else 4832 pos = PyLong_Check(posobj) ? 4833 PyLong_AsLongLong(posobj) : PyLong_AsLong(posobj); 4834#endif 4835 if (PyErr_Occurred()) 4836 return NULL; 4837 4838 Py_BEGIN_ALLOW_THREADS 4839#if defined(MS_WIN64) || defined(MS_WINDOWS) 4840 res = _lseeki64(fd, pos, how); 4841#else 4842 res = lseek(fd, pos, how); 4843#endif 4844 Py_END_ALLOW_THREADS 4845 if (res < 0) 4846 return posix_error(); 4847 4848#if !defined(HAVE_LARGEFILE_SUPPORT) 4849 return PyLong_FromLong(res); 4850#else 4851 return PyLong_FromLongLong(res); 4852#endif 4853} 4854 4855 4856PyDoc_STRVAR(posix_read__doc__, 4857"read(fd, buffersize) -> string\n\n\ 4858Read a file descriptor."); 4859 4860static PyObject * 4861posix_read(PyObject *self, PyObject *args) 4862{ 4863 int fd, size; 4864 Py_ssize_t n; 4865 PyObject *buffer; 4866 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size)) 4867 return NULL; 4868 if (size < 0) { 4869 errno = EINVAL; 4870 return posix_error(); 4871 } 4872 buffer = PyBytes_FromStringAndSize((char *)NULL, size); 4873 if (buffer == NULL) 4874 return NULL; 4875 Py_BEGIN_ALLOW_THREADS 4876 n = read(fd, PyBytes_AS_STRING(buffer), size); 4877 Py_END_ALLOW_THREADS 4878 if (n < 0) { 4879 Py_DECREF(buffer); 4880 return posix_error(); 4881 } 4882 if (n != size) 4883 _PyBytes_Resize(&buffer, n); 4884 return buffer; 4885} 4886 4887 4888PyDoc_STRVAR(posix_write__doc__, 4889"write(fd, string) -> byteswritten\n\n\ 4890Write a string to a file descriptor."); 4891 4892static PyObject * 4893posix_write(PyObject *self, PyObject *args) 4894{ 4895 int fd; 4896 Py_ssize_t size; 4897 char *buffer; 4898 4899 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size)) 4900 return NULL; 4901 Py_BEGIN_ALLOW_THREADS 4902 size = write(fd, buffer, (size_t)size); 4903 Py_END_ALLOW_THREADS 4904 if (size < 0) 4905 return posix_error(); 4906 return PyLong_FromSsize_t(size); 4907} 4908 4909 4910PyDoc_STRVAR(posix_fstat__doc__, 4911"fstat(fd) -> stat result\n\n\ 4912Like stat(), but for an open file descriptor."); 4913 4914static PyObject * 4915posix_fstat(PyObject *self, PyObject *args) 4916{ 4917 int fd; 4918 STRUCT_STAT st; 4919 int res; 4920 if (!PyArg_ParseTuple(args, "i:fstat", &fd)) 4921 return NULL; 4922#ifdef __VMS 4923 /* on OpenVMS we must ensure that all bytes are written to the file */ 4924 fsync(fd); 4925#endif 4926 Py_BEGIN_ALLOW_THREADS 4927 res = FSTAT(fd, &st); 4928 Py_END_ALLOW_THREADS 4929 if (res != 0) { 4930#ifdef MS_WINDOWS 4931 return win32_error("fstat", NULL); 4932#else 4933 return posix_error(); 4934#endif 4935 } 4936 4937 return _pystat_fromstructstat(&st); 4938} 4939 4940PyDoc_STRVAR(posix_isatty__doc__, 4941"isatty(fd) -> bool\n\n\ 4942Return True if the file descriptor 'fd' is an open file descriptor\n\ 4943connected to the slave end of a terminal."); 4944 4945static PyObject * 4946posix_isatty(PyObject *self, PyObject *args) 4947{ 4948 int fd; 4949 if (!PyArg_ParseTuple(args, "i:isatty", &fd)) 4950 return NULL; 4951 return PyBool_FromLong(isatty(fd)); 4952} 4953 4954#ifdef HAVE_PIPE 4955PyDoc_STRVAR(posix_pipe__doc__, 4956"pipe() -> (read_end, write_end)\n\n\ 4957Create a pipe."); 4958 4959static PyObject * 4960posix_pipe(PyObject *self, PyObject *noargs) 4961{ 4962#if defined(PYOS_OS2) 4963 HFILE read, write; 4964 APIRET rc; 4965 4966 Py_BEGIN_ALLOW_THREADS 4967 rc = DosCreatePipe( &read, &write, 4096); 4968 Py_END_ALLOW_THREADS 4969 if (rc != NO_ERROR) 4970 return os2_error(rc); 4971 4972 return Py_BuildValue("(ii)", read, write); 4973#else 4974#if !defined(MS_WINDOWS) 4975 int fds[2]; 4976 int res; 4977 Py_BEGIN_ALLOW_THREADS 4978 res = pipe(fds); 4979 Py_END_ALLOW_THREADS 4980 if (res != 0) 4981 return posix_error(); 4982 return Py_BuildValue("(ii)", fds[0], fds[1]); 4983#else /* MS_WINDOWS */ 4984 HANDLE read, write; 4985 int read_fd, write_fd; 4986 BOOL ok; 4987 Py_BEGIN_ALLOW_THREADS 4988 ok = CreatePipe(&read, &write, NULL, 0); 4989 Py_END_ALLOW_THREADS 4990 if (!ok) 4991 return win32_error("CreatePipe", NULL); 4992 read_fd = _open_osfhandle((Py_intptr_t)read, 0); 4993 write_fd = _open_osfhandle((Py_intptr_t)write, 1); 4994 return Py_BuildValue("(ii)", read_fd, write_fd); 4995#endif /* MS_WINDOWS */ 4996#endif 4997} 4998#endif /* HAVE_PIPE */ 4999 5000 5001#ifdef HAVE_MKFIFO 5002PyDoc_STRVAR(posix_mkfifo__doc__, 5003"mkfifo(filename [, mode=0666])\n\n\ 5004Create a FIFO (a POSIX named pipe)."); 5005 5006static PyObject * 5007posix_mkfifo(PyObject *self, PyObject *args) 5008{ 5009 char *filename; 5010 int mode = 0666; 5011 int res; 5012 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode)) 5013 return NULL; 5014 Py_BEGIN_ALLOW_THREADS 5015 res = mkfifo(filename, mode); 5016 Py_END_ALLOW_THREADS 5017 if (res < 0) 5018 return posix_error(); 5019 Py_INCREF(Py_None); 5020 return Py_None; 5021} 5022#endif 5023 5024 5025#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) 5026PyDoc_STRVAR(posix_mknod__doc__, 5027"mknod(filename [, mode=0600, device])\n\n\ 5028Create a filesystem node (file, device special file or named pipe)\n\ 5029named filename. mode specifies both the permissions to use and the\n\ 5030type of node to be created, being combined (bitwise OR) with one of\n\ 5031S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\ 5032device defines the newly created device special file (probably using\n\ 5033os.makedev()), otherwise it is ignored."); 5034 5035 5036static PyObject * 5037posix_mknod(PyObject *self, PyObject *args) 5038{ 5039 char *filename; 5040 int mode = 0600; 5041 int device = 0; 5042 int res; 5043 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device)) 5044 return NULL; 5045 Py_BEGIN_ALLOW_THREADS 5046 res = mknod(filename, mode, device); 5047 Py_END_ALLOW_THREADS 5048 if (res < 0) 5049 return posix_error(); 5050 Py_INCREF(Py_None); 5051 return Py_None; 5052} 5053#endif 5054 5055#ifdef HAVE_DEVICE_MACROS 5056PyDoc_STRVAR(posix_major__doc__, 5057"major(device) -> major number\n\ 5058Extracts a device major number from a raw device number."); 5059 5060static PyObject * 5061posix_major(PyObject *self, PyObject *args) 5062{ 5063 int device; 5064 if (!PyArg_ParseTuple(args, "i:major", &device)) 5065 return NULL; 5066 return PyLong_FromLong((long)major(device)); 5067} 5068 5069PyDoc_STRVAR(posix_minor__doc__, 5070"minor(device) -> minor number\n\ 5071Extracts a device minor number from a raw device number."); 5072 5073static PyObject * 5074posix_minor(PyObject *self, PyObject *args) 5075{ 5076 int device; 5077 if (!PyArg_ParseTuple(args, "i:minor", &device)) 5078 return NULL; 5079 return PyLong_FromLong((long)minor(device)); 5080} 5081 5082PyDoc_STRVAR(posix_makedev__doc__, 5083"makedev(major, minor) -> device number\n\ 5084Composes a raw device number from the major and minor device numbers."); 5085 5086static PyObject * 5087posix_makedev(PyObject *self, PyObject *args) 5088{ 5089 int major, minor; 5090 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor)) 5091 return NULL; 5092 return PyLong_FromLong((long)makedev(major, minor)); 5093} 5094#endif /* device macros */ 5095 5096 5097#ifdef HAVE_FTRUNCATE 5098PyDoc_STRVAR(posix_ftruncate__doc__, 5099"ftruncate(fd, length)\n\n\ 5100Truncate a file to a specified length."); 5101 5102static PyObject * 5103posix_ftruncate(PyObject *self, PyObject *args) 5104{ 5105 int fd; 5106 off_t length; 5107 int res; 5108 PyObject *lenobj; 5109 5110 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj)) 5111 return NULL; 5112 5113#if !defined(HAVE_LARGEFILE_SUPPORT) 5114 length = PyLong_AsLong(lenobj); 5115#else 5116 length = PyLong_Check(lenobj) ? 5117 PyLong_AsLongLong(lenobj) : PyLong_AsLong(lenobj); 5118#endif 5119 if (PyErr_Occurred()) 5120 return NULL; 5121 5122 Py_BEGIN_ALLOW_THREADS 5123 res = ftruncate(fd, length); 5124 Py_END_ALLOW_THREADS 5125 if (res < 0) { 5126 PyErr_SetFromErrno(PyExc_IOError); 5127 return NULL; 5128 } 5129 Py_INCREF(Py_None); 5130 return Py_None; 5131} 5132#endif 5133 5134#ifdef HAVE_PUTENV 5135PyDoc_STRVAR(posix_putenv__doc__, 5136"putenv(key, value)\n\n\ 5137Change or add an environment variable."); 5138 5139/* Save putenv() parameters as values here, so we can collect them when they 5140 * get re-set with another call for the same key. */ 5141static PyObject *posix_putenv_garbage; 5142 5143static PyObject * 5144posix_putenv(PyObject *self, PyObject *args) 5145{ 5146#ifdef MS_WINDOWS 5147 wchar_t *s1, *s2; 5148 wchar_t *newenv; 5149#else 5150 char *s1, *s2; 5151 char *newenv; 5152#endif 5153 PyObject *newstr; 5154 size_t len; 5155 5156 if (!PyArg_ParseTuple(args, 5157#ifdef MS_WINDOWS 5158 "uu:putenv", 5159#else 5160 "ss:putenv", 5161#endif 5162 &s1, &s2)) 5163 return NULL; 5164 5165#if defined(PYOS_OS2) 5166 if (stricmp(s1, "BEGINLIBPATH") == 0) { 5167 APIRET rc; 5168 5169 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH); 5170 if (rc != NO_ERROR) 5171 return os2_error(rc); 5172 5173 } else if (stricmp(s1, "ENDLIBPATH") == 0) { 5174 APIRET rc; 5175 5176 rc = DosSetExtLIBPATH(s2, END_LIBPATH); 5177 if (rc != NO_ERROR) 5178 return os2_error(rc); 5179 } else { 5180#endif 5181 /* XXX This can leak memory -- not easy to fix :-( */ 5182 /* len includes space for a trailing \0; the size arg to 5183 PyBytes_FromStringAndSize does not count that */ 5184#ifdef MS_WINDOWS 5185 len = wcslen(s1) + wcslen(s2) + 2; 5186 newstr = PyUnicode_FromUnicode(NULL, (int)len - 1); 5187#else 5188 len = strlen(s1) + strlen(s2) + 2; 5189 newstr = PyBytes_FromStringAndSize(NULL, (int)len - 1); 5190#endif 5191 if (newstr == NULL) 5192 return PyErr_NoMemory(); 5193#ifdef MS_WINDOWS 5194 newenv = PyUnicode_AsUnicode(newstr); 5195 _snwprintf(newenv, len, L"%s=%s", s1, s2); 5196 if (_wputenv(newenv)) { 5197 Py_DECREF(newstr); 5198 posix_error(); 5199 return NULL; 5200 } 5201#else 5202 newenv = PyBytes_AS_STRING(newstr); 5203 PyOS_snprintf(newenv, len, "%s=%s", s1, s2); 5204 if (putenv(newenv)) { 5205 Py_DECREF(newstr); 5206 posix_error(); 5207 return NULL; 5208 } 5209#endif 5210 /* Install the first arg and newstr in posix_putenv_garbage; 5211 * this will cause previous value to be collected. This has to 5212 * happen after the real putenv() call because the old value 5213 * was still accessible until then. */ 5214 if (PyDict_SetItem(posix_putenv_garbage, 5215 PyTuple_GET_ITEM(args, 0), newstr)) { 5216 /* really not much we can do; just leak */ 5217 PyErr_Clear(); 5218 } 5219 else { 5220 Py_DECREF(newstr); 5221 } 5222 5223#if defined(PYOS_OS2) 5224 } 5225#endif 5226 Py_INCREF(Py_None); 5227 return Py_None; 5228} 5229#endif /* putenv */ 5230 5231#ifdef HAVE_UNSETENV 5232PyDoc_STRVAR(posix_unsetenv__doc__, 5233"unsetenv(key)\n\n\ 5234Delete an environment variable."); 5235 5236static PyObject * 5237posix_unsetenv(PyObject *self, PyObject *args) 5238{ 5239 char *s1; 5240 5241 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1)) 5242 return NULL; 5243 5244 unsetenv(s1); 5245 5246 /* Remove the key from posix_putenv_garbage; 5247 * this will cause it to be collected. This has to 5248 * happen after the real unsetenv() call because the 5249 * old value was still accessible until then. 5250 */ 5251 if (PyDict_DelItem(posix_putenv_garbage, 5252 PyTuple_GET_ITEM(args, 0))) { 5253 /* really not much we can do; just leak */ 5254 PyErr_Clear(); 5255 } 5256 5257 Py_INCREF(Py_None); 5258 return Py_None; 5259} 5260#endif /* unsetenv */ 5261 5262PyDoc_STRVAR(posix_strerror__doc__, 5263"strerror(code) -> string\n\n\ 5264Translate an error code to a message string."); 5265 5266static PyObject * 5267posix_strerror(PyObject *self, PyObject *args) 5268{ 5269 int code; 5270 char *message; 5271 if (!PyArg_ParseTuple(args, "i:strerror", &code)) 5272 return NULL; 5273 message = strerror(code); 5274 if (message == NULL) { 5275 PyErr_SetString(PyExc_ValueError, 5276 "strerror() argument out of range"); 5277 return NULL; 5278 } 5279 return PyUnicode_FromString(message); 5280} 5281 5282 5283#ifdef HAVE_SYS_WAIT_H 5284 5285#ifdef WCOREDUMP 5286PyDoc_STRVAR(posix_WCOREDUMP__doc__, 5287"WCOREDUMP(status) -> bool\n\n\ 5288Return True if the process returning 'status' was dumped to a core file."); 5289 5290static PyObject * 5291posix_WCOREDUMP(PyObject *self, PyObject *args) 5292{ 5293 WAIT_TYPE status; 5294 WAIT_STATUS_INT(status) = 0; 5295 5296 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status))) 5297 return NULL; 5298 5299 return PyBool_FromLong(WCOREDUMP(status)); 5300} 5301#endif /* WCOREDUMP */ 5302 5303#ifdef WIFCONTINUED 5304PyDoc_STRVAR(posix_WIFCONTINUED__doc__, 5305"WIFCONTINUED(status) -> bool\n\n\ 5306Return True if the process returning 'status' was continued from a\n\ 5307job control stop."); 5308 5309static PyObject * 5310posix_WIFCONTINUED(PyObject *self, PyObject *args) 5311{ 5312 WAIT_TYPE status; 5313 WAIT_STATUS_INT(status) = 0; 5314 5315 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status))) 5316 return NULL; 5317 5318 return PyBool_FromLong(WIFCONTINUED(status)); 5319} 5320#endif /* WIFCONTINUED */ 5321 5322#ifdef WIFSTOPPED 5323PyDoc_STRVAR(posix_WIFSTOPPED__doc__, 5324"WIFSTOPPED(status) -> bool\n\n\ 5325Return True if the process returning 'status' was stopped."); 5326 5327static PyObject * 5328posix_WIFSTOPPED(PyObject *self, PyObject *args) 5329{ 5330 WAIT_TYPE status; 5331 WAIT_STATUS_INT(status) = 0; 5332 5333 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status))) 5334 return NULL; 5335 5336 return PyBool_FromLong(WIFSTOPPED(status)); 5337} 5338#endif /* WIFSTOPPED */ 5339 5340#ifdef WIFSIGNALED 5341PyDoc_STRVAR(posix_WIFSIGNALED__doc__, 5342"WIFSIGNALED(status) -> bool\n\n\ 5343Return True if the process returning 'status' was terminated by a signal."); 5344 5345static PyObject * 5346posix_WIFSIGNALED(PyObject *self, PyObject *args) 5347{ 5348 WAIT_TYPE status; 5349 WAIT_STATUS_INT(status) = 0; 5350 5351 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status))) 5352 return NULL; 5353 5354 return PyBool_FromLong(WIFSIGNALED(status)); 5355} 5356#endif /* WIFSIGNALED */ 5357 5358#ifdef WIFEXITED 5359PyDoc_STRVAR(posix_WIFEXITED__doc__, 5360"WIFEXITED(status) -> bool\n\n\ 5361Return true if the process returning 'status' exited using the exit()\n\ 5362system call."); 5363 5364static PyObject * 5365posix_WIFEXITED(PyObject *self, PyObject *args) 5366{ 5367 WAIT_TYPE status; 5368 WAIT_STATUS_INT(status) = 0; 5369 5370 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status))) 5371 return NULL; 5372 5373 return PyBool_FromLong(WIFEXITED(status)); 5374} 5375#endif /* WIFEXITED */ 5376 5377#ifdef WEXITSTATUS 5378PyDoc_STRVAR(posix_WEXITSTATUS__doc__, 5379"WEXITSTATUS(status) -> integer\n\n\ 5380Return the process return code from 'status'."); 5381 5382static PyObject * 5383posix_WEXITSTATUS(PyObject *self, PyObject *args) 5384{ 5385 WAIT_TYPE status; 5386 WAIT_STATUS_INT(status) = 0; 5387 5388 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status))) 5389 return NULL; 5390 5391 return Py_BuildValue("i", WEXITSTATUS(status)); 5392} 5393#endif /* WEXITSTATUS */ 5394 5395#ifdef WTERMSIG 5396PyDoc_STRVAR(posix_WTERMSIG__doc__, 5397"WTERMSIG(status) -> integer\n\n\ 5398Return the signal that terminated the process that provided the 'status'\n\ 5399value."); 5400 5401static PyObject * 5402posix_WTERMSIG(PyObject *self, PyObject *args) 5403{ 5404 WAIT_TYPE status; 5405 WAIT_STATUS_INT(status) = 0; 5406 5407 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status))) 5408 return NULL; 5409 5410 return Py_BuildValue("i", WTERMSIG(status)); 5411} 5412#endif /* WTERMSIG */ 5413 5414#ifdef WSTOPSIG 5415PyDoc_STRVAR(posix_WSTOPSIG__doc__, 5416"WSTOPSIG(status) -> integer\n\n\ 5417Return the signal that stopped the process that provided\n\ 5418the 'status' value."); 5419 5420static PyObject * 5421posix_WSTOPSIG(PyObject *self, PyObject *args) 5422{ 5423 WAIT_TYPE status; 5424 WAIT_STATUS_INT(status) = 0; 5425 5426 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status))) 5427 return NULL; 5428 5429 return Py_BuildValue("i", WSTOPSIG(status)); 5430} 5431#endif /* WSTOPSIG */ 5432 5433#endif /* HAVE_SYS_WAIT_H */ 5434 5435 5436#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) 5437#ifdef _SCO_DS 5438/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the 5439 needed definitions in sys/statvfs.h */ 5440#define _SVID3 5441#endif 5442#include <sys/statvfs.h> 5443 5444static PyObject* 5445_pystatvfs_fromstructstatvfs(struct statvfs st) { 5446 PyObject *v = PyStructSequence_New(&StatVFSResultType); 5447 if (v == NULL) 5448 return NULL; 5449 5450#if !defined(HAVE_LARGEFILE_SUPPORT) 5451 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize)); 5452 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize)); 5453 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks)); 5454 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree)); 5455 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail)); 5456 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files)); 5457 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree)); 5458 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail)); 5459 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag)); 5460 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax)); 5461#else 5462 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize)); 5463 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize)); 5464 PyStructSequence_SET_ITEM(v, 2, 5465 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks)); 5466 PyStructSequence_SET_ITEM(v, 3, 5467 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree)); 5468 PyStructSequence_SET_ITEM(v, 4, 5469 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail)); 5470 PyStructSequence_SET_ITEM(v, 5, 5471 PyLong_FromLongLong((PY_LONG_LONG) st.f_files)); 5472 PyStructSequence_SET_ITEM(v, 6, 5473 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree)); 5474 PyStructSequence_SET_ITEM(v, 7, 5475 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail)); 5476 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag)); 5477 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax)); 5478#endif 5479 5480 return v; 5481} 5482 5483PyDoc_STRVAR(posix_fstatvfs__doc__, 5484"fstatvfs(fd) -> statvfs result\n\n\ 5485Perform an fstatvfs system call on the given fd."); 5486 5487static PyObject * 5488posix_fstatvfs(PyObject *self, PyObject *args) 5489{ 5490 int fd, res; 5491 struct statvfs st; 5492 5493 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd)) 5494 return NULL; 5495 Py_BEGIN_ALLOW_THREADS 5496 res = fstatvfs(fd, &st); 5497 Py_END_ALLOW_THREADS 5498 if (res != 0) 5499 return posix_error(); 5500 5501 return _pystatvfs_fromstructstatvfs(st); 5502} 5503#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */ 5504 5505 5506#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) 5507#include <sys/statvfs.h> 5508 5509PyDoc_STRVAR(posix_statvfs__doc__, 5510"statvfs(path) -> statvfs result\n\n\ 5511Perform a statvfs system call on the given path."); 5512 5513static PyObject * 5514posix_statvfs(PyObject *self, PyObject *args) 5515{ 5516 char *path; 5517 int res; 5518 struct statvfs st; 5519 if (!PyArg_ParseTuple(args, "s:statvfs", &path)) 5520 return NULL; 5521 Py_BEGIN_ALLOW_THREADS 5522 res = statvfs(path, &st); 5523 Py_END_ALLOW_THREADS 5524 if (res != 0) 5525 return posix_error_with_filename(path); 5526 5527 return _pystatvfs_fromstructstatvfs(st); 5528} 5529#endif /* HAVE_STATVFS */ 5530 5531/* This is used for fpathconf(), pathconf(), confstr() and sysconf(). 5532 * It maps strings representing configuration variable names to 5533 * integer values, allowing those functions to be called with the 5534 * magic names instead of polluting the module's namespace with tons of 5535 * rarely-used constants. There are three separate tables that use 5536 * these definitions. 5537 * 5538 * This code is always included, even if none of the interfaces that 5539 * need it are included. The #if hackery needed to avoid it would be 5540 * sufficiently pervasive that it's not worth the loss of readability. 5541 */ 5542struct constdef { 5543 char *name; 5544 long value; 5545}; 5546 5547static int 5548conv_confname(PyObject *arg, int *valuep, struct constdef *table, 5549 size_t tablesize) 5550{ 5551 if (PyLong_Check(arg)) { 5552 *valuep = PyLong_AS_LONG(arg); 5553 return 1; 5554 } 5555 else { 5556 /* look up the value in the table using a binary search */ 5557 size_t lo = 0; 5558 size_t mid; 5559 size_t hi = tablesize; 5560 int cmp; 5561 const char *confname; 5562 if (!PyUnicode_Check(arg)) { 5563 PyErr_SetString(PyExc_TypeError, 5564 "configuration names must be strings or integers"); 5565 return 0; 5566 } 5567 confname = PyUnicode_AsString(arg); 5568 if (confname == NULL) 5569 return 0; 5570 while (lo < hi) { 5571 mid = (lo + hi) / 2; 5572 cmp = strcmp(confname, table[mid].name); 5573 if (cmp < 0) 5574 hi = mid; 5575 else if (cmp > 0) 5576 lo = mid + 1; 5577 else { 5578 *valuep = table[mid].value; 5579 return 1; 5580 } 5581 } 5582 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name"); 5583 return 0; 5584 } 5585} 5586 5587 5588#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF) 5589static struct constdef posix_constants_pathconf[] = { 5590#ifdef _PC_ABI_AIO_XFER_MAX 5591 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX}, 5592#endif 5593#ifdef _PC_ABI_ASYNC_IO 5594 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO}, 5595#endif 5596#ifdef _PC_ASYNC_IO 5597 {"PC_ASYNC_IO", _PC_ASYNC_IO}, 5598#endif 5599#ifdef _PC_CHOWN_RESTRICTED 5600 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED}, 5601#endif 5602#ifdef _PC_FILESIZEBITS 5603 {"PC_FILESIZEBITS", _PC_FILESIZEBITS}, 5604#endif 5605#ifdef _PC_LAST 5606 {"PC_LAST", _PC_LAST}, 5607#endif 5608#ifdef _PC_LINK_MAX 5609 {"PC_LINK_MAX", _PC_LINK_MAX}, 5610#endif 5611#ifdef _PC_MAX_CANON 5612 {"PC_MAX_CANON", _PC_MAX_CANON}, 5613#endif 5614#ifdef _PC_MAX_INPUT 5615 {"PC_MAX_INPUT", _PC_MAX_INPUT}, 5616#endif 5617#ifdef _PC_NAME_MAX 5618 {"PC_NAME_MAX", _PC_NAME_MAX}, 5619#endif 5620#ifdef _PC_NO_TRUNC 5621 {"PC_NO_TRUNC", _PC_NO_TRUNC}, 5622#endif 5623#ifdef _PC_PATH_MAX 5624 {"PC_PATH_MAX", _PC_PATH_MAX}, 5625#endif 5626#ifdef _PC_PIPE_BUF 5627 {"PC_PIPE_BUF", _PC_PIPE_BUF}, 5628#endif 5629#ifdef _PC_PRIO_IO 5630 {"PC_PRIO_IO", _PC_PRIO_IO}, 5631#endif 5632#ifdef _PC_SOCK_MAXBUF 5633 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF}, 5634#endif 5635#ifdef _PC_SYNC_IO 5636 {"PC_SYNC_IO", _PC_SYNC_IO}, 5637#endif 5638#ifdef _PC_VDISABLE 5639 {"PC_VDISABLE", _PC_VDISABLE}, 5640#endif 5641}; 5642 5643static int 5644conv_path_confname(PyObject *arg, int *valuep) 5645{ 5646 return conv_confname(arg, valuep, posix_constants_pathconf, 5647 sizeof(posix_constants_pathconf) 5648 / sizeof(struct constdef)); 5649} 5650#endif 5651 5652#ifdef HAVE_FPATHCONF 5653PyDoc_STRVAR(posix_fpathconf__doc__, 5654"fpathconf(fd, name) -> integer\n\n\ 5655Return the configuration limit name for the file descriptor fd.\n\ 5656If there is no limit, return -1."); 5657 5658static PyObject * 5659posix_fpathconf(PyObject *self, PyObject *args) 5660{ 5661 PyObject *result = NULL; 5662 int name, fd; 5663 5664 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd, 5665 conv_path_confname, &name)) { 5666 long limit; 5667 5668 errno = 0; 5669 limit = fpathconf(fd, name); 5670 if (limit == -1 && errno != 0) 5671 posix_error(); 5672 else 5673 result = PyLong_FromLong(limit); 5674 } 5675 return result; 5676} 5677#endif 5678 5679 5680#ifdef HAVE_PATHCONF 5681PyDoc_STRVAR(posix_pathconf__doc__, 5682"pathconf(path, name) -> integer\n\n\ 5683Return the configuration limit name for the file or directory path.\n\ 5684If there is no limit, return -1."); 5685 5686static PyObject * 5687posix_pathconf(PyObject *self, PyObject *args) 5688{ 5689 PyObject *result = NULL; 5690 int name; 5691 char *path; 5692 5693 if (PyArg_ParseTuple(args, "sO&:pathconf", &path, 5694 conv_path_confname, &name)) { 5695 long limit; 5696 5697 errno = 0; 5698 limit = pathconf(path, name); 5699 if (limit == -1 && errno != 0) { 5700 if (errno == EINVAL) 5701 /* could be a path or name problem */ 5702 posix_error(); 5703 else 5704 posix_error_with_filename(path); 5705 } 5706 else 5707 result = PyLong_FromLong(limit); 5708 } 5709 return result; 5710} 5711#endif 5712 5713#ifdef HAVE_CONFSTR 5714static struct constdef posix_constants_confstr[] = { 5715#ifdef _CS_ARCHITECTURE 5716 {"CS_ARCHITECTURE", _CS_ARCHITECTURE}, 5717#endif 5718#ifdef _CS_HOSTNAME 5719 {"CS_HOSTNAME", _CS_HOSTNAME}, 5720#endif 5721#ifdef _CS_HW_PROVIDER 5722 {"CS_HW_PROVIDER", _CS_HW_PROVIDER}, 5723#endif 5724#ifdef _CS_HW_SERIAL 5725 {"CS_HW_SERIAL", _CS_HW_SERIAL}, 5726#endif 5727#ifdef _CS_INITTAB_NAME 5728 {"CS_INITTAB_NAME", _CS_INITTAB_NAME}, 5729#endif 5730#ifdef _CS_LFS64_CFLAGS 5731 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS}, 5732#endif 5733#ifdef _CS_LFS64_LDFLAGS 5734 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS}, 5735#endif 5736#ifdef _CS_LFS64_LIBS 5737 {"CS_LFS64_LIBS", _CS_LFS64_LIBS}, 5738#endif 5739#ifdef _CS_LFS64_LINTFLAGS 5740 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS}, 5741#endif 5742#ifdef _CS_LFS_CFLAGS 5743 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS}, 5744#endif 5745#ifdef _CS_LFS_LDFLAGS 5746 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS}, 5747#endif 5748#ifdef _CS_LFS_LIBS 5749 {"CS_LFS_LIBS", _CS_LFS_LIBS}, 5750#endif 5751#ifdef _CS_LFS_LINTFLAGS 5752 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS}, 5753#endif 5754#ifdef _CS_MACHINE 5755 {"CS_MACHINE", _CS_MACHINE}, 5756#endif 5757#ifdef _CS_PATH 5758 {"CS_PATH", _CS_PATH}, 5759#endif 5760#ifdef _CS_RELEASE 5761 {"CS_RELEASE", _CS_RELEASE}, 5762#endif 5763#ifdef _CS_SRPC_DOMAIN 5764 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN}, 5765#endif 5766#ifdef _CS_SYSNAME 5767 {"CS_SYSNAME", _CS_SYSNAME}, 5768#endif 5769#ifdef _CS_VERSION 5770 {"CS_VERSION", _CS_VERSION}, 5771#endif 5772#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS 5773 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS}, 5774#endif 5775#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS 5776 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS}, 5777#endif 5778#ifdef _CS_XBS5_ILP32_OFF32_LIBS 5779 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS}, 5780#endif 5781#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS 5782 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS}, 5783#endif 5784#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS 5785 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS}, 5786#endif 5787#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS 5788 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS}, 5789#endif 5790#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS 5791 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS}, 5792#endif 5793#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS 5794 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS}, 5795#endif 5796#ifdef _CS_XBS5_LP64_OFF64_CFLAGS 5797 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS}, 5798#endif 5799#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS 5800 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS}, 5801#endif 5802#ifdef _CS_XBS5_LP64_OFF64_LIBS 5803 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS}, 5804#endif 5805#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS 5806 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS}, 5807#endif 5808#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS 5809 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS}, 5810#endif 5811#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS 5812 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS}, 5813#endif 5814#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS 5815 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS}, 5816#endif 5817#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS 5818 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS}, 5819#endif 5820#ifdef _MIPS_CS_AVAIL_PROCESSORS 5821 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS}, 5822#endif 5823#ifdef _MIPS_CS_BASE 5824 {"MIPS_CS_BASE", _MIPS_CS_BASE}, 5825#endif 5826#ifdef _MIPS_CS_HOSTID 5827 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID}, 5828#endif 5829#ifdef _MIPS_CS_HW_NAME 5830 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME}, 5831#endif 5832#ifdef _MIPS_CS_NUM_PROCESSORS 5833 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS}, 5834#endif 5835#ifdef _MIPS_CS_OSREL_MAJ 5836 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ}, 5837#endif 5838#ifdef _MIPS_CS_OSREL_MIN 5839 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN}, 5840#endif 5841#ifdef _MIPS_CS_OSREL_PATCH 5842 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH}, 5843#endif 5844#ifdef _MIPS_CS_OS_NAME 5845 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME}, 5846#endif 5847#ifdef _MIPS_CS_OS_PROVIDER 5848 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER}, 5849#endif 5850#ifdef _MIPS_CS_PROCESSORS 5851 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS}, 5852#endif 5853#ifdef _MIPS_CS_SERIAL 5854 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL}, 5855#endif 5856#ifdef _MIPS_CS_VENDOR 5857 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR}, 5858#endif 5859}; 5860 5861static int 5862conv_confstr_confname(PyObject *arg, int *valuep) 5863{ 5864 return conv_confname(arg, valuep, posix_constants_confstr, 5865 sizeof(posix_constants_confstr) 5866 / sizeof(struct constdef)); 5867} 5868 5869PyDoc_STRVAR(posix_confstr__doc__, 5870"confstr(name) -> string\n\n\ 5871Return a string-valued system configuration variable."); 5872 5873static PyObject * 5874posix_confstr(PyObject *self, PyObject *args) 5875{ 5876 PyObject *result = NULL; 5877 int name; 5878 char buffer[256]; 5879 5880 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) { 5881 int len; 5882 5883 errno = 0; 5884 len = confstr(name, buffer, sizeof(buffer)); 5885 if (len == 0) { 5886 if (errno) { 5887 posix_error(); 5888 } 5889 else { 5890 result = Py_None; 5891 Py_INCREF(Py_None); 5892 } 5893 } 5894 else { 5895 if ((unsigned int)len >= sizeof(buffer)) { 5896 result = PyUnicode_FromStringAndSize(NULL, len-1); 5897 if (result != NULL) 5898 confstr(name, PyUnicode_AsString(result), len); 5899 } 5900 else 5901 result = PyUnicode_FromStringAndSize(buffer, len-1); 5902 } 5903 } 5904 return result; 5905} 5906#endif 5907 5908 5909#ifdef HAVE_SYSCONF 5910static struct constdef posix_constants_sysconf[] = { 5911#ifdef _SC_2_CHAR_TERM 5912 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM}, 5913#endif 5914#ifdef _SC_2_C_BIND 5915 {"SC_2_C_BIND", _SC_2_C_BIND}, 5916#endif 5917#ifdef _SC_2_C_DEV 5918 {"SC_2_C_DEV", _SC_2_C_DEV}, 5919#endif 5920#ifdef _SC_2_C_VERSION 5921 {"SC_2_C_VERSION", _SC_2_C_VERSION}, 5922#endif 5923#ifdef _SC_2_FORT_DEV 5924 {"SC_2_FORT_DEV", _SC_2_FORT_DEV}, 5925#endif 5926#ifdef _SC_2_FORT_RUN 5927 {"SC_2_FORT_RUN", _SC_2_FORT_RUN}, 5928#endif 5929#ifdef _SC_2_LOCALEDEF 5930 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF}, 5931#endif 5932#ifdef _SC_2_SW_DEV 5933 {"SC_2_SW_DEV", _SC_2_SW_DEV}, 5934#endif 5935#ifdef _SC_2_UPE 5936 {"SC_2_UPE", _SC_2_UPE}, 5937#endif 5938#ifdef _SC_2_VERSION 5939 {"SC_2_VERSION", _SC_2_VERSION}, 5940#endif 5941#ifdef _SC_ABI_ASYNCHRONOUS_IO 5942 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO}, 5943#endif 5944#ifdef _SC_ACL 5945 {"SC_ACL", _SC_ACL}, 5946#endif 5947#ifdef _SC_AIO_LISTIO_MAX 5948 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX}, 5949#endif 5950#ifdef _SC_AIO_MAX 5951 {"SC_AIO_MAX", _SC_AIO_MAX}, 5952#endif 5953#ifdef _SC_AIO_PRIO_DELTA_MAX 5954 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX}, 5955#endif 5956#ifdef _SC_ARG_MAX 5957 {"SC_ARG_MAX", _SC_ARG_MAX}, 5958#endif 5959#ifdef _SC_ASYNCHRONOUS_IO 5960 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO}, 5961#endif 5962#ifdef _SC_ATEXIT_MAX 5963 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX}, 5964#endif 5965#ifdef _SC_AUDIT 5966 {"SC_AUDIT", _SC_AUDIT}, 5967#endif 5968#ifdef _SC_AVPHYS_PAGES 5969 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES}, 5970#endif 5971#ifdef _SC_BC_BASE_MAX 5972 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX}, 5973#endif 5974#ifdef _SC_BC_DIM_MAX 5975 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX}, 5976#endif 5977#ifdef _SC_BC_SCALE_MAX 5978 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX}, 5979#endif 5980#ifdef _SC_BC_STRING_MAX 5981 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX}, 5982#endif 5983#ifdef _SC_CAP 5984 {"SC_CAP", _SC_CAP}, 5985#endif 5986#ifdef _SC_CHARCLASS_NAME_MAX 5987 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX}, 5988#endif 5989#ifdef _SC_CHAR_BIT 5990 {"SC_CHAR_BIT", _SC_CHAR_BIT}, 5991#endif 5992#ifdef _SC_CHAR_MAX 5993 {"SC_CHAR_MAX", _SC_CHAR_MAX}, 5994#endif 5995#ifdef _SC_CHAR_MIN 5996 {"SC_CHAR_MIN", _SC_CHAR_MIN}, 5997#endif 5998#ifdef _SC_CHILD_MAX 5999 {"SC_CHILD_MAX", _SC_CHILD_MAX}, 6000#endif 6001#ifdef _SC_CLK_TCK 6002 {"SC_CLK_TCK", _SC_CLK_TCK}, 6003#endif 6004#ifdef _SC_COHER_BLKSZ 6005 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ}, 6006#endif 6007#ifdef _SC_COLL_WEIGHTS_MAX 6008 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX}, 6009#endif 6010#ifdef _SC_DCACHE_ASSOC 6011 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC}, 6012#endif 6013#ifdef _SC_DCACHE_BLKSZ 6014 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ}, 6015#endif 6016#ifdef _SC_DCACHE_LINESZ 6017 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ}, 6018#endif 6019#ifdef _SC_DCACHE_SZ 6020 {"SC_DCACHE_SZ", _SC_DCACHE_SZ}, 6021#endif 6022#ifdef _SC_DCACHE_TBLKSZ 6023 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ}, 6024#endif 6025#ifdef _SC_DELAYTIMER_MAX 6026 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX}, 6027#endif 6028#ifdef _SC_EQUIV_CLASS_MAX 6029 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX}, 6030#endif 6031#ifdef _SC_EXPR_NEST_MAX 6032 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX}, 6033#endif 6034#ifdef _SC_FSYNC 6035 {"SC_FSYNC", _SC_FSYNC}, 6036#endif 6037#ifdef _SC_GETGR_R_SIZE_MAX 6038 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX}, 6039#endif 6040#ifdef _SC_GETPW_R_SIZE_MAX 6041 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX}, 6042#endif 6043#ifdef _SC_ICACHE_ASSOC 6044 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC}, 6045#endif 6046#ifdef _SC_ICACHE_BLKSZ 6047 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ}, 6048#endif 6049#ifdef _SC_ICACHE_LINESZ 6050 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ}, 6051#endif 6052#ifdef _SC_ICACHE_SZ 6053 {"SC_ICACHE_SZ", _SC_ICACHE_SZ}, 6054#endif 6055#ifdef _SC_INF 6056 {"SC_INF", _SC_INF}, 6057#endif 6058#ifdef _SC_INT_MAX 6059 {"SC_INT_MAX", _SC_INT_MAX}, 6060#endif 6061#ifdef _SC_INT_MIN 6062 {"SC_INT_MIN", _SC_INT_MIN}, 6063#endif 6064#ifdef _SC_IOV_MAX 6065 {"SC_IOV_MAX", _SC_IOV_MAX}, 6066#endif 6067#ifdef _SC_IP_SECOPTS 6068 {"SC_IP_SECOPTS", _SC_IP_SECOPTS}, 6069#endif 6070#ifdef _SC_JOB_CONTROL 6071 {"SC_JOB_CONTROL", _SC_JOB_CONTROL}, 6072#endif 6073#ifdef _SC_KERN_POINTERS 6074 {"SC_KERN_POINTERS", _SC_KERN_POINTERS}, 6075#endif 6076#ifdef _SC_KERN_SIM 6077 {"SC_KERN_SIM", _SC_KERN_SIM}, 6078#endif 6079#ifdef _SC_LINE_MAX 6080 {"SC_LINE_MAX", _SC_LINE_MAX}, 6081#endif 6082#ifdef _SC_LOGIN_NAME_MAX 6083 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX}, 6084#endif 6085#ifdef _SC_LOGNAME_MAX 6086 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX}, 6087#endif 6088#ifdef _SC_LONG_BIT 6089 {"SC_LONG_BIT", _SC_LONG_BIT}, 6090#endif 6091#ifdef _SC_MAC 6092 {"SC_MAC", _SC_MAC}, 6093#endif 6094#ifdef _SC_MAPPED_FILES 6095 {"SC_MAPPED_FILES", _SC_MAPPED_FILES}, 6096#endif 6097#ifdef _SC_MAXPID 6098 {"SC_MAXPID", _SC_MAXPID}, 6099#endif 6100#ifdef _SC_MB_LEN_MAX 6101 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX}, 6102#endif 6103#ifdef _SC_MEMLOCK 6104 {"SC_MEMLOCK", _SC_MEMLOCK}, 6105#endif 6106#ifdef _SC_MEMLOCK_RANGE 6107 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE}, 6108#endif 6109#ifdef _SC_MEMORY_PROTECTION 6110 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION}, 6111#endif 6112#ifdef _SC_MESSAGE_PASSING 6113 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING}, 6114#endif 6115#ifdef _SC_MMAP_FIXED_ALIGNMENT 6116 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT}, 6117#endif 6118#ifdef _SC_MQ_OPEN_MAX 6119 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX}, 6120#endif 6121#ifdef _SC_MQ_PRIO_MAX 6122 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX}, 6123#endif 6124#ifdef _SC_NACLS_MAX 6125 {"SC_NACLS_MAX", _SC_NACLS_MAX}, 6126#endif 6127#ifdef _SC_NGROUPS_MAX 6128 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX}, 6129#endif 6130#ifdef _SC_NL_ARGMAX 6131 {"SC_NL_ARGMAX", _SC_NL_ARGMAX}, 6132#endif 6133#ifdef _SC_NL_LANGMAX 6134 {"SC_NL_LANGMAX", _SC_NL_LANGMAX}, 6135#endif 6136#ifdef _SC_NL_MSGMAX 6137 {"SC_NL_MSGMAX", _SC_NL_MSGMAX}, 6138#endif 6139#ifdef _SC_NL_NMAX 6140 {"SC_NL_NMAX", _SC_NL_NMAX}, 6141#endif 6142#ifdef _SC_NL_SETMAX 6143 {"SC_NL_SETMAX", _SC_NL_SETMAX}, 6144#endif 6145#ifdef _SC_NL_TEXTMAX 6146 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX}, 6147#endif 6148#ifdef _SC_NPROCESSORS_CONF 6149 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF}, 6150#endif 6151#ifdef _SC_NPROCESSORS_ONLN 6152 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN}, 6153#endif 6154#ifdef _SC_NPROC_CONF 6155 {"SC_NPROC_CONF", _SC_NPROC_CONF}, 6156#endif 6157#ifdef _SC_NPROC_ONLN 6158 {"SC_NPROC_ONLN", _SC_NPROC_ONLN}, 6159#endif 6160#ifdef _SC_NZERO 6161 {"SC_NZERO", _SC_NZERO}, 6162#endif 6163#ifdef _SC_OPEN_MAX 6164 {"SC_OPEN_MAX", _SC_OPEN_MAX}, 6165#endif 6166#ifdef _SC_PAGESIZE 6167 {"SC_PAGESIZE", _SC_PAGESIZE}, 6168#endif 6169#ifdef _SC_PAGE_SIZE 6170 {"SC_PAGE_SIZE", _SC_PAGE_SIZE}, 6171#endif 6172#ifdef _SC_PASS_MAX 6173 {"SC_PASS_MAX", _SC_PASS_MAX}, 6174#endif 6175#ifdef _SC_PHYS_PAGES 6176 {"SC_PHYS_PAGES", _SC_PHYS_PAGES}, 6177#endif 6178#ifdef _SC_PII 6179 {"SC_PII", _SC_PII}, 6180#endif 6181#ifdef _SC_PII_INTERNET 6182 {"SC_PII_INTERNET", _SC_PII_INTERNET}, 6183#endif 6184#ifdef _SC_PII_INTERNET_DGRAM 6185 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM}, 6186#endif 6187#ifdef _SC_PII_INTERNET_STREAM 6188 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM}, 6189#endif 6190#ifdef _SC_PII_OSI 6191 {"SC_PII_OSI", _SC_PII_OSI}, 6192#endif 6193#ifdef _SC_PII_OSI_CLTS 6194 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS}, 6195#endif 6196#ifdef _SC_PII_OSI_COTS 6197 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS}, 6198#endif 6199#ifdef _SC_PII_OSI_M 6200 {"SC_PII_OSI_M", _SC_PII_OSI_M}, 6201#endif 6202#ifdef _SC_PII_SOCKET 6203 {"SC_PII_SOCKET", _SC_PII_SOCKET}, 6204#endif 6205#ifdef _SC_PII_XTI 6206 {"SC_PII_XTI", _SC_PII_XTI}, 6207#endif 6208#ifdef _SC_POLL 6209 {"SC_POLL", _SC_POLL}, 6210#endif 6211#ifdef _SC_PRIORITIZED_IO 6212 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO}, 6213#endif 6214#ifdef _SC_PRIORITY_SCHEDULING 6215 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING}, 6216#endif 6217#ifdef _SC_REALTIME_SIGNALS 6218 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS}, 6219#endif 6220#ifdef _SC_RE_DUP_MAX 6221 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX}, 6222#endif 6223#ifdef _SC_RTSIG_MAX 6224 {"SC_RTSIG_MAX", _SC_RTSIG_MAX}, 6225#endif 6226#ifdef _SC_SAVED_IDS 6227 {"SC_SAVED_IDS", _SC_SAVED_IDS}, 6228#endif 6229#ifdef _SC_SCHAR_MAX 6230 {"SC_SCHAR_MAX", _SC_SCHAR_MAX}, 6231#endif 6232#ifdef _SC_SCHAR_MIN 6233 {"SC_SCHAR_MIN", _SC_SCHAR_MIN}, 6234#endif 6235#ifdef _SC_SELECT 6236 {"SC_SELECT", _SC_SELECT}, 6237#endif 6238#ifdef _SC_SEMAPHORES 6239 {"SC_SEMAPHORES", _SC_SEMAPHORES}, 6240#endif 6241#ifdef _SC_SEM_NSEMS_MAX 6242 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX}, 6243#endif 6244#ifdef _SC_SEM_VALUE_MAX 6245 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX}, 6246#endif 6247#ifdef _SC_SHARED_MEMORY_OBJECTS 6248 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS}, 6249#endif 6250#ifdef _SC_SHRT_MAX 6251 {"SC_SHRT_MAX", _SC_SHRT_MAX}, 6252#endif 6253#ifdef _SC_SHRT_MIN 6254 {"SC_SHRT_MIN", _SC_SHRT_MIN}, 6255#endif 6256#ifdef _SC_SIGQUEUE_MAX 6257 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX}, 6258#endif 6259#ifdef _SC_SIGRT_MAX 6260 {"SC_SIGRT_MAX", _SC_SIGRT_MAX}, 6261#endif 6262#ifdef _SC_SIGRT_MIN 6263 {"SC_SIGRT_MIN", _SC_SIGRT_MIN}, 6264#endif 6265#ifdef _SC_SOFTPOWER 6266 {"SC_SOFTPOWER", _SC_SOFTPOWER}, 6267#endif 6268#ifdef _SC_SPLIT_CACHE 6269 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE}, 6270#endif 6271#ifdef _SC_SSIZE_MAX 6272 {"SC_SSIZE_MAX", _SC_SSIZE_MAX}, 6273#endif 6274#ifdef _SC_STACK_PROT 6275 {"SC_STACK_PROT", _SC_STACK_PROT}, 6276#endif 6277#ifdef _SC_STREAM_MAX 6278 {"SC_STREAM_MAX", _SC_STREAM_MAX}, 6279#endif 6280#ifdef _SC_SYNCHRONIZED_IO 6281 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO}, 6282#endif 6283#ifdef _SC_THREADS 6284 {"SC_THREADS", _SC_THREADS}, 6285#endif 6286#ifdef _SC_THREAD_ATTR_STACKADDR 6287 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR}, 6288#endif 6289#ifdef _SC_THREAD_ATTR_STACKSIZE 6290 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE}, 6291#endif 6292#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS 6293 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS}, 6294#endif 6295#ifdef _SC_THREAD_KEYS_MAX 6296 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX}, 6297#endif 6298#ifdef _SC_THREAD_PRIORITY_SCHEDULING 6299 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING}, 6300#endif 6301#ifdef _SC_THREAD_PRIO_INHERIT 6302 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT}, 6303#endif 6304#ifdef _SC_THREAD_PRIO_PROTECT 6305 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT}, 6306#endif 6307#ifdef _SC_THREAD_PROCESS_SHARED 6308 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED}, 6309#endif 6310#ifdef _SC_THREAD_SAFE_FUNCTIONS 6311 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS}, 6312#endif 6313#ifdef _SC_THREAD_STACK_MIN 6314 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN}, 6315#endif 6316#ifdef _SC_THREAD_THREADS_MAX 6317 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX}, 6318#endif 6319#ifdef _SC_TIMERS 6320 {"SC_TIMERS", _SC_TIMERS}, 6321#endif 6322#ifdef _SC_TIMER_MAX 6323 {"SC_TIMER_MAX", _SC_TIMER_MAX}, 6324#endif 6325#ifdef _SC_TTY_NAME_MAX 6326 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX}, 6327#endif 6328#ifdef _SC_TZNAME_MAX 6329 {"SC_TZNAME_MAX", _SC_TZNAME_MAX}, 6330#endif 6331#ifdef _SC_T_IOV_MAX 6332 {"SC_T_IOV_MAX", _SC_T_IOV_MAX}, 6333#endif 6334#ifdef _SC_UCHAR_MAX 6335 {"SC_UCHAR_MAX", _SC_UCHAR_MAX}, 6336#endif 6337#ifdef _SC_UINT_MAX 6338 {"SC_UINT_MAX", _SC_UINT_MAX}, 6339#endif 6340#ifdef _SC_UIO_MAXIOV 6341 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV}, 6342#endif 6343#ifdef _SC_ULONG_MAX 6344 {"SC_ULONG_MAX", _SC_ULONG_MAX}, 6345#endif 6346#ifdef _SC_USHRT_MAX 6347 {"SC_USHRT_MAX", _SC_USHRT_MAX}, 6348#endif 6349#ifdef _SC_VERSION 6350 {"SC_VERSION", _SC_VERSION}, 6351#endif 6352#ifdef _SC_WORD_BIT 6353 {"SC_WORD_BIT", _SC_WORD_BIT}, 6354#endif 6355#ifdef _SC_XBS5_ILP32_OFF32 6356 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32}, 6357#endif 6358#ifdef _SC_XBS5_ILP32_OFFBIG 6359 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG}, 6360#endif 6361#ifdef _SC_XBS5_LP64_OFF64 6362 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64}, 6363#endif 6364#ifdef _SC_XBS5_LPBIG_OFFBIG 6365 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG}, 6366#endif 6367#ifdef _SC_XOPEN_CRYPT 6368 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT}, 6369#endif 6370#ifdef _SC_XOPEN_ENH_I18N 6371 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N}, 6372#endif 6373#ifdef _SC_XOPEN_LEGACY 6374 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY}, 6375#endif 6376#ifdef _SC_XOPEN_REALTIME 6377 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME}, 6378#endif 6379#ifdef _SC_XOPEN_REALTIME_THREADS 6380 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS}, 6381#endif 6382#ifdef _SC_XOPEN_SHM 6383 {"SC_XOPEN_SHM", _SC_XOPEN_SHM}, 6384#endif 6385#ifdef _SC_XOPEN_UNIX 6386 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX}, 6387#endif 6388#ifdef _SC_XOPEN_VERSION 6389 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION}, 6390#endif 6391#ifdef _SC_XOPEN_XCU_VERSION 6392 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION}, 6393#endif 6394#ifdef _SC_XOPEN_XPG2 6395 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2}, 6396#endif 6397#ifdef _SC_XOPEN_XPG3 6398 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3}, 6399#endif 6400#ifdef _SC_XOPEN_XPG4 6401 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4}, 6402#endif 6403}; 6404 6405static int 6406conv_sysconf_confname(PyObject *arg, int *valuep) 6407{ 6408 return conv_confname(arg, valuep, posix_constants_sysconf, 6409 sizeof(posix_constants_sysconf) 6410 / sizeof(struct constdef)); 6411} 6412 6413PyDoc_STRVAR(posix_sysconf__doc__, 6414"sysconf(name) -> integer\n\n\ 6415Return an integer-valued system configuration variable."); 6416 6417static PyObject * 6418posix_sysconf(PyObject *self, PyObject *args) 6419{ 6420 PyObject *result = NULL; 6421 int name; 6422 6423 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) { 6424 int value; 6425 6426 errno = 0; 6427 value = sysconf(name); 6428 if (value == -1 && errno != 0) 6429 posix_error(); 6430 else 6431 result = PyLong_FromLong(value); 6432 } 6433 return result; 6434} 6435#endif 6436 6437 6438/* This code is used to ensure that the tables of configuration value names 6439 * are in sorted order as required by conv_confname(), and also to build the 6440 * the exported dictionaries that are used to publish information about the 6441 * names available on the host platform. 6442 * 6443 * Sorting the table at runtime ensures that the table is properly ordered 6444 * when used, even for platforms we're not able to test on. It also makes 6445 * it easier to add additional entries to the tables. 6446 */ 6447 6448static int 6449cmp_constdefs(const void *v1, const void *v2) 6450{ 6451 const struct constdef *c1 = 6452 (const struct constdef *) v1; 6453 const struct constdef *c2 = 6454 (const struct constdef *) v2; 6455 6456 return strcmp(c1->name, c2->name); 6457} 6458 6459static int 6460setup_confname_table(struct constdef *table, size_t tablesize, 6461 char *tablename, PyObject *module) 6462{ 6463 PyObject *d = NULL; 6464 size_t i; 6465 6466 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs); 6467 d = PyDict_New(); 6468 if (d == NULL) 6469 return -1; 6470 6471 for (i=0; i < tablesize; ++i) { 6472 PyObject *o = PyLong_FromLong(table[i].value); 6473 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) { 6474 Py_XDECREF(o); 6475 Py_DECREF(d); 6476 return -1; 6477 } 6478 Py_DECREF(o); 6479 } 6480 return PyModule_AddObject(module, tablename, d); 6481} 6482 6483/* Return -1 on failure, 0 on success. */ 6484static int 6485setup_confname_tables(PyObject *module) 6486{ 6487#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF) 6488 if (setup_confname_table(posix_constants_pathconf, 6489 sizeof(posix_constants_pathconf) 6490 / sizeof(struct constdef), 6491 "pathconf_names", module)) 6492 return -1; 6493#endif 6494#ifdef HAVE_CONFSTR 6495 if (setup_confname_table(posix_constants_confstr, 6496 sizeof(posix_constants_confstr) 6497 / sizeof(struct constdef), 6498 "confstr_names", module)) 6499 return -1; 6500#endif 6501#ifdef HAVE_SYSCONF 6502 if (setup_confname_table(posix_constants_sysconf, 6503 sizeof(posix_constants_sysconf) 6504 / sizeof(struct constdef), 6505 "sysconf_names", module)) 6506 return -1; 6507#endif 6508 return 0; 6509} 6510 6511 6512PyDoc_STRVAR(posix_abort__doc__, 6513"abort() -> does not return!\n\n\ 6514Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\ 6515in the hardest way possible on the hosting operating system."); 6516 6517static PyObject * 6518posix_abort(PyObject *self, PyObject *noargs) 6519{ 6520 abort(); 6521 /*NOTREACHED*/ 6522 Py_FatalError("abort() called from Python code didn't abort!"); 6523 return NULL; 6524} 6525 6526#ifdef MS_WINDOWS 6527PyDoc_STRVAR(win32_startfile__doc__, 6528"startfile(filepath [, operation]) - Start a file with its associated\n\ 6529application.\n\ 6530\n\ 6531When \"operation\" is not specified or \"open\", this acts like\n\ 6532double-clicking the file in Explorer, or giving the file name as an\n\ 6533argument to the DOS \"start\" command: the file is opened with whatever\n\ 6534application (if any) its extension is associated.\n\ 6535When another \"operation\" is given, it specifies what should be done with\n\ 6536the file. A typical operation is \"print\".\n\ 6537\n\ 6538startfile returns as soon as the associated application is launched.\n\ 6539There is no option to wait for the application to close, and no way\n\ 6540to retrieve the application's exit status.\n\ 6541\n\ 6542The filepath is relative to the current directory. If you want to use\n\ 6543an absolute path, make sure the first character is not a slash (\"/\");\n\ 6544the underlying Win32 ShellExecute function doesn't work if it is."); 6545 6546static PyObject * 6547win32_startfile(PyObject *self, PyObject *args) 6548{ 6549 char *filepath; 6550 char *operation = NULL; 6551 HINSTANCE rc; 6552#ifdef Py_WIN_WIDE_FILENAMES 6553 if (unicode_file_names()) { 6554 PyObject *unipath, *woperation = NULL; 6555 if (!PyArg_ParseTuple(args, "U|s:startfile", 6556 &unipath, &operation)) { 6557 PyErr_Clear(); 6558 goto normal; 6559 } 6560 6561 6562 if (operation) { 6563 woperation = PyUnicode_DecodeASCII(operation, 6564 strlen(operation), NULL); 6565 if (!woperation) { 6566 PyErr_Clear(); 6567 operation = NULL; 6568 goto normal; 6569 } 6570 } 6571 6572 Py_BEGIN_ALLOW_THREADS 6573 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0, 6574 PyUnicode_AS_UNICODE(unipath), 6575 NULL, NULL, SW_SHOWNORMAL); 6576 Py_END_ALLOW_THREADS 6577 6578 Py_XDECREF(woperation); 6579 if (rc <= (HINSTANCE)32) { 6580 PyObject *errval = win32_error_unicode("startfile", 6581 PyUnicode_AS_UNICODE(unipath)); 6582 return errval; 6583 } 6584 Py_INCREF(Py_None); 6585 return Py_None; 6586 } 6587#endif 6588 6589normal: 6590 if (!PyArg_ParseTuple(args, "et|s:startfile", 6591 Py_FileSystemDefaultEncoding, &filepath, 6592 &operation)) 6593 return NULL; 6594 Py_BEGIN_ALLOW_THREADS 6595 rc = ShellExecute((HWND)0, operation, filepath, 6596 NULL, NULL, SW_SHOWNORMAL); 6597 Py_END_ALLOW_THREADS 6598 if (rc <= (HINSTANCE)32) { 6599 PyObject *errval = win32_error("startfile", filepath); 6600 PyMem_Free(filepath); 6601 return errval; 6602 } 6603 PyMem_Free(filepath); 6604 Py_INCREF(Py_None); 6605 return Py_None; 6606} 6607#endif 6608 6609#ifdef HAVE_GETLOADAVG 6610PyDoc_STRVAR(posix_getloadavg__doc__, 6611"getloadavg() -> (float, float, float)\n\n\ 6612Return the number of processes in the system run queue averaged over\n\ 6613the last 1, 5, and 15 minutes or raises OSError if the load average\n\ 6614was unobtainable"); 6615 6616static PyObject * 6617posix_getloadavg(PyObject *self, PyObject *noargs) 6618{ 6619 double loadavg[3]; 6620 if (getloadavg(loadavg, 3)!=3) { 6621 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable"); 6622 return NULL; 6623 } else 6624 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]); 6625} 6626#endif 6627 6628#ifdef MS_WINDOWS 6629 6630PyDoc_STRVAR(win32_urandom__doc__, 6631"urandom(n) -> str\n\n\ 6632Return n random bytes suitable for cryptographic use."); 6633 6634typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\ 6635 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\ 6636 DWORD dwFlags ); 6637typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\ 6638 BYTE *pbBuffer ); 6639 6640static CRYPTGENRANDOM pCryptGenRandom = NULL; 6641/* This handle is never explicitly released. Instead, the operating 6642 system will release it when the process terminates. */ 6643static HCRYPTPROV hCryptProv = 0; 6644 6645static PyObject* 6646win32_urandom(PyObject *self, PyObject *args) 6647{ 6648 int howMany; 6649 PyObject* result; 6650 6651 /* Read arguments */ 6652 if (! PyArg_ParseTuple(args, "i:urandom", &howMany)) 6653 return NULL; 6654 if (howMany < 0) 6655 return PyErr_Format(PyExc_ValueError, 6656 "negative argument not allowed"); 6657 6658 if (hCryptProv == 0) { 6659 HINSTANCE hAdvAPI32 = NULL; 6660 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL; 6661 6662 /* Obtain handle to the DLL containing CryptoAPI 6663 This should not fail */ 6664 hAdvAPI32 = GetModuleHandle("advapi32.dll"); 6665 if(hAdvAPI32 == NULL) 6666 return win32_error("GetModuleHandle", NULL); 6667 6668 /* Obtain pointers to the CryptoAPI functions 6669 This will fail on some early versions of Win95 */ 6670 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress( 6671 hAdvAPI32, 6672 "CryptAcquireContextA"); 6673 if (pCryptAcquireContext == NULL) 6674 return PyErr_Format(PyExc_NotImplementedError, 6675 "CryptAcquireContextA not found"); 6676 6677 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress( 6678 hAdvAPI32, "CryptGenRandom"); 6679 if (pCryptGenRandom == NULL) 6680 return PyErr_Format(PyExc_NotImplementedError, 6681 "CryptGenRandom not found"); 6682 6683 /* Acquire context */ 6684 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL, 6685 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) 6686 return win32_error("CryptAcquireContext", NULL); 6687 } 6688 6689 /* Allocate bytes */ 6690 result = PyBytes_FromStringAndSize(NULL, howMany); 6691 if (result != NULL) { 6692 /* Get random data */ 6693 memset(PyBytes_AS_STRING(result), 0, howMany); /* zero seed */ 6694 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*) 6695 PyBytes_AS_STRING(result))) { 6696 Py_DECREF(result); 6697 return win32_error("CryptGenRandom", NULL); 6698 } 6699 } 6700 return result; 6701} 6702#endif 6703 6704PyDoc_STRVAR(device_encoding__doc__, 6705"device_encoding(fd) -> str\n\n\ 6706Return a string describing the encoding of the device\n\ 6707if the output is a terminal; else return None."); 6708 6709static PyObject * 6710device_encoding(PyObject *self, PyObject *args) 6711{ 6712 int fd; 6713 if (!PyArg_ParseTuple(args, "i:device_encoding", &fd)) 6714 return NULL; 6715 if (!isatty(fd)) { 6716 Py_INCREF(Py_None); 6717 return Py_None; 6718 } 6719#if defined(MS_WINDOWS) || defined(MS_WIN64) 6720 if (fd == 0) { 6721 char buf[100]; 6722 sprintf(buf, "cp%d", GetConsoleCP()); 6723 return PyUnicode_FromString(buf); 6724 } 6725 if (fd == 1 || fd == 2) { 6726 char buf[100]; 6727 sprintf(buf, "cp%d", GetConsoleOutputCP()); 6728 return PyUnicode_FromString(buf); 6729 } 6730#elif defined(CODESET) 6731 { 6732 char *codeset = nl_langinfo(CODESET); 6733 if (codeset) 6734 return PyUnicode_FromString(codeset); 6735 } 6736#endif 6737 Py_INCREF(Py_None); 6738 return Py_None; 6739} 6740 6741#ifdef __VMS 6742/* Use openssl random routine */ 6743#include <openssl/rand.h> 6744PyDoc_STRVAR(vms_urandom__doc__, 6745"urandom(n) -> str\n\n\ 6746Return n random bytes suitable for cryptographic use."); 6747 6748static PyObject* 6749vms_urandom(PyObject *self, PyObject *args) 6750{ 6751 int howMany; 6752 PyObject* result; 6753 6754 /* Read arguments */ 6755 if (! PyArg_ParseTuple(args, "i:urandom", &howMany)) 6756 return NULL; 6757 if (howMany < 0) 6758 return PyErr_Format(PyExc_ValueError, 6759 "negative argument not allowed"); 6760 6761 /* Allocate bytes */ 6762 result = PyBytes_FromStringAndSize(NULL, howMany); 6763 if (result != NULL) { 6764 /* Get random data */ 6765 if (RAND_pseudo_bytes((unsigned char*) 6766 PyBytes_AS_STRING(result), 6767 howMany) < 0) { 6768 Py_DECREF(result); 6769 return PyErr_Format(PyExc_ValueError, 6770 "RAND_pseudo_bytes"); 6771 } 6772 } 6773 return result; 6774} 6775#endif 6776 6777static PyMethodDef posix_methods[] = { 6778 {"access", posix_access, METH_VARARGS, posix_access__doc__}, 6779#ifdef HAVE_TTYNAME 6780 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__}, 6781#endif 6782 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__}, 6783#ifdef HAVE_CHFLAGS 6784 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__}, 6785#endif /* HAVE_CHFLAGS */ 6786 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__}, 6787#ifdef HAVE_FCHMOD 6788 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__}, 6789#endif /* HAVE_FCHMOD */ 6790#ifdef HAVE_CHOWN 6791 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__}, 6792#endif /* HAVE_CHOWN */ 6793#ifdef HAVE_LCHMOD 6794 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__}, 6795#endif /* HAVE_LCHMOD */ 6796#ifdef HAVE_FCHOWN 6797 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__}, 6798#endif /* HAVE_FCHOWN */ 6799#ifdef HAVE_LCHFLAGS 6800 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__}, 6801#endif /* HAVE_LCHFLAGS */ 6802#ifdef HAVE_LCHOWN 6803 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__}, 6804#endif /* HAVE_LCHOWN */ 6805#ifdef HAVE_CHROOT 6806 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__}, 6807#endif 6808#ifdef HAVE_CTERMID 6809 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__}, 6810#endif 6811#ifdef HAVE_GETCWD 6812 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__}, 6813 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__}, 6814#endif 6815#ifdef HAVE_LINK 6816 {"link", posix_link, METH_VARARGS, posix_link__doc__}, 6817#endif /* HAVE_LINK */ 6818 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__}, 6819 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__}, 6820 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__}, 6821#ifdef HAVE_NICE 6822 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__}, 6823#endif /* HAVE_NICE */ 6824#ifdef HAVE_READLINK 6825 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__}, 6826#endif /* HAVE_READLINK */ 6827 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__}, 6828 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__}, 6829 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__}, 6830 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__}, 6831#ifdef HAVE_SYMLINK 6832 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__}, 6833#endif /* HAVE_SYMLINK */ 6834#ifdef HAVE_SYSTEM 6835 {"system", posix_system, METH_VARARGS, posix_system__doc__}, 6836#endif 6837 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__}, 6838#ifdef HAVE_UNAME 6839 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__}, 6840#endif /* HAVE_UNAME */ 6841 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__}, 6842 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__}, 6843 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__}, 6844#ifdef HAVE_TIMES 6845 {"times", posix_times, METH_NOARGS, posix_times__doc__}, 6846#endif /* HAVE_TIMES */ 6847 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__}, 6848#ifdef HAVE_EXECV 6849 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__}, 6850 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__}, 6851#endif /* HAVE_EXECV */ 6852#ifdef HAVE_SPAWNV 6853 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__}, 6854 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__}, 6855#if defined(PYOS_OS2) 6856 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__}, 6857 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__}, 6858#endif /* PYOS_OS2 */ 6859#endif /* HAVE_SPAWNV */ 6860#ifdef HAVE_FORK1 6861 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__}, 6862#endif /* HAVE_FORK1 */ 6863#ifdef HAVE_FORK 6864 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__}, 6865#endif /* HAVE_FORK */ 6866#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) 6867 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__}, 6868#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */ 6869#ifdef HAVE_FORKPTY 6870 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__}, 6871#endif /* HAVE_FORKPTY */ 6872#ifdef HAVE_GETEGID 6873 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__}, 6874#endif /* HAVE_GETEGID */ 6875#ifdef HAVE_GETEUID 6876 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__}, 6877#endif /* HAVE_GETEUID */ 6878#ifdef HAVE_GETGID 6879 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__}, 6880#endif /* HAVE_GETGID */ 6881#ifdef HAVE_GETGROUPS 6882 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__}, 6883#endif 6884 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__}, 6885#ifdef HAVE_GETPGRP 6886 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__}, 6887#endif /* HAVE_GETPGRP */ 6888#ifdef HAVE_GETPPID 6889 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__}, 6890#endif /* HAVE_GETPPID */ 6891#ifdef HAVE_GETUID 6892 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__}, 6893#endif /* HAVE_GETUID */ 6894#ifdef HAVE_GETLOGIN 6895 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__}, 6896#endif 6897#ifdef HAVE_KILL 6898 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__}, 6899#endif /* HAVE_KILL */ 6900#ifdef HAVE_KILLPG 6901 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__}, 6902#endif /* HAVE_KILLPG */ 6903#ifdef HAVE_PLOCK 6904 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__}, 6905#endif /* HAVE_PLOCK */ 6906#ifdef MS_WINDOWS 6907 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__}, 6908#endif 6909#ifdef HAVE_SETUID 6910 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__}, 6911#endif /* HAVE_SETUID */ 6912#ifdef HAVE_SETEUID 6913 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__}, 6914#endif /* HAVE_SETEUID */ 6915#ifdef HAVE_SETEGID 6916 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__}, 6917#endif /* HAVE_SETEGID */ 6918#ifdef HAVE_SETREUID 6919 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__}, 6920#endif /* HAVE_SETREUID */ 6921#ifdef HAVE_SETREGID 6922 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__}, 6923#endif /* HAVE_SETREGID */ 6924#ifdef HAVE_SETGID 6925 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__}, 6926#endif /* HAVE_SETGID */ 6927#ifdef HAVE_SETGROUPS 6928 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__}, 6929#endif /* HAVE_SETGROUPS */ 6930#ifdef HAVE_GETPGID 6931 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__}, 6932#endif /* HAVE_GETPGID */ 6933#ifdef HAVE_SETPGRP 6934 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__}, 6935#endif /* HAVE_SETPGRP */ 6936#ifdef HAVE_WAIT 6937 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__}, 6938#endif /* HAVE_WAIT */ 6939#ifdef HAVE_WAIT3 6940 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__}, 6941#endif /* HAVE_WAIT3 */ 6942#ifdef HAVE_WAIT4 6943 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__}, 6944#endif /* HAVE_WAIT4 */ 6945#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT) 6946 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__}, 6947#endif /* HAVE_WAITPID */ 6948#ifdef HAVE_GETSID 6949 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__}, 6950#endif /* HAVE_GETSID */ 6951#ifdef HAVE_SETSID 6952 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__}, 6953#endif /* HAVE_SETSID */ 6954#ifdef HAVE_SETPGID 6955 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__}, 6956#endif /* HAVE_SETPGID */ 6957#ifdef HAVE_TCGETPGRP 6958 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__}, 6959#endif /* HAVE_TCGETPGRP */ 6960#ifdef HAVE_TCSETPGRP 6961 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__}, 6962#endif /* HAVE_TCSETPGRP */ 6963 {"open", posix_open, METH_VARARGS, posix_open__doc__}, 6964 {"close", posix_close, METH_VARARGS, posix_close__doc__}, 6965 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__}, 6966 {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__}, 6967 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__}, 6968 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__}, 6969 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__}, 6970 {"read", posix_read, METH_VARARGS, posix_read__doc__}, 6971 {"write", posix_write, METH_VARARGS, posix_write__doc__}, 6972 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__}, 6973 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__}, 6974#ifdef HAVE_PIPE 6975 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__}, 6976#endif 6977#ifdef HAVE_MKFIFO 6978 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__}, 6979#endif 6980#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) 6981 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__}, 6982#endif 6983#ifdef HAVE_DEVICE_MACROS 6984 {"major", posix_major, METH_VARARGS, posix_major__doc__}, 6985 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__}, 6986 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__}, 6987#endif 6988#ifdef HAVE_FTRUNCATE 6989 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__}, 6990#endif 6991#ifdef HAVE_PUTENV 6992 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__}, 6993#endif 6994#ifdef HAVE_UNSETENV 6995 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__}, 6996#endif 6997 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__}, 6998#ifdef HAVE_FCHDIR 6999 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__}, 7000#endif 7001#ifdef HAVE_FSYNC 7002 {"fsync", posix_fsync, METH_O, posix_fsync__doc__}, 7003#endif 7004#ifdef HAVE_FDATASYNC 7005 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__}, 7006#endif 7007#ifdef HAVE_SYS_WAIT_H 7008#ifdef WCOREDUMP 7009 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__}, 7010#endif /* WCOREDUMP */ 7011#ifdef WIFCONTINUED 7012 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__}, 7013#endif /* WIFCONTINUED */ 7014#ifdef WIFSTOPPED 7015 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__}, 7016#endif /* WIFSTOPPED */ 7017#ifdef WIFSIGNALED 7018 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__}, 7019#endif /* WIFSIGNALED */ 7020#ifdef WIFEXITED 7021 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__}, 7022#endif /* WIFEXITED */ 7023#ifdef WEXITSTATUS 7024 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__}, 7025#endif /* WEXITSTATUS */ 7026#ifdef WTERMSIG 7027 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__}, 7028#endif /* WTERMSIG */ 7029#ifdef WSTOPSIG 7030 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__}, 7031#endif /* WSTOPSIG */ 7032#endif /* HAVE_SYS_WAIT_H */ 7033#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) 7034 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__}, 7035#endif 7036#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) 7037 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__}, 7038#endif 7039#ifdef HAVE_CONFSTR 7040 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__}, 7041#endif 7042#ifdef HAVE_SYSCONF 7043 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__}, 7044#endif 7045#ifdef HAVE_FPATHCONF 7046 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__}, 7047#endif 7048#ifdef HAVE_PATHCONF 7049 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__}, 7050#endif 7051 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__}, 7052#ifdef MS_WINDOWS 7053 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL}, 7054#endif 7055#ifdef HAVE_GETLOADAVG 7056 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__}, 7057#endif 7058 #ifdef MS_WINDOWS 7059 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__}, 7060 #endif 7061 #ifdef __VMS 7062 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__}, 7063 #endif 7064 {NULL, NULL} /* Sentinel */ 7065}; 7066 7067 7068static int 7069ins(PyObject *module, char *symbol, long value) 7070{ 7071 return PyModule_AddIntConstant(module, symbol, value); 7072} 7073 7074#if defined(PYOS_OS2) 7075/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */ 7076static int insertvalues(PyObject *module) 7077{ 7078 APIRET rc; 7079 ULONG values[QSV_MAX+1]; 7080 PyObject *v; 7081 char *ver, tmp[50]; 7082 7083 Py_BEGIN_ALLOW_THREADS 7084 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX); 7085 Py_END_ALLOW_THREADS 7086 7087 if (rc != NO_ERROR) { 7088 os2_error(rc); 7089 return -1; 7090 } 7091 7092 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1; 7093 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1; 7094 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1; 7095 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1; 7096 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1; 7097 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1; 7098 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1; 7099 7100 switch (values[QSV_VERSION_MINOR]) { 7101 case 0: ver = "2.00"; break; 7102 case 10: ver = "2.10"; break; 7103 case 11: ver = "2.11"; break; 7104 case 30: ver = "3.00"; break; 7105 case 40: ver = "4.00"; break; 7106 case 50: ver = "5.00"; break; 7107 default: 7108 PyOS_snprintf(tmp, sizeof(tmp), 7109 "%d-%d", values[QSV_VERSION_MAJOR], 7110 values[QSV_VERSION_MINOR]); 7111 ver = &tmp[0]; 7112 } 7113 7114 /* Add Indicator of the Version of the Operating System */ 7115 if (PyModule_AddStringConstant(module, "version", tmp) < 0) 7116 return -1; 7117 7118 /* Add Indicator of Which Drive was Used to Boot the System */ 7119 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1; 7120 tmp[1] = ':'; 7121 tmp[2] = '\0'; 7122 7123 return PyModule_AddStringConstant(module, "bootdrive", tmp); 7124} 7125#endif 7126 7127static int 7128all_ins(PyObject *d) 7129{ 7130#ifdef F_OK 7131 if (ins(d, "F_OK", (long)F_OK)) return -1; 7132#endif 7133#ifdef R_OK 7134 if (ins(d, "R_OK", (long)R_OK)) return -1; 7135#endif 7136#ifdef W_OK 7137 if (ins(d, "W_OK", (long)W_OK)) return -1; 7138#endif 7139#ifdef X_OK 7140 if (ins(d, "X_OK", (long)X_OK)) return -1; 7141#endif 7142#ifdef NGROUPS_MAX 7143 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1; 7144#endif 7145#ifdef TMP_MAX 7146 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1; 7147#endif 7148#ifdef WCONTINUED 7149 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1; 7150#endif 7151#ifdef WNOHANG 7152 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1; 7153#endif 7154#ifdef WUNTRACED 7155 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1; 7156#endif 7157#ifdef O_RDONLY 7158 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1; 7159#endif 7160#ifdef O_WRONLY 7161 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1; 7162#endif 7163#ifdef O_RDWR 7164 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1; 7165#endif 7166#ifdef O_NDELAY 7167 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1; 7168#endif 7169#ifdef O_NONBLOCK 7170 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1; 7171#endif 7172#ifdef O_APPEND 7173 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1; 7174#endif 7175#ifdef O_DSYNC 7176 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1; 7177#endif 7178#ifdef O_RSYNC 7179 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1; 7180#endif 7181#ifdef O_SYNC 7182 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1; 7183#endif 7184#ifdef O_NOCTTY 7185 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1; 7186#endif 7187#ifdef O_CREAT 7188 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1; 7189#endif 7190#ifdef O_EXCL 7191 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1; 7192#endif 7193#ifdef O_TRUNC 7194 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1; 7195#endif 7196#ifdef O_BINARY 7197 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1; 7198#endif 7199#ifdef O_TEXT 7200 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1; 7201#endif 7202#ifdef O_LARGEFILE 7203 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1; 7204#endif 7205#ifdef O_SHLOCK 7206 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1; 7207#endif 7208#ifdef O_EXLOCK 7209 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1; 7210#endif 7211 7212/* MS Windows */ 7213#ifdef O_NOINHERIT 7214 /* Don't inherit in child processes. */ 7215 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1; 7216#endif 7217#ifdef _O_SHORT_LIVED 7218 /* Optimize for short life (keep in memory). */ 7219 /* MS forgot to define this one with a non-underscore form too. */ 7220 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1; 7221#endif 7222#ifdef O_TEMPORARY 7223 /* Automatically delete when last handle is closed. */ 7224 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1; 7225#endif 7226#ifdef O_RANDOM 7227 /* Optimize for random access. */ 7228 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1; 7229#endif 7230#ifdef O_SEQUENTIAL 7231 /* Optimize for sequential access. */ 7232 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1; 7233#endif 7234 7235/* GNU extensions. */ 7236#ifdef O_ASYNC 7237 /* Send a SIGIO signal whenever input or output 7238 becomes available on file descriptor */ 7239 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1; 7240#endif 7241#ifdef O_DIRECT 7242 /* Direct disk access. */ 7243 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1; 7244#endif 7245#ifdef O_DIRECTORY 7246 /* Must be a directory. */ 7247 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1; 7248#endif 7249#ifdef O_NOFOLLOW 7250 /* Do not follow links. */ 7251 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1; 7252#endif 7253#ifdef O_NOATIME 7254 /* Do not update the access time. */ 7255 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1; 7256#endif 7257 7258 /* These come from sysexits.h */ 7259#ifdef EX_OK 7260 if (ins(d, "EX_OK", (long)EX_OK)) return -1; 7261#endif /* EX_OK */ 7262#ifdef EX_USAGE 7263 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1; 7264#endif /* EX_USAGE */ 7265#ifdef EX_DATAERR 7266 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1; 7267#endif /* EX_DATAERR */ 7268#ifdef EX_NOINPUT 7269 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1; 7270#endif /* EX_NOINPUT */ 7271#ifdef EX_NOUSER 7272 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1; 7273#endif /* EX_NOUSER */ 7274#ifdef EX_NOHOST 7275 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1; 7276#endif /* EX_NOHOST */ 7277#ifdef EX_UNAVAILABLE 7278 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1; 7279#endif /* EX_UNAVAILABLE */ 7280#ifdef EX_SOFTWARE 7281 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1; 7282#endif /* EX_SOFTWARE */ 7283#ifdef EX_OSERR 7284 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1; 7285#endif /* EX_OSERR */ 7286#ifdef EX_OSFILE 7287 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1; 7288#endif /* EX_OSFILE */ 7289#ifdef EX_CANTCREAT 7290 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1; 7291#endif /* EX_CANTCREAT */ 7292#ifdef EX_IOERR 7293 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1; 7294#endif /* EX_IOERR */ 7295#ifdef EX_TEMPFAIL 7296 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1; 7297#endif /* EX_TEMPFAIL */ 7298#ifdef EX_PROTOCOL 7299 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1; 7300#endif /* EX_PROTOCOL */ 7301#ifdef EX_NOPERM 7302 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1; 7303#endif /* EX_NOPERM */ 7304#ifdef EX_CONFIG 7305 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1; 7306#endif /* EX_CONFIG */ 7307#ifdef EX_NOTFOUND 7308 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1; 7309#endif /* EX_NOTFOUND */ 7310 7311#ifdef HAVE_SPAWNV 7312#if defined(PYOS_OS2) && defined(PYCC_GCC) 7313 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1; 7314 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1; 7315 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1; 7316 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1; 7317 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1; 7318 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1; 7319 if (ins(d, "P_PM", (long)P_PM)) return -1; 7320 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1; 7321 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1; 7322 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1; 7323 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1; 7324 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1; 7325 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1; 7326 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1; 7327 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1; 7328 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1; 7329 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1; 7330 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1; 7331 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1; 7332 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1; 7333#else 7334 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1; 7335 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1; 7336 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1; 7337 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1; 7338 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1; 7339#endif 7340#endif 7341 7342#if defined(PYOS_OS2) 7343 if (insertvalues(d)) return -1; 7344#endif 7345 return 0; 7346} 7347 7348 7349#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__) 7350#define INITFUNC PyInit_nt 7351#define MODNAME "nt" 7352 7353#elif defined(PYOS_OS2) 7354#define INITFUNC PyInit_os2 7355#define MODNAME "os2" 7356 7357#else 7358#define INITFUNC PyInit_posix 7359#define MODNAME "posix" 7360#endif 7361 7362static struct PyModuleDef posixmodule = { 7363 PyModuleDef_HEAD_INIT, 7364 MODNAME, 7365 posix__doc__, 7366 -1, 7367 posix_methods, 7368 NULL, 7369 NULL, 7370 NULL, 7371 NULL 7372}; 7373 7374 7375PyMODINIT_FUNC 7376INITFUNC(void) 7377{ 7378 PyObject *m, *v; 7379 7380 m = PyModule_Create(&posixmodule); 7381 if (m == NULL) 7382 return NULL; 7383 7384 /* Initialize environ dictionary */ 7385 v = convertenviron(); 7386 Py_XINCREF(v); 7387 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0) 7388 return NULL; 7389 Py_DECREF(v); 7390 7391 if (all_ins(m)) 7392 return NULL; 7393 7394 if (setup_confname_tables(m)) 7395 return NULL; 7396 7397 Py_INCREF(PyExc_OSError); 7398 PyModule_AddObject(m, "error", PyExc_OSError); 7399 7400#ifdef HAVE_PUTENV 7401 if (posix_putenv_garbage == NULL) 7402 posix_putenv_garbage = PyDict_New(); 7403#endif 7404 7405 if (!initialized) { 7406 stat_result_desc.name = MODNAME ".stat_result"; 7407 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField; 7408 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField; 7409 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField; 7410 PyStructSequence_InitType(&StatResultType, &stat_result_desc); 7411 structseq_new = StatResultType.tp_new; 7412 StatResultType.tp_new = statresult_new; 7413 7414 statvfs_result_desc.name = MODNAME ".statvfs_result"; 7415 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc); 7416 } 7417 Py_INCREF((PyObject*) &StatResultType); 7418 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType); 7419 Py_INCREF((PyObject*) &StatVFSResultType); 7420 PyModule_AddObject(m, "statvfs_result", 7421 (PyObject*) &StatVFSResultType); 7422 initialized = 1; 7423 7424#ifdef __APPLE__ 7425 /* 7426 * Step 2 of weak-linking support on Mac OS X. 7427 * 7428 * The code below removes functions that are not available on the 7429 * currently active platform. 7430 * 7431 * This block allow one to use a python binary that was build on 7432 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on 7433 * OSX 10.4. 7434 */ 7435#ifdef HAVE_FSTATVFS 7436 if (fstatvfs == NULL) { 7437 if (PyObject_DelAttrString(m, "fstatvfs") == -1) { 7438 return NULL; 7439 } 7440 } 7441#endif /* HAVE_FSTATVFS */ 7442 7443#ifdef HAVE_STATVFS 7444 if (statvfs == NULL) { 7445 if (PyObject_DelAttrString(m, "statvfs") == -1) { 7446 return NULL; 7447 } 7448 } 7449#endif /* HAVE_STATVFS */ 7450 7451# ifdef HAVE_LCHOWN 7452 if (lchown == NULL) { 7453 if (PyObject_DelAttrString(m, "lchown") == -1) { 7454 return NULL; 7455 } 7456 } 7457#endif /* HAVE_LCHOWN */ 7458 7459 7460#endif /* __APPLE__ */ 7461 return m; 7462 7463} 7464 7465#ifdef __cplusplus 7466} 7467#endif 7468