Home | History | Annotate | Download | only in Modules
      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) 2015, Daryl McDaniel. All rights reserved.<BR>
      6     Copyright (c) 2011 - 2012, Intel Corporation. All rights reserved.<BR>
      7     This program and the accompanying materials are licensed and made available under
      8     the terms and conditions of the BSD License that accompanies this distribution.
      9     The full text of the license may be found at
     10     http://opensource.org/licenses/bsd-license.
     11 
     12     THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     13     WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     14 **/
     15 #define PY_SSIZE_T_CLEAN
     16 
     17 #include "Python.h"
     18 #include "structseq.h"
     19 
     20 #include  <stdio.h>
     21 #include  <stdlib.h>
     22 #include  <wchar.h>
     23 #include  <sys/syslimits.h>
     24 
     25 #ifdef __cplusplus
     26 extern "C" {
     27 #endif
     28 
     29 PyDoc_STRVAR(edk2__doc__,
     30              "This module provides access to UEFI firmware functionality that is\n\
     31              standardized by the C Standard and the POSIX standard (a thinly\n\
     32              disguised Unix interface).  Refer to the library manual and\n\
     33              corresponding UEFI Specification entries for more information on calls.");
     34 
     35 #ifndef Py_USING_UNICODE
     36   /* This is used in signatures of functions. */
     37   #define Py_UNICODE void
     38 #endif
     39 
     40 #ifdef HAVE_SYS_TYPES_H
     41   #include <sys/types.h>
     42 #endif /* HAVE_SYS_TYPES_H */
     43 
     44 #ifdef HAVE_SYS_STAT_H
     45   #include <sys/stat.h>
     46 #endif /* HAVE_SYS_STAT_H */
     47 
     48 #ifdef HAVE_SYS_WAIT_H
     49   #include <sys/wait.h>           /* For WNOHANG */
     50 #endif
     51 
     52 #ifdef HAVE_SIGNAL_H
     53   #include <signal.h>
     54 #endif
     55 
     56 #ifdef HAVE_FCNTL_H
     57   #include <fcntl.h>
     58 #endif /* HAVE_FCNTL_H */
     59 
     60 #ifdef HAVE_GRP_H
     61   #include <grp.h>
     62 #endif
     63 
     64 #ifdef HAVE_SYSEXITS_H
     65   #include <sysexits.h>
     66 #endif /* HAVE_SYSEXITS_H */
     67 
     68 #ifdef HAVE_SYS_LOADAVG_H
     69   #include <sys/loadavg.h>
     70 #endif
     71 
     72 #ifdef HAVE_UTIME_H
     73   #include <utime.h>
     74 #endif /* HAVE_UTIME_H */
     75 
     76 #ifdef HAVE_SYS_UTIME_H
     77   #include <sys/utime.h>
     78   #define HAVE_UTIME_H /* pretend we do for the rest of this file */
     79 #endif /* HAVE_SYS_UTIME_H */
     80 
     81 #ifdef HAVE_SYS_TIMES_H
     82   #include <sys/times.h>
     83 #endif /* HAVE_SYS_TIMES_H */
     84 
     85 #ifdef HAVE_SYS_PARAM_H
     86   #include <sys/param.h>
     87 #endif /* HAVE_SYS_PARAM_H */
     88 
     89 #ifdef HAVE_SYS_UTSNAME_H
     90   #include <sys/utsname.h>
     91 #endif /* HAVE_SYS_UTSNAME_H */
     92 
     93 #ifdef HAVE_DIRENT_H
     94   #include <dirent.h>
     95   #define NAMLEN(dirent) wcslen((dirent)->FileName)
     96 #else
     97   #define dirent direct
     98   #define NAMLEN(dirent) (dirent)->d_namlen
     99   #ifdef HAVE_SYS_NDIR_H
    100     #include <sys/ndir.h>
    101   #endif
    102   #ifdef HAVE_SYS_DIR_H
    103     #include <sys/dir.h>
    104   #endif
    105   #ifdef HAVE_NDIR_H
    106     #include <ndir.h>
    107   #endif
    108 #endif
    109 
    110 #ifndef MAXPATHLEN
    111   #if defined(PATH_MAX) && PATH_MAX > 1024
    112     #define MAXPATHLEN PATH_MAX
    113   #else
    114     #define MAXPATHLEN 1024
    115   #endif
    116 #endif /* MAXPATHLEN */
    117 
    118 #define WAIT_TYPE int
    119 #define WAIT_STATUS_INT(s) (s)
    120 
    121 /* Issue #1983: pid_t can be longer than a C long on some systems */
    122 #if !defined(SIZEOF_PID_T) || SIZEOF_PID_T == SIZEOF_INT
    123   #define PARSE_PID "i"
    124   #define PyLong_FromPid PyInt_FromLong
    125   #define PyLong_AsPid PyInt_AsLong
    126 #elif SIZEOF_PID_T == SIZEOF_LONG
    127   #define PARSE_PID "l"
    128   #define PyLong_FromPid PyInt_FromLong
    129   #define PyLong_AsPid PyInt_AsLong
    130 #elif defined(SIZEOF_LONG_LONG) && SIZEOF_PID_T == SIZEOF_LONG_LONG
    131   #define PARSE_PID "L"
    132   #define PyLong_FromPid PyLong_FromLongLong
    133   #define PyLong_AsPid PyInt_AsLongLong
    134 #else
    135   #error "sizeof(pid_t) is neither sizeof(int), sizeof(long) or sizeof(long long)"
    136 #endif /* SIZEOF_PID_T */
    137 
    138 /* Don't use the "_r" form if we don't need it (also, won't have a
    139    prototype for it, at least on Solaris -- maybe others as well?). */
    140 #if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
    141   #define USE_CTERMID_R
    142 #endif
    143 
    144 #if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
    145   #define USE_TMPNAM_R
    146 #endif
    147 
    148 /* choose the appropriate stat and fstat functions and return structs */
    149 #undef STAT
    150 #undef FSTAT
    151 #undef STRUCT_STAT
    152 #define STAT stat
    153 #define FSTAT fstat
    154 #define STRUCT_STAT struct stat
    155 
    156 /* dummy version. _PyVerify_fd() is already defined in fileobject.h */
    157 #define _PyVerify_fd_dup2(A, B) (1)
    158 
    159 #ifndef UEFI_C_SOURCE
    160 /* Return a dictionary corresponding to the POSIX environment table */
    161 extern char **environ;
    162 
    163 static PyObject *
    164 convertenviron(void)
    165 {
    166     PyObject *d;
    167     char **e;
    168     d = PyDict_New();
    169     if (d == NULL)
    170         return NULL;
    171     if (environ == NULL)
    172         return d;
    173     /* This part ignores errors */
    174     for (e = environ; *e != NULL; e++) {
    175         PyObject *k;
    176         PyObject *v;
    177         char *p = strchr(*e, '=');
    178         if (p == NULL)
    179             continue;
    180         k = PyString_FromStringAndSize(*e, (int)(p-*e));
    181         if (k == NULL) {
    182             PyErr_Clear();
    183             continue;
    184         }
    185         v = PyString_FromString(p+1);
    186         if (v == NULL) {
    187             PyErr_Clear();
    188             Py_DECREF(k);
    189             continue;
    190         }
    191         if (PyDict_GetItem(d, k) == NULL) {
    192             if (PyDict_SetItem(d, k, v) != 0)
    193                 PyErr_Clear();
    194         }
    195         Py_DECREF(k);
    196         Py_DECREF(v);
    197     }
    198     return d;
    199 }
    200 #endif  /* UEFI_C_SOURCE */
    201 
    202 /* Set a POSIX-specific error from errno, and return NULL */
    203 
    204 static PyObject *
    205 edk2_error(void)
    206 {
    207     return PyErr_SetFromErrno(PyExc_OSError);
    208 }
    209 static PyObject *
    210 edk2_error_with_filename(char* name)
    211 {
    212     return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
    213 }
    214 
    215 
    216 static PyObject *
    217 edk2_error_with_allocated_filename(char* name)
    218 {
    219     PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
    220     PyMem_Free(name);
    221     return rc;
    222 }
    223 
    224 /* POSIX generic methods */
    225 
    226 #ifndef UEFI_C_SOURCE
    227   static PyObject *
    228   edk2_fildes(PyObject *fdobj, int (*func)(int))
    229   {
    230       int fd;
    231       int res;
    232       fd = PyObject_AsFileDescriptor(fdobj);
    233       if (fd < 0)
    234           return NULL;
    235       if (!_PyVerify_fd(fd))
    236           return edk2_error();
    237       Py_BEGIN_ALLOW_THREADS
    238       res = (*func)(fd);
    239       Py_END_ALLOW_THREADS
    240       if (res < 0)
    241           return edk2_error();
    242       Py_INCREF(Py_None);
    243       return Py_None;
    244   }
    245 #endif  /* UEFI_C_SOURCE */
    246 
    247 static PyObject *
    248 edk2_1str(PyObject *args, char *format, int (*func)(const char*))
    249 {
    250     char *path1 = NULL;
    251     int res;
    252     if (!PyArg_ParseTuple(args, format,
    253                           Py_FileSystemDefaultEncoding, &path1))
    254         return NULL;
    255     Py_BEGIN_ALLOW_THREADS
    256     res = (*func)(path1);
    257     Py_END_ALLOW_THREADS
    258     if (res < 0)
    259         return edk2_error_with_allocated_filename(path1);
    260     PyMem_Free(path1);
    261     Py_INCREF(Py_None);
    262     return Py_None;
    263 }
    264 
    265 static PyObject *
    266 edk2_2str(PyObject *args,
    267            char *format,
    268            int (*func)(const char *, const char *))
    269 {
    270     char *path1 = NULL, *path2 = NULL;
    271     int res;
    272     if (!PyArg_ParseTuple(args, format,
    273                           Py_FileSystemDefaultEncoding, &path1,
    274                           Py_FileSystemDefaultEncoding, &path2))
    275         return NULL;
    276     Py_BEGIN_ALLOW_THREADS
    277     res = (*func)(path1, path2);
    278     Py_END_ALLOW_THREADS
    279     PyMem_Free(path1);
    280     PyMem_Free(path2);
    281     if (res != 0)
    282         /* XXX how to report both path1 and path2??? */
    283         return edk2_error();
    284     Py_INCREF(Py_None);
    285     return Py_None;
    286 }
    287 
    288 PyDoc_STRVAR(stat_result__doc__,
    289 "stat_result: Result from stat or lstat.\n\n\
    290 This object may be accessed either as a tuple of\n\
    291   (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
    292 or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
    293 \n\
    294 Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
    295 or st_flags, they are available as attributes only.\n\
    296 \n\
    297 See os.stat for more information.");
    298 
    299 static PyStructSequence_Field stat_result_fields[] = {
    300     {"st_mode",    "protection bits"},
    301     //{"st_ino",     "inode"},
    302     //{"st_dev",     "device"},
    303     //{"st_nlink",   "number of hard links"},
    304     //{"st_uid",     "user ID of owner"},
    305     //{"st_gid",     "group ID of owner"},
    306     {"st_size",    "total size, in bytes"},
    307     /* The NULL is replaced with PyStructSequence_UnnamedField later. */
    308     {NULL,   "integer time of last access"},
    309     {NULL,   "integer time of last modification"},
    310     {NULL,   "integer time of last change"},
    311     {"st_atime",   "time of last access"},
    312     {"st_mtime",   "time of last modification"},
    313     {"st_ctime",   "time of last change"},
    314 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
    315     {"st_blksize", "blocksize for filesystem I/O"},
    316 #endif
    317 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
    318     {"st_blocks",  "number of blocks allocated"},
    319 #endif
    320 #ifdef HAVE_STRUCT_STAT_ST_RDEV
    321     {"st_rdev",    "device type (if inode device)"},
    322 #endif
    323 #ifdef HAVE_STRUCT_STAT_ST_FLAGS
    324     {"st_flags",   "user defined flags for file"},
    325 #endif
    326 #ifdef HAVE_STRUCT_STAT_ST_GEN
    327     {"st_gen",    "generation number"},
    328 #endif
    329 #ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
    330     {"st_birthtime",   "time of creation"},
    331 #endif
    332     {0}
    333 };
    334 
    335 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
    336 #define ST_BLKSIZE_IDX 8
    337 #else
    338 #define ST_BLKSIZE_IDX 12
    339 #endif
    340 
    341 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
    342 #define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
    343 #else
    344 #define ST_BLOCKS_IDX ST_BLKSIZE_IDX
    345 #endif
    346 
    347 #ifdef HAVE_STRUCT_STAT_ST_RDEV
    348 #define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
    349 #else
    350 #define ST_RDEV_IDX ST_BLOCKS_IDX
    351 #endif
    352 
    353 #ifdef HAVE_STRUCT_STAT_ST_FLAGS
    354 #define ST_FLAGS_IDX (ST_RDEV_IDX+1)
    355 #else
    356 #define ST_FLAGS_IDX ST_RDEV_IDX
    357 #endif
    358 
    359 #ifdef HAVE_STRUCT_STAT_ST_GEN
    360 #define ST_GEN_IDX (ST_FLAGS_IDX+1)
    361 #else
    362 #define ST_GEN_IDX ST_FLAGS_IDX
    363 #endif
    364 
    365 #ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
    366 #define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
    367 #else
    368 #define ST_BIRTHTIME_IDX ST_GEN_IDX
    369 #endif
    370 
    371 static PyStructSequence_Desc stat_result_desc = {
    372     "stat_result", /* name */
    373     stat_result__doc__, /* doc */
    374     stat_result_fields,
    375     10
    376 };
    377 
    378 #ifndef UEFI_C_SOURCE   /* Not in UEFI */
    379 PyDoc_STRVAR(statvfs_result__doc__,
    380 "statvfs_result: Result from statvfs or fstatvfs.\n\n\
    381 This object may be accessed either as a tuple of\n\
    382   (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
    383 or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
    384 \n\
    385 See os.statvfs for more information.");
    386 
    387 static PyStructSequence_Field statvfs_result_fields[] = {
    388     {"f_bsize",  },
    389     {"f_frsize", },
    390     {"f_blocks", },
    391     {"f_bfree",  },
    392     {"f_bavail", },
    393     {"f_files",  },
    394     {"f_ffree",  },
    395     {"f_favail", },
    396     {"f_flag",   },
    397     {"f_namemax",},
    398     {0}
    399 };
    400 
    401 static PyStructSequence_Desc statvfs_result_desc = {
    402     "statvfs_result", /* name */
    403     statvfs_result__doc__, /* doc */
    404     statvfs_result_fields,
    405     10
    406 };
    407 
    408 static PyTypeObject StatVFSResultType;
    409 #endif
    410 
    411 static int initialized;
    412 static PyTypeObject StatResultType;
    413 static newfunc structseq_new;
    414 
    415 static PyObject *
    416 statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
    417 {
    418     PyStructSequence *result;
    419     int i;
    420 
    421     result = (PyStructSequence*)structseq_new(type, args, kwds);
    422     if (!result)
    423         return NULL;
    424     /* If we have been initialized from a tuple,
    425        st_?time might be set to None. Initialize it
    426        from the int slots.  */
    427     for (i = 7; i <= 9; i++) {
    428         if (result->ob_item[i+3] == Py_None) {
    429             Py_DECREF(Py_None);
    430             Py_INCREF(result->ob_item[i]);
    431             result->ob_item[i+3] = result->ob_item[i];
    432         }
    433     }
    434     return (PyObject*)result;
    435 }
    436 
    437 
    438 
    439 /* If true, st_?time is float. */
    440 #if defined(UEFI_C_SOURCE)
    441   static int _stat_float_times = 0;
    442 #else
    443   static int _stat_float_times = 1;
    444 
    445 PyDoc_STRVAR(stat_float_times__doc__,
    446 "stat_float_times([newval]) -> oldval\n\n\
    447 Determine whether os.[lf]stat represents time stamps as float objects.\n\
    448 If newval is True, future calls to stat() return floats, if it is False,\n\
    449 future calls return ints. \n\
    450 If newval is omitted, return the current setting.\n");
    451 
    452 static PyObject*
    453 stat_float_times(PyObject* self, PyObject *args)
    454 {
    455     int newval = -1;
    456 
    457     if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
    458         return NULL;
    459     if (newval == -1)
    460         /* Return old value */
    461         return PyBool_FromLong(_stat_float_times);
    462     _stat_float_times = newval;
    463     Py_INCREF(Py_None);
    464     return Py_None;
    465 }
    466 #endif  /* UEFI_C_SOURCE */
    467 
    468 static void
    469 fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
    470 {
    471     PyObject *fval,*ival;
    472 #if SIZEOF_TIME_T > SIZEOF_LONG
    473     ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
    474 #else
    475     ival = PyInt_FromLong((long)sec);
    476 #endif
    477     if (!ival)
    478         return;
    479     if (_stat_float_times) {
    480         fval = PyFloat_FromDouble(sec + 1e-9*nsec);
    481     } else {
    482         fval = ival;
    483         Py_INCREF(fval);
    484     }
    485     PyStructSequence_SET_ITEM(v, index, ival);
    486     PyStructSequence_SET_ITEM(v, index+3, fval);
    487 }
    488 
    489 /* pack a system stat C structure into the Python stat tuple
    490    (used by edk2_stat() and edk2_fstat()) */
    491 static PyObject*
    492 _pystat_fromstructstat(STRUCT_STAT *st)
    493 {
    494     unsigned long ansec, mnsec, cnsec;
    495     PyObject *v = PyStructSequence_New(&StatResultType);
    496     if (v == NULL)
    497         return NULL;
    498 
    499     PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st->st_mode));
    500     PyStructSequence_SET_ITEM(v, 1,
    501                               PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
    502 
    503     ansec = mnsec = cnsec = 0;
    504     /* The index used by fill_time is the index of the integer time.
    505        fill_time will add 3 to the index to get the floating time index.
    506     */
    507     fill_time(v, 2, st->st_atime, ansec);
    508     fill_time(v, 3, st->st_mtime, mnsec);
    509     fill_time(v, 4, st->st_mtime, cnsec);
    510 
    511 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
    512     PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
    513                               PyInt_FromLong((long)st->st_blksize));
    514 #endif
    515 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
    516     PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
    517                               PyInt_FromLong((long)st->st_blocks));
    518 #endif
    519 #ifdef HAVE_STRUCT_STAT_ST_RDEV
    520     PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
    521                               PyInt_FromLong((long)st->st_rdev));
    522 #endif
    523 #ifdef HAVE_STRUCT_STAT_ST_GEN
    524     PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
    525                               PyInt_FromLong((long)st->st_gen));
    526 #endif
    527 #ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
    528     {
    529       PyObject *val;
    530       unsigned long bsec,bnsec;
    531       bsec = (long)st->st_birthtime;
    532 #ifdef HAVE_STAT_TV_NSEC2
    533       bnsec = st->st_birthtimespec.tv_nsec;
    534 #else
    535       bnsec = 0;
    536 #endif
    537       if (_stat_float_times) {
    538         val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
    539       } else {
    540         val = PyInt_FromLong((long)bsec);
    541       }
    542       PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
    543                                 val);
    544     }
    545 #endif
    546 #ifdef HAVE_STRUCT_STAT_ST_FLAGS
    547     PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
    548                               PyInt_FromLong((long)st->st_flags));
    549 #endif
    550 
    551     if (PyErr_Occurred()) {
    552         Py_DECREF(v);
    553         return NULL;
    554     }
    555 
    556     return v;
    557 }
    558 
    559 static PyObject *
    560 edk2_do_stat(PyObject *self, PyObject *args,
    561               char *format,
    562               int (*statfunc)(const char *, STRUCT_STAT *),
    563               char *wformat,
    564               int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
    565 {
    566     STRUCT_STAT st;
    567     char *path = NULL;          /* pass this to stat; do not free() it */
    568     char *pathfree = NULL;  /* this memory must be free'd */
    569     int res;
    570     PyObject *result;
    571 
    572     if (!PyArg_ParseTuple(args, format,
    573                           Py_FileSystemDefaultEncoding, &path))
    574         return NULL;
    575     pathfree = path;
    576 
    577     Py_BEGIN_ALLOW_THREADS
    578     res = (*statfunc)(path, &st);
    579     Py_END_ALLOW_THREADS
    580 
    581     if (res != 0) {
    582         result = edk2_error_with_filename(pathfree);
    583     }
    584     else
    585         result = _pystat_fromstructstat(&st);
    586 
    587     PyMem_Free(pathfree);
    588     return result;
    589 }
    590 
    591 /* POSIX methods */
    592 
    593 PyDoc_STRVAR(edk2_access__doc__,
    594 "access(path, mode) -> True if granted, False otherwise\n\n\
    595 Use the real uid/gid to test for access to a path.  Note that most\n\
    596 operations will use the effective uid/gid, therefore this routine can\n\
    597 be used in a suid/sgid environment to test if the invoking user has the\n\
    598 specified access to the path.  The mode argument can be F_OK to test\n\
    599 existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
    600 
    601 static PyObject *
    602 edk2_access(PyObject *self, PyObject *args)
    603 {
    604     char *path;
    605     int mode;
    606 
    607     int res;
    608     if (!PyArg_ParseTuple(args, "eti:access",
    609                           Py_FileSystemDefaultEncoding, &path, &mode))
    610         return NULL;
    611     Py_BEGIN_ALLOW_THREADS
    612     res = access(path, mode);
    613     Py_END_ALLOW_THREADS
    614     PyMem_Free(path);
    615     return PyBool_FromLong(res == 0);
    616 }
    617 
    618 #ifndef F_OK
    619   #define F_OK 0
    620 #endif
    621 #ifndef R_OK
    622   #define R_OK 4
    623 #endif
    624 #ifndef W_OK
    625   #define W_OK 2
    626 #endif
    627 #ifndef X_OK
    628   #define X_OK 1
    629 #endif
    630 
    631 PyDoc_STRVAR(edk2_chdir__doc__,
    632 "chdir(path)\n\n\
    633 Change the current working directory to the specified path.");
    634 
    635 static PyObject *
    636 edk2_chdir(PyObject *self, PyObject *args)
    637 {
    638     return edk2_1str(args, "et:chdir", chdir);
    639 }
    640 
    641 PyDoc_STRVAR(edk2_chmod__doc__,
    642 "chmod(path, mode)\n\n\
    643 Change the access permissions of a file.");
    644 
    645 static PyObject *
    646 edk2_chmod(PyObject *self, PyObject *args)
    647 {
    648     char *path = NULL;
    649     int i;
    650     int res;
    651     if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
    652                           &path, &i))
    653         return NULL;
    654     Py_BEGIN_ALLOW_THREADS
    655     res = chmod(path, i);
    656     Py_END_ALLOW_THREADS
    657     if (res < 0)
    658         return edk2_error_with_allocated_filename(path);
    659     PyMem_Free(path);
    660     Py_INCREF(Py_None);
    661     return Py_None;
    662 }
    663 
    664 #ifdef HAVE_FCHMOD
    665 PyDoc_STRVAR(edk2_fchmod__doc__,
    666 "fchmod(fd, mode)\n\n\
    667 Change the access permissions of the file given by file\n\
    668 descriptor fd.");
    669 
    670 static PyObject *
    671 edk2_fchmod(PyObject *self, PyObject *args)
    672 {
    673     int fd, mode, res;
    674     if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
    675         return NULL;
    676     Py_BEGIN_ALLOW_THREADS
    677     res = fchmod(fd, mode);
    678     Py_END_ALLOW_THREADS
    679     if (res < 0)
    680         return edk2_error();
    681     Py_RETURN_NONE;
    682 }
    683 #endif /* HAVE_FCHMOD */
    684 
    685 #ifdef HAVE_LCHMOD
    686 PyDoc_STRVAR(edk2_lchmod__doc__,
    687 "lchmod(path, mode)\n\n\
    688 Change the access permissions of a file. If path is a symlink, this\n\
    689 affects the link itself rather than the target.");
    690 
    691 static PyObject *
    692 edk2_lchmod(PyObject *self, PyObject *args)
    693 {
    694     char *path = NULL;
    695     int i;
    696     int res;
    697     if (!PyArg_ParseTuple(args, "eti:lchmod", Py_FileSystemDefaultEncoding,
    698                           &path, &i))
    699         return NULL;
    700     Py_BEGIN_ALLOW_THREADS
    701     res = lchmod(path, i);
    702     Py_END_ALLOW_THREADS
    703     if (res < 0)
    704         return edk2_error_with_allocated_filename(path);
    705     PyMem_Free(path);
    706     Py_RETURN_NONE;
    707 }
    708 #endif /* HAVE_LCHMOD */
    709 
    710 
    711 #ifdef HAVE_CHFLAGS
    712 PyDoc_STRVAR(edk2_chflags__doc__,
    713 "chflags(path, flags)\n\n\
    714 Set file flags.");
    715 
    716 static PyObject *
    717 edk2_chflags(PyObject *self, PyObject *args)
    718 {
    719     char *path;
    720     unsigned long flags;
    721     int res;
    722     if (!PyArg_ParseTuple(args, "etk:chflags",
    723                           Py_FileSystemDefaultEncoding, &path, &flags))
    724         return NULL;
    725     Py_BEGIN_ALLOW_THREADS
    726     res = chflags(path, flags);
    727     Py_END_ALLOW_THREADS
    728     if (res < 0)
    729         return edk2_error_with_allocated_filename(path);
    730     PyMem_Free(path);
    731     Py_INCREF(Py_None);
    732     return Py_None;
    733 }
    734 #endif /* HAVE_CHFLAGS */
    735 
    736 #ifdef HAVE_LCHFLAGS
    737 PyDoc_STRVAR(edk2_lchflags__doc__,
    738 "lchflags(path, flags)\n\n\
    739 Set file flags.\n\
    740 This function will not follow symbolic links.");
    741 
    742 static PyObject *
    743 edk2_lchflags(PyObject *self, PyObject *args)
    744 {
    745     char *path;
    746     unsigned long flags;
    747     int res;
    748     if (!PyArg_ParseTuple(args, "etk:lchflags",
    749                           Py_FileSystemDefaultEncoding, &path, &flags))
    750         return NULL;
    751     Py_BEGIN_ALLOW_THREADS
    752     res = lchflags(path, flags);
    753     Py_END_ALLOW_THREADS
    754     if (res < 0)
    755         return edk2_error_with_allocated_filename(path);
    756     PyMem_Free(path);
    757     Py_INCREF(Py_None);
    758     return Py_None;
    759 }
    760 #endif /* HAVE_LCHFLAGS */
    761 
    762 #ifdef HAVE_CHROOT
    763 PyDoc_STRVAR(edk2_chroot__doc__,
    764 "chroot(path)\n\n\
    765 Change root directory to path.");
    766 
    767 static PyObject *
    768 edk2_chroot(PyObject *self, PyObject *args)
    769 {
    770     return edk2_1str(args, "et:chroot", chroot);
    771 }
    772 #endif
    773 
    774 #ifdef HAVE_FSYNC
    775 PyDoc_STRVAR(edk2_fsync__doc__,
    776 "fsync(fildes)\n\n\
    777 force write of file with filedescriptor to disk.");
    778 
    779 static PyObject *
    780 edk2_fsync(PyObject *self, PyObject *fdobj)
    781 {
    782     return edk2_fildes(fdobj, fsync);
    783 }
    784 #endif /* HAVE_FSYNC */
    785 
    786 #ifdef HAVE_FDATASYNC
    787 
    788 #ifdef __hpux
    789 extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
    790 #endif
    791 
    792 PyDoc_STRVAR(edk2_fdatasync__doc__,
    793 "fdatasync(fildes)\n\n\
    794 force write of file with filedescriptor to disk.\n\
    795  does not force update of metadata.");
    796 
    797 static PyObject *
    798 edk2_fdatasync(PyObject *self, PyObject *fdobj)
    799 {
    800     return edk2_fildes(fdobj, fdatasync);
    801 }
    802 #endif /* HAVE_FDATASYNC */
    803 
    804 
    805 #ifdef HAVE_CHOWN
    806 PyDoc_STRVAR(edk2_chown__doc__,
    807 "chown(path, uid, gid)\n\n\
    808 Change the owner and group id of path to the numeric uid and gid.");
    809 
    810 static PyObject *
    811 edk2_chown(PyObject *self, PyObject *args)
    812 {
    813     char *path = NULL;
    814     long uid, gid;
    815     int res;
    816     if (!PyArg_ParseTuple(args, "etll:chown",
    817                           Py_FileSystemDefaultEncoding, &path,
    818                           &uid, &gid))
    819         return NULL;
    820     Py_BEGIN_ALLOW_THREADS
    821     res = chown(path, (uid_t) uid, (gid_t) gid);
    822     Py_END_ALLOW_THREADS
    823     if (res < 0)
    824         return edk2_error_with_allocated_filename(path);
    825     PyMem_Free(path);
    826     Py_INCREF(Py_None);
    827     return Py_None;
    828 }
    829 #endif /* HAVE_CHOWN */
    830 
    831 #ifdef HAVE_FCHOWN
    832 PyDoc_STRVAR(edk2_fchown__doc__,
    833 "fchown(fd, uid, gid)\n\n\
    834 Change the owner and group id of the file given by file descriptor\n\
    835 fd to the numeric uid and gid.");
    836 
    837 static PyObject *
    838 edk2_fchown(PyObject *self, PyObject *args)
    839 {
    840     int fd;
    841     long uid, gid;
    842     int res;
    843     if (!PyArg_ParseTuple(args, "ill:chown", &fd, &uid, &gid))
    844         return NULL;
    845     Py_BEGIN_ALLOW_THREADS
    846     res = fchown(fd, (uid_t) uid, (gid_t) gid);
    847     Py_END_ALLOW_THREADS
    848     if (res < 0)
    849         return edk2_error();
    850     Py_RETURN_NONE;
    851 }
    852 #endif /* HAVE_FCHOWN */
    853 
    854 #ifdef HAVE_LCHOWN
    855 PyDoc_STRVAR(edk2_lchown__doc__,
    856 "lchown(path, uid, gid)\n\n\
    857 Change the owner and group id of path to the numeric uid and gid.\n\
    858 This function will not follow symbolic links.");
    859 
    860 static PyObject *
    861 edk2_lchown(PyObject *self, PyObject *args)
    862 {
    863     char *path = NULL;
    864     long uid, gid;
    865     int res;
    866     if (!PyArg_ParseTuple(args, "etll:lchown",
    867                           Py_FileSystemDefaultEncoding, &path,
    868                           &uid, &gid))
    869         return NULL;
    870     Py_BEGIN_ALLOW_THREADS
    871     res = lchown(path, (uid_t) uid, (gid_t) gid);
    872     Py_END_ALLOW_THREADS
    873     if (res < 0)
    874         return edk2_error_with_allocated_filename(path);
    875     PyMem_Free(path);
    876     Py_INCREF(Py_None);
    877     return Py_None;
    878 }
    879 #endif /* HAVE_LCHOWN */
    880 
    881 
    882 #ifdef HAVE_GETCWD
    883 PyDoc_STRVAR(edk2_getcwd__doc__,
    884 "getcwd() -> path\n\n\
    885 Return a string representing the current working directory.");
    886 
    887 static PyObject *
    888 edk2_getcwd(PyObject *self, PyObject *noargs)
    889 {
    890     int bufsize_incr = 1024;
    891     int bufsize = 0;
    892     char *tmpbuf = NULL;
    893     char *res = NULL;
    894     PyObject *dynamic_return;
    895 
    896     Py_BEGIN_ALLOW_THREADS
    897     do {
    898         bufsize = bufsize + bufsize_incr;
    899         tmpbuf = malloc(bufsize);
    900         if (tmpbuf == NULL) {
    901             break;
    902         }
    903         res = getcwd(tmpbuf, bufsize);
    904         if (res == NULL) {
    905             free(tmpbuf);
    906         }
    907     } while ((res == NULL) && (errno == ERANGE));
    908     Py_END_ALLOW_THREADS
    909 
    910     if (res == NULL)
    911         return edk2_error();
    912 
    913     dynamic_return = PyString_FromString(tmpbuf);
    914     free(tmpbuf);
    915 
    916     return dynamic_return;
    917 }
    918 
    919 #ifdef Py_USING_UNICODE
    920 PyDoc_STRVAR(edk2_getcwdu__doc__,
    921 "getcwdu() -> path\n\n\
    922 Return a unicode string representing the current working directory.");
    923 
    924 static PyObject *
    925 edk2_getcwdu(PyObject *self, PyObject *noargs)
    926 {
    927     char buf[1026];
    928     char *res;
    929 
    930     Py_BEGIN_ALLOW_THREADS
    931     res = getcwd(buf, sizeof buf);
    932     Py_END_ALLOW_THREADS
    933     if (res == NULL)
    934         return edk2_error();
    935     return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
    936 }
    937 #endif /* Py_USING_UNICODE */
    938 #endif /* HAVE_GETCWD */
    939 
    940 
    941 PyDoc_STRVAR(edk2_listdir__doc__,
    942 "listdir(path) -> list_of_strings\n\n\
    943 Return a list containing the names of the entries in the directory.\n\
    944 \n\
    945     path: path of directory to list\n\
    946 \n\
    947 The list is in arbitrary order.  It does not include the special\n\
    948 entries '.' and '..' even if they are present in the directory.");
    949 
    950 static PyObject *
    951 edk2_listdir(PyObject *self, PyObject *args)
    952 {
    953     /* XXX Should redo this putting the (now four) versions of opendir
    954        in separate files instead of having them all here... */
    955 
    956     char           *name            = NULL;
    957     char           *MBname;
    958     PyObject       *d, *v;
    959     DIR            *dirp;
    960     struct dirent  *ep;
    961     int             arg_is_unicode  = 1;
    962 
    963     errno = 0;
    964     if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
    965         arg_is_unicode = 0;
    966         PyErr_Clear();
    967     }
    968     if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
    969         return NULL;
    970     Py_BEGIN_ALLOW_THREADS
    971     dirp = opendir(name);
    972     Py_END_ALLOW_THREADS
    973     if (dirp == NULL) {
    974         return edk2_error_with_allocated_filename(name);
    975     }
    976     if ((d = PyList_New(0)) == NULL) {
    977         Py_BEGIN_ALLOW_THREADS
    978         closedir(dirp);
    979         Py_END_ALLOW_THREADS
    980         PyMem_Free(name);
    981         return NULL;
    982     }
    983     if((MBname = malloc(NAME_MAX)) == NULL) {
    984       Py_BEGIN_ALLOW_THREADS
    985       closedir(dirp);
    986       Py_END_ALLOW_THREADS
    987       Py_DECREF(d);
    988       PyMem_Free(name);
    989       return NULL;
    990     }
    991     for (;;) {
    992         errno = 0;
    993         Py_BEGIN_ALLOW_THREADS
    994         ep = readdir(dirp);
    995         Py_END_ALLOW_THREADS
    996         if (ep == NULL) {
    997             if ((errno == 0) || (errno == EISDIR)) {
    998                 break;
    999             } else {
   1000                 Py_BEGIN_ALLOW_THREADS
   1001                 closedir(dirp);
   1002                 Py_END_ALLOW_THREADS
   1003                 Py_DECREF(d);
   1004                 return edk2_error_with_allocated_filename(name);
   1005             }
   1006         }
   1007         if (ep->FileName[0] == L'.' &&
   1008             (NAMLEN(ep) == 1 ||
   1009              (ep->FileName[1] == L'.' && NAMLEN(ep) == 2)))
   1010             continue;
   1011         if(wcstombs(MBname, ep->FileName, NAME_MAX) == -1) {
   1012           free(MBname);
   1013           Py_BEGIN_ALLOW_THREADS
   1014           closedir(dirp);
   1015           Py_END_ALLOW_THREADS
   1016           Py_DECREF(d);
   1017           PyMem_Free(name);
   1018           return NULL;
   1019         }
   1020         v = PyString_FromStringAndSize(MBname, strlen(MBname));
   1021         if (v == NULL) {
   1022             Py_DECREF(d);
   1023             d = NULL;
   1024             break;
   1025         }
   1026 #ifdef Py_USING_UNICODE
   1027         if (arg_is_unicode) {
   1028             PyObject *w;
   1029 
   1030             w = PyUnicode_FromEncodedObject(v,
   1031                                             Py_FileSystemDefaultEncoding,
   1032                                             "strict");
   1033             if (w != NULL) {
   1034                 Py_DECREF(v);
   1035                 v = w;
   1036             }
   1037             else {
   1038                 /* fall back to the original byte string, as
   1039                    discussed in patch #683592 */
   1040                 PyErr_Clear();
   1041             }
   1042         }
   1043 #endif
   1044         if (PyList_Append(d, v) != 0) {
   1045             Py_DECREF(v);
   1046             Py_DECREF(d);
   1047             d = NULL;
   1048             break;
   1049         }
   1050         Py_DECREF(v);
   1051     }
   1052     Py_BEGIN_ALLOW_THREADS
   1053     closedir(dirp);
   1054     Py_END_ALLOW_THREADS
   1055     PyMem_Free(name);
   1056     if(MBname != NULL) {
   1057       free(MBname);
   1058     }
   1059 
   1060     return d;
   1061 
   1062 }  /* end of edk2_listdir */
   1063 
   1064 PyDoc_STRVAR(edk2_mkdir__doc__,
   1065 "mkdir(path [, mode=0777])\n\n\
   1066 Create a directory.");
   1067 
   1068 static PyObject *
   1069 edk2_mkdir(PyObject *self, PyObject *args)
   1070 {
   1071     int res;
   1072     char *path = NULL;
   1073     int mode = 0777;
   1074 
   1075     if (!PyArg_ParseTuple(args, "et|i:mkdir",
   1076                           Py_FileSystemDefaultEncoding, &path, &mode))
   1077         return NULL;
   1078     Py_BEGIN_ALLOW_THREADS
   1079     res = mkdir(path, mode);
   1080     Py_END_ALLOW_THREADS
   1081     if (res < 0)
   1082         return edk2_error_with_allocated_filename(path);
   1083     PyMem_Free(path);
   1084     Py_INCREF(Py_None);
   1085     return Py_None;
   1086 }
   1087 
   1088 
   1089 /* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
   1090 #if defined(HAVE_SYS_RESOURCE_H)
   1091 #include <sys/resource.h>
   1092 #endif
   1093 
   1094 
   1095 #ifdef HAVE_NICE
   1096 PyDoc_STRVAR(edk2_nice__doc__,
   1097 "nice(inc) -> new_priority\n\n\
   1098 Decrease the priority of process by inc and return the new priority.");
   1099 
   1100 static PyObject *
   1101 edk2_nice(PyObject *self, PyObject *args)
   1102 {
   1103     int increment, value;
   1104 
   1105     if (!PyArg_ParseTuple(args, "i:nice", &increment))
   1106         return NULL;
   1107 
   1108     /* There are two flavours of 'nice': one that returns the new
   1109        priority (as required by almost all standards out there) and the
   1110        Linux/FreeBSD/BSDI one, which returns '0' on success and advices
   1111        the use of getpriority() to get the new priority.
   1112 
   1113        If we are of the nice family that returns the new priority, we
   1114        need to clear errno before the call, and check if errno is filled
   1115        before calling edk2_error() on a returnvalue of -1, because the
   1116        -1 may be the actual new priority! */
   1117 
   1118     errno = 0;
   1119     value = nice(increment);
   1120 #if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
   1121     if (value == 0)
   1122         value = getpriority(PRIO_PROCESS, 0);
   1123 #endif
   1124     if (value == -1 && errno != 0)
   1125         /* either nice() or getpriority() returned an error */
   1126         return edk2_error();
   1127     return PyInt_FromLong((long) value);
   1128 }
   1129 #endif /* HAVE_NICE */
   1130 
   1131 PyDoc_STRVAR(edk2_rename__doc__,
   1132 "rename(old, new)\n\n\
   1133 Rename a file or directory.");
   1134 
   1135 static PyObject *
   1136 edk2_rename(PyObject *self, PyObject *args)
   1137 {
   1138     return edk2_2str(args, "etet:rename", rename);
   1139 }
   1140 
   1141 
   1142 PyDoc_STRVAR(edk2_rmdir__doc__,
   1143 "rmdir(path)\n\n\
   1144 Remove a directory.");
   1145 
   1146 static PyObject *
   1147 edk2_rmdir(PyObject *self, PyObject *args)
   1148 {
   1149     return edk2_1str(args, "et:rmdir", rmdir);
   1150 }
   1151 
   1152 
   1153 PyDoc_STRVAR(edk2_stat__doc__,
   1154 "stat(path) -> stat result\n\n\
   1155 Perform a stat system call on the given path.");
   1156 
   1157 static PyObject *
   1158 edk2_stat(PyObject *self, PyObject *args)
   1159 {
   1160     return edk2_do_stat(self, args, "et:stat", STAT, NULL, NULL);
   1161 }
   1162 
   1163 
   1164 #ifdef HAVE_SYSTEM
   1165 PyDoc_STRVAR(edk2_system__doc__,
   1166 "system(command) -> exit_status\n\n\
   1167 Execute the command (a string) in a subshell.");
   1168 
   1169 static PyObject *
   1170 edk2_system(PyObject *self, PyObject *args)
   1171 {
   1172     char *command;
   1173     long sts;
   1174     if (!PyArg_ParseTuple(args, "s:system", &command))
   1175         return NULL;
   1176     Py_BEGIN_ALLOW_THREADS
   1177     sts = system(command);
   1178     Py_END_ALLOW_THREADS
   1179     return PyInt_FromLong(sts);
   1180 }
   1181 #endif
   1182 
   1183 
   1184 PyDoc_STRVAR(edk2_umask__doc__,
   1185 "umask(new_mask) -> old_mask\n\n\
   1186 Set the current numeric umask and return the previous umask.");
   1187 
   1188 static PyObject *
   1189 edk2_umask(PyObject *self, PyObject *args)
   1190 {
   1191     int i;
   1192     if (!PyArg_ParseTuple(args, "i:umask", &i))
   1193         return NULL;
   1194     i = (int)umask(i);
   1195     if (i < 0)
   1196         return edk2_error();
   1197     return PyInt_FromLong((long)i);
   1198 }
   1199 
   1200 
   1201 PyDoc_STRVAR(edk2_unlink__doc__,
   1202 "unlink(path)\n\n\
   1203 Remove a file (same as remove(path)).");
   1204 
   1205 PyDoc_STRVAR(edk2_remove__doc__,
   1206 "remove(path)\n\n\
   1207 Remove a file (same as unlink(path)).");
   1208 
   1209 static PyObject *
   1210 edk2_unlink(PyObject *self, PyObject *args)
   1211 {
   1212     return edk2_1str(args, "et:remove", unlink);
   1213 }
   1214 
   1215 
   1216 static int
   1217 extract_time(PyObject *t, time_t* sec, long* usec)
   1218 {
   1219     time_t intval;
   1220     if (PyFloat_Check(t)) {
   1221         double tval = PyFloat_AsDouble(t);
   1222         PyObject *intobj = PyNumber_Long(t);
   1223         if (!intobj)
   1224             return -1;
   1225 #if SIZEOF_TIME_T > SIZEOF_LONG
   1226         intval = PyInt_AsUnsignedLongLongMask(intobj);
   1227 #else
   1228         intval = PyInt_AsLong(intobj);
   1229 #endif
   1230         Py_DECREF(intobj);
   1231         if (intval == -1 && PyErr_Occurred())
   1232             return -1;
   1233         *sec = intval;
   1234         *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
   1235         if (*usec < 0)
   1236             /* If rounding gave us a negative number,
   1237                truncate.  */
   1238             *usec = 0;
   1239         return 0;
   1240     }
   1241 #if SIZEOF_TIME_T > SIZEOF_LONG
   1242     intval = PyInt_AsUnsignedLongLongMask(t);
   1243 #else
   1244     intval = PyInt_AsLong(t);
   1245 #endif
   1246     if (intval == -1 && PyErr_Occurred())
   1247         return -1;
   1248     *sec = intval;
   1249     *usec = 0;
   1250     return 0;
   1251 }
   1252 
   1253 PyDoc_STRVAR(edk2_utime__doc__,
   1254 "utime(path, (atime, mtime))\n\
   1255 utime(path, None)\n\n\
   1256 Set the access and modified time of the file to the given values.  If the\n\
   1257 second form is used, set the access and modified times to the current time.");
   1258 
   1259 static PyObject *
   1260 edk2_utime(PyObject *self, PyObject *args)
   1261 {
   1262     char *path = NULL;
   1263     time_t atime, mtime;
   1264     long ausec, musec;
   1265     int res;
   1266     PyObject* arg;
   1267 
   1268 #if defined(HAVE_UTIMES)
   1269     struct timeval buf[2];
   1270 #define ATIME buf[0].tv_sec
   1271 #define MTIME buf[1].tv_sec
   1272 #elif defined(HAVE_UTIME_H)
   1273 /* XXX should define struct utimbuf instead, above */
   1274     struct utimbuf buf;
   1275 #define ATIME buf.actime
   1276 #define MTIME buf.modtime
   1277 #define UTIME_ARG &buf
   1278 #else /* HAVE_UTIMES */
   1279     time_t buf[2];
   1280 #define ATIME buf[0]
   1281 #define MTIME buf[1]
   1282 #define UTIME_ARG buf
   1283 #endif /* HAVE_UTIMES */
   1284 
   1285 
   1286     if (!PyArg_ParseTuple(args, "etO:utime",
   1287                           Py_FileSystemDefaultEncoding, &path, &arg))
   1288         return NULL;
   1289     if (arg == Py_None) {
   1290         /* optional time values not given */
   1291         Py_BEGIN_ALLOW_THREADS
   1292         res = utime(path, NULL);
   1293         Py_END_ALLOW_THREADS
   1294     }
   1295     else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
   1296         PyErr_SetString(PyExc_TypeError,
   1297                         "utime() arg 2 must be a tuple (atime, mtime)");
   1298         PyMem_Free(path);
   1299         return NULL;
   1300     }
   1301     else {
   1302         if (extract_time(PyTuple_GET_ITEM(arg, 0),
   1303                          &atime, &ausec) == -1) {
   1304             PyMem_Free(path);
   1305             return NULL;
   1306         }
   1307         if (extract_time(PyTuple_GET_ITEM(arg, 1),
   1308                          &mtime, &musec) == -1) {
   1309             PyMem_Free(path);
   1310             return NULL;
   1311         }
   1312         ATIME = atime;
   1313         MTIME = mtime;
   1314 #ifdef HAVE_UTIMES
   1315         buf[0].tv_usec = ausec;
   1316         buf[1].tv_usec = musec;
   1317         Py_BEGIN_ALLOW_THREADS
   1318         res = utimes(path, buf);
   1319         Py_END_ALLOW_THREADS
   1320 #else
   1321         Py_BEGIN_ALLOW_THREADS
   1322         res = utime(path, UTIME_ARG);
   1323         Py_END_ALLOW_THREADS
   1324 #endif /* HAVE_UTIMES */
   1325     }
   1326     if (res < 0) {
   1327         return edk2_error_with_allocated_filename(path);
   1328     }
   1329     PyMem_Free(path);
   1330     Py_INCREF(Py_None);
   1331     return Py_None;
   1332 #undef UTIME_ARG
   1333 #undef ATIME
   1334 #undef MTIME
   1335 }
   1336 
   1337 
   1338 /* Process operations */
   1339 
   1340 PyDoc_STRVAR(edk2__exit__doc__,
   1341 "_exit(status)\n\n\
   1342 Exit to the system with specified status, without normal exit processing.");
   1343 
   1344 static PyObject *
   1345 edk2__exit(PyObject *self, PyObject *args)
   1346 {
   1347     int sts;
   1348     if (!PyArg_ParseTuple(args, "i:_exit", &sts))
   1349         return NULL;
   1350     _Exit(sts);
   1351     return NULL; /* Make gcc -Wall happy */
   1352 }
   1353 
   1354 #if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
   1355 static void
   1356 free_string_array(char **array, Py_ssize_t count)
   1357 {
   1358     Py_ssize_t i;
   1359     for (i = 0; i < count; i++)
   1360         PyMem_Free(array[i]);
   1361     PyMem_DEL(array);
   1362 }
   1363 #endif
   1364 
   1365 
   1366 #ifdef HAVE_EXECV
   1367 PyDoc_STRVAR(edk2_execv__doc__,
   1368 "execv(path, args)\n\n\
   1369 Execute an executable path with arguments, replacing current process.\n\
   1370 \n\
   1371     path: path of executable file\n\
   1372     args: tuple or list of strings");
   1373 
   1374 static PyObject *
   1375 edk2_execv(PyObject *self, PyObject *args)
   1376 {
   1377     char *path;
   1378     PyObject *argv;
   1379     char **argvlist;
   1380     Py_ssize_t i, argc;
   1381     PyObject *(*getitem)(PyObject *, Py_ssize_t);
   1382 
   1383     /* execv has two arguments: (path, argv), where
   1384        argv is a list or tuple of strings. */
   1385 
   1386     if (!PyArg_ParseTuple(args, "etO:execv",
   1387                           Py_FileSystemDefaultEncoding,
   1388                           &path, &argv))
   1389         return NULL;
   1390     if (PyList_Check(argv)) {
   1391         argc = PyList_Size(argv);
   1392         getitem = PyList_GetItem;
   1393     }
   1394     else if (PyTuple_Check(argv)) {
   1395         argc = PyTuple_Size(argv);
   1396         getitem = PyTuple_GetItem;
   1397     }
   1398     else {
   1399         PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
   1400         PyMem_Free(path);
   1401         return NULL;
   1402     }
   1403     if (argc < 1) {
   1404         PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
   1405         PyMem_Free(path);
   1406         return NULL;
   1407     }
   1408 
   1409     argvlist = PyMem_NEW(char *, argc+1);
   1410     if (argvlist == NULL) {
   1411         PyMem_Free(path);
   1412         return PyErr_NoMemory();
   1413     }
   1414     for (i = 0; i < argc; i++) {
   1415         if (!PyArg_Parse((*getitem)(argv, i), "et",
   1416                          Py_FileSystemDefaultEncoding,
   1417                          &argvlist[i])) {
   1418             free_string_array(argvlist, i);
   1419             PyErr_SetString(PyExc_TypeError,
   1420                             "execv() arg 2 must contain only strings");
   1421             PyMem_Free(path);
   1422             return NULL;
   1423 
   1424         }
   1425     }
   1426     argvlist[argc] = NULL;
   1427 
   1428     execv(path, argvlist);
   1429 
   1430     /* If we get here it's definitely an error */
   1431 
   1432     free_string_array(argvlist, argc);
   1433     PyMem_Free(path);
   1434     return edk2_error();
   1435 }
   1436 
   1437 
   1438 PyDoc_STRVAR(edk2_execve__doc__,
   1439 "execve(path, args, env)\n\n\
   1440 Execute a path with arguments and environment, replacing current process.\n\
   1441 \n\
   1442     path: path of executable file\n\
   1443     args: tuple or list of arguments\n\
   1444     env: dictionary of strings mapping to strings");
   1445 
   1446 static PyObject *
   1447 edk2_execve(PyObject *self, PyObject *args)
   1448 {
   1449     char *path;
   1450     PyObject *argv, *env;
   1451     char **argvlist;
   1452     char **envlist;
   1453     PyObject *key, *val, *keys=NULL, *vals=NULL;
   1454     Py_ssize_t i, pos, argc, envc;
   1455     PyObject *(*getitem)(PyObject *, Py_ssize_t);
   1456     Py_ssize_t lastarg = 0;
   1457 
   1458     /* execve has three arguments: (path, argv, env), where
   1459        argv is a list or tuple of strings and env is a dictionary
   1460        like posix.environ. */
   1461 
   1462     if (!PyArg_ParseTuple(args, "etOO:execve",
   1463                           Py_FileSystemDefaultEncoding,
   1464                           &path, &argv, &env))
   1465         return NULL;
   1466     if (PyList_Check(argv)) {
   1467         argc = PyList_Size(argv);
   1468         getitem = PyList_GetItem;
   1469     }
   1470     else if (PyTuple_Check(argv)) {
   1471         argc = PyTuple_Size(argv);
   1472         getitem = PyTuple_GetItem;
   1473     }
   1474     else {
   1475         PyErr_SetString(PyExc_TypeError,
   1476                         "execve() arg 2 must be a tuple or list");
   1477         goto fail_0;
   1478     }
   1479     if (!PyMapping_Check(env)) {
   1480         PyErr_SetString(PyExc_TypeError,
   1481                         "execve() arg 3 must be a mapping object");
   1482         goto fail_0;
   1483     }
   1484 
   1485     argvlist = PyMem_NEW(char *, argc+1);
   1486     if (argvlist == NULL) {
   1487         PyErr_NoMemory();
   1488         goto fail_0;
   1489     }
   1490     for (i = 0; i < argc; i++) {
   1491         if (!PyArg_Parse((*getitem)(argv, i),
   1492                          "et;execve() arg 2 must contain only strings",
   1493                          Py_FileSystemDefaultEncoding,
   1494                          &argvlist[i]))
   1495         {
   1496             lastarg = i;
   1497             goto fail_1;
   1498         }
   1499     }
   1500     lastarg = argc;
   1501     argvlist[argc] = NULL;
   1502 
   1503     i = PyMapping_Size(env);
   1504     if (i < 0)
   1505         goto fail_1;
   1506     envlist = PyMem_NEW(char *, i + 1);
   1507     if (envlist == NULL) {
   1508         PyErr_NoMemory();
   1509         goto fail_1;
   1510     }
   1511     envc = 0;
   1512     keys = PyMapping_Keys(env);
   1513     vals = PyMapping_Values(env);
   1514     if (!keys || !vals)
   1515         goto fail_2;
   1516     if (!PyList_Check(keys) || !PyList_Check(vals)) {
   1517         PyErr_SetString(PyExc_TypeError,
   1518                         "execve(): env.keys() or env.values() is not a list");
   1519         goto fail_2;
   1520     }
   1521 
   1522     for (pos = 0; pos < i; pos++) {
   1523         char *p, *k, *v;
   1524         size_t len;
   1525 
   1526         key = PyList_GetItem(keys, pos);
   1527         val = PyList_GetItem(vals, pos);
   1528         if (!key || !val)
   1529             goto fail_2;
   1530 
   1531         if (!PyArg_Parse(
   1532                     key,
   1533                     "s;execve() arg 3 contains a non-string key",
   1534                     &k) ||
   1535             !PyArg_Parse(
   1536                 val,
   1537                 "s;execve() arg 3 contains a non-string value",
   1538                 &v))
   1539         {
   1540             goto fail_2;
   1541         }
   1542 
   1543 #if defined(PYOS_OS2)
   1544         /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
   1545         if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
   1546 #endif
   1547         len = PyString_Size(key) + PyString_Size(val) + 2;
   1548         p = PyMem_NEW(char, len);
   1549         if (p == NULL) {
   1550             PyErr_NoMemory();
   1551             goto fail_2;
   1552         }
   1553         PyOS_snprintf(p, len, "%s=%s", k, v);
   1554         envlist[envc++] = p;
   1555 #if defined(PYOS_OS2)
   1556         }
   1557 #endif
   1558     }
   1559     envlist[envc] = 0;
   1560 
   1561     execve(path, argvlist, envlist);
   1562 
   1563     /* If we get here it's definitely an error */
   1564 
   1565     (void) edk2_error();
   1566 
   1567   fail_2:
   1568     while (--envc >= 0)
   1569         PyMem_DEL(envlist[envc]);
   1570     PyMem_DEL(envlist);
   1571   fail_1:
   1572     free_string_array(argvlist, lastarg);
   1573     Py_XDECREF(vals);
   1574     Py_XDECREF(keys);
   1575   fail_0:
   1576     PyMem_Free(path);
   1577     return NULL;
   1578 }
   1579 #endif /* HAVE_EXECV */
   1580 
   1581 
   1582 #ifdef HAVE_SPAWNV
   1583 PyDoc_STRVAR(edk2_spawnv__doc__,
   1584 "spawnv(mode, path, args)\n\n\
   1585 Execute the program 'path' in a new process.\n\
   1586 \n\
   1587     mode: mode of process creation\n\
   1588     path: path of executable file\n\
   1589     args: tuple or list of strings");
   1590 
   1591 static PyObject *
   1592 edk2_spawnv(PyObject *self, PyObject *args)
   1593 {
   1594     char *path;
   1595     PyObject *argv;
   1596     char **argvlist;
   1597     int mode, i;
   1598     Py_ssize_t argc;
   1599     Py_intptr_t spawnval;
   1600     PyObject *(*getitem)(PyObject *, Py_ssize_t);
   1601 
   1602     /* spawnv has three arguments: (mode, path, argv), where
   1603        argv is a list or tuple of strings. */
   1604 
   1605     if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
   1606                           Py_FileSystemDefaultEncoding,
   1607                           &path, &argv))
   1608         return NULL;
   1609     if (PyList_Check(argv)) {
   1610         argc = PyList_Size(argv);
   1611         getitem = PyList_GetItem;
   1612     }
   1613     else if (PyTuple_Check(argv)) {
   1614         argc = PyTuple_Size(argv);
   1615         getitem = PyTuple_GetItem;
   1616     }
   1617     else {
   1618         PyErr_SetString(PyExc_TypeError,
   1619                         "spawnv() arg 2 must be a tuple or list");
   1620         PyMem_Free(path);
   1621         return NULL;
   1622     }
   1623 
   1624     argvlist = PyMem_NEW(char *, argc+1);
   1625     if (argvlist == NULL) {
   1626         PyMem_Free(path);
   1627         return PyErr_NoMemory();
   1628     }
   1629     for (i = 0; i < argc; i++) {
   1630         if (!PyArg_Parse((*getitem)(argv, i), "et",
   1631                          Py_FileSystemDefaultEncoding,
   1632                          &argvlist[i])) {
   1633             free_string_array(argvlist, i);
   1634             PyErr_SetString(
   1635                 PyExc_TypeError,
   1636                 "spawnv() arg 2 must contain only strings");
   1637             PyMem_Free(path);
   1638             return NULL;
   1639         }
   1640     }
   1641     argvlist[argc] = NULL;
   1642 
   1643 #if defined(PYOS_OS2) && defined(PYCC_GCC)
   1644     Py_BEGIN_ALLOW_THREADS
   1645     spawnval = spawnv(mode, path, argvlist);
   1646     Py_END_ALLOW_THREADS
   1647 #else
   1648     if (mode == _OLD_P_OVERLAY)
   1649         mode = _P_OVERLAY;
   1650 
   1651     Py_BEGIN_ALLOW_THREADS
   1652     spawnval = _spawnv(mode, path, argvlist);
   1653     Py_END_ALLOW_THREADS
   1654 #endif
   1655 
   1656     free_string_array(argvlist, argc);
   1657     PyMem_Free(path);
   1658 
   1659     if (spawnval == -1)
   1660         return edk2_error();
   1661     else
   1662 #if SIZEOF_LONG == SIZEOF_VOID_P
   1663         return Py_BuildValue("l", (long) spawnval);
   1664 #else
   1665         return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
   1666 #endif
   1667 }
   1668 
   1669 
   1670 PyDoc_STRVAR(edk2_spawnve__doc__,
   1671 "spawnve(mode, path, args, env)\n\n\
   1672 Execute the program 'path' in a new process.\n\
   1673 \n\
   1674     mode: mode of process creation\n\
   1675     path: path of executable file\n\
   1676     args: tuple or list of arguments\n\
   1677     env: dictionary of strings mapping to strings");
   1678 
   1679 static PyObject *
   1680 edk2_spawnve(PyObject *self, PyObject *args)
   1681 {
   1682     char *path;
   1683     PyObject *argv, *env;
   1684     char **argvlist;
   1685     char **envlist;
   1686     PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
   1687     int mode, pos, envc;
   1688     Py_ssize_t argc, i;
   1689     Py_intptr_t spawnval;
   1690     PyObject *(*getitem)(PyObject *, Py_ssize_t);
   1691     Py_ssize_t lastarg = 0;
   1692 
   1693     /* spawnve has four arguments: (mode, path, argv, env), where
   1694        argv is a list or tuple of strings and env is a dictionary
   1695        like posix.environ. */
   1696 
   1697     if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
   1698                           Py_FileSystemDefaultEncoding,
   1699                           &path, &argv, &env))
   1700         return NULL;
   1701     if (PyList_Check(argv)) {
   1702         argc = PyList_Size(argv);
   1703         getitem = PyList_GetItem;
   1704     }
   1705     else if (PyTuple_Check(argv)) {
   1706         argc = PyTuple_Size(argv);
   1707         getitem = PyTuple_GetItem;
   1708     }
   1709     else {
   1710         PyErr_SetString(PyExc_TypeError,
   1711                         "spawnve() arg 2 must be a tuple or list");
   1712         goto fail_0;
   1713     }
   1714     if (!PyMapping_Check(env)) {
   1715         PyErr_SetString(PyExc_TypeError,
   1716                         "spawnve() arg 3 must be a mapping object");
   1717         goto fail_0;
   1718     }
   1719 
   1720     argvlist = PyMem_NEW(char *, argc+1);
   1721     if (argvlist == NULL) {
   1722         PyErr_NoMemory();
   1723         goto fail_0;
   1724     }
   1725     for (i = 0; i < argc; i++) {
   1726         if (!PyArg_Parse((*getitem)(argv, i),
   1727                      "et;spawnve() arg 2 must contain only strings",
   1728                          Py_FileSystemDefaultEncoding,
   1729                          &argvlist[i]))
   1730         {
   1731             lastarg = i;
   1732             goto fail_1;
   1733         }
   1734     }
   1735     lastarg = argc;
   1736     argvlist[argc] = NULL;
   1737 
   1738     i = PyMapping_Size(env);
   1739     if (i < 0)
   1740         goto fail_1;
   1741     envlist = PyMem_NEW(char *, i + 1);
   1742     if (envlist == NULL) {
   1743         PyErr_NoMemory();
   1744         goto fail_1;
   1745     }
   1746     envc = 0;
   1747     keys = PyMapping_Keys(env);
   1748     vals = PyMapping_Values(env);
   1749     if (!keys || !vals)
   1750         goto fail_2;
   1751     if (!PyList_Check(keys) || !PyList_Check(vals)) {
   1752         PyErr_SetString(PyExc_TypeError,
   1753                         "spawnve(): env.keys() or env.values() is not a list");
   1754         goto fail_2;
   1755     }
   1756 
   1757     for (pos = 0; pos < i; pos++) {
   1758         char *p, *k, *v;
   1759         size_t len;
   1760 
   1761         key = PyList_GetItem(keys, pos);
   1762         val = PyList_GetItem(vals, pos);
   1763         if (!key || !val)
   1764             goto fail_2;
   1765 
   1766         if (!PyArg_Parse(
   1767                     key,
   1768                     "s;spawnve() arg 3 contains a non-string key",
   1769                     &k) ||
   1770             !PyArg_Parse(
   1771                 val,
   1772                 "s;spawnve() arg 3 contains a non-string value",
   1773                 &v))
   1774         {
   1775             goto fail_2;
   1776         }
   1777         len = PyString_Size(key) + PyString_Size(val) + 2;
   1778         p = PyMem_NEW(char, len);
   1779         if (p == NULL) {
   1780             PyErr_NoMemory();
   1781             goto fail_2;
   1782         }
   1783         PyOS_snprintf(p, len, "%s=%s", k, v);
   1784         envlist[envc++] = p;
   1785     }
   1786     envlist[envc] = 0;
   1787 
   1788 #if defined(PYOS_OS2) && defined(PYCC_GCC)
   1789     Py_BEGIN_ALLOW_THREADS
   1790     spawnval = spawnve(mode, path, argvlist, envlist);
   1791     Py_END_ALLOW_THREADS
   1792 #else
   1793     if (mode == _OLD_P_OVERLAY)
   1794         mode = _P_OVERLAY;
   1795 
   1796     Py_BEGIN_ALLOW_THREADS
   1797     spawnval = _spawnve(mode, path, argvlist, envlist);
   1798     Py_END_ALLOW_THREADS
   1799 #endif
   1800 
   1801     if (spawnval == -1)
   1802         (void) edk2_error();
   1803     else
   1804 #if SIZEOF_LONG == SIZEOF_VOID_P
   1805         res = Py_BuildValue("l", (long) spawnval);
   1806 #else
   1807         res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
   1808 #endif
   1809 
   1810   fail_2:
   1811     while (--envc >= 0)
   1812         PyMem_DEL(envlist[envc]);
   1813     PyMem_DEL(envlist);
   1814   fail_1:
   1815     free_string_array(argvlist, lastarg);
   1816     Py_XDECREF(vals);
   1817     Py_XDECREF(keys);
   1818   fail_0:
   1819     PyMem_Free(path);
   1820     return res;
   1821 }
   1822 
   1823 /* OS/2 supports spawnvp & spawnvpe natively */
   1824 #if defined(PYOS_OS2)
   1825 PyDoc_STRVAR(edk2_spawnvp__doc__,
   1826 "spawnvp(mode, file, args)\n\n\
   1827 Execute the program 'file' in a new process, using the environment\n\
   1828 search path to find the file.\n\
   1829 \n\
   1830     mode: mode of process creation\n\
   1831     file: executable file name\n\
   1832     args: tuple or list of strings");
   1833 
   1834 static PyObject *
   1835 edk2_spawnvp(PyObject *self, PyObject *args)
   1836 {
   1837     char *path;
   1838     PyObject *argv;
   1839     char **argvlist;
   1840     int mode, i, argc;
   1841     Py_intptr_t spawnval;
   1842     PyObject *(*getitem)(PyObject *, Py_ssize_t);
   1843 
   1844     /* spawnvp has three arguments: (mode, path, argv), where
   1845        argv is a list or tuple of strings. */
   1846 
   1847     if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
   1848                           Py_FileSystemDefaultEncoding,
   1849                           &path, &argv))
   1850         return NULL;
   1851     if (PyList_Check(argv)) {
   1852         argc = PyList_Size(argv);
   1853         getitem = PyList_GetItem;
   1854     }
   1855     else if (PyTuple_Check(argv)) {
   1856         argc = PyTuple_Size(argv);
   1857         getitem = PyTuple_GetItem;
   1858     }
   1859     else {
   1860         PyErr_SetString(PyExc_TypeError,
   1861                         "spawnvp() arg 2 must be a tuple or list");
   1862         PyMem_Free(path);
   1863         return NULL;
   1864     }
   1865 
   1866     argvlist = PyMem_NEW(char *, argc+1);
   1867     if (argvlist == NULL) {
   1868         PyMem_Free(path);
   1869         return PyErr_NoMemory();
   1870     }
   1871     for (i = 0; i < argc; i++) {
   1872         if (!PyArg_Parse((*getitem)(argv, i), "et",
   1873                          Py_FileSystemDefaultEncoding,
   1874                          &argvlist[i])) {
   1875             free_string_array(argvlist, i);
   1876             PyErr_SetString(
   1877                 PyExc_TypeError,
   1878                 "spawnvp() arg 2 must contain only strings");
   1879             PyMem_Free(path);
   1880             return NULL;
   1881         }
   1882     }
   1883     argvlist[argc] = NULL;
   1884 
   1885     Py_BEGIN_ALLOW_THREADS
   1886 #if defined(PYCC_GCC)
   1887     spawnval = spawnvp(mode, path, argvlist);
   1888 #else
   1889     spawnval = _spawnvp(mode, path, argvlist);
   1890 #endif
   1891     Py_END_ALLOW_THREADS
   1892 
   1893     free_string_array(argvlist, argc);
   1894     PyMem_Free(path);
   1895 
   1896     if (spawnval == -1)
   1897         return edk2_error();
   1898     else
   1899         return Py_BuildValue("l", (long) spawnval);
   1900 }
   1901 
   1902 
   1903 PyDoc_STRVAR(edk2_spawnvpe__doc__,
   1904 "spawnvpe(mode, file, args, env)\n\n\
   1905 Execute the program 'file' in a new process, using the environment\n\
   1906 search path to find the file.\n\
   1907 \n\
   1908     mode: mode of process creation\n\
   1909     file: executable file name\n\
   1910     args: tuple or list of arguments\n\
   1911     env: dictionary of strings mapping to strings");
   1912 
   1913 static PyObject *
   1914 edk2_spawnvpe(PyObject *self, PyObject *args)
   1915 {
   1916     char *path;
   1917     PyObject *argv, *env;
   1918     char **argvlist;
   1919     char **envlist;
   1920     PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
   1921     int mode, i, pos, argc, envc;
   1922     Py_intptr_t spawnval;
   1923     PyObject *(*getitem)(PyObject *, Py_ssize_t);
   1924     int lastarg = 0;
   1925 
   1926     /* spawnvpe has four arguments: (mode, path, argv, env), where
   1927        argv is a list or tuple of strings and env is a dictionary
   1928        like posix.environ. */
   1929 
   1930     if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
   1931                           Py_FileSystemDefaultEncoding,
   1932                           &path, &argv, &env))
   1933         return NULL;
   1934     if (PyList_Check(argv)) {
   1935         argc = PyList_Size(argv);
   1936         getitem = PyList_GetItem;
   1937     }
   1938     else if (PyTuple_Check(argv)) {
   1939         argc = PyTuple_Size(argv);
   1940         getitem = PyTuple_GetItem;
   1941     }
   1942     else {
   1943         PyErr_SetString(PyExc_TypeError,
   1944                         "spawnvpe() arg 2 must be a tuple or list");
   1945         goto fail_0;
   1946     }
   1947     if (!PyMapping_Check(env)) {
   1948         PyErr_SetString(PyExc_TypeError,
   1949                         "spawnvpe() arg 3 must be a mapping object");
   1950         goto fail_0;
   1951     }
   1952 
   1953     argvlist = PyMem_NEW(char *, argc+1);
   1954     if (argvlist == NULL) {
   1955         PyErr_NoMemory();
   1956         goto fail_0;
   1957     }
   1958     for (i = 0; i < argc; i++) {
   1959         if (!PyArg_Parse((*getitem)(argv, i),
   1960                      "et;spawnvpe() arg 2 must contain only strings",
   1961                          Py_FileSystemDefaultEncoding,
   1962                          &argvlist[i]))
   1963         {
   1964             lastarg = i;
   1965             goto fail_1;
   1966         }
   1967     }
   1968     lastarg = argc;
   1969     argvlist[argc] = NULL;
   1970 
   1971     i = PyMapping_Size(env);
   1972     if (i < 0)
   1973         goto fail_1;
   1974     envlist = PyMem_NEW(char *, i + 1);
   1975     if (envlist == NULL) {
   1976         PyErr_NoMemory();
   1977         goto fail_1;
   1978     }
   1979     envc = 0;
   1980     keys = PyMapping_Keys(env);
   1981     vals = PyMapping_Values(env);
   1982     if (!keys || !vals)
   1983         goto fail_2;
   1984     if (!PyList_Check(keys) || !PyList_Check(vals)) {
   1985         PyErr_SetString(PyExc_TypeError,
   1986                         "spawnvpe(): env.keys() or env.values() is not a list");
   1987         goto fail_2;
   1988     }
   1989 
   1990     for (pos = 0; pos < i; pos++) {
   1991         char *p, *k, *v;
   1992         size_t len;
   1993 
   1994         key = PyList_GetItem(keys, pos);
   1995         val = PyList_GetItem(vals, pos);
   1996         if (!key || !val)
   1997             goto fail_2;
   1998 
   1999         if (!PyArg_Parse(
   2000                     key,
   2001                     "s;spawnvpe() arg 3 contains a non-string key",
   2002                     &k) ||
   2003             !PyArg_Parse(
   2004                 val,
   2005                 "s;spawnvpe() arg 3 contains a non-string value",
   2006                 &v))
   2007         {
   2008             goto fail_2;
   2009         }
   2010         len = PyString_Size(key) + PyString_Size(val) + 2;
   2011         p = PyMem_NEW(char, len);
   2012         if (p == NULL) {
   2013             PyErr_NoMemory();
   2014             goto fail_2;
   2015         }
   2016         PyOS_snprintf(p, len, "%s=%s", k, v);
   2017         envlist[envc++] = p;
   2018     }
   2019     envlist[envc] = 0;
   2020 
   2021     Py_BEGIN_ALLOW_THREADS
   2022 #if defined(PYCC_GCC)
   2023     spawnval = spawnvpe(mode, path, argvlist, envlist);
   2024 #else
   2025     spawnval = _spawnvpe(mode, path, argvlist, envlist);
   2026 #endif
   2027     Py_END_ALLOW_THREADS
   2028 
   2029     if (spawnval == -1)
   2030         (void) edk2_error();
   2031     else
   2032         res = Py_BuildValue("l", (long) spawnval);
   2033 
   2034   fail_2:
   2035     while (--envc >= 0)
   2036         PyMem_DEL(envlist[envc]);
   2037     PyMem_DEL(envlist);
   2038   fail_1:
   2039     free_string_array(argvlist, lastarg);
   2040     Py_XDECREF(vals);
   2041     Py_XDECREF(keys);
   2042   fail_0:
   2043     PyMem_Free(path);
   2044     return res;
   2045 }
   2046 #endif /* PYOS_OS2 */
   2047 #endif /* HAVE_SPAWNV */
   2048 
   2049 
   2050 #ifdef HAVE_FORK1
   2051 PyDoc_STRVAR(edk2_fork1__doc__,
   2052 "fork1() -> pid\n\n\
   2053 Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
   2054 \n\
   2055 Return 0 to child process and PID of child to parent process.");
   2056 
   2057 static PyObject *
   2058 edk2_fork1(PyObject *self, PyObject *noargs)
   2059 {
   2060     pid_t pid;
   2061     int result = 0;
   2062     _PyImport_AcquireLock();
   2063     pid = fork1();
   2064     if (pid == 0) {
   2065         /* child: this clobbers and resets the import lock. */
   2066         PyOS_AfterFork();
   2067     } else {
   2068         /* parent: release the import lock. */
   2069         result = _PyImport_ReleaseLock();
   2070     }
   2071     if (pid == -1)
   2072         return edk2_error();
   2073     if (result < 0) {
   2074         /* Don't clobber the OSError if the fork failed. */
   2075         PyErr_SetString(PyExc_RuntimeError,
   2076                         "not holding the import lock");
   2077         return NULL;
   2078     }
   2079     return PyLong_FromPid(pid);
   2080 }
   2081 #endif
   2082 
   2083 
   2084 #ifdef HAVE_FORK
   2085 PyDoc_STRVAR(edk2_fork__doc__,
   2086 "fork() -> pid\n\n\
   2087 Fork a child process.\n\
   2088 Return 0 to child process and PID of child to parent process.");
   2089 
   2090 static PyObject *
   2091 edk2_fork(PyObject *self, PyObject *noargs)
   2092 {
   2093     pid_t pid;
   2094     int result = 0;
   2095     _PyImport_AcquireLock();
   2096     pid = fork();
   2097     if (pid == 0) {
   2098         /* child: this clobbers and resets the import lock. */
   2099         PyOS_AfterFork();
   2100     } else {
   2101         /* parent: release the import lock. */
   2102         result = _PyImport_ReleaseLock();
   2103     }
   2104     if (pid == -1)
   2105         return edk2_error();
   2106     if (result < 0) {
   2107         /* Don't clobber the OSError if the fork failed. */
   2108         PyErr_SetString(PyExc_RuntimeError,
   2109                         "not holding the import lock");
   2110         return NULL;
   2111     }
   2112     return PyLong_FromPid(pid);
   2113 }
   2114 #endif
   2115 
   2116 /* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
   2117 /* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
   2118 #if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
   2119 #define DEV_PTY_FILE "/dev/ptc"
   2120 #define HAVE_DEV_PTMX
   2121 #else
   2122 #define DEV_PTY_FILE "/dev/ptmx"
   2123 #endif
   2124 
   2125 #if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
   2126 #ifdef HAVE_PTY_H
   2127 #include <pty.h>
   2128 #else
   2129 #ifdef HAVE_LIBUTIL_H
   2130 #include <libutil.h>
   2131 #else
   2132 #ifdef HAVE_UTIL_H
   2133 #include <util.h>
   2134 #endif /* HAVE_UTIL_H */
   2135 #endif /* HAVE_LIBUTIL_H */
   2136 #endif /* HAVE_PTY_H */
   2137 #ifdef HAVE_STROPTS_H
   2138 #include <stropts.h>
   2139 #endif
   2140 #endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
   2141 
   2142 #if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
   2143 PyDoc_STRVAR(edk2_openpty__doc__,
   2144 "openpty() -> (master_fd, slave_fd)\n\n\
   2145 Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
   2146 
   2147 static PyObject *
   2148 edk2_openpty(PyObject *self, PyObject *noargs)
   2149 {
   2150     int master_fd, slave_fd;
   2151 #ifndef HAVE_OPENPTY
   2152     char * slave_name;
   2153 #endif
   2154 #if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
   2155     PyOS_sighandler_t sig_saved;
   2156 #ifdef sun
   2157     extern char *ptsname(int fildes);
   2158 #endif
   2159 #endif
   2160 
   2161 #ifdef HAVE_OPENPTY
   2162     if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
   2163         return edk2_error();
   2164 #elif defined(HAVE__GETPTY)
   2165     slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
   2166     if (slave_name == NULL)
   2167         return edk2_error();
   2168 
   2169     slave_fd = open(slave_name, O_RDWR);
   2170     if (slave_fd < 0)
   2171         return edk2_error();
   2172 #else
   2173     master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
   2174     if (master_fd < 0)
   2175         return edk2_error();
   2176     sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
   2177     /* change permission of slave */
   2178     if (grantpt(master_fd) < 0) {
   2179         PyOS_setsig(SIGCHLD, sig_saved);
   2180         return edk2_error();
   2181     }
   2182     /* unlock slave */
   2183     if (unlockpt(master_fd) < 0) {
   2184         PyOS_setsig(SIGCHLD, sig_saved);
   2185         return edk2_error();
   2186     }
   2187     PyOS_setsig(SIGCHLD, sig_saved);
   2188     slave_name = ptsname(master_fd); /* get name of slave */
   2189     if (slave_name == NULL)
   2190         return edk2_error();
   2191     slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
   2192     if (slave_fd < 0)
   2193         return edk2_error();
   2194 #if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
   2195     ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
   2196     ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
   2197 #ifndef __hpux
   2198     ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
   2199 #endif /* __hpux */
   2200 #endif /* HAVE_CYGWIN */
   2201 #endif /* HAVE_OPENPTY */
   2202 
   2203     return Py_BuildValue("(ii)", master_fd, slave_fd);
   2204 
   2205 }
   2206 #endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
   2207 
   2208 #ifdef HAVE_FORKPTY
   2209 PyDoc_STRVAR(edk2_forkpty__doc__,
   2210 "forkpty() -> (pid, master_fd)\n\n\
   2211 Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
   2212 Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
   2213 To both, return fd of newly opened pseudo-terminal.\n");
   2214 
   2215 static PyObject *
   2216 edk2_forkpty(PyObject *self, PyObject *noargs)
   2217 {
   2218     int master_fd = -1, result = 0;
   2219     pid_t pid;
   2220 
   2221     _PyImport_AcquireLock();
   2222     pid = forkpty(&master_fd, NULL, NULL, NULL);
   2223     if (pid == 0) {
   2224         /* child: this clobbers and resets the import lock. */
   2225         PyOS_AfterFork();
   2226     } else {
   2227         /* parent: release the import lock. */
   2228         result = _PyImport_ReleaseLock();
   2229     }
   2230     if (pid == -1)
   2231         return edk2_error();
   2232     if (result < 0) {
   2233         /* Don't clobber the OSError if the fork failed. */
   2234         PyErr_SetString(PyExc_RuntimeError,
   2235                         "not holding the import lock");
   2236         return NULL;
   2237     }
   2238     return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
   2239 }
   2240 #endif
   2241 
   2242 PyDoc_STRVAR(edk2_getpid__doc__,
   2243 "getpid() -> pid\n\n\
   2244 Return the current process id");
   2245 
   2246 static PyObject *
   2247 edk2_getpid(PyObject *self, PyObject *noargs)
   2248 {
   2249     return PyLong_FromPid(getpid());
   2250 }
   2251 
   2252 
   2253 #ifdef HAVE_GETLOGIN
   2254 PyDoc_STRVAR(edk2_getlogin__doc__,
   2255 "getlogin() -> string\n\n\
   2256 Return the actual login name.");
   2257 
   2258 static PyObject *
   2259 edk2_getlogin(PyObject *self, PyObject *noargs)
   2260 {
   2261     PyObject *result = NULL;
   2262     char *name;
   2263     int old_errno = errno;
   2264 
   2265     errno = 0;
   2266     name = getlogin();
   2267     if (name == NULL) {
   2268         if (errno)
   2269         edk2_error();
   2270         else
   2271         PyErr_SetString(PyExc_OSError,
   2272                         "unable to determine login name");
   2273     }
   2274     else
   2275         result = PyString_FromString(name);
   2276     errno = old_errno;
   2277 
   2278     return result;
   2279 }
   2280 #endif
   2281 
   2282 #ifdef HAVE_KILL
   2283 PyDoc_STRVAR(edk2_kill__doc__,
   2284 "kill(pid, sig)\n\n\
   2285 Kill a process with a signal.");
   2286 
   2287 static PyObject *
   2288 edk2_kill(PyObject *self, PyObject *args)
   2289 {
   2290     pid_t pid;
   2291     int sig;
   2292     if (!PyArg_ParseTuple(args, PARSE_PID "i:kill", &pid, &sig))
   2293         return NULL;
   2294 #if defined(PYOS_OS2) && !defined(PYCC_GCC)
   2295     if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
   2296         APIRET rc;
   2297         if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
   2298             return os2_error(rc);
   2299 
   2300     } else if (sig == XCPT_SIGNAL_KILLPROC) {
   2301         APIRET rc;
   2302         if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
   2303             return os2_error(rc);
   2304 
   2305     } else
   2306         return NULL; /* Unrecognized Signal Requested */
   2307 #else
   2308     if (kill(pid, sig) == -1)
   2309         return edk2_error();
   2310 #endif
   2311     Py_INCREF(Py_None);
   2312     return Py_None;
   2313 }
   2314 #endif
   2315 
   2316 #ifdef HAVE_PLOCK
   2317 
   2318 #ifdef HAVE_SYS_LOCK_H
   2319 #include <sys/lock.h>
   2320 #endif
   2321 
   2322 PyDoc_STRVAR(edk2_plock__doc__,
   2323 "plock(op)\n\n\
   2324 Lock program segments into memory.");
   2325 
   2326 static PyObject *
   2327 edk2_plock(PyObject *self, PyObject *args)
   2328 {
   2329     int op;
   2330     if (!PyArg_ParseTuple(args, "i:plock", &op))
   2331         return NULL;
   2332     if (plock(op) == -1)
   2333         return edk2_error();
   2334     Py_INCREF(Py_None);
   2335     return Py_None;
   2336 }
   2337 #endif
   2338 
   2339 
   2340 #ifdef HAVE_POPEN
   2341 PyDoc_STRVAR(edk2_popen__doc__,
   2342 "popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
   2343 Open a pipe to/from a command returning a file object.");
   2344 
   2345 static PyObject *
   2346 edk2_popen(PyObject *self, PyObject *args)
   2347 {
   2348     char *name;
   2349     char *mode = "r";
   2350     int bufsize = -1;
   2351     FILE *fp;
   2352     PyObject *f;
   2353     if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
   2354         return NULL;
   2355     /* Strip mode of binary or text modifiers */
   2356     if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
   2357         mode = "r";
   2358     else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
   2359         mode = "w";
   2360     Py_BEGIN_ALLOW_THREADS
   2361     fp = popen(name, mode);
   2362     Py_END_ALLOW_THREADS
   2363     if (fp == NULL)
   2364         return edk2_error();
   2365     f = PyFile_FromFile(fp, name, mode, pclose);
   2366     if (f != NULL)
   2367         PyFile_SetBufSize(f, bufsize);
   2368     return f;
   2369 }
   2370 
   2371 #endif /* HAVE_POPEN */
   2372 
   2373 
   2374 #if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
   2375 static PyObject *
   2376 wait_helper(pid_t pid, int status, struct rusage *ru)
   2377 {
   2378     PyObject *result;
   2379     static PyObject *struct_rusage;
   2380 
   2381     if (pid == -1)
   2382         return edk2_error();
   2383 
   2384     if (struct_rusage == NULL) {
   2385         PyObject *m = PyImport_ImportModuleNoBlock("resource");
   2386         if (m == NULL)
   2387             return NULL;
   2388         struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
   2389         Py_DECREF(m);
   2390         if (struct_rusage == NULL)
   2391             return NULL;
   2392     }
   2393 
   2394     /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
   2395     result = PyStructSequence_New((PyTypeObject*) struct_rusage);
   2396     if (!result)
   2397         return NULL;
   2398 
   2399 #ifndef doubletime
   2400 #define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
   2401 #endif
   2402 
   2403     PyStructSequence_SET_ITEM(result, 0,
   2404                               PyFloat_FromDouble(doubletime(ru->ru_utime)));
   2405     PyStructSequence_SET_ITEM(result, 1,
   2406                               PyFloat_FromDouble(doubletime(ru->ru_stime)));
   2407 #define SET_INT(result, index, value)\
   2408         PyStructSequence_SET_ITEM(result, index, PyInt_FromLong(value))
   2409     SET_INT(result, 2, ru->ru_maxrss);
   2410     SET_INT(result, 3, ru->ru_ixrss);
   2411     SET_INT(result, 4, ru->ru_idrss);
   2412     SET_INT(result, 5, ru->ru_isrss);
   2413     SET_INT(result, 6, ru->ru_minflt);
   2414     SET_INT(result, 7, ru->ru_majflt);
   2415     SET_INT(result, 8, ru->ru_nswap);
   2416     SET_INT(result, 9, ru->ru_inblock);
   2417     SET_INT(result, 10, ru->ru_oublock);
   2418     SET_INT(result, 11, ru->ru_msgsnd);
   2419     SET_INT(result, 12, ru->ru_msgrcv);
   2420     SET_INT(result, 13, ru->ru_nsignals);
   2421     SET_INT(result, 14, ru->ru_nvcsw);
   2422     SET_INT(result, 15, ru->ru_nivcsw);
   2423 #undef SET_INT
   2424 
   2425     if (PyErr_Occurred()) {
   2426         Py_DECREF(result);
   2427         return NULL;
   2428     }
   2429 
   2430     return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
   2431 }
   2432 #endif /* HAVE_WAIT3 || HAVE_WAIT4 */
   2433 
   2434 #ifdef HAVE_WAIT3
   2435 PyDoc_STRVAR(edk2_wait3__doc__,
   2436 "wait3(options) -> (pid, status, rusage)\n\n\
   2437 Wait for completion of a child process.");
   2438 
   2439 static PyObject *
   2440 edk2_wait3(PyObject *self, PyObject *args)
   2441 {
   2442     pid_t pid;
   2443     int options;
   2444     struct rusage ru;
   2445     WAIT_TYPE status;
   2446     WAIT_STATUS_INT(status) = 0;
   2447 
   2448     if (!PyArg_ParseTuple(args, "i:wait3", &options))
   2449         return NULL;
   2450 
   2451     Py_BEGIN_ALLOW_THREADS
   2452     pid = wait3(&status, options, &ru);
   2453     Py_END_ALLOW_THREADS
   2454 
   2455     return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
   2456 }
   2457 #endif /* HAVE_WAIT3 */
   2458 
   2459 #ifdef HAVE_WAIT4
   2460 PyDoc_STRVAR(edk2_wait4__doc__,
   2461 "wait4(pid, options) -> (pid, status, rusage)\n\n\
   2462 Wait for completion of a given child process.");
   2463 
   2464 static PyObject *
   2465 edk2_wait4(PyObject *self, PyObject *args)
   2466 {
   2467     pid_t pid;
   2468     int options;
   2469     struct rusage ru;
   2470     WAIT_TYPE status;
   2471     WAIT_STATUS_INT(status) = 0;
   2472 
   2473     if (!PyArg_ParseTuple(args, PARSE_PID "i:wait4", &pid, &options))
   2474         return NULL;
   2475 
   2476     Py_BEGIN_ALLOW_THREADS
   2477     pid = wait4(pid, &status, options, &ru);
   2478     Py_END_ALLOW_THREADS
   2479 
   2480     return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
   2481 }
   2482 #endif /* HAVE_WAIT4 */
   2483 
   2484 #ifdef HAVE_WAITPID
   2485 PyDoc_STRVAR(edk2_waitpid__doc__,
   2486 "waitpid(pid, options) -> (pid, status)\n\n\
   2487 Wait for completion of a given child process.");
   2488 
   2489 static PyObject *
   2490 edk2_waitpid(PyObject *self, PyObject *args)
   2491 {
   2492     pid_t pid;
   2493     int options;
   2494     WAIT_TYPE status;
   2495     WAIT_STATUS_INT(status) = 0;
   2496 
   2497     if (!PyArg_ParseTuple(args, PARSE_PID "i:waitpid", &pid, &options))
   2498         return NULL;
   2499     Py_BEGIN_ALLOW_THREADS
   2500     pid = waitpid(pid, &status, options);
   2501     Py_END_ALLOW_THREADS
   2502     if (pid == -1)
   2503         return edk2_error();
   2504 
   2505     return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
   2506 }
   2507 
   2508 #elif defined(HAVE_CWAIT)
   2509 
   2510 /* MS C has a variant of waitpid() that's usable for most purposes. */
   2511 PyDoc_STRVAR(edk2_waitpid__doc__,
   2512 "waitpid(pid, options) -> (pid, status << 8)\n\n"
   2513 "Wait for completion of a given process.  options is ignored on Windows.");
   2514 
   2515 static PyObject *
   2516 edk2_waitpid(PyObject *self, PyObject *args)
   2517 {
   2518     Py_intptr_t pid;
   2519     int status, options;
   2520 
   2521     if (!PyArg_ParseTuple(args, PARSE_PID "i:waitpid", &pid, &options))
   2522         return NULL;
   2523     Py_BEGIN_ALLOW_THREADS
   2524     pid = _cwait(&status, pid, options);
   2525     Py_END_ALLOW_THREADS
   2526     if (pid == -1)
   2527         return edk2_error();
   2528 
   2529     /* shift the status left a byte so this is more like the POSIX waitpid */
   2530     return Py_BuildValue("Ni", PyLong_FromPid(pid), status << 8);
   2531 }
   2532 #endif /* HAVE_WAITPID || HAVE_CWAIT */
   2533 
   2534 #ifdef HAVE_WAIT
   2535 PyDoc_STRVAR(edk2_wait__doc__,
   2536 "wait() -> (pid, status)\n\n\
   2537 Wait for completion of a child process.");
   2538 
   2539 static PyObject *
   2540 edk2_wait(PyObject *self, PyObject *noargs)
   2541 {
   2542     pid_t pid;
   2543     WAIT_TYPE status;
   2544     WAIT_STATUS_INT(status) = 0;
   2545 
   2546     Py_BEGIN_ALLOW_THREADS
   2547     pid = wait(&status);
   2548     Py_END_ALLOW_THREADS
   2549     if (pid == -1)
   2550         return edk2_error();
   2551 
   2552     return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
   2553 }
   2554 #endif
   2555 
   2556 
   2557 PyDoc_STRVAR(edk2_lstat__doc__,
   2558 "lstat(path) -> stat result\n\n\
   2559 Like stat(path), but do not follow symbolic links.");
   2560 
   2561 static PyObject *
   2562 edk2_lstat(PyObject *self, PyObject *args)
   2563 {
   2564 #ifdef HAVE_LSTAT
   2565     return edk2_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
   2566 #else /* !HAVE_LSTAT */
   2567     return edk2_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
   2568 #endif /* !HAVE_LSTAT */
   2569 }
   2570 
   2571 
   2572 #ifdef HAVE_READLINK
   2573 PyDoc_STRVAR(edk2_readlink__doc__,
   2574 "readlink(path) -> path\n\n\
   2575 Return a string representing the path to which the symbolic link points.");
   2576 
   2577 static PyObject *
   2578 edk2_readlink(PyObject *self, PyObject *args)
   2579 {
   2580     PyObject* v;
   2581     char buf[MAXPATHLEN];
   2582     char *path;
   2583     int n;
   2584 #ifdef Py_USING_UNICODE
   2585     int arg_is_unicode = 0;
   2586 #endif
   2587 
   2588     if (!PyArg_ParseTuple(args, "et:readlink",
   2589                           Py_FileSystemDefaultEncoding, &path))
   2590         return NULL;
   2591 #ifdef Py_USING_UNICODE
   2592     v = PySequence_GetItem(args, 0);
   2593     if (v == NULL) {
   2594         PyMem_Free(path);
   2595         return NULL;
   2596     }
   2597 
   2598     if (PyUnicode_Check(v)) {
   2599         arg_is_unicode = 1;
   2600     }
   2601     Py_DECREF(v);
   2602 #endif
   2603 
   2604     Py_BEGIN_ALLOW_THREADS
   2605     n = readlink(path, buf, (int) sizeof buf);
   2606     Py_END_ALLOW_THREADS
   2607     if (n < 0)
   2608         return edk2_error_with_allocated_filename(path);
   2609 
   2610     PyMem_Free(path);
   2611     v = PyString_FromStringAndSize(buf, n);
   2612 #ifdef Py_USING_UNICODE
   2613     if (arg_is_unicode) {
   2614         PyObject *w;
   2615 
   2616         w = PyUnicode_FromEncodedObject(v,
   2617                                         Py_FileSystemDefaultEncoding,
   2618                                         "strict");
   2619         if (w != NULL) {
   2620             Py_DECREF(v);
   2621             v = w;
   2622         }
   2623         else {
   2624             /* fall back to the original byte string, as
   2625                discussed in patch #683592 */
   2626             PyErr_Clear();
   2627         }
   2628     }
   2629 #endif
   2630     return v;
   2631 }
   2632 #endif /* HAVE_READLINK */
   2633 
   2634 
   2635 #ifdef HAVE_SYMLINK
   2636 PyDoc_STRVAR(edk2_symlink__doc__,
   2637 "symlink(src, dst)\n\n\
   2638 Create a symbolic link pointing to src named dst.");
   2639 
   2640 static PyObject *
   2641 edk2_symlink(PyObject *self, PyObject *args)
   2642 {
   2643     return edk2_2str(args, "etet:symlink", symlink);
   2644 }
   2645 #endif /* HAVE_SYMLINK */
   2646 
   2647 
   2648 #ifdef HAVE_TIMES
   2649 #define NEED_TICKS_PER_SECOND
   2650 static long ticks_per_second = -1;
   2651 static PyObject *
   2652 edk2_times(PyObject *self, PyObject *noargs)
   2653 {
   2654     struct tms t;
   2655     clock_t c;
   2656     errno = 0;
   2657     c = times(&t);
   2658     if (c == (clock_t) -1)
   2659         return edk2_error();
   2660     return Py_BuildValue("ddddd",
   2661                          (double)t.tms_utime / ticks_per_second,
   2662                          (double)t.tms_stime / ticks_per_second,
   2663                          (double)t.tms_cutime / ticks_per_second,
   2664                          (double)t.tms_cstime / ticks_per_second,
   2665                          (double)c / ticks_per_second);
   2666 }
   2667 #endif /* HAVE_TIMES */
   2668 
   2669 
   2670 #ifdef HAVE_TIMES
   2671 PyDoc_STRVAR(edk2_times__doc__,
   2672 "times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
   2673 Return a tuple of floating point numbers indicating process times.");
   2674 #endif
   2675 
   2676 
   2677 #ifdef HAVE_GETSID
   2678 PyDoc_STRVAR(edk2_getsid__doc__,
   2679 "getsid(pid) -> sid\n\n\
   2680 Call the system call getsid().");
   2681 
   2682 static PyObject *
   2683 edk2_getsid(PyObject *self, PyObject *args)
   2684 {
   2685     pid_t pid;
   2686     int sid;
   2687     if (!PyArg_ParseTuple(args, PARSE_PID ":getsid", &pid))
   2688         return NULL;
   2689     sid = getsid(pid);
   2690     if (sid < 0)
   2691         return edk2_error();
   2692     return PyInt_FromLong((long)sid);
   2693 }
   2694 #endif /* HAVE_GETSID */
   2695 
   2696 
   2697 #ifdef HAVE_SETSID
   2698 PyDoc_STRVAR(edk2_setsid__doc__,
   2699 "setsid()\n\n\
   2700 Call the system call setsid().");
   2701 
   2702 static PyObject *
   2703 edk2_setsid(PyObject *self, PyObject *noargs)
   2704 {
   2705     if (setsid() < 0)
   2706         return edk2_error();
   2707     Py_INCREF(Py_None);
   2708     return Py_None;
   2709 }
   2710 #endif /* HAVE_SETSID */
   2711 
   2712 #ifdef HAVE_SETPGID
   2713 PyDoc_STRVAR(edk2_setpgid__doc__,
   2714 "setpgid(pid, pgrp)\n\n\
   2715 Call the system call setpgid().");
   2716 
   2717 static PyObject *
   2718 edk2_setpgid(PyObject *self, PyObject *args)
   2719 {
   2720     pid_t pid;
   2721     int pgrp;
   2722     if (!PyArg_ParseTuple(args, PARSE_PID "i:setpgid", &pid, &pgrp))
   2723         return NULL;
   2724     if (setpgid(pid, pgrp) < 0)
   2725         return edk2_error();
   2726     Py_INCREF(Py_None);
   2727     return Py_None;
   2728 }
   2729 #endif /* HAVE_SETPGID */
   2730 
   2731 
   2732 #ifdef HAVE_TCGETPGRP
   2733 PyDoc_STRVAR(edk2_tcgetpgrp__doc__,
   2734 "tcgetpgrp(fd) -> pgid\n\n\
   2735 Return the process group associated with the terminal given by a fd.");
   2736 
   2737 static PyObject *
   2738 edk2_tcgetpgrp(PyObject *self, PyObject *args)
   2739 {
   2740     int fd;
   2741     pid_t pgid;
   2742     if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
   2743         return NULL;
   2744     pgid = tcgetpgrp(fd);
   2745     if (pgid < 0)
   2746         return edk2_error();
   2747     return PyLong_FromPid(pgid);
   2748 }
   2749 #endif /* HAVE_TCGETPGRP */
   2750 
   2751 
   2752 #ifdef HAVE_TCSETPGRP
   2753 PyDoc_STRVAR(edk2_tcsetpgrp__doc__,
   2754 "tcsetpgrp(fd, pgid)\n\n\
   2755 Set the process group associated with the terminal given by a fd.");
   2756 
   2757 static PyObject *
   2758 edk2_tcsetpgrp(PyObject *self, PyObject *args)
   2759 {
   2760     int fd;
   2761     pid_t pgid;
   2762     if (!PyArg_ParseTuple(args, "i" PARSE_PID ":tcsetpgrp", &fd, &pgid))
   2763         return NULL;
   2764     if (tcsetpgrp(fd, pgid) < 0)
   2765         return edk2_error();
   2766     Py_INCREF(Py_None);
   2767     return Py_None;
   2768 }
   2769 #endif /* HAVE_TCSETPGRP */
   2770 
   2771 /* Functions acting on file descriptors */
   2772 
   2773 PyDoc_STRVAR(edk2_open__doc__,
   2774 "open(filename, flag [, mode=0777]) -> fd\n\n\
   2775 Open a file (for low level IO).");
   2776 
   2777 static PyObject *
   2778 edk2_open(PyObject *self, PyObject *args)
   2779 {
   2780     char *file = NULL;
   2781     int flag;
   2782     int mode = 0777;
   2783     int fd;
   2784 
   2785     if (!PyArg_ParseTuple(args, "eti|i",
   2786                           Py_FileSystemDefaultEncoding, &file,
   2787                           &flag, &mode))
   2788         return NULL;
   2789 
   2790     Py_BEGIN_ALLOW_THREADS
   2791     fd = open(file, flag, mode);
   2792     Py_END_ALLOW_THREADS
   2793     if (fd < 0)
   2794         return edk2_error_with_allocated_filename(file);
   2795     PyMem_Free(file);
   2796     return PyInt_FromLong((long)fd);
   2797 }
   2798 
   2799 
   2800 PyDoc_STRVAR(edk2_close__doc__,
   2801 "close(fd)\n\n\
   2802 Close a file descriptor (for low level IO).");
   2803 
   2804 static PyObject *
   2805 edk2_close(PyObject *self, PyObject *args)
   2806 {
   2807     int fd, res;
   2808     if (!PyArg_ParseTuple(args, "i:close", &fd))
   2809         return NULL;
   2810     if (!_PyVerify_fd(fd))
   2811         return edk2_error();
   2812     Py_BEGIN_ALLOW_THREADS
   2813     res = close(fd);
   2814     Py_END_ALLOW_THREADS
   2815     if (res < 0)
   2816         return edk2_error();
   2817     Py_INCREF(Py_None);
   2818     return Py_None;
   2819 }
   2820 
   2821 
   2822 PyDoc_STRVAR(edk2_closerange__doc__,
   2823 "closerange(fd_low, fd_high)\n\n\
   2824 Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
   2825 
   2826 static PyObject *
   2827 edk2_closerange(PyObject *self, PyObject *args)
   2828 {
   2829     int fd_from, fd_to, i;
   2830     if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
   2831         return NULL;
   2832     Py_BEGIN_ALLOW_THREADS
   2833     for (i = fd_from; i < fd_to; i++)
   2834         if (_PyVerify_fd(i))
   2835             close(i);
   2836     Py_END_ALLOW_THREADS
   2837     Py_RETURN_NONE;
   2838 }
   2839 
   2840 
   2841 PyDoc_STRVAR(edk2_dup__doc__,
   2842 "dup(fd) -> fd2\n\n\
   2843 Return a duplicate of a file descriptor.");
   2844 
   2845 static PyObject *
   2846 edk2_dup(PyObject *self, PyObject *args)
   2847 {
   2848     int fd;
   2849     if (!PyArg_ParseTuple(args, "i:dup", &fd))
   2850         return NULL;
   2851     if (!_PyVerify_fd(fd))
   2852         return edk2_error();
   2853     Py_BEGIN_ALLOW_THREADS
   2854     fd = dup(fd);
   2855     Py_END_ALLOW_THREADS
   2856     if (fd < 0)
   2857         return edk2_error();
   2858     return PyInt_FromLong((long)fd);
   2859 }
   2860 
   2861 
   2862 PyDoc_STRVAR(edk2_dup2__doc__,
   2863 "dup2(old_fd, new_fd)\n\n\
   2864 Duplicate file descriptor.");
   2865 
   2866 static PyObject *
   2867 edk2_dup2(PyObject *self, PyObject *args)
   2868 {
   2869     int fd, fd2, res;
   2870     if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
   2871         return NULL;
   2872     if (!_PyVerify_fd_dup2(fd, fd2))
   2873         return edk2_error();
   2874     Py_BEGIN_ALLOW_THREADS
   2875     res = dup2(fd, fd2);
   2876     Py_END_ALLOW_THREADS
   2877     if (res < 0)
   2878         return edk2_error();
   2879     Py_INCREF(Py_None);
   2880     return Py_None;
   2881 }
   2882 
   2883 
   2884 PyDoc_STRVAR(edk2_lseek__doc__,
   2885 "lseek(fd, pos, how) -> newpos\n\n\
   2886 Set the current position of a file descriptor.");
   2887 
   2888 static PyObject *
   2889 edk2_lseek(PyObject *self, PyObject *args)
   2890 {
   2891     int fd, how;
   2892     off_t pos, res;
   2893     PyObject *posobj;
   2894     if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
   2895         return NULL;
   2896 #ifdef SEEK_SET
   2897     /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
   2898     switch (how) {
   2899     case 0: how = SEEK_SET; break;
   2900     case 1: how = SEEK_CUR; break;
   2901     case 2: how = SEEK_END; break;
   2902     }
   2903 #endif /* SEEK_END */
   2904 
   2905 #if !defined(HAVE_LARGEFILE_SUPPORT)
   2906     pos = PyInt_AsLong(posobj);
   2907 #else
   2908     pos = PyLong_Check(posobj) ?
   2909         PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
   2910 #endif
   2911     if (PyErr_Occurred())
   2912         return NULL;
   2913 
   2914     if (!_PyVerify_fd(fd))
   2915         return edk2_error();
   2916     Py_BEGIN_ALLOW_THREADS
   2917     res = lseek(fd, pos, how);
   2918     Py_END_ALLOW_THREADS
   2919     if (res < 0)
   2920         return edk2_error();
   2921 
   2922 #if !defined(HAVE_LARGEFILE_SUPPORT)
   2923     return PyInt_FromLong(res);
   2924 #else
   2925     return PyLong_FromLongLong(res);
   2926 #endif
   2927 }
   2928 
   2929 
   2930 PyDoc_STRVAR(edk2_read__doc__,
   2931 "read(fd, buffersize) -> string\n\n\
   2932 Read a file descriptor.");
   2933 
   2934 static PyObject *
   2935 edk2_read(PyObject *self, PyObject *args)
   2936 {
   2937     int fd, size, n;
   2938     PyObject *buffer;
   2939     if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
   2940         return NULL;
   2941     if (size < 0) {
   2942         errno = EINVAL;
   2943         return edk2_error();
   2944     }
   2945     buffer = PyString_FromStringAndSize((char *)NULL, size);
   2946     if (buffer == NULL)
   2947         return NULL;
   2948     if (!_PyVerify_fd(fd)) {
   2949         Py_DECREF(buffer);
   2950         return edk2_error();
   2951     }
   2952     Py_BEGIN_ALLOW_THREADS
   2953     n = read(fd, PyString_AsString(buffer), size);
   2954     Py_END_ALLOW_THREADS
   2955     if (n < 0) {
   2956         Py_DECREF(buffer);
   2957         return edk2_error();
   2958     }
   2959     if (n != size)
   2960         _PyString_Resize(&buffer, n);
   2961     return buffer;
   2962 }
   2963 
   2964 
   2965 PyDoc_STRVAR(edk2_write__doc__,
   2966 "write(fd, string) -> byteswritten\n\n\
   2967 Write a string to a file descriptor.");
   2968 
   2969 static PyObject *
   2970 edk2_write(PyObject *self, PyObject *args)
   2971 {
   2972     Py_buffer pbuf;
   2973     int fd;
   2974     Py_ssize_t size;
   2975 
   2976     if (!PyArg_ParseTuple(args, "is*:write", &fd, &pbuf))
   2977         return NULL;
   2978     if (!_PyVerify_fd(fd)) {
   2979         PyBuffer_Release(&pbuf);
   2980         return edk2_error();
   2981     }
   2982     Py_BEGIN_ALLOW_THREADS
   2983     size = write(fd, pbuf.buf, (size_t)pbuf.len);
   2984     Py_END_ALLOW_THREADS
   2985     PyBuffer_Release(&pbuf);
   2986     if (size < 0)
   2987         return edk2_error();
   2988     return PyInt_FromSsize_t(size);
   2989 }
   2990 
   2991 
   2992 PyDoc_STRVAR(edk2_fstat__doc__,
   2993 "fstat(fd) -> stat result\n\n\
   2994 Like stat(), but for an open file descriptor.");
   2995 
   2996 static PyObject *
   2997 edk2_fstat(PyObject *self, PyObject *args)
   2998 {
   2999     int fd;
   3000     STRUCT_STAT st;
   3001     int res;
   3002     if (!PyArg_ParseTuple(args, "i:fstat", &fd))
   3003         return NULL;
   3004     if (!_PyVerify_fd(fd))
   3005         return edk2_error();
   3006     Py_BEGIN_ALLOW_THREADS
   3007     res = FSTAT(fd, &st);
   3008     Py_END_ALLOW_THREADS
   3009     if (res != 0) {
   3010       return edk2_error();
   3011     }
   3012 
   3013     return _pystat_fromstructstat(&st);
   3014 }
   3015 
   3016 
   3017 PyDoc_STRVAR(edk2_fdopen__doc__,
   3018 "fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
   3019 Return an open file object connected to a file descriptor.");
   3020 
   3021 static PyObject *
   3022 edk2_fdopen(PyObject *self, PyObject *args)
   3023 {
   3024     int fd;
   3025     char *orgmode = "r";
   3026     int bufsize = -1;
   3027     FILE *fp;
   3028     PyObject *f;
   3029     char *mode;
   3030     if (!PyArg_ParseTuple(args, "i|si", &fd, &orgmode, &bufsize))
   3031         return NULL;
   3032 
   3033     /* Sanitize mode.  See fileobject.c */
   3034     mode = PyMem_MALLOC(strlen(orgmode)+3);
   3035     if (!mode) {
   3036         PyErr_NoMemory();
   3037         return NULL;
   3038     }
   3039     strcpy(mode, orgmode);
   3040     if (_PyFile_SanitizeMode(mode)) {
   3041         PyMem_FREE(mode);
   3042         return NULL;
   3043     }
   3044     if (!_PyVerify_fd(fd))
   3045         return edk2_error();
   3046     Py_BEGIN_ALLOW_THREADS
   3047 #if defined(HAVE_FCNTL_H)
   3048     if (mode[0] == 'a') {
   3049         /* try to make sure the O_APPEND flag is set */
   3050         int flags;
   3051         flags = fcntl(fd, F_GETFL);
   3052         if (flags != -1)
   3053             fcntl(fd, F_SETFL, flags | O_APPEND);
   3054         fp = fdopen(fd, mode);
   3055         if (fp == NULL && flags != -1)
   3056             /* restore old mode if fdopen failed */
   3057             fcntl(fd, F_SETFL, flags);
   3058     } else {
   3059         fp = fdopen(fd, mode);
   3060     }
   3061 #else
   3062     fp = fdopen(fd, mode);
   3063 #endif
   3064     Py_END_ALLOW_THREADS
   3065     PyMem_FREE(mode);
   3066     if (fp == NULL)
   3067         return edk2_error();
   3068     f = PyFile_FromFile(fp, "<fdopen>", orgmode, fclose);
   3069     if (f != NULL)
   3070         PyFile_SetBufSize(f, bufsize);
   3071     return f;
   3072 }
   3073 
   3074 PyDoc_STRVAR(edk2_isatty__doc__,
   3075 "isatty(fd) -> bool\n\n\
   3076 Return True if the file descriptor 'fd' is an open file descriptor\n\
   3077 connected to the slave end of a terminal.");
   3078 
   3079 static PyObject *
   3080 edk2_isatty(PyObject *self, PyObject *args)
   3081 {
   3082     int fd;
   3083     if (!PyArg_ParseTuple(args, "i:isatty", &fd))
   3084         return NULL;
   3085     if (!_PyVerify_fd(fd))
   3086         return PyBool_FromLong(0);
   3087     return PyBool_FromLong(isatty(fd));
   3088 }
   3089 
   3090 #ifdef HAVE_PIPE
   3091 PyDoc_STRVAR(edk2_pipe__doc__,
   3092 "pipe() -> (read_end, write_end)\n\n\
   3093 Create a pipe.");
   3094 
   3095 static PyObject *
   3096 edk2_pipe(PyObject *self, PyObject *noargs)
   3097 {
   3098     int fds[2];
   3099     int res;
   3100     Py_BEGIN_ALLOW_THREADS
   3101     res = pipe(fds);
   3102     Py_END_ALLOW_THREADS
   3103     if (res != 0)
   3104         return edk2_error();
   3105     return Py_BuildValue("(ii)", fds[0], fds[1]);
   3106 }
   3107 #endif  /* HAVE_PIPE */
   3108 
   3109 
   3110 #ifdef HAVE_MKFIFO
   3111 PyDoc_STRVAR(edk2_mkfifo__doc__,
   3112 "mkfifo(filename [, mode=0666])\n\n\
   3113 Create a FIFO (a POSIX named pipe).");
   3114 
   3115 static PyObject *
   3116 edk2_mkfifo(PyObject *self, PyObject *args)
   3117 {
   3118     char *filename;
   3119     int mode = 0666;
   3120     int res;
   3121     if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
   3122         return NULL;
   3123     Py_BEGIN_ALLOW_THREADS
   3124     res = mkfifo(filename, mode);
   3125     Py_END_ALLOW_THREADS
   3126     if (res < 0)
   3127         return edk2_error();
   3128     Py_INCREF(Py_None);
   3129     return Py_None;
   3130 }
   3131 #endif
   3132 
   3133 
   3134 #if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
   3135 PyDoc_STRVAR(edk2_mknod__doc__,
   3136 "mknod(filename [, mode=0600, device])\n\n\
   3137 Create a filesystem node (file, device special file or named pipe)\n\
   3138 named filename. mode specifies both the permissions to use and the\n\
   3139 type of node to be created, being combined (bitwise OR) with one of\n\
   3140 S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
   3141 device defines the newly created device special file (probably using\n\
   3142 os.makedev()), otherwise it is ignored.");
   3143 
   3144 
   3145 static PyObject *
   3146 edk2_mknod(PyObject *self, PyObject *args)
   3147 {
   3148     char *filename;
   3149     int mode = 0600;
   3150     int device = 0;
   3151     int res;
   3152     if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
   3153         return NULL;
   3154     Py_BEGIN_ALLOW_THREADS
   3155     res = mknod(filename, mode, device);
   3156     Py_END_ALLOW_THREADS
   3157     if (res < 0)
   3158         return edk2_error();
   3159     Py_INCREF(Py_None);
   3160     return Py_None;
   3161 }
   3162 #endif
   3163 
   3164 #ifdef HAVE_DEVICE_MACROS
   3165 PyDoc_STRVAR(edk2_major__doc__,
   3166 "major(device) -> major number\n\
   3167 Extracts a device major number from a raw device number.");
   3168 
   3169 static PyObject *
   3170 edk2_major(PyObject *self, PyObject *args)
   3171 {
   3172     int device;
   3173     if (!PyArg_ParseTuple(args, "i:major", &device))
   3174         return NULL;
   3175     return PyInt_FromLong((long)major(device));
   3176 }
   3177 
   3178 PyDoc_STRVAR(edk2_minor__doc__,
   3179 "minor(device) -> minor number\n\
   3180 Extracts a device minor number from a raw device number.");
   3181 
   3182 static PyObject *
   3183 edk2_minor(PyObject *self, PyObject *args)
   3184 {
   3185     int device;
   3186     if (!PyArg_ParseTuple(args, "i:minor", &device))
   3187         return NULL;
   3188     return PyInt_FromLong((long)minor(device));
   3189 }
   3190 
   3191 PyDoc_STRVAR(edk2_makedev__doc__,
   3192 "makedev(major, minor) -> device number\n\
   3193 Composes a raw device number from the major and minor device numbers.");
   3194 
   3195 static PyObject *
   3196 edk2_makedev(PyObject *self, PyObject *args)
   3197 {
   3198     int major, minor;
   3199     if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
   3200         return NULL;
   3201     return PyInt_FromLong((long)makedev(major, minor));
   3202 }
   3203 #endif /* device macros */
   3204 
   3205 
   3206 #ifdef HAVE_FTRUNCATE
   3207 PyDoc_STRVAR(edk2_ftruncate__doc__,
   3208 "ftruncate(fd, length)\n\n\
   3209 Truncate a file to a specified length.");
   3210 
   3211 static PyObject *
   3212 edk2_ftruncate(PyObject *self, PyObject *args)
   3213 {
   3214     int fd;
   3215     off_t length;
   3216     int res;
   3217     PyObject *lenobj;
   3218 
   3219     if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
   3220         return NULL;
   3221 
   3222 #if !defined(HAVE_LARGEFILE_SUPPORT)
   3223     length = PyInt_AsLong(lenobj);
   3224 #else
   3225     length = PyLong_Check(lenobj) ?
   3226         PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
   3227 #endif
   3228     if (PyErr_Occurred())
   3229         return NULL;
   3230 
   3231     Py_BEGIN_ALLOW_THREADS
   3232     res = ftruncate(fd, length);
   3233     Py_END_ALLOW_THREADS
   3234     if (res < 0)
   3235         return edk2_error();
   3236     Py_INCREF(Py_None);
   3237     return Py_None;
   3238 }
   3239 #endif
   3240 
   3241 #ifdef HAVE_PUTENV
   3242 PyDoc_STRVAR(edk2_putenv__doc__,
   3243 "putenv(key, value)\n\n\
   3244 Change or add an environment variable.");
   3245 
   3246 /* Save putenv() parameters as values here, so we can collect them when they
   3247  * get re-set with another call for the same key. */
   3248 static PyObject *edk2_putenv_garbage;
   3249 
   3250 static PyObject *
   3251 edk2_putenv(PyObject *self, PyObject *args)
   3252 {
   3253     char *s1, *s2;
   3254     char *newenv;
   3255     PyObject *newstr;
   3256     size_t len;
   3257 
   3258     if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
   3259         return NULL;
   3260 
   3261     /* XXX This can leak memory -- not easy to fix :-( */
   3262     len = strlen(s1) + strlen(s2) + 2;
   3263     /* len includes space for a trailing \0; the size arg to
   3264        PyString_FromStringAndSize does not count that */
   3265     newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
   3266     if (newstr == NULL)
   3267         return PyErr_NoMemory();
   3268     newenv = PyString_AS_STRING(newstr);
   3269     PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
   3270     if (putenv(newenv)) {
   3271         Py_DECREF(newstr);
   3272         edk2_error();
   3273         return NULL;
   3274     }
   3275     /* Install the first arg and newstr in edk2_putenv_garbage;
   3276      * this will cause previous value to be collected.  This has to
   3277      * happen after the real putenv() call because the old value
   3278      * was still accessible until then. */
   3279     if (PyDict_SetItem(edk2_putenv_garbage,
   3280                        PyTuple_GET_ITEM(args, 0), newstr)) {
   3281         /* really not much we can do; just leak */
   3282         PyErr_Clear();
   3283     }
   3284     else {
   3285         Py_DECREF(newstr);
   3286     }
   3287 
   3288     Py_INCREF(Py_None);
   3289     return Py_None;
   3290 }
   3291 #endif /* putenv */
   3292 
   3293 #ifdef HAVE_UNSETENV
   3294 PyDoc_STRVAR(edk2_unsetenv__doc__,
   3295 "unsetenv(key)\n\n\
   3296 Delete an environment variable.");
   3297 
   3298 static PyObject *
   3299 edk2_unsetenv(PyObject *self, PyObject *args)
   3300 {
   3301     char *s1;
   3302 
   3303     if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
   3304         return NULL;
   3305 
   3306     unsetenv(s1);
   3307 
   3308     /* Remove the key from edk2_putenv_garbage;
   3309      * this will cause it to be collected.  This has to
   3310      * happen after the real unsetenv() call because the
   3311      * old value was still accessible until then.
   3312      */
   3313     if (PyDict_DelItem(edk2_putenv_garbage,
   3314                        PyTuple_GET_ITEM(args, 0))) {
   3315         /* really not much we can do; just leak */
   3316         PyErr_Clear();
   3317     }
   3318 
   3319     Py_INCREF(Py_None);
   3320     return Py_None;
   3321 }
   3322 #endif /* unsetenv */
   3323 
   3324 PyDoc_STRVAR(edk2_strerror__doc__,
   3325 "strerror(code) -> string\n\n\
   3326 Translate an error code to a message string.");
   3327 
   3328 static PyObject *
   3329 edk2_strerror(PyObject *self, PyObject *args)
   3330 {
   3331     int code;
   3332     char *message;
   3333     if (!PyArg_ParseTuple(args, "i:strerror", &code))
   3334         return NULL;
   3335     message = strerror(code);
   3336     if (message == NULL) {
   3337         PyErr_SetString(PyExc_ValueError,
   3338                         "strerror() argument out of range");
   3339         return NULL;
   3340     }
   3341     return PyString_FromString(message);
   3342 }
   3343 
   3344 
   3345 #ifdef HAVE_SYS_WAIT_H
   3346 
   3347 #ifdef WCOREDUMP
   3348 PyDoc_STRVAR(edk2_WCOREDUMP__doc__,
   3349 "WCOREDUMP(status) -> bool\n\n\
   3350 Return True if the process returning 'status' was dumped to a core file.");
   3351 
   3352 static PyObject *
   3353 edk2_WCOREDUMP(PyObject *self, PyObject *args)
   3354 {
   3355     WAIT_TYPE status;
   3356     WAIT_STATUS_INT(status) = 0;
   3357 
   3358     if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
   3359         return NULL;
   3360 
   3361     return PyBool_FromLong(WCOREDUMP(status));
   3362 }
   3363 #endif /* WCOREDUMP */
   3364 
   3365 #ifdef WIFCONTINUED
   3366 PyDoc_STRVAR(edk2_WIFCONTINUED__doc__,
   3367 "WIFCONTINUED(status) -> bool\n\n\
   3368 Return True if the process returning 'status' was continued from a\n\
   3369 job control stop.");
   3370 
   3371 static PyObject *
   3372 edk2_WIFCONTINUED(PyObject *self, PyObject *args)
   3373 {
   3374     WAIT_TYPE status;
   3375     WAIT_STATUS_INT(status) = 0;
   3376 
   3377     if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
   3378         return NULL;
   3379 
   3380     return PyBool_FromLong(WIFCONTINUED(status));
   3381 }
   3382 #endif /* WIFCONTINUED */
   3383 
   3384 #ifdef WIFSTOPPED
   3385 PyDoc_STRVAR(edk2_WIFSTOPPED__doc__,
   3386 "WIFSTOPPED(status) -> bool\n\n\
   3387 Return True if the process returning 'status' was stopped.");
   3388 
   3389 static PyObject *
   3390 edk2_WIFSTOPPED(PyObject *self, PyObject *args)
   3391 {
   3392     WAIT_TYPE status;
   3393     WAIT_STATUS_INT(status) = 0;
   3394 
   3395     if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
   3396         return NULL;
   3397 
   3398     return PyBool_FromLong(WIFSTOPPED(status));
   3399 }
   3400 #endif /* WIFSTOPPED */
   3401 
   3402 #ifdef WIFSIGNALED
   3403 PyDoc_STRVAR(edk2_WIFSIGNALED__doc__,
   3404 "WIFSIGNALED(status) -> bool\n\n\
   3405 Return True if the process returning 'status' was terminated by a signal.");
   3406 
   3407 static PyObject *
   3408 edk2_WIFSIGNALED(PyObject *self, PyObject *args)
   3409 {
   3410     WAIT_TYPE status;
   3411     WAIT_STATUS_INT(status) = 0;
   3412 
   3413     if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
   3414         return NULL;
   3415 
   3416     return PyBool_FromLong(WIFSIGNALED(status));
   3417 }
   3418 #endif /* WIFSIGNALED */
   3419 
   3420 #ifdef WIFEXITED
   3421 PyDoc_STRVAR(edk2_WIFEXITED__doc__,
   3422 "WIFEXITED(status) -> bool\n\n\
   3423 Return true if the process returning 'status' exited using the exit()\n\
   3424 system call.");
   3425 
   3426 static PyObject *
   3427 edk2_WIFEXITED(PyObject *self, PyObject *args)
   3428 {
   3429     WAIT_TYPE status;
   3430     WAIT_STATUS_INT(status) = 0;
   3431 
   3432     if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
   3433         return NULL;
   3434 
   3435     return PyBool_FromLong(WIFEXITED(status));
   3436 }
   3437 #endif /* WIFEXITED */
   3438 
   3439 #ifdef WEXITSTATUS
   3440 PyDoc_STRVAR(edk2_WEXITSTATUS__doc__,
   3441 "WEXITSTATUS(status) -> integer\n\n\
   3442 Return the process return code from 'status'.");
   3443 
   3444 static PyObject *
   3445 edk2_WEXITSTATUS(PyObject *self, PyObject *args)
   3446 {
   3447     WAIT_TYPE status;
   3448     WAIT_STATUS_INT(status) = 0;
   3449 
   3450     if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
   3451         return NULL;
   3452 
   3453     return Py_BuildValue("i", WEXITSTATUS(status));
   3454 }
   3455 #endif /* WEXITSTATUS */
   3456 
   3457 #ifdef WTERMSIG
   3458 PyDoc_STRVAR(edk2_WTERMSIG__doc__,
   3459 "WTERMSIG(status) -> integer\n\n\
   3460 Return the signal that terminated the process that provided the 'status'\n\
   3461 value.");
   3462 
   3463 static PyObject *
   3464 edk2_WTERMSIG(PyObject *self, PyObject *args)
   3465 {
   3466     WAIT_TYPE status;
   3467     WAIT_STATUS_INT(status) = 0;
   3468 
   3469     if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
   3470         return NULL;
   3471 
   3472     return Py_BuildValue("i", WTERMSIG(status));
   3473 }
   3474 #endif /* WTERMSIG */
   3475 
   3476 #ifdef WSTOPSIG
   3477 PyDoc_STRVAR(edk2_WSTOPSIG__doc__,
   3478 "WSTOPSIG(status) -> integer\n\n\
   3479 Return the signal that stopped the process that provided\n\
   3480 the 'status' value.");
   3481 
   3482 static PyObject *
   3483 edk2_WSTOPSIG(PyObject *self, PyObject *args)
   3484 {
   3485     WAIT_TYPE status;
   3486     WAIT_STATUS_INT(status) = 0;
   3487 
   3488     if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
   3489         return NULL;
   3490 
   3491     return Py_BuildValue("i", WSTOPSIG(status));
   3492 }
   3493 #endif /* WSTOPSIG */
   3494 
   3495 #endif /* HAVE_SYS_WAIT_H */
   3496 
   3497 
   3498 #if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
   3499 #include <sys/statvfs.h>
   3500 
   3501 static PyObject*
   3502 _pystatvfs_fromstructstatvfs(struct statvfs st) {
   3503     PyObject *v = PyStructSequence_New(&StatVFSResultType);
   3504     if (v == NULL)
   3505         return NULL;
   3506 
   3507 #if !defined(HAVE_LARGEFILE_SUPPORT)
   3508     PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
   3509     PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
   3510     PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
   3511     PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
   3512     PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
   3513     PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
   3514     PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
   3515     PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
   3516     PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
   3517     PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
   3518 #else
   3519     PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
   3520     PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
   3521     PyStructSequence_SET_ITEM(v, 2,
   3522                               PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
   3523     PyStructSequence_SET_ITEM(v, 3,
   3524                               PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
   3525     PyStructSequence_SET_ITEM(v, 4,
   3526                               PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
   3527     PyStructSequence_SET_ITEM(v, 5,
   3528                               PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
   3529     PyStructSequence_SET_ITEM(v, 6,
   3530                               PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
   3531     PyStructSequence_SET_ITEM(v, 7,
   3532                               PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
   3533     PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
   3534     PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
   3535 #endif
   3536 
   3537     return v;
   3538 }
   3539 
   3540 PyDoc_STRVAR(edk2_fstatvfs__doc__,
   3541 "fstatvfs(fd) -> statvfs result\n\n\
   3542 Perform an fstatvfs system call on the given fd.");
   3543 
   3544 static PyObject *
   3545 edk2_fstatvfs(PyObject *self, PyObject *args)
   3546 {
   3547     int fd, res;
   3548     struct statvfs st;
   3549 
   3550     if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
   3551         return NULL;
   3552     Py_BEGIN_ALLOW_THREADS
   3553     res = fstatvfs(fd, &st);
   3554     Py_END_ALLOW_THREADS
   3555     if (res != 0)
   3556         return edk2_error();
   3557 
   3558     return _pystatvfs_fromstructstatvfs(st);
   3559 }
   3560 #endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
   3561 
   3562 
   3563 #if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
   3564 #include <sys/statvfs.h>
   3565 
   3566 PyDoc_STRVAR(edk2_statvfs__doc__,
   3567 "statvfs(path) -> statvfs result\n\n\
   3568 Perform a statvfs system call on the given path.");
   3569 
   3570 static PyObject *
   3571 edk2_statvfs(PyObject *self, PyObject *args)
   3572 {
   3573     char *path;
   3574     int res;
   3575     struct statvfs st;
   3576     if (!PyArg_ParseTuple(args, "s:statvfs", &path))
   3577         return NULL;
   3578     Py_BEGIN_ALLOW_THREADS
   3579     res = statvfs(path, &st);
   3580     Py_END_ALLOW_THREADS
   3581     if (res != 0)
   3582         return edk2_error_with_filename(path);
   3583 
   3584     return _pystatvfs_fromstructstatvfs(st);
   3585 }
   3586 #endif /* HAVE_STATVFS */
   3587 
   3588 
   3589 #ifdef HAVE_TEMPNAM
   3590 PyDoc_STRVAR(edk2_tempnam__doc__,
   3591 "tempnam([dir[, prefix]]) -> string\n\n\
   3592 Return a unique name for a temporary file.\n\
   3593 The directory and a prefix may be specified as strings; they may be omitted\n\
   3594 or None if not needed.");
   3595 
   3596 static PyObject *
   3597 edk2_tempnam(PyObject *self, PyObject *args)
   3598 {
   3599     PyObject *result = NULL;
   3600     char *dir = NULL;
   3601     char *pfx = NULL;
   3602     char *name;
   3603 
   3604     if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
   3605     return NULL;
   3606 
   3607     if (PyErr_Warn(PyExc_RuntimeWarning,
   3608                    "tempnam is a potential security risk to your program") < 0)
   3609         return NULL;
   3610 
   3611     if (PyErr_WarnPy3k("tempnam has been removed in 3.x; "
   3612                        "use the tempfile module", 1) < 0)
   3613         return NULL;
   3614 
   3615     name = tempnam(dir, pfx);
   3616     if (name == NULL)
   3617         return PyErr_NoMemory();
   3618     result = PyString_FromString(name);
   3619     free(name);
   3620     return result;
   3621 }
   3622 #endif
   3623 
   3624 
   3625 #ifdef HAVE_TMPFILE
   3626 PyDoc_STRVAR(edk2_tmpfile__doc__,
   3627 "tmpfile() -> file object\n\n\
   3628 Create a temporary file with no directory entries.");
   3629 
   3630 static PyObject *
   3631 edk2_tmpfile(PyObject *self, PyObject *noargs)
   3632 {
   3633     FILE *fp;
   3634 
   3635     if (PyErr_WarnPy3k("tmpfile has been removed in 3.x; "
   3636                        "use the tempfile module", 1) < 0)
   3637         return NULL;
   3638 
   3639     fp = tmpfile();
   3640     if (fp == NULL)
   3641         return edk2_error();
   3642     return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
   3643 }
   3644 #endif
   3645 
   3646 
   3647 #ifdef HAVE_TMPNAM
   3648 PyDoc_STRVAR(edk2_tmpnam__doc__,
   3649 "tmpnam() -> string\n\n\
   3650 Return a unique name for a temporary file.");
   3651 
   3652 static PyObject *
   3653 edk2_tmpnam(PyObject *self, PyObject *noargs)
   3654 {
   3655     char buffer[L_tmpnam];
   3656     char *name;
   3657 
   3658     if (PyErr_Warn(PyExc_RuntimeWarning,
   3659                    "tmpnam is a potential security risk to your program") < 0)
   3660         return NULL;
   3661 
   3662     if (PyErr_WarnPy3k("tmpnam has been removed in 3.x; "
   3663                        "use the tempfile module", 1) < 0)
   3664         return NULL;
   3665 
   3666 #ifdef USE_TMPNAM_R
   3667     name = tmpnam_r(buffer);
   3668 #else
   3669     name = tmpnam(buffer);
   3670 #endif
   3671     if (name == NULL) {
   3672         PyObject *err = Py_BuildValue("is", 0,
   3673 #ifdef USE_TMPNAM_R
   3674                                       "unexpected NULL from tmpnam_r"
   3675 #else
   3676                                       "unexpected NULL from tmpnam"
   3677 #endif
   3678                                       );
   3679         PyErr_SetObject(PyExc_OSError, err);
   3680         Py_XDECREF(err);
   3681         return NULL;
   3682     }
   3683     return PyString_FromString(buffer);
   3684 }
   3685 #endif
   3686 
   3687 PyDoc_STRVAR(edk2_abort__doc__,
   3688 "abort() -> does not return!\n\n\
   3689 Abort the interpreter immediately.  This 'dumps core' or otherwise fails\n\
   3690 in the hardest way possible on the hosting operating system.");
   3691 
   3692 static PyObject *
   3693 edk2_abort(PyObject *self, PyObject *noargs)
   3694 {
   3695     abort();
   3696     /*NOTREACHED*/
   3697     Py_FatalError("abort() called from Python code didn't abort!");
   3698     return NULL;
   3699 }
   3700 
   3701 static PyMethodDef edk2_methods[] = {
   3702     {"access",          edk2_access,     METH_VARARGS, edk2_access__doc__},
   3703 #ifdef HAVE_TTYNAME
   3704     {"ttyname",         edk2_ttyname, METH_VARARGS, edk2_ttyname__doc__},
   3705 #endif
   3706     {"chdir",           edk2_chdir,      METH_VARARGS, edk2_chdir__doc__},
   3707 #ifdef HAVE_CHFLAGS
   3708     {"chflags",         edk2_chflags, METH_VARARGS, edk2_chflags__doc__},
   3709 #endif /* HAVE_CHFLAGS */
   3710     {"chmod",           edk2_chmod,      METH_VARARGS, edk2_chmod__doc__},
   3711 #ifdef HAVE_FCHMOD
   3712     {"fchmod",          edk2_fchmod, METH_VARARGS, edk2_fchmod__doc__},
   3713 #endif /* HAVE_FCHMOD */
   3714 #ifdef HAVE_CHOWN
   3715     {"chown",           edk2_chown, METH_VARARGS, edk2_chown__doc__},
   3716 #endif /* HAVE_CHOWN */
   3717 #ifdef HAVE_LCHMOD
   3718     {"lchmod",          edk2_lchmod, METH_VARARGS, edk2_lchmod__doc__},
   3719 #endif /* HAVE_LCHMOD */
   3720 #ifdef HAVE_FCHOWN
   3721     {"fchown",          edk2_fchown, METH_VARARGS, edk2_fchown__doc__},
   3722 #endif /* HAVE_FCHOWN */
   3723 #ifdef HAVE_LCHFLAGS
   3724     {"lchflags",        edk2_lchflags, METH_VARARGS, edk2_lchflags__doc__},
   3725 #endif /* HAVE_LCHFLAGS */
   3726 #ifdef HAVE_LCHOWN
   3727     {"lchown",          edk2_lchown, METH_VARARGS, edk2_lchown__doc__},
   3728 #endif /* HAVE_LCHOWN */
   3729 #ifdef HAVE_CHROOT
   3730     {"chroot",          edk2_chroot, METH_VARARGS, edk2_chroot__doc__},
   3731 #endif
   3732 #ifdef HAVE_CTERMID
   3733     {"ctermid",         edk2_ctermid, METH_NOARGS, edk2_ctermid__doc__},
   3734 #endif
   3735 #ifdef HAVE_GETCWD
   3736     {"getcwd",          edk2_getcwd,     METH_NOARGS,  edk2_getcwd__doc__},
   3737 #ifdef Py_USING_UNICODE
   3738     {"getcwdu",         edk2_getcwdu,    METH_NOARGS,  edk2_getcwdu__doc__},
   3739 #endif
   3740 #endif
   3741 #ifdef HAVE_LINK
   3742     {"link",            edk2_link, METH_VARARGS, edk2_link__doc__},
   3743 #endif /* HAVE_LINK */
   3744     {"listdir",         edk2_listdir,    METH_VARARGS, edk2_listdir__doc__},
   3745     {"lstat",           edk2_lstat,      METH_VARARGS, edk2_lstat__doc__},
   3746     {"mkdir",           edk2_mkdir,      METH_VARARGS, edk2_mkdir__doc__},
   3747 #ifdef HAVE_NICE
   3748     {"nice",            edk2_nice, METH_VARARGS, edk2_nice__doc__},
   3749 #endif /* HAVE_NICE */
   3750 #ifdef HAVE_READLINK
   3751     {"readlink",        edk2_readlink, METH_VARARGS, edk2_readlink__doc__},
   3752 #endif /* HAVE_READLINK */
   3753     {"rename",          edk2_rename,     METH_VARARGS, edk2_rename__doc__},
   3754     {"rmdir",           edk2_rmdir,      METH_VARARGS, edk2_rmdir__doc__},
   3755     {"stat",            edk2_stat,       METH_VARARGS, edk2_stat__doc__},
   3756     //{"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
   3757 #ifdef HAVE_SYMLINK
   3758     {"symlink",         edk2_symlink, METH_VARARGS, edk2_symlink__doc__},
   3759 #endif /* HAVE_SYMLINK */
   3760 #ifdef HAVE_SYSTEM
   3761     {"system",          edk2_system, METH_VARARGS, edk2_system__doc__},
   3762 #endif
   3763     {"umask",           edk2_umask,      METH_VARARGS, edk2_umask__doc__},
   3764 #ifdef HAVE_UNAME
   3765     {"uname",           edk2_uname, METH_NOARGS, edk2_uname__doc__},
   3766 #endif /* HAVE_UNAME */
   3767     {"unlink",          edk2_unlink,     METH_VARARGS, edk2_unlink__doc__},
   3768     {"remove",          edk2_unlink,     METH_VARARGS, edk2_remove__doc__},
   3769     {"utime",           edk2_utime,      METH_VARARGS, edk2_utime__doc__},
   3770 #ifdef HAVE_TIMES
   3771     {"times",           edk2_times, METH_NOARGS, edk2_times__doc__},
   3772 #endif /* HAVE_TIMES */
   3773     {"_exit",           edk2__exit,      METH_VARARGS, edk2__exit__doc__},
   3774 #ifdef HAVE_EXECV
   3775     {"execv",           edk2_execv, METH_VARARGS, edk2_execv__doc__},
   3776     {"execve",          edk2_execve, METH_VARARGS, edk2_execve__doc__},
   3777 #endif /* HAVE_EXECV */
   3778 #ifdef HAVE_SPAWNV
   3779     {"spawnv",          edk2_spawnv, METH_VARARGS, edk2_spawnv__doc__},
   3780     {"spawnve",         edk2_spawnve, METH_VARARGS, edk2_spawnve__doc__},
   3781 #if defined(PYOS_OS2)
   3782     {"spawnvp",         edk2_spawnvp, METH_VARARGS, edk2_spawnvp__doc__},
   3783     {"spawnvpe",        edk2_spawnvpe, METH_VARARGS, edk2_spawnvpe__doc__},
   3784 #endif /* PYOS_OS2 */
   3785 #endif /* HAVE_SPAWNV */
   3786 #ifdef HAVE_FORK1
   3787     {"fork1",       edk2_fork1, METH_NOARGS, edk2_fork1__doc__},
   3788 #endif /* HAVE_FORK1 */
   3789 #ifdef HAVE_FORK
   3790     {"fork",            edk2_fork, METH_NOARGS, edk2_fork__doc__},
   3791 #endif /* HAVE_FORK */
   3792 #if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
   3793     {"openpty",         edk2_openpty, METH_NOARGS, edk2_openpty__doc__},
   3794 #endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
   3795 #ifdef HAVE_FORKPTY
   3796     {"forkpty",         edk2_forkpty, METH_NOARGS, edk2_forkpty__doc__},
   3797 #endif /* HAVE_FORKPTY */
   3798     {"getpid",          edk2_getpid,     METH_NOARGS,  edk2_getpid__doc__},
   3799 #ifdef HAVE_GETPGRP
   3800     {"getpgrp",         edk2_getpgrp, METH_NOARGS, edk2_getpgrp__doc__},
   3801 #endif /* HAVE_GETPGRP */
   3802 #ifdef HAVE_GETPPID
   3803     {"getppid",         edk2_getppid, METH_NOARGS, edk2_getppid__doc__},
   3804 #endif /* HAVE_GETPPID */
   3805 #ifdef HAVE_GETLOGIN
   3806     {"getlogin",        edk2_getlogin, METH_NOARGS, edk2_getlogin__doc__},
   3807 #endif
   3808 #ifdef HAVE_KILL
   3809     {"kill",            edk2_kill, METH_VARARGS, edk2_kill__doc__},
   3810 #endif /* HAVE_KILL */
   3811 #ifdef HAVE_KILLPG
   3812     {"killpg",          edk2_killpg, METH_VARARGS, edk2_killpg__doc__},
   3813 #endif /* HAVE_KILLPG */
   3814 #ifdef HAVE_PLOCK
   3815     {"plock",           edk2_plock, METH_VARARGS, edk2_plock__doc__},
   3816 #endif /* HAVE_PLOCK */
   3817 #ifdef HAVE_POPEN
   3818     {"popen",           edk2_popen, METH_VARARGS, edk2_popen__doc__},
   3819 #endif /* HAVE_POPEN */
   3820 #ifdef HAVE_SETGROUPS
   3821     {"setgroups",       edk2_setgroups, METH_O, edk2_setgroups__doc__},
   3822 #endif /* HAVE_SETGROUPS */
   3823 #ifdef HAVE_INITGROUPS
   3824     {"initgroups",      edk2_initgroups, METH_VARARGS, edk2_initgroups__doc__},
   3825 #endif /* HAVE_INITGROUPS */
   3826 #ifdef HAVE_GETPGID
   3827     {"getpgid",         edk2_getpgid, METH_VARARGS, edk2_getpgid__doc__},
   3828 #endif /* HAVE_GETPGID */
   3829 #ifdef HAVE_SETPGRP
   3830     {"setpgrp",         edk2_setpgrp, METH_NOARGS, edk2_setpgrp__doc__},
   3831 #endif /* HAVE_SETPGRP */
   3832 #ifdef HAVE_WAIT
   3833     {"wait",            edk2_wait, METH_NOARGS, edk2_wait__doc__},
   3834 #endif /* HAVE_WAIT */
   3835 #ifdef HAVE_WAIT3
   3836     {"wait3",           edk2_wait3, METH_VARARGS, edk2_wait3__doc__},
   3837 #endif /* HAVE_WAIT3 */
   3838 #ifdef HAVE_WAIT4
   3839     {"wait4",           edk2_wait4, METH_VARARGS, edk2_wait4__doc__},
   3840 #endif /* HAVE_WAIT4 */
   3841 #if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
   3842     {"waitpid",         edk2_waitpid, METH_VARARGS, edk2_waitpid__doc__},
   3843 #endif /* HAVE_WAITPID */
   3844 #ifdef HAVE_GETSID
   3845     {"getsid",          edk2_getsid, METH_VARARGS, edk2_getsid__doc__},
   3846 #endif /* HAVE_GETSID */
   3847 #ifdef HAVE_SETSID
   3848     {"setsid",          edk2_setsid, METH_NOARGS, edk2_setsid__doc__},
   3849 #endif /* HAVE_SETSID */
   3850 #ifdef HAVE_SETPGID
   3851     {"setpgid",         edk2_setpgid, METH_VARARGS, edk2_setpgid__doc__},
   3852 #endif /* HAVE_SETPGID */
   3853 #ifdef HAVE_TCGETPGRP
   3854     {"tcgetpgrp",       edk2_tcgetpgrp, METH_VARARGS, edk2_tcgetpgrp__doc__},
   3855 #endif /* HAVE_TCGETPGRP */
   3856 #ifdef HAVE_TCSETPGRP
   3857     {"tcsetpgrp",       edk2_tcsetpgrp, METH_VARARGS, edk2_tcsetpgrp__doc__},
   3858 #endif /* HAVE_TCSETPGRP */
   3859     {"open",            edk2_open,       METH_VARARGS, edk2_open__doc__},
   3860     {"close",           edk2_close,      METH_VARARGS, edk2_close__doc__},
   3861     {"closerange",      edk2_closerange, METH_VARARGS, edk2_closerange__doc__},
   3862     {"dup",             edk2_dup,        METH_VARARGS, edk2_dup__doc__},
   3863     {"dup2",            edk2_dup2,       METH_VARARGS, edk2_dup2__doc__},
   3864     {"lseek",           edk2_lseek,      METH_VARARGS, edk2_lseek__doc__},
   3865     {"read",            edk2_read,       METH_VARARGS, edk2_read__doc__},
   3866     {"write",           edk2_write,      METH_VARARGS, edk2_write__doc__},
   3867     {"fstat",           edk2_fstat,      METH_VARARGS, edk2_fstat__doc__},
   3868     {"fdopen",          edk2_fdopen,     METH_VARARGS, edk2_fdopen__doc__},
   3869     {"isatty",          edk2_isatty,     METH_VARARGS, edk2_isatty__doc__},
   3870 #ifdef HAVE_PIPE
   3871     {"pipe",            edk2_pipe, METH_NOARGS, edk2_pipe__doc__},
   3872 #endif
   3873 #ifdef HAVE_MKFIFO
   3874     {"mkfifo",          edk2_mkfifo, METH_VARARGS, edk2_mkfifo__doc__},
   3875 #endif
   3876 #if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
   3877     {"mknod",           edk2_mknod, METH_VARARGS, edk2_mknod__doc__},
   3878 #endif
   3879 #ifdef HAVE_DEVICE_MACROS
   3880     {"major",           edk2_major, METH_VARARGS, edk2_major__doc__},
   3881     {"minor",           edk2_minor, METH_VARARGS, edk2_minor__doc__},
   3882     {"makedev",         edk2_makedev, METH_VARARGS, edk2_makedev__doc__},
   3883 #endif
   3884 #ifdef HAVE_FTRUNCATE
   3885     {"ftruncate",       edk2_ftruncate, METH_VARARGS, edk2_ftruncate__doc__},
   3886 #endif
   3887 #ifdef HAVE_PUTENV
   3888     {"putenv",          edk2_putenv, METH_VARARGS, edk2_putenv__doc__},
   3889 #endif
   3890 #ifdef HAVE_UNSETENV
   3891     {"unsetenv",        edk2_unsetenv, METH_VARARGS, edk2_unsetenv__doc__},
   3892 #endif
   3893     {"strerror",        edk2_strerror,   METH_VARARGS, edk2_strerror__doc__},
   3894 #ifdef HAVE_FCHDIR
   3895     {"fchdir",          edk2_fchdir, METH_O, edk2_fchdir__doc__},
   3896 #endif
   3897 #ifdef HAVE_FSYNC
   3898     {"fsync",       edk2_fsync, METH_O, edk2_fsync__doc__},
   3899 #endif
   3900 #ifdef HAVE_FDATASYNC
   3901     {"fdatasync",   edk2_fdatasync,  METH_O, edk2_fdatasync__doc__},
   3902 #endif
   3903 #ifdef HAVE_SYS_WAIT_H
   3904 #ifdef WCOREDUMP
   3905     {"WCOREDUMP",       edk2_WCOREDUMP, METH_VARARGS, edk2_WCOREDUMP__doc__},
   3906 #endif /* WCOREDUMP */
   3907 #ifdef WIFCONTINUED
   3908     {"WIFCONTINUED",edk2_WIFCONTINUED, METH_VARARGS, edk2_WIFCONTINUED__doc__},
   3909 #endif /* WIFCONTINUED */
   3910 #ifdef WIFSTOPPED
   3911     {"WIFSTOPPED",      edk2_WIFSTOPPED, METH_VARARGS, edk2_WIFSTOPPED__doc__},
   3912 #endif /* WIFSTOPPED */
   3913 #ifdef WIFSIGNALED
   3914     {"WIFSIGNALED",     edk2_WIFSIGNALED, METH_VARARGS, edk2_WIFSIGNALED__doc__},
   3915 #endif /* WIFSIGNALED */
   3916 #ifdef WIFEXITED
   3917     {"WIFEXITED",       edk2_WIFEXITED, METH_VARARGS, edk2_WIFEXITED__doc__},
   3918 #endif /* WIFEXITED */
   3919 #ifdef WEXITSTATUS
   3920     {"WEXITSTATUS",     edk2_WEXITSTATUS, METH_VARARGS, edk2_WEXITSTATUS__doc__},
   3921 #endif /* WEXITSTATUS */
   3922 #ifdef WTERMSIG
   3923     {"WTERMSIG",        edk2_WTERMSIG, METH_VARARGS, edk2_WTERMSIG__doc__},
   3924 #endif /* WTERMSIG */
   3925 #ifdef WSTOPSIG
   3926     {"WSTOPSIG",        edk2_WSTOPSIG, METH_VARARGS, edk2_WSTOPSIG__doc__},
   3927 #endif /* WSTOPSIG */
   3928 #endif /* HAVE_SYS_WAIT_H */
   3929 #if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
   3930     {"fstatvfs",        edk2_fstatvfs, METH_VARARGS, edk2_fstatvfs__doc__},
   3931 #endif
   3932 #if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
   3933     {"statvfs",         edk2_statvfs, METH_VARARGS, edk2_statvfs__doc__},
   3934 #endif
   3935 #ifdef HAVE_TMPFILE
   3936     {"tmpfile",         edk2_tmpfile,    METH_NOARGS,  edk2_tmpfile__doc__},
   3937 #endif
   3938 #ifdef HAVE_TEMPNAM
   3939     {"tempnam",         edk2_tempnam,    METH_VARARGS, edk2_tempnam__doc__},
   3940 #endif
   3941 #ifdef HAVE_TMPNAM
   3942     {"tmpnam",          edk2_tmpnam,     METH_NOARGS,  edk2_tmpnam__doc__},
   3943 #endif
   3944 #ifdef HAVE_CONFSTR
   3945     {"confstr",         edk2_confstr, METH_VARARGS, edk2_confstr__doc__},
   3946 #endif
   3947 #ifdef HAVE_SYSCONF
   3948     {"sysconf",         edk2_sysconf, METH_VARARGS, edk2_sysconf__doc__},
   3949 #endif
   3950 #ifdef HAVE_FPATHCONF
   3951     {"fpathconf",       edk2_fpathconf, METH_VARARGS, edk2_fpathconf__doc__},
   3952 #endif
   3953 #ifdef HAVE_PATHCONF
   3954     {"pathconf",        edk2_pathconf, METH_VARARGS, edk2_pathconf__doc__},
   3955 #endif
   3956     {"abort",           edk2_abort,      METH_NOARGS,  edk2_abort__doc__},
   3957 
   3958     {NULL,              NULL}            /* Sentinel */
   3959 };
   3960 
   3961 
   3962 static int
   3963 ins(PyObject *module, char *symbol, long value)
   3964 {
   3965     return PyModule_AddIntConstant(module, symbol, value);
   3966 }
   3967 
   3968 static int
   3969 all_ins(PyObject *d)
   3970 {
   3971 #ifdef F_OK
   3972     if (ins(d, "F_OK", (long)F_OK)) return -1;
   3973 #endif
   3974 #ifdef R_OK
   3975     if (ins(d, "R_OK", (long)R_OK)) return -1;
   3976 #endif
   3977 #ifdef W_OK
   3978     if (ins(d, "W_OK", (long)W_OK)) return -1;
   3979 #endif
   3980 #ifdef X_OK
   3981     if (ins(d, "X_OK", (long)X_OK)) return -1;
   3982 #endif
   3983 #ifdef NGROUPS_MAX
   3984     if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
   3985 #endif
   3986 #ifdef TMP_MAX
   3987     if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
   3988 #endif
   3989 #ifdef WCONTINUED
   3990     if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
   3991 #endif
   3992 #ifdef WNOHANG
   3993     if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
   3994 #endif
   3995 #ifdef WUNTRACED
   3996     if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
   3997 #endif
   3998 #ifdef O_RDONLY
   3999     if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
   4000 #endif
   4001 #ifdef O_WRONLY
   4002     if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
   4003 #endif
   4004 #ifdef O_RDWR
   4005     if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
   4006 #endif
   4007 #ifdef O_NDELAY
   4008     if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
   4009 #endif
   4010 #ifdef O_NONBLOCK
   4011     if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
   4012 #endif
   4013 #ifdef O_APPEND
   4014     if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
   4015 #endif
   4016 #ifdef O_DSYNC
   4017     if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
   4018 #endif
   4019 #ifdef O_RSYNC
   4020     if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
   4021 #endif
   4022 #ifdef O_SYNC
   4023     if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
   4024 #endif
   4025 #ifdef O_NOCTTY
   4026     if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
   4027 #endif
   4028 #ifdef O_CREAT
   4029     if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
   4030 #endif
   4031 #ifdef O_EXCL
   4032     if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
   4033 #endif
   4034 #ifdef O_TRUNC
   4035     if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
   4036 #endif
   4037 #ifdef O_BINARY
   4038     if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
   4039 #endif
   4040 #ifdef O_TEXT
   4041     if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
   4042 #endif
   4043 #ifdef O_LARGEFILE
   4044     if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
   4045 #endif
   4046 #ifdef O_SHLOCK
   4047     if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
   4048 #endif
   4049 #ifdef O_EXLOCK
   4050     if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
   4051 #endif
   4052 
   4053 /* MS Windows */
   4054 #ifdef O_NOINHERIT
   4055     /* Don't inherit in child processes. */
   4056     if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
   4057 #endif
   4058 #ifdef _O_SHORT_LIVED
   4059     /* Optimize for short life (keep in memory). */
   4060     /* MS forgot to define this one with a non-underscore form too. */
   4061     if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
   4062 #endif
   4063 #ifdef O_TEMPORARY
   4064     /* Automatically delete when last handle is closed. */
   4065     if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
   4066 #endif
   4067 #ifdef O_RANDOM
   4068     /* Optimize for random access. */
   4069     if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
   4070 #endif
   4071 #ifdef O_SEQUENTIAL
   4072     /* Optimize for sequential access. */
   4073     if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
   4074 #endif
   4075 
   4076 /* GNU extensions. */
   4077 #ifdef O_ASYNC
   4078     /* Send a SIGIO signal whenever input or output
   4079        becomes available on file descriptor */
   4080     if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
   4081 #endif
   4082 #ifdef O_DIRECT
   4083     /* Direct disk access. */
   4084     if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
   4085 #endif
   4086 #ifdef O_DIRECTORY
   4087     /* Must be a directory.      */
   4088     if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
   4089 #endif
   4090 #ifdef O_NOFOLLOW
   4091     /* Do not follow links.      */
   4092     if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
   4093 #endif
   4094 #ifdef O_NOATIME
   4095     /* Do not update the access time. */
   4096     if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
   4097 #endif
   4098 
   4099     /* These come from sysexits.h */
   4100 #ifdef EX_OK
   4101     if (ins(d, "EX_OK", (long)EX_OK)) return -1;
   4102 #endif /* EX_OK */
   4103 #ifdef EX_USAGE
   4104     if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
   4105 #endif /* EX_USAGE */
   4106 #ifdef EX_DATAERR
   4107     if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
   4108 #endif /* EX_DATAERR */
   4109 #ifdef EX_NOINPUT
   4110     if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
   4111 #endif /* EX_NOINPUT */
   4112 #ifdef EX_NOUSER
   4113     if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
   4114 #endif /* EX_NOUSER */
   4115 #ifdef EX_NOHOST
   4116     if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
   4117 #endif /* EX_NOHOST */
   4118 #ifdef EX_UNAVAILABLE
   4119     if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
   4120 #endif /* EX_UNAVAILABLE */
   4121 #ifdef EX_SOFTWARE
   4122     if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
   4123 #endif /* EX_SOFTWARE */
   4124 #ifdef EX_OSERR
   4125     if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
   4126 #endif /* EX_OSERR */
   4127 #ifdef EX_OSFILE
   4128     if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
   4129 #endif /* EX_OSFILE */
   4130 #ifdef EX_CANTCREAT
   4131     if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
   4132 #endif /* EX_CANTCREAT */
   4133 #ifdef EX_IOERR
   4134     if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
   4135 #endif /* EX_IOERR */
   4136 #ifdef EX_TEMPFAIL
   4137     if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
   4138 #endif /* EX_TEMPFAIL */
   4139 #ifdef EX_PROTOCOL
   4140     if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
   4141 #endif /* EX_PROTOCOL */
   4142 #ifdef EX_NOPERM
   4143     if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
   4144 #endif /* EX_NOPERM */
   4145 #ifdef EX_CONFIG
   4146     if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
   4147 #endif /* EX_CONFIG */
   4148 #ifdef EX_NOTFOUND
   4149     if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
   4150 #endif /* EX_NOTFOUND */
   4151 
   4152 #ifdef HAVE_SPAWNV
   4153     if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
   4154     if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
   4155     if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
   4156     if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
   4157     if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
   4158 #endif
   4159   return 0;
   4160 }
   4161 
   4162 #define INITFUNC initedk2
   4163 #define MODNAME "edk2"
   4164 
   4165 PyMODINIT_FUNC
   4166 INITFUNC(void)
   4167 {
   4168     PyObject *m;
   4169 
   4170 #ifndef UEFI_C_SOURCE
   4171   PyObject *v;
   4172 #endif
   4173 
   4174     m = Py_InitModule3(MODNAME,
   4175                        edk2_methods,
   4176                        edk2__doc__);
   4177     if (m == NULL)
   4178         return;
   4179 
   4180 #ifndef UEFI_C_SOURCE
   4181     /* Initialize environ dictionary */
   4182     v = convertenviron();
   4183     Py_XINCREF(v);
   4184     if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
   4185         return;
   4186     Py_DECREF(v);
   4187 #endif  /* UEFI_C_SOURCE */
   4188 
   4189     if (all_ins(m))
   4190         return;
   4191 
   4192     Py_INCREF(PyExc_OSError);
   4193     PyModule_AddObject(m, "error", PyExc_OSError);
   4194 
   4195 #ifdef HAVE_PUTENV
   4196     if (edk2_putenv_garbage == NULL)
   4197         edk2_putenv_garbage = PyDict_New();
   4198 #endif
   4199 
   4200     if (!initialized) {
   4201         stat_result_desc.name = MODNAME ".stat_result";
   4202         stat_result_desc.fields[2].name = PyStructSequence_UnnamedField;
   4203         stat_result_desc.fields[3].name = PyStructSequence_UnnamedField;
   4204         stat_result_desc.fields[4].name = PyStructSequence_UnnamedField;
   4205         PyStructSequence_InitType(&StatResultType, &stat_result_desc);
   4206         structseq_new = StatResultType.tp_new;
   4207         StatResultType.tp_new = statresult_new;
   4208 
   4209         //statvfs_result_desc.name = MODNAME ".statvfs_result";
   4210         //PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
   4211 #ifdef NEED_TICKS_PER_SECOND
   4212 #  if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
   4213         ticks_per_second = sysconf(_SC_CLK_TCK);
   4214 #  elif defined(HZ)
   4215         ticks_per_second = HZ;
   4216 #  else
   4217         ticks_per_second = 60; /* magic fallback value; may be bogus */
   4218 #  endif
   4219 #endif
   4220     }
   4221     Py_INCREF((PyObject*) &StatResultType);
   4222     PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
   4223     //Py_INCREF((PyObject*) &StatVFSResultType);
   4224     //PyModule_AddObject(m, "statvfs_result",
   4225     //                   (PyObject*) &StatVFSResultType);
   4226     initialized = 1;
   4227 
   4228 }
   4229 
   4230 #ifdef __cplusplus
   4231 }
   4232 #endif
   4233 
   4234 
   4235