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