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