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