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