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