posixmodule.c revision f3f33dcf03eaed3c4e720178f9d69205a66d6a91
1/***********************************************************
2Copyright (c) 2000, BeOpen.com.
3Copyright (c) 1995-2000, Corporation for National Research Initiatives.
4Copyright (c) 1990-1995, Stichting Mathematisch Centrum.
5All rights reserved.
6
7See the file "Misc/COPYRIGHT" for information on usage and
8redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
9******************************************************************/
10
11/* POSIX module implementation */
12
13/* This file is also used for Windows NT and MS-Win.  In that case the module
14   actually calls itself 'nt', not 'posix', and a few functions are
15   either unimplemented or implemented differently.  The source
16   assumes that for Windows NT, the macro 'MS_WIN32' is defined independent
17   of the compiler used.  Different compilers define their own feature
18   test macro, e.g. '__BORLANDC__' or '_MSC_VER'. */
19
20/* See also ../Dos/dosmodule.c */
21
22static char posix__doc__ [] =
23"This module provides access to operating system functionality that is\n\
24standardized by the C Standard and the POSIX standard (a thinly\n\
25disguised Unix interface).  Refer to the library manual and\n\
26corresponding Unix manual entries for more information on calls.";
27
28#include "Python.h"
29
30#if defined(PYOS_OS2)
31#define  INCL_DOS
32#define  INCL_DOSERRORS
33#define  INCL_DOSPROCESS
34#define  INCL_NOPMAPI
35#include <os2.h>
36#endif
37
38#include <sys/types.h>
39#include <sys/stat.h>
40#ifdef HAVE_SYS_WAIT_H
41#include <sys/wait.h>		/* For WNOHANG */
42#endif
43
44#ifdef HAVE_SIGNAL_H
45#include <signal.h>
46#endif
47
48#include "mytime.h"		/* For clock_t on some systems */
49
50#ifdef HAVE_FCNTL_H
51#include <fcntl.h>
52#endif /* HAVE_FCNTL_H */
53
54/* Various compilers have only certain posix functions */
55/* XXX Gosh I wish these were all moved into config.h */
56#if defined(PYCC_VACPP) && defined(PYOS_OS2)
57#include <process.h>
58#else
59#if defined(__WATCOMC__) && !defined(__QNX__)		/* Watcom compiler */
60#define HAVE_GETCWD     1
61#define HAVE_OPENDIR    1
62#define HAVE_SYSTEM	1
63#if defined(__OS2__)
64#define HAVE_EXECV      1
65#define HAVE_WAIT       1
66#endif
67#include <process.h>
68#else
69#ifdef __BORLANDC__		/* Borland compiler */
70#define HAVE_EXECV      1
71#define HAVE_GETCWD     1
72#define HAVE_GETEGID    1
73#define HAVE_GETEUID    1
74#define HAVE_GETGID     1
75#define HAVE_GETPPID    1
76#define HAVE_GETUID     1
77#define HAVE_KILL       1
78#define HAVE_OPENDIR    1
79#define HAVE_PIPE       1
80#define HAVE_POPEN      1
81#define HAVE_SYSTEM	1
82#define HAVE_WAIT       1
83#else
84#ifdef _MSC_VER		/* Microsoft compiler */
85#define HAVE_GETCWD     1
86#ifdef MS_WIN32
87#define HAVE_SPAWNV	1
88#define HAVE_EXECV      1
89#define HAVE_PIPE       1
90#define HAVE_POPEN      1
91#define HAVE_SYSTEM	1
92#else /* 16-bit Windows */
93#endif /* !MS_WIN32 */
94#else			/* all other compilers */
95/* Unix functions that the configure script doesn't check for */
96#define HAVE_EXECV      1
97#define HAVE_FORK       1
98#define HAVE_GETCWD     1
99#define HAVE_GETEGID    1
100#define HAVE_GETEUID    1
101#define HAVE_GETGID     1
102#define HAVE_GETPPID    1
103#define HAVE_GETUID     1
104#define HAVE_KILL       1
105#define HAVE_OPENDIR    1
106#define HAVE_PIPE       1
107#define HAVE_POPEN      1
108#define HAVE_SYSTEM	1
109#define HAVE_WAIT       1
110#define HAVE_TTYNAME	1
111#endif  /* _MSC_VER */
112#endif  /* __BORLANDC__ */
113#endif  /* ! __WATCOMC__ || __QNX__ */
114#endif /* ! __IBMC__ */
115
116#ifndef _MSC_VER
117
118#ifdef HAVE_UNISTD_H
119#include <unistd.h>
120#endif
121
122#ifdef NeXT
123/* NeXT's <unistd.h> and <utime.h> aren't worth much */
124#undef HAVE_UNISTD_H
125#undef HAVE_UTIME_H
126#define HAVE_WAITPID
127/* #undef HAVE_GETCWD */
128#define UNION_WAIT /* This should really be checked for by autoconf */
129#endif
130
131#ifdef HAVE_UNISTD_H
132/* XXX These are for SunOS4.1.3 but shouldn't hurt elsewhere */
133extern int rename();
134extern int pclose();
135extern int lstat();
136extern int symlink();
137extern int fsync();
138#else /* !HAVE_UNISTD_H */
139#if defined(PYCC_VACPP)
140extern int mkdir(char *);
141#else
142#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
143extern int mkdir(const char *);
144#else
145extern int mkdir(const char *, mode_t);
146#endif
147#endif
148#if defined(__IBMC__) || defined(__IBMCPP__)
149extern int chdir(char *);
150extern int rmdir(char *);
151#else
152extern int chdir(const char *);
153extern int rmdir(const char *);
154#endif
155extern int chmod(const char *, mode_t);
156extern int chown(const char *, uid_t, gid_t);
157extern char *getcwd(char *, int);
158extern char *strerror(int);
159extern int link(const char *, const char *);
160extern int rename(const char *, const char *);
161extern int stat(const char *, struct stat *);
162extern int unlink(const char *);
163extern int pclose(FILE *);
164#ifdef HAVE_SYMLINK
165extern int symlink(const char *, const char *);
166#endif /* HAVE_SYMLINK */
167#ifdef HAVE_LSTAT
168extern int lstat(const char *, struct stat *);
169#endif /* HAVE_LSTAT */
170#endif /* !HAVE_UNISTD_H */
171
172#endif /* !_MSC_VER */
173
174#ifdef HAVE_UTIME_H
175#include <utime.h>
176#endif /* HAVE_UTIME_H */
177
178#ifdef HAVE_SYS_UTIME_H
179#include <sys/utime.h>
180#define HAVE_UTIME_H /* pretend we do for the rest of this file */
181#endif /* HAVE_SYS_UTIME_H */
182
183#ifdef HAVE_SYS_TIMES_H
184#include <sys/times.h>
185#endif /* HAVE_SYS_TIMES_H */
186
187#ifdef HAVE_SYS_PARAM_H
188#include <sys/param.h>
189#endif /* HAVE_SYS_PARAM_H */
190
191#ifdef HAVE_SYS_UTSNAME_H
192#include <sys/utsname.h>
193#endif /* HAVE_SYS_UTSNAME_H */
194
195#ifndef MAXPATHLEN
196#define MAXPATHLEN 1024
197#endif /* MAXPATHLEN */
198
199#ifdef HAVE_DIRENT_H
200#include <dirent.h>
201#define NAMLEN(dirent) strlen((dirent)->d_name)
202#else
203#if defined(__WATCOMC__) && !defined(__QNX__)
204#include <direct.h>
205#define NAMLEN(dirent) strlen((dirent)->d_name)
206#else
207#define dirent direct
208#define NAMLEN(dirent) (dirent)->d_namlen
209#endif
210#ifdef HAVE_SYS_NDIR_H
211#include <sys/ndir.h>
212#endif
213#ifdef HAVE_SYS_DIR_H
214#include <sys/dir.h>
215#endif
216#ifdef HAVE_NDIR_H
217#include <ndir.h>
218#endif
219#endif
220
221#ifdef _MSC_VER
222#include <direct.h>
223#include <io.h>
224#include <process.h>
225#define WINDOWS_LEAN_AND_MEAN
226#include <windows.h>
227#ifdef MS_WIN32
228#define popen	_popen
229#define pclose	_pclose
230#else /* 16-bit Windows */
231#include <dos.h>
232#include <ctype.h>
233#endif /* MS_WIN32 */
234#endif /* _MSC_VER */
235
236#if defined(PYCC_VACPP) && defined(PYOS_OS2)
237#include <io.h>
238#endif /* OS2 */
239
240#ifdef UNION_WAIT
241/* Emulate some macros on systems that have a union instead of macros */
242
243#ifndef WIFEXITED
244#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
245#endif
246
247#ifndef WEXITSTATUS
248#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
249#endif
250
251#ifndef WTERMSIG
252#define WTERMSIG(u_wait) ((u_wait).w_termsig)
253#endif
254
255#endif /* UNION_WAIT */
256
257/* Don't use the "_r" form if we don't need it (also, won't have a
258   prototype for it, at least on Solaris -- maybe others as well?). */
259#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
260#define USE_CTERMID_R
261#endif
262
263#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
264#define USE_TMPNAM_R
265#endif
266
267/* choose the appropriate stat and fstat functions and return structs */
268#undef STAT
269#ifdef MS_WIN64
270#	define STAT _stati64
271#	define FSTAT _fstati64
272#	define STRUCT_STAT struct _stati64
273#else
274#	define STAT stat
275#	define FSTAT fstat
276#	define STRUCT_STAT struct stat
277#endif
278
279
280/* Return a dictionary corresponding to the POSIX environment table */
281
282#if !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
283extern char **environ;
284#endif /* !_MSC_VER */
285
286static PyObject *
287convertenviron(void)
288{
289	PyObject *d;
290	char **e;
291	d = PyDict_New();
292	if (d == NULL)
293		return NULL;
294	if (environ == NULL)
295		return d;
296	/* This part ignores errors */
297	for (e = environ; *e != NULL; e++) {
298		PyObject *k;
299		PyObject *v;
300		char *p = strchr(*e, '=');
301		if (p == NULL)
302			continue;
303		k = PyString_FromStringAndSize(*e, (int)(p-*e));
304		if (k == NULL) {
305			PyErr_Clear();
306			continue;
307		}
308		v = PyString_FromString(p+1);
309		if (v == NULL) {
310			PyErr_Clear();
311			Py_DECREF(k);
312			continue;
313		}
314		if (PyDict_GetItem(d, k) == NULL) {
315			if (PyDict_SetItem(d, k, v) != 0)
316				PyErr_Clear();
317		}
318		Py_DECREF(k);
319		Py_DECREF(v);
320	}
321#if defined(PYOS_OS2)
322    {
323        APIRET rc;
324        char   buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
325
326        rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
327	if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
328            PyObject *v = PyString_FromString(buffer);
329		    PyDict_SetItemString(d, "BEGINLIBPATH", v);
330            Py_DECREF(v);
331        }
332        rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
333        if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
334            PyObject *v = PyString_FromString(buffer);
335		    PyDict_SetItemString(d, "ENDLIBPATH", v);
336            Py_DECREF(v);
337        }
338    }
339#endif
340	return d;
341}
342
343
344/* Set a POSIX-specific error from errno, and return NULL */
345
346static PyObject *
347posix_error(void)
348{
349	return PyErr_SetFromErrno(PyExc_OSError);
350}
351static PyObject *
352posix_error_with_filename(char* name)
353{
354	return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
355}
356
357#ifdef MS_WIN32
358static PyObject *
359win32_error(char* function, char* filename)
360{
361	/* XXX this could be improved */
362	errno = GetLastError();
363	if (filename)
364		return PyErr_SetFromErrnoWithFilename(PyExc_OSError, filename);
365	else
366		return PyErr_SetFromErrno(PyExc_OSError);
367}
368#endif
369
370#if defined(PYOS_OS2)
371/**********************************************************************
372 *         Helper Function to Trim and Format OS/2 Messages
373 **********************************************************************/
374    static void
375os2_formatmsg(char *msgbuf, int msglen, char *reason)
376{
377    msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
378
379    if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
380        char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
381
382        while (lastc > msgbuf && isspace(*lastc))
383            *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
384    }
385
386    /* Add Optional Reason Text */
387    if (reason) {
388        strcat(msgbuf, " : ");
389        strcat(msgbuf, reason);
390    }
391}
392
393/**********************************************************************
394 *             Decode an OS/2 Operating System Error Code
395 *
396 * A convenience function to lookup an OS/2 error code and return a
397 * text message we can use to raise a Python exception.
398 *
399 * Notes:
400 *   The messages for errors returned from the OS/2 kernel reside in
401 *   the file OSO001.MSG in the \OS2 directory hierarchy.
402 *
403 **********************************************************************/
404    static char *
405os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
406{
407    APIRET rc;
408    ULONG  msglen;
409
410    /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
411    Py_BEGIN_ALLOW_THREADS
412    rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
413                       errorcode, "oso001.msg", &msglen);
414    Py_END_ALLOW_THREADS
415
416    if (rc == NO_ERROR)
417        os2_formatmsg(msgbuf, msglen, reason);
418    else
419        sprintf(msgbuf, "unknown OS error #%d", errorcode);
420
421    return msgbuf;
422}
423
424/* Set an OS/2-specific error and return NULL.  OS/2 kernel
425   errors are not in a global variable e.g. 'errno' nor are
426   they congruent with posix error numbers. */
427
428static PyObject * os2_error(int code)
429{
430    char text[1024];
431    PyObject *v;
432
433    os2_strerror(text, sizeof(text), code, "");
434
435    v = Py_BuildValue("(is)", code, text);
436    if (v != NULL) {
437        PyErr_SetObject(PyExc_OSError, v);
438        Py_DECREF(v);
439    }
440    return NULL; /* Signal to Python that an Exception is Pending */
441}
442
443#endif /* OS2 */
444
445/* POSIX generic methods */
446
447static PyObject *
448posix_int(PyObject *args, char *format, int (*func)(int))
449{
450	int fd;
451	int res;
452	if (!PyArg_ParseTuple(args,  format, &fd))
453		return NULL;
454	Py_BEGIN_ALLOW_THREADS
455	res = (*func)(fd);
456	Py_END_ALLOW_THREADS
457	if (res < 0)
458		return posix_error();
459	Py_INCREF(Py_None);
460	return Py_None;
461}
462
463
464static PyObject *
465posix_1str(PyObject *args, char *format, int (*func)(const char*))
466{
467	char *path1;
468	int res;
469	if (!PyArg_ParseTuple(args, format, &path1))
470		return NULL;
471	Py_BEGIN_ALLOW_THREADS
472	res = (*func)(path1);
473	Py_END_ALLOW_THREADS
474	if (res < 0)
475		return posix_error_with_filename(path1);
476	Py_INCREF(Py_None);
477	return Py_None;
478}
479
480static PyObject *
481posix_2str(PyObject *args, char *format,
482	   int (*func)(const char *, const char *))
483{
484	char *path1, *path2;
485	int res;
486	if (!PyArg_ParseTuple(args, format, &path1, &path2))
487		return NULL;
488	Py_BEGIN_ALLOW_THREADS
489	res = (*func)(path1, path2);
490	Py_END_ALLOW_THREADS
491	if (res != 0)
492		/* XXX how to report both path1 and path2??? */
493		return posix_error();
494	Py_INCREF(Py_None);
495	return Py_None;
496}
497
498static PyObject *
499posix_strint(PyObject *args, char *format, int (*func)(const char *, int))
500{
501	char *path;
502	int i;
503	int res;
504	if (!PyArg_ParseTuple(args, format, &path, &i))
505		return NULL;
506	Py_BEGIN_ALLOW_THREADS
507	res = (*func)(path, i);
508	Py_END_ALLOW_THREADS
509	if (res < 0)
510		return posix_error_with_filename(path);
511	Py_INCREF(Py_None);
512	return Py_None;
513}
514
515
516/* pack a system stat C structure into the Python stat tuple
517   (used by posix_stat() and posix_fstat()) */
518static PyObject*
519_pystat_fromstructstat(STRUCT_STAT st)
520{
521	PyObject *v = PyTuple_New(10);
522	if (v == NULL)
523		return NULL;
524
525	PyTuple_SetItem(v, 0, PyInt_FromLong((long)st.st_mode));
526#ifdef HAVE_LARGEFILE_SUPPORT
527	PyTuple_SetItem(v, 1, PyLong_FromLongLong((LONG_LONG)st.st_ino));
528#else
529	PyTuple_SetItem(v, 1, PyInt_FromLong((long)st.st_ino));
530#endif
531#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
532	PyTuple_SetItem(v, 2, PyLong_FromLongLong((LONG_LONG)st.st_dev));
533#else
534	PyTuple_SetItem(v, 2, PyInt_FromLong((long)st.st_dev));
535#endif
536	PyTuple_SetItem(v, 3, PyInt_FromLong((long)st.st_nlink));
537	PyTuple_SetItem(v, 4, PyInt_FromLong((long)st.st_uid));
538	PyTuple_SetItem(v, 5, PyInt_FromLong((long)st.st_gid));
539#ifdef HAVE_LARGEFILE_SUPPORT
540	PyTuple_SetItem(v, 6, PyLong_FromLongLong((LONG_LONG)st.st_size));
541#else
542	PyTuple_SetItem(v, 6, PyInt_FromLong(st.st_size));
543#endif
544#if SIZEOF_TIME_T > SIZEOF_LONG
545	PyTuple_SetItem(v, 7, PyLong_FromLongLong((LONG_LONG)st.st_atime));
546	PyTuple_SetItem(v, 8, PyLong_FromLongLong((LONG_LONG)st.st_mtime));
547	PyTuple_SetItem(v, 9, PyLong_FromLongLong((LONG_LONG)st.st_ctime));
548#else
549	PyTuple_SetItem(v, 7, PyInt_FromLong((long)st.st_atime));
550	PyTuple_SetItem(v, 8, PyInt_FromLong((long)st.st_mtime));
551	PyTuple_SetItem(v, 9, PyInt_FromLong((long)st.st_ctime));
552#endif
553
554	if (PyErr_Occurred()) {
555		Py_DECREF(v);
556		return NULL;
557	}
558
559	return v;
560}
561
562
563static PyObject *
564posix_do_stat(PyObject *self, PyObject *args, char *format,
565	      int (*statfunc)(const char *, STRUCT_STAT *))
566{
567	STRUCT_STAT st;
568	char *path;
569	int res;
570
571#ifdef MS_WIN32
572      int pathlen;
573      char pathcopy[MAX_PATH];
574#endif /* MS_WIN32 */
575
576	if (!PyArg_ParseTuple(args, format, &path))
577		return NULL;
578
579#ifdef MS_WIN32
580	pathlen = strlen(path);
581	/* the library call can blow up if the file name is too long! */
582	if (pathlen > MAX_PATH) {
583		errno = ENAMETOOLONG;
584		return posix_error();
585	}
586
587	if ((pathlen > 0) && (path[pathlen-1] == '\\' || path[pathlen-1] == '/')) {
588		/* exception for specific or current drive root */
589		if (!((pathlen == 1) ||
590		      ((pathlen == 3) &&
591		      (path[1] == ':') &&
592		      (path[2] == '\\' || path[2] == '/'))))
593		{
594			strncpy(pathcopy, path, pathlen);
595			pathcopy[pathlen-1] = '\0'; /* nuke the trailing backslash */
596			path = pathcopy;
597		}
598	}
599#endif /* MS_WIN32 */
600
601	Py_BEGIN_ALLOW_THREADS
602	res = (*statfunc)(path, &st);
603	Py_END_ALLOW_THREADS
604	if (res != 0)
605		return posix_error_with_filename(path);
606
607	return _pystat_fromstructstat(st);
608}
609
610
611/* POSIX methods */
612
613static char posix_access__doc__[] =
614"access(path, mode) -> 1 if granted, 0 otherwise\n\
615Test for access to a file.";
616
617static PyObject *
618posix_access(PyObject *self, PyObject *args)
619{
620	char *path;
621	int mode;
622	int res;
623
624	if (!PyArg_ParseTuple(args, "si:access", &path, &mode))
625		return NULL;
626	Py_BEGIN_ALLOW_THREADS
627	res = access(path, mode);
628	Py_END_ALLOW_THREADS
629	return(PyInt_FromLong(res == 0 ? 1L : 0L));
630}
631
632#ifndef F_OK
633#define F_OK 0
634#endif
635#ifndef R_OK
636#define R_OK 4
637#endif
638#ifndef W_OK
639#define W_OK 2
640#endif
641#ifndef X_OK
642#define X_OK 1
643#endif
644
645#ifdef HAVE_TTYNAME
646static char posix_ttyname__doc__[] =
647"ttyname(fd) -> String\n\
648Return the name of the terminal device connected to 'fd'.";
649
650static PyObject *
651posix_ttyname(PyObject *self, PyObject *args)
652{
653	int id;
654	char *ret;
655
656	if (!PyArg_ParseTuple(args, "i:ttyname", &id))
657		return NULL;
658
659	ret = ttyname(id);
660	if (ret == NULL)
661		return(posix_error());
662	return(PyString_FromString(ret));
663}
664#endif
665
666#ifdef HAVE_CTERMID
667static char posix_ctermid__doc__[] =
668"ctermid() -> String\n\
669Return the name of the controlling terminal for this process.";
670
671static PyObject *
672posix_ctermid(PyObject *self, PyObject *args)
673{
674        char *ret;
675        char buffer[L_ctermid];
676
677	if (!PyArg_ParseTuple(args, ":ctermid"))
678		return NULL;
679
680#ifdef USE_CTERMID_R
681	ret = ctermid_r(buffer);
682#else
683        ret = ctermid(buffer);
684#endif
685	if (ret == NULL)
686		return(posix_error());
687	return(PyString_FromString(buffer));
688}
689#endif
690
691static char posix_chdir__doc__[] =
692"chdir(path) -> None\n\
693Change the current working directory to the specified path.";
694
695static PyObject *
696posix_chdir(PyObject *self, PyObject *args)
697{
698	return posix_1str(args, "s:chdir", chdir);
699}
700
701
702static char posix_chmod__doc__[] =
703"chmod(path, mode) -> None\n\
704Change the access permissions of a file.";
705
706static PyObject *
707posix_chmod(PyObject *self, PyObject *args)
708{
709	char *path;
710	int i;
711	int res;
712	if (!PyArg_ParseTuple(args, "si", &path, &i))
713		return NULL;
714	Py_BEGIN_ALLOW_THREADS
715	res = chmod(path, i);
716	Py_END_ALLOW_THREADS
717	if (res < 0)
718		return posix_error_with_filename(path);
719	Py_INCREF(Py_None);
720	return Py_None;
721}
722
723
724#ifdef HAVE_FSYNC
725static char posix_fsync__doc__[] =
726"fsync(fildes) -> None\n\
727force write of file with filedescriptor to disk.";
728
729static PyObject *
730posix_fsync(PyObject *self, PyObject *args)
731{
732       return posix_int(args, "i:fsync", fsync);
733}
734#endif /* HAVE_FSYNC */
735
736#ifdef HAVE_FDATASYNC
737static char posix_fdatasync__doc__[] =
738"fdatasync(fildes) -> None\n\
739force write of file with filedescriptor to disk.\n\
740 does not force update of metadata.";
741
742extern int fdatasync(int); /* Prototype just in case */
743
744static PyObject *
745posix_fdatasync(PyObject *self, PyObject *args)
746{
747       return posix_int(args, "i:fdatasync", fdatasync);
748}
749#endif /* HAVE_FDATASYNC */
750
751
752#ifdef HAVE_CHOWN
753static char posix_chown__doc__[] =
754"chown(path, uid, gid) -> None\n\
755Change the owner and group id of path to the numeric uid and gid.";
756
757static PyObject *
758posix_chown(PyObject *self, PyObject *args)
759{
760	char *path;
761	int uid, gid;
762	int res;
763	if (!PyArg_ParseTuple(args, "sii:chown", &path, &uid, &gid))
764		return NULL;
765	Py_BEGIN_ALLOW_THREADS
766	res = chown(path, (uid_t) uid, (gid_t) gid);
767	Py_END_ALLOW_THREADS
768	if (res < 0)
769		return posix_error_with_filename(path);
770	Py_INCREF(Py_None);
771	return Py_None;
772}
773#endif /* HAVE_CHOWN */
774
775
776#ifdef HAVE_GETCWD
777static char posix_getcwd__doc__[] =
778"getcwd() -> path\n\
779Return a string representing the current working directory.";
780
781static PyObject *
782posix_getcwd(PyObject *self, PyObject *args)
783{
784	char buf[1026];
785	char *res;
786	if (!PyArg_ParseTuple(args, ":getcwd"))
787		return NULL;
788	Py_BEGIN_ALLOW_THREADS
789	res = getcwd(buf, sizeof buf);
790	Py_END_ALLOW_THREADS
791	if (res == NULL)
792		return posix_error();
793	return PyString_FromString(buf);
794}
795#endif
796
797
798#ifdef HAVE_LINK
799static char posix_link__doc__[] =
800"link(src, dst) -> None\n\
801Create a hard link to a file.";
802
803static PyObject *
804posix_link(PyObject *self, PyObject *args)
805{
806	return posix_2str(args, "ss:link", link);
807}
808#endif /* HAVE_LINK */
809
810
811static char posix_listdir__doc__[] =
812"listdir(path) -> list_of_strings\n\
813Return a list containing the names of the entries in the directory.\n\
814\n\
815	path: path of directory to list\n\
816\n\
817The list is in arbitrary order.  It does not include the special\n\
818entries '.' and '..' even if they are present in the directory.";
819
820static PyObject *
821posix_listdir(PyObject *self, PyObject *args)
822{
823	/* XXX Should redo this putting the (now four) versions of opendir
824	   in separate files instead of having them all here... */
825#if defined(MS_WIN32) && !defined(HAVE_OPENDIR)
826
827	char *name;
828	int len;
829	PyObject *d, *v;
830	HANDLE hFindFile;
831	WIN32_FIND_DATA FileData;
832	char namebuf[MAX_PATH+5];
833
834	if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
835		return NULL;
836	if (len >= MAX_PATH) {
837		PyErr_SetString(PyExc_ValueError, "path too long");
838		return NULL;
839	}
840	strcpy(namebuf, name);
841	if (namebuf[len-1] != '/' && namebuf[len-1] != '\\')
842		namebuf[len++] = '/';
843	strcpy(namebuf + len, "*.*");
844
845	if ((d = PyList_New(0)) == NULL)
846		return NULL;
847
848	hFindFile = FindFirstFile(namebuf, &FileData);
849	if (hFindFile == INVALID_HANDLE_VALUE) {
850		errno = GetLastError();
851		if (errno == ERROR_FILE_NOT_FOUND)
852			return PyList_New(0);
853		return win32_error("FindFirstFile", name);
854	}
855	do {
856		if (FileData.cFileName[0] == '.' &&
857		    (FileData.cFileName[1] == '\0' ||
858		     FileData.cFileName[1] == '.' &&
859		     FileData.cFileName[2] == '\0'))
860			continue;
861		v = PyString_FromString(FileData.cFileName);
862		if (v == NULL) {
863			Py_DECREF(d);
864			d = NULL;
865			break;
866		}
867		if (PyList_Append(d, v) != 0) {
868			Py_DECREF(v);
869			Py_DECREF(d);
870			d = NULL;
871			break;
872		}
873		Py_DECREF(v);
874	} while (FindNextFile(hFindFile, &FileData) == TRUE);
875
876	if (FindClose(hFindFile) == FALSE)
877		return win32_error("FindClose", name);
878
879	return d;
880
881#else /* !MS_WIN32 */
882#ifdef _MSC_VER /* 16-bit Windows */
883
884#ifndef MAX_PATH
885#define MAX_PATH	250
886#endif
887	char *name, *pt;
888	int len;
889	PyObject *d, *v;
890	char namebuf[MAX_PATH+5];
891	struct _find_t ep;
892
893	if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
894		return NULL;
895	if (len >= MAX_PATH) {
896		PyErr_SetString(PyExc_ValueError, "path too long");
897		return NULL;
898	}
899	strcpy(namebuf, name);
900	for (pt = namebuf; *pt; pt++)
901		if (*pt == '/')
902			*pt = '\\';
903	if (namebuf[len-1] != '\\')
904		namebuf[len++] = '\\';
905	strcpy(namebuf + len, "*.*");
906
907	if ((d = PyList_New(0)) == NULL)
908		return NULL;
909
910	if (_dos_findfirst(namebuf, _A_RDONLY |
911			   _A_HIDDEN | _A_SYSTEM | _A_SUBDIR, &ep) != 0)
912        {
913		errno = ENOENT;
914		return posix_error_with_filename(name);
915	}
916	do {
917		if (ep.name[0] == '.' &&
918		    (ep.name[1] == '\0' ||
919		     ep.name[1] == '.' &&
920		     ep.name[2] == '\0'))
921			continue;
922		strcpy(namebuf, ep.name);
923		for (pt = namebuf; *pt; pt++)
924			if (isupper(*pt))
925				*pt = tolower(*pt);
926		v = PyString_FromString(namebuf);
927		if (v == NULL) {
928			Py_DECREF(d);
929			d = NULL;
930			break;
931		}
932		if (PyList_Append(d, v) != 0) {
933			Py_DECREF(v);
934			Py_DECREF(d);
935			d = NULL;
936			break;
937		}
938		Py_DECREF(v);
939	} while (_dos_findnext(&ep) == 0);
940
941	return d;
942
943#else
944#if defined(PYOS_OS2)
945
946#ifndef MAX_PATH
947#define MAX_PATH    CCHMAXPATH
948#endif
949    char *name, *pt;
950    int len;
951    PyObject *d, *v;
952    char namebuf[MAX_PATH+5];
953    HDIR  hdir = 1;
954    ULONG srchcnt = 1;
955    FILEFINDBUF3   ep;
956    APIRET rc;
957
958    if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
959        return NULL;
960    if (len >= MAX_PATH) {
961		PyErr_SetString(PyExc_ValueError, "path too long");
962        return NULL;
963    }
964    strcpy(namebuf, name);
965    for (pt = namebuf; *pt; pt++)
966        if (*pt == '/')
967            *pt = '\\';
968    if (namebuf[len-1] != '\\')
969        namebuf[len++] = '\\';
970    strcpy(namebuf + len, "*.*");
971
972	if ((d = PyList_New(0)) == NULL)
973        return NULL;
974
975    rc = DosFindFirst(namebuf,         /* Wildcard Pattern to Match */
976                      &hdir,           /* Handle to Use While Search Directory */
977                      FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
978                      &ep, sizeof(ep), /* Structure to Receive Directory Entry */
979                      &srchcnt,        /* Max and Actual Count of Entries Per Iteration */
980                      FIL_STANDARD);   /* Format of Entry (EAs or Not) */
981
982    if (rc != NO_ERROR) {
983        errno = ENOENT;
984        return posix_error_with_filename(name);
985    }
986
987    if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
988        do {
989            if (ep.achName[0] == '.'
990            && (ep.achName[1] == '\0' || ep.achName[1] == '.' && ep.achName[2] == '\0'))
991                continue; /* Skip Over "." and ".." Names */
992
993            strcpy(namebuf, ep.achName);
994
995            /* Leave Case of Name Alone -- In Native Form */
996            /* (Removed Forced Lowercasing Code) */
997
998            v = PyString_FromString(namebuf);
999            if (v == NULL) {
1000                Py_DECREF(d);
1001                d = NULL;
1002                break;
1003            }
1004            if (PyList_Append(d, v) != 0) {
1005                Py_DECREF(v);
1006                Py_DECREF(d);
1007                d = NULL;
1008                break;
1009            }
1010            Py_DECREF(v);
1011        } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1012    }
1013
1014    return d;
1015#else
1016
1017	char *name;
1018	PyObject *d, *v;
1019	DIR *dirp;
1020	struct dirent *ep;
1021	if (!PyArg_ParseTuple(args, "s:listdir", &name))
1022		return NULL;
1023	if ((dirp = opendir(name)) == NULL) {
1024		return posix_error_with_filename(name);
1025	}
1026	if ((d = PyList_New(0)) == NULL) {
1027		closedir(dirp);
1028		return NULL;
1029	}
1030	while ((ep = readdir(dirp)) != NULL) {
1031		if (ep->d_name[0] == '.' &&
1032		    (NAMLEN(ep) == 1 ||
1033		     (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
1034			continue;
1035		v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
1036		if (v == NULL) {
1037			Py_DECREF(d);
1038			d = NULL;
1039			break;
1040		}
1041		if (PyList_Append(d, v) != 0) {
1042			Py_DECREF(v);
1043			Py_DECREF(d);
1044			d = NULL;
1045			break;
1046		}
1047		Py_DECREF(v);
1048	}
1049	closedir(dirp);
1050
1051	return d;
1052
1053#endif /* !PYOS_OS2 */
1054#endif /* !_MSC_VER */
1055#endif /* !MS_WIN32 */
1056}
1057
1058static char posix_mkdir__doc__[] =
1059"mkdir(path [, mode=0777]) -> None\n\
1060Create a directory.";
1061
1062static PyObject *
1063posix_mkdir(PyObject *self, PyObject *args)
1064{
1065	int res;
1066	char *path;
1067	int mode = 0777;
1068	if (!PyArg_ParseTuple(args, "s|i:mkdir", &path, &mode))
1069		return NULL;
1070	Py_BEGIN_ALLOW_THREADS
1071#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
1072	res = mkdir(path);
1073#else
1074	res = mkdir(path, mode);
1075#endif
1076	Py_END_ALLOW_THREADS
1077	if (res < 0)
1078		return posix_error_with_filename(path);
1079	Py_INCREF(Py_None);
1080	return Py_None;
1081}
1082
1083
1084#ifdef HAVE_NICE
1085static char posix_nice__doc__[] =
1086"nice(inc) -> new_priority\n\
1087Decrease the priority of process and return new priority.";
1088
1089static PyObject *
1090posix_nice(PyObject *self, PyObject *args)
1091{
1092	int increment, value;
1093
1094	if (!PyArg_ParseTuple(args, "i:nice", &increment))
1095		return NULL;
1096	value = nice(increment);
1097	if (value == -1)
1098		return posix_error();
1099	return PyInt_FromLong((long) value);
1100}
1101#endif /* HAVE_NICE */
1102
1103
1104static char posix_rename__doc__[] =
1105"rename(old, new) -> None\n\
1106Rename a file or directory.";
1107
1108static PyObject *
1109posix_rename(PyObject *self, PyObject *args)
1110{
1111	return posix_2str(args, "ss:rename", rename);
1112}
1113
1114
1115static char posix_rmdir__doc__[] =
1116"rmdir(path) -> None\n\
1117Remove a directory.";
1118
1119static PyObject *
1120posix_rmdir(PyObject *self, PyObject *args)
1121{
1122	return posix_1str(args, "s:rmdir", rmdir);
1123}
1124
1125
1126static char posix_stat__doc__[] =
1127"stat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
1128Perform a stat system call on the given path.";
1129
1130static PyObject *
1131posix_stat(PyObject *self, PyObject *args)
1132{
1133	return posix_do_stat(self, args, "s:stat", STAT);
1134}
1135
1136
1137#ifdef HAVE_SYSTEM
1138static char posix_system__doc__[] =
1139"system(command) -> exit_status\n\
1140Execute the command (a string) in a subshell.";
1141
1142static PyObject *
1143posix_system(PyObject *self, PyObject *args)
1144{
1145	char *command;
1146	long sts;
1147	if (!PyArg_ParseTuple(args, "s:system", &command))
1148		return NULL;
1149	Py_BEGIN_ALLOW_THREADS
1150	sts = system(command);
1151	Py_END_ALLOW_THREADS
1152	return PyInt_FromLong(sts);
1153}
1154#endif
1155
1156
1157static char posix_umask__doc__[] =
1158"umask(new_mask) -> old_mask\n\
1159Set the current numeric umask and return the previous umask.";
1160
1161static PyObject *
1162posix_umask(PyObject *self, PyObject *args)
1163{
1164	int i;
1165	if (!PyArg_ParseTuple(args, "i:umask", &i))
1166		return NULL;
1167	i = umask(i);
1168	if (i < 0)
1169		return posix_error();
1170	return PyInt_FromLong((long)i);
1171}
1172
1173
1174static char posix_unlink__doc__[] =
1175"unlink(path) -> None\n\
1176Remove a file (same as remove(path)).";
1177
1178static char posix_remove__doc__[] =
1179"remove(path) -> None\n\
1180Remove a file (same as unlink(path)).";
1181
1182static PyObject *
1183posix_unlink(PyObject *self, PyObject *args)
1184{
1185	return posix_1str(args, "s:remove", unlink);
1186}
1187
1188
1189#ifdef HAVE_UNAME
1190static char posix_uname__doc__[] =
1191"uname() -> (sysname, nodename, release, version, machine)\n\
1192Return a tuple identifying the current operating system.";
1193
1194static PyObject *
1195posix_uname(PyObject *self, PyObject *args)
1196{
1197	struct utsname u;
1198	int res;
1199	if (!PyArg_ParseTuple(args, ":uname"))
1200		return NULL;
1201	Py_BEGIN_ALLOW_THREADS
1202	res = uname(&u);
1203	Py_END_ALLOW_THREADS
1204	if (res < 0)
1205		return posix_error();
1206	return Py_BuildValue("(sssss)",
1207			     u.sysname,
1208			     u.nodename,
1209			     u.release,
1210			     u.version,
1211			     u.machine);
1212}
1213#endif /* HAVE_UNAME */
1214
1215
1216static char posix_utime__doc__[] =
1217"utime(path, (atime, utime)) -> None\n\
1218utime(path, None) -> None\n\
1219Set the access and modified time of the file to the given values.  If the\n\
1220second form is used, set the access and modified times to the current time.";
1221
1222static PyObject *
1223posix_utime(PyObject *self, PyObject *args)
1224{
1225	char *path;
1226	long atime, mtime;
1227	int res;
1228	PyObject* arg;
1229
1230/* XXX should define struct utimbuf instead, above */
1231#ifdef HAVE_UTIME_H
1232	struct utimbuf buf;
1233#define ATIME buf.actime
1234#define MTIME buf.modtime
1235#define UTIME_ARG &buf
1236#else /* HAVE_UTIME_H */
1237	time_t buf[2];
1238#define ATIME buf[0]
1239#define MTIME buf[1]
1240#define UTIME_ARG buf
1241#endif /* HAVE_UTIME_H */
1242
1243	if (!PyArg_ParseTuple(args, "sO:utime", &path, &arg))
1244		return NULL;
1245	if (arg == Py_None) {
1246		/* optional time values not given */
1247		Py_BEGIN_ALLOW_THREADS
1248		res = utime(path, NULL);
1249		Py_END_ALLOW_THREADS
1250	}
1251	else if (!PyArg_Parse(arg, "(ll)", &atime, &mtime)) {
1252		PyErr_SetString(PyExc_TypeError,
1253			      "Second argument must be a 2-tuple of numbers.");
1254		return NULL;
1255	}
1256	else {
1257		ATIME = atime;
1258		MTIME = mtime;
1259		Py_BEGIN_ALLOW_THREADS
1260		res = utime(path, UTIME_ARG);
1261		Py_END_ALLOW_THREADS
1262	}
1263	if (res < 0)
1264		return posix_error_with_filename(path);
1265	Py_INCREF(Py_None);
1266	return Py_None;
1267#undef UTIME_ARG
1268#undef ATIME
1269#undef MTIME
1270}
1271
1272
1273/* Process operations */
1274
1275static char posix__exit__doc__[] =
1276"_exit(status)\n\
1277Exit to the system with specified status, without normal exit processing.";
1278
1279static PyObject *
1280posix__exit(PyObject *self, PyObject *args)
1281{
1282	int sts;
1283	if (!PyArg_ParseTuple(args, "i:_exit", &sts))
1284		return NULL;
1285	_exit(sts);
1286	return NULL; /* Make gcc -Wall happy */
1287}
1288
1289
1290#ifdef HAVE_EXECV
1291static char posix_execv__doc__[] =
1292"execv(path, args)\n\
1293Execute an executable path with arguments, replacing current process.\n\
1294\n\
1295	path: path of executable file\n\
1296	args: tuple or list of strings";
1297
1298static PyObject *
1299posix_execv(PyObject *self, PyObject *args)
1300{
1301	char *path;
1302	PyObject *argv;
1303	char **argvlist;
1304	int i, argc;
1305	PyObject *(*getitem)(PyObject *, int);
1306
1307	/* execv has two arguments: (path, argv), where
1308	   argv is a list or tuple of strings. */
1309
1310	if (!PyArg_ParseTuple(args, "sO:execv", &path, &argv))
1311		return NULL;
1312	if (PyList_Check(argv)) {
1313		argc = PyList_Size(argv);
1314		getitem = PyList_GetItem;
1315	}
1316	else if (PyTuple_Check(argv)) {
1317		argc = PyTuple_Size(argv);
1318		getitem = PyTuple_GetItem;
1319	}
1320	else {
1321		PyErr_SetString(PyExc_TypeError, "argv must be tuple or list");
1322		return NULL;
1323	}
1324
1325	if (argc == 0) {
1326		PyErr_SetString(PyExc_ValueError, "empty argument list");
1327		return NULL;
1328	}
1329
1330	argvlist = PyMem_NEW(char *, argc+1);
1331	if (argvlist == NULL)
1332		return NULL;
1333	for (i = 0; i < argc; i++) {
1334		if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1335			PyMem_DEL(argvlist);
1336			PyErr_SetString(PyExc_TypeError,
1337					"all arguments must be strings");
1338			return NULL;
1339
1340		}
1341	}
1342	argvlist[argc] = NULL;
1343
1344#ifdef BAD_EXEC_PROTOTYPES
1345	execv(path, (const char **) argvlist);
1346#else /* BAD_EXEC_PROTOTYPES */
1347	execv(path, argvlist);
1348#endif /* BAD_EXEC_PROTOTYPES */
1349
1350	/* If we get here it's definitely an error */
1351
1352	PyMem_DEL(argvlist);
1353	return posix_error();
1354}
1355
1356
1357static char posix_execve__doc__[] =
1358"execve(path, args, env)\n\
1359Execute a path with arguments and environment, replacing current process.\n\
1360\n\
1361	path: path of executable file\n\
1362	args: tuple or list of arguments\n\
1363	env: dictionary of strings mapping to strings";
1364
1365static PyObject *
1366posix_execve(PyObject *self, PyObject *args)
1367{
1368	char *path;
1369	PyObject *argv, *env;
1370	char **argvlist;
1371	char **envlist;
1372	PyObject *key, *val, *keys=NULL, *vals=NULL;
1373	int i, pos, argc, envc;
1374	PyObject *(*getitem)(PyObject *, int);
1375
1376	/* execve has three arguments: (path, argv, env), where
1377	   argv is a list or tuple of strings and env is a dictionary
1378	   like posix.environ. */
1379
1380	if (!PyArg_ParseTuple(args, "sOO:execve", &path, &argv, &env))
1381		return NULL;
1382	if (PyList_Check(argv)) {
1383		argc = PyList_Size(argv);
1384		getitem = PyList_GetItem;
1385	}
1386	else if (PyTuple_Check(argv)) {
1387		argc = PyTuple_Size(argv);
1388		getitem = PyTuple_GetItem;
1389	}
1390	else {
1391		PyErr_SetString(PyExc_TypeError, "argv must be tuple or list");
1392		return NULL;
1393	}
1394	if (!PyMapping_Check(env)) {
1395		PyErr_SetString(PyExc_TypeError, "env must be mapping object");
1396		return NULL;
1397	}
1398
1399	if (argc == 0) {
1400		PyErr_SetString(PyExc_ValueError,
1401				"empty argument list");
1402		return NULL;
1403	}
1404
1405	argvlist = PyMem_NEW(char *, argc+1);
1406	if (argvlist == NULL) {
1407		PyErr_NoMemory();
1408		return NULL;
1409	}
1410	for (i = 0; i < argc; i++) {
1411		if (!PyArg_Parse((*getitem)(argv, i),
1412				 "s;argv must be list of strings",
1413				 &argvlist[i]))
1414		{
1415			goto fail_1;
1416		}
1417	}
1418	argvlist[argc] = NULL;
1419
1420	i = PyMapping_Size(env);
1421	envlist = PyMem_NEW(char *, i + 1);
1422	if (envlist == NULL) {
1423		PyErr_NoMemory();
1424		goto fail_1;
1425	}
1426	envc = 0;
1427	keys = PyMapping_Keys(env);
1428	vals = PyMapping_Values(env);
1429	if (!keys || !vals)
1430		goto fail_2;
1431
1432	for (pos = 0; pos < i; pos++) {
1433		char *p, *k, *v;
1434
1435		key = PyList_GetItem(keys, pos);
1436		val = PyList_GetItem(vals, pos);
1437		if (!key || !val)
1438			goto fail_2;
1439
1440		if (!PyArg_Parse(key, "s;non-string key in env", &k) ||
1441		    !PyArg_Parse(val, "s;non-string value in env", &v))
1442		{
1443			goto fail_2;
1444		}
1445
1446#if defined(PYOS_OS2)
1447        /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
1448        if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
1449#endif
1450		p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2);
1451		if (p == NULL) {
1452			PyErr_NoMemory();
1453			goto fail_2;
1454		}
1455		sprintf(p, "%s=%s", k, v);
1456		envlist[envc++] = p;
1457#if defined(PYOS_OS2)
1458    }
1459#endif
1460	}
1461	envlist[envc] = 0;
1462
1463
1464#ifdef BAD_EXEC_PROTOTYPES
1465	execve(path, (const char **)argvlist, envlist);
1466#else /* BAD_EXEC_PROTOTYPES */
1467	execve(path, argvlist, envlist);
1468#endif /* BAD_EXEC_PROTOTYPES */
1469
1470	/* If we get here it's definitely an error */
1471
1472	(void) posix_error();
1473
1474 fail_2:
1475	while (--envc >= 0)
1476		PyMem_DEL(envlist[envc]);
1477	PyMem_DEL(envlist);
1478 fail_1:
1479	PyMem_DEL(argvlist);
1480	Py_XDECREF(vals);
1481	Py_XDECREF(keys);
1482	return NULL;
1483}
1484#endif /* HAVE_EXECV */
1485
1486
1487#ifdef HAVE_SPAWNV
1488static char posix_spawnv__doc__[] =
1489"spawnv(mode, path, args)\n\
1490Execute an executable path with arguments, replacing current process.\n\
1491\n\
1492	mode: mode of process creation\n\
1493	path: path of executable file\n\
1494	args: tuple or list of strings";
1495
1496static PyObject *
1497posix_spawnv(PyObject *self, PyObject *args)
1498{
1499	char *path;
1500	PyObject *argv;
1501	char **argvlist;
1502	int mode, i, argc;
1503	intptr_t spawnval;
1504	PyObject *(*getitem)(PyObject *, int);
1505
1506	/* spawnv has three arguments: (mode, path, argv), where
1507	   argv is a list or tuple of strings. */
1508
1509	if (!PyArg_ParseTuple(args, "isO:spawnv", &mode, &path, &argv))
1510		return NULL;
1511	if (PyList_Check(argv)) {
1512		argc = PyList_Size(argv);
1513		getitem = PyList_GetItem;
1514	}
1515	else if (PyTuple_Check(argv)) {
1516		argc = PyTuple_Size(argv);
1517		getitem = PyTuple_GetItem;
1518	}
1519	else {
1520		PyErr_SetString(PyExc_TypeError, "argv must be tuple or list");
1521		return NULL;
1522	}
1523
1524	argvlist = PyMem_NEW(char *, argc+1);
1525	if (argvlist == NULL)
1526		return NULL;
1527	for (i = 0; i < argc; i++) {
1528		if (!PyArg_Parse((*getitem)(argv, i), "s", &argvlist[i])) {
1529			PyMem_DEL(argvlist);
1530			PyErr_SetString(PyExc_TypeError,
1531					"all arguments must be strings");
1532			return NULL;
1533		}
1534	}
1535	argvlist[argc] = NULL;
1536
1537	if (mode == _OLD_P_OVERLAY)
1538		mode = _P_OVERLAY;
1539	spawnval = _spawnv(mode, path, argvlist);
1540
1541	PyMem_DEL(argvlist);
1542
1543	if (spawnval == -1)
1544		return posix_error();
1545	else
1546#if SIZEOF_LONG == SIZEOF_VOID_P
1547		return Py_BuildValue("l", (long) spawnval);
1548#else
1549		return Py_BuildValue("L", (LONG_LONG) spawnval);
1550#endif
1551}
1552
1553
1554static char posix_spawnve__doc__[] =
1555"spawnve(mode, path, args, env)\n\
1556Execute a path with arguments and environment, replacing current process.\n\
1557\n\
1558	mode: mode of process creation\n\
1559	path: path of executable file\n\
1560	args: tuple or list of arguments\n\
1561	env: dictionary of strings mapping to strings";
1562
1563static PyObject *
1564posix_spawnve(PyObject *self, PyObject *args)
1565{
1566	char *path;
1567	PyObject *argv, *env;
1568	char **argvlist;
1569	char **envlist;
1570	PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
1571	int mode, i, pos, argc, envc;
1572	intptr_t spawnval;
1573	PyObject *(*getitem)(PyObject *, int);
1574
1575	/* spawnve has four arguments: (mode, path, argv, env), where
1576	   argv is a list or tuple of strings and env is a dictionary
1577	   like posix.environ. */
1578
1579	if (!PyArg_ParseTuple(args, "isOO:spawnve", &mode, &path, &argv, &env))
1580		return NULL;
1581	if (PyList_Check(argv)) {
1582		argc = PyList_Size(argv);
1583		getitem = PyList_GetItem;
1584	}
1585	else if (PyTuple_Check(argv)) {
1586		argc = PyTuple_Size(argv);
1587		getitem = PyTuple_GetItem;
1588	}
1589	else {
1590		PyErr_SetString(PyExc_TypeError, "argv must be tuple or list");
1591		return NULL;
1592	}
1593	if (!PyMapping_Check(env)) {
1594		PyErr_SetString(PyExc_TypeError, "env must be mapping object");
1595		return NULL;
1596	}
1597
1598	argvlist = PyMem_NEW(char *, argc+1);
1599	if (argvlist == NULL) {
1600		PyErr_NoMemory();
1601		return NULL;
1602	}
1603	for (i = 0; i < argc; i++) {
1604		if (!PyArg_Parse((*getitem)(argv, i),
1605				 "s;argv must be list of strings",
1606				 &argvlist[i]))
1607		{
1608			goto fail_1;
1609		}
1610	}
1611	argvlist[argc] = NULL;
1612
1613	i = PyMapping_Size(env);
1614	envlist = PyMem_NEW(char *, i + 1);
1615	if (envlist == NULL) {
1616		PyErr_NoMemory();
1617		goto fail_1;
1618	}
1619	envc = 0;
1620	keys = PyMapping_Keys(env);
1621	vals = PyMapping_Values(env);
1622	if (!keys || !vals)
1623		goto fail_2;
1624
1625	for (pos = 0; pos < i; pos++) {
1626		char *p, *k, *v;
1627
1628		key = PyList_GetItem(keys, pos);
1629		val = PyList_GetItem(vals, pos);
1630		if (!key || !val)
1631			goto fail_2;
1632
1633		if (!PyArg_Parse(key, "s;non-string key in env", &k) ||
1634		    !PyArg_Parse(val, "s;non-string value in env", &v))
1635		{
1636			goto fail_2;
1637		}
1638		p = PyMem_NEW(char, PyString_Size(key)+PyString_Size(val) + 2);
1639		if (p == NULL) {
1640			PyErr_NoMemory();
1641			goto fail_2;
1642		}
1643		sprintf(p, "%s=%s", k, v);
1644		envlist[envc++] = p;
1645	}
1646	envlist[envc] = 0;
1647
1648	if (mode == _OLD_P_OVERLAY)
1649		mode = _P_OVERLAY;
1650	spawnval = _spawnve(mode, path, argvlist, envlist);
1651	if (spawnval == -1)
1652		(void) posix_error();
1653	else
1654#if SIZEOF_LONG == SIZEOF_VOID_P
1655		res = Py_BuildValue("l", (long) spawnval);
1656#else
1657		res = Py_BuildValue("L", (LONG_LONG) spawnval);
1658#endif
1659
1660 fail_2:
1661	while (--envc >= 0)
1662		PyMem_DEL(envlist[envc]);
1663	PyMem_DEL(envlist);
1664 fail_1:
1665	PyMem_DEL(argvlist);
1666	Py_XDECREF(vals);
1667	Py_XDECREF(keys);
1668	return res;
1669}
1670#endif /* HAVE_SPAWNV */
1671
1672
1673#ifdef HAVE_FORK
1674static char posix_fork__doc__[] =
1675"fork() -> pid\n\
1676Fork a child process.\n\
1677\n\
1678Return 0 to child process and PID of child to parent process.";
1679
1680static PyObject *
1681posix_fork(PyObject *self, PyObject *args)
1682{
1683	int pid;
1684	if (!PyArg_ParseTuple(args, ":fork"))
1685		return NULL;
1686	pid = fork();
1687	if (pid == -1)
1688		return posix_error();
1689	if (pid == 0)
1690		PyOS_AfterFork();
1691	return PyInt_FromLong((long)pid);
1692}
1693#endif
1694
1695#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY)
1696#ifdef HAVE_PTY_H
1697#include <pty.h>
1698#else
1699#ifdef HAVE_LIBUTIL_H
1700#include <libutil.h>
1701#else
1702/* BSDI does not supply a prototype for the 'openpty' and 'forkpty'
1703   functions, even though they are included in libutil. */
1704#include <termios.h>
1705extern int openpty(int *, int *, char *, struct termios *, struct winsize *);
1706extern int forkpty(int *, char *, struct termios *, struct winsize *);
1707#endif /* HAVE_LIBUTIL_H */
1708#endif /* HAVE_PTY_H */
1709#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */
1710
1711#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
1712static char posix_openpty__doc__[] =
1713"openpty() -> (master_fd, slave_fd)\n\
1714Open a pseudo-terminal, returning open fd's for both master and slave end.\n";
1715
1716static PyObject *
1717posix_openpty(PyObject *self, PyObject *args)
1718{
1719	int master_fd, slave_fd;
1720#ifndef HAVE_OPENPTY
1721	char * slave_name;
1722	/* SGI apparently needs this forward declaration */
1723	extern char * _getpty(int *, int, mode_t, int);
1724#endif
1725
1726	if (!PyArg_ParseTuple(args, ":openpty"))
1727		return NULL;
1728
1729#ifdef HAVE_OPENPTY
1730	if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
1731		return posix_error();
1732#else
1733	slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
1734	if (slave_name == NULL)
1735		return posix_error();
1736
1737	slave_fd = open(slave_name, O_RDWR);
1738	if (slave_fd < 0)
1739		return posix_error();
1740#endif /* defined(HAVE_OPENPTY) */
1741
1742	return Py_BuildValue("(ii)", master_fd, slave_fd);
1743
1744}
1745#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) */
1746
1747#ifdef HAVE_FORKPTY
1748static char posix_forkpty__doc__[] =
1749"forkpty() -> (pid, master_fd)\n\
1750Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
1751Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
1752To both, return fd of newly opened pseudo-terminal.\n";
1753
1754static PyObject *
1755posix_forkpty(PyObject *self, PyObject *args)
1756{
1757	int master_fd, pid;
1758
1759	if (!PyArg_ParseTuple(args, ":forkpty"))
1760		return NULL;
1761	pid = forkpty(&master_fd, NULL, NULL, NULL);
1762	if (pid == -1)
1763		return posix_error();
1764	if (pid == 0)
1765		PyOS_AfterFork();
1766	return Py_BuildValue("(ii)", pid, master_fd);
1767}
1768#endif
1769
1770#ifdef HAVE_GETEGID
1771static char posix_getegid__doc__[] =
1772"getegid() -> egid\n\
1773Return the current process's effective group id.";
1774
1775static PyObject *
1776posix_getegid(PyObject *self, PyObject *args)
1777{
1778	if (!PyArg_ParseTuple(args, ":getegid"))
1779		return NULL;
1780	return PyInt_FromLong((long)getegid());
1781}
1782#endif
1783
1784
1785#ifdef HAVE_GETEUID
1786static char posix_geteuid__doc__[] =
1787"geteuid() -> euid\n\
1788Return the current process's effective user id.";
1789
1790static PyObject *
1791posix_geteuid(PyObject *self, PyObject *args)
1792{
1793	if (!PyArg_ParseTuple(args, ":geteuid"))
1794		return NULL;
1795	return PyInt_FromLong((long)geteuid());
1796}
1797#endif
1798
1799
1800#ifdef HAVE_GETGID
1801static char posix_getgid__doc__[] =
1802"getgid() -> gid\n\
1803Return the current process's group id.";
1804
1805static PyObject *
1806posix_getgid(PyObject *self, PyObject *args)
1807{
1808	if (!PyArg_ParseTuple(args, ":getgid"))
1809		return NULL;
1810	return PyInt_FromLong((long)getgid());
1811}
1812#endif
1813
1814
1815static char posix_getpid__doc__[] =
1816"getpid() -> pid\n\
1817Return the current process id";
1818
1819static PyObject *
1820posix_getpid(PyObject *self, PyObject *args)
1821{
1822	if (!PyArg_ParseTuple(args, ":getpid"))
1823		return NULL;
1824	return PyInt_FromLong((long)getpid());
1825}
1826
1827
1828#ifdef HAVE_GETGROUPS
1829static char posix_getgroups__doc__[] = "\
1830getgroups() -> list of group IDs\n\
1831Return list of supplemental group IDs for the process.";
1832
1833static PyObject *
1834posix_getgroups(PyObject *self, PyObject *args)
1835{
1836    PyObject *result = NULL;
1837
1838    if (PyArg_ParseTuple(args, ":getgroups")) {
1839#ifdef NGROUPS_MAX
1840#define MAX_GROUPS NGROUPS_MAX
1841#else
1842        /* defined to be 16 on Solaris7, so this should be a small number */
1843#define MAX_GROUPS 64
1844#endif
1845        gid_t grouplist[MAX_GROUPS];
1846        int n;
1847
1848        n = getgroups(MAX_GROUPS, grouplist);
1849        if (n < 0)
1850            posix_error();
1851        else {
1852            result = PyList_New(n);
1853            if (result != NULL) {
1854                PyObject *o;
1855                int i;
1856                for (i = 0; i < n; ++i) {
1857                    o = PyInt_FromLong((long)grouplist[i]);
1858                    if (o == NULL) {
1859                        Py_DECREF(result);
1860                        result = NULL;
1861                        break;
1862                    }
1863                    PyList_SET_ITEM(result, i, o);
1864                }
1865            }
1866        }
1867    }
1868    return result;
1869}
1870#endif
1871
1872#ifdef HAVE_GETPGRP
1873static char posix_getpgrp__doc__[] =
1874"getpgrp() -> pgrp\n\
1875Return the current process group id.";
1876
1877static PyObject *
1878posix_getpgrp(PyObject *self, PyObject *args)
1879{
1880	if (!PyArg_ParseTuple(args, ":getpgrp"))
1881		return NULL;
1882#ifdef GETPGRP_HAVE_ARG
1883	return PyInt_FromLong((long)getpgrp(0));
1884#else /* GETPGRP_HAVE_ARG */
1885	return PyInt_FromLong((long)getpgrp());
1886#endif /* GETPGRP_HAVE_ARG */
1887}
1888#endif /* HAVE_GETPGRP */
1889
1890
1891#ifdef HAVE_SETPGRP
1892static char posix_setpgrp__doc__[] =
1893"setpgrp() -> None\n\
1894Make this process a session leader.";
1895
1896static PyObject *
1897posix_setpgrp(PyObject *self, PyObject *args)
1898{
1899	if (!PyArg_ParseTuple(args, ":setpgrp"))
1900		return NULL;
1901#ifdef SETPGRP_HAVE_ARG
1902	if (setpgrp(0, 0) < 0)
1903#else /* SETPGRP_HAVE_ARG */
1904	if (setpgrp() < 0)
1905#endif /* SETPGRP_HAVE_ARG */
1906		return posix_error();
1907	Py_INCREF(Py_None);
1908	return Py_None;
1909}
1910
1911#endif /* HAVE_SETPGRP */
1912
1913#ifdef HAVE_GETPPID
1914static char posix_getppid__doc__[] =
1915"getppid() -> ppid\n\
1916Return the parent's process id.";
1917
1918static PyObject *
1919posix_getppid(PyObject *self, PyObject *args)
1920{
1921	if (!PyArg_ParseTuple(args, ":getppid"))
1922		return NULL;
1923	return PyInt_FromLong((long)getppid());
1924}
1925#endif
1926
1927
1928#ifdef HAVE_GETLOGIN
1929static char posix_getlogin__doc__[] = "\
1930getlogin() -> string\n\
1931Return the actual login name.";
1932
1933static PyObject *
1934posix_getlogin(PyObject *self, PyObject *args)
1935{
1936    PyObject *result = NULL;
1937
1938    if (PyArg_ParseTuple(args, ":getlogin")) {
1939        char *name = getlogin();
1940
1941        if (name == NULL)
1942            posix_error();
1943        else
1944            result = PyString_FromString(name);
1945    }
1946    return result;
1947}
1948#endif
1949
1950#ifdef HAVE_GETUID
1951static char posix_getuid__doc__[] =
1952"getuid() -> uid\n\
1953Return the current process's user id.";
1954
1955static PyObject *
1956posix_getuid(PyObject *self, PyObject *args)
1957{
1958	if (!PyArg_ParseTuple(args, ":getuid"))
1959		return NULL;
1960	return PyInt_FromLong((long)getuid());
1961}
1962#endif
1963
1964
1965#ifdef HAVE_KILL
1966static char posix_kill__doc__[] =
1967"kill(pid, sig) -> None\n\
1968Kill a process with a signal.";
1969
1970static PyObject *
1971posix_kill(PyObject *self, PyObject *args)
1972{
1973	int pid, sig;
1974	if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
1975		return NULL;
1976#if defined(PYOS_OS2)
1977    if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
1978        APIRET rc;
1979        if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
1980            return os2_error(rc);
1981
1982    } else if (sig == XCPT_SIGNAL_KILLPROC) {
1983        APIRET rc;
1984        if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
1985            return os2_error(rc);
1986
1987    } else
1988        return NULL; /* Unrecognized Signal Requested */
1989#else
1990	if (kill(pid, sig) == -1)
1991		return posix_error();
1992#endif
1993	Py_INCREF(Py_None);
1994	return Py_None;
1995}
1996#endif
1997
1998#ifdef HAVE_PLOCK
1999
2000#ifdef HAVE_SYS_LOCK_H
2001#include <sys/lock.h>
2002#endif
2003
2004static char posix_plock__doc__[] =
2005"plock(op) -> None\n\
2006Lock program segments into memory.";
2007
2008static PyObject *
2009posix_plock(PyObject *self, PyObject *args)
2010{
2011	int op;
2012	if (!PyArg_ParseTuple(args, "i:plock", &op))
2013		return NULL;
2014	if (plock(op) == -1)
2015		return posix_error();
2016	Py_INCREF(Py_None);
2017	return Py_None;
2018}
2019#endif
2020
2021
2022#ifdef HAVE_POPEN
2023static char posix_popen__doc__[] =
2024"popen(command [, mode='r' [, bufsize]]) -> pipe\n\
2025Open a pipe to/from a command returning a file object.";
2026
2027#if defined(PYOS_OS2)
2028static int
2029async_system(const char *command)
2030{
2031    char        *p, errormsg[256], args[1024];
2032    RESULTCODES  rcodes;
2033    APIRET       rc;
2034    char        *shell = getenv("COMSPEC");
2035    if (!shell)
2036        shell = "cmd";
2037
2038    strcpy(args, shell);
2039    p = &args[ strlen(args)+1 ];
2040    strcpy(p, "/c ");
2041    strcat(p, command);
2042    p += strlen(p) + 1;
2043    *p = '\0';
2044
2045    rc = DosExecPgm(errormsg, sizeof(errormsg),
2046                    EXEC_ASYNC, /* Execute Async w/o Wait for Results */
2047                    args,
2048                    NULL,       /* Inherit Parent's Environment */
2049                    &rcodes, shell);
2050    return rc;
2051}
2052
2053static FILE *
2054popen(const char *command, const char *mode, int pipesize, int *err)
2055{
2056    HFILE    rhan, whan;
2057    FILE    *retfd = NULL;
2058    APIRET   rc = DosCreatePipe(&rhan, &whan, pipesize);
2059
2060    if (rc != NO_ERROR) {
2061	*err = rc;
2062        return NULL; /* ERROR - Unable to Create Anon Pipe */
2063    }
2064
2065    if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
2066        int oldfd = dup(1);      /* Save STDOUT Handle in Another Handle */
2067
2068        DosEnterCritSec();      /* Stop Other Threads While Changing Handles */
2069        close(1);                /* Make STDOUT Available for Reallocation */
2070
2071        if (dup2(whan, 1) == 0) {      /* Connect STDOUT to Pipe Write Side */
2072            DosClose(whan);            /* Close Now-Unused Pipe Write Handle */
2073
2074            if (async_system(command) == NO_ERROR)
2075                retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
2076        }
2077
2078        dup2(oldfd, 1);          /* Reconnect STDOUT to Original Handle */
2079        DosExitCritSec();        /* Now Allow Other Threads to Run */
2080
2081        close(oldfd);            /* And Close Saved STDOUT Handle */
2082        return retfd;            /* Return fd of Pipe or NULL if Error */
2083
2084    } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
2085        int oldfd = dup(0);      /* Save STDIN Handle in Another Handle */
2086
2087        DosEnterCritSec();      /* Stop Other Threads While Changing Handles */
2088        close(0);                /* Make STDIN Available for Reallocation */
2089
2090        if (dup2(rhan, 0) == 0)     { /* Connect STDIN to Pipe Read Side */
2091            DosClose(rhan);           /* Close Now-Unused Pipe Read Handle */
2092
2093            if (async_system(command) == NO_ERROR)
2094                retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
2095        }
2096
2097        dup2(oldfd, 0);          /* Reconnect STDIN to Original Handle */
2098        DosExitCritSec();        /* Now Allow Other Threads to Run */
2099
2100        close(oldfd);            /* And Close Saved STDIN Handle */
2101        return retfd;            /* Return fd of Pipe or NULL if Error */
2102
2103    } else {
2104	*err = ERROR_INVALID_ACCESS;
2105        return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
2106    }
2107}
2108
2109static PyObject *
2110posix_popen(PyObject *self, PyObject *args)
2111{
2112	char *name;
2113	char *mode = "r";
2114	int   err, bufsize = -1;
2115	FILE *fp;
2116	PyObject *f;
2117	if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
2118		return NULL;
2119	Py_BEGIN_ALLOW_THREADS
2120	fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
2121	Py_END_ALLOW_THREADS
2122	if (fp == NULL)
2123		return os2_error(err);
2124
2125	f = PyFile_FromFile(fp, name, mode, fclose);
2126	if (f != NULL)
2127		PyFile_SetBufSize(f, bufsize);
2128	return f;
2129}
2130
2131#elif defined(MS_WIN32)
2132
2133/*
2134 * Portable 'popen' replacement for Win32.
2135 *
2136 * Written by Bill Tutt <billtut@microsoft.com>.  Minor tweaks
2137 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
2138 */
2139
2140#include <malloc.h>
2141#include <io.h>
2142#include <fcntl.h>
2143
2144/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
2145#define POPEN_1 1
2146#define POPEN_2 2
2147#define POPEN_3 3
2148#define POPEN_4 4
2149
2150static PyObject *_PyPopen(char *, int, int);
2151
2152/* popen that works from a GUI.
2153 *
2154 * The result of this function is a pipe (file) connected to the
2155 * processes stdin or stdout, depending on the requested mode.
2156 */
2157
2158static PyObject *
2159posix_popen(PyObject *self, PyObject *args)
2160{
2161	PyObject *f, *s;
2162	int tm = 0;
2163
2164	char *cmdstring;
2165	char *mode = "r";
2166	int bufsize = -1;
2167	if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
2168		return NULL;
2169
2170	s = PyTuple_New(0);
2171
2172	if (*mode == 'r')
2173		tm = _O_RDONLY;
2174	else if (*mode != 'w') {
2175		PyErr_SetString(PyExc_ValueError, "mode must be 'r' or 'w'");
2176		return NULL;
2177	} else
2178		tm = _O_WRONLY;
2179
2180	if (bufsize != -1) {
2181		PyErr_SetString(PyExc_ValueError, "bufsize must be -1");
2182		return NULL;
2183	}
2184
2185	if (*(mode+1) == 't')
2186		f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
2187	else if (*(mode+1) == 'b')
2188		f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
2189	else
2190		f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
2191
2192	return f;
2193}
2194
2195/* Variation on win32pipe.popen
2196 *
2197 * The result of this function is a pipe (file) connected to the
2198 * process's stdin, and a pipe connected to the process's stdout.
2199 */
2200
2201static PyObject *
2202win32_popen2(PyObject *self, PyObject  *args)
2203{
2204	PyObject *f;
2205	int tm=0;
2206
2207	char *cmdstring;
2208	char *mode = "t";
2209	int bufsize = -1;
2210	if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
2211		return NULL;
2212
2213	if (*mode == 't')
2214		tm = _O_TEXT;
2215	else if (*mode != 'b') {
2216		PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2217		return NULL;
2218	} else
2219		tm = _O_BINARY;
2220
2221	if (bufsize != -1) {
2222		PyErr_SetString(PyExc_ValueError, "bufsize must be -1");
2223		return NULL;
2224	}
2225
2226	f = _PyPopen(cmdstring, tm, POPEN_2);
2227
2228	return f;
2229}
2230
2231/*
2232 * Variation on <om win32pipe.popen>
2233 *
2234 * The result of this function is 3 pipes - the process's stdin,
2235 * stdout and stderr
2236 */
2237
2238static PyObject *
2239win32_popen3(PyObject *self, PyObject *args)
2240{
2241	PyObject *f;
2242	int tm = 0;
2243
2244	char *cmdstring;
2245	char *mode = "t";
2246	int bufsize = -1;
2247	if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
2248		return NULL;
2249
2250	if (*mode == 't')
2251		tm = _O_TEXT;
2252	else if (*mode != 'b') {
2253		PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2254		return NULL;
2255	} else
2256		tm = _O_BINARY;
2257
2258	if (bufsize != -1) {
2259		PyErr_SetString(PyExc_ValueError, "bufsize must be -1");
2260		return NULL;
2261	}
2262
2263	f = _PyPopen(cmdstring, tm, POPEN_3);
2264
2265	return f;
2266}
2267
2268/*
2269 * Variation on win32pipe.popen
2270 *
2271 * The result of this function is 2 pipes - the processes stdin,
2272 * and stdout+stderr combined as a single pipe.
2273 */
2274
2275static PyObject *
2276win32_popen4(PyObject *self, PyObject  *args)
2277{
2278	PyObject *f;
2279	int tm = 0;
2280
2281	char *cmdstring;
2282	char *mode = "t";
2283	int bufsize = -1;
2284	if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
2285		return NULL;
2286
2287	if (*mode == 't')
2288		tm = _O_TEXT;
2289	else if (*mode != 'b') {
2290		PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
2291		return NULL;
2292	} else
2293		tm = _O_BINARY;
2294
2295	if (bufsize != -1) {
2296		PyErr_SetString(PyExc_ValueError, "bufsize must be -1");
2297		return NULL;
2298	}
2299
2300	f = _PyPopen(cmdstring, tm, POPEN_4);
2301
2302	return f;
2303}
2304
2305static int
2306_PyPopenCreateProcess(char *cmdstring,
2307		      HANDLE hStdin,
2308		      HANDLE hStdout,
2309		      HANDLE hStderr)
2310{
2311	PROCESS_INFORMATION piProcInfo;
2312	STARTUPINFO siStartInfo;
2313	char *s1,*s2, *s3 = " /c ";
2314	const char *szConsoleSpawn = "w9xpopen.exe \"";
2315	int i;
2316	int x;
2317
2318	if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
2319		s1 = (char *)_alloca(i);
2320		if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
2321			return x;
2322		if (GetVersion() < 0x80000000) {
2323			/*
2324			 * NT/2000
2325			 */
2326			x = i + strlen(s3) + strlen(cmdstring) + 1;
2327			s2 = (char *)_alloca(x);
2328			ZeroMemory(s2, x);
2329			sprintf(s2, "%s%s%s", s1, s3, cmdstring);
2330		}
2331		else {
2332			/*
2333			 * Oh gag, we're on Win9x. Use the workaround listed in
2334			 * KB: Q150956
2335			 */
2336			char modulepath[256];
2337			GetModuleFileName(NULL, modulepath, sizeof(modulepath));
2338			for (i = x = 0; modulepath[i]; i++)
2339				if (modulepath[i] == '\\')
2340					x = i+1;
2341			modulepath[x] = '\0';
2342			x = i + strlen(s3) + strlen(cmdstring) + 1 +
2343				strlen(modulepath) +
2344				strlen(szConsoleSpawn) + 1;
2345			s2 = (char *)_alloca(x);
2346			ZeroMemory(s2, x);
2347			sprintf(
2348				s2,
2349				"%s%s%s%s%s\"",
2350				modulepath,
2351				szConsoleSpawn,
2352				s1,
2353				s3,
2354				cmdstring);
2355		}
2356	}
2357
2358	/* Could be an else here to try cmd.exe / command.com in the path
2359	   Now we'll just error out.. */
2360	else
2361		return -1;
2362
2363	ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
2364	siStartInfo.cb = sizeof(STARTUPINFO);
2365	siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
2366	siStartInfo.hStdInput = hStdin;
2367	siStartInfo.hStdOutput = hStdout;
2368	siStartInfo.hStdError = hStderr;
2369	siStartInfo.wShowWindow = SW_HIDE;
2370
2371	if (CreateProcess(NULL,
2372			  s2,
2373			  NULL,
2374			  NULL,
2375			  TRUE,
2376			  CREATE_NEW_CONSOLE,
2377			  NULL,
2378			  NULL,
2379			  &siStartInfo,
2380			  &piProcInfo) ) {
2381		/* Close the handles now so anyone waiting is woken. */
2382		CloseHandle(piProcInfo.hProcess);
2383		CloseHandle(piProcInfo.hThread);
2384		return TRUE;
2385	}
2386	return FALSE;
2387}
2388
2389/* The following code is based off of KB: Q190351 */
2390
2391static PyObject *
2392_PyPopen(char *cmdstring, int mode, int n)
2393{
2394	HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
2395		hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
2396		hChildStderrRdDup; /* hChildStdoutWrDup; */
2397
2398	SECURITY_ATTRIBUTES saAttr;
2399	BOOL fSuccess;
2400	int fd1, fd2, fd3;
2401	FILE *f1, *f2, *f3;
2402	PyObject *f;
2403
2404	saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
2405	saAttr.bInheritHandle = TRUE;
2406	saAttr.lpSecurityDescriptor = NULL;
2407
2408	if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
2409		return win32_error("CreatePipe", NULL);
2410
2411	/* Create new output read handle and the input write handle. Set
2412	 * the inheritance properties to FALSE. Otherwise, the child inherits
2413	 * the these handles; resulting in non-closeable handles to the pipes
2414	 * being created. */
2415	 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
2416				    GetCurrentProcess(), &hChildStdinWrDup, 0,
2417				    FALSE,
2418				    DUPLICATE_SAME_ACCESS);
2419	 if (!fSuccess)
2420		 return win32_error("DuplicateHandle", NULL);
2421
2422	 /* Close the inheritable version of ChildStdin
2423	that we're using. */
2424	 CloseHandle(hChildStdinWr);
2425
2426	 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
2427		 return win32_error("CreatePipe", NULL);
2428
2429	 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
2430				    GetCurrentProcess(), &hChildStdoutRdDup, 0,
2431				    FALSE, DUPLICATE_SAME_ACCESS);
2432	 if (!fSuccess)
2433		 return win32_error("DuplicateHandle", NULL);
2434
2435	 /* Close the inheritable version of ChildStdout
2436		that we're using. */
2437	 CloseHandle(hChildStdoutRd);
2438
2439	 if (n != POPEN_4) {
2440		 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
2441			 return win32_error("CreatePipe", NULL);
2442		 fSuccess = DuplicateHandle(GetCurrentProcess(),
2443					    hChildStderrRd,
2444					    GetCurrentProcess(),
2445					    &hChildStderrRdDup, 0,
2446					    FALSE, DUPLICATE_SAME_ACCESS);
2447		 if (!fSuccess)
2448			 return win32_error("DuplicateHandle", NULL);
2449		 /* Close the inheritable version of ChildStdErr that we're using. */
2450		 CloseHandle(hChildStderrRd);
2451	 }
2452
2453	 switch (n) {
2454	 case POPEN_1:
2455		 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
2456		 case _O_WRONLY | _O_TEXT:
2457			 /* Case for writing to child Stdin in text mode. */
2458			 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2459			 f1 = _fdopen(fd1, "w");
2460			 f = PyFile_FromFile(f1, cmdstring, "w", fclose);
2461			 PyFile_SetBufSize(f, 0);
2462			 /* We don't care about these pipes anymore, so close them. */
2463			 CloseHandle(hChildStdoutRdDup);
2464			 CloseHandle(hChildStderrRdDup);
2465			 break;
2466
2467		 case _O_RDONLY | _O_TEXT:
2468			 /* Case for reading from child Stdout in text mode. */
2469			 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2470			 f1 = _fdopen(fd1, "r");
2471			 f = PyFile_FromFile(f1, cmdstring, "r", fclose);
2472			 PyFile_SetBufSize(f, 0);
2473			 /* We don't care about these pipes anymore, so close them. */
2474			 CloseHandle(hChildStdinWrDup);
2475			 CloseHandle(hChildStderrRdDup);
2476			 break;
2477
2478		 case _O_RDONLY | _O_BINARY:
2479			 /* Case for readinig from child Stdout in binary mode. */
2480			 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2481			 f1 = _fdopen(fd1, "rb");
2482			 f = PyFile_FromFile(f1, cmdstring, "rb", fclose);
2483			 PyFile_SetBufSize(f, 0);
2484			 /* We don't care about these pipes anymore, so close them. */
2485			 CloseHandle(hChildStdinWrDup);
2486			 CloseHandle(hChildStderrRdDup);
2487			 break;
2488
2489		 case _O_WRONLY | _O_BINARY:
2490			 /* Case for writing to child Stdin in binary mode. */
2491			 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2492			 f1 = _fdopen(fd1, "wb");
2493			 f = PyFile_FromFile(f1, cmdstring, "wb", fclose);
2494			 PyFile_SetBufSize(f, 0);
2495			 /* We don't care about these pipes anymore, so close them. */
2496			 CloseHandle(hChildStdoutRdDup);
2497			 CloseHandle(hChildStderrRdDup);
2498			 break;
2499		 }
2500		 break;
2501
2502	 case POPEN_2:
2503	 case POPEN_4:
2504	 {
2505		 char *m1, *m2;
2506		 PyObject *p1, *p2;
2507
2508		 if (mode && _O_TEXT) {
2509			 m1 = "r";
2510			 m2 = "w";
2511		 } else {
2512			 m1 = "rb";
2513			 m2 = "wb";
2514		 }
2515
2516		 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2517		 f1 = _fdopen(fd1, m2);
2518		 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2519		 f2 = _fdopen(fd2, m1);
2520		 p1 = PyFile_FromFile(f1, cmdstring, m2, fclose);
2521		 PyFile_SetBufSize(p1, 0);
2522		 p2 = PyFile_FromFile(f2, cmdstring, m1, fclose);
2523		 PyFile_SetBufSize(p2, 0);
2524
2525		 if (n != 4)
2526			 CloseHandle(hChildStderrRdDup);
2527
2528		 f = Py_BuildValue("OO",p1,p2);
2529		 break;
2530	 }
2531
2532	 case POPEN_3:
2533	 {
2534		 char *m1, *m2;
2535		 PyObject *p1, *p2, *p3;
2536
2537		 if (mode && _O_TEXT) {
2538			 m1 = "r";
2539			 m2 = "w";
2540		 } else {
2541			 m1 = "rb";
2542			 m2 = "wb";
2543		 }
2544
2545		 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
2546		 f1 = _fdopen(fd1, m2);
2547		 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
2548		 f2 = _fdopen(fd2, m1);
2549		 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
2550		 f3 = _fdopen(fd3, m1);
2551		 p1 = PyFile_FromFile(f1, cmdstring, m2, fclose);
2552		 p2 = PyFile_FromFile(f2, cmdstring, m1, fclose);
2553		 p3 = PyFile_FromFile(f3, cmdstring, m1, fclose);
2554		 PyFile_SetBufSize(p1, 0);
2555		 PyFile_SetBufSize(p2, 0);
2556		 PyFile_SetBufSize(p3, 0);
2557		 f = Py_BuildValue("OOO",p1,p2,p3);
2558		 break;
2559	 }
2560	 }
2561
2562	 if (n == POPEN_4) {
2563		 if (!_PyPopenCreateProcess(cmdstring,
2564					    hChildStdinRd,
2565					    hChildStdoutWr,
2566					    hChildStdoutWr))
2567			 return win32_error("CreateProcess", NULL);
2568	 }
2569	 else {
2570		 if (!_PyPopenCreateProcess(cmdstring,
2571					    hChildStdinRd,
2572					    hChildStdoutWr,
2573					    hChildStderrWr))
2574			 return win32_error("CreateProcess", NULL);
2575	 }
2576
2577	 /* Child is launched. Close the parents copy of those pipe
2578	  * handles that only the child should have open.  You need to
2579	  * make sure that no handles to the write end of the output pipe
2580	  * are maintained in this process or else the pipe will not close
2581	  * when the child process exits and the ReadFile will hang. */
2582
2583	 if (!CloseHandle(hChildStdinRd))
2584		 return win32_error("CloseHandle", NULL);
2585
2586	 if (!CloseHandle(hChildStdoutWr))
2587		 return win32_error("CloseHandle", NULL);
2588
2589	 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
2590		 return win32_error("CloseHandle", NULL);
2591
2592	 return f;
2593}
2594#else
2595static PyObject *
2596posix_popen(PyObject *self, PyObject *args)
2597{
2598	char *name;
2599	char *mode = "r";
2600	int bufsize = -1;
2601	FILE *fp;
2602	PyObject *f;
2603	if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
2604		return NULL;
2605	Py_BEGIN_ALLOW_THREADS
2606	fp = popen(name, mode);
2607	Py_END_ALLOW_THREADS
2608	if (fp == NULL)
2609		return posix_error();
2610	f = PyFile_FromFile(fp, name, mode, pclose);
2611	if (f != NULL)
2612		PyFile_SetBufSize(f, bufsize);
2613	return f;
2614}
2615#endif
2616
2617#endif /* HAVE_POPEN */
2618
2619
2620#ifdef HAVE_SETUID
2621static char posix_setuid__doc__[] =
2622"setuid(uid) -> None\n\
2623Set the current process's user id.";
2624static PyObject *
2625posix_setuid(PyObject *self, PyObject *args)
2626{
2627	int uid;
2628	if (!PyArg_ParseTuple(args, "i:setuid", &uid))
2629		return NULL;
2630	if (setuid(uid) < 0)
2631		return posix_error();
2632	Py_INCREF(Py_None);
2633	return Py_None;
2634}
2635#endif /* HAVE_SETUID */
2636
2637
2638#ifdef HAVE_SETEUID
2639static char posix_seteuid__doc__[] =
2640"seteuid(uid) -> None\n\
2641Set the current process's effective user id.";
2642static PyObject *
2643posix_seteuid (PyObject *self, PyObject *args)
2644{
2645	int euid;
2646	if (!PyArg_ParseTuple(args, "i", &euid)) {
2647		return NULL;
2648	} else if (seteuid(euid) < 0) {
2649		return posix_error();
2650	} else {
2651		Py_INCREF(Py_None);
2652		return Py_None;
2653	}
2654}
2655#endif /* HAVE_SETEUID */
2656
2657#ifdef HAVE_SETEGID
2658static char posix_setegid__doc__[] =
2659"setegid(gid) -> None\n\
2660Set the current process's effective group id.";
2661static PyObject *
2662posix_setegid (PyObject *self, PyObject *args)
2663{
2664	int egid;
2665	if (!PyArg_ParseTuple(args, "i", &egid)) {
2666		return NULL;
2667	} else if (setegid(egid) < 0) {
2668		return posix_error();
2669	} else {
2670		Py_INCREF(Py_None);
2671		return Py_None;
2672	}
2673}
2674#endif /* HAVE_SETEGID */
2675
2676#ifdef HAVE_SETREUID
2677static char posix_setreuid__doc__[] =
2678"seteuid(ruid, euid) -> None\n\
2679Set the current process's real and effective user ids.";
2680static PyObject *
2681posix_setreuid (PyObject *self, PyObject *args)
2682{
2683	int ruid, euid;
2684	if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
2685		return NULL;
2686	} else if (setreuid(ruid, euid) < 0) {
2687		return posix_error();
2688	} else {
2689		Py_INCREF(Py_None);
2690		return Py_None;
2691	}
2692}
2693#endif /* HAVE_SETREUID */
2694
2695#ifdef HAVE_SETREGID
2696static char posix_setregid__doc__[] =
2697"setegid(rgid, egid) -> None\n\
2698Set the current process's real and effective group ids.";
2699static PyObject *
2700posix_setregid (PyObject *self, PyObject *args)
2701{
2702	int rgid, egid;
2703	if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
2704		return NULL;
2705	} else if (setregid(rgid, egid) < 0) {
2706		return posix_error();
2707	} else {
2708		Py_INCREF(Py_None);
2709		return Py_None;
2710	}
2711}
2712#endif /* HAVE_SETREGID */
2713
2714#ifdef HAVE_SETGID
2715static char posix_setgid__doc__[] =
2716"setgid(gid) -> None\n\
2717Set the current process's group id.";
2718
2719static PyObject *
2720posix_setgid(PyObject *self, PyObject *args)
2721{
2722	int gid;
2723	if (!PyArg_ParseTuple(args, "i:setgid", &gid))
2724		return NULL;
2725	if (setgid(gid) < 0)
2726		return posix_error();
2727	Py_INCREF(Py_None);
2728	return Py_None;
2729}
2730#endif /* HAVE_SETGID */
2731
2732
2733#ifdef HAVE_WAITPID
2734static char posix_waitpid__doc__[] =
2735"waitpid(pid, options) -> (pid, status)\n\
2736Wait for completion of a give child process.";
2737
2738static PyObject *
2739posix_waitpid(PyObject *self, PyObject *args)
2740{
2741	int pid, options;
2742#ifdef UNION_WAIT
2743	union wait status;
2744#define status_i (status.w_status)
2745#else
2746	int status;
2747#define status_i status
2748#endif
2749	status_i = 0;
2750
2751	if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
2752		return NULL;
2753	Py_BEGIN_ALLOW_THREADS
2754#ifdef NeXT
2755	pid = wait4(pid, &status, options, NULL);
2756#else
2757	pid = waitpid(pid, &status, options);
2758#endif
2759	Py_END_ALLOW_THREADS
2760	if (pid == -1)
2761		return posix_error();
2762	else
2763		return Py_BuildValue("ii", pid, status_i);
2764}
2765#endif /* HAVE_WAITPID */
2766
2767
2768#ifdef HAVE_WAIT
2769static char posix_wait__doc__[] =
2770"wait() -> (pid, status)\n\
2771Wait for completion of a child process.";
2772
2773static PyObject *
2774posix_wait(PyObject *self, PyObject *args)
2775{
2776	int pid;
2777#ifdef UNION_WAIT
2778	union wait status;
2779#define status_i (status.w_status)
2780#else
2781	int status;
2782#define status_i status
2783#endif
2784        if (!PyArg_ParseTuple(args, ":wait"))
2785                return NULL;
2786	status_i = 0;
2787	Py_BEGIN_ALLOW_THREADS
2788	pid = wait(&status);
2789	Py_END_ALLOW_THREADS
2790	if (pid == -1)
2791		return posix_error();
2792	else
2793		return Py_BuildValue("ii", pid, status_i);
2794#undef status_i
2795}
2796#endif
2797
2798
2799static char posix_lstat__doc__[] =
2800"lstat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
2801Like stat(path), but do not follow symbolic links.";
2802
2803static PyObject *
2804posix_lstat(PyObject *self, PyObject *args)
2805{
2806#ifdef HAVE_LSTAT
2807	return posix_do_stat(self, args, "s:lstat", lstat);
2808#else /* !HAVE_LSTAT */
2809	return posix_do_stat(self, args, "s:lstat", STAT);
2810#endif /* !HAVE_LSTAT */
2811}
2812
2813
2814#ifdef HAVE_READLINK
2815static char posix_readlink__doc__[] =
2816"readlink(path) -> path\n\
2817Return a string representing the path to which the symbolic link points.";
2818
2819static PyObject *
2820posix_readlink(PyObject *self, PyObject *args)
2821{
2822	char buf[MAXPATHLEN];
2823	char *path;
2824	int n;
2825	if (!PyArg_ParseTuple(args, "s:readlink", &path))
2826		return NULL;
2827	Py_BEGIN_ALLOW_THREADS
2828	n = readlink(path, buf, (int) sizeof buf);
2829	Py_END_ALLOW_THREADS
2830	if (n < 0)
2831		return posix_error_with_filename(path);
2832	return PyString_FromStringAndSize(buf, n);
2833}
2834#endif /* HAVE_READLINK */
2835
2836
2837#ifdef HAVE_SYMLINK
2838static char posix_symlink__doc__[] =
2839"symlink(src, dst) -> None\n\
2840Create a symbolic link.";
2841
2842static PyObject *
2843posix_symlink(PyObject *self, PyObject *args)
2844{
2845	return posix_2str(args, "ss:symlink", symlink);
2846}
2847#endif /* HAVE_SYMLINK */
2848
2849
2850#ifdef HAVE_TIMES
2851#ifndef HZ
2852#define HZ 60 /* Universal constant :-) */
2853#endif /* HZ */
2854
2855#if defined(PYCC_VACPP) && defined(PYOS_OS2)
2856static long
2857system_uptime(void)
2858{
2859    ULONG     value = 0;
2860
2861    Py_BEGIN_ALLOW_THREADS
2862    DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
2863    Py_END_ALLOW_THREADS
2864
2865    return value;
2866}
2867
2868static PyObject *
2869posix_times(PyObject *self, PyObject *args)
2870{
2871	if (!PyArg_ParseTuple(args, ":times"))
2872		return NULL;
2873
2874    /* Currently Only Uptime is Provided -- Others Later */
2875	return Py_BuildValue("ddddd",
2876			     (double)0 /* t.tms_utime / HZ */,
2877			     (double)0 /* t.tms_stime / HZ */,
2878			     (double)0 /* t.tms_cutime / HZ */,
2879			     (double)0 /* t.tms_cstime / HZ */,
2880			     (double)system_uptime() / 1000);
2881}
2882#else /* not OS2 */
2883static PyObject *
2884posix_times(PyObject *self, PyObject *args)
2885{
2886	struct tms t;
2887	clock_t c;
2888	if (!PyArg_ParseTuple(args, ":times"))
2889		return NULL;
2890	errno = 0;
2891	c = times(&t);
2892	if (c == (clock_t) -1)
2893		return posix_error();
2894	return Py_BuildValue("ddddd",
2895			     (double)t.tms_utime / HZ,
2896			     (double)t.tms_stime / HZ,
2897			     (double)t.tms_cutime / HZ,
2898			     (double)t.tms_cstime / HZ,
2899			     (double)c / HZ);
2900}
2901#endif /* not OS2 */
2902#endif /* HAVE_TIMES */
2903
2904
2905#ifdef MS_WIN32
2906#define HAVE_TIMES	/* so the method table will pick it up */
2907static PyObject *
2908posix_times(PyObject *self, PyObject *args)
2909{
2910	FILETIME create, exit, kernel, user;
2911	HANDLE hProc;
2912	if (!PyArg_ParseTuple(args, ":times"))
2913		return NULL;
2914	hProc = GetCurrentProcess();
2915	GetProcessTimes(hProc, &create, &exit, &kernel, &user);
2916	/* The fields of a FILETIME structure are the hi and lo part
2917	   of a 64-bit value expressed in 100 nanosecond units.
2918	   1e7 is one second in such units; 1e-7 the inverse.
2919	   429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
2920	*/
2921	return Py_BuildValue(
2922		"ddddd",
2923		(double)(kernel.dwHighDateTime*429.4967296 +
2924		         kernel.dwLowDateTime*1e-7),
2925		(double)(user.dwHighDateTime*429.4967296 +
2926		         user.dwLowDateTime*1e-7),
2927		(double)0,
2928		(double)0,
2929		(double)0);
2930}
2931#endif /* MS_WIN32 */
2932
2933#ifdef HAVE_TIMES
2934static char posix_times__doc__[] =
2935"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\
2936Return a tuple of floating point numbers indicating process times.";
2937#endif
2938
2939
2940#ifdef HAVE_SETSID
2941static char posix_setsid__doc__[] =
2942"setsid() -> None\n\
2943Call the system call setsid().";
2944
2945static PyObject *
2946posix_setsid(PyObject *self, PyObject *args)
2947{
2948	if (!PyArg_ParseTuple(args, ":setsid"))
2949		return NULL;
2950	if (setsid() < 0)
2951		return posix_error();
2952	Py_INCREF(Py_None);
2953	return Py_None;
2954}
2955#endif /* HAVE_SETSID */
2956
2957#ifdef HAVE_SETPGID
2958static char posix_setpgid__doc__[] =
2959"setpgid(pid, pgrp) -> None\n\
2960Call the system call setpgid().";
2961
2962static PyObject *
2963posix_setpgid(PyObject *self, PyObject *args)
2964{
2965	int pid, pgrp;
2966	if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
2967		return NULL;
2968	if (setpgid(pid, pgrp) < 0)
2969		return posix_error();
2970	Py_INCREF(Py_None);
2971	return Py_None;
2972}
2973#endif /* HAVE_SETPGID */
2974
2975
2976#ifdef HAVE_TCGETPGRP
2977static char posix_tcgetpgrp__doc__[] =
2978"tcgetpgrp(fd) -> pgid\n\
2979Return the process group associated with the terminal given by a fd.";
2980
2981static PyObject *
2982posix_tcgetpgrp(PyObject *self, PyObject *args)
2983{
2984	int fd, pgid;
2985	if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
2986		return NULL;
2987	pgid = tcgetpgrp(fd);
2988	if (pgid < 0)
2989		return posix_error();
2990	return PyInt_FromLong((long)pgid);
2991}
2992#endif /* HAVE_TCGETPGRP */
2993
2994
2995#ifdef HAVE_TCSETPGRP
2996static char posix_tcsetpgrp__doc__[] =
2997"tcsetpgrp(fd, pgid) -> None\n\
2998Set the process group associated with the terminal given by a fd.";
2999
3000static PyObject *
3001posix_tcsetpgrp(PyObject *self, PyObject *args)
3002{
3003	int fd, pgid;
3004	if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
3005		return NULL;
3006	if (tcsetpgrp(fd, pgid) < 0)
3007		return posix_error();
3008	Py_INCREF(Py_None);
3009	return Py_None;
3010}
3011#endif /* HAVE_TCSETPGRP */
3012
3013/* Functions acting on file descriptors */
3014
3015static char posix_open__doc__[] =
3016"open(filename, flag [, mode=0777]) -> fd\n\
3017Open a file (for low level IO).";
3018
3019static PyObject *
3020posix_open(PyObject *self, PyObject *args)
3021{
3022	char *file;
3023	int flag;
3024	int mode = 0777;
3025	int fd;
3026	if (!PyArg_ParseTuple(args, "si|i", &file, &flag, &mode))
3027		return NULL;
3028
3029	Py_BEGIN_ALLOW_THREADS
3030	fd = open(file, flag, mode);
3031	Py_END_ALLOW_THREADS
3032	if (fd < 0)
3033		return posix_error_with_filename(file);
3034	return PyInt_FromLong((long)fd);
3035}
3036
3037
3038static char posix_close__doc__[] =
3039"close(fd) -> None\n\
3040Close a file descriptor (for low level IO).";
3041
3042static PyObject *
3043posix_close(PyObject *self, PyObject *args)
3044{
3045	int fd, res;
3046	if (!PyArg_ParseTuple(args, "i:close", &fd))
3047		return NULL;
3048	Py_BEGIN_ALLOW_THREADS
3049	res = close(fd);
3050	Py_END_ALLOW_THREADS
3051	if (res < 0)
3052		return posix_error();
3053	Py_INCREF(Py_None);
3054	return Py_None;
3055}
3056
3057
3058static char posix_dup__doc__[] =
3059"dup(fd) -> fd2\n\
3060Return a duplicate of a file descriptor.";
3061
3062static PyObject *
3063posix_dup(PyObject *self, PyObject *args)
3064{
3065	int fd;
3066	if (!PyArg_ParseTuple(args, "i:dup", &fd))
3067		return NULL;
3068	Py_BEGIN_ALLOW_THREADS
3069	fd = dup(fd);
3070	Py_END_ALLOW_THREADS
3071	if (fd < 0)
3072		return posix_error();
3073	return PyInt_FromLong((long)fd);
3074}
3075
3076
3077static char posix_dup2__doc__[] =
3078"dup2(fd, fd2) -> None\n\
3079Duplicate file descriptor.";
3080
3081static PyObject *
3082posix_dup2(PyObject *self, PyObject *args)
3083{
3084	int fd, fd2, res;
3085	if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
3086		return NULL;
3087	Py_BEGIN_ALLOW_THREADS
3088	res = dup2(fd, fd2);
3089	Py_END_ALLOW_THREADS
3090	if (res < 0)
3091		return posix_error();
3092	Py_INCREF(Py_None);
3093	return Py_None;
3094}
3095
3096
3097static char posix_lseek__doc__[] =
3098"lseek(fd, pos, how) -> newpos\n\
3099Set the current position of a file descriptor.";
3100
3101static PyObject *
3102posix_lseek(PyObject *self, PyObject *args)
3103{
3104	int fd, how;
3105#ifdef MS_WIN64
3106	LONG_LONG pos, res;
3107#else
3108	off_t pos, res;
3109#endif
3110	PyObject *posobj;
3111	if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
3112		return NULL;
3113#ifdef SEEK_SET
3114	/* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
3115	switch (how) {
3116	case 0: how = SEEK_SET; break;
3117	case 1: how = SEEK_CUR; break;
3118	case 2: how = SEEK_END; break;
3119	}
3120#endif /* SEEK_END */
3121
3122#if !defined(HAVE_LARGEFILE_SUPPORT)
3123	pos = PyInt_AsLong(posobj);
3124#else
3125	pos = PyLong_Check(posobj) ?
3126		PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
3127#endif
3128	if (PyErr_Occurred())
3129		return NULL;
3130
3131	Py_BEGIN_ALLOW_THREADS
3132#ifdef MS_WIN64
3133	res = _lseeki64(fd, pos, how);
3134#else
3135	res = lseek(fd, pos, how);
3136#endif
3137	Py_END_ALLOW_THREADS
3138	if (res < 0)
3139		return posix_error();
3140
3141#if !defined(HAVE_LARGEFILE_SUPPORT)
3142	return PyInt_FromLong(res);
3143#else
3144	return PyLong_FromLongLong(res);
3145#endif
3146}
3147
3148
3149static char posix_read__doc__[] =
3150"read(fd, buffersize) -> string\n\
3151Read a file descriptor.";
3152
3153static PyObject *
3154posix_read(PyObject *self, PyObject *args)
3155{
3156	int fd, size, n;
3157	PyObject *buffer;
3158	if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
3159		return NULL;
3160	buffer = PyString_FromStringAndSize((char *)NULL, size);
3161	if (buffer == NULL)
3162		return NULL;
3163	Py_BEGIN_ALLOW_THREADS
3164	n = read(fd, PyString_AsString(buffer), size);
3165	Py_END_ALLOW_THREADS
3166	if (n < 0) {
3167		Py_DECREF(buffer);
3168		return posix_error();
3169	}
3170	if (n != size)
3171		_PyString_Resize(&buffer, n);
3172	return buffer;
3173}
3174
3175
3176static char posix_write__doc__[] =
3177"write(fd, string) -> byteswritten\n\
3178Write a string to a file descriptor.";
3179
3180static PyObject *
3181posix_write(PyObject *self, PyObject *args)
3182{
3183	int fd, size;
3184	char *buffer;
3185	if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
3186		return NULL;
3187	Py_BEGIN_ALLOW_THREADS
3188	size = write(fd, buffer, size);
3189	Py_END_ALLOW_THREADS
3190	if (size < 0)
3191		return posix_error();
3192	return PyInt_FromLong((long)size);
3193}
3194
3195
3196static char posix_fstat__doc__[]=
3197"fstat(fd) -> (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
3198Like stat(), but for an open file descriptor.";
3199
3200static PyObject *
3201posix_fstat(PyObject *self, PyObject *args)
3202{
3203	int fd;
3204	STRUCT_STAT st;
3205	int res;
3206	if (!PyArg_ParseTuple(args, "i:fstat", &fd))
3207		return NULL;
3208	Py_BEGIN_ALLOW_THREADS
3209	res = FSTAT(fd, &st);
3210	Py_END_ALLOW_THREADS
3211	if (res != 0)
3212		return posix_error();
3213
3214	return _pystat_fromstructstat(st);
3215}
3216
3217
3218static char posix_fdopen__doc__[] =
3219"fdopen(fd, [, mode='r' [, bufsize]]) -> file_object\n\
3220Return an open file object connected to a file descriptor.";
3221
3222static PyObject *
3223posix_fdopen(PyObject *self, PyObject *args)
3224{
3225	extern int fclose(FILE *);
3226	int fd;
3227	char *mode = "r";
3228	int bufsize = -1;
3229	FILE *fp;
3230	PyObject *f;
3231	if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
3232		return NULL;
3233
3234	Py_BEGIN_ALLOW_THREADS
3235	fp = fdopen(fd, mode);
3236	Py_END_ALLOW_THREADS
3237	if (fp == NULL)
3238		return posix_error();
3239	f = PyFile_FromFile(fp, "(fdopen)", mode, fclose);
3240	if (f != NULL)
3241		PyFile_SetBufSize(f, bufsize);
3242	return f;
3243}
3244
3245static char posix_isatty__doc__[] =
3246"isatty(fd) -> Boolean\n\
3247Return true if the file descriptor 'fd' is an open file descriptor\n\
3248connected to a terminal.";
3249
3250static PyObject *
3251posix_isatty(PyObject *self, PyObject *args)
3252{
3253	int fd;
3254	if (!PyArg_ParseTuple(args, "i:isatty", &fd))
3255		return NULL;
3256	return Py_BuildValue("i", isatty(fd));
3257}
3258
3259#ifdef HAVE_PIPE
3260static char posix_pipe__doc__[] =
3261"pipe() -> (read_end, write_end)\n\
3262Create a pipe.";
3263
3264static PyObject *
3265posix_pipe(PyObject *self, PyObject *args)
3266{
3267#if defined(PYOS_OS2)
3268    HFILE read, write;
3269    APIRET rc;
3270
3271    if (!PyArg_ParseTuple(args, ":pipe"))
3272        return NULL;
3273
3274	Py_BEGIN_ALLOW_THREADS
3275    rc = DosCreatePipe( &read, &write, 4096);
3276	Py_END_ALLOW_THREADS
3277    if (rc != NO_ERROR)
3278        return os2_error(rc);
3279
3280    return Py_BuildValue("(ii)", read, write);
3281#else
3282#if !defined(MS_WIN32)
3283	int fds[2];
3284	int res;
3285	if (!PyArg_ParseTuple(args, ":pipe"))
3286		return NULL;
3287	Py_BEGIN_ALLOW_THREADS
3288	res = pipe(fds);
3289	Py_END_ALLOW_THREADS
3290	if (res != 0)
3291		return posix_error();
3292	return Py_BuildValue("(ii)", fds[0], fds[1]);
3293#else /* MS_WIN32 */
3294	HANDLE read, write;
3295	int read_fd, write_fd;
3296	BOOL ok;
3297	if (!PyArg_ParseTuple(args, ":pipe"))
3298		return NULL;
3299	Py_BEGIN_ALLOW_THREADS
3300	ok = CreatePipe(&read, &write, NULL, 0);
3301	Py_END_ALLOW_THREADS
3302	if (!ok)
3303		return win32_error("CreatePipe", NULL);
3304	read_fd = _open_osfhandle((intptr_t)read, 0);
3305	write_fd = _open_osfhandle((intptr_t)write, 1);
3306	return Py_BuildValue("(ii)", read_fd, write_fd);
3307#endif /* MS_WIN32 */
3308#endif
3309}
3310#endif  /* HAVE_PIPE */
3311
3312
3313#ifdef HAVE_MKFIFO
3314static char posix_mkfifo__doc__[] =
3315"mkfifo(file, [, mode=0666]) -> None\n\
3316Create a FIFO (a POSIX named pipe).";
3317
3318static PyObject *
3319posix_mkfifo(PyObject *self, PyObject *args)
3320{
3321	char *file;
3322	int mode = 0666;
3323	int res;
3324	if (!PyArg_ParseTuple(args, "s|i:mkfifo", &file, &mode))
3325		return NULL;
3326	Py_BEGIN_ALLOW_THREADS
3327	res = mkfifo(file, mode);
3328	Py_END_ALLOW_THREADS
3329	if (res < 0)
3330		return posix_error();
3331	Py_INCREF(Py_None);
3332	return Py_None;
3333}
3334#endif
3335
3336
3337#ifdef HAVE_FTRUNCATE
3338static char posix_ftruncate__doc__[] =
3339"ftruncate(fd, length) -> None\n\
3340Truncate a file to a specified length.";
3341
3342static PyObject *
3343posix_ftruncate(PyObject *self, PyObject *args)
3344{
3345	int fd;
3346	off_t length;
3347	int res;
3348	PyObject *lenobj;
3349
3350	if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
3351		return NULL;
3352
3353#if !defined(HAVE_LARGEFILE_SUPPORT)
3354	length = PyInt_AsLong(lenobj);
3355#else
3356	length = PyLong_Check(lenobj) ?
3357		PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
3358#endif
3359	if (PyErr_Occurred())
3360		return NULL;
3361
3362	Py_BEGIN_ALLOW_THREADS
3363	res = ftruncate(fd, length);
3364	Py_END_ALLOW_THREADS
3365	if (res < 0) {
3366		PyErr_SetFromErrno(PyExc_IOError);
3367		return NULL;
3368	}
3369	Py_INCREF(Py_None);
3370	return Py_None;
3371}
3372#endif
3373
3374#ifdef NeXT
3375#define HAVE_PUTENV
3376/* Steve Spicklemire got this putenv from NeXTAnswers */
3377static int
3378putenv(char *newval)
3379{
3380	extern char **environ;
3381
3382	static int firstTime = 1;
3383	char **ep;
3384	char *cp;
3385	int esiz;
3386	char *np;
3387
3388	if (!(np = strchr(newval, '=')))
3389		return 1;
3390	*np = '\0';
3391
3392	/* look it up */
3393	for (ep=environ ; *ep ; ep++)
3394	{
3395		/* this should always be true... */
3396		if (cp = strchr(*ep, '='))
3397		{
3398			*cp = '\0';
3399			if (!strcmp(*ep, newval))
3400			{
3401				/* got it! */
3402				*cp = '=';
3403				break;
3404			}
3405			*cp = '=';
3406		}
3407		else
3408		{
3409			*np = '=';
3410			return 1;
3411		}
3412	}
3413
3414	*np = '=';
3415	if (*ep)
3416	{
3417		/* the string was already there:
3418		   just replace it with the new one */
3419		*ep = newval;
3420		return 0;
3421	}
3422
3423	/* expand environ by one */
3424	for (esiz=2, ep=environ ; *ep ; ep++)
3425		esiz++;
3426	if (firstTime)
3427	{
3428		char **epp;
3429		char **newenv;
3430		if (!(newenv = malloc(esiz * sizeof(char *))))
3431			return 1;
3432
3433		for (ep=environ, epp=newenv ; *ep ;)
3434			*epp++ = *ep++;
3435		*epp++ = newval;
3436		*epp = (char *) 0;
3437		environ = newenv;
3438	}
3439	else
3440	{
3441		if (!(environ = realloc(environ, esiz * sizeof(char *))))
3442			return 1;
3443		environ[esiz - 2] = newval;
3444		environ[esiz - 1] = (char *) 0;
3445		firstTime = 0;
3446	}
3447
3448	return 0;
3449}
3450#endif /* NeXT */
3451
3452
3453#ifdef HAVE_PUTENV
3454static char posix_putenv__doc__[] =
3455"putenv(key, value) -> None\n\
3456Change or add an environment variable.";
3457
3458#ifdef __BEOS__
3459/* We have putenv(), but not in the headers (as of PR2). - [cjh] */
3460int putenv( const char *str );
3461#endif
3462
3463/* Save putenv() parameters as values here, so we can collect them when they
3464 * get re-set with another call for the same key. */
3465static PyObject *posix_putenv_garbage;
3466
3467static PyObject *
3468posix_putenv(PyObject *self, PyObject *args)
3469{
3470        char *s1, *s2;
3471        char *new;
3472	PyObject *newstr;
3473
3474	if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
3475		return NULL;
3476
3477#if defined(PYOS_OS2)
3478    if (stricmp(s1, "BEGINLIBPATH") == 0) {
3479        APIRET rc;
3480
3481        if (strlen(s2) == 0)  /* If New Value is an Empty String */
3482            s2 = NULL;        /* Then OS/2 API Wants a NULL to Undefine It */
3483
3484        rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
3485        if (rc != NO_ERROR)
3486            return os2_error(rc);
3487
3488    } else if (stricmp(s1, "ENDLIBPATH") == 0) {
3489        APIRET rc;
3490
3491        if (strlen(s2) == 0)  /* If New Value is an Empty String */
3492            s2 = NULL;        /* Then OS/2 API Wants a NULL to Undefine It */
3493
3494        rc = DosSetExtLIBPATH(s2, END_LIBPATH);
3495        if (rc != NO_ERROR)
3496            return os2_error(rc);
3497    } else {
3498#endif
3499
3500	/* XXX This can leak memory -- not easy to fix :-( */
3501	newstr = PyString_FromStringAndSize(NULL, strlen(s1) + strlen(s2) + 2);
3502	if (newstr == NULL)
3503		return PyErr_NoMemory();
3504	new = PyString_AS_STRING(newstr);
3505	(void) sprintf(new, "%s=%s", s1, s2);
3506	if (putenv(new)) {
3507                posix_error();
3508                return NULL;
3509	}
3510	/* Install the first arg and newstr in posix_putenv_garbage;
3511	 * this will cause previous value to be collected.  This has to
3512	 * happen after the real putenv() call because the old value
3513	 * was still accessible until then. */
3514	if (PyDict_SetItem(posix_putenv_garbage,
3515			   PyTuple_GET_ITEM(args, 0), newstr)) {
3516		/* really not much we can do; just leak */
3517		PyErr_Clear();
3518	}
3519	else {
3520		Py_DECREF(newstr);
3521	}
3522
3523#if defined(PYOS_OS2)
3524    }
3525#endif
3526	Py_INCREF(Py_None);
3527        return Py_None;
3528}
3529#endif /* putenv */
3530
3531#ifdef HAVE_STRERROR
3532static char posix_strerror__doc__[] =
3533"strerror(code) -> string\n\
3534Translate an error code to a message string.";
3535
3536PyObject *
3537posix_strerror(PyObject *self, PyObject *args)
3538{
3539	int code;
3540	char *message;
3541	if (!PyArg_ParseTuple(args, "i:strerror", &code))
3542		return NULL;
3543	message = strerror(code);
3544	if (message == NULL) {
3545		PyErr_SetString(PyExc_ValueError,
3546				"strerror code out of range");
3547		return NULL;
3548	}
3549	return PyString_FromString(message);
3550}
3551#endif /* strerror */
3552
3553
3554#ifdef HAVE_SYS_WAIT_H
3555
3556#ifdef WIFSTOPPED
3557static char posix_WIFSTOPPED__doc__[] =
3558"WIFSTOPPED(status) -> Boolean\n\
3559Return true if the process returning 'status' was stopped.";
3560
3561static PyObject *
3562posix_WIFSTOPPED(PyObject *self, PyObject *args)
3563{
3564#ifdef UNION_WAIT
3565	union wait status;
3566#define status_i (status.w_status)
3567#else
3568	int status;
3569#define status_i status
3570#endif
3571	status_i = 0;
3572
3573	if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
3574	{
3575		return NULL;
3576	}
3577
3578	return Py_BuildValue("i", WIFSTOPPED(status));
3579#undef status_i
3580}
3581#endif /* WIFSTOPPED */
3582
3583#ifdef WIFSIGNALED
3584static char posix_WIFSIGNALED__doc__[] =
3585"WIFSIGNALED(status) -> Boolean\n\
3586Return true if the process returning 'status' was terminated by a signal.";
3587
3588static PyObject *
3589posix_WIFSIGNALED(PyObject *self, PyObject *args)
3590{
3591#ifdef UNION_WAIT
3592	union wait status;
3593#define status_i (status.w_status)
3594#else
3595	int status;
3596#define status_i status
3597#endif
3598	status_i = 0;
3599
3600	if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
3601	{
3602		return NULL;
3603	}
3604
3605	return Py_BuildValue("i", WIFSIGNALED(status));
3606#undef status_i
3607}
3608#endif /* WIFSIGNALED */
3609
3610#ifdef WIFEXITED
3611static char posix_WIFEXITED__doc__[] =
3612"WIFEXITED(status) -> Boolean\n\
3613Return true if the process returning 'status' exited using the exit()\n\
3614system call.";
3615
3616static PyObject *
3617posix_WIFEXITED(PyObject *self, PyObject *args)
3618{
3619#ifdef UNION_WAIT
3620	union wait status;
3621#define status_i (status.w_status)
3622#else
3623	int status;
3624#define status_i status
3625#endif
3626	status_i = 0;
3627
3628	if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
3629	{
3630		return NULL;
3631	}
3632
3633	return Py_BuildValue("i", WIFEXITED(status));
3634#undef status_i
3635}
3636#endif /* WIFEXITED */
3637
3638#ifdef WEXITSTATUS
3639static char posix_WEXITSTATUS__doc__[] =
3640"WEXITSTATUS(status) -> integer\n\
3641Return the process return code from 'status'.";
3642
3643static PyObject *
3644posix_WEXITSTATUS(PyObject *self, PyObject *args)
3645{
3646#ifdef UNION_WAIT
3647	union wait status;
3648#define status_i (status.w_status)
3649#else
3650	int status;
3651#define status_i status
3652#endif
3653	status_i = 0;
3654
3655	if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
3656	{
3657		return NULL;
3658	}
3659
3660	return Py_BuildValue("i", WEXITSTATUS(status));
3661#undef status_i
3662}
3663#endif /* WEXITSTATUS */
3664
3665#ifdef WTERMSIG
3666static char posix_WTERMSIG__doc__[] =
3667"WTERMSIG(status) -> integer\n\
3668Return the signal that terminated the process that provided the 'status'\n\
3669value.";
3670
3671static PyObject *
3672posix_WTERMSIG(PyObject *self, PyObject *args)
3673{
3674#ifdef UNION_WAIT
3675	union wait status;
3676#define status_i (status.w_status)
3677#else
3678	int status;
3679#define status_i status
3680#endif
3681	status_i = 0;
3682
3683	if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
3684	{
3685		return NULL;
3686	}
3687
3688	return Py_BuildValue("i", WTERMSIG(status));
3689#undef status_i
3690}
3691#endif /* WTERMSIG */
3692
3693#ifdef WSTOPSIG
3694static char posix_WSTOPSIG__doc__[] =
3695"WSTOPSIG(status) -> integer\n\
3696Return the signal that stopped the process that provided the 'status' value.";
3697
3698static PyObject *
3699posix_WSTOPSIG(PyObject *self, PyObject *args)
3700{
3701#ifdef UNION_WAIT
3702	union wait status;
3703#define status_i (status.w_status)
3704#else
3705	int status;
3706#define status_i status
3707#endif
3708	status_i = 0;
3709
3710	if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
3711	{
3712		return NULL;
3713	}
3714
3715	return Py_BuildValue("i", WSTOPSIG(status));
3716#undef status_i
3717}
3718#endif /* WSTOPSIG */
3719
3720#endif /* HAVE_SYS_WAIT_H */
3721
3722
3723#if defined(HAVE_FSTATVFS)
3724#ifdef _SCO_DS
3725/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
3726   needed definitions in sys/statvfs.h */
3727#define _SVID3
3728#endif
3729#include <sys/statvfs.h>
3730
3731static char posix_fstatvfs__doc__[] =
3732"fstatvfs(fd) -> \n\
3733 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
3734Perform an fstatvfs system call on the given fd.";
3735
3736static PyObject *
3737posix_fstatvfs(PyObject *self, PyObject *args)
3738{
3739	int fd, res;
3740	struct statvfs st;
3741	if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
3742		return NULL;
3743	Py_BEGIN_ALLOW_THREADS
3744	res = fstatvfs(fd, &st);
3745	Py_END_ALLOW_THREADS
3746	if (res != 0)
3747		return posix_error();
3748#if !defined(HAVE_LARGEFILE_SUPPORT)
3749	return Py_BuildValue("(llllllllll)",
3750		    (long) st.f_bsize,
3751		    (long) st.f_frsize,
3752		    (long) st.f_blocks,
3753		    (long) st.f_bfree,
3754		    (long) st.f_bavail,
3755		    (long) st.f_files,
3756		    (long) st.f_ffree,
3757		    (long) st.f_favail,
3758		    (long) st.f_flag,
3759		    (long) st.f_namemax);
3760#else
3761	return Py_BuildValue("(llLLLLLLll)",
3762		    (long) st.f_bsize,
3763		    (long) st.f_frsize,
3764		    (LONG_LONG) st.f_blocks,
3765		    (LONG_LONG) st.f_bfree,
3766		    (LONG_LONG) st.f_bavail,
3767		    (LONG_LONG) st.f_files,
3768		    (LONG_LONG) st.f_ffree,
3769		    (LONG_LONG) st.f_favail,
3770		    (long) st.f_flag,
3771		    (long) st.f_namemax);
3772#endif
3773}
3774#endif /* HAVE_FSTATVFS */
3775
3776
3777#if defined(HAVE_STATVFS)
3778#include <sys/statvfs.h>
3779
3780static char posix_statvfs__doc__[] =
3781"statvfs(path) -> \n\
3782 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
3783Perform a statvfs system call on the given path.";
3784
3785static PyObject *
3786posix_statvfs(PyObject *self, PyObject *args)
3787{
3788	char *path;
3789	int res;
3790	struct statvfs st;
3791	if (!PyArg_ParseTuple(args, "s:statvfs", &path))
3792		return NULL;
3793	Py_BEGIN_ALLOW_THREADS
3794	res = statvfs(path, &st);
3795	Py_END_ALLOW_THREADS
3796	if (res != 0)
3797		return posix_error_with_filename(path);
3798#if !defined(HAVE_LARGEFILE_SUPPORT)
3799	return Py_BuildValue("(llllllllll)",
3800		    (long) st.f_bsize,
3801		    (long) st.f_frsize,
3802		    (long) st.f_blocks,
3803		    (long) st.f_bfree,
3804		    (long) st.f_bavail,
3805		    (long) st.f_files,
3806		    (long) st.f_ffree,
3807		    (long) st.f_favail,
3808		    (long) st.f_flag,
3809		    (long) st.f_namemax);
3810#else	/* HAVE_LARGEFILE_SUPPORT */
3811	return Py_BuildValue("(llLLLLLLll)",
3812		    (long) st.f_bsize,
3813		    (long) st.f_frsize,
3814		    (LONG_LONG) st.f_blocks,
3815		    (LONG_LONG) st.f_bfree,
3816		    (LONG_LONG) st.f_bavail,
3817		    (LONG_LONG) st.f_files,
3818		    (LONG_LONG) st.f_ffree,
3819		    (LONG_LONG) st.f_favail,
3820		    (long) st.f_flag,
3821		    (long) st.f_namemax);
3822#endif
3823}
3824#endif /* HAVE_STATVFS */
3825
3826
3827#ifdef HAVE_TEMPNAM
3828static char posix_tempnam__doc__[] = "\
3829tempnam([dir[, prefix]]) -> string\n\
3830Return a unique name for a temporary file.\n\
3831The directory and a short may be specified as strings; they may be omitted\n\
3832or None if not needed.";
3833
3834static PyObject *
3835posix_tempnam(PyObject *self, PyObject *args)
3836{
3837    PyObject *result = NULL;
3838    char *dir = NULL;
3839    char *pfx = NULL;
3840    char *name;
3841
3842    if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
3843        return NULL;
3844    name = tempnam(dir, pfx);
3845    if (name == NULL)
3846        return PyErr_NoMemory();
3847    result = PyString_FromString(name);
3848    free(name);
3849    return result;
3850}
3851#endif
3852
3853
3854#ifdef HAVE_TMPFILE
3855static char posix_tmpfile__doc__[] = "\
3856tmpfile() -> file object\n\
3857Create a temporary file with no directory entries.";
3858
3859static PyObject *
3860posix_tmpfile(PyObject *self, PyObject *args)
3861{
3862    FILE *fp;
3863
3864    if (!PyArg_ParseTuple(args, ":tmpfile"))
3865        return NULL;
3866    fp = tmpfile();
3867    if (fp == NULL)
3868        return posix_error();
3869    return PyFile_FromFile(fp, "<tmpfile>", "w+", fclose);
3870}
3871#endif
3872
3873
3874#ifdef HAVE_TMPNAM
3875static char posix_tmpnam__doc__[] = "\
3876tmpnam() -> string\n\
3877Return a unique name for a temporary file.";
3878
3879static PyObject *
3880posix_tmpnam(PyObject *self, PyObject *args)
3881{
3882    char buffer[L_tmpnam];
3883    char *name;
3884
3885    if (!PyArg_ParseTuple(args, ":tmpnam"))
3886        return NULL;
3887#ifdef USE_TMPNAM_R
3888    name = tmpnam_r(buffer);
3889#else
3890    name = tmpnam(buffer);
3891#endif
3892    if (name == NULL) {
3893        PyErr_SetObject(PyExc_OSError,
3894                        Py_BuildValue("is", 0,
3895#ifdef USE_TMPNAM_R
3896                                      "unexpected NULL from tmpnam_r"
3897#else
3898                                      "unexpected NULL from tmpnam"
3899#endif
3900                                      ));
3901        return NULL;
3902    }
3903    return PyString_FromString(buffer);
3904}
3905#endif
3906
3907
3908/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
3909 * It maps strings representing configuration variable names to
3910 * integer values, allowing those functions to be called with the
3911 * magic names instead of polluting the module's namespace with tons of
3912 * rarely-used constants.  There are three separate tables that use
3913 * these definitions.
3914 *
3915 * This code is always included, even if none of the interfaces that
3916 * need it are included.  The #if hackery needed to avoid it would be
3917 * sufficiently pervasive that it's not worth the loss of readability.
3918 */
3919struct constdef {
3920    char *name;
3921    long value;
3922};
3923
3924static int
3925conv_confname(PyObject *arg, int *valuep, struct constdef *table,
3926	      size_t tablesize)
3927{
3928    if (PyInt_Check(arg)) {
3929        *valuep = PyInt_AS_LONG(arg);
3930        return 1;
3931    }
3932    if (PyString_Check(arg)) {
3933        /* look up the value in the table using a binary search */
3934        size_t lo = 0;
3935		size_t mid;
3936        size_t hi = tablesize;
3937        int cmp;
3938        char *confname = PyString_AS_STRING(arg);
3939        while (lo < hi) {
3940            mid = (lo + hi) / 2;
3941            cmp = strcmp(confname, table[mid].name);
3942            if (cmp < 0)
3943                hi = mid;
3944            else if (cmp > 0)
3945                lo = mid + 1;
3946            else {
3947                *valuep = table[mid].value;
3948                return 1;
3949            }
3950        }
3951        PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
3952    }
3953    else
3954        PyErr_SetString(PyExc_TypeError,
3955                        "configuration names must be strings or integers");
3956    return 0;
3957}
3958
3959
3960#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
3961static struct constdef  posix_constants_pathconf[] = {
3962#ifdef _PC_ABI_AIO_XFER_MAX
3963    {"PC_ABI_AIO_XFER_MAX",	_PC_ABI_AIO_XFER_MAX},
3964#endif
3965#ifdef _PC_ABI_ASYNC_IO
3966    {"PC_ABI_ASYNC_IO",	_PC_ABI_ASYNC_IO},
3967#endif
3968#ifdef _PC_ASYNC_IO
3969    {"PC_ASYNC_IO",	_PC_ASYNC_IO},
3970#endif
3971#ifdef _PC_CHOWN_RESTRICTED
3972    {"PC_CHOWN_RESTRICTED",	_PC_CHOWN_RESTRICTED},
3973#endif
3974#ifdef _PC_FILESIZEBITS
3975    {"PC_FILESIZEBITS",	_PC_FILESIZEBITS},
3976#endif
3977#ifdef _PC_LAST
3978    {"PC_LAST",	_PC_LAST},
3979#endif
3980#ifdef _PC_LINK_MAX
3981    {"PC_LINK_MAX",	_PC_LINK_MAX},
3982#endif
3983#ifdef _PC_MAX_CANON
3984    {"PC_MAX_CANON",	_PC_MAX_CANON},
3985#endif
3986#ifdef _PC_MAX_INPUT
3987    {"PC_MAX_INPUT",	_PC_MAX_INPUT},
3988#endif
3989#ifdef _PC_NAME_MAX
3990    {"PC_NAME_MAX",	_PC_NAME_MAX},
3991#endif
3992#ifdef _PC_NO_TRUNC
3993    {"PC_NO_TRUNC",	_PC_NO_TRUNC},
3994#endif
3995#ifdef _PC_PATH_MAX
3996    {"PC_PATH_MAX",	_PC_PATH_MAX},
3997#endif
3998#ifdef _PC_PIPE_BUF
3999    {"PC_PIPE_BUF",	_PC_PIPE_BUF},
4000#endif
4001#ifdef _PC_PRIO_IO
4002    {"PC_PRIO_IO",	_PC_PRIO_IO},
4003#endif
4004#ifdef _PC_SOCK_MAXBUF
4005    {"PC_SOCK_MAXBUF",	_PC_SOCK_MAXBUF},
4006#endif
4007#ifdef _PC_SYNC_IO
4008    {"PC_SYNC_IO",	_PC_SYNC_IO},
4009#endif
4010#ifdef _PC_VDISABLE
4011    {"PC_VDISABLE",	_PC_VDISABLE},
4012#endif
4013};
4014
4015static int
4016conv_path_confname(PyObject *arg, int *valuep)
4017{
4018    return conv_confname(arg, valuep, posix_constants_pathconf,
4019                         sizeof(posix_constants_pathconf)
4020                           / sizeof(struct constdef));
4021}
4022#endif
4023
4024#ifdef HAVE_FPATHCONF
4025static char posix_fpathconf__doc__[] = "\
4026fpathconf(fd, name) -> integer\n\
4027Return the configuration limit name for the file descriptor fd.\n\
4028If there is no limit, return -1.";
4029
4030static PyObject *
4031posix_fpathconf(PyObject *self, PyObject *args)
4032{
4033    PyObject *result = NULL;
4034    int name, fd;
4035
4036    if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
4037                         conv_path_confname, &name)) {
4038        long limit;
4039
4040        errno = 0;
4041        limit = fpathconf(fd, name);
4042        if (limit == -1 && errno != 0)
4043            posix_error();
4044        else
4045            result = PyInt_FromLong(limit);
4046    }
4047    return result;
4048}
4049#endif
4050
4051
4052#ifdef HAVE_PATHCONF
4053static char posix_pathconf__doc__[] = "\
4054pathconf(path, name) -> integer\n\
4055Return the configuration limit name for the file or directory path.\n\
4056If there is no limit, return -1.";
4057
4058static PyObject *
4059posix_pathconf(PyObject *self, PyObject *args)
4060{
4061    PyObject *result = NULL;
4062    int name;
4063    char *path;
4064
4065    if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
4066                         conv_path_confname, &name)) {
4067        long limit;
4068
4069        errno = 0;
4070        limit = pathconf(path, name);
4071        if (limit == -1 && errno != 0) {
4072            if (errno == EINVAL)
4073                /* could be a path or name problem */
4074                posix_error();
4075            else
4076                posix_error_with_filename(path);
4077        }
4078        else
4079            result = PyInt_FromLong(limit);
4080    }
4081    return result;
4082}
4083#endif
4084
4085#ifdef HAVE_CONFSTR
4086static struct constdef posix_constants_confstr[] = {
4087#ifdef _CS_ARCHITECTURE
4088    {"CS_ARCHITECTURE",	_CS_ARCHITECTURE},
4089#endif
4090#ifdef _CS_HOSTNAME
4091    {"CS_HOSTNAME",	_CS_HOSTNAME},
4092#endif
4093#ifdef _CS_HW_PROVIDER
4094    {"CS_HW_PROVIDER",	_CS_HW_PROVIDER},
4095#endif
4096#ifdef _CS_HW_SERIAL
4097    {"CS_HW_SERIAL",	_CS_HW_SERIAL},
4098#endif
4099#ifdef _CS_INITTAB_NAME
4100    {"CS_INITTAB_NAME",	_CS_INITTAB_NAME},
4101#endif
4102#ifdef _CS_LFS64_CFLAGS
4103    {"CS_LFS64_CFLAGS",	_CS_LFS64_CFLAGS},
4104#endif
4105#ifdef _CS_LFS64_LDFLAGS
4106    {"CS_LFS64_LDFLAGS",	_CS_LFS64_LDFLAGS},
4107#endif
4108#ifdef _CS_LFS64_LIBS
4109    {"CS_LFS64_LIBS",	_CS_LFS64_LIBS},
4110#endif
4111#ifdef _CS_LFS64_LINTFLAGS
4112    {"CS_LFS64_LINTFLAGS",	_CS_LFS64_LINTFLAGS},
4113#endif
4114#ifdef _CS_LFS_CFLAGS
4115    {"CS_LFS_CFLAGS",	_CS_LFS_CFLAGS},
4116#endif
4117#ifdef _CS_LFS_LDFLAGS
4118    {"CS_LFS_LDFLAGS",	_CS_LFS_LDFLAGS},
4119#endif
4120#ifdef _CS_LFS_LIBS
4121    {"CS_LFS_LIBS",	_CS_LFS_LIBS},
4122#endif
4123#ifdef _CS_LFS_LINTFLAGS
4124    {"CS_LFS_LINTFLAGS",	_CS_LFS_LINTFLAGS},
4125#endif
4126#ifdef _CS_MACHINE
4127    {"CS_MACHINE",	_CS_MACHINE},
4128#endif
4129#ifdef _CS_PATH
4130    {"CS_PATH",	_CS_PATH},
4131#endif
4132#ifdef _CS_RELEASE
4133    {"CS_RELEASE",	_CS_RELEASE},
4134#endif
4135#ifdef _CS_SRPC_DOMAIN
4136    {"CS_SRPC_DOMAIN",	_CS_SRPC_DOMAIN},
4137#endif
4138#ifdef _CS_SYSNAME
4139    {"CS_SYSNAME",	_CS_SYSNAME},
4140#endif
4141#ifdef _CS_VERSION
4142    {"CS_VERSION",	_CS_VERSION},
4143#endif
4144#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
4145    {"CS_XBS5_ILP32_OFF32_CFLAGS",	_CS_XBS5_ILP32_OFF32_CFLAGS},
4146#endif
4147#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
4148    {"CS_XBS5_ILP32_OFF32_LDFLAGS",	_CS_XBS5_ILP32_OFF32_LDFLAGS},
4149#endif
4150#ifdef _CS_XBS5_ILP32_OFF32_LIBS
4151    {"CS_XBS5_ILP32_OFF32_LIBS",	_CS_XBS5_ILP32_OFF32_LIBS},
4152#endif
4153#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
4154    {"CS_XBS5_ILP32_OFF32_LINTFLAGS",	_CS_XBS5_ILP32_OFF32_LINTFLAGS},
4155#endif
4156#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
4157    {"CS_XBS5_ILP32_OFFBIG_CFLAGS",	_CS_XBS5_ILP32_OFFBIG_CFLAGS},
4158#endif
4159#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
4160    {"CS_XBS5_ILP32_OFFBIG_LDFLAGS",	_CS_XBS5_ILP32_OFFBIG_LDFLAGS},
4161#endif
4162#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
4163    {"CS_XBS5_ILP32_OFFBIG_LIBS",	_CS_XBS5_ILP32_OFFBIG_LIBS},
4164#endif
4165#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
4166    {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS",	_CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
4167#endif
4168#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
4169    {"CS_XBS5_LP64_OFF64_CFLAGS",	_CS_XBS5_LP64_OFF64_CFLAGS},
4170#endif
4171#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
4172    {"CS_XBS5_LP64_OFF64_LDFLAGS",	_CS_XBS5_LP64_OFF64_LDFLAGS},
4173#endif
4174#ifdef _CS_XBS5_LP64_OFF64_LIBS
4175    {"CS_XBS5_LP64_OFF64_LIBS",	_CS_XBS5_LP64_OFF64_LIBS},
4176#endif
4177#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
4178    {"CS_XBS5_LP64_OFF64_LINTFLAGS",	_CS_XBS5_LP64_OFF64_LINTFLAGS},
4179#endif
4180#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
4181    {"CS_XBS5_LPBIG_OFFBIG_CFLAGS",	_CS_XBS5_LPBIG_OFFBIG_CFLAGS},
4182#endif
4183#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
4184    {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS",	_CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
4185#endif
4186#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
4187    {"CS_XBS5_LPBIG_OFFBIG_LIBS",	_CS_XBS5_LPBIG_OFFBIG_LIBS},
4188#endif
4189#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
4190    {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS",	_CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
4191#endif
4192#ifdef _MIPS_CS_AVAIL_PROCESSORS
4193    {"MIPS_CS_AVAIL_PROCESSORS",	_MIPS_CS_AVAIL_PROCESSORS},
4194#endif
4195#ifdef _MIPS_CS_BASE
4196    {"MIPS_CS_BASE",	_MIPS_CS_BASE},
4197#endif
4198#ifdef _MIPS_CS_HOSTID
4199    {"MIPS_CS_HOSTID",	_MIPS_CS_HOSTID},
4200#endif
4201#ifdef _MIPS_CS_HW_NAME
4202    {"MIPS_CS_HW_NAME",	_MIPS_CS_HW_NAME},
4203#endif
4204#ifdef _MIPS_CS_NUM_PROCESSORS
4205    {"MIPS_CS_NUM_PROCESSORS",	_MIPS_CS_NUM_PROCESSORS},
4206#endif
4207#ifdef _MIPS_CS_OSREL_MAJ
4208    {"MIPS_CS_OSREL_MAJ",	_MIPS_CS_OSREL_MAJ},
4209#endif
4210#ifdef _MIPS_CS_OSREL_MIN
4211    {"MIPS_CS_OSREL_MIN",	_MIPS_CS_OSREL_MIN},
4212#endif
4213#ifdef _MIPS_CS_OSREL_PATCH
4214    {"MIPS_CS_OSREL_PATCH",	_MIPS_CS_OSREL_PATCH},
4215#endif
4216#ifdef _MIPS_CS_OS_NAME
4217    {"MIPS_CS_OS_NAME",	_MIPS_CS_OS_NAME},
4218#endif
4219#ifdef _MIPS_CS_OS_PROVIDER
4220    {"MIPS_CS_OS_PROVIDER",	_MIPS_CS_OS_PROVIDER},
4221#endif
4222#ifdef _MIPS_CS_PROCESSORS
4223    {"MIPS_CS_PROCESSORS",	_MIPS_CS_PROCESSORS},
4224#endif
4225#ifdef _MIPS_CS_SERIAL
4226    {"MIPS_CS_SERIAL",	_MIPS_CS_SERIAL},
4227#endif
4228#ifdef _MIPS_CS_VENDOR
4229    {"MIPS_CS_VENDOR",	_MIPS_CS_VENDOR},
4230#endif
4231};
4232
4233static int
4234conv_confstr_confname(PyObject *arg, int *valuep)
4235{
4236    return conv_confname(arg, valuep, posix_constants_confstr,
4237                         sizeof(posix_constants_confstr)
4238                           / sizeof(struct constdef));
4239}
4240
4241static char posix_confstr__doc__[] = "\
4242confstr(name) -> string\n\
4243Return a string-valued system configuration variable.";
4244
4245static PyObject *
4246posix_confstr(PyObject *self, PyObject *args)
4247{
4248    PyObject *result = NULL;
4249    int name;
4250    char buffer[64];
4251
4252    if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
4253        int len = confstr(name, buffer, sizeof(buffer));
4254
4255        errno = 0;
4256        if (len == 0) {
4257            if (errno != 0)
4258                posix_error();
4259            else
4260                result = PyString_FromString("");
4261        }
4262        else {
4263            if (len >= sizeof(buffer)) {
4264                result = PyString_FromStringAndSize(NULL, len);
4265                if (result != NULL)
4266                    confstr(name, PyString_AS_STRING(result), len+1);
4267            }
4268            else
4269                result = PyString_FromString(buffer);
4270        }
4271    }
4272    return result;
4273}
4274#endif
4275
4276
4277#ifdef HAVE_SYSCONF
4278static struct constdef posix_constants_sysconf[] = {
4279#ifdef _SC_2_CHAR_TERM
4280    {"SC_2_CHAR_TERM",	_SC_2_CHAR_TERM},
4281#endif
4282#ifdef _SC_2_C_BIND
4283    {"SC_2_C_BIND",	_SC_2_C_BIND},
4284#endif
4285#ifdef _SC_2_C_DEV
4286    {"SC_2_C_DEV",	_SC_2_C_DEV},
4287#endif
4288#ifdef _SC_2_C_VERSION
4289    {"SC_2_C_VERSION",	_SC_2_C_VERSION},
4290#endif
4291#ifdef _SC_2_FORT_DEV
4292    {"SC_2_FORT_DEV",	_SC_2_FORT_DEV},
4293#endif
4294#ifdef _SC_2_FORT_RUN
4295    {"SC_2_FORT_RUN",	_SC_2_FORT_RUN},
4296#endif
4297#ifdef _SC_2_LOCALEDEF
4298    {"SC_2_LOCALEDEF",	_SC_2_LOCALEDEF},
4299#endif
4300#ifdef _SC_2_SW_DEV
4301    {"SC_2_SW_DEV",	_SC_2_SW_DEV},
4302#endif
4303#ifdef _SC_2_UPE
4304    {"SC_2_UPE",	_SC_2_UPE},
4305#endif
4306#ifdef _SC_2_VERSION
4307    {"SC_2_VERSION",	_SC_2_VERSION},
4308#endif
4309#ifdef _SC_ABI_ASYNCHRONOUS_IO
4310    {"SC_ABI_ASYNCHRONOUS_IO",	_SC_ABI_ASYNCHRONOUS_IO},
4311#endif
4312#ifdef _SC_ACL
4313    {"SC_ACL",	_SC_ACL},
4314#endif
4315#ifdef _SC_AIO_LISTIO_MAX
4316    {"SC_AIO_LISTIO_MAX",	_SC_AIO_LISTIO_MAX},
4317#endif
4318#ifdef _SC_AIO_MAX
4319    {"SC_AIO_MAX",	_SC_AIO_MAX},
4320#endif
4321#ifdef _SC_AIO_PRIO_DELTA_MAX
4322    {"SC_AIO_PRIO_DELTA_MAX",	_SC_AIO_PRIO_DELTA_MAX},
4323#endif
4324#ifdef _SC_ARG_MAX
4325    {"SC_ARG_MAX",	_SC_ARG_MAX},
4326#endif
4327#ifdef _SC_ASYNCHRONOUS_IO
4328    {"SC_ASYNCHRONOUS_IO",	_SC_ASYNCHRONOUS_IO},
4329#endif
4330#ifdef _SC_ATEXIT_MAX
4331    {"SC_ATEXIT_MAX",	_SC_ATEXIT_MAX},
4332#endif
4333#ifdef _SC_AUDIT
4334    {"SC_AUDIT",	_SC_AUDIT},
4335#endif
4336#ifdef _SC_AVPHYS_PAGES
4337    {"SC_AVPHYS_PAGES",	_SC_AVPHYS_PAGES},
4338#endif
4339#ifdef _SC_BC_BASE_MAX
4340    {"SC_BC_BASE_MAX",	_SC_BC_BASE_MAX},
4341#endif
4342#ifdef _SC_BC_DIM_MAX
4343    {"SC_BC_DIM_MAX",	_SC_BC_DIM_MAX},
4344#endif
4345#ifdef _SC_BC_SCALE_MAX
4346    {"SC_BC_SCALE_MAX",	_SC_BC_SCALE_MAX},
4347#endif
4348#ifdef _SC_BC_STRING_MAX
4349    {"SC_BC_STRING_MAX",	_SC_BC_STRING_MAX},
4350#endif
4351#ifdef _SC_CAP
4352    {"SC_CAP",	_SC_CAP},
4353#endif
4354#ifdef _SC_CHARCLASS_NAME_MAX
4355    {"SC_CHARCLASS_NAME_MAX",	_SC_CHARCLASS_NAME_MAX},
4356#endif
4357#ifdef _SC_CHAR_BIT
4358    {"SC_CHAR_BIT",	_SC_CHAR_BIT},
4359#endif
4360#ifdef _SC_CHAR_MAX
4361    {"SC_CHAR_MAX",	_SC_CHAR_MAX},
4362#endif
4363#ifdef _SC_CHAR_MIN
4364    {"SC_CHAR_MIN",	_SC_CHAR_MIN},
4365#endif
4366#ifdef _SC_CHILD_MAX
4367    {"SC_CHILD_MAX",	_SC_CHILD_MAX},
4368#endif
4369#ifdef _SC_CLK_TCK
4370    {"SC_CLK_TCK",	_SC_CLK_TCK},
4371#endif
4372#ifdef _SC_COHER_BLKSZ
4373    {"SC_COHER_BLKSZ",	_SC_COHER_BLKSZ},
4374#endif
4375#ifdef _SC_COLL_WEIGHTS_MAX
4376    {"SC_COLL_WEIGHTS_MAX",	_SC_COLL_WEIGHTS_MAX},
4377#endif
4378#ifdef _SC_DCACHE_ASSOC
4379    {"SC_DCACHE_ASSOC",	_SC_DCACHE_ASSOC},
4380#endif
4381#ifdef _SC_DCACHE_BLKSZ
4382    {"SC_DCACHE_BLKSZ",	_SC_DCACHE_BLKSZ},
4383#endif
4384#ifdef _SC_DCACHE_LINESZ
4385    {"SC_DCACHE_LINESZ",	_SC_DCACHE_LINESZ},
4386#endif
4387#ifdef _SC_DCACHE_SZ
4388    {"SC_DCACHE_SZ",	_SC_DCACHE_SZ},
4389#endif
4390#ifdef _SC_DCACHE_TBLKSZ
4391    {"SC_DCACHE_TBLKSZ",	_SC_DCACHE_TBLKSZ},
4392#endif
4393#ifdef _SC_DELAYTIMER_MAX
4394    {"SC_DELAYTIMER_MAX",	_SC_DELAYTIMER_MAX},
4395#endif
4396#ifdef _SC_EQUIV_CLASS_MAX
4397    {"SC_EQUIV_CLASS_MAX",	_SC_EQUIV_CLASS_MAX},
4398#endif
4399#ifdef _SC_EXPR_NEST_MAX
4400    {"SC_EXPR_NEST_MAX",	_SC_EXPR_NEST_MAX},
4401#endif
4402#ifdef _SC_FSYNC
4403    {"SC_FSYNC",	_SC_FSYNC},
4404#endif
4405#ifdef _SC_GETGR_R_SIZE_MAX
4406    {"SC_GETGR_R_SIZE_MAX",	_SC_GETGR_R_SIZE_MAX},
4407#endif
4408#ifdef _SC_GETPW_R_SIZE_MAX
4409    {"SC_GETPW_R_SIZE_MAX",	_SC_GETPW_R_SIZE_MAX},
4410#endif
4411#ifdef _SC_ICACHE_ASSOC
4412    {"SC_ICACHE_ASSOC",	_SC_ICACHE_ASSOC},
4413#endif
4414#ifdef _SC_ICACHE_BLKSZ
4415    {"SC_ICACHE_BLKSZ",	_SC_ICACHE_BLKSZ},
4416#endif
4417#ifdef _SC_ICACHE_LINESZ
4418    {"SC_ICACHE_LINESZ",	_SC_ICACHE_LINESZ},
4419#endif
4420#ifdef _SC_ICACHE_SZ
4421    {"SC_ICACHE_SZ",	_SC_ICACHE_SZ},
4422#endif
4423#ifdef _SC_INF
4424    {"SC_INF",	_SC_INF},
4425#endif
4426#ifdef _SC_INT_MAX
4427    {"SC_INT_MAX",	_SC_INT_MAX},
4428#endif
4429#ifdef _SC_INT_MIN
4430    {"SC_INT_MIN",	_SC_INT_MIN},
4431#endif
4432#ifdef _SC_IOV_MAX
4433    {"SC_IOV_MAX",	_SC_IOV_MAX},
4434#endif
4435#ifdef _SC_IP_SECOPTS
4436    {"SC_IP_SECOPTS",	_SC_IP_SECOPTS},
4437#endif
4438#ifdef _SC_JOB_CONTROL
4439    {"SC_JOB_CONTROL",	_SC_JOB_CONTROL},
4440#endif
4441#ifdef _SC_KERN_POINTERS
4442    {"SC_KERN_POINTERS",	_SC_KERN_POINTERS},
4443#endif
4444#ifdef _SC_KERN_SIM
4445    {"SC_KERN_SIM",	_SC_KERN_SIM},
4446#endif
4447#ifdef _SC_LINE_MAX
4448    {"SC_LINE_MAX",	_SC_LINE_MAX},
4449#endif
4450#ifdef _SC_LOGIN_NAME_MAX
4451    {"SC_LOGIN_NAME_MAX",	_SC_LOGIN_NAME_MAX},
4452#endif
4453#ifdef _SC_LOGNAME_MAX
4454    {"SC_LOGNAME_MAX",	_SC_LOGNAME_MAX},
4455#endif
4456#ifdef _SC_LONG_BIT
4457    {"SC_LONG_BIT",	_SC_LONG_BIT},
4458#endif
4459#ifdef _SC_MAC
4460    {"SC_MAC",	_SC_MAC},
4461#endif
4462#ifdef _SC_MAPPED_FILES
4463    {"SC_MAPPED_FILES",	_SC_MAPPED_FILES},
4464#endif
4465#ifdef _SC_MAXPID
4466    {"SC_MAXPID",	_SC_MAXPID},
4467#endif
4468#ifdef _SC_MB_LEN_MAX
4469    {"SC_MB_LEN_MAX",	_SC_MB_LEN_MAX},
4470#endif
4471#ifdef _SC_MEMLOCK
4472    {"SC_MEMLOCK",	_SC_MEMLOCK},
4473#endif
4474#ifdef _SC_MEMLOCK_RANGE
4475    {"SC_MEMLOCK_RANGE",	_SC_MEMLOCK_RANGE},
4476#endif
4477#ifdef _SC_MEMORY_PROTECTION
4478    {"SC_MEMORY_PROTECTION",	_SC_MEMORY_PROTECTION},
4479#endif
4480#ifdef _SC_MESSAGE_PASSING
4481    {"SC_MESSAGE_PASSING",	_SC_MESSAGE_PASSING},
4482#endif
4483#ifdef _SC_MMAP_FIXED_ALIGNMENT
4484    {"SC_MMAP_FIXED_ALIGNMENT",	_SC_MMAP_FIXED_ALIGNMENT},
4485#endif
4486#ifdef _SC_MQ_OPEN_MAX
4487    {"SC_MQ_OPEN_MAX",	_SC_MQ_OPEN_MAX},
4488#endif
4489#ifdef _SC_MQ_PRIO_MAX
4490    {"SC_MQ_PRIO_MAX",	_SC_MQ_PRIO_MAX},
4491#endif
4492#ifdef _SC_NACLS_MAX
4493    {"SC_NACLS_MAX",	_SC_NACLS_MAX},
4494#endif
4495#ifdef _SC_NGROUPS_MAX
4496    {"SC_NGROUPS_MAX",	_SC_NGROUPS_MAX},
4497#endif
4498#ifdef _SC_NL_ARGMAX
4499    {"SC_NL_ARGMAX",	_SC_NL_ARGMAX},
4500#endif
4501#ifdef _SC_NL_LANGMAX
4502    {"SC_NL_LANGMAX",	_SC_NL_LANGMAX},
4503#endif
4504#ifdef _SC_NL_MSGMAX
4505    {"SC_NL_MSGMAX",	_SC_NL_MSGMAX},
4506#endif
4507#ifdef _SC_NL_NMAX
4508    {"SC_NL_NMAX",	_SC_NL_NMAX},
4509#endif
4510#ifdef _SC_NL_SETMAX
4511    {"SC_NL_SETMAX",	_SC_NL_SETMAX},
4512#endif
4513#ifdef _SC_NL_TEXTMAX
4514    {"SC_NL_TEXTMAX",	_SC_NL_TEXTMAX},
4515#endif
4516#ifdef _SC_NPROCESSORS_CONF
4517    {"SC_NPROCESSORS_CONF",	_SC_NPROCESSORS_CONF},
4518#endif
4519#ifdef _SC_NPROCESSORS_ONLN
4520    {"SC_NPROCESSORS_ONLN",	_SC_NPROCESSORS_ONLN},
4521#endif
4522#ifdef _SC_NPROC_CONF
4523    {"SC_NPROC_CONF",	_SC_NPROC_CONF},
4524#endif
4525#ifdef _SC_NPROC_ONLN
4526    {"SC_NPROC_ONLN",	_SC_NPROC_ONLN},
4527#endif
4528#ifdef _SC_NZERO
4529    {"SC_NZERO",	_SC_NZERO},
4530#endif
4531#ifdef _SC_OPEN_MAX
4532    {"SC_OPEN_MAX",	_SC_OPEN_MAX},
4533#endif
4534#ifdef _SC_PAGESIZE
4535    {"SC_PAGESIZE",	_SC_PAGESIZE},
4536#endif
4537#ifdef _SC_PAGE_SIZE
4538    {"SC_PAGE_SIZE",	_SC_PAGE_SIZE},
4539#endif
4540#ifdef _SC_PASS_MAX
4541    {"SC_PASS_MAX",	_SC_PASS_MAX},
4542#endif
4543#ifdef _SC_PHYS_PAGES
4544    {"SC_PHYS_PAGES",	_SC_PHYS_PAGES},
4545#endif
4546#ifdef _SC_PII
4547    {"SC_PII",	_SC_PII},
4548#endif
4549#ifdef _SC_PII_INTERNET
4550    {"SC_PII_INTERNET",	_SC_PII_INTERNET},
4551#endif
4552#ifdef _SC_PII_INTERNET_DGRAM
4553    {"SC_PII_INTERNET_DGRAM",	_SC_PII_INTERNET_DGRAM},
4554#endif
4555#ifdef _SC_PII_INTERNET_STREAM
4556    {"SC_PII_INTERNET_STREAM",	_SC_PII_INTERNET_STREAM},
4557#endif
4558#ifdef _SC_PII_OSI
4559    {"SC_PII_OSI",	_SC_PII_OSI},
4560#endif
4561#ifdef _SC_PII_OSI_CLTS
4562    {"SC_PII_OSI_CLTS",	_SC_PII_OSI_CLTS},
4563#endif
4564#ifdef _SC_PII_OSI_COTS
4565    {"SC_PII_OSI_COTS",	_SC_PII_OSI_COTS},
4566#endif
4567#ifdef _SC_PII_OSI_M
4568    {"SC_PII_OSI_M",	_SC_PII_OSI_M},
4569#endif
4570#ifdef _SC_PII_SOCKET
4571    {"SC_PII_SOCKET",	_SC_PII_SOCKET},
4572#endif
4573#ifdef _SC_PII_XTI
4574    {"SC_PII_XTI",	_SC_PII_XTI},
4575#endif
4576#ifdef _SC_POLL
4577    {"SC_POLL",	_SC_POLL},
4578#endif
4579#ifdef _SC_PRIORITIZED_IO
4580    {"SC_PRIORITIZED_IO",	_SC_PRIORITIZED_IO},
4581#endif
4582#ifdef _SC_PRIORITY_SCHEDULING
4583    {"SC_PRIORITY_SCHEDULING",	_SC_PRIORITY_SCHEDULING},
4584#endif
4585#ifdef _SC_REALTIME_SIGNALS
4586    {"SC_REALTIME_SIGNALS",	_SC_REALTIME_SIGNALS},
4587#endif
4588#ifdef _SC_RE_DUP_MAX
4589    {"SC_RE_DUP_MAX",	_SC_RE_DUP_MAX},
4590#endif
4591#ifdef _SC_RTSIG_MAX
4592    {"SC_RTSIG_MAX",	_SC_RTSIG_MAX},
4593#endif
4594#ifdef _SC_SAVED_IDS
4595    {"SC_SAVED_IDS",	_SC_SAVED_IDS},
4596#endif
4597#ifdef _SC_SCHAR_MAX
4598    {"SC_SCHAR_MAX",	_SC_SCHAR_MAX},
4599#endif
4600#ifdef _SC_SCHAR_MIN
4601    {"SC_SCHAR_MIN",	_SC_SCHAR_MIN},
4602#endif
4603#ifdef _SC_SELECT
4604    {"SC_SELECT",	_SC_SELECT},
4605#endif
4606#ifdef _SC_SEMAPHORES
4607    {"SC_SEMAPHORES",	_SC_SEMAPHORES},
4608#endif
4609#ifdef _SC_SEM_NSEMS_MAX
4610    {"SC_SEM_NSEMS_MAX",	_SC_SEM_NSEMS_MAX},
4611#endif
4612#ifdef _SC_SEM_VALUE_MAX
4613    {"SC_SEM_VALUE_MAX",	_SC_SEM_VALUE_MAX},
4614#endif
4615#ifdef _SC_SHARED_MEMORY_OBJECTS
4616    {"SC_SHARED_MEMORY_OBJECTS",	_SC_SHARED_MEMORY_OBJECTS},
4617#endif
4618#ifdef _SC_SHRT_MAX
4619    {"SC_SHRT_MAX",	_SC_SHRT_MAX},
4620#endif
4621#ifdef _SC_SHRT_MIN
4622    {"SC_SHRT_MIN",	_SC_SHRT_MIN},
4623#endif
4624#ifdef _SC_SIGQUEUE_MAX
4625    {"SC_SIGQUEUE_MAX",	_SC_SIGQUEUE_MAX},
4626#endif
4627#ifdef _SC_SIGRT_MAX
4628    {"SC_SIGRT_MAX",	_SC_SIGRT_MAX},
4629#endif
4630#ifdef _SC_SIGRT_MIN
4631    {"SC_SIGRT_MIN",	_SC_SIGRT_MIN},
4632#endif
4633#ifdef _SC_SOFTPOWER
4634    {"SC_SOFTPOWER",	_SC_SOFTPOWER},
4635#endif
4636#ifdef _SC_SPLIT_CACHE
4637    {"SC_SPLIT_CACHE",	_SC_SPLIT_CACHE},
4638#endif
4639#ifdef _SC_SSIZE_MAX
4640    {"SC_SSIZE_MAX",	_SC_SSIZE_MAX},
4641#endif
4642#ifdef _SC_STACK_PROT
4643    {"SC_STACK_PROT",	_SC_STACK_PROT},
4644#endif
4645#ifdef _SC_STREAM_MAX
4646    {"SC_STREAM_MAX",	_SC_STREAM_MAX},
4647#endif
4648#ifdef _SC_SYNCHRONIZED_IO
4649    {"SC_SYNCHRONIZED_IO",	_SC_SYNCHRONIZED_IO},
4650#endif
4651#ifdef _SC_THREADS
4652    {"SC_THREADS",	_SC_THREADS},
4653#endif
4654#ifdef _SC_THREAD_ATTR_STACKADDR
4655    {"SC_THREAD_ATTR_STACKADDR",	_SC_THREAD_ATTR_STACKADDR},
4656#endif
4657#ifdef _SC_THREAD_ATTR_STACKSIZE
4658    {"SC_THREAD_ATTR_STACKSIZE",	_SC_THREAD_ATTR_STACKSIZE},
4659#endif
4660#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
4661    {"SC_THREAD_DESTRUCTOR_ITERATIONS",	_SC_THREAD_DESTRUCTOR_ITERATIONS},
4662#endif
4663#ifdef _SC_THREAD_KEYS_MAX
4664    {"SC_THREAD_KEYS_MAX",	_SC_THREAD_KEYS_MAX},
4665#endif
4666#ifdef _SC_THREAD_PRIORITY_SCHEDULING
4667    {"SC_THREAD_PRIORITY_SCHEDULING",	_SC_THREAD_PRIORITY_SCHEDULING},
4668#endif
4669#ifdef _SC_THREAD_PRIO_INHERIT
4670    {"SC_THREAD_PRIO_INHERIT",	_SC_THREAD_PRIO_INHERIT},
4671#endif
4672#ifdef _SC_THREAD_PRIO_PROTECT
4673    {"SC_THREAD_PRIO_PROTECT",	_SC_THREAD_PRIO_PROTECT},
4674#endif
4675#ifdef _SC_THREAD_PROCESS_SHARED
4676    {"SC_THREAD_PROCESS_SHARED",	_SC_THREAD_PROCESS_SHARED},
4677#endif
4678#ifdef _SC_THREAD_SAFE_FUNCTIONS
4679    {"SC_THREAD_SAFE_FUNCTIONS",	_SC_THREAD_SAFE_FUNCTIONS},
4680#endif
4681#ifdef _SC_THREAD_STACK_MIN
4682    {"SC_THREAD_STACK_MIN",	_SC_THREAD_STACK_MIN},
4683#endif
4684#ifdef _SC_THREAD_THREADS_MAX
4685    {"SC_THREAD_THREADS_MAX",	_SC_THREAD_THREADS_MAX},
4686#endif
4687#ifdef _SC_TIMERS
4688    {"SC_TIMERS",	_SC_TIMERS},
4689#endif
4690#ifdef _SC_TIMER_MAX
4691    {"SC_TIMER_MAX",	_SC_TIMER_MAX},
4692#endif
4693#ifdef _SC_TTY_NAME_MAX
4694    {"SC_TTY_NAME_MAX",	_SC_TTY_NAME_MAX},
4695#endif
4696#ifdef _SC_TZNAME_MAX
4697    {"SC_TZNAME_MAX",	_SC_TZNAME_MAX},
4698#endif
4699#ifdef _SC_T_IOV_MAX
4700    {"SC_T_IOV_MAX",	_SC_T_IOV_MAX},
4701#endif
4702#ifdef _SC_UCHAR_MAX
4703    {"SC_UCHAR_MAX",	_SC_UCHAR_MAX},
4704#endif
4705#ifdef _SC_UINT_MAX
4706    {"SC_UINT_MAX",	_SC_UINT_MAX},
4707#endif
4708#ifdef _SC_UIO_MAXIOV
4709    {"SC_UIO_MAXIOV",	_SC_UIO_MAXIOV},
4710#endif
4711#ifdef _SC_ULONG_MAX
4712    {"SC_ULONG_MAX",	_SC_ULONG_MAX},
4713#endif
4714#ifdef _SC_USHRT_MAX
4715    {"SC_USHRT_MAX",	_SC_USHRT_MAX},
4716#endif
4717#ifdef _SC_VERSION
4718    {"SC_VERSION",	_SC_VERSION},
4719#endif
4720#ifdef _SC_WORD_BIT
4721    {"SC_WORD_BIT",	_SC_WORD_BIT},
4722#endif
4723#ifdef _SC_XBS5_ILP32_OFF32
4724    {"SC_XBS5_ILP32_OFF32",	_SC_XBS5_ILP32_OFF32},
4725#endif
4726#ifdef _SC_XBS5_ILP32_OFFBIG
4727    {"SC_XBS5_ILP32_OFFBIG",	_SC_XBS5_ILP32_OFFBIG},
4728#endif
4729#ifdef _SC_XBS5_LP64_OFF64
4730    {"SC_XBS5_LP64_OFF64",	_SC_XBS5_LP64_OFF64},
4731#endif
4732#ifdef _SC_XBS5_LPBIG_OFFBIG
4733    {"SC_XBS5_LPBIG_OFFBIG",	_SC_XBS5_LPBIG_OFFBIG},
4734#endif
4735#ifdef _SC_XOPEN_CRYPT
4736    {"SC_XOPEN_CRYPT",	_SC_XOPEN_CRYPT},
4737#endif
4738#ifdef _SC_XOPEN_ENH_I18N
4739    {"SC_XOPEN_ENH_I18N",	_SC_XOPEN_ENH_I18N},
4740#endif
4741#ifdef _SC_XOPEN_LEGACY
4742    {"SC_XOPEN_LEGACY",	_SC_XOPEN_LEGACY},
4743#endif
4744#ifdef _SC_XOPEN_REALTIME
4745    {"SC_XOPEN_REALTIME",	_SC_XOPEN_REALTIME},
4746#endif
4747#ifdef _SC_XOPEN_REALTIME_THREADS
4748    {"SC_XOPEN_REALTIME_THREADS",	_SC_XOPEN_REALTIME_THREADS},
4749#endif
4750#ifdef _SC_XOPEN_SHM
4751    {"SC_XOPEN_SHM",	_SC_XOPEN_SHM},
4752#endif
4753#ifdef _SC_XOPEN_UNIX
4754    {"SC_XOPEN_UNIX",	_SC_XOPEN_UNIX},
4755#endif
4756#ifdef _SC_XOPEN_VERSION
4757    {"SC_XOPEN_VERSION",	_SC_XOPEN_VERSION},
4758#endif
4759#ifdef _SC_XOPEN_XCU_VERSION
4760    {"SC_XOPEN_XCU_VERSION",	_SC_XOPEN_XCU_VERSION},
4761#endif
4762#ifdef _SC_XOPEN_XPG2
4763    {"SC_XOPEN_XPG2",	_SC_XOPEN_XPG2},
4764#endif
4765#ifdef _SC_XOPEN_XPG3
4766    {"SC_XOPEN_XPG3",	_SC_XOPEN_XPG3},
4767#endif
4768#ifdef _SC_XOPEN_XPG4
4769    {"SC_XOPEN_XPG4",	_SC_XOPEN_XPG4},
4770#endif
4771};
4772
4773static int
4774conv_sysconf_confname(PyObject *arg, int *valuep)
4775{
4776    return conv_confname(arg, valuep, posix_constants_sysconf,
4777                         sizeof(posix_constants_sysconf)
4778                           / sizeof(struct constdef));
4779}
4780
4781static char posix_sysconf__doc__[] = "\
4782sysconf(name) -> integer\n\
4783Return an integer-valued system configuration variable.";
4784
4785static PyObject *
4786posix_sysconf(PyObject *self, PyObject *args)
4787{
4788    PyObject *result = NULL;
4789    int name;
4790
4791    if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
4792        int value;
4793
4794        errno = 0;
4795        value = sysconf(name);
4796        if (value == -1 && errno != 0)
4797            posix_error();
4798        else
4799            result = PyInt_FromLong(value);
4800    }
4801    return result;
4802}
4803#endif
4804
4805
4806/* This code is used to ensure that the tables of configuration value names
4807 * are in sorted order as required by conv_confname(), and also to build the
4808 * the exported dictionaries that are used to publish information about the
4809 * names available on the host platform.
4810 *
4811 * Sorting the table at runtime ensures that the table is properly ordered
4812 * when used, even for platforms we're not able to test on.  It also makes
4813 * it easier to add additional entries to the tables.
4814 */
4815
4816static int
4817cmp_constdefs(const void *v1,  const void *v2)
4818{
4819    const struct constdef *c1 =
4820        (const struct constdef *) v1;
4821    const struct constdef *c2 =
4822        (const struct constdef *) v2;
4823
4824    return strcmp(c1->name, c2->name);
4825}
4826
4827static int
4828setup_confname_table(struct constdef *table, size_t tablesize,
4829		     char *tablename, PyObject *moddict)
4830{
4831    PyObject *d = NULL;
4832    size_t i;
4833    int status;
4834
4835    qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
4836    d = PyDict_New();
4837    if (d == NULL)
4838	    return -1;
4839
4840    for (i=0; i < tablesize; ++i) {
4841            PyObject *o = PyInt_FromLong(table[i].value);
4842            if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
4843		    Py_XDECREF(o);
4844		    Py_DECREF(d);
4845		    return -1;
4846            }
4847	    Py_DECREF(o);
4848    }
4849    status = PyDict_SetItemString(moddict, tablename, d);
4850    Py_DECREF(d);
4851    return status;
4852}
4853
4854/* Return -1 on failure, 0 on success. */
4855static int
4856setup_confname_tables(PyObject *moddict)
4857{
4858#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
4859    if (setup_confname_table(posix_constants_pathconf,
4860                             sizeof(posix_constants_pathconf)
4861                               / sizeof(struct constdef),
4862                             "pathconf_names", moddict))
4863        return -1;
4864#endif
4865#ifdef HAVE_CONFSTR
4866    if (setup_confname_table(posix_constants_confstr,
4867                             sizeof(posix_constants_confstr)
4868                               / sizeof(struct constdef),
4869                             "confstr_names", moddict))
4870        return -1;
4871#endif
4872#ifdef HAVE_SYSCONF
4873    if (setup_confname_table(posix_constants_sysconf,
4874                             sizeof(posix_constants_sysconf)
4875                               / sizeof(struct constdef),
4876                             "sysconf_names", moddict))
4877        return -1;
4878#endif
4879    return 0;
4880}
4881
4882
4883static char posix_abort__doc__[] = "\
4884abort() -> does not return!\n\
4885Abort the interpreter immediately.  This 'dumps core' or otherwise fails\n\
4886in the hardest way possible on the hosting operating system.";
4887
4888static PyObject *
4889posix_abort(PyObject *self, PyObject *args)
4890{
4891    if (!PyArg_ParseTuple(args, ":abort"))
4892        return NULL;
4893    abort();
4894    /*NOTREACHED*/
4895    Py_FatalError("abort() called from Python code didn't abort!");
4896    return NULL;
4897}
4898
4899
4900static PyMethodDef posix_methods[] = {
4901	{"access",	posix_access, METH_VARARGS, posix_access__doc__},
4902#ifdef HAVE_TTYNAME
4903	{"ttyname",	posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
4904#endif
4905	{"chdir",	posix_chdir, METH_VARARGS, posix_chdir__doc__},
4906	{"chmod",	posix_chmod, METH_VARARGS, posix_chmod__doc__},
4907#ifdef HAVE_CHOWN
4908	{"chown",	posix_chown, METH_VARARGS, posix_chown__doc__},
4909#endif /* HAVE_CHOWN */
4910#ifdef HAVE_CTERMID
4911	{"ctermid",	posix_ctermid, METH_VARARGS, posix_ctermid__doc__},
4912#endif
4913#ifdef HAVE_GETCWD
4914	{"getcwd",	posix_getcwd, METH_VARARGS, posix_getcwd__doc__},
4915#endif
4916#ifdef HAVE_LINK
4917	{"link",	posix_link, METH_VARARGS, posix_link__doc__},
4918#endif /* HAVE_LINK */
4919	{"listdir",	posix_listdir, METH_VARARGS, posix_listdir__doc__},
4920	{"lstat",	posix_lstat, METH_VARARGS, posix_lstat__doc__},
4921	{"mkdir",	posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
4922#ifdef HAVE_NICE
4923	{"nice",	posix_nice, METH_VARARGS, posix_nice__doc__},
4924#endif /* HAVE_NICE */
4925#ifdef HAVE_READLINK
4926	{"readlink",	posix_readlink, METH_VARARGS, posix_readlink__doc__},
4927#endif /* HAVE_READLINK */
4928	{"rename",	posix_rename, METH_VARARGS, posix_rename__doc__},
4929	{"rmdir",	posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
4930	{"stat",	posix_stat, METH_VARARGS, posix_stat__doc__},
4931#ifdef HAVE_SYMLINK
4932	{"symlink",	posix_symlink, METH_VARARGS, posix_symlink__doc__},
4933#endif /* HAVE_SYMLINK */
4934#ifdef HAVE_SYSTEM
4935	{"system",	posix_system, METH_VARARGS, posix_system__doc__},
4936#endif
4937	{"umask",	posix_umask, METH_VARARGS, posix_umask__doc__},
4938#ifdef HAVE_UNAME
4939	{"uname",	posix_uname, METH_VARARGS, posix_uname__doc__},
4940#endif /* HAVE_UNAME */
4941	{"unlink",	posix_unlink, METH_VARARGS, posix_unlink__doc__},
4942	{"remove",	posix_unlink, METH_VARARGS, posix_remove__doc__},
4943	{"utime",	posix_utime, METH_VARARGS, posix_utime__doc__},
4944#ifdef HAVE_TIMES
4945	{"times",	posix_times, METH_VARARGS, posix_times__doc__},
4946#endif /* HAVE_TIMES */
4947	{"_exit",	posix__exit, METH_VARARGS, posix__exit__doc__},
4948#ifdef HAVE_EXECV
4949	{"execv",	posix_execv, METH_VARARGS, posix_execv__doc__},
4950	{"execve",	posix_execve, METH_VARARGS, posix_execve__doc__},
4951#endif /* HAVE_EXECV */
4952#ifdef HAVE_SPAWNV
4953	{"spawnv",	posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
4954	{"spawnve",	posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
4955#endif /* HAVE_SPAWNV */
4956#ifdef HAVE_FORK
4957	{"fork",	posix_fork, METH_VARARGS, posix_fork__doc__},
4958#endif /* HAVE_FORK */
4959#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
4960	{"openpty",	posix_openpty, METH_VARARGS, posix_openpty__doc__},
4961#endif /* HAVE_OPENPTY || HAVE__GETPTY */
4962#ifdef HAVE_FORKPTY
4963	{"forkpty",	posix_forkpty, METH_VARARGS, posix_forkpty__doc__},
4964#endif /* HAVE_FORKPTY */
4965#ifdef HAVE_GETEGID
4966	{"getegid",	posix_getegid, METH_VARARGS, posix_getegid__doc__},
4967#endif /* HAVE_GETEGID */
4968#ifdef HAVE_GETEUID
4969	{"geteuid",	posix_geteuid, METH_VARARGS, posix_geteuid__doc__},
4970#endif /* HAVE_GETEUID */
4971#ifdef HAVE_GETGID
4972	{"getgid",	posix_getgid, METH_VARARGS, posix_getgid__doc__},
4973#endif /* HAVE_GETGID */
4974#ifdef HAVE_GETGROUPS
4975	{"getgroups",	posix_getgroups, METH_VARARGS, posix_getgroups__doc__},
4976#endif
4977	{"getpid",	posix_getpid, METH_VARARGS, posix_getpid__doc__},
4978#ifdef HAVE_GETPGRP
4979	{"getpgrp",	posix_getpgrp, METH_VARARGS, posix_getpgrp__doc__},
4980#endif /* HAVE_GETPGRP */
4981#ifdef HAVE_GETPPID
4982	{"getppid",	posix_getppid, METH_VARARGS, posix_getppid__doc__},
4983#endif /* HAVE_GETPPID */
4984#ifdef HAVE_GETUID
4985	{"getuid",	posix_getuid, METH_VARARGS, posix_getuid__doc__},
4986#endif /* HAVE_GETUID */
4987#ifdef HAVE_GETLOGIN
4988	{"getlogin",	posix_getlogin, METH_VARARGS, posix_getlogin__doc__},
4989#endif
4990#ifdef HAVE_KILL
4991	{"kill",	posix_kill, METH_VARARGS, posix_kill__doc__},
4992#endif /* HAVE_KILL */
4993#ifdef HAVE_PLOCK
4994	{"plock",	posix_plock, METH_VARARGS, posix_plock__doc__},
4995#endif /* HAVE_PLOCK */
4996#ifdef HAVE_POPEN
4997	{"popen",	posix_popen, METH_VARARGS, posix_popen__doc__},
4998#ifdef MS_WIN32
4999	{"popen2",	win32_popen2, METH_VARARGS},
5000	{"popen3",	win32_popen3, METH_VARARGS},
5001	{"popen4",	win32_popen4, METH_VARARGS},
5002#endif
5003#endif /* HAVE_POPEN */
5004#ifdef HAVE_SETUID
5005	{"setuid",	posix_setuid, METH_VARARGS, posix_setuid__doc__},
5006#endif /* HAVE_SETUID */
5007#ifdef HAVE_SETEUID
5008	{"seteuid",	posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
5009#endif /* HAVE_SETEUID */
5010#ifdef HAVE_SETEGID
5011	{"setegid",	posix_setegid, METH_VARARGS, posix_setegid__doc__},
5012#endif /* HAVE_SETEGID */
5013#ifdef HAVE_SETREUID
5014	{"setreuid",	posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
5015#endif /* HAVE_SETREUID */
5016#ifdef HAVE_SETREGID
5017	{"setregid",	posix_setregid,	METH_VARARGS, posix_setregid__doc__},
5018#endif /* HAVE_SETREGID */
5019#ifdef HAVE_SETGID
5020	{"setgid",	posix_setgid, METH_VARARGS, posix_setgid__doc__},
5021#endif /* HAVE_SETGID */
5022#ifdef HAVE_SETPGRP
5023	{"setpgrp",	posix_setpgrp, METH_VARARGS, posix_setpgrp__doc__},
5024#endif /* HAVE_SETPGRP */
5025#ifdef HAVE_WAIT
5026	{"wait",	posix_wait, METH_VARARGS, posix_wait__doc__},
5027#endif /* HAVE_WAIT */
5028#ifdef HAVE_WAITPID
5029	{"waitpid",	posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
5030#endif /* HAVE_WAITPID */
5031#ifdef HAVE_SETSID
5032	{"setsid",	posix_setsid, METH_VARARGS, posix_setsid__doc__},
5033#endif /* HAVE_SETSID */
5034#ifdef HAVE_SETPGID
5035	{"setpgid",	posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
5036#endif /* HAVE_SETPGID */
5037#ifdef HAVE_TCGETPGRP
5038	{"tcgetpgrp",	posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
5039#endif /* HAVE_TCGETPGRP */
5040#ifdef HAVE_TCSETPGRP
5041	{"tcsetpgrp",	posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
5042#endif /* HAVE_TCSETPGRP */
5043	{"open",	posix_open, METH_VARARGS, posix_open__doc__},
5044	{"close",	posix_close, METH_VARARGS, posix_close__doc__},
5045	{"dup",		posix_dup, METH_VARARGS, posix_dup__doc__},
5046	{"dup2",	posix_dup2, METH_VARARGS, posix_dup2__doc__},
5047	{"lseek",	posix_lseek, METH_VARARGS, posix_lseek__doc__},
5048	{"read",	posix_read, METH_VARARGS, posix_read__doc__},
5049	{"write",	posix_write, METH_VARARGS, posix_write__doc__},
5050	{"fstat",	posix_fstat, METH_VARARGS, posix_fstat__doc__},
5051	{"fdopen",	posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
5052	{"isatty",	posix_isatty, METH_VARARGS, posix_isatty__doc__},
5053#ifdef HAVE_PIPE
5054	{"pipe",	posix_pipe, METH_VARARGS, posix_pipe__doc__},
5055#endif
5056#ifdef HAVE_MKFIFO
5057	{"mkfifo",	posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
5058#endif
5059#ifdef HAVE_FTRUNCATE
5060	{"ftruncate",	posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
5061#endif
5062#ifdef HAVE_PUTENV
5063	{"putenv",	posix_putenv, METH_VARARGS, posix_putenv__doc__},
5064#endif
5065#ifdef HAVE_STRERROR
5066	{"strerror",	posix_strerror, METH_VARARGS, posix_strerror__doc__},
5067#endif
5068#ifdef HAVE_FSYNC
5069	{"fsync",       posix_fsync, METH_VARARGS, posix_fsync__doc__},
5070#endif
5071#ifdef HAVE_FDATASYNC
5072	{"fdatasync",   posix_fdatasync,  METH_VARARGS, posix_fdatasync__doc__},
5073#endif
5074#ifdef HAVE_SYS_WAIT_H
5075#ifdef WIFSTOPPED
5076        {"WIFSTOPPED",	posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
5077#endif /* WIFSTOPPED */
5078#ifdef WIFSIGNALED
5079        {"WIFSIGNALED",	posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
5080#endif /* WIFSIGNALED */
5081#ifdef WIFEXITED
5082        {"WIFEXITED",	posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
5083#endif /* WIFEXITED */
5084#ifdef WEXITSTATUS
5085        {"WEXITSTATUS",	posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
5086#endif /* WEXITSTATUS */
5087#ifdef WTERMSIG
5088        {"WTERMSIG",	posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
5089#endif /* WTERMSIG */
5090#ifdef WSTOPSIG
5091        {"WSTOPSIG",	posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
5092#endif /* WSTOPSIG */
5093#endif /* HAVE_SYS_WAIT_H */
5094#ifdef HAVE_FSTATVFS
5095	{"fstatvfs",	posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
5096#endif
5097#ifdef HAVE_STATVFS
5098	{"statvfs",	posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
5099#endif
5100#ifdef HAVE_TMPNAM
5101	{"tmpfile",	posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__},
5102#endif
5103#ifdef HAVE_TEMPNAM
5104	{"tempnam",	posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
5105#endif
5106#ifdef HAVE_TMPNAM
5107	{"tmpnam",	posix_tmpnam, METH_VARARGS, posix_tmpnam__doc__},
5108#endif
5109#ifdef HAVE_CONFSTR
5110	{"confstr",	posix_confstr, METH_VARARGS, posix_confstr__doc__},
5111#endif
5112#ifdef HAVE_SYSCONF
5113	{"sysconf",	posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
5114#endif
5115#ifdef HAVE_FPATHCONF
5116	{"fpathconf",	posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
5117#endif
5118#ifdef HAVE_PATHCONF
5119	{"pathconf",	posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
5120#endif
5121	{"abort",	posix_abort, METH_VARARGS, posix_abort__doc__},
5122	{NULL,		NULL}		 /* Sentinel */
5123};
5124
5125
5126static int
5127ins(PyObject *d, char *symbol, long value)
5128{
5129        PyObject* v = PyInt_FromLong(value);
5130        if (!v || PyDict_SetItemString(d, symbol, v) < 0)
5131                return -1;                   /* triggers fatal error */
5132
5133        Py_DECREF(v);
5134        return 0;
5135}
5136
5137#if defined(PYOS_OS2)
5138/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
5139static int insertvalues(PyObject *d)
5140{
5141    APIRET    rc;
5142    ULONG     values[QSV_MAX+1];
5143    PyObject *v;
5144    char     *ver, tmp[10];
5145
5146    Py_BEGIN_ALLOW_THREADS
5147    rc = DosQuerySysInfo(1, QSV_MAX, &values[1], sizeof(values));
5148    Py_END_ALLOW_THREADS
5149
5150    if (rc != NO_ERROR) {
5151        os2_error(rc);
5152        return -1;
5153    }
5154
5155    if (ins(d, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
5156    if (ins(d, "memkernel",    values[QSV_TOTRESMEM])) return -1;
5157    if (ins(d, "memvirtual",   values[QSV_TOTAVAILMEM])) return -1;
5158    if (ins(d, "maxpathlen",   values[QSV_MAX_PATH_LENGTH])) return -1;
5159    if (ins(d, "maxnamelen",   values[QSV_MAX_COMP_LENGTH])) return -1;
5160    if (ins(d, "revision",     values[QSV_VERSION_REVISION])) return -1;
5161    if (ins(d, "timeslice",    values[QSV_MIN_SLICE])) return -1;
5162
5163    switch (values[QSV_VERSION_MINOR]) {
5164    case 0:  ver = "2.00"; break;
5165    case 10: ver = "2.10"; break;
5166    case 11: ver = "2.11"; break;
5167    case 30: ver = "3.00"; break;
5168    case 40: ver = "4.00"; break;
5169    case 50: ver = "5.00"; break;
5170    default:
5171        sprintf(tmp, "%d-%d", values[QSV_VERSION_MAJOR],
5172                              values[QSV_VERSION_MINOR]);
5173        ver = &tmp[0];
5174    }
5175
5176    /* Add Indicator of the Version of the Operating System */
5177    v = PyString_FromString(ver);
5178    if (!v || PyDict_SetItemString(d, "version", v) < 0)
5179        return -1;
5180    Py_DECREF(v);
5181
5182    /* Add Indicator of Which Drive was Used to Boot the System */
5183    tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
5184    tmp[1] = ':';
5185    tmp[2] = '\0';
5186
5187    v = PyString_FromString(tmp);
5188    if (!v || PyDict_SetItemString(d, "bootdrive", v) < 0)
5189        return -1;
5190    Py_DECREF(v);
5191
5192    return 0;
5193}
5194#endif
5195
5196static int
5197all_ins(PyObject *d)
5198{
5199#ifdef F_OK
5200        if (ins(d, "F_OK", (long)F_OK)) return -1;
5201#endif
5202#ifdef R_OK
5203        if (ins(d, "R_OK", (long)R_OK)) return -1;
5204#endif
5205#ifdef W_OK
5206        if (ins(d, "W_OK", (long)W_OK)) return -1;
5207#endif
5208#ifdef X_OK
5209        if (ins(d, "X_OK", (long)X_OK)) return -1;
5210#endif
5211#ifdef NGROUPS_MAX
5212        if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
5213#endif
5214#ifdef TMP_MAX
5215        if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
5216#endif
5217#ifdef WNOHANG
5218        if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
5219#endif
5220#ifdef O_RDONLY
5221        if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
5222#endif
5223#ifdef O_WRONLY
5224        if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
5225#endif
5226#ifdef O_RDWR
5227        if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
5228#endif
5229#ifdef O_NDELAY
5230        if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
5231#endif
5232#ifdef O_NONBLOCK
5233        if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
5234#endif
5235#ifdef O_APPEND
5236        if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
5237#endif
5238#ifdef O_DSYNC
5239        if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
5240#endif
5241#ifdef O_RSYNC
5242        if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
5243#endif
5244#ifdef O_SYNC
5245        if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
5246#endif
5247#ifdef O_NOCTTY
5248        if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
5249#endif
5250#ifdef O_CREAT
5251        if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
5252#endif
5253#ifdef O_EXCL
5254        if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
5255#endif
5256#ifdef O_TRUNC
5257        if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
5258#endif
5259#ifdef O_BINARY
5260        if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
5261#endif
5262#ifdef O_TEXT
5263        if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
5264#endif
5265
5266#ifdef HAVE_SPAWNV
5267        if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
5268        if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
5269        if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
5270        if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
5271        if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
5272#endif
5273
5274#if defined(PYOS_OS2)
5275        if (insertvalues(d)) return -1;
5276#endif
5277        return 0;
5278}
5279
5280
5281#if ( defined(_MSC_VER) || defined(__WATCOMC__) ) && !defined(__QNX__)
5282#define INITFUNC initnt
5283#define MODNAME "nt"
5284#else
5285#if defined(PYOS_OS2)
5286#define INITFUNC initos2
5287#define MODNAME "os2"
5288#else
5289#define INITFUNC initposix
5290#define MODNAME "posix"
5291#endif
5292#endif
5293
5294DL_EXPORT(void)
5295INITFUNC(void)
5296{
5297	PyObject *m, *d, *v;
5298
5299	m = Py_InitModule4(MODNAME,
5300			   posix_methods,
5301			   posix__doc__,
5302			   (PyObject *)NULL,
5303			   PYTHON_API_VERSION);
5304	d = PyModule_GetDict(m);
5305
5306	/* Initialize environ dictionary */
5307	v = convertenviron();
5308	if (v == NULL || PyDict_SetItemString(d, "environ", v) != 0)
5309		return;
5310	Py_DECREF(v);
5311
5312        if (all_ins(d))
5313                return;
5314
5315        if (setup_confname_tables(d))
5316                return;
5317
5318	PyDict_SetItemString(d, "error", PyExc_OSError);
5319
5320#ifdef HAVE_PUTENV
5321	posix_putenv_garbage = PyDict_New();
5322#endif
5323}
5324