LCOV - code coverage report
Current view: top level - Modules - posixmodule.c (source / functions) Hit Total Coverage
Test: CPython lcov report Lines: 174 1428 12.2 %
Date: 2017-04-19 Functions: 17 145 11.7 %

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

Generated by: LCOV version 1.10