Exceptions raised during renaming in rotating file handlers are now passed to handleE...
[python.git] / Modules / posixmodule.c
blobb7835736856c2c76e4fc7db246a41c2fb44e47bf
2 /* POSIX module implementation */
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. */
14 /* See also ../Dos/dosmodule.c */
16 #include "Python.h"
17 #include "structseq.h"
19 #if defined(__VMS)
20 # include <unixio.h>
21 #endif /* defined(__VMS) */
23 PyDoc_STRVAR(posix__doc__,
24 "This module provides access to operating system functionality that is\n\
25 standardized by the C Standard and the POSIX standard (a thinly\n\
26 disguised Unix interface). Refer to the library manual and\n\
27 corresponding Unix manual entries for more information on calls.");
29 #ifndef Py_USING_UNICODE
30 /* This is used in signatures of functions. */
31 #define Py_UNICODE void
32 #endif
34 #if defined(PYOS_OS2)
35 #define INCL_DOS
36 #define INCL_DOSERRORS
37 #define INCL_DOSPROCESS
38 #define INCL_NOPMAPI
39 #include <os2.h>
40 #if defined(PYCC_GCC)
41 #include <ctype.h>
42 #include <io.h>
43 #include <stdio.h>
44 #include <process.h>
45 #endif
46 #include "osdefs.h"
47 #endif
49 #include <sys/types.h>
50 #include <sys/stat.h>
52 #ifdef HAVE_SYS_WAIT_H
53 #include <sys/wait.h> /* For WNOHANG */
54 #endif
56 #include <signal.h>
58 #ifdef HAVE_FCNTL_H
59 #include <fcntl.h>
60 #endif /* HAVE_FCNTL_H */
62 #ifdef HAVE_GRP_H
63 #include <grp.h>
64 #endif
66 #ifdef HAVE_SYSEXITS_H
67 #include <sysexits.h>
68 #endif /* HAVE_SYSEXITS_H */
70 #ifdef HAVE_SYS_LOADAVG_H
71 #include <sys/loadavg.h>
72 #endif
74 /* Various compilers have only certain posix functions */
75 /* XXX Gosh I wish these were all moved into pyconfig.h */
76 #if defined(PYCC_VACPP) && defined(PYOS_OS2)
77 #include <process.h>
78 #else
79 #if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
80 #define HAVE_GETCWD 1
81 #define HAVE_OPENDIR 1
82 #define HAVE_SYSTEM 1
83 #if defined(__OS2__)
84 #define HAVE_EXECV 1
85 #define HAVE_WAIT 1
86 #endif
87 #include <process.h>
88 #else
89 #ifdef __BORLANDC__ /* Borland compiler */
90 #define HAVE_EXECV 1
91 #define HAVE_GETCWD 1
92 #define HAVE_OPENDIR 1
93 #define HAVE_PIPE 1
94 #define HAVE_POPEN 1
95 #define HAVE_SYSTEM 1
96 #define HAVE_WAIT 1
97 #else
98 #ifdef _MSC_VER /* Microsoft compiler */
99 #define HAVE_GETCWD 1
100 #define HAVE_SPAWNV 1
101 #define HAVE_EXECV 1
102 #define HAVE_PIPE 1
103 #define HAVE_POPEN 1
104 #define HAVE_SYSTEM 1
105 #define HAVE_CWAIT 1
106 #define HAVE_FSYNC 1
107 #define fsync _commit
108 #else
109 #if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
110 /* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
111 #else /* all other compilers */
112 /* Unix functions that the configure script doesn't check for */
113 #define HAVE_EXECV 1
114 #define HAVE_FORK 1
115 #if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
116 #define HAVE_FORK1 1
117 #endif
118 #define HAVE_GETCWD 1
119 #define HAVE_GETEGID 1
120 #define HAVE_GETEUID 1
121 #define HAVE_GETGID 1
122 #define HAVE_GETPPID 1
123 #define HAVE_GETUID 1
124 #define HAVE_KILL 1
125 #define HAVE_OPENDIR 1
126 #define HAVE_PIPE 1
127 #ifndef __rtems__
128 #define HAVE_POPEN 1
129 #endif
130 #define HAVE_SYSTEM 1
131 #define HAVE_WAIT 1
132 #define HAVE_TTYNAME 1
133 #endif /* PYOS_OS2 && PYCC_GCC && __VMS */
134 #endif /* _MSC_VER */
135 #endif /* __BORLANDC__ */
136 #endif /* ! __WATCOMC__ || __QNX__ */
137 #endif /* ! __IBMC__ */
139 #ifndef _MSC_VER
141 #if defined(__sgi)&&_COMPILER_VERSION>=700
142 /* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
143 (default) */
144 extern char *ctermid_r(char *);
145 #endif
147 #ifndef HAVE_UNISTD_H
148 #if defined(PYCC_VACPP)
149 extern int mkdir(char *);
150 #else
151 #if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
152 extern int mkdir(const char *);
153 #else
154 extern int mkdir(const char *, mode_t);
155 #endif
156 #endif
157 #if defined(__IBMC__) || defined(__IBMCPP__)
158 extern int chdir(char *);
159 extern int rmdir(char *);
160 #else
161 extern int chdir(const char *);
162 extern int rmdir(const char *);
163 #endif
164 #ifdef __BORLANDC__
165 extern int chmod(const char *, int);
166 #else
167 extern int chmod(const char *, mode_t);
168 #endif
169 extern int chown(const char *, uid_t, gid_t);
170 extern char *getcwd(char *, int);
171 extern char *strerror(int);
172 extern int link(const char *, const char *);
173 extern int rename(const char *, const char *);
174 extern int stat(const char *, struct stat *);
175 extern int unlink(const char *);
176 extern int pclose(FILE *);
177 #ifdef HAVE_SYMLINK
178 extern int symlink(const char *, const char *);
179 #endif /* HAVE_SYMLINK */
180 #ifdef HAVE_LSTAT
181 extern int lstat(const char *, struct stat *);
182 #endif /* HAVE_LSTAT */
183 #endif /* !HAVE_UNISTD_H */
185 #endif /* !_MSC_VER */
187 #ifdef HAVE_UTIME_H
188 #include <utime.h>
189 #endif /* HAVE_UTIME_H */
191 #ifdef HAVE_SYS_UTIME_H
192 #include <sys/utime.h>
193 #define HAVE_UTIME_H /* pretend we do for the rest of this file */
194 #endif /* HAVE_SYS_UTIME_H */
196 #ifdef HAVE_SYS_TIMES_H
197 #include <sys/times.h>
198 #endif /* HAVE_SYS_TIMES_H */
200 #ifdef HAVE_SYS_PARAM_H
201 #include <sys/param.h>
202 #endif /* HAVE_SYS_PARAM_H */
204 #ifdef HAVE_SYS_UTSNAME_H
205 #include <sys/utsname.h>
206 #endif /* HAVE_SYS_UTSNAME_H */
208 #ifdef HAVE_DIRENT_H
209 #include <dirent.h>
210 #define NAMLEN(dirent) strlen((dirent)->d_name)
211 #else
212 #if defined(__WATCOMC__) && !defined(__QNX__)
213 #include <direct.h>
214 #define NAMLEN(dirent) strlen((dirent)->d_name)
215 #else
216 #define dirent direct
217 #define NAMLEN(dirent) (dirent)->d_namlen
218 #endif
219 #ifdef HAVE_SYS_NDIR_H
220 #include <sys/ndir.h>
221 #endif
222 #ifdef HAVE_SYS_DIR_H
223 #include <sys/dir.h>
224 #endif
225 #ifdef HAVE_NDIR_H
226 #include <ndir.h>
227 #endif
228 #endif
230 #ifdef _MSC_VER
231 #include <direct.h>
232 #include <io.h>
233 #include <process.h>
234 #include "osdefs.h"
235 #define _WIN32_WINNT 0x0400 /* Needed for CryptoAPI on some systems */
236 #include <windows.h>
237 #include <shellapi.h> /* for ShellExecute() */
238 #define popen _popen
239 #define pclose _pclose
240 #endif /* _MSC_VER */
242 #if defined(PYCC_VACPP) && defined(PYOS_OS2)
243 #include <io.h>
244 #endif /* OS2 */
246 #ifndef MAXPATHLEN
247 #define MAXPATHLEN 1024
248 #endif /* MAXPATHLEN */
250 #ifdef UNION_WAIT
251 /* Emulate some macros on systems that have a union instead of macros */
253 #ifndef WIFEXITED
254 #define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
255 #endif
257 #ifndef WEXITSTATUS
258 #define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
259 #endif
261 #ifndef WTERMSIG
262 #define WTERMSIG(u_wait) ((u_wait).w_termsig)
263 #endif
265 #endif /* UNION_WAIT */
267 /* Don't use the "_r" form if we don't need it (also, won't have a
268 prototype for it, at least on Solaris -- maybe others as well?). */
269 #if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
270 #define USE_CTERMID_R
271 #endif
273 #if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
274 #define USE_TMPNAM_R
275 #endif
277 /* choose the appropriate stat and fstat functions and return structs */
278 #undef STAT
279 #if defined(MS_WIN64) || defined(MS_WINDOWS)
280 # define STAT _stati64
281 # define FSTAT _fstati64
282 # define STRUCT_STAT struct _stati64
283 #else
284 # define STAT stat
285 # define FSTAT fstat
286 # define STRUCT_STAT struct stat
287 #endif
289 #if defined(MAJOR_IN_MKDEV)
290 #include <sys/mkdev.h>
291 #else
292 #if defined(MAJOR_IN_SYSMACROS)
293 #include <sys/sysmacros.h>
294 #endif
295 #if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
296 #include <sys/mkdev.h>
297 #endif
298 #endif
300 /* Return a dictionary corresponding to the POSIX environment table */
301 #ifdef WITH_NEXT_FRAMEWORK
302 /* On Darwin/MacOSX a shared library or framework has no access to
303 ** environ directly, we must obtain it with _NSGetEnviron().
305 #include <crt_externs.h>
306 static char **environ;
307 #elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
308 extern char **environ;
309 #endif /* !_MSC_VER */
311 static PyObject *
312 convertenviron(void)
314 PyObject *d;
315 char **e;
316 d = PyDict_New();
317 if (d == NULL)
318 return NULL;
319 #ifdef WITH_NEXT_FRAMEWORK
320 if (environ == NULL)
321 environ = *_NSGetEnviron();
322 #endif
323 if (environ == NULL)
324 return d;
325 /* This part ignores errors */
326 for (e = environ; *e != NULL; e++) {
327 PyObject *k;
328 PyObject *v;
329 char *p = strchr(*e, '=');
330 if (p == NULL)
331 continue;
332 k = PyString_FromStringAndSize(*e, (int)(p-*e));
333 if (k == NULL) {
334 PyErr_Clear();
335 continue;
337 v = PyString_FromString(p+1);
338 if (v == NULL) {
339 PyErr_Clear();
340 Py_DECREF(k);
341 continue;
343 if (PyDict_GetItem(d, k) == NULL) {
344 if (PyDict_SetItem(d, k, v) != 0)
345 PyErr_Clear();
347 Py_DECREF(k);
348 Py_DECREF(v);
350 #if defined(PYOS_OS2)
352 APIRET rc;
353 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
355 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
356 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
357 PyObject *v = PyString_FromString(buffer);
358 PyDict_SetItemString(d, "BEGINLIBPATH", v);
359 Py_DECREF(v);
361 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
362 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
363 PyObject *v = PyString_FromString(buffer);
364 PyDict_SetItemString(d, "ENDLIBPATH", v);
365 Py_DECREF(v);
368 #endif
369 return d;
373 /* Set a POSIX-specific error from errno, and return NULL */
375 static PyObject *
376 posix_error(void)
378 return PyErr_SetFromErrno(PyExc_OSError);
380 static PyObject *
381 posix_error_with_filename(char* name)
383 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
386 #ifdef Py_WIN_WIDE_FILENAMES
387 static PyObject *
388 posix_error_with_unicode_filename(Py_UNICODE* name)
390 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
392 #endif /* Py_WIN_WIDE_FILENAMES */
395 static PyObject *
396 posix_error_with_allocated_filename(char* name)
398 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
399 PyMem_Free(name);
400 return rc;
403 #ifdef MS_WINDOWS
404 static PyObject *
405 win32_error(char* function, char* filename)
407 /* XXX We should pass the function name along in the future.
408 (_winreg.c also wants to pass the function name.)
409 This would however require an additional param to the
410 Windows error object, which is non-trivial.
412 errno = GetLastError();
413 if (filename)
414 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
415 else
416 return PyErr_SetFromWindowsErr(errno);
419 #ifdef Py_WIN_WIDE_FILENAMES
420 static PyObject *
421 win32_error_unicode(char* function, Py_UNICODE* filename)
423 /* XXX - see win32_error for comments on 'function' */
424 errno = GetLastError();
425 if (filename)
426 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
427 else
428 return PyErr_SetFromWindowsErr(errno);
431 static PyObject *_PyUnicode_FromFileSystemEncodedObject(register PyObject *obj)
433 /* XXX Perhaps we should make this API an alias of
434 PyObject_Unicode() instead ?! */
435 if (PyUnicode_CheckExact(obj)) {
436 Py_INCREF(obj);
437 return obj;
439 if (PyUnicode_Check(obj)) {
440 /* For a Unicode subtype that's not a Unicode object,
441 return a true Unicode object with the same data. */
442 return PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(obj),
443 PyUnicode_GET_SIZE(obj));
445 return PyUnicode_FromEncodedObject(obj,
446 Py_FileSystemDefaultEncoding,
447 "strict");
450 #endif /* Py_WIN_WIDE_FILENAMES */
452 #endif
454 #if defined(PYOS_OS2)
455 /**********************************************************************
456 * Helper Function to Trim and Format OS/2 Messages
457 **********************************************************************/
458 static void
459 os2_formatmsg(char *msgbuf, int msglen, char *reason)
461 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
463 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
464 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
466 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
467 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
470 /* Add Optional Reason Text */
471 if (reason) {
472 strcat(msgbuf, " : ");
473 strcat(msgbuf, reason);
477 /**********************************************************************
478 * Decode an OS/2 Operating System Error Code
480 * A convenience function to lookup an OS/2 error code and return a
481 * text message we can use to raise a Python exception.
483 * Notes:
484 * The messages for errors returned from the OS/2 kernel reside in
485 * the file OSO001.MSG in the \OS2 directory hierarchy.
487 **********************************************************************/
488 static char *
489 os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
491 APIRET rc;
492 ULONG msglen;
494 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
495 Py_BEGIN_ALLOW_THREADS
496 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
497 errorcode, "oso001.msg", &msglen);
498 Py_END_ALLOW_THREADS
500 if (rc == NO_ERROR)
501 os2_formatmsg(msgbuf, msglen, reason);
502 else
503 PyOS_snprintf(msgbuf, msgbuflen,
504 "unknown OS error #%d", errorcode);
506 return msgbuf;
509 /* Set an OS/2-specific error and return NULL. OS/2 kernel
510 errors are not in a global variable e.g. 'errno' nor are
511 they congruent with posix error numbers. */
513 static PyObject * os2_error(int code)
515 char text[1024];
516 PyObject *v;
518 os2_strerror(text, sizeof(text), code, "");
520 v = Py_BuildValue("(is)", code, text);
521 if (v != NULL) {
522 PyErr_SetObject(PyExc_OSError, v);
523 Py_DECREF(v);
525 return NULL; /* Signal to Python that an Exception is Pending */
528 #endif /* OS2 */
530 /* POSIX generic methods */
532 static PyObject *
533 posix_fildes(PyObject *fdobj, int (*func)(int))
535 int fd;
536 int res;
537 fd = PyObject_AsFileDescriptor(fdobj);
538 if (fd < 0)
539 return NULL;
540 Py_BEGIN_ALLOW_THREADS
541 res = (*func)(fd);
542 Py_END_ALLOW_THREADS
543 if (res < 0)
544 return posix_error();
545 Py_INCREF(Py_None);
546 return Py_None;
549 #ifdef Py_WIN_WIDE_FILENAMES
550 static int
551 unicode_file_names(void)
553 static int canusewide = -1;
554 if (canusewide == -1) {
555 /* As per doc for ::GetVersion(), this is the correct test for
556 the Windows NT family. */
557 canusewide = (GetVersion() < 0x80000000) ? 1 : 0;
559 return canusewide;
561 #endif
563 static PyObject *
564 posix_1str(PyObject *args, char *format, int (*func)(const char*),
565 char *wformat, int (*wfunc)(const Py_UNICODE*))
567 char *path1 = NULL;
568 int res;
569 #ifdef Py_WIN_WIDE_FILENAMES
570 if (unicode_file_names()) {
571 PyUnicodeObject *po;
572 if (PyArg_ParseTuple(args, wformat, &po)) {
573 Py_BEGIN_ALLOW_THREADS
574 /* PyUnicode_AS_UNICODE OK without thread
575 lock as it is a simple dereference. */
576 res = (*wfunc)(PyUnicode_AS_UNICODE(po));
577 Py_END_ALLOW_THREADS
578 if (res < 0)
579 return posix_error_with_unicode_filename(PyUnicode_AS_UNICODE(po));
580 Py_INCREF(Py_None);
581 return Py_None;
583 /* Drop the argument parsing error as narrow
584 strings are also valid. */
585 PyErr_Clear();
587 #else
588 /* Platforms that don't support Unicode filenames
589 shouldn't be passing these extra params */
590 assert(wformat==NULL && wfunc == NULL);
591 #endif
593 if (!PyArg_ParseTuple(args, format,
594 Py_FileSystemDefaultEncoding, &path1))
595 return NULL;
596 Py_BEGIN_ALLOW_THREADS
597 res = (*func)(path1);
598 Py_END_ALLOW_THREADS
599 if (res < 0)
600 return posix_error_with_allocated_filename(path1);
601 PyMem_Free(path1);
602 Py_INCREF(Py_None);
603 return Py_None;
606 static PyObject *
607 posix_2str(PyObject *args,
608 char *format,
609 int (*func)(const char *, const char *),
610 char *wformat,
611 int (*wfunc)(const Py_UNICODE *, const Py_UNICODE *))
613 char *path1 = NULL, *path2 = NULL;
614 int res;
615 #ifdef Py_WIN_WIDE_FILENAMES
616 if (unicode_file_names()) {
617 PyObject *po1;
618 PyObject *po2;
619 if (PyArg_ParseTuple(args, wformat, &po1, &po2)) {
620 if (PyUnicode_Check(po1) || PyUnicode_Check(po2)) {
621 PyObject *wpath1;
622 PyObject *wpath2;
623 wpath1 = _PyUnicode_FromFileSystemEncodedObject(po1);
624 wpath2 = _PyUnicode_FromFileSystemEncodedObject(po2);
625 if (!wpath1 || !wpath2) {
626 Py_XDECREF(wpath1);
627 Py_XDECREF(wpath2);
628 return NULL;
630 Py_BEGIN_ALLOW_THREADS
631 /* PyUnicode_AS_UNICODE OK without thread
632 lock as it is a simple dereference. */
633 res = (*wfunc)(PyUnicode_AS_UNICODE(wpath1),
634 PyUnicode_AS_UNICODE(wpath2));
635 Py_END_ALLOW_THREADS
636 Py_XDECREF(wpath1);
637 Py_XDECREF(wpath2);
638 if (res != 0)
639 return posix_error();
640 Py_INCREF(Py_None);
641 return Py_None;
643 /* Else flow through as neither is Unicode. */
645 /* Drop the argument parsing error as narrow
646 strings are also valid. */
647 PyErr_Clear();
649 #else
650 /* Platforms that don't support Unicode filenames
651 shouldn't be passing these extra params */
652 assert(wformat==NULL && wfunc == NULL);
653 #endif
655 if (!PyArg_ParseTuple(args, format,
656 Py_FileSystemDefaultEncoding, &path1,
657 Py_FileSystemDefaultEncoding, &path2))
658 return NULL;
659 Py_BEGIN_ALLOW_THREADS
660 res = (*func)(path1, path2);
661 Py_END_ALLOW_THREADS
662 PyMem_Free(path1);
663 PyMem_Free(path2);
664 if (res != 0)
665 /* XXX how to report both path1 and path2??? */
666 return posix_error();
667 Py_INCREF(Py_None);
668 return Py_None;
671 PyDoc_STRVAR(stat_result__doc__,
672 "stat_result: Result from stat or lstat.\n\n\
673 This object may be accessed either as a tuple of\n\
674 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
675 or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
677 Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
678 or st_flags, they are available as attributes only.\n\
680 See os.stat for more information.");
682 static PyStructSequence_Field stat_result_fields[] = {
683 {"st_mode", "protection bits"},
684 {"st_ino", "inode"},
685 {"st_dev", "device"},
686 {"st_nlink", "number of hard links"},
687 {"st_uid", "user ID of owner"},
688 {"st_gid", "group ID of owner"},
689 {"st_size", "total size, in bytes"},
690 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
691 {NULL, "integer time of last access"},
692 {NULL, "integer time of last modification"},
693 {NULL, "integer time of last change"},
694 {"st_atime", "time of last access"},
695 {"st_mtime", "time of last modification"},
696 {"st_ctime", "time of last change"},
697 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
698 {"st_blksize", "blocksize for filesystem I/O"},
699 #endif
700 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
701 {"st_blocks", "number of blocks allocated"},
702 #endif
703 #ifdef HAVE_STRUCT_STAT_ST_RDEV
704 {"st_rdev", "device type (if inode device)"},
705 #endif
706 #ifdef HAVE_STRUCT_STAT_ST_FLAGS
707 {"st_flags", "user defined flags for file"},
708 #endif
709 #ifdef HAVE_STRUCT_STAT_ST_GEN
710 {"st_gen", "generation number"},
711 #endif
712 #ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
713 {"st_birthtime", "time of creation"},
714 #endif
718 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
719 #define ST_BLKSIZE_IDX 13
720 #else
721 #define ST_BLKSIZE_IDX 12
722 #endif
724 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
725 #define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
726 #else
727 #define ST_BLOCKS_IDX ST_BLKSIZE_IDX
728 #endif
730 #ifdef HAVE_STRUCT_STAT_ST_RDEV
731 #define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
732 #else
733 #define ST_RDEV_IDX ST_BLOCKS_IDX
734 #endif
736 #ifdef HAVE_STRUCT_STAT_ST_FLAGS
737 #define ST_FLAGS_IDX (ST_RDEV_IDX+1)
738 #else
739 #define ST_FLAGS_IDX ST_RDEV_IDX
740 #endif
742 #ifdef HAVE_STRUCT_STAT_ST_GEN
743 #define ST_GEN_IDX (ST_FLAGS_IDX+1)
744 #else
745 #define ST_GEN_IDX ST_FLAGS_IDX
746 #endif
748 #ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
749 #define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
750 #else
751 #define ST_BIRTHTIME_IDX ST_GEN_IDX
752 #endif
754 static PyStructSequence_Desc stat_result_desc = {
755 "stat_result", /* name */
756 stat_result__doc__, /* doc */
757 stat_result_fields,
761 PyDoc_STRVAR(statvfs_result__doc__,
762 "statvfs_result: Result from statvfs or fstatvfs.\n\n\
763 This object may be accessed either as a tuple of\n\
764 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
765 or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
767 See os.statvfs for more information.");
769 static PyStructSequence_Field statvfs_result_fields[] = {
770 {"f_bsize", },
771 {"f_frsize", },
772 {"f_blocks", },
773 {"f_bfree", },
774 {"f_bavail", },
775 {"f_files", },
776 {"f_ffree", },
777 {"f_favail", },
778 {"f_flag", },
779 {"f_namemax",},
783 static PyStructSequence_Desc statvfs_result_desc = {
784 "statvfs_result", /* name */
785 statvfs_result__doc__, /* doc */
786 statvfs_result_fields,
790 static PyTypeObject StatResultType;
791 static PyTypeObject StatVFSResultType;
792 static newfunc structseq_new;
794 static PyObject *
795 statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
797 PyStructSequence *result;
798 int i;
800 result = (PyStructSequence*)structseq_new(type, args, kwds);
801 if (!result)
802 return NULL;
803 /* If we have been initialized from a tuple,
804 st_?time might be set to None. Initialize it
805 from the int slots. */
806 for (i = 7; i <= 9; i++) {
807 if (result->ob_item[i+3] == Py_None) {
808 Py_DECREF(Py_None);
809 Py_INCREF(result->ob_item[i]);
810 result->ob_item[i+3] = result->ob_item[i];
813 return (PyObject*)result;
818 /* If true, st_?time is float. */
819 static int _stat_float_times = 1;
821 PyDoc_STRVAR(stat_float_times__doc__,
822 "stat_float_times([newval]) -> oldval\n\n\
823 Determine whether os.[lf]stat represents time stamps as float objects.\n\
824 If newval is True, future calls to stat() return floats, if it is False,\n\
825 future calls return ints. \n\
826 If newval is omitted, return the current setting.\n");
828 static PyObject*
829 stat_float_times(PyObject* self, PyObject *args)
831 int newval = -1;
832 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
833 return NULL;
834 if (newval == -1)
835 /* Return old value */
836 return PyBool_FromLong(_stat_float_times);
837 _stat_float_times = newval;
838 Py_INCREF(Py_None);
839 return Py_None;
842 static void
843 fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
845 PyObject *fval,*ival;
846 #if SIZEOF_TIME_T > SIZEOF_LONG
847 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
848 #else
849 ival = PyInt_FromLong((long)sec);
850 #endif
851 if (_stat_float_times) {
852 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
853 } else {
854 fval = ival;
855 Py_INCREF(fval);
857 PyStructSequence_SET_ITEM(v, index, ival);
858 PyStructSequence_SET_ITEM(v, index+3, fval);
861 /* pack a system stat C structure into the Python stat tuple
862 (used by posix_stat() and posix_fstat()) */
863 static PyObject*
864 _pystat_fromstructstat(STRUCT_STAT st)
866 unsigned long ansec, mnsec, cnsec;
867 PyObject *v = PyStructSequence_New(&StatResultType);
868 if (v == NULL)
869 return NULL;
871 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st.st_mode));
872 #ifdef HAVE_LARGEFILE_SUPPORT
873 PyStructSequence_SET_ITEM(v, 1,
874 PyLong_FromLongLong((PY_LONG_LONG)st.st_ino));
875 #else
876 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st.st_ino));
877 #endif
878 #if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
879 PyStructSequence_SET_ITEM(v, 2,
880 PyLong_FromLongLong((PY_LONG_LONG)st.st_dev));
881 #else
882 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st.st_dev));
883 #endif
884 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st.st_nlink));
885 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st.st_uid));
886 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st.st_gid));
887 #ifdef HAVE_LARGEFILE_SUPPORT
888 PyStructSequence_SET_ITEM(v, 6,
889 PyLong_FromLongLong((PY_LONG_LONG)st.st_size));
890 #else
891 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st.st_size));
892 #endif
894 #ifdef HAVE_STAT_TV_NSEC
895 ansec = st.st_atim.tv_nsec;
896 mnsec = st.st_mtim.tv_nsec;
897 cnsec = st.st_ctim.tv_nsec;
898 #else
899 #ifdef HAVE_STAT_TV_NSEC2
900 ansec = st.st_atimespec.tv_nsec;
901 mnsec = st.st_mtimespec.tv_nsec;
902 cnsec = st.st_ctimespec.tv_nsec;
903 #else
904 ansec = mnsec = cnsec = 0;
905 #endif
906 #endif
907 fill_time(v, 7, st.st_atime, ansec);
908 fill_time(v, 8, st.st_mtime, mnsec);
909 fill_time(v, 9, st.st_ctime, cnsec);
911 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
912 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
913 PyInt_FromLong((long)st.st_blksize));
914 #endif
915 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
916 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
917 PyInt_FromLong((long)st.st_blocks));
918 #endif
919 #ifdef HAVE_STRUCT_STAT_ST_RDEV
920 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
921 PyInt_FromLong((long)st.st_rdev));
922 #endif
923 #ifdef HAVE_STRUCT_STAT_ST_GEN
924 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
925 PyInt_FromLong((long)st.st_gen));
926 #endif
927 #ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
929 PyObject *val;
930 unsigned long bsec,bnsec;
931 bsec = (long)st.st_birthtime;
932 #ifdef HAVE_STAT_TV_NSEC2
933 bnsec = st.st_birthtimespec.tv_nsec;
934 #else
935 bnsec = 0;
936 #endif
937 if (_stat_float_times) {
938 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
939 } else {
940 val = PyInt_FromLong((long)bsec);
942 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
943 val);
945 #endif
946 #ifdef HAVE_STRUCT_STAT_ST_FLAGS
947 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
948 PyInt_FromLong((long)st.st_flags));
949 #endif
951 if (PyErr_Occurred()) {
952 Py_DECREF(v);
953 return NULL;
956 return v;
959 #ifdef MS_WINDOWS
961 /* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
962 where / can be used in place of \ and the trailing slash is optional.
963 Both SERVER and SHARE must have at least one character.
966 #define ISSLASHA(c) ((c) == '\\' || (c) == '/')
967 #define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
968 #define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
970 static BOOL
971 IsUNCRootA(char *path, int pathlen)
973 #define ISSLASH ISSLASHA
975 int i, share;
977 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
978 /* minimum UNCRoot is \\x\y */
979 return FALSE;
980 for (i = 2; i < pathlen ; i++)
981 if (ISSLASH(path[i])) break;
982 if (i == 2 || i == pathlen)
983 /* do not allow \\\SHARE or \\SERVER */
984 return FALSE;
985 share = i+1;
986 for (i = share; i < pathlen; i++)
987 if (ISSLASH(path[i])) break;
988 return (i != share && (i == pathlen || i == pathlen-1));
990 #undef ISSLASH
993 #ifdef Py_WIN_WIDE_FILENAMES
994 static BOOL
995 IsUNCRootW(Py_UNICODE *path, int pathlen)
997 #define ISSLASH ISSLASHW
999 int i, share;
1001 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1002 /* minimum UNCRoot is \\x\y */
1003 return FALSE;
1004 for (i = 2; i < pathlen ; i++)
1005 if (ISSLASH(path[i])) break;
1006 if (i == 2 || i == pathlen)
1007 /* do not allow \\\SHARE or \\SERVER */
1008 return FALSE;
1009 share = i+1;
1010 for (i = share; i < pathlen; i++)
1011 if (ISSLASH(path[i])) break;
1012 return (i != share && (i == pathlen || i == pathlen-1));
1014 #undef ISSLASH
1016 #endif /* Py_WIN_WIDE_FILENAMES */
1017 #endif /* MS_WINDOWS */
1019 static PyObject *
1020 posix_do_stat(PyObject *self, PyObject *args,
1021 char *format,
1022 #ifdef __VMS
1023 int (*statfunc)(const char *, STRUCT_STAT *, ...),
1024 #else
1025 int (*statfunc)(const char *, STRUCT_STAT *),
1026 #endif
1027 char *wformat,
1028 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
1030 STRUCT_STAT st;
1031 char *path = NULL; /* pass this to stat; do not free() it */
1032 char *pathfree = NULL; /* this memory must be free'd */
1033 int res;
1035 #ifdef MS_WINDOWS
1036 int pathlen;
1037 char pathcopy[MAX_PATH];
1038 #endif /* MS_WINDOWS */
1041 #ifdef Py_WIN_WIDE_FILENAMES
1042 /* If on wide-character-capable OS see if argument
1043 is Unicode and if so use wide API. */
1044 if (unicode_file_names()) {
1045 PyUnicodeObject *po;
1046 if (PyArg_ParseTuple(args, wformat, &po)) {
1047 Py_UNICODE wpath[MAX_PATH+1];
1048 pathlen = wcslen(PyUnicode_AS_UNICODE(po));
1049 /* the library call can blow up if the file name is too long! */
1050 if (pathlen > MAX_PATH) {
1051 errno = ENAMETOOLONG;
1052 return posix_error();
1054 wcscpy(wpath, PyUnicode_AS_UNICODE(po));
1055 /* Remove trailing slash or backslash, unless it's the current
1056 drive root (/ or \) or a specific drive's root (like c:\ or c:/).
1058 if (pathlen > 0) {
1059 if (ISSLASHW(wpath[pathlen-1])) {
1060 /* It does end with a slash -- exempt the root drive cases. */
1061 if (pathlen == 1 || (pathlen == 3 && wpath[1] == L':') ||
1062 IsUNCRootW(wpath, pathlen))
1063 /* leave it alone */;
1064 else {
1065 /* nuke the trailing backslash */
1066 wpath[pathlen-1] = L'\0';
1069 else if (ISSLASHW(wpath[1]) && pathlen < ARRAYSIZE(wpath)-1 &&
1070 IsUNCRootW(wpath, pathlen)) {
1071 /* UNC root w/o trailing slash: add one when there's room */
1072 wpath[pathlen++] = L'\\';
1073 wpath[pathlen] = L'\0';
1076 Py_BEGIN_ALLOW_THREADS
1077 /* PyUnicode_AS_UNICODE result OK without
1078 thread lock as it is a simple dereference. */
1079 res = wstatfunc(wpath, &st);
1080 Py_END_ALLOW_THREADS
1081 if (res != 0)
1082 return posix_error_with_unicode_filename(wpath);
1083 return _pystat_fromstructstat(st);
1085 /* Drop the argument parsing error as narrow strings
1086 are also valid. */
1087 PyErr_Clear();
1089 #endif
1091 if (!PyArg_ParseTuple(args, format,
1092 Py_FileSystemDefaultEncoding, &path))
1093 return NULL;
1094 pathfree = path;
1096 #ifdef MS_WINDOWS
1097 pathlen = strlen(path);
1098 /* the library call can blow up if the file name is too long! */
1099 if (pathlen > MAX_PATH) {
1100 PyMem_Free(pathfree);
1101 errno = ENAMETOOLONG;
1102 return posix_error();
1105 /* Remove trailing slash or backslash, unless it's the current
1106 drive root (/ or \) or a specific drive's root (like c:\ or c:/).
1108 if (pathlen > 0) {
1109 if (ISSLASHA(path[pathlen-1])) {
1110 /* It does end with a slash -- exempt the root drive cases. */
1111 if (pathlen == 1 || (pathlen == 3 && path[1] == ':') ||
1112 IsUNCRootA(path, pathlen))
1113 /* leave it alone */;
1114 else {
1115 /* nuke the trailing backslash */
1116 strncpy(pathcopy, path, pathlen);
1117 pathcopy[pathlen-1] = '\0';
1118 path = pathcopy;
1121 else if (ISSLASHA(path[1]) && pathlen < ARRAYSIZE(pathcopy)-1 &&
1122 IsUNCRootA(path, pathlen)) {
1123 /* UNC root w/o trailing slash: add one when there's room */
1124 strncpy(pathcopy, path, pathlen);
1125 pathcopy[pathlen++] = '\\';
1126 pathcopy[pathlen] = '\0';
1127 path = pathcopy;
1130 #endif /* MS_WINDOWS */
1132 Py_BEGIN_ALLOW_THREADS
1133 res = (*statfunc)(path, &st);
1134 Py_END_ALLOW_THREADS
1135 if (res != 0)
1136 return posix_error_with_allocated_filename(pathfree);
1138 PyMem_Free(pathfree);
1139 return _pystat_fromstructstat(st);
1143 /* POSIX methods */
1145 PyDoc_STRVAR(posix_access__doc__,
1146 "access(path, mode) -> 1 if granted, 0 otherwise\n\n\
1147 Use the real uid/gid to test for access to a path. Note that most\n\
1148 operations will use the effective uid/gid, therefore this routine can\n\
1149 be used in a suid/sgid environment to test if the invoking user has the\n\
1150 specified access to the path. The mode argument can be F_OK to test\n\
1151 existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
1153 static PyObject *
1154 posix_access(PyObject *self, PyObject *args)
1156 char *path;
1157 int mode;
1158 int res;
1160 #ifdef Py_WIN_WIDE_FILENAMES
1161 if (unicode_file_names()) {
1162 PyUnicodeObject *po;
1163 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1164 Py_BEGIN_ALLOW_THREADS
1165 /* PyUnicode_AS_UNICODE OK without thread lock as
1166 it is a simple dereference. */
1167 res = _waccess(PyUnicode_AS_UNICODE(po), mode);
1168 Py_END_ALLOW_THREADS
1169 return PyBool_FromLong(res == 0);
1171 /* Drop the argument parsing error as narrow strings
1172 are also valid. */
1173 PyErr_Clear();
1175 #endif
1176 if (!PyArg_ParseTuple(args, "eti:access",
1177 Py_FileSystemDefaultEncoding, &path, &mode))
1178 return NULL;
1179 Py_BEGIN_ALLOW_THREADS
1180 res = access(path, mode);
1181 Py_END_ALLOW_THREADS
1182 PyMem_Free(path);
1183 return PyBool_FromLong(res == 0);
1186 #ifndef F_OK
1187 #define F_OK 0
1188 #endif
1189 #ifndef R_OK
1190 #define R_OK 4
1191 #endif
1192 #ifndef W_OK
1193 #define W_OK 2
1194 #endif
1195 #ifndef X_OK
1196 #define X_OK 1
1197 #endif
1199 #ifdef HAVE_TTYNAME
1200 PyDoc_STRVAR(posix_ttyname__doc__,
1201 "ttyname(fd) -> string\n\n\
1202 Return the name of the terminal device connected to 'fd'.");
1204 static PyObject *
1205 posix_ttyname(PyObject *self, PyObject *args)
1207 int id;
1208 char *ret;
1210 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
1211 return NULL;
1213 #if defined(__VMS)
1214 /* file descriptor 0 only, the default input device (stdin) */
1215 if (id == 0) {
1216 ret = ttyname();
1218 else {
1219 ret = NULL;
1221 #else
1222 ret = ttyname(id);
1223 #endif
1224 if (ret == NULL)
1225 return posix_error();
1226 return PyString_FromString(ret);
1228 #endif
1230 #ifdef HAVE_CTERMID
1231 PyDoc_STRVAR(posix_ctermid__doc__,
1232 "ctermid() -> string\n\n\
1233 Return the name of the controlling terminal for this process.");
1235 static PyObject *
1236 posix_ctermid(PyObject *self, PyObject *noargs)
1238 char *ret;
1239 char buffer[L_ctermid];
1241 #ifdef USE_CTERMID_R
1242 ret = ctermid_r(buffer);
1243 #else
1244 ret = ctermid(buffer);
1245 #endif
1246 if (ret == NULL)
1247 return posix_error();
1248 return PyString_FromString(buffer);
1250 #endif
1252 PyDoc_STRVAR(posix_chdir__doc__,
1253 "chdir(path)\n\n\
1254 Change the current working directory to the specified path.");
1256 static PyObject *
1257 posix_chdir(PyObject *self, PyObject *args)
1259 #ifdef MS_WINDOWS
1260 return posix_1str(args, "et:chdir", chdir, "U:chdir", _wchdir);
1261 #elif defined(PYOS_OS2) && defined(PYCC_GCC)
1262 return posix_1str(args, "et:chdir", _chdir2, NULL, NULL);
1263 #elif defined(__VMS)
1264 return posix_1str(args, "et:chdir", (int (*)(const char *))chdir,
1265 NULL, NULL);
1266 #else
1267 return posix_1str(args, "et:chdir", chdir, NULL, NULL);
1268 #endif
1271 #ifdef HAVE_FCHDIR
1272 PyDoc_STRVAR(posix_fchdir__doc__,
1273 "fchdir(fildes)\n\n\
1274 Change to the directory of the given file descriptor. fildes must be\n\
1275 opened on a directory, not a file.");
1277 static PyObject *
1278 posix_fchdir(PyObject *self, PyObject *fdobj)
1280 return posix_fildes(fdobj, fchdir);
1282 #endif /* HAVE_FCHDIR */
1285 PyDoc_STRVAR(posix_chmod__doc__,
1286 "chmod(path, mode)\n\n\
1287 Change the access permissions of a file.");
1289 static PyObject *
1290 posix_chmod(PyObject *self, PyObject *args)
1292 char *path = NULL;
1293 int i;
1294 int res;
1295 #ifdef Py_WIN_WIDE_FILENAMES
1296 if (unicode_file_names()) {
1297 PyUnicodeObject *po;
1298 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1299 Py_BEGIN_ALLOW_THREADS
1300 res = _wchmod(PyUnicode_AS_UNICODE(po), i);
1301 Py_END_ALLOW_THREADS
1302 if (res < 0)
1303 return posix_error_with_unicode_filename(
1304 PyUnicode_AS_UNICODE(po));
1305 Py_INCREF(Py_None);
1306 return Py_None;
1308 /* Drop the argument parsing error as narrow strings
1309 are also valid. */
1310 PyErr_Clear();
1312 #endif /* Py_WIN_WIDE_FILENAMES */
1313 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
1314 &path, &i))
1315 return NULL;
1316 Py_BEGIN_ALLOW_THREADS
1317 res = chmod(path, i);
1318 Py_END_ALLOW_THREADS
1319 if (res < 0)
1320 return posix_error_with_allocated_filename(path);
1321 PyMem_Free(path);
1322 Py_INCREF(Py_None);
1323 return Py_None;
1327 #ifdef HAVE_CHROOT
1328 PyDoc_STRVAR(posix_chroot__doc__,
1329 "chroot(path)\n\n\
1330 Change root directory to path.");
1332 static PyObject *
1333 posix_chroot(PyObject *self, PyObject *args)
1335 return posix_1str(args, "et:chroot", chroot, NULL, NULL);
1337 #endif
1339 #ifdef HAVE_FSYNC
1340 PyDoc_STRVAR(posix_fsync__doc__,
1341 "fsync(fildes)\n\n\
1342 force write of file with filedescriptor to disk.");
1344 static PyObject *
1345 posix_fsync(PyObject *self, PyObject *fdobj)
1347 return posix_fildes(fdobj, fsync);
1349 #endif /* HAVE_FSYNC */
1351 #ifdef HAVE_FDATASYNC
1353 #ifdef __hpux
1354 extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1355 #endif
1357 PyDoc_STRVAR(posix_fdatasync__doc__,
1358 "fdatasync(fildes)\n\n\
1359 force write of file with filedescriptor to disk.\n\
1360 does not force update of metadata.");
1362 static PyObject *
1363 posix_fdatasync(PyObject *self, PyObject *fdobj)
1365 return posix_fildes(fdobj, fdatasync);
1367 #endif /* HAVE_FDATASYNC */
1370 #ifdef HAVE_CHOWN
1371 PyDoc_STRVAR(posix_chown__doc__,
1372 "chown(path, uid, gid)\n\n\
1373 Change the owner and group id of path to the numeric uid and gid.");
1375 static PyObject *
1376 posix_chown(PyObject *self, PyObject *args)
1378 char *path = NULL;
1379 int uid, gid;
1380 int res;
1381 if (!PyArg_ParseTuple(args, "etii:chown",
1382 Py_FileSystemDefaultEncoding, &path,
1383 &uid, &gid))
1384 return NULL;
1385 Py_BEGIN_ALLOW_THREADS
1386 res = chown(path, (uid_t) uid, (gid_t) gid);
1387 Py_END_ALLOW_THREADS
1388 if (res < 0)
1389 return posix_error_with_allocated_filename(path);
1390 PyMem_Free(path);
1391 Py_INCREF(Py_None);
1392 return Py_None;
1394 #endif /* HAVE_CHOWN */
1396 #ifdef HAVE_LCHOWN
1397 PyDoc_STRVAR(posix_lchown__doc__,
1398 "lchown(path, uid, gid)\n\n\
1399 Change the owner and group id of path to the numeric uid and gid.\n\
1400 This function will not follow symbolic links.");
1402 static PyObject *
1403 posix_lchown(PyObject *self, PyObject *args)
1405 char *path = NULL;
1406 int uid, gid;
1407 int res;
1408 if (!PyArg_ParseTuple(args, "etii:lchown",
1409 Py_FileSystemDefaultEncoding, &path,
1410 &uid, &gid))
1411 return NULL;
1412 Py_BEGIN_ALLOW_THREADS
1413 res = lchown(path, (uid_t) uid, (gid_t) gid);
1414 Py_END_ALLOW_THREADS
1415 if (res < 0)
1416 return posix_error_with_allocated_filename(path);
1417 PyMem_Free(path);
1418 Py_INCREF(Py_None);
1419 return Py_None;
1421 #endif /* HAVE_LCHOWN */
1424 #ifdef HAVE_GETCWD
1425 PyDoc_STRVAR(posix_getcwd__doc__,
1426 "getcwd() -> path\n\n\
1427 Return a string representing the current working directory.");
1429 static PyObject *
1430 posix_getcwd(PyObject *self, PyObject *noargs)
1432 char buf[1026];
1433 char *res;
1435 Py_BEGIN_ALLOW_THREADS
1436 #if defined(PYOS_OS2) && defined(PYCC_GCC)
1437 res = _getcwd2(buf, sizeof buf);
1438 #else
1439 res = getcwd(buf, sizeof buf);
1440 #endif
1441 Py_END_ALLOW_THREADS
1442 if (res == NULL)
1443 return posix_error();
1444 return PyString_FromString(buf);
1447 #ifdef Py_USING_UNICODE
1448 PyDoc_STRVAR(posix_getcwdu__doc__,
1449 "getcwdu() -> path\n\n\
1450 Return a unicode string representing the current working directory.");
1452 static PyObject *
1453 posix_getcwdu(PyObject *self, PyObject *noargs)
1455 char buf[1026];
1456 char *res;
1458 #ifdef Py_WIN_WIDE_FILENAMES
1459 if (unicode_file_names()) {
1460 wchar_t *wres;
1461 wchar_t wbuf[1026];
1462 Py_BEGIN_ALLOW_THREADS
1463 wres = _wgetcwd(wbuf, sizeof wbuf/ sizeof wbuf[0]);
1464 Py_END_ALLOW_THREADS
1465 if (wres == NULL)
1466 return posix_error();
1467 return PyUnicode_FromWideChar(wbuf, wcslen(wbuf));
1469 #endif
1471 Py_BEGIN_ALLOW_THREADS
1472 #if defined(PYOS_OS2) && defined(PYCC_GCC)
1473 res = _getcwd2(buf, sizeof buf);
1474 #else
1475 res = getcwd(buf, sizeof buf);
1476 #endif
1477 Py_END_ALLOW_THREADS
1478 if (res == NULL)
1479 return posix_error();
1480 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
1482 #endif
1483 #endif
1486 #ifdef HAVE_LINK
1487 PyDoc_STRVAR(posix_link__doc__,
1488 "link(src, dst)\n\n\
1489 Create a hard link to a file.");
1491 static PyObject *
1492 posix_link(PyObject *self, PyObject *args)
1494 return posix_2str(args, "etet:link", link, NULL, NULL);
1496 #endif /* HAVE_LINK */
1499 PyDoc_STRVAR(posix_listdir__doc__,
1500 "listdir(path) -> list_of_strings\n\n\
1501 Return a list containing the names of the entries in the directory.\n\
1503 path: path of directory to list\n\
1505 The list is in arbitrary order. It does not include the special\n\
1506 entries '.' and '..' even if they are present in the directory.");
1508 static PyObject *
1509 posix_listdir(PyObject *self, PyObject *args)
1511 /* XXX Should redo this putting the (now four) versions of opendir
1512 in separate files instead of having them all here... */
1513 #if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
1515 PyObject *d, *v;
1516 HANDLE hFindFile;
1517 WIN32_FIND_DATA FileData;
1518 /* MAX_PATH characters could mean a bigger encoded string */
1519 char namebuf[MAX_PATH*2+5];
1520 char *bufptr = namebuf;
1521 int len = sizeof(namebuf)/sizeof(namebuf[0]);
1523 #ifdef Py_WIN_WIDE_FILENAMES
1524 /* If on wide-character-capable OS see if argument
1525 is Unicode and if so use wide API. */
1526 if (unicode_file_names()) {
1527 PyUnicodeObject *po;
1528 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
1529 WIN32_FIND_DATAW wFileData;
1530 Py_UNICODE wnamebuf[MAX_PATH*2+5];
1531 Py_UNICODE wch;
1532 wcsncpy(wnamebuf, PyUnicode_AS_UNICODE(po), MAX_PATH);
1533 wnamebuf[MAX_PATH] = L'\0';
1534 len = wcslen(wnamebuf);
1535 wch = (len > 0) ? wnamebuf[len-1] : L'\0';
1536 if (wch != L'/' && wch != L'\\' && wch != L':')
1537 wnamebuf[len++] = L'/';
1538 wcscpy(wnamebuf + len, L"*.*");
1539 if ((d = PyList_New(0)) == NULL)
1540 return NULL;
1541 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
1542 if (hFindFile == INVALID_HANDLE_VALUE) {
1543 errno = GetLastError();
1544 if (errno == ERROR_FILE_NOT_FOUND) {
1545 return d;
1547 Py_DECREF(d);
1548 return win32_error_unicode("FindFirstFileW", wnamebuf);
1550 do {
1551 if (wFileData.cFileName[0] == L'.' &&
1552 (wFileData.cFileName[1] == L'\0' ||
1553 wFileData.cFileName[1] == L'.' &&
1554 wFileData.cFileName[2] == L'\0'))
1555 continue;
1556 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
1557 if (v == NULL) {
1558 Py_DECREF(d);
1559 d = NULL;
1560 break;
1562 if (PyList_Append(d, v) != 0) {
1563 Py_DECREF(v);
1564 Py_DECREF(d);
1565 d = NULL;
1566 break;
1568 Py_DECREF(v);
1569 } while (FindNextFileW(hFindFile, &wFileData) == TRUE);
1571 if (FindClose(hFindFile) == FALSE) {
1572 Py_DECREF(d);
1573 return win32_error_unicode("FindClose", wnamebuf);
1575 return d;
1577 /* Drop the argument parsing error as narrow strings
1578 are also valid. */
1579 PyErr_Clear();
1581 #endif
1583 if (!PyArg_ParseTuple(args, "et#:listdir",
1584 Py_FileSystemDefaultEncoding, &bufptr, &len))
1585 return NULL;
1586 if (len > 0) {
1587 char ch = namebuf[len-1];
1588 if (ch != SEP && ch != ALTSEP && ch != ':')
1589 namebuf[len++] = '/';
1591 strcpy(namebuf + len, "*.*");
1593 if ((d = PyList_New(0)) == NULL)
1594 return NULL;
1596 hFindFile = FindFirstFile(namebuf, &FileData);
1597 if (hFindFile == INVALID_HANDLE_VALUE) {
1598 errno = GetLastError();
1599 if (errno == ERROR_FILE_NOT_FOUND)
1600 return d;
1601 Py_DECREF(d);
1602 return win32_error("FindFirstFile", namebuf);
1604 do {
1605 if (FileData.cFileName[0] == '.' &&
1606 (FileData.cFileName[1] == '\0' ||
1607 FileData.cFileName[1] == '.' &&
1608 FileData.cFileName[2] == '\0'))
1609 continue;
1610 v = PyString_FromString(FileData.cFileName);
1611 if (v == NULL) {
1612 Py_DECREF(d);
1613 d = NULL;
1614 break;
1616 if (PyList_Append(d, v) != 0) {
1617 Py_DECREF(v);
1618 Py_DECREF(d);
1619 d = NULL;
1620 break;
1622 Py_DECREF(v);
1623 } while (FindNextFile(hFindFile, &FileData) == TRUE);
1625 if (FindClose(hFindFile) == FALSE) {
1626 Py_DECREF(d);
1627 return win32_error("FindClose", namebuf);
1630 return d;
1632 #elif defined(PYOS_OS2)
1634 #ifndef MAX_PATH
1635 #define MAX_PATH CCHMAXPATH
1636 #endif
1637 char *name, *pt;
1638 int len;
1639 PyObject *d, *v;
1640 char namebuf[MAX_PATH+5];
1641 HDIR hdir = 1;
1642 ULONG srchcnt = 1;
1643 FILEFINDBUF3 ep;
1644 APIRET rc;
1646 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
1647 return NULL;
1648 if (len >= MAX_PATH) {
1649 PyErr_SetString(PyExc_ValueError, "path too long");
1650 return NULL;
1652 strcpy(namebuf, name);
1653 for (pt = namebuf; *pt; pt++)
1654 if (*pt == ALTSEP)
1655 *pt = SEP;
1656 if (namebuf[len-1] != SEP)
1657 namebuf[len++] = SEP;
1658 strcpy(namebuf + len, "*.*");
1660 if ((d = PyList_New(0)) == NULL)
1661 return NULL;
1663 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
1664 &hdir, /* Handle to Use While Search Directory */
1665 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
1666 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
1667 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
1668 FIL_STANDARD); /* Format of Entry (EAs or Not) */
1670 if (rc != NO_ERROR) {
1671 errno = ENOENT;
1672 return posix_error_with_filename(name);
1675 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
1676 do {
1677 if (ep.achName[0] == '.'
1678 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
1679 continue; /* Skip Over "." and ".." Names */
1681 strcpy(namebuf, ep.achName);
1683 /* Leave Case of Name Alone -- In Native Form */
1684 /* (Removed Forced Lowercasing Code) */
1686 v = PyString_FromString(namebuf);
1687 if (v == NULL) {
1688 Py_DECREF(d);
1689 d = NULL;
1690 break;
1692 if (PyList_Append(d, v) != 0) {
1693 Py_DECREF(v);
1694 Py_DECREF(d);
1695 d = NULL;
1696 break;
1698 Py_DECREF(v);
1699 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1702 return d;
1703 #else
1705 char *name = NULL;
1706 PyObject *d, *v;
1707 DIR *dirp;
1708 struct dirent *ep;
1709 int arg_is_unicode = 1;
1711 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
1712 arg_is_unicode = 0;
1713 PyErr_Clear();
1715 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
1716 return NULL;
1717 if ((dirp = opendir(name)) == NULL) {
1718 return posix_error_with_allocated_filename(name);
1720 if ((d = PyList_New(0)) == NULL) {
1721 closedir(dirp);
1722 PyMem_Free(name);
1723 return NULL;
1725 while ((ep = readdir(dirp)) != NULL) {
1726 if (ep->d_name[0] == '.' &&
1727 (NAMLEN(ep) == 1 ||
1728 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
1729 continue;
1730 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
1731 if (v == NULL) {
1732 Py_DECREF(d);
1733 d = NULL;
1734 break;
1736 #ifdef Py_USING_UNICODE
1737 if (arg_is_unicode) {
1738 PyObject *w;
1740 w = PyUnicode_FromEncodedObject(v,
1741 Py_FileSystemDefaultEncoding,
1742 "strict");
1743 if (w != NULL) {
1744 Py_DECREF(v);
1745 v = w;
1747 else {
1748 /* fall back to the original byte string, as
1749 discussed in patch #683592 */
1750 PyErr_Clear();
1753 #endif
1754 if (PyList_Append(d, v) != 0) {
1755 Py_DECREF(v);
1756 Py_DECREF(d);
1757 d = NULL;
1758 break;
1760 Py_DECREF(v);
1762 closedir(dirp);
1763 PyMem_Free(name);
1765 return d;
1767 #endif /* which OS */
1768 } /* end of posix_listdir */
1770 #ifdef MS_WINDOWS
1771 /* A helper function for abspath on win32 */
1772 static PyObject *
1773 posix__getfullpathname(PyObject *self, PyObject *args)
1775 /* assume encoded strings wont more than double no of chars */
1776 char inbuf[MAX_PATH*2];
1777 char *inbufp = inbuf;
1778 int insize = sizeof(inbuf)/sizeof(inbuf[0]);
1779 char outbuf[MAX_PATH*2];
1780 char *temp;
1781 #ifdef Py_WIN_WIDE_FILENAMES
1782 if (unicode_file_names()) {
1783 PyUnicodeObject *po;
1784 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
1785 Py_UNICODE woutbuf[MAX_PATH*2];
1786 Py_UNICODE *wtemp;
1787 if (!GetFullPathNameW(PyUnicode_AS_UNICODE(po),
1788 sizeof(woutbuf)/sizeof(woutbuf[0]),
1789 woutbuf, &wtemp))
1790 return win32_error("GetFullPathName", "");
1791 return PyUnicode_FromUnicode(woutbuf, wcslen(woutbuf));
1793 /* Drop the argument parsing error as narrow strings
1794 are also valid. */
1795 PyErr_Clear();
1797 #endif
1798 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
1799 Py_FileSystemDefaultEncoding, &inbufp,
1800 &insize))
1801 return NULL;
1802 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
1803 outbuf, &temp))
1804 return win32_error("GetFullPathName", inbuf);
1805 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
1806 return PyUnicode_Decode(outbuf, strlen(outbuf),
1807 Py_FileSystemDefaultEncoding, NULL);
1809 return PyString_FromString(outbuf);
1810 } /* end of posix__getfullpathname */
1811 #endif /* MS_WINDOWS */
1813 PyDoc_STRVAR(posix_mkdir__doc__,
1814 "mkdir(path [, mode=0777])\n\n\
1815 Create a directory.");
1817 static PyObject *
1818 posix_mkdir(PyObject *self, PyObject *args)
1820 int res;
1821 char *path = NULL;
1822 int mode = 0777;
1824 #ifdef Py_WIN_WIDE_FILENAMES
1825 if (unicode_file_names()) {
1826 PyUnicodeObject *po;
1827 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
1828 Py_BEGIN_ALLOW_THREADS
1829 /* PyUnicode_AS_UNICODE OK without thread lock as
1830 it is a simple dereference. */
1831 res = _wmkdir(PyUnicode_AS_UNICODE(po));
1832 Py_END_ALLOW_THREADS
1833 if (res < 0)
1834 return posix_error();
1835 Py_INCREF(Py_None);
1836 return Py_None;
1838 /* Drop the argument parsing error as narrow strings
1839 are also valid. */
1840 PyErr_Clear();
1842 #endif
1844 if (!PyArg_ParseTuple(args, "et|i:mkdir",
1845 Py_FileSystemDefaultEncoding, &path, &mode))
1846 return NULL;
1847 Py_BEGIN_ALLOW_THREADS
1848 #if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
1849 res = mkdir(path);
1850 #else
1851 res = mkdir(path, mode);
1852 #endif
1853 Py_END_ALLOW_THREADS
1854 if (res < 0)
1855 return posix_error_with_allocated_filename(path);
1856 PyMem_Free(path);
1857 Py_INCREF(Py_None);
1858 return Py_None;
1862 #ifdef HAVE_NICE
1863 #if defined(HAVE_BROKEN_NICE) && defined(HAVE_SYS_RESOURCE_H)
1864 #if defined(HAVE_GETPRIORITY) && !defined(PRIO_PROCESS)
1865 #include <sys/resource.h>
1866 #endif
1867 #endif
1869 PyDoc_STRVAR(posix_nice__doc__,
1870 "nice(inc) -> new_priority\n\n\
1871 Decrease the priority of process by inc and return the new priority.");
1873 static PyObject *
1874 posix_nice(PyObject *self, PyObject *args)
1876 int increment, value;
1878 if (!PyArg_ParseTuple(args, "i:nice", &increment))
1879 return NULL;
1881 /* There are two flavours of 'nice': one that returns the new
1882 priority (as required by almost all standards out there) and the
1883 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
1884 the use of getpriority() to get the new priority.
1886 If we are of the nice family that returns the new priority, we
1887 need to clear errno before the call, and check if errno is filled
1888 before calling posix_error() on a returnvalue of -1, because the
1889 -1 may be the actual new priority! */
1891 errno = 0;
1892 value = nice(increment);
1893 #if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
1894 if (value == 0)
1895 value = getpriority(PRIO_PROCESS, 0);
1896 #endif
1897 if (value == -1 && errno != 0)
1898 /* either nice() or getpriority() returned an error */
1899 return posix_error();
1900 return PyInt_FromLong((long) value);
1902 #endif /* HAVE_NICE */
1905 PyDoc_STRVAR(posix_rename__doc__,
1906 "rename(old, new)\n\n\
1907 Rename a file or directory.");
1909 static PyObject *
1910 posix_rename(PyObject *self, PyObject *args)
1912 #ifdef MS_WINDOWS
1913 return posix_2str(args, "etet:rename", rename, "OO:rename", _wrename);
1914 #else
1915 return posix_2str(args, "etet:rename", rename, NULL, NULL);
1916 #endif
1920 PyDoc_STRVAR(posix_rmdir__doc__,
1921 "rmdir(path)\n\n\
1922 Remove a directory.");
1924 static PyObject *
1925 posix_rmdir(PyObject *self, PyObject *args)
1927 #ifdef MS_WINDOWS
1928 return posix_1str(args, "et:rmdir", rmdir, "U:rmdir", _wrmdir);
1929 #else
1930 return posix_1str(args, "et:rmdir", rmdir, NULL, NULL);
1931 #endif
1935 PyDoc_STRVAR(posix_stat__doc__,
1936 "stat(path) -> stat result\n\n\
1937 Perform a stat system call on the given path.");
1939 static PyObject *
1940 posix_stat(PyObject *self, PyObject *args)
1942 #ifdef MS_WINDOWS
1943 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", _wstati64);
1944 #else
1945 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
1946 #endif
1950 #ifdef HAVE_SYSTEM
1951 PyDoc_STRVAR(posix_system__doc__,
1952 "system(command) -> exit_status\n\n\
1953 Execute the command (a string) in a subshell.");
1955 static PyObject *
1956 posix_system(PyObject *self, PyObject *args)
1958 char *command;
1959 long sts;
1960 if (!PyArg_ParseTuple(args, "s:system", &command))
1961 return NULL;
1962 Py_BEGIN_ALLOW_THREADS
1963 sts = system(command);
1964 Py_END_ALLOW_THREADS
1965 return PyInt_FromLong(sts);
1967 #endif
1970 PyDoc_STRVAR(posix_umask__doc__,
1971 "umask(new_mask) -> old_mask\n\n\
1972 Set the current numeric umask and return the previous umask.");
1974 static PyObject *
1975 posix_umask(PyObject *self, PyObject *args)
1977 int i;
1978 if (!PyArg_ParseTuple(args, "i:umask", &i))
1979 return NULL;
1980 i = (int)umask(i);
1981 if (i < 0)
1982 return posix_error();
1983 return PyInt_FromLong((long)i);
1987 PyDoc_STRVAR(posix_unlink__doc__,
1988 "unlink(path)\n\n\
1989 Remove a file (same as remove(path)).");
1991 PyDoc_STRVAR(posix_remove__doc__,
1992 "remove(path)\n\n\
1993 Remove a file (same as unlink(path)).");
1995 static PyObject *
1996 posix_unlink(PyObject *self, PyObject *args)
1998 #ifdef MS_WINDOWS
1999 return posix_1str(args, "et:remove", unlink, "U:remove", _wunlink);
2000 #else
2001 return posix_1str(args, "et:remove", unlink, NULL, NULL);
2002 #endif
2006 #ifdef HAVE_UNAME
2007 PyDoc_STRVAR(posix_uname__doc__,
2008 "uname() -> (sysname, nodename, release, version, machine)\n\n\
2009 Return a tuple identifying the current operating system.");
2011 static PyObject *
2012 posix_uname(PyObject *self, PyObject *noargs)
2014 struct utsname u;
2015 int res;
2017 Py_BEGIN_ALLOW_THREADS
2018 res = uname(&u);
2019 Py_END_ALLOW_THREADS
2020 if (res < 0)
2021 return posix_error();
2022 return Py_BuildValue("(sssss)",
2023 u.sysname,
2024 u.nodename,
2025 u.release,
2026 u.version,
2027 u.machine);
2029 #endif /* HAVE_UNAME */
2031 static int
2032 extract_time(PyObject *t, long* sec, long* usec)
2034 long intval;
2035 if (PyFloat_Check(t)) {
2036 double tval = PyFloat_AsDouble(t);
2037 PyObject *intobj = t->ob_type->tp_as_number->nb_int(t);
2038 if (!intobj)
2039 return -1;
2040 intval = PyInt_AsLong(intobj);
2041 Py_DECREF(intobj);
2042 if (intval == -1 && PyErr_Occurred())
2043 return -1;
2044 *sec = intval;
2045 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
2046 if (*usec < 0)
2047 /* If rounding gave us a negative number,
2048 truncate. */
2049 *usec = 0;
2050 return 0;
2052 intval = PyInt_AsLong(t);
2053 if (intval == -1 && PyErr_Occurred())
2054 return -1;
2055 *sec = intval;
2056 *usec = 0;
2057 return 0;
2060 PyDoc_STRVAR(posix_utime__doc__,
2061 "utime(path, (atime, utime))\n\
2062 utime(path, None)\n\n\
2063 Set the access and modified time of the file to the given values. If the\n\
2064 second form is used, set the access and modified times to the current time.");
2066 static PyObject *
2067 posix_utime(PyObject *self, PyObject *args)
2069 char *path = NULL;
2070 long atime, mtime, ausec, musec;
2071 int res;
2072 PyObject* arg;
2074 #if defined(HAVE_UTIMES)
2075 struct timeval buf[2];
2076 #define ATIME buf[0].tv_sec
2077 #define MTIME buf[1].tv_sec
2078 #elif defined(HAVE_UTIME_H)
2079 /* XXX should define struct utimbuf instead, above */
2080 struct utimbuf buf;
2081 #define ATIME buf.actime
2082 #define MTIME buf.modtime
2083 #define UTIME_ARG &buf
2084 #else /* HAVE_UTIMES */
2085 time_t buf[2];
2086 #define ATIME buf[0]
2087 #define MTIME buf[1]
2088 #define UTIME_ARG buf
2089 #endif /* HAVE_UTIMES */
2091 int have_unicode_filename = 0;
2092 #ifdef Py_WIN_WIDE_FILENAMES
2093 PyUnicodeObject *obwpath;
2094 wchar_t *wpath;
2095 if (unicode_file_names()) {
2096 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
2097 wpath = PyUnicode_AS_UNICODE(obwpath);
2098 have_unicode_filename = 1;
2099 } else
2100 /* Drop the argument parsing error as narrow strings
2101 are also valid. */
2102 PyErr_Clear();
2104 #endif /* Py_WIN_WIDE_FILENAMES */
2106 if (!have_unicode_filename && \
2107 !PyArg_ParseTuple(args, "etO:utime",
2108 Py_FileSystemDefaultEncoding, &path, &arg))
2109 return NULL;
2110 if (arg == Py_None) {
2111 /* optional time values not given */
2112 Py_BEGIN_ALLOW_THREADS
2113 #ifdef Py_WIN_WIDE_FILENAMES
2114 if (have_unicode_filename)
2115 res = _wutime(wpath, NULL);
2116 else
2117 #endif /* Py_WIN_WIDE_FILENAMES */
2118 res = utime(path, NULL);
2119 Py_END_ALLOW_THREADS
2121 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
2122 PyErr_SetString(PyExc_TypeError,
2123 "utime() arg 2 must be a tuple (atime, mtime)");
2124 PyMem_Free(path);
2125 return NULL;
2127 else {
2128 if (extract_time(PyTuple_GET_ITEM(arg, 0),
2129 &atime, &ausec) == -1) {
2130 PyMem_Free(path);
2131 return NULL;
2133 if (extract_time(PyTuple_GET_ITEM(arg, 1),
2134 &mtime, &musec) == -1) {
2135 PyMem_Free(path);
2136 return NULL;
2138 ATIME = atime;
2139 MTIME = mtime;
2140 #ifdef HAVE_UTIMES
2141 buf[0].tv_usec = ausec;
2142 buf[1].tv_usec = musec;
2143 Py_BEGIN_ALLOW_THREADS
2144 res = utimes(path, buf);
2145 Py_END_ALLOW_THREADS
2146 #else
2147 Py_BEGIN_ALLOW_THREADS
2148 #ifdef Py_WIN_WIDE_FILENAMES
2149 if (have_unicode_filename)
2150 /* utime is OK with utimbuf, but _wutime insists
2151 on _utimbuf (the msvc headers assert the
2152 underscore version is ansi) */
2153 res = _wutime(wpath, (struct _utimbuf *)UTIME_ARG);
2154 else
2155 #endif /* Py_WIN_WIDE_FILENAMES */
2156 res = utime(path, UTIME_ARG);
2157 Py_END_ALLOW_THREADS
2158 #endif /* HAVE_UTIMES */
2160 if (res < 0) {
2161 #ifdef Py_WIN_WIDE_FILENAMES
2162 if (have_unicode_filename)
2163 return posix_error_with_unicode_filename(wpath);
2164 #endif /* Py_WIN_WIDE_FILENAMES */
2165 return posix_error_with_allocated_filename(path);
2167 PyMem_Free(path);
2168 Py_INCREF(Py_None);
2169 return Py_None;
2170 #undef UTIME_ARG
2171 #undef ATIME
2172 #undef MTIME
2176 /* Process operations */
2178 PyDoc_STRVAR(posix__exit__doc__,
2179 "_exit(status)\n\n\
2180 Exit to the system with specified status, without normal exit processing.");
2182 static PyObject *
2183 posix__exit(PyObject *self, PyObject *args)
2185 int sts;
2186 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
2187 return NULL;
2188 _exit(sts);
2189 return NULL; /* Make gcc -Wall happy */
2192 #if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
2193 static void
2194 free_string_array(char **array, int count)
2196 int i;
2197 for (i = 0; i < count; i++)
2198 PyMem_Free(array[i]);
2199 PyMem_DEL(array);
2201 #endif
2204 #ifdef HAVE_EXECV
2205 PyDoc_STRVAR(posix_execv__doc__,
2206 "execv(path, args)\n\n\
2207 Execute an executable path with arguments, replacing current process.\n\
2209 path: path of executable file\n\
2210 args: tuple or list of strings");
2212 static PyObject *
2213 posix_execv(PyObject *self, PyObject *args)
2215 char *path;
2216 PyObject *argv;
2217 char **argvlist;
2218 int i, argc;
2219 PyObject *(*getitem)(PyObject *, int);
2221 /* execv has two arguments: (path, argv), where
2222 argv is a list or tuple of strings. */
2224 if (!PyArg_ParseTuple(args, "etO:execv",
2225 Py_FileSystemDefaultEncoding,
2226 &path, &argv))
2227 return NULL;
2228 if (PyList_Check(argv)) {
2229 argc = PyList_Size(argv);
2230 getitem = PyList_GetItem;
2232 else if (PyTuple_Check(argv)) {
2233 argc = PyTuple_Size(argv);
2234 getitem = PyTuple_GetItem;
2236 else {
2237 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
2238 PyMem_Free(path);
2239 return NULL;
2242 argvlist = PyMem_NEW(char *, argc+1);
2243 if (argvlist == NULL) {
2244 PyMem_Free(path);
2245 return PyErr_NoMemory();
2247 for (i = 0; i < argc; i++) {
2248 if (!PyArg_Parse((*getitem)(argv, i), "et",
2249 Py_FileSystemDefaultEncoding,
2250 &argvlist[i])) {
2251 free_string_array(argvlist, i);
2252 PyErr_SetString(PyExc_TypeError,
2253 "execv() arg 2 must contain only strings");
2254 PyMem_Free(path);
2255 return NULL;
2259 argvlist[argc] = NULL;
2261 execv(path, argvlist);
2263 /* If we get here it's definitely an error */
2265 free_string_array(argvlist, argc);
2266 PyMem_Free(path);
2267 return posix_error();
2271 PyDoc_STRVAR(posix_execve__doc__,
2272 "execve(path, args, env)\n\n\
2273 Execute a path with arguments and environment, replacing current process.\n\
2275 path: path of executable file\n\
2276 args: tuple or list of arguments\n\
2277 env: dictionary of strings mapping to strings");
2279 static PyObject *
2280 posix_execve(PyObject *self, PyObject *args)
2282 char *path;
2283 PyObject *argv, *env;
2284 char **argvlist;
2285 char **envlist;
2286 PyObject *key, *val, *keys=NULL, *vals=NULL;
2287 int i, pos, argc, envc;
2288 PyObject *(*getitem)(PyObject *, int);
2289 int lastarg = 0;
2291 /* execve has three arguments: (path, argv, env), where
2292 argv is a list or tuple of strings and env is a dictionary
2293 like posix.environ. */
2295 if (!PyArg_ParseTuple(args, "etOO:execve",
2296 Py_FileSystemDefaultEncoding,
2297 &path, &argv, &env))
2298 return NULL;
2299 if (PyList_Check(argv)) {
2300 argc = PyList_Size(argv);
2301 getitem = PyList_GetItem;
2303 else if (PyTuple_Check(argv)) {
2304 argc = PyTuple_Size(argv);
2305 getitem = PyTuple_GetItem;
2307 else {
2308 PyErr_SetString(PyExc_TypeError,
2309 "execve() arg 2 must be a tuple or list");
2310 goto fail_0;
2312 if (!PyMapping_Check(env)) {
2313 PyErr_SetString(PyExc_TypeError,
2314 "execve() arg 3 must be a mapping object");
2315 goto fail_0;
2318 argvlist = PyMem_NEW(char *, argc+1);
2319 if (argvlist == NULL) {
2320 PyErr_NoMemory();
2321 goto fail_0;
2323 for (i = 0; i < argc; i++) {
2324 if (!PyArg_Parse((*getitem)(argv, i),
2325 "et;execve() arg 2 must contain only strings",
2326 Py_FileSystemDefaultEncoding,
2327 &argvlist[i]))
2329 lastarg = i;
2330 goto fail_1;
2333 lastarg = argc;
2334 argvlist[argc] = NULL;
2336 i = PyMapping_Size(env);
2337 if (i < 0)
2338 goto fail_1;
2339 envlist = PyMem_NEW(char *, i + 1);
2340 if (envlist == NULL) {
2341 PyErr_NoMemory();
2342 goto fail_1;
2344 envc = 0;
2345 keys = PyMapping_Keys(env);
2346 vals = PyMapping_Values(env);
2347 if (!keys || !vals)
2348 goto fail_2;
2349 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2350 PyErr_SetString(PyExc_TypeError,
2351 "execve(): env.keys() or env.values() is not a list");
2352 goto fail_2;
2355 for (pos = 0; pos < i; pos++) {
2356 char *p, *k, *v;
2357 size_t len;
2359 key = PyList_GetItem(keys, pos);
2360 val = PyList_GetItem(vals, pos);
2361 if (!key || !val)
2362 goto fail_2;
2364 if (!PyArg_Parse(
2365 key,
2366 "s;execve() arg 3 contains a non-string key",
2367 &k) ||
2368 !PyArg_Parse(
2369 val,
2370 "s;execve() arg 3 contains a non-string value",
2371 &v))
2373 goto fail_2;
2376 #if defined(PYOS_OS2)
2377 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
2378 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
2379 #endif
2380 len = PyString_Size(key) + PyString_Size(val) + 2;
2381 p = PyMem_NEW(char, len);
2382 if (p == NULL) {
2383 PyErr_NoMemory();
2384 goto fail_2;
2386 PyOS_snprintf(p, len, "%s=%s", k, v);
2387 envlist[envc++] = p;
2388 #if defined(PYOS_OS2)
2390 #endif
2392 envlist[envc] = 0;
2394 execve(path, argvlist, envlist);
2396 /* If we get here it's definitely an error */
2398 (void) posix_error();
2400 fail_2:
2401 while (--envc >= 0)
2402 PyMem_DEL(envlist[envc]);
2403 PyMem_DEL(envlist);
2404 fail_1:
2405 free_string_array(argvlist, lastarg);
2406 Py_XDECREF(vals);
2407 Py_XDECREF(keys);
2408 fail_0:
2409 PyMem_Free(path);
2410 return NULL;
2412 #endif /* HAVE_EXECV */
2415 #ifdef HAVE_SPAWNV
2416 PyDoc_STRVAR(posix_spawnv__doc__,
2417 "spawnv(mode, path, args)\n\n\
2418 Execute the program 'path' in a new process.\n\
2420 mode: mode of process creation\n\
2421 path: path of executable file\n\
2422 args: tuple or list of strings");
2424 static PyObject *
2425 posix_spawnv(PyObject *self, PyObject *args)
2427 char *path;
2428 PyObject *argv;
2429 char **argvlist;
2430 int mode, i, argc;
2431 Py_intptr_t spawnval;
2432 PyObject *(*getitem)(PyObject *, int);
2434 /* spawnv has three arguments: (mode, path, argv), where
2435 argv is a list or tuple of strings. */
2437 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
2438 Py_FileSystemDefaultEncoding,
2439 &path, &argv))
2440 return NULL;
2441 if (PyList_Check(argv)) {
2442 argc = PyList_Size(argv);
2443 getitem = PyList_GetItem;
2445 else if (PyTuple_Check(argv)) {
2446 argc = PyTuple_Size(argv);
2447 getitem = PyTuple_GetItem;
2449 else {
2450 PyErr_SetString(PyExc_TypeError,
2451 "spawnv() arg 2 must be a tuple or list");
2452 PyMem_Free(path);
2453 return NULL;
2456 argvlist = PyMem_NEW(char *, argc+1);
2457 if (argvlist == NULL) {
2458 PyMem_Free(path);
2459 return PyErr_NoMemory();
2461 for (i = 0; i < argc; i++) {
2462 if (!PyArg_Parse((*getitem)(argv, i), "et",
2463 Py_FileSystemDefaultEncoding,
2464 &argvlist[i])) {
2465 free_string_array(argvlist, i);
2466 PyErr_SetString(
2467 PyExc_TypeError,
2468 "spawnv() arg 2 must contain only strings");
2469 PyMem_Free(path);
2470 return NULL;
2473 argvlist[argc] = NULL;
2475 #if defined(PYOS_OS2) && defined(PYCC_GCC)
2476 Py_BEGIN_ALLOW_THREADS
2477 spawnval = spawnv(mode, path, argvlist);
2478 Py_END_ALLOW_THREADS
2479 #else
2480 if (mode == _OLD_P_OVERLAY)
2481 mode = _P_OVERLAY;
2483 Py_BEGIN_ALLOW_THREADS
2484 spawnval = _spawnv(mode, path, argvlist);
2485 Py_END_ALLOW_THREADS
2486 #endif
2488 free_string_array(argvlist, argc);
2489 PyMem_Free(path);
2491 if (spawnval == -1)
2492 return posix_error();
2493 else
2494 #if SIZEOF_LONG == SIZEOF_VOID_P
2495 return Py_BuildValue("l", (long) spawnval);
2496 #else
2497 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
2498 #endif
2502 PyDoc_STRVAR(posix_spawnve__doc__,
2503 "spawnve(mode, path, args, env)\n\n\
2504 Execute the program 'path' in a new process.\n\
2506 mode: mode of process creation\n\
2507 path: path of executable file\n\
2508 args: tuple or list of arguments\n\
2509 env: dictionary of strings mapping to strings");
2511 static PyObject *
2512 posix_spawnve(PyObject *self, PyObject *args)
2514 char *path;
2515 PyObject *argv, *env;
2516 char **argvlist;
2517 char **envlist;
2518 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
2519 int mode, i, pos, argc, envc;
2520 Py_intptr_t spawnval;
2521 PyObject *(*getitem)(PyObject *, int);
2522 int lastarg = 0;
2524 /* spawnve has four arguments: (mode, path, argv, env), where
2525 argv is a list or tuple of strings and env is a dictionary
2526 like posix.environ. */
2528 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
2529 Py_FileSystemDefaultEncoding,
2530 &path, &argv, &env))
2531 return NULL;
2532 if (PyList_Check(argv)) {
2533 argc = PyList_Size(argv);
2534 getitem = PyList_GetItem;
2536 else if (PyTuple_Check(argv)) {
2537 argc = PyTuple_Size(argv);
2538 getitem = PyTuple_GetItem;
2540 else {
2541 PyErr_SetString(PyExc_TypeError,
2542 "spawnve() arg 2 must be a tuple or list");
2543 goto fail_0;
2545 if (!PyMapping_Check(env)) {
2546 PyErr_SetString(PyExc_TypeError,
2547 "spawnve() arg 3 must be a mapping object");
2548 goto fail_0;
2551 argvlist = PyMem_NEW(char *, argc+1);
2552 if (argvlist == NULL) {
2553 PyErr_NoMemory();
2554 goto fail_0;
2556 for (i = 0; i < argc; i++) {
2557 if (!PyArg_Parse((*getitem)(argv, i),
2558 "et;spawnve() arg 2 must contain only strings",
2559 Py_FileSystemDefaultEncoding,
2560 &argvlist[i]))
2562 lastarg = i;
2563 goto fail_1;
2566 lastarg = argc;
2567 argvlist[argc] = NULL;
2569 i = PyMapping_Size(env);
2570 if (i < 0)
2571 goto fail_1;
2572 envlist = PyMem_NEW(char *, i + 1);
2573 if (envlist == NULL) {
2574 PyErr_NoMemory();
2575 goto fail_1;
2577 envc = 0;
2578 keys = PyMapping_Keys(env);
2579 vals = PyMapping_Values(env);
2580 if (!keys || !vals)
2581 goto fail_2;
2582 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2583 PyErr_SetString(PyExc_TypeError,
2584 "spawnve(): env.keys() or env.values() is not a list");
2585 goto fail_2;
2588 for (pos = 0; pos < i; pos++) {
2589 char *p, *k, *v;
2590 size_t len;
2592 key = PyList_GetItem(keys, pos);
2593 val = PyList_GetItem(vals, pos);
2594 if (!key || !val)
2595 goto fail_2;
2597 if (!PyArg_Parse(
2598 key,
2599 "s;spawnve() arg 3 contains a non-string key",
2600 &k) ||
2601 !PyArg_Parse(
2602 val,
2603 "s;spawnve() arg 3 contains a non-string value",
2604 &v))
2606 goto fail_2;
2608 len = PyString_Size(key) + PyString_Size(val) + 2;
2609 p = PyMem_NEW(char, len);
2610 if (p == NULL) {
2611 PyErr_NoMemory();
2612 goto fail_2;
2614 PyOS_snprintf(p, len, "%s=%s", k, v);
2615 envlist[envc++] = p;
2617 envlist[envc] = 0;
2619 #if defined(PYOS_OS2) && defined(PYCC_GCC)
2620 Py_BEGIN_ALLOW_THREADS
2621 spawnval = spawnve(mode, path, argvlist, envlist);
2622 Py_END_ALLOW_THREADS
2623 #else
2624 if (mode == _OLD_P_OVERLAY)
2625 mode = _P_OVERLAY;
2627 Py_BEGIN_ALLOW_THREADS
2628 spawnval = _spawnve(mode, path, argvlist, envlist);
2629 Py_END_ALLOW_THREADS
2630 #endif
2632 if (spawnval == -1)
2633 (void) posix_error();
2634 else
2635 #if SIZEOF_LONG == SIZEOF_VOID_P
2636 res = Py_BuildValue("l", (long) spawnval);
2637 #else
2638 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
2639 #endif
2641 fail_2:
2642 while (--envc >= 0)
2643 PyMem_DEL(envlist[envc]);
2644 PyMem_DEL(envlist);
2645 fail_1:
2646 free_string_array(argvlist, lastarg);
2647 Py_XDECREF(vals);
2648 Py_XDECREF(keys);
2649 fail_0:
2650 PyMem_Free(path);
2651 return res;
2654 /* OS/2 supports spawnvp & spawnvpe natively */
2655 #if defined(PYOS_OS2)
2656 PyDoc_STRVAR(posix_spawnvp__doc__,
2657 "spawnvp(mode, file, args)\n\n\
2658 Execute the program 'file' in a new process, using the environment\n\
2659 search path to find the file.\n\
2661 mode: mode of process creation\n\
2662 file: executable file name\n\
2663 args: tuple or list of strings");
2665 static PyObject *
2666 posix_spawnvp(PyObject *self, PyObject *args)
2668 char *path;
2669 PyObject *argv;
2670 char **argvlist;
2671 int mode, i, argc;
2672 Py_intptr_t spawnval;
2673 PyObject *(*getitem)(PyObject *, int);
2675 /* spawnvp has three arguments: (mode, path, argv), where
2676 argv is a list or tuple of strings. */
2678 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
2679 Py_FileSystemDefaultEncoding,
2680 &path, &argv))
2681 return NULL;
2682 if (PyList_Check(argv)) {
2683 argc = PyList_Size(argv);
2684 getitem = PyList_GetItem;
2686 else if (PyTuple_Check(argv)) {
2687 argc = PyTuple_Size(argv);
2688 getitem = PyTuple_GetItem;
2690 else {
2691 PyErr_SetString(PyExc_TypeError,
2692 "spawnvp() arg 2 must be a tuple or list");
2693 PyMem_Free(path);
2694 return NULL;
2697 argvlist = PyMem_NEW(char *, argc+1);
2698 if (argvlist == NULL) {
2699 PyMem_Free(path);
2700 return PyErr_NoMemory();
2702 for (i = 0; i < argc; i++) {
2703 if (!PyArg_Parse((*getitem)(argv, i), "et",
2704 Py_FileSystemDefaultEncoding,
2705 &argvlist[i])) {
2706 free_string_array(argvlist, i);
2707 PyErr_SetString(
2708 PyExc_TypeError,
2709 "spawnvp() arg 2 must contain only strings");
2710 PyMem_Free(path);
2711 return NULL;
2714 argvlist[argc] = NULL;
2716 Py_BEGIN_ALLOW_THREADS
2717 #if defined(PYCC_GCC)
2718 spawnval = spawnvp(mode, path, argvlist);
2719 #else
2720 spawnval = _spawnvp(mode, path, argvlist);
2721 #endif
2722 Py_END_ALLOW_THREADS
2724 free_string_array(argvlist, argc);
2725 PyMem_Free(path);
2727 if (spawnval == -1)
2728 return posix_error();
2729 else
2730 return Py_BuildValue("l", (long) spawnval);
2734 PyDoc_STRVAR(posix_spawnvpe__doc__,
2735 "spawnvpe(mode, file, args, env)\n\n\
2736 Execute the program 'file' in a new process, using the environment\n\
2737 search path to find the file.\n\
2739 mode: mode of process creation\n\
2740 file: executable file name\n\
2741 args: tuple or list of arguments\n\
2742 env: dictionary of strings mapping to strings");
2744 static PyObject *
2745 posix_spawnvpe(PyObject *self, PyObject *args)
2747 char *path;
2748 PyObject *argv, *env;
2749 char **argvlist;
2750 char **envlist;
2751 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
2752 int mode, i, pos, argc, envc;
2753 Py_intptr_t spawnval;
2754 PyObject *(*getitem)(PyObject *, int);
2755 int lastarg = 0;
2757 /* spawnvpe has four arguments: (mode, path, argv, env), where
2758 argv is a list or tuple of strings and env is a dictionary
2759 like posix.environ. */
2761 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
2762 Py_FileSystemDefaultEncoding,
2763 &path, &argv, &env))
2764 return NULL;
2765 if (PyList_Check(argv)) {
2766 argc = PyList_Size(argv);
2767 getitem = PyList_GetItem;
2769 else if (PyTuple_Check(argv)) {
2770 argc = PyTuple_Size(argv);
2771 getitem = PyTuple_GetItem;
2773 else {
2774 PyErr_SetString(PyExc_TypeError,
2775 "spawnvpe() arg 2 must be a tuple or list");
2776 goto fail_0;
2778 if (!PyMapping_Check(env)) {
2779 PyErr_SetString(PyExc_TypeError,
2780 "spawnvpe() arg 3 must be a mapping object");
2781 goto fail_0;
2784 argvlist = PyMem_NEW(char *, argc+1);
2785 if (argvlist == NULL) {
2786 PyErr_NoMemory();
2787 goto fail_0;
2789 for (i = 0; i < argc; i++) {
2790 if (!PyArg_Parse((*getitem)(argv, i),
2791 "et;spawnvpe() arg 2 must contain only strings",
2792 Py_FileSystemDefaultEncoding,
2793 &argvlist[i]))
2795 lastarg = i;
2796 goto fail_1;
2799 lastarg = argc;
2800 argvlist[argc] = NULL;
2802 i = PyMapping_Size(env);
2803 if (i < 0)
2804 goto fail_1;
2805 envlist = PyMem_NEW(char *, i + 1);
2806 if (envlist == NULL) {
2807 PyErr_NoMemory();
2808 goto fail_1;
2810 envc = 0;
2811 keys = PyMapping_Keys(env);
2812 vals = PyMapping_Values(env);
2813 if (!keys || !vals)
2814 goto fail_2;
2815 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2816 PyErr_SetString(PyExc_TypeError,
2817 "spawnvpe(): env.keys() or env.values() is not a list");
2818 goto fail_2;
2821 for (pos = 0; pos < i; pos++) {
2822 char *p, *k, *v;
2823 size_t len;
2825 key = PyList_GetItem(keys, pos);
2826 val = PyList_GetItem(vals, pos);
2827 if (!key || !val)
2828 goto fail_2;
2830 if (!PyArg_Parse(
2831 key,
2832 "s;spawnvpe() arg 3 contains a non-string key",
2833 &k) ||
2834 !PyArg_Parse(
2835 val,
2836 "s;spawnvpe() arg 3 contains a non-string value",
2837 &v))
2839 goto fail_2;
2841 len = PyString_Size(key) + PyString_Size(val) + 2;
2842 p = PyMem_NEW(char, len);
2843 if (p == NULL) {
2844 PyErr_NoMemory();
2845 goto fail_2;
2847 PyOS_snprintf(p, len, "%s=%s", k, v);
2848 envlist[envc++] = p;
2850 envlist[envc] = 0;
2852 Py_BEGIN_ALLOW_THREADS
2853 #if defined(PYCC_GCC)
2854 spawnval = spawnve(mode, path, argvlist, envlist);
2855 #else
2856 spawnval = _spawnve(mode, path, argvlist, envlist);
2857 #endif
2858 Py_END_ALLOW_THREADS
2860 if (spawnval == -1)
2861 (void) posix_error();
2862 else
2863 res = Py_BuildValue("l", (long) spawnval);
2865 fail_2:
2866 while (--envc >= 0)
2867 PyMem_DEL(envlist[envc]);
2868 PyMem_DEL(envlist);
2869 fail_1:
2870 free_string_array(argvlist, lastarg);
2871 Py_XDECREF(vals);
2872 Py_XDECREF(keys);
2873 fail_0:
2874 PyMem_Free(path);
2875 return res;
2877 #endif /* PYOS_OS2 */
2878 #endif /* HAVE_SPAWNV */
2881 #ifdef HAVE_FORK1
2882 PyDoc_STRVAR(posix_fork1__doc__,
2883 "fork1() -> pid\n\n\
2884 Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
2886 Return 0 to child process and PID of child to parent process.");
2888 static PyObject *
2889 posix_fork1(PyObject *self, PyObject *noargs)
2891 int pid = fork1();
2892 if (pid == -1)
2893 return posix_error();
2894 PyOS_AfterFork();
2895 return PyInt_FromLong((long)pid);
2897 #endif
2900 #ifdef HAVE_FORK
2901 PyDoc_STRVAR(posix_fork__doc__,
2902 "fork() -> pid\n\n\
2903 Fork a child process.\n\
2904 Return 0 to child process and PID of child to parent process.");
2906 static PyObject *
2907 posix_fork(PyObject *self, PyObject *noargs)
2909 int pid = fork();
2910 if (pid == -1)
2911 return posix_error();
2912 if (pid == 0)
2913 PyOS_AfterFork();
2914 return PyInt_FromLong((long)pid);
2916 #endif
2918 /* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
2919 /* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
2920 #if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
2921 #define DEV_PTY_FILE "/dev/ptc"
2922 #define HAVE_DEV_PTMX
2923 #else
2924 #define DEV_PTY_FILE "/dev/ptmx"
2925 #endif
2927 #if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
2928 #ifdef HAVE_PTY_H
2929 #include <pty.h>
2930 #else
2931 #ifdef HAVE_LIBUTIL_H
2932 #include <libutil.h>
2933 #endif /* HAVE_LIBUTIL_H */
2934 #endif /* HAVE_PTY_H */
2935 #ifdef HAVE_STROPTS_H
2936 #include <stropts.h>
2937 #endif
2938 #endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
2940 #if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
2941 PyDoc_STRVAR(posix_openpty__doc__,
2942 "openpty() -> (master_fd, slave_fd)\n\n\
2943 Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
2945 static PyObject *
2946 posix_openpty(PyObject *self, PyObject *noargs)
2948 int master_fd, slave_fd;
2949 #ifndef HAVE_OPENPTY
2950 char * slave_name;
2951 #endif
2952 #if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
2953 PyOS_sighandler_t sig_saved;
2954 #ifdef sun
2955 extern char *ptsname();
2956 #endif
2957 #endif
2959 #ifdef HAVE_OPENPTY
2960 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
2961 return posix_error();
2962 #elif defined(HAVE__GETPTY)
2963 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
2964 if (slave_name == NULL)
2965 return posix_error();
2967 slave_fd = open(slave_name, O_RDWR);
2968 if (slave_fd < 0)
2969 return posix_error();
2970 #else
2971 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
2972 if (master_fd < 0)
2973 return posix_error();
2974 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
2975 /* change permission of slave */
2976 if (grantpt(master_fd) < 0) {
2977 PyOS_setsig(SIGCHLD, sig_saved);
2978 return posix_error();
2980 /* unlock slave */
2981 if (unlockpt(master_fd) < 0) {
2982 PyOS_setsig(SIGCHLD, sig_saved);
2983 return posix_error();
2985 PyOS_setsig(SIGCHLD, sig_saved);
2986 slave_name = ptsname(master_fd); /* get name of slave */
2987 if (slave_name == NULL)
2988 return posix_error();
2989 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
2990 if (slave_fd < 0)
2991 return posix_error();
2992 #if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
2993 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
2994 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
2995 #ifndef __hpux
2996 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
2997 #endif /* __hpux */
2998 #endif /* HAVE_CYGWIN */
2999 #endif /* HAVE_OPENPTY */
3001 return Py_BuildValue("(ii)", master_fd, slave_fd);
3004 #endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
3006 #ifdef HAVE_FORKPTY
3007 PyDoc_STRVAR(posix_forkpty__doc__,
3008 "forkpty() -> (pid, master_fd)\n\n\
3009 Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
3010 Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
3011 To both, return fd of newly opened pseudo-terminal.\n");
3013 static PyObject *
3014 posix_forkpty(PyObject *self, PyObject *noargs)
3016 int master_fd = -1, pid;
3018 pid = forkpty(&master_fd, NULL, NULL, NULL);
3019 if (pid == -1)
3020 return posix_error();
3021 if (pid == 0)
3022 PyOS_AfterFork();
3023 return Py_BuildValue("(ii)", pid, master_fd);
3025 #endif
3027 #ifdef HAVE_GETEGID
3028 PyDoc_STRVAR(posix_getegid__doc__,
3029 "getegid() -> egid\n\n\
3030 Return the current process's effective group id.");
3032 static PyObject *
3033 posix_getegid(PyObject *self, PyObject *noargs)
3035 return PyInt_FromLong((long)getegid());
3037 #endif
3040 #ifdef HAVE_GETEUID
3041 PyDoc_STRVAR(posix_geteuid__doc__,
3042 "geteuid() -> euid\n\n\
3043 Return the current process's effective user id.");
3045 static PyObject *
3046 posix_geteuid(PyObject *self, PyObject *noargs)
3048 return PyInt_FromLong((long)geteuid());
3050 #endif
3053 #ifdef HAVE_GETGID
3054 PyDoc_STRVAR(posix_getgid__doc__,
3055 "getgid() -> gid\n\n\
3056 Return the current process's group id.");
3058 static PyObject *
3059 posix_getgid(PyObject *self, PyObject *noargs)
3061 return PyInt_FromLong((long)getgid());
3063 #endif
3066 PyDoc_STRVAR(posix_getpid__doc__,
3067 "getpid() -> pid\n\n\
3068 Return the current process id");
3070 static PyObject *
3071 posix_getpid(PyObject *self, PyObject *noargs)
3073 return PyInt_FromLong((long)getpid());
3077 #ifdef HAVE_GETGROUPS
3078 PyDoc_STRVAR(posix_getgroups__doc__,
3079 "getgroups() -> list of group IDs\n\n\
3080 Return list of supplemental group IDs for the process.");
3082 static PyObject *
3083 posix_getgroups(PyObject *self, PyObject *noargs)
3085 PyObject *result = NULL;
3087 #ifdef NGROUPS_MAX
3088 #define MAX_GROUPS NGROUPS_MAX
3089 #else
3090 /* defined to be 16 on Solaris7, so this should be a small number */
3091 #define MAX_GROUPS 64
3092 #endif
3093 gid_t grouplist[MAX_GROUPS];
3094 int n;
3096 n = getgroups(MAX_GROUPS, grouplist);
3097 if (n < 0)
3098 posix_error();
3099 else {
3100 result = PyList_New(n);
3101 if (result != NULL) {
3102 int i;
3103 for (i = 0; i < n; ++i) {
3104 PyObject *o = PyInt_FromLong((long)grouplist[i]);
3105 if (o == NULL) {
3106 Py_DECREF(result);
3107 result = NULL;
3108 break;
3110 PyList_SET_ITEM(result, i, o);
3115 return result;
3117 #endif
3119 #ifdef HAVE_GETPGID
3120 PyDoc_STRVAR(posix_getpgid__doc__,
3121 "getpgid(pid) -> pgid\n\n\
3122 Call the system call getpgid().");
3124 static PyObject *
3125 posix_getpgid(PyObject *self, PyObject *args)
3127 int pid, pgid;
3128 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
3129 return NULL;
3130 pgid = getpgid(pid);
3131 if (pgid < 0)
3132 return posix_error();
3133 return PyInt_FromLong((long)pgid);
3135 #endif /* HAVE_GETPGID */
3138 #ifdef HAVE_GETPGRP
3139 PyDoc_STRVAR(posix_getpgrp__doc__,
3140 "getpgrp() -> pgrp\n\n\
3141 Return the current process group id.");
3143 static PyObject *
3144 posix_getpgrp(PyObject *self, PyObject *noargs)
3146 #ifdef GETPGRP_HAVE_ARG
3147 return PyInt_FromLong((long)getpgrp(0));
3148 #else /* GETPGRP_HAVE_ARG */
3149 return PyInt_FromLong((long)getpgrp());
3150 #endif /* GETPGRP_HAVE_ARG */
3152 #endif /* HAVE_GETPGRP */
3155 #ifdef HAVE_SETPGRP
3156 PyDoc_STRVAR(posix_setpgrp__doc__,
3157 "setpgrp()\n\n\
3158 Make this process a session leader.");
3160 static PyObject *
3161 posix_setpgrp(PyObject *self, PyObject *noargs)
3163 #ifdef SETPGRP_HAVE_ARG
3164 if (setpgrp(0, 0) < 0)
3165 #else /* SETPGRP_HAVE_ARG */
3166 if (setpgrp() < 0)
3167 #endif /* SETPGRP_HAVE_ARG */
3168 return posix_error();
3169 Py_INCREF(Py_None);
3170 return Py_None;
3173 #endif /* HAVE_SETPGRP */
3175 #ifdef HAVE_GETPPID
3176 PyDoc_STRVAR(posix_getppid__doc__,
3177 "getppid() -> ppid\n\n\
3178 Return the parent's process id.");
3180 static PyObject *
3181 posix_getppid(PyObject *self, PyObject *noargs)
3183 return PyInt_FromLong((long)getppid());
3185 #endif
3188 #ifdef HAVE_GETLOGIN
3189 PyDoc_STRVAR(posix_getlogin__doc__,
3190 "getlogin() -> string\n\n\
3191 Return the actual login name.");
3193 static PyObject *
3194 posix_getlogin(PyObject *self, PyObject *noargs)
3196 PyObject *result = NULL;
3197 char *name;
3198 int old_errno = errno;
3200 errno = 0;
3201 name = getlogin();
3202 if (name == NULL) {
3203 if (errno)
3204 posix_error();
3205 else
3206 PyErr_SetString(PyExc_OSError,
3207 "unable to determine login name");
3209 else
3210 result = PyString_FromString(name);
3211 errno = old_errno;
3213 return result;
3215 #endif
3217 #ifdef HAVE_GETUID
3218 PyDoc_STRVAR(posix_getuid__doc__,
3219 "getuid() -> uid\n\n\
3220 Return the current process's user id.");
3222 static PyObject *
3223 posix_getuid(PyObject *self, PyObject *noargs)
3225 return PyInt_FromLong((long)getuid());
3227 #endif
3230 #ifdef HAVE_KILL
3231 PyDoc_STRVAR(posix_kill__doc__,
3232 "kill(pid, sig)\n\n\
3233 Kill a process with a signal.");
3235 static PyObject *
3236 posix_kill(PyObject *self, PyObject *args)
3238 int pid, sig;
3239 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
3240 return NULL;
3241 #if defined(PYOS_OS2) && !defined(PYCC_GCC)
3242 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
3243 APIRET rc;
3244 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
3245 return os2_error(rc);
3247 } else if (sig == XCPT_SIGNAL_KILLPROC) {
3248 APIRET rc;
3249 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
3250 return os2_error(rc);
3252 } else
3253 return NULL; /* Unrecognized Signal Requested */
3254 #else
3255 if (kill(pid, sig) == -1)
3256 return posix_error();
3257 #endif
3258 Py_INCREF(Py_None);
3259 return Py_None;
3261 #endif
3263 #ifdef HAVE_KILLPG
3264 PyDoc_STRVAR(posix_killpg__doc__,
3265 "killpg(pgid, sig)\n\n\
3266 Kill a process group with a signal.");
3268 static PyObject *
3269 posix_killpg(PyObject *self, PyObject *args)
3271 int pgid, sig;
3272 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
3273 return NULL;
3274 if (killpg(pgid, sig) == -1)
3275 return posix_error();
3276 Py_INCREF(Py_None);
3277 return Py_None;
3279 #endif
3281 #ifdef HAVE_PLOCK
3283 #ifdef HAVE_SYS_LOCK_H
3284 #include <sys/lock.h>
3285 #endif
3287 PyDoc_STRVAR(posix_plock__doc__,
3288 "plock(op)\n\n\
3289 Lock program segments into memory.");
3291 static PyObject *
3292 posix_plock(PyObject *self, PyObject *args)
3294 int op;
3295 if (!PyArg_ParseTuple(args, "i:plock", &op))
3296 return NULL;
3297 if (plock(op) == -1)
3298 return posix_error();
3299 Py_INCREF(Py_None);
3300 return Py_None;
3302 #endif
3305 #ifdef HAVE_POPEN
3306 PyDoc_STRVAR(posix_popen__doc__,
3307 "popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
3308 Open a pipe to/from a command returning a file object.");
3310 #if defined(PYOS_OS2)
3311 #if defined(PYCC_VACPP)
3312 static int
3313 async_system(const char *command)
3315 char errormsg[256], args[1024];
3316 RESULTCODES rcodes;
3317 APIRET rc;
3319 char *shell = getenv("COMSPEC");
3320 if (!shell)
3321 shell = "cmd";
3323 /* avoid overflowing the argument buffer */
3324 if (strlen(shell) + 3 + strlen(command) >= 1024)
3325 return ERROR_NOT_ENOUGH_MEMORY
3327 args[0] = '\0';
3328 strcat(args, shell);
3329 strcat(args, "/c ");
3330 strcat(args, command);
3332 /* execute asynchronously, inheriting the environment */
3333 rc = DosExecPgm(errormsg,
3334 sizeof(errormsg),
3335 EXEC_ASYNC,
3336 args,
3337 NULL,
3338 &rcodes,
3339 shell);
3340 return rc;
3343 static FILE *
3344 popen(const char *command, const char *mode, int pipesize, int *err)
3346 int oldfd, tgtfd;
3347 HFILE pipeh[2];
3348 APIRET rc;
3350 /* mode determines which of stdin or stdout is reconnected to
3351 * the pipe to the child
3353 if (strchr(mode, 'r') != NULL) {
3354 tgt_fd = 1; /* stdout */
3355 } else if (strchr(mode, 'w')) {
3356 tgt_fd = 0; /* stdin */
3357 } else {
3358 *err = ERROR_INVALID_ACCESS;
3359 return NULL;
3362 /* setup the pipe */
3363 if ((rc = DosCreatePipe(&pipeh[0], &pipeh[1], pipesize)) != NO_ERROR) {
3364 *err = rc;
3365 return NULL;
3368 /* prevent other threads accessing stdio */
3369 DosEnterCritSec();
3371 /* reconnect stdio and execute child */
3372 oldfd = dup(tgtfd);
3373 close(tgtfd);
3374 if (dup2(pipeh[tgtfd], tgtfd) == 0) {
3375 DosClose(pipeh[tgtfd]);
3376 rc = async_system(command);
3379 /* restore stdio */
3380 dup2(oldfd, tgtfd);
3381 close(oldfd);
3383 /* allow other threads access to stdio */
3384 DosExitCritSec();
3386 /* if execution of child was successful return file stream */
3387 if (rc == NO_ERROR)
3388 return fdopen(pipeh[1 - tgtfd], mode);
3389 else {
3390 DosClose(pipeh[1 - tgtfd]);
3391 *err = rc;
3392 return NULL;
3396 static PyObject *
3397 posix_popen(PyObject *self, PyObject *args)
3399 char *name;
3400 char *mode = "r";
3401 int err, bufsize = -1;
3402 FILE *fp;
3403 PyObject *f;
3404 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
3405 return NULL;
3406 Py_BEGIN_ALLOW_THREADS
3407 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
3408 Py_END_ALLOW_THREADS
3409 if (fp == NULL)
3410 return os2_error(err);
3412 f = PyFile_FromFile(fp, name, mode, fclose);
3413 if (f != NULL)
3414 PyFile_SetBufSize(f, bufsize);
3415 return f;
3418 #elif defined(PYCC_GCC)
3420 /* standard posix version of popen() support */
3421 static PyObject *
3422 posix_popen(PyObject *self, PyObject *args)
3424 char *name;
3425 char *mode = "r";
3426 int bufsize = -1;
3427 FILE *fp;
3428 PyObject *f;
3429 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
3430 return NULL;
3431 Py_BEGIN_ALLOW_THREADS
3432 fp = popen(name, mode);
3433 Py_END_ALLOW_THREADS
3434 if (fp == NULL)
3435 return posix_error();
3436 f = PyFile_FromFile(fp, name, mode, pclose);
3437 if (f != NULL)
3438 PyFile_SetBufSize(f, bufsize);
3439 return f;
3442 /* fork() under OS/2 has lots'o'warts
3443 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
3444 * most of this code is a ripoff of the win32 code, but using the
3445 * capabilities of EMX's C library routines
3448 /* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
3449 #define POPEN_1 1
3450 #define POPEN_2 2
3451 #define POPEN_3 3
3452 #define POPEN_4 4
3454 static PyObject *_PyPopen(char *, int, int, int);
3455 static int _PyPclose(FILE *file);
3458 * Internal dictionary mapping popen* file pointers to process handles,
3459 * for use when retrieving the process exit code. See _PyPclose() below
3460 * for more information on this dictionary's use.
3462 static PyObject *_PyPopenProcs = NULL;
3464 /* os2emx version of popen2()
3466 * The result of this function is a pipe (file) connected to the
3467 * process's stdin, and a pipe connected to the process's stdout.
3470 static PyObject *
3471 os2emx_popen2(PyObject *self, PyObject *args)
3473 PyObject *f;
3474 int tm=0;
3476 char *cmdstring;
3477 char *mode = "t";
3478 int bufsize = -1;
3479 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
3480 return NULL;
3482 if (*mode == 't')
3483 tm = O_TEXT;
3484 else if (*mode != 'b') {
3485 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3486 return NULL;
3487 } else
3488 tm = O_BINARY;
3490 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
3492 return f;
3496 * Variation on os2emx.popen2
3498 * The result of this function is 3 pipes - the process's stdin,
3499 * stdout and stderr
3502 static PyObject *
3503 os2emx_popen3(PyObject *self, PyObject *args)
3505 PyObject *f;
3506 int tm = 0;
3508 char *cmdstring;
3509 char *mode = "t";
3510 int bufsize = -1;
3511 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
3512 return NULL;
3514 if (*mode == 't')
3515 tm = O_TEXT;
3516 else if (*mode != 'b') {
3517 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3518 return NULL;
3519 } else
3520 tm = O_BINARY;
3522 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
3524 return f;
3528 * Variation on os2emx.popen2
3530 * The result of this function is 2 pipes - the processes stdin,
3531 * and stdout+stderr combined as a single pipe.
3534 static PyObject *
3535 os2emx_popen4(PyObject *self, PyObject *args)
3537 PyObject *f;
3538 int tm = 0;
3540 char *cmdstring;
3541 char *mode = "t";
3542 int bufsize = -1;
3543 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
3544 return NULL;
3546 if (*mode == 't')
3547 tm = O_TEXT;
3548 else if (*mode != 'b') {
3549 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3550 return NULL;
3551 } else
3552 tm = O_BINARY;
3554 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
3556 return f;
3559 /* a couple of structures for convenient handling of multiple
3560 * file handles and pipes
3562 struct file_ref
3564 int handle;
3565 int flags;
3568 struct pipe_ref
3570 int rd;
3571 int wr;
3574 /* The following code is derived from the win32 code */
3576 static PyObject *
3577 _PyPopen(char *cmdstring, int mode, int n, int bufsize)
3579 struct file_ref stdio[3];
3580 struct pipe_ref p_fd[3];
3581 FILE *p_s[3];
3582 int file_count, i, pipe_err, pipe_pid;
3583 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
3584 PyObject *f, *p_f[3];
3586 /* file modes for subsequent fdopen's on pipe handles */
3587 if (mode == O_TEXT)
3589 rd_mode = "rt";
3590 wr_mode = "wt";
3592 else
3594 rd_mode = "rb";
3595 wr_mode = "wb";
3598 /* prepare shell references */
3599 if ((shell = getenv("EMXSHELL")) == NULL)
3600 if ((shell = getenv("COMSPEC")) == NULL)
3602 errno = ENOENT;
3603 return posix_error();
3606 sh_name = _getname(shell);
3607 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
3608 opt = "/c";
3609 else
3610 opt = "-c";
3612 /* save current stdio fds + their flags, and set not inheritable */
3613 i = pipe_err = 0;
3614 while (pipe_err >= 0 && i < 3)
3616 pipe_err = stdio[i].handle = dup(i);
3617 stdio[i].flags = fcntl(i, F_GETFD, 0);
3618 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
3619 i++;
3621 if (pipe_err < 0)
3623 /* didn't get them all saved - clean up and bail out */
3624 int saved_err = errno;
3625 while (i-- > 0)
3627 close(stdio[i].handle);
3629 errno = saved_err;
3630 return posix_error();
3633 /* create pipe ends */
3634 file_count = 2;
3635 if (n == POPEN_3)
3636 file_count = 3;
3637 i = pipe_err = 0;
3638 while ((pipe_err == 0) && (i < file_count))
3639 pipe_err = pipe((int *)&p_fd[i++]);
3640 if (pipe_err < 0)
3642 /* didn't get them all made - clean up and bail out */
3643 while (i-- > 0)
3645 close(p_fd[i].wr);
3646 close(p_fd[i].rd);
3648 errno = EPIPE;
3649 return posix_error();
3652 /* change the actual standard IO streams over temporarily,
3653 * making the retained pipe ends non-inheritable
3655 pipe_err = 0;
3657 /* - stdin */
3658 if (dup2(p_fd[0].rd, 0) == 0)
3660 close(p_fd[0].rd);
3661 i = fcntl(p_fd[0].wr, F_GETFD, 0);
3662 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
3663 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
3665 close(p_fd[0].wr);
3666 pipe_err = -1;
3669 else
3671 pipe_err = -1;
3674 /* - stdout */
3675 if (pipe_err == 0)
3677 if (dup2(p_fd[1].wr, 1) == 1)
3679 close(p_fd[1].wr);
3680 i = fcntl(p_fd[1].rd, F_GETFD, 0);
3681 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
3682 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
3684 close(p_fd[1].rd);
3685 pipe_err = -1;
3688 else
3690 pipe_err = -1;
3694 /* - stderr, as required */
3695 if (pipe_err == 0)
3696 switch (n)
3698 case POPEN_3:
3700 if (dup2(p_fd[2].wr, 2) == 2)
3702 close(p_fd[2].wr);
3703 i = fcntl(p_fd[2].rd, F_GETFD, 0);
3704 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
3705 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
3707 close(p_fd[2].rd);
3708 pipe_err = -1;
3711 else
3713 pipe_err = -1;
3715 break;
3718 case POPEN_4:
3720 if (dup2(1, 2) != 2)
3722 pipe_err = -1;
3724 break;
3728 /* spawn the child process */
3729 if (pipe_err == 0)
3731 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
3732 if (pipe_pid == -1)
3734 pipe_err = -1;
3736 else
3738 /* save the PID into the FILE structure
3739 * NOTE: this implementation doesn't actually
3740 * take advantage of this, but do it for
3741 * completeness - AIM Apr01
3743 for (i = 0; i < file_count; i++)
3744 p_s[i]->_pid = pipe_pid;
3748 /* reset standard IO to normal */
3749 for (i = 0; i < 3; i++)
3751 dup2(stdio[i].handle, i);
3752 fcntl(i, F_SETFD, stdio[i].flags);
3753 close(stdio[i].handle);
3756 /* if any remnant problems, clean up and bail out */
3757 if (pipe_err < 0)
3759 for (i = 0; i < 3; i++)
3761 close(p_fd[i].rd);
3762 close(p_fd[i].wr);
3764 errno = EPIPE;
3765 return posix_error_with_filename(cmdstring);
3768 /* build tuple of file objects to return */
3769 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
3770 PyFile_SetBufSize(p_f[0], bufsize);
3771 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
3772 PyFile_SetBufSize(p_f[1], bufsize);
3773 if (n == POPEN_3)
3775 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
3776 PyFile_SetBufSize(p_f[0], bufsize);
3777 f = PyTuple_Pack(3, p_f[0], p_f[1], p_f[2]);
3779 else
3780 f = PyTuple_Pack(2, p_f[0], p_f[1]);
3783 * Insert the files we've created into the process dictionary
3784 * all referencing the list with the process handle and the
3785 * initial number of files (see description below in _PyPclose).
3786 * Since if _PyPclose later tried to wait on a process when all
3787 * handles weren't closed, it could create a deadlock with the
3788 * child, we spend some energy here to try to ensure that we
3789 * either insert all file handles into the dictionary or none
3790 * at all. It's a little clumsy with the various popen modes
3791 * and variable number of files involved.
3793 if (!_PyPopenProcs)
3795 _PyPopenProcs = PyDict_New();
3798 if (_PyPopenProcs)
3800 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
3801 int ins_rc[3];
3803 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
3804 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
3806 procObj = PyList_New(2);
3807 pidObj = PyInt_FromLong((long) pipe_pid);
3808 intObj = PyInt_FromLong((long) file_count);
3810 if (procObj && pidObj && intObj)
3812 PyList_SetItem(procObj, 0, pidObj);
3813 PyList_SetItem(procObj, 1, intObj);
3815 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
3816 if (fileObj[0])
3818 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
3819 fileObj[0],
3820 procObj);
3822 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
3823 if (fileObj[1])
3825 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
3826 fileObj[1],
3827 procObj);
3829 if (file_count >= 3)
3831 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
3832 if (fileObj[2])
3834 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
3835 fileObj[2],
3836 procObj);
3840 if (ins_rc[0] < 0 || !fileObj[0] ||
3841 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
3842 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
3844 /* Something failed - remove any dictionary
3845 * entries that did make it.
3847 if (!ins_rc[0] && fileObj[0])
3849 PyDict_DelItem(_PyPopenProcs,
3850 fileObj[0]);
3852 if (!ins_rc[1] && fileObj[1])
3854 PyDict_DelItem(_PyPopenProcs,
3855 fileObj[1]);
3857 if (!ins_rc[2] && fileObj[2])
3859 PyDict_DelItem(_PyPopenProcs,
3860 fileObj[2]);
3866 * Clean up our localized references for the dictionary keys
3867 * and value since PyDict_SetItem will Py_INCREF any copies
3868 * that got placed in the dictionary.
3870 Py_XDECREF(procObj);
3871 Py_XDECREF(fileObj[0]);
3872 Py_XDECREF(fileObj[1]);
3873 Py_XDECREF(fileObj[2]);
3876 /* Child is launched. */
3877 return f;
3881 * Wrapper for fclose() to use for popen* files, so we can retrieve the
3882 * exit code for the child process and return as a result of the close.
3884 * This function uses the _PyPopenProcs dictionary in order to map the
3885 * input file pointer to information about the process that was
3886 * originally created by the popen* call that created the file pointer.
3887 * The dictionary uses the file pointer as a key (with one entry
3888 * inserted for each file returned by the original popen* call) and a
3889 * single list object as the value for all files from a single call.
3890 * The list object contains the Win32 process handle at [0], and a file
3891 * count at [1], which is initialized to the total number of file
3892 * handles using that list.
3894 * This function closes whichever handle it is passed, and decrements
3895 * the file count in the dictionary for the process handle pointed to
3896 * by this file. On the last close (when the file count reaches zero),
3897 * this function will wait for the child process and then return its
3898 * exit code as the result of the close() operation. This permits the
3899 * files to be closed in any order - it is always the close() of the
3900 * final handle that will return the exit code.
3902 * NOTE: This function is currently called with the GIL released.
3903 * hence we use the GILState API to manage our state.
3906 static int _PyPclose(FILE *file)
3908 int result;
3909 int exit_code;
3910 int pipe_pid;
3911 PyObject *procObj, *pidObj, *intObj, *fileObj;
3912 int file_count;
3913 #ifdef WITH_THREAD
3914 PyGILState_STATE state;
3915 #endif
3917 /* Close the file handle first, to ensure it can't block the
3918 * child from exiting if it's the last handle.
3920 result = fclose(file);
3922 #ifdef WITH_THREAD
3923 state = PyGILState_Ensure();
3924 #endif
3925 if (_PyPopenProcs)
3927 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
3928 (procObj = PyDict_GetItem(_PyPopenProcs,
3929 fileObj)) != NULL &&
3930 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
3931 (intObj = PyList_GetItem(procObj,1)) != NULL)
3933 pipe_pid = (int) PyInt_AsLong(pidObj);
3934 file_count = (int) PyInt_AsLong(intObj);
3936 if (file_count > 1)
3938 /* Still other files referencing process */
3939 file_count--;
3940 PyList_SetItem(procObj,1,
3941 PyInt_FromLong((long) file_count));
3943 else
3945 /* Last file for this process */
3946 if (result != EOF &&
3947 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
3949 /* extract exit status */
3950 if (WIFEXITED(exit_code))
3952 result = WEXITSTATUS(exit_code);
3954 else
3956 errno = EPIPE;
3957 result = -1;
3960 else
3962 /* Indicate failure - this will cause the file object
3963 * to raise an I/O error and translate the last
3964 * error code from errno. We do have a problem with
3965 * last errors that overlap the normal errno table,
3966 * but that's a consistent problem with the file object.
3968 result = -1;
3972 /* Remove this file pointer from dictionary */
3973 PyDict_DelItem(_PyPopenProcs, fileObj);
3975 if (PyDict_Size(_PyPopenProcs) == 0)
3977 Py_DECREF(_PyPopenProcs);
3978 _PyPopenProcs = NULL;
3981 } /* if object retrieval ok */
3983 Py_XDECREF(fileObj);
3984 } /* if _PyPopenProcs */
3986 #ifdef WITH_THREAD
3987 PyGILState_Release(state);
3988 #endif
3989 return result;
3992 #endif /* PYCC_??? */
3994 #elif defined(MS_WINDOWS)
3997 * Portable 'popen' replacement for Win32.
3999 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
4000 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
4001 * Return code handling by David Bolen <db3l@fitlinxx.com>.
4004 #include <malloc.h>
4005 #include <io.h>
4006 #include <fcntl.h>
4008 /* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
4009 #define POPEN_1 1
4010 #define POPEN_2 2
4011 #define POPEN_3 3
4012 #define POPEN_4 4
4014 static PyObject *_PyPopen(char *, int, int);
4015 static int _PyPclose(FILE *file);
4018 * Internal dictionary mapping popen* file pointers to process handles,
4019 * for use when retrieving the process exit code. See _PyPclose() below
4020 * for more information on this dictionary's use.
4022 static PyObject *_PyPopenProcs = NULL;
4025 /* popen that works from a GUI.
4027 * The result of this function is a pipe (file) connected to the
4028 * processes stdin or stdout, depending on the requested mode.
4031 static PyObject *
4032 posix_popen(PyObject *self, PyObject *args)
4034 PyObject *f;
4035 int tm = 0;
4037 char *cmdstring;
4038 char *mode = "r";
4039 int bufsize = -1;
4040 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
4041 return NULL;
4043 if (*mode == 'r')
4044 tm = _O_RDONLY;
4045 else if (*mode != 'w') {
4046 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
4047 return NULL;
4048 } else
4049 tm = _O_WRONLY;
4051 if (bufsize != -1) {
4052 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
4053 return NULL;
4056 if (*(mode+1) == 't')
4057 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
4058 else if (*(mode+1) == 'b')
4059 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
4060 else
4061 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
4063 return f;
4066 /* Variation on win32pipe.popen
4068 * The result of this function is a pipe (file) connected to the
4069 * process's stdin, and a pipe connected to the process's stdout.
4072 static PyObject *
4073 win32_popen2(PyObject *self, PyObject *args)
4075 PyObject *f;
4076 int tm=0;
4078 char *cmdstring;
4079 char *mode = "t";
4080 int bufsize = -1;
4081 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
4082 return NULL;
4084 if (*mode == 't')
4085 tm = _O_TEXT;
4086 else if (*mode != 'b') {
4087 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
4088 return NULL;
4089 } else
4090 tm = _O_BINARY;
4092 if (bufsize != -1) {
4093 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
4094 return NULL;
4097 f = _PyPopen(cmdstring, tm, POPEN_2);
4099 return f;
4103 * Variation on <om win32pipe.popen>
4105 * The result of this function is 3 pipes - the process's stdin,
4106 * stdout and stderr
4109 static PyObject *
4110 win32_popen3(PyObject *self, PyObject *args)
4112 PyObject *f;
4113 int tm = 0;
4115 char *cmdstring;
4116 char *mode = "t";
4117 int bufsize = -1;
4118 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
4119 return NULL;
4121 if (*mode == 't')
4122 tm = _O_TEXT;
4123 else if (*mode != 'b') {
4124 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
4125 return NULL;
4126 } else
4127 tm = _O_BINARY;
4129 if (bufsize != -1) {
4130 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
4131 return NULL;
4134 f = _PyPopen(cmdstring, tm, POPEN_3);
4136 return f;
4140 * Variation on win32pipe.popen
4142 * The result of this function is 2 pipes - the processes stdin,
4143 * and stdout+stderr combined as a single pipe.
4146 static PyObject *
4147 win32_popen4(PyObject *self, PyObject *args)
4149 PyObject *f;
4150 int tm = 0;
4152 char *cmdstring;
4153 char *mode = "t";
4154 int bufsize = -1;
4155 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
4156 return NULL;
4158 if (*mode == 't')
4159 tm = _O_TEXT;
4160 else if (*mode != 'b') {
4161 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
4162 return NULL;
4163 } else
4164 tm = _O_BINARY;
4166 if (bufsize != -1) {
4167 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
4168 return NULL;
4171 f = _PyPopen(cmdstring, tm, POPEN_4);
4173 return f;
4176 static BOOL
4177 _PyPopenCreateProcess(char *cmdstring,
4178 HANDLE hStdin,
4179 HANDLE hStdout,
4180 HANDLE hStderr,
4181 HANDLE *hProcess)
4183 PROCESS_INFORMATION piProcInfo;
4184 STARTUPINFO siStartInfo;
4185 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
4186 char *s1,*s2, *s3 = " /c ";
4187 const char *szConsoleSpawn = "w9xpopen.exe";
4188 int i;
4189 int x;
4191 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
4192 char *comshell;
4194 s1 = (char *)alloca(i);
4195 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
4196 return x;
4198 /* Explicitly check if we are using COMMAND.COM. If we are
4199 * then use the w9xpopen hack.
4201 comshell = s1 + x;
4202 while (comshell >= s1 && *comshell != '\\')
4203 --comshell;
4204 ++comshell;
4206 if (GetVersion() < 0x80000000 &&
4207 _stricmp(comshell, "command.com") != 0) {
4208 /* NT/2000 and not using command.com. */
4209 x = i + strlen(s3) + strlen(cmdstring) + 1;
4210 s2 = (char *)alloca(x);
4211 ZeroMemory(s2, x);
4212 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
4214 else {
4216 * Oh gag, we're on Win9x or using COMMAND.COM. Use
4217 * the workaround listed in KB: Q150956
4219 char modulepath[_MAX_PATH];
4220 struct stat statinfo;
4221 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
4222 for (i = x = 0; modulepath[i]; i++)
4223 if (modulepath[i] == SEP)
4224 x = i+1;
4225 modulepath[x] = '\0';
4226 /* Create the full-name to w9xpopen, so we can test it exists */
4227 strncat(modulepath,
4228 szConsoleSpawn,
4229 (sizeof(modulepath)/sizeof(modulepath[0]))
4230 -strlen(modulepath));
4231 if (stat(modulepath, &statinfo) != 0) {
4232 /* Eeek - file-not-found - possibly an embedding
4233 situation - see if we can locate it in sys.prefix
4235 strncpy(modulepath,
4236 Py_GetExecPrefix(),
4237 sizeof(modulepath)/sizeof(modulepath[0]));
4238 if (modulepath[strlen(modulepath)-1] != '\\')
4239 strcat(modulepath, "\\");
4240 strncat(modulepath,
4241 szConsoleSpawn,
4242 (sizeof(modulepath)/sizeof(modulepath[0]))
4243 -strlen(modulepath));
4244 /* No where else to look - raise an easily identifiable
4245 error, rather than leaving Windows to report
4246 "file not found" - as the user is probably blissfully
4247 unaware this shim EXE is used, and it will confuse them.
4248 (well, it confused me for a while ;-)
4250 if (stat(modulepath, &statinfo) != 0) {
4251 PyErr_Format(PyExc_RuntimeError,
4252 "Can not locate '%s' which is needed "
4253 "for popen to work with your shell "
4254 "or platform.",
4255 szConsoleSpawn);
4256 return FALSE;
4259 x = i + strlen(s3) + strlen(cmdstring) + 1 +
4260 strlen(modulepath) +
4261 strlen(szConsoleSpawn) + 1;
4263 s2 = (char *)alloca(x);
4264 ZeroMemory(s2, x);
4265 /* To maintain correct argument passing semantics,
4266 we pass the command-line as it stands, and allow
4267 quoting to be applied. w9xpopen.exe will then
4268 use its argv vector, and re-quote the necessary
4269 args for the ultimate child process.
4271 PyOS_snprintf(
4272 s2, x,
4273 "\"%s\" %s%s%s",
4274 modulepath,
4277 cmdstring);
4278 /* Not passing CREATE_NEW_CONSOLE has been known to
4279 cause random failures on win9x. Specifically a
4280 dialog:
4281 "Your program accessed mem currently in use at xxx"
4282 and a hopeful warning about the stability of your
4283 system.
4284 Cost is Ctrl+C wont kill children, but anyone
4285 who cares can have a go!
4287 dwProcessFlags |= CREATE_NEW_CONSOLE;
4291 /* Could be an else here to try cmd.exe / command.com in the path
4292 Now we'll just error out.. */
4293 else {
4294 PyErr_SetString(PyExc_RuntimeError,
4295 "Cannot locate a COMSPEC environment variable to "
4296 "use as the shell");
4297 return FALSE;
4300 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
4301 siStartInfo.cb = sizeof(STARTUPINFO);
4302 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
4303 siStartInfo.hStdInput = hStdin;
4304 siStartInfo.hStdOutput = hStdout;
4305 siStartInfo.hStdError = hStderr;
4306 siStartInfo.wShowWindow = SW_HIDE;
4308 if (CreateProcess(NULL,
4310 NULL,
4311 NULL,
4312 TRUE,
4313 dwProcessFlags,
4314 NULL,
4315 NULL,
4316 &siStartInfo,
4317 &piProcInfo) ) {
4318 /* Close the handles now so anyone waiting is woken. */
4319 CloseHandle(piProcInfo.hThread);
4321 /* Return process handle */
4322 *hProcess = piProcInfo.hProcess;
4323 return TRUE;
4325 win32_error("CreateProcess", s2);
4326 return FALSE;
4329 /* The following code is based off of KB: Q190351 */
4331 static PyObject *
4332 _PyPopen(char *cmdstring, int mode, int n)
4334 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
4335 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
4336 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
4338 SECURITY_ATTRIBUTES saAttr;
4339 BOOL fSuccess;
4340 int fd1, fd2, fd3;
4341 FILE *f1, *f2, *f3;
4342 long file_count;
4343 PyObject *f;
4345 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
4346 saAttr.bInheritHandle = TRUE;
4347 saAttr.lpSecurityDescriptor = NULL;
4349 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
4350 return win32_error("CreatePipe", NULL);
4352 /* Create new output read handle and the input write handle. Set
4353 * the inheritance properties to FALSE. Otherwise, the child inherits
4354 * these handles; resulting in non-closeable handles to the pipes
4355 * being created. */
4356 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
4357 GetCurrentProcess(), &hChildStdinWrDup, 0,
4358 FALSE,
4359 DUPLICATE_SAME_ACCESS);
4360 if (!fSuccess)
4361 return win32_error("DuplicateHandle", NULL);
4363 /* Close the inheritable version of ChildStdin
4364 that we're using. */
4365 CloseHandle(hChildStdinWr);
4367 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
4368 return win32_error("CreatePipe", NULL);
4370 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
4371 GetCurrentProcess(), &hChildStdoutRdDup, 0,
4372 FALSE, DUPLICATE_SAME_ACCESS);
4373 if (!fSuccess)
4374 return win32_error("DuplicateHandle", NULL);
4376 /* Close the inheritable version of ChildStdout
4377 that we're using. */
4378 CloseHandle(hChildStdoutRd);
4380 if (n != POPEN_4) {
4381 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
4382 return win32_error("CreatePipe", NULL);
4383 fSuccess = DuplicateHandle(GetCurrentProcess(),
4384 hChildStderrRd,
4385 GetCurrentProcess(),
4386 &hChildStderrRdDup, 0,
4387 FALSE, DUPLICATE_SAME_ACCESS);
4388 if (!fSuccess)
4389 return win32_error("DuplicateHandle", NULL);
4390 /* Close the inheritable version of ChildStdErr that we're using. */
4391 CloseHandle(hChildStderrRd);
4394 switch (n) {
4395 case POPEN_1:
4396 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
4397 case _O_WRONLY | _O_TEXT:
4398 /* Case for writing to child Stdin in text mode. */
4399 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4400 f1 = _fdopen(fd1, "w");
4401 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
4402 PyFile_SetBufSize(f, 0);
4403 /* We don't care about these pipes anymore, so close them. */
4404 CloseHandle(hChildStdoutRdDup);
4405 CloseHandle(hChildStderrRdDup);
4406 break;
4408 case _O_RDONLY | _O_TEXT:
4409 /* Case for reading from child Stdout in text mode. */
4410 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4411 f1 = _fdopen(fd1, "r");
4412 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
4413 PyFile_SetBufSize(f, 0);
4414 /* We don't care about these pipes anymore, so close them. */
4415 CloseHandle(hChildStdinWrDup);
4416 CloseHandle(hChildStderrRdDup);
4417 break;
4419 case _O_RDONLY | _O_BINARY:
4420 /* Case for readinig from child Stdout in binary mode. */
4421 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4422 f1 = _fdopen(fd1, "rb");
4423 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
4424 PyFile_SetBufSize(f, 0);
4425 /* We don't care about these pipes anymore, so close them. */
4426 CloseHandle(hChildStdinWrDup);
4427 CloseHandle(hChildStderrRdDup);
4428 break;
4430 case _O_WRONLY | _O_BINARY:
4431 /* Case for writing to child Stdin in binary mode. */
4432 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4433 f1 = _fdopen(fd1, "wb");
4434 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
4435 PyFile_SetBufSize(f, 0);
4436 /* We don't care about these pipes anymore, so close them. */
4437 CloseHandle(hChildStdoutRdDup);
4438 CloseHandle(hChildStderrRdDup);
4439 break;
4441 file_count = 1;
4442 break;
4444 case POPEN_2:
4445 case POPEN_4:
4447 char *m1, *m2;
4448 PyObject *p1, *p2;
4450 if (mode & _O_TEXT) {
4451 m1 = "r";
4452 m2 = "w";
4453 } else {
4454 m1 = "rb";
4455 m2 = "wb";
4458 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4459 f1 = _fdopen(fd1, m2);
4460 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4461 f2 = _fdopen(fd2, m1);
4462 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
4463 PyFile_SetBufSize(p1, 0);
4464 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
4465 PyFile_SetBufSize(p2, 0);
4467 if (n != 4)
4468 CloseHandle(hChildStderrRdDup);
4470 f = PyTuple_Pack(2,p1,p2);
4471 Py_XDECREF(p1);
4472 Py_XDECREF(p2);
4473 file_count = 2;
4474 break;
4477 case POPEN_3:
4479 char *m1, *m2;
4480 PyObject *p1, *p2, *p3;
4482 if (mode & _O_TEXT) {
4483 m1 = "r";
4484 m2 = "w";
4485 } else {
4486 m1 = "rb";
4487 m2 = "wb";
4490 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4491 f1 = _fdopen(fd1, m2);
4492 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4493 f2 = _fdopen(fd2, m1);
4494 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
4495 f3 = _fdopen(fd3, m1);
4496 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
4497 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
4498 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
4499 PyFile_SetBufSize(p1, 0);
4500 PyFile_SetBufSize(p2, 0);
4501 PyFile_SetBufSize(p3, 0);
4502 f = PyTuple_Pack(3,p1,p2,p3);
4503 Py_XDECREF(p1);
4504 Py_XDECREF(p2);
4505 Py_XDECREF(p3);
4506 file_count = 3;
4507 break;
4511 if (n == POPEN_4) {
4512 if (!_PyPopenCreateProcess(cmdstring,
4513 hChildStdinRd,
4514 hChildStdoutWr,
4515 hChildStdoutWr,
4516 &hProcess))
4517 return NULL;
4519 else {
4520 if (!_PyPopenCreateProcess(cmdstring,
4521 hChildStdinRd,
4522 hChildStdoutWr,
4523 hChildStderrWr,
4524 &hProcess))
4525 return NULL;
4529 * Insert the files we've created into the process dictionary
4530 * all referencing the list with the process handle and the
4531 * initial number of files (see description below in _PyPclose).
4532 * Since if _PyPclose later tried to wait on a process when all
4533 * handles weren't closed, it could create a deadlock with the
4534 * child, we spend some energy here to try to ensure that we
4535 * either insert all file handles into the dictionary or none
4536 * at all. It's a little clumsy with the various popen modes
4537 * and variable number of files involved.
4539 if (!_PyPopenProcs) {
4540 _PyPopenProcs = PyDict_New();
4543 if (_PyPopenProcs) {
4544 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
4545 int ins_rc[3];
4547 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4548 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4550 procObj = PyList_New(2);
4551 hProcessObj = PyLong_FromVoidPtr(hProcess);
4552 intObj = PyInt_FromLong(file_count);
4554 if (procObj && hProcessObj && intObj) {
4555 PyList_SetItem(procObj,0,hProcessObj);
4556 PyList_SetItem(procObj,1,intObj);
4558 fileObj[0] = PyLong_FromVoidPtr(f1);
4559 if (fileObj[0]) {
4560 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4561 fileObj[0],
4562 procObj);
4564 if (file_count >= 2) {
4565 fileObj[1] = PyLong_FromVoidPtr(f2);
4566 if (fileObj[1]) {
4567 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4568 fileObj[1],
4569 procObj);
4572 if (file_count >= 3) {
4573 fileObj[2] = PyLong_FromVoidPtr(f3);
4574 if (fileObj[2]) {
4575 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4576 fileObj[2],
4577 procObj);
4581 if (ins_rc[0] < 0 || !fileObj[0] ||
4582 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4583 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
4584 /* Something failed - remove any dictionary
4585 * entries that did make it.
4587 if (!ins_rc[0] && fileObj[0]) {
4588 PyDict_DelItem(_PyPopenProcs,
4589 fileObj[0]);
4591 if (!ins_rc[1] && fileObj[1]) {
4592 PyDict_DelItem(_PyPopenProcs,
4593 fileObj[1]);
4595 if (!ins_rc[2] && fileObj[2]) {
4596 PyDict_DelItem(_PyPopenProcs,
4597 fileObj[2]);
4603 * Clean up our localized references for the dictionary keys
4604 * and value since PyDict_SetItem will Py_INCREF any copies
4605 * that got placed in the dictionary.
4607 Py_XDECREF(procObj);
4608 Py_XDECREF(fileObj[0]);
4609 Py_XDECREF(fileObj[1]);
4610 Py_XDECREF(fileObj[2]);
4613 /* Child is launched. Close the parents copy of those pipe
4614 * handles that only the child should have open. You need to
4615 * make sure that no handles to the write end of the output pipe
4616 * are maintained in this process or else the pipe will not close
4617 * when the child process exits and the ReadFile will hang. */
4619 if (!CloseHandle(hChildStdinRd))
4620 return win32_error("CloseHandle", NULL);
4622 if (!CloseHandle(hChildStdoutWr))
4623 return win32_error("CloseHandle", NULL);
4625 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
4626 return win32_error("CloseHandle", NULL);
4628 return f;
4632 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4633 * exit code for the child process and return as a result of the close.
4635 * This function uses the _PyPopenProcs dictionary in order to map the
4636 * input file pointer to information about the process that was
4637 * originally created by the popen* call that created the file pointer.
4638 * The dictionary uses the file pointer as a key (with one entry
4639 * inserted for each file returned by the original popen* call) and a
4640 * single list object as the value for all files from a single call.
4641 * The list object contains the Win32 process handle at [0], and a file
4642 * count at [1], which is initialized to the total number of file
4643 * handles using that list.
4645 * This function closes whichever handle it is passed, and decrements
4646 * the file count in the dictionary for the process handle pointed to
4647 * by this file. On the last close (when the file count reaches zero),
4648 * this function will wait for the child process and then return its
4649 * exit code as the result of the close() operation. This permits the
4650 * files to be closed in any order - it is always the close() of the
4651 * final handle that will return the exit code.
4653 * NOTE: This function is currently called with the GIL released.
4654 * hence we use the GILState API to manage our state.
4657 static int _PyPclose(FILE *file)
4659 int result;
4660 DWORD exit_code;
4661 HANDLE hProcess;
4662 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
4663 long file_count;
4664 #ifdef WITH_THREAD
4665 PyGILState_STATE state;
4666 #endif
4668 /* Close the file handle first, to ensure it can't block the
4669 * child from exiting if it's the last handle.
4671 result = fclose(file);
4672 #ifdef WITH_THREAD
4673 state = PyGILState_Ensure();
4674 #endif
4675 if (_PyPopenProcs) {
4676 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4677 (procObj = PyDict_GetItem(_PyPopenProcs,
4678 fileObj)) != NULL &&
4679 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
4680 (intObj = PyList_GetItem(procObj,1)) != NULL) {
4682 hProcess = PyLong_AsVoidPtr(hProcessObj);
4683 file_count = PyInt_AsLong(intObj);
4685 if (file_count > 1) {
4686 /* Still other files referencing process */
4687 file_count--;
4688 PyList_SetItem(procObj,1,
4689 PyInt_FromLong(file_count));
4690 } else {
4691 /* Last file for this process */
4692 if (result != EOF &&
4693 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
4694 GetExitCodeProcess(hProcess, &exit_code)) {
4695 /* Possible truncation here in 16-bit environments, but
4696 * real exit codes are just the lower byte in any event.
4698 result = exit_code;
4699 } else {
4700 /* Indicate failure - this will cause the file object
4701 * to raise an I/O error and translate the last Win32
4702 * error code from errno. We do have a problem with
4703 * last errors that overlap the normal errno table,
4704 * but that's a consistent problem with the file object.
4706 if (result != EOF) {
4707 /* If the error wasn't from the fclose(), then
4708 * set errno for the file object error handling.
4710 errno = GetLastError();
4712 result = -1;
4715 /* Free up the native handle at this point */
4716 CloseHandle(hProcess);
4719 /* Remove this file pointer from dictionary */
4720 PyDict_DelItem(_PyPopenProcs, fileObj);
4722 if (PyDict_Size(_PyPopenProcs) == 0) {
4723 Py_DECREF(_PyPopenProcs);
4724 _PyPopenProcs = NULL;
4727 } /* if object retrieval ok */
4729 Py_XDECREF(fileObj);
4730 } /* if _PyPopenProcs */
4732 #ifdef WITH_THREAD
4733 PyGILState_Release(state);
4734 #endif
4735 return result;
4738 #else /* which OS? */
4739 static PyObject *
4740 posix_popen(PyObject *self, PyObject *args)
4742 char *name;
4743 char *mode = "r";
4744 int bufsize = -1;
4745 FILE *fp;
4746 PyObject *f;
4747 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
4748 return NULL;
4749 /* Strip mode of binary or text modifiers */
4750 if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
4751 mode = "r";
4752 else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
4753 mode = "w";
4754 Py_BEGIN_ALLOW_THREADS
4755 fp = popen(name, mode);
4756 Py_END_ALLOW_THREADS
4757 if (fp == NULL)
4758 return posix_error();
4759 f = PyFile_FromFile(fp, name, mode, pclose);
4760 if (f != NULL)
4761 PyFile_SetBufSize(f, bufsize);
4762 return f;
4765 #endif /* PYOS_??? */
4766 #endif /* HAVE_POPEN */
4769 #ifdef HAVE_SETUID
4770 PyDoc_STRVAR(posix_setuid__doc__,
4771 "setuid(uid)\n\n\
4772 Set the current process's user id.");
4774 static PyObject *
4775 posix_setuid(PyObject *self, PyObject *args)
4777 int uid;
4778 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
4779 return NULL;
4780 if (setuid(uid) < 0)
4781 return posix_error();
4782 Py_INCREF(Py_None);
4783 return Py_None;
4785 #endif /* HAVE_SETUID */
4788 #ifdef HAVE_SETEUID
4789 PyDoc_STRVAR(posix_seteuid__doc__,
4790 "seteuid(uid)\n\n\
4791 Set the current process's effective user id.");
4793 static PyObject *
4794 posix_seteuid (PyObject *self, PyObject *args)
4796 int euid;
4797 if (!PyArg_ParseTuple(args, "i", &euid)) {
4798 return NULL;
4799 } else if (seteuid(euid) < 0) {
4800 return posix_error();
4801 } else {
4802 Py_INCREF(Py_None);
4803 return Py_None;
4806 #endif /* HAVE_SETEUID */
4808 #ifdef HAVE_SETEGID
4809 PyDoc_STRVAR(posix_setegid__doc__,
4810 "setegid(gid)\n\n\
4811 Set the current process's effective group id.");
4813 static PyObject *
4814 posix_setegid (PyObject *self, PyObject *args)
4816 int egid;
4817 if (!PyArg_ParseTuple(args, "i", &egid)) {
4818 return NULL;
4819 } else if (setegid(egid) < 0) {
4820 return posix_error();
4821 } else {
4822 Py_INCREF(Py_None);
4823 return Py_None;
4826 #endif /* HAVE_SETEGID */
4828 #ifdef HAVE_SETREUID
4829 PyDoc_STRVAR(posix_setreuid__doc__,
4830 "setreuid(ruid, euid)\n\n\
4831 Set the current process's real and effective user ids.");
4833 static PyObject *
4834 posix_setreuid (PyObject *self, PyObject *args)
4836 int ruid, euid;
4837 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
4838 return NULL;
4839 } else if (setreuid(ruid, euid) < 0) {
4840 return posix_error();
4841 } else {
4842 Py_INCREF(Py_None);
4843 return Py_None;
4846 #endif /* HAVE_SETREUID */
4848 #ifdef HAVE_SETREGID
4849 PyDoc_STRVAR(posix_setregid__doc__,
4850 "setregid(rgid, egid)\n\n\
4851 Set the current process's real and effective group ids.");
4853 static PyObject *
4854 posix_setregid (PyObject *self, PyObject *args)
4856 int rgid, egid;
4857 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
4858 return NULL;
4859 } else if (setregid(rgid, egid) < 0) {
4860 return posix_error();
4861 } else {
4862 Py_INCREF(Py_None);
4863 return Py_None;
4866 #endif /* HAVE_SETREGID */
4868 #ifdef HAVE_SETGID
4869 PyDoc_STRVAR(posix_setgid__doc__,
4870 "setgid(gid)\n\n\
4871 Set the current process's group id.");
4873 static PyObject *
4874 posix_setgid(PyObject *self, PyObject *args)
4876 int gid;
4877 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
4878 return NULL;
4879 if (setgid(gid) < 0)
4880 return posix_error();
4881 Py_INCREF(Py_None);
4882 return Py_None;
4884 #endif /* HAVE_SETGID */
4886 #ifdef HAVE_SETGROUPS
4887 PyDoc_STRVAR(posix_setgroups__doc__,
4888 "setgroups(list)\n\n\
4889 Set the groups of the current process to list.");
4891 static PyObject *
4892 posix_setgroups(PyObject *self, PyObject *args)
4894 PyObject *groups;
4895 int i, len;
4896 gid_t grouplist[MAX_GROUPS];
4898 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
4899 return NULL;
4900 if (!PySequence_Check(groups)) {
4901 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
4902 return NULL;
4904 len = PySequence_Size(groups);
4905 if (len > MAX_GROUPS) {
4906 PyErr_SetString(PyExc_ValueError, "too many groups");
4907 return NULL;
4909 for(i = 0; i < len; i++) {
4910 PyObject *elem;
4911 elem = PySequence_GetItem(groups, i);
4912 if (!elem)
4913 return NULL;
4914 if (!PyInt_Check(elem)) {
4915 if (!PyLong_Check(elem)) {
4916 PyErr_SetString(PyExc_TypeError,
4917 "groups must be integers");
4918 Py_DECREF(elem);
4919 return NULL;
4920 } else {
4921 unsigned long x = PyLong_AsUnsignedLong(elem);
4922 if (PyErr_Occurred()) {
4923 PyErr_SetString(PyExc_TypeError,
4924 "group id too big");
4925 Py_DECREF(elem);
4926 return NULL;
4928 grouplist[i] = x;
4929 /* read back the value to see if it fitted in gid_t */
4930 if (grouplist[i] != x) {
4931 PyErr_SetString(PyExc_TypeError,
4932 "group id too big");
4933 Py_DECREF(elem);
4934 return NULL;
4937 } else {
4938 long x = PyInt_AsLong(elem);
4939 grouplist[i] = x;
4940 if (grouplist[i] != x) {
4941 PyErr_SetString(PyExc_TypeError,
4942 "group id too big");
4943 Py_DECREF(elem);
4944 return NULL;
4947 Py_DECREF(elem);
4950 if (setgroups(len, grouplist) < 0)
4951 return posix_error();
4952 Py_INCREF(Py_None);
4953 return Py_None;
4955 #endif /* HAVE_SETGROUPS */
4957 #ifdef HAVE_WAITPID
4958 PyDoc_STRVAR(posix_waitpid__doc__,
4959 "waitpid(pid, options) -> (pid, status)\n\n\
4960 Wait for completion of a given child process.");
4962 static PyObject *
4963 posix_waitpid(PyObject *self, PyObject *args)
4965 int pid, options;
4966 #ifdef UNION_WAIT
4967 union wait status;
4968 #define status_i (status.w_status)
4969 #else
4970 int status;
4971 #define status_i status
4972 #endif
4973 status_i = 0;
4975 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
4976 return NULL;
4977 Py_BEGIN_ALLOW_THREADS
4978 pid = waitpid(pid, &status, options);
4979 Py_END_ALLOW_THREADS
4980 if (pid == -1)
4981 return posix_error();
4982 else
4983 return Py_BuildValue("ii", pid, status_i);
4986 #elif defined(HAVE_CWAIT)
4988 /* MS C has a variant of waitpid() that's usable for most purposes. */
4989 PyDoc_STRVAR(posix_waitpid__doc__,
4990 "waitpid(pid, options) -> (pid, status << 8)\n\n"
4991 "Wait for completion of a given process. options is ignored on Windows.");
4993 static PyObject *
4994 posix_waitpid(PyObject *self, PyObject *args)
4996 int pid, options;
4997 int status;
4999 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
5000 return NULL;
5001 Py_BEGIN_ALLOW_THREADS
5002 pid = _cwait(&status, pid, options);
5003 Py_END_ALLOW_THREADS
5004 if (pid == -1)
5005 return posix_error();
5006 else
5007 /* shift the status left a byte so this is more like the
5008 POSIX waitpid */
5009 return Py_BuildValue("ii", pid, status << 8);
5011 #endif /* HAVE_WAITPID || HAVE_CWAIT */
5013 #ifdef HAVE_WAIT
5014 PyDoc_STRVAR(posix_wait__doc__,
5015 "wait() -> (pid, status)\n\n\
5016 Wait for completion of a child process.");
5018 static PyObject *
5019 posix_wait(PyObject *self, PyObject *noargs)
5021 int pid;
5022 #ifdef UNION_WAIT
5023 union wait status;
5024 #define status_i (status.w_status)
5025 #else
5026 int status;
5027 #define status_i status
5028 #endif
5030 status_i = 0;
5031 Py_BEGIN_ALLOW_THREADS
5032 pid = wait(&status);
5033 Py_END_ALLOW_THREADS
5034 if (pid == -1)
5035 return posix_error();
5036 else
5037 return Py_BuildValue("ii", pid, status_i);
5038 #undef status_i
5040 #endif
5043 PyDoc_STRVAR(posix_lstat__doc__,
5044 "lstat(path) -> stat result\n\n\
5045 Like stat(path), but do not follow symbolic links.");
5047 static PyObject *
5048 posix_lstat(PyObject *self, PyObject *args)
5050 #ifdef HAVE_LSTAT
5051 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
5052 #else /* !HAVE_LSTAT */
5053 #ifdef MS_WINDOWS
5054 return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", _wstati64);
5055 #else
5056 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
5057 #endif
5058 #endif /* !HAVE_LSTAT */
5062 #ifdef HAVE_READLINK
5063 PyDoc_STRVAR(posix_readlink__doc__,
5064 "readlink(path) -> path\n\n\
5065 Return a string representing the path to which the symbolic link points.");
5067 static PyObject *
5068 posix_readlink(PyObject *self, PyObject *args)
5070 char buf[MAXPATHLEN];
5071 char *path;
5072 int n;
5073 if (!PyArg_ParseTuple(args, "s:readlink", &path))
5074 return NULL;
5075 Py_BEGIN_ALLOW_THREADS
5076 n = readlink(path, buf, (int) sizeof buf);
5077 Py_END_ALLOW_THREADS
5078 if (n < 0)
5079 return posix_error_with_filename(path);
5080 return PyString_FromStringAndSize(buf, n);
5082 #endif /* HAVE_READLINK */
5085 #ifdef HAVE_SYMLINK
5086 PyDoc_STRVAR(posix_symlink__doc__,
5087 "symlink(src, dst)\n\n\
5088 Create a symbolic link pointing to src named dst.");
5090 static PyObject *
5091 posix_symlink(PyObject *self, PyObject *args)
5093 return posix_2str(args, "etet:symlink", symlink, NULL, NULL);
5095 #endif /* HAVE_SYMLINK */
5098 #ifdef HAVE_TIMES
5099 #ifndef HZ
5100 #define HZ 60 /* Universal constant :-) */
5101 #endif /* HZ */
5103 #if defined(PYCC_VACPP) && defined(PYOS_OS2)
5104 static long
5105 system_uptime(void)
5107 ULONG value = 0;
5109 Py_BEGIN_ALLOW_THREADS
5110 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
5111 Py_END_ALLOW_THREADS
5113 return value;
5116 static PyObject *
5117 posix_times(PyObject *self, PyObject *noargs)
5119 /* Currently Only Uptime is Provided -- Others Later */
5120 return Py_BuildValue("ddddd",
5121 (double)0 /* t.tms_utime / HZ */,
5122 (double)0 /* t.tms_stime / HZ */,
5123 (double)0 /* t.tms_cutime / HZ */,
5124 (double)0 /* t.tms_cstime / HZ */,
5125 (double)system_uptime() / 1000);
5127 #else /* not OS2 */
5128 static PyObject *
5129 posix_times(PyObject *self, PyObject *noargs)
5131 struct tms t;
5132 clock_t c;
5133 errno = 0;
5134 c = times(&t);
5135 if (c == (clock_t) -1)
5136 return posix_error();
5137 return Py_BuildValue("ddddd",
5138 (double)t.tms_utime / HZ,
5139 (double)t.tms_stime / HZ,
5140 (double)t.tms_cutime / HZ,
5141 (double)t.tms_cstime / HZ,
5142 (double)c / HZ);
5144 #endif /* not OS2 */
5145 #endif /* HAVE_TIMES */
5148 #ifdef MS_WINDOWS
5149 #define HAVE_TIMES /* so the method table will pick it up */
5150 static PyObject *
5151 posix_times(PyObject *self, PyObject *noargs)
5153 FILETIME create, exit, kernel, user;
5154 HANDLE hProc;
5155 hProc = GetCurrentProcess();
5156 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
5157 /* The fields of a FILETIME structure are the hi and lo part
5158 of a 64-bit value expressed in 100 nanosecond units.
5159 1e7 is one second in such units; 1e-7 the inverse.
5160 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
5162 return Py_BuildValue(
5163 "ddddd",
5164 (double)(kernel.dwHighDateTime*429.4967296 +
5165 kernel.dwLowDateTime*1e-7),
5166 (double)(user.dwHighDateTime*429.4967296 +
5167 user.dwLowDateTime*1e-7),
5168 (double)0,
5169 (double)0,
5170 (double)0);
5172 #endif /* MS_WINDOWS */
5174 #ifdef HAVE_TIMES
5175 PyDoc_STRVAR(posix_times__doc__,
5176 "times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
5177 Return a tuple of floating point numbers indicating process times.");
5178 #endif
5181 #ifdef HAVE_GETSID
5182 PyDoc_STRVAR(posix_getsid__doc__,
5183 "getsid(pid) -> sid\n\n\
5184 Call the system call getsid().");
5186 static PyObject *
5187 posix_getsid(PyObject *self, PyObject *args)
5189 int pid, sid;
5190 if (!PyArg_ParseTuple(args, "i:getsid", &pid))
5191 return NULL;
5192 sid = getsid(pid);
5193 if (sid < 0)
5194 return posix_error();
5195 return PyInt_FromLong((long)sid);
5197 #endif /* HAVE_GETSID */
5200 #ifdef HAVE_SETSID
5201 PyDoc_STRVAR(posix_setsid__doc__,
5202 "setsid()\n\n\
5203 Call the system call setsid().");
5205 static PyObject *
5206 posix_setsid(PyObject *self, PyObject *noargs)
5208 if (setsid() < 0)
5209 return posix_error();
5210 Py_INCREF(Py_None);
5211 return Py_None;
5213 #endif /* HAVE_SETSID */
5215 #ifdef HAVE_SETPGID
5216 PyDoc_STRVAR(posix_setpgid__doc__,
5217 "setpgid(pid, pgrp)\n\n\
5218 Call the system call setpgid().");
5220 static PyObject *
5221 posix_setpgid(PyObject *self, PyObject *args)
5223 int pid, pgrp;
5224 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
5225 return NULL;
5226 if (setpgid(pid, pgrp) < 0)
5227 return posix_error();
5228 Py_INCREF(Py_None);
5229 return Py_None;
5231 #endif /* HAVE_SETPGID */
5234 #ifdef HAVE_TCGETPGRP
5235 PyDoc_STRVAR(posix_tcgetpgrp__doc__,
5236 "tcgetpgrp(fd) -> pgid\n\n\
5237 Return the process group associated with the terminal given by a fd.");
5239 static PyObject *
5240 posix_tcgetpgrp(PyObject *self, PyObject *args)
5242 int fd, pgid;
5243 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
5244 return NULL;
5245 pgid = tcgetpgrp(fd);
5246 if (pgid < 0)
5247 return posix_error();
5248 return PyInt_FromLong((long)pgid);
5250 #endif /* HAVE_TCGETPGRP */
5253 #ifdef HAVE_TCSETPGRP
5254 PyDoc_STRVAR(posix_tcsetpgrp__doc__,
5255 "tcsetpgrp(fd, pgid)\n\n\
5256 Set the process group associated with the terminal given by a fd.");
5258 static PyObject *
5259 posix_tcsetpgrp(PyObject *self, PyObject *args)
5261 int fd, pgid;
5262 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
5263 return NULL;
5264 if (tcsetpgrp(fd, pgid) < 0)
5265 return posix_error();
5266 Py_INCREF(Py_None);
5267 return Py_None;
5269 #endif /* HAVE_TCSETPGRP */
5271 /* Functions acting on file descriptors */
5273 PyDoc_STRVAR(posix_open__doc__,
5274 "open(filename, flag [, mode=0777]) -> fd\n\n\
5275 Open a file (for low level IO).");
5277 static PyObject *
5278 posix_open(PyObject *self, PyObject *args)
5280 char *file = NULL;
5281 int flag;
5282 int mode = 0777;
5283 int fd;
5285 #ifdef MS_WINDOWS
5286 if (unicode_file_names()) {
5287 PyUnicodeObject *po;
5288 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
5289 Py_BEGIN_ALLOW_THREADS
5290 /* PyUnicode_AS_UNICODE OK without thread
5291 lock as it is a simple dereference. */
5292 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
5293 Py_END_ALLOW_THREADS
5294 if (fd < 0)
5295 return posix_error();
5296 return PyInt_FromLong((long)fd);
5298 /* Drop the argument parsing error as narrow strings
5299 are also valid. */
5300 PyErr_Clear();
5302 #endif
5304 if (!PyArg_ParseTuple(args, "eti|i",
5305 Py_FileSystemDefaultEncoding, &file,
5306 &flag, &mode))
5307 return NULL;
5309 Py_BEGIN_ALLOW_THREADS
5310 fd = open(file, flag, mode);
5311 Py_END_ALLOW_THREADS
5312 if (fd < 0)
5313 return posix_error_with_allocated_filename(file);
5314 PyMem_Free(file);
5315 return PyInt_FromLong((long)fd);
5319 PyDoc_STRVAR(posix_close__doc__,
5320 "close(fd)\n\n\
5321 Close a file descriptor (for low level IO).");
5323 static PyObject *
5324 posix_close(PyObject *self, PyObject *args)
5326 int fd, res;
5327 if (!PyArg_ParseTuple(args, "i:close", &fd))
5328 return NULL;
5329 Py_BEGIN_ALLOW_THREADS
5330 res = close(fd);
5331 Py_END_ALLOW_THREADS
5332 if (res < 0)
5333 return posix_error();
5334 Py_INCREF(Py_None);
5335 return Py_None;
5339 PyDoc_STRVAR(posix_dup__doc__,
5340 "dup(fd) -> fd2\n\n\
5341 Return a duplicate of a file descriptor.");
5343 static PyObject *
5344 posix_dup(PyObject *self, PyObject *args)
5346 int fd;
5347 if (!PyArg_ParseTuple(args, "i:dup", &fd))
5348 return NULL;
5349 Py_BEGIN_ALLOW_THREADS
5350 fd = dup(fd);
5351 Py_END_ALLOW_THREADS
5352 if (fd < 0)
5353 return posix_error();
5354 return PyInt_FromLong((long)fd);
5358 PyDoc_STRVAR(posix_dup2__doc__,
5359 "dup2(old_fd, new_fd)\n\n\
5360 Duplicate file descriptor.");
5362 static PyObject *
5363 posix_dup2(PyObject *self, PyObject *args)
5365 int fd, fd2, res;
5366 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
5367 return NULL;
5368 Py_BEGIN_ALLOW_THREADS
5369 res = dup2(fd, fd2);
5370 Py_END_ALLOW_THREADS
5371 if (res < 0)
5372 return posix_error();
5373 Py_INCREF(Py_None);
5374 return Py_None;
5378 PyDoc_STRVAR(posix_lseek__doc__,
5379 "lseek(fd, pos, how) -> newpos\n\n\
5380 Set the current position of a file descriptor.");
5382 static PyObject *
5383 posix_lseek(PyObject *self, PyObject *args)
5385 int fd, how;
5386 #if defined(MS_WIN64) || defined(MS_WINDOWS)
5387 PY_LONG_LONG pos, res;
5388 #else
5389 off_t pos, res;
5390 #endif
5391 PyObject *posobj;
5392 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
5393 return NULL;
5394 #ifdef SEEK_SET
5395 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
5396 switch (how) {
5397 case 0: how = SEEK_SET; break;
5398 case 1: how = SEEK_CUR; break;
5399 case 2: how = SEEK_END; break;
5401 #endif /* SEEK_END */
5403 #if !defined(HAVE_LARGEFILE_SUPPORT)
5404 pos = PyInt_AsLong(posobj);
5405 #else
5406 pos = PyLong_Check(posobj) ?
5407 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
5408 #endif
5409 if (PyErr_Occurred())
5410 return NULL;
5412 Py_BEGIN_ALLOW_THREADS
5413 #if defined(MS_WIN64) || defined(MS_WINDOWS)
5414 res = _lseeki64(fd, pos, how);
5415 #else
5416 res = lseek(fd, pos, how);
5417 #endif
5418 Py_END_ALLOW_THREADS
5419 if (res < 0)
5420 return posix_error();
5422 #if !defined(HAVE_LARGEFILE_SUPPORT)
5423 return PyInt_FromLong(res);
5424 #else
5425 return PyLong_FromLongLong(res);
5426 #endif
5430 PyDoc_STRVAR(posix_read__doc__,
5431 "read(fd, buffersize) -> string\n\n\
5432 Read a file descriptor.");
5434 static PyObject *
5435 posix_read(PyObject *self, PyObject *args)
5437 int fd, size, n;
5438 PyObject *buffer;
5439 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
5440 return NULL;
5441 if (size < 0) {
5442 errno = EINVAL;
5443 return posix_error();
5445 buffer = PyString_FromStringAndSize((char *)NULL, size);
5446 if (buffer == NULL)
5447 return NULL;
5448 Py_BEGIN_ALLOW_THREADS
5449 n = read(fd, PyString_AsString(buffer), size);
5450 Py_END_ALLOW_THREADS
5451 if (n < 0) {
5452 Py_DECREF(buffer);
5453 return posix_error();
5455 if (n != size)
5456 _PyString_Resize(&buffer, n);
5457 return buffer;
5461 PyDoc_STRVAR(posix_write__doc__,
5462 "write(fd, string) -> byteswritten\n\n\
5463 Write a string to a file descriptor.");
5465 static PyObject *
5466 posix_write(PyObject *self, PyObject *args)
5468 int fd, size;
5469 char *buffer;
5470 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
5471 return NULL;
5472 Py_BEGIN_ALLOW_THREADS
5473 size = write(fd, buffer, size);
5474 Py_END_ALLOW_THREADS
5475 if (size < 0)
5476 return posix_error();
5477 return PyInt_FromLong((long)size);
5481 PyDoc_STRVAR(posix_fstat__doc__,
5482 "fstat(fd) -> stat result\n\n\
5483 Like stat(), but for an open file descriptor.");
5485 static PyObject *
5486 posix_fstat(PyObject *self, PyObject *args)
5488 int fd;
5489 STRUCT_STAT st;
5490 int res;
5491 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
5492 return NULL;
5493 #ifdef __VMS
5494 /* on OpenVMS we must ensure that all bytes are written to the file */
5495 fsync(fd);
5496 #endif
5497 Py_BEGIN_ALLOW_THREADS
5498 res = FSTAT(fd, &st);
5499 Py_END_ALLOW_THREADS
5500 if (res != 0)
5501 return posix_error();
5503 return _pystat_fromstructstat(st);
5507 PyDoc_STRVAR(posix_fdopen__doc__,
5508 "fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
5509 Return an open file object connected to a file descriptor.");
5511 static PyObject *
5512 posix_fdopen(PyObject *self, PyObject *args)
5514 int fd;
5515 char *mode = "r";
5516 int bufsize = -1;
5517 FILE *fp;
5518 PyObject *f;
5519 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
5520 return NULL;
5522 if (mode[0] != 'r' && mode[0] != 'w' && mode[0] != 'a') {
5523 PyErr_Format(PyExc_ValueError,
5524 "invalid file mode '%s'", mode);
5525 return NULL;
5528 Py_BEGIN_ALLOW_THREADS
5529 fp = fdopen(fd, mode);
5530 Py_END_ALLOW_THREADS
5531 if (fp == NULL)
5532 return posix_error();
5533 f = PyFile_FromFile(fp, "<fdopen>", mode, fclose);
5534 if (f != NULL)
5535 PyFile_SetBufSize(f, bufsize);
5536 return f;
5539 PyDoc_STRVAR(posix_isatty__doc__,
5540 "isatty(fd) -> bool\n\n\
5541 Return True if the file descriptor 'fd' is an open file descriptor\n\
5542 connected to the slave end of a terminal.");
5544 static PyObject *
5545 posix_isatty(PyObject *self, PyObject *args)
5547 int fd;
5548 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
5549 return NULL;
5550 return PyBool_FromLong(isatty(fd));
5553 #ifdef HAVE_PIPE
5554 PyDoc_STRVAR(posix_pipe__doc__,
5555 "pipe() -> (read_end, write_end)\n\n\
5556 Create a pipe.");
5558 static PyObject *
5559 posix_pipe(PyObject *self, PyObject *noargs)
5561 #if defined(PYOS_OS2)
5562 HFILE read, write;
5563 APIRET rc;
5565 Py_BEGIN_ALLOW_THREADS
5566 rc = DosCreatePipe( &read, &write, 4096);
5567 Py_END_ALLOW_THREADS
5568 if (rc != NO_ERROR)
5569 return os2_error(rc);
5571 return Py_BuildValue("(ii)", read, write);
5572 #else
5573 #if !defined(MS_WINDOWS)
5574 int fds[2];
5575 int res;
5576 Py_BEGIN_ALLOW_THREADS
5577 res = pipe(fds);
5578 Py_END_ALLOW_THREADS
5579 if (res != 0)
5580 return posix_error();
5581 return Py_BuildValue("(ii)", fds[0], fds[1]);
5582 #else /* MS_WINDOWS */
5583 HANDLE read, write;
5584 int read_fd, write_fd;
5585 BOOL ok;
5586 Py_BEGIN_ALLOW_THREADS
5587 ok = CreatePipe(&read, &write, NULL, 0);
5588 Py_END_ALLOW_THREADS
5589 if (!ok)
5590 return win32_error("CreatePipe", NULL);
5591 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
5592 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
5593 return Py_BuildValue("(ii)", read_fd, write_fd);
5594 #endif /* MS_WINDOWS */
5595 #endif
5597 #endif /* HAVE_PIPE */
5600 #ifdef HAVE_MKFIFO
5601 PyDoc_STRVAR(posix_mkfifo__doc__,
5602 "mkfifo(filename [, mode=0666])\n\n\
5603 Create a FIFO (a POSIX named pipe).");
5605 static PyObject *
5606 posix_mkfifo(PyObject *self, PyObject *args)
5608 char *filename;
5609 int mode = 0666;
5610 int res;
5611 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
5612 return NULL;
5613 Py_BEGIN_ALLOW_THREADS
5614 res = mkfifo(filename, mode);
5615 Py_END_ALLOW_THREADS
5616 if (res < 0)
5617 return posix_error();
5618 Py_INCREF(Py_None);
5619 return Py_None;
5621 #endif
5624 #if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
5625 PyDoc_STRVAR(posix_mknod__doc__,
5626 "mknod(filename [, mode=0600, device])\n\n\
5627 Create a filesystem node (file, device special file or named pipe)\n\
5628 named filename. mode specifies both the permissions to use and the\n\
5629 type of node to be created, being combined (bitwise OR) with one of\n\
5630 S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
5631 device defines the newly created device special file (probably using\n\
5632 os.makedev()), otherwise it is ignored.");
5635 static PyObject *
5636 posix_mknod(PyObject *self, PyObject *args)
5638 char *filename;
5639 int mode = 0600;
5640 int device = 0;
5641 int res;
5642 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
5643 return NULL;
5644 Py_BEGIN_ALLOW_THREADS
5645 res = mknod(filename, mode, device);
5646 Py_END_ALLOW_THREADS
5647 if (res < 0)
5648 return posix_error();
5649 Py_INCREF(Py_None);
5650 return Py_None;
5652 #endif
5654 #ifdef HAVE_DEVICE_MACROS
5655 PyDoc_STRVAR(posix_major__doc__,
5656 "major(device) -> major number\n\
5657 Extracts a device major number from a raw device number.");
5659 static PyObject *
5660 posix_major(PyObject *self, PyObject *args)
5662 int device;
5663 if (!PyArg_ParseTuple(args, "i:major", &device))
5664 return NULL;
5665 return PyInt_FromLong((long)major(device));
5668 PyDoc_STRVAR(posix_minor__doc__,
5669 "minor(device) -> minor number\n\
5670 Extracts a device minor number from a raw device number.");
5672 static PyObject *
5673 posix_minor(PyObject *self, PyObject *args)
5675 int device;
5676 if (!PyArg_ParseTuple(args, "i:minor", &device))
5677 return NULL;
5678 return PyInt_FromLong((long)minor(device));
5681 PyDoc_STRVAR(posix_makedev__doc__,
5682 "makedev(major, minor) -> device number\n\
5683 Composes a raw device number from the major and minor device numbers.");
5685 static PyObject *
5686 posix_makedev(PyObject *self, PyObject *args)
5688 int major, minor;
5689 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
5690 return NULL;
5691 return PyInt_FromLong((long)makedev(major, minor));
5693 #endif /* device macros */
5696 #ifdef HAVE_FTRUNCATE
5697 PyDoc_STRVAR(posix_ftruncate__doc__,
5698 "ftruncate(fd, length)\n\n\
5699 Truncate a file to a specified length.");
5701 static PyObject *
5702 posix_ftruncate(PyObject *self, PyObject *args)
5704 int fd;
5705 off_t length;
5706 int res;
5707 PyObject *lenobj;
5709 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
5710 return NULL;
5712 #if !defined(HAVE_LARGEFILE_SUPPORT)
5713 length = PyInt_AsLong(lenobj);
5714 #else
5715 length = PyLong_Check(lenobj) ?
5716 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
5717 #endif
5718 if (PyErr_Occurred())
5719 return NULL;
5721 Py_BEGIN_ALLOW_THREADS
5722 res = ftruncate(fd, length);
5723 Py_END_ALLOW_THREADS
5724 if (res < 0) {
5725 PyErr_SetFromErrno(PyExc_IOError);
5726 return NULL;
5728 Py_INCREF(Py_None);
5729 return Py_None;
5731 #endif
5733 #ifdef HAVE_PUTENV
5734 PyDoc_STRVAR(posix_putenv__doc__,
5735 "putenv(key, value)\n\n\
5736 Change or add an environment variable.");
5738 /* Save putenv() parameters as values here, so we can collect them when they
5739 * get re-set with another call for the same key. */
5740 static PyObject *posix_putenv_garbage;
5742 static PyObject *
5743 posix_putenv(PyObject *self, PyObject *args)
5745 char *s1, *s2;
5746 char *new;
5747 PyObject *newstr;
5748 size_t len;
5750 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
5751 return NULL;
5753 #if defined(PYOS_OS2)
5754 if (stricmp(s1, "BEGINLIBPATH") == 0) {
5755 APIRET rc;
5757 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
5758 if (rc != NO_ERROR)
5759 return os2_error(rc);
5761 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
5762 APIRET rc;
5764 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
5765 if (rc != NO_ERROR)
5766 return os2_error(rc);
5767 } else {
5768 #endif
5770 /* XXX This can leak memory -- not easy to fix :-( */
5771 len = strlen(s1) + strlen(s2) + 2;
5772 /* len includes space for a trailing \0; the size arg to
5773 PyString_FromStringAndSize does not count that */
5774 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
5775 if (newstr == NULL)
5776 return PyErr_NoMemory();
5777 new = PyString_AS_STRING(newstr);
5778 PyOS_snprintf(new, len, "%s=%s", s1, s2);
5779 if (putenv(new)) {
5780 Py_DECREF(newstr);
5781 posix_error();
5782 return NULL;
5784 /* Install the first arg and newstr in posix_putenv_garbage;
5785 * this will cause previous value to be collected. This has to
5786 * happen after the real putenv() call because the old value
5787 * was still accessible until then. */
5788 if (PyDict_SetItem(posix_putenv_garbage,
5789 PyTuple_GET_ITEM(args, 0), newstr)) {
5790 /* really not much we can do; just leak */
5791 PyErr_Clear();
5793 else {
5794 Py_DECREF(newstr);
5797 #if defined(PYOS_OS2)
5799 #endif
5800 Py_INCREF(Py_None);
5801 return Py_None;
5803 #endif /* putenv */
5805 #ifdef HAVE_UNSETENV
5806 PyDoc_STRVAR(posix_unsetenv__doc__,
5807 "unsetenv(key)\n\n\
5808 Delete an environment variable.");
5810 static PyObject *
5811 posix_unsetenv(PyObject *self, PyObject *args)
5813 char *s1;
5815 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
5816 return NULL;
5818 unsetenv(s1);
5820 /* Remove the key from posix_putenv_garbage;
5821 * this will cause it to be collected. This has to
5822 * happen after the real unsetenv() call because the
5823 * old value was still accessible until then.
5825 if (PyDict_DelItem(posix_putenv_garbage,
5826 PyTuple_GET_ITEM(args, 0))) {
5827 /* really not much we can do; just leak */
5828 PyErr_Clear();
5831 Py_INCREF(Py_None);
5832 return Py_None;
5834 #endif /* unsetenv */
5836 #ifdef HAVE_STRERROR
5837 PyDoc_STRVAR(posix_strerror__doc__,
5838 "strerror(code) -> string\n\n\
5839 Translate an error code to a message string.");
5841 static PyObject *
5842 posix_strerror(PyObject *self, PyObject *args)
5844 int code;
5845 char *message;
5846 if (!PyArg_ParseTuple(args, "i:strerror", &code))
5847 return NULL;
5848 message = strerror(code);
5849 if (message == NULL) {
5850 PyErr_SetString(PyExc_ValueError,
5851 "strerror() argument out of range");
5852 return NULL;
5854 return PyString_FromString(message);
5856 #endif /* strerror */
5859 #ifdef HAVE_SYS_WAIT_H
5861 #ifdef WCOREDUMP
5862 PyDoc_STRVAR(posix_WCOREDUMP__doc__,
5863 "WCOREDUMP(status) -> bool\n\n\
5864 Return True if the process returning 'status' was dumped to a core file.");
5866 static PyObject *
5867 posix_WCOREDUMP(PyObject *self, PyObject *args)
5869 #ifdef UNION_WAIT
5870 union wait status;
5871 #define status_i (status.w_status)
5872 #else
5873 int status;
5874 #define status_i status
5875 #endif
5876 status_i = 0;
5878 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &status_i))
5880 return NULL;
5883 return PyBool_FromLong(WCOREDUMP(status));
5884 #undef status_i
5886 #endif /* WCOREDUMP */
5888 #ifdef WIFCONTINUED
5889 PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
5890 "WIFCONTINUED(status) -> bool\n\n\
5891 Return True if the process returning 'status' was continued from a\n\
5892 job control stop.");
5894 static PyObject *
5895 posix_WIFCONTINUED(PyObject *self, PyObject *args)
5897 #ifdef UNION_WAIT
5898 union wait status;
5899 #define status_i (status.w_status)
5900 #else
5901 int status;
5902 #define status_i status
5903 #endif
5904 status_i = 0;
5906 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &status_i))
5908 return NULL;
5911 return PyBool_FromLong(WIFCONTINUED(status));
5912 #undef status_i
5914 #endif /* WIFCONTINUED */
5916 #ifdef WIFSTOPPED
5917 PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
5918 "WIFSTOPPED(status) -> bool\n\n\
5919 Return True if the process returning 'status' was stopped.");
5921 static PyObject *
5922 posix_WIFSTOPPED(PyObject *self, PyObject *args)
5924 #ifdef UNION_WAIT
5925 union wait status;
5926 #define status_i (status.w_status)
5927 #else
5928 int status;
5929 #define status_i status
5930 #endif
5931 status_i = 0;
5933 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
5935 return NULL;
5938 return PyBool_FromLong(WIFSTOPPED(status));
5939 #undef status_i
5941 #endif /* WIFSTOPPED */
5943 #ifdef WIFSIGNALED
5944 PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
5945 "WIFSIGNALED(status) -> bool\n\n\
5946 Return True if the process returning 'status' was terminated by a signal.");
5948 static PyObject *
5949 posix_WIFSIGNALED(PyObject *self, PyObject *args)
5951 #ifdef UNION_WAIT
5952 union wait status;
5953 #define status_i (status.w_status)
5954 #else
5955 int status;
5956 #define status_i status
5957 #endif
5958 status_i = 0;
5960 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
5962 return NULL;
5965 return PyBool_FromLong(WIFSIGNALED(status));
5966 #undef status_i
5968 #endif /* WIFSIGNALED */
5970 #ifdef WIFEXITED
5971 PyDoc_STRVAR(posix_WIFEXITED__doc__,
5972 "WIFEXITED(status) -> bool\n\n\
5973 Return true if the process returning 'status' exited using the exit()\n\
5974 system call.");
5976 static PyObject *
5977 posix_WIFEXITED(PyObject *self, PyObject *args)
5979 #ifdef UNION_WAIT
5980 union wait status;
5981 #define status_i (status.w_status)
5982 #else
5983 int status;
5984 #define status_i status
5985 #endif
5986 status_i = 0;
5988 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
5990 return NULL;
5993 return PyBool_FromLong(WIFEXITED(status));
5994 #undef status_i
5996 #endif /* WIFEXITED */
5998 #ifdef WEXITSTATUS
5999 PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
6000 "WEXITSTATUS(status) -> integer\n\n\
6001 Return the process return code from 'status'.");
6003 static PyObject *
6004 posix_WEXITSTATUS(PyObject *self, PyObject *args)
6006 #ifdef UNION_WAIT
6007 union wait status;
6008 #define status_i (status.w_status)
6009 #else
6010 int status;
6011 #define status_i status
6012 #endif
6013 status_i = 0;
6015 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
6017 return NULL;
6020 return Py_BuildValue("i", WEXITSTATUS(status));
6021 #undef status_i
6023 #endif /* WEXITSTATUS */
6025 #ifdef WTERMSIG
6026 PyDoc_STRVAR(posix_WTERMSIG__doc__,
6027 "WTERMSIG(status) -> integer\n\n\
6028 Return the signal that terminated the process that provided the 'status'\n\
6029 value.");
6031 static PyObject *
6032 posix_WTERMSIG(PyObject *self, PyObject *args)
6034 #ifdef UNION_WAIT
6035 union wait status;
6036 #define status_i (status.w_status)
6037 #else
6038 int status;
6039 #define status_i status
6040 #endif
6041 status_i = 0;
6043 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
6045 return NULL;
6048 return Py_BuildValue("i", WTERMSIG(status));
6049 #undef status_i
6051 #endif /* WTERMSIG */
6053 #ifdef WSTOPSIG
6054 PyDoc_STRVAR(posix_WSTOPSIG__doc__,
6055 "WSTOPSIG(status) -> integer\n\n\
6056 Return the signal that stopped the process that provided\n\
6057 the 'status' value.");
6059 static PyObject *
6060 posix_WSTOPSIG(PyObject *self, PyObject *args)
6062 #ifdef UNION_WAIT
6063 union wait status;
6064 #define status_i (status.w_status)
6065 #else
6066 int status;
6067 #define status_i status
6068 #endif
6069 status_i = 0;
6071 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
6073 return NULL;
6076 return Py_BuildValue("i", WSTOPSIG(status));
6077 #undef status_i
6079 #endif /* WSTOPSIG */
6081 #endif /* HAVE_SYS_WAIT_H */
6084 #if defined(HAVE_FSTATVFS)
6085 #ifdef _SCO_DS
6086 /* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
6087 needed definitions in sys/statvfs.h */
6088 #define _SVID3
6089 #endif
6090 #include <sys/statvfs.h>
6092 static PyObject*
6093 _pystatvfs_fromstructstatvfs(struct statvfs st) {
6094 PyObject *v = PyStructSequence_New(&StatVFSResultType);
6095 if (v == NULL)
6096 return NULL;
6098 #if !defined(HAVE_LARGEFILE_SUPPORT)
6099 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6100 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
6101 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
6102 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
6103 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
6104 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
6105 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
6106 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
6107 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6108 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6109 #else
6110 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6111 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
6112 PyStructSequence_SET_ITEM(v, 2,
6113 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
6114 PyStructSequence_SET_ITEM(v, 3,
6115 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
6116 PyStructSequence_SET_ITEM(v, 4,
6117 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
6118 PyStructSequence_SET_ITEM(v, 5,
6119 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
6120 PyStructSequence_SET_ITEM(v, 6,
6121 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
6122 PyStructSequence_SET_ITEM(v, 7,
6123 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
6124 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6125 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6126 #endif
6128 return v;
6131 PyDoc_STRVAR(posix_fstatvfs__doc__,
6132 "fstatvfs(fd) -> statvfs result\n\n\
6133 Perform an fstatvfs system call on the given fd.");
6135 static PyObject *
6136 posix_fstatvfs(PyObject *self, PyObject *args)
6138 int fd, res;
6139 struct statvfs st;
6141 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
6142 return NULL;
6143 Py_BEGIN_ALLOW_THREADS
6144 res = fstatvfs(fd, &st);
6145 Py_END_ALLOW_THREADS
6146 if (res != 0)
6147 return posix_error();
6149 return _pystatvfs_fromstructstatvfs(st);
6151 #endif /* HAVE_FSTATVFS */
6154 #if defined(HAVE_STATVFS)
6155 #include <sys/statvfs.h>
6157 PyDoc_STRVAR(posix_statvfs__doc__,
6158 "statvfs(path) -> statvfs result\n\n\
6159 Perform a statvfs system call on the given path.");
6161 static PyObject *
6162 posix_statvfs(PyObject *self, PyObject *args)
6164 char *path;
6165 int res;
6166 struct statvfs st;
6167 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
6168 return NULL;
6169 Py_BEGIN_ALLOW_THREADS
6170 res = statvfs(path, &st);
6171 Py_END_ALLOW_THREADS
6172 if (res != 0)
6173 return posix_error_with_filename(path);
6175 return _pystatvfs_fromstructstatvfs(st);
6177 #endif /* HAVE_STATVFS */
6180 #ifdef HAVE_TEMPNAM
6181 PyDoc_STRVAR(posix_tempnam__doc__,
6182 "tempnam([dir[, prefix]]) -> string\n\n\
6183 Return a unique name for a temporary file.\n\
6184 The directory and a prefix may be specified as strings; they may be omitted\n\
6185 or None if not needed.");
6187 static PyObject *
6188 posix_tempnam(PyObject *self, PyObject *args)
6190 PyObject *result = NULL;
6191 char *dir = NULL;
6192 char *pfx = NULL;
6193 char *name;
6195 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
6196 return NULL;
6198 if (PyErr_Warn(PyExc_RuntimeWarning,
6199 "tempnam is a potential security risk to your program") < 0)
6200 return NULL;
6202 #ifdef MS_WINDOWS
6203 name = _tempnam(dir, pfx);
6204 #else
6205 name = tempnam(dir, pfx);
6206 #endif
6207 if (name == NULL)
6208 return PyErr_NoMemory();
6209 result = PyString_FromString(name);
6210 free(name);
6211 return result;
6213 #endif
6216 #ifdef HAVE_TMPFILE
6217 PyDoc_STRVAR(posix_tmpfile__doc__,
6218 "tmpfile() -> file object\n\n\
6219 Create a temporary file with no directory entries.");
6221 static PyObject *
6222 posix_tmpfile(PyObject *self, PyObject *noargs)
6224 FILE *fp;
6226 fp = tmpfile();
6227 if (fp == NULL)
6228 return posix_error();
6229 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
6231 #endif
6234 #ifdef HAVE_TMPNAM
6235 PyDoc_STRVAR(posix_tmpnam__doc__,
6236 "tmpnam() -> string\n\n\
6237 Return a unique name for a temporary file.");
6239 static PyObject *
6240 posix_tmpnam(PyObject *self, PyObject *noargs)
6242 char buffer[L_tmpnam];
6243 char *name;
6245 if (PyErr_Warn(PyExc_RuntimeWarning,
6246 "tmpnam is a potential security risk to your program") < 0)
6247 return NULL;
6249 #ifdef USE_TMPNAM_R
6250 name = tmpnam_r(buffer);
6251 #else
6252 name = tmpnam(buffer);
6253 #endif
6254 if (name == NULL) {
6255 PyErr_SetObject(PyExc_OSError,
6256 Py_BuildValue("is", 0,
6257 #ifdef USE_TMPNAM_R
6258 "unexpected NULL from tmpnam_r"
6259 #else
6260 "unexpected NULL from tmpnam"
6261 #endif
6263 return NULL;
6265 return PyString_FromString(buffer);
6267 #endif
6270 /* This is used for fpathconf(), pathconf(), confstr() and sysconf().
6271 * It maps strings representing configuration variable names to
6272 * integer values, allowing those functions to be called with the
6273 * magic names instead of polluting the module's namespace with tons of
6274 * rarely-used constants. There are three separate tables that use
6275 * these definitions.
6277 * This code is always included, even if none of the interfaces that
6278 * need it are included. The #if hackery needed to avoid it would be
6279 * sufficiently pervasive that it's not worth the loss of readability.
6281 struct constdef {
6282 char *name;
6283 long value;
6286 static int
6287 conv_confname(PyObject *arg, int *valuep, struct constdef *table,
6288 size_t tablesize)
6290 if (PyInt_Check(arg)) {
6291 *valuep = PyInt_AS_LONG(arg);
6292 return 1;
6294 if (PyString_Check(arg)) {
6295 /* look up the value in the table using a binary search */
6296 size_t lo = 0;
6297 size_t mid;
6298 size_t hi = tablesize;
6299 int cmp;
6300 char *confname = PyString_AS_STRING(arg);
6301 while (lo < hi) {
6302 mid = (lo + hi) / 2;
6303 cmp = strcmp(confname, table[mid].name);
6304 if (cmp < 0)
6305 hi = mid;
6306 else if (cmp > 0)
6307 lo = mid + 1;
6308 else {
6309 *valuep = table[mid].value;
6310 return 1;
6313 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
6315 else
6316 PyErr_SetString(PyExc_TypeError,
6317 "configuration names must be strings or integers");
6318 return 0;
6322 #if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
6323 static struct constdef posix_constants_pathconf[] = {
6324 #ifdef _PC_ABI_AIO_XFER_MAX
6325 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
6326 #endif
6327 #ifdef _PC_ABI_ASYNC_IO
6328 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
6329 #endif
6330 #ifdef _PC_ASYNC_IO
6331 {"PC_ASYNC_IO", _PC_ASYNC_IO},
6332 #endif
6333 #ifdef _PC_CHOWN_RESTRICTED
6334 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
6335 #endif
6336 #ifdef _PC_FILESIZEBITS
6337 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
6338 #endif
6339 #ifdef _PC_LAST
6340 {"PC_LAST", _PC_LAST},
6341 #endif
6342 #ifdef _PC_LINK_MAX
6343 {"PC_LINK_MAX", _PC_LINK_MAX},
6344 #endif
6345 #ifdef _PC_MAX_CANON
6346 {"PC_MAX_CANON", _PC_MAX_CANON},
6347 #endif
6348 #ifdef _PC_MAX_INPUT
6349 {"PC_MAX_INPUT", _PC_MAX_INPUT},
6350 #endif
6351 #ifdef _PC_NAME_MAX
6352 {"PC_NAME_MAX", _PC_NAME_MAX},
6353 #endif
6354 #ifdef _PC_NO_TRUNC
6355 {"PC_NO_TRUNC", _PC_NO_TRUNC},
6356 #endif
6357 #ifdef _PC_PATH_MAX
6358 {"PC_PATH_MAX", _PC_PATH_MAX},
6359 #endif
6360 #ifdef _PC_PIPE_BUF
6361 {"PC_PIPE_BUF", _PC_PIPE_BUF},
6362 #endif
6363 #ifdef _PC_PRIO_IO
6364 {"PC_PRIO_IO", _PC_PRIO_IO},
6365 #endif
6366 #ifdef _PC_SOCK_MAXBUF
6367 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
6368 #endif
6369 #ifdef _PC_SYNC_IO
6370 {"PC_SYNC_IO", _PC_SYNC_IO},
6371 #endif
6372 #ifdef _PC_VDISABLE
6373 {"PC_VDISABLE", _PC_VDISABLE},
6374 #endif
6377 static int
6378 conv_path_confname(PyObject *arg, int *valuep)
6380 return conv_confname(arg, valuep, posix_constants_pathconf,
6381 sizeof(posix_constants_pathconf)
6382 / sizeof(struct constdef));
6384 #endif
6386 #ifdef HAVE_FPATHCONF
6387 PyDoc_STRVAR(posix_fpathconf__doc__,
6388 "fpathconf(fd, name) -> integer\n\n\
6389 Return the configuration limit name for the file descriptor fd.\n\
6390 If there is no limit, return -1.");
6392 static PyObject *
6393 posix_fpathconf(PyObject *self, PyObject *args)
6395 PyObject *result = NULL;
6396 int name, fd;
6398 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
6399 conv_path_confname, &name)) {
6400 long limit;
6402 errno = 0;
6403 limit = fpathconf(fd, name);
6404 if (limit == -1 && errno != 0)
6405 posix_error();
6406 else
6407 result = PyInt_FromLong(limit);
6409 return result;
6411 #endif
6414 #ifdef HAVE_PATHCONF
6415 PyDoc_STRVAR(posix_pathconf__doc__,
6416 "pathconf(path, name) -> integer\n\n\
6417 Return the configuration limit name for the file or directory path.\n\
6418 If there is no limit, return -1.");
6420 static PyObject *
6421 posix_pathconf(PyObject *self, PyObject *args)
6423 PyObject *result = NULL;
6424 int name;
6425 char *path;
6427 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
6428 conv_path_confname, &name)) {
6429 long limit;
6431 errno = 0;
6432 limit = pathconf(path, name);
6433 if (limit == -1 && errno != 0) {
6434 if (errno == EINVAL)
6435 /* could be a path or name problem */
6436 posix_error();
6437 else
6438 posix_error_with_filename(path);
6440 else
6441 result = PyInt_FromLong(limit);
6443 return result;
6445 #endif
6447 #ifdef HAVE_CONFSTR
6448 static struct constdef posix_constants_confstr[] = {
6449 #ifdef _CS_ARCHITECTURE
6450 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
6451 #endif
6452 #ifdef _CS_HOSTNAME
6453 {"CS_HOSTNAME", _CS_HOSTNAME},
6454 #endif
6455 #ifdef _CS_HW_PROVIDER
6456 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
6457 #endif
6458 #ifdef _CS_HW_SERIAL
6459 {"CS_HW_SERIAL", _CS_HW_SERIAL},
6460 #endif
6461 #ifdef _CS_INITTAB_NAME
6462 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
6463 #endif
6464 #ifdef _CS_LFS64_CFLAGS
6465 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
6466 #endif
6467 #ifdef _CS_LFS64_LDFLAGS
6468 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
6469 #endif
6470 #ifdef _CS_LFS64_LIBS
6471 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
6472 #endif
6473 #ifdef _CS_LFS64_LINTFLAGS
6474 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
6475 #endif
6476 #ifdef _CS_LFS_CFLAGS
6477 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
6478 #endif
6479 #ifdef _CS_LFS_LDFLAGS
6480 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
6481 #endif
6482 #ifdef _CS_LFS_LIBS
6483 {"CS_LFS_LIBS", _CS_LFS_LIBS},
6484 #endif
6485 #ifdef _CS_LFS_LINTFLAGS
6486 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
6487 #endif
6488 #ifdef _CS_MACHINE
6489 {"CS_MACHINE", _CS_MACHINE},
6490 #endif
6491 #ifdef _CS_PATH
6492 {"CS_PATH", _CS_PATH},
6493 #endif
6494 #ifdef _CS_RELEASE
6495 {"CS_RELEASE", _CS_RELEASE},
6496 #endif
6497 #ifdef _CS_SRPC_DOMAIN
6498 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
6499 #endif
6500 #ifdef _CS_SYSNAME
6501 {"CS_SYSNAME", _CS_SYSNAME},
6502 #endif
6503 #ifdef _CS_VERSION
6504 {"CS_VERSION", _CS_VERSION},
6505 #endif
6506 #ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
6507 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
6508 #endif
6509 #ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
6510 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
6511 #endif
6512 #ifdef _CS_XBS5_ILP32_OFF32_LIBS
6513 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
6514 #endif
6515 #ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
6516 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
6517 #endif
6518 #ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
6519 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
6520 #endif
6521 #ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
6522 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
6523 #endif
6524 #ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
6525 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
6526 #endif
6527 #ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
6528 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
6529 #endif
6530 #ifdef _CS_XBS5_LP64_OFF64_CFLAGS
6531 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
6532 #endif
6533 #ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
6534 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
6535 #endif
6536 #ifdef _CS_XBS5_LP64_OFF64_LIBS
6537 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
6538 #endif
6539 #ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
6540 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
6541 #endif
6542 #ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
6543 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
6544 #endif
6545 #ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
6546 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
6547 #endif
6548 #ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
6549 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
6550 #endif
6551 #ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
6552 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
6553 #endif
6554 #ifdef _MIPS_CS_AVAIL_PROCESSORS
6555 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
6556 #endif
6557 #ifdef _MIPS_CS_BASE
6558 {"MIPS_CS_BASE", _MIPS_CS_BASE},
6559 #endif
6560 #ifdef _MIPS_CS_HOSTID
6561 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
6562 #endif
6563 #ifdef _MIPS_CS_HW_NAME
6564 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
6565 #endif
6566 #ifdef _MIPS_CS_NUM_PROCESSORS
6567 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
6568 #endif
6569 #ifdef _MIPS_CS_OSREL_MAJ
6570 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
6571 #endif
6572 #ifdef _MIPS_CS_OSREL_MIN
6573 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
6574 #endif
6575 #ifdef _MIPS_CS_OSREL_PATCH
6576 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
6577 #endif
6578 #ifdef _MIPS_CS_OS_NAME
6579 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
6580 #endif
6581 #ifdef _MIPS_CS_OS_PROVIDER
6582 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
6583 #endif
6584 #ifdef _MIPS_CS_PROCESSORS
6585 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
6586 #endif
6587 #ifdef _MIPS_CS_SERIAL
6588 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
6589 #endif
6590 #ifdef _MIPS_CS_VENDOR
6591 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
6592 #endif
6595 static int
6596 conv_confstr_confname(PyObject *arg, int *valuep)
6598 return conv_confname(arg, valuep, posix_constants_confstr,
6599 sizeof(posix_constants_confstr)
6600 / sizeof(struct constdef));
6603 PyDoc_STRVAR(posix_confstr__doc__,
6604 "confstr(name) -> string\n\n\
6605 Return a string-valued system configuration variable.");
6607 static PyObject *
6608 posix_confstr(PyObject *self, PyObject *args)
6610 PyObject *result = NULL;
6611 int name;
6612 char buffer[64];
6614 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
6615 int len = confstr(name, buffer, sizeof(buffer));
6617 errno = 0;
6618 if (len == 0) {
6619 if (errno != 0)
6620 posix_error();
6621 else
6622 result = PyString_FromString("");
6624 else {
6625 if (len >= sizeof(buffer)) {
6626 result = PyString_FromStringAndSize(NULL, len);
6627 if (result != NULL)
6628 confstr(name, PyString_AS_STRING(result), len+1);
6630 else
6631 result = PyString_FromString(buffer);
6634 return result;
6636 #endif
6639 #ifdef HAVE_SYSCONF
6640 static struct constdef posix_constants_sysconf[] = {
6641 #ifdef _SC_2_CHAR_TERM
6642 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
6643 #endif
6644 #ifdef _SC_2_C_BIND
6645 {"SC_2_C_BIND", _SC_2_C_BIND},
6646 #endif
6647 #ifdef _SC_2_C_DEV
6648 {"SC_2_C_DEV", _SC_2_C_DEV},
6649 #endif
6650 #ifdef _SC_2_C_VERSION
6651 {"SC_2_C_VERSION", _SC_2_C_VERSION},
6652 #endif
6653 #ifdef _SC_2_FORT_DEV
6654 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
6655 #endif
6656 #ifdef _SC_2_FORT_RUN
6657 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
6658 #endif
6659 #ifdef _SC_2_LOCALEDEF
6660 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
6661 #endif
6662 #ifdef _SC_2_SW_DEV
6663 {"SC_2_SW_DEV", _SC_2_SW_DEV},
6664 #endif
6665 #ifdef _SC_2_UPE
6666 {"SC_2_UPE", _SC_2_UPE},
6667 #endif
6668 #ifdef _SC_2_VERSION
6669 {"SC_2_VERSION", _SC_2_VERSION},
6670 #endif
6671 #ifdef _SC_ABI_ASYNCHRONOUS_IO
6672 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
6673 #endif
6674 #ifdef _SC_ACL
6675 {"SC_ACL", _SC_ACL},
6676 #endif
6677 #ifdef _SC_AIO_LISTIO_MAX
6678 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
6679 #endif
6680 #ifdef _SC_AIO_MAX
6681 {"SC_AIO_MAX", _SC_AIO_MAX},
6682 #endif
6683 #ifdef _SC_AIO_PRIO_DELTA_MAX
6684 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
6685 #endif
6686 #ifdef _SC_ARG_MAX
6687 {"SC_ARG_MAX", _SC_ARG_MAX},
6688 #endif
6689 #ifdef _SC_ASYNCHRONOUS_IO
6690 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
6691 #endif
6692 #ifdef _SC_ATEXIT_MAX
6693 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
6694 #endif
6695 #ifdef _SC_AUDIT
6696 {"SC_AUDIT", _SC_AUDIT},
6697 #endif
6698 #ifdef _SC_AVPHYS_PAGES
6699 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
6700 #endif
6701 #ifdef _SC_BC_BASE_MAX
6702 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
6703 #endif
6704 #ifdef _SC_BC_DIM_MAX
6705 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
6706 #endif
6707 #ifdef _SC_BC_SCALE_MAX
6708 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
6709 #endif
6710 #ifdef _SC_BC_STRING_MAX
6711 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
6712 #endif
6713 #ifdef _SC_CAP
6714 {"SC_CAP", _SC_CAP},
6715 #endif
6716 #ifdef _SC_CHARCLASS_NAME_MAX
6717 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
6718 #endif
6719 #ifdef _SC_CHAR_BIT
6720 {"SC_CHAR_BIT", _SC_CHAR_BIT},
6721 #endif
6722 #ifdef _SC_CHAR_MAX
6723 {"SC_CHAR_MAX", _SC_CHAR_MAX},
6724 #endif
6725 #ifdef _SC_CHAR_MIN
6726 {"SC_CHAR_MIN", _SC_CHAR_MIN},
6727 #endif
6728 #ifdef _SC_CHILD_MAX
6729 {"SC_CHILD_MAX", _SC_CHILD_MAX},
6730 #endif
6731 #ifdef _SC_CLK_TCK
6732 {"SC_CLK_TCK", _SC_CLK_TCK},
6733 #endif
6734 #ifdef _SC_COHER_BLKSZ
6735 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
6736 #endif
6737 #ifdef _SC_COLL_WEIGHTS_MAX
6738 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
6739 #endif
6740 #ifdef _SC_DCACHE_ASSOC
6741 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
6742 #endif
6743 #ifdef _SC_DCACHE_BLKSZ
6744 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
6745 #endif
6746 #ifdef _SC_DCACHE_LINESZ
6747 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
6748 #endif
6749 #ifdef _SC_DCACHE_SZ
6750 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
6751 #endif
6752 #ifdef _SC_DCACHE_TBLKSZ
6753 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
6754 #endif
6755 #ifdef _SC_DELAYTIMER_MAX
6756 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
6757 #endif
6758 #ifdef _SC_EQUIV_CLASS_MAX
6759 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
6760 #endif
6761 #ifdef _SC_EXPR_NEST_MAX
6762 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
6763 #endif
6764 #ifdef _SC_FSYNC
6765 {"SC_FSYNC", _SC_FSYNC},
6766 #endif
6767 #ifdef _SC_GETGR_R_SIZE_MAX
6768 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
6769 #endif
6770 #ifdef _SC_GETPW_R_SIZE_MAX
6771 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
6772 #endif
6773 #ifdef _SC_ICACHE_ASSOC
6774 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
6775 #endif
6776 #ifdef _SC_ICACHE_BLKSZ
6777 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
6778 #endif
6779 #ifdef _SC_ICACHE_LINESZ
6780 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
6781 #endif
6782 #ifdef _SC_ICACHE_SZ
6783 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
6784 #endif
6785 #ifdef _SC_INF
6786 {"SC_INF", _SC_INF},
6787 #endif
6788 #ifdef _SC_INT_MAX
6789 {"SC_INT_MAX", _SC_INT_MAX},
6790 #endif
6791 #ifdef _SC_INT_MIN
6792 {"SC_INT_MIN", _SC_INT_MIN},
6793 #endif
6794 #ifdef _SC_IOV_MAX
6795 {"SC_IOV_MAX", _SC_IOV_MAX},
6796 #endif
6797 #ifdef _SC_IP_SECOPTS
6798 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
6799 #endif
6800 #ifdef _SC_JOB_CONTROL
6801 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
6802 #endif
6803 #ifdef _SC_KERN_POINTERS
6804 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
6805 #endif
6806 #ifdef _SC_KERN_SIM
6807 {"SC_KERN_SIM", _SC_KERN_SIM},
6808 #endif
6809 #ifdef _SC_LINE_MAX
6810 {"SC_LINE_MAX", _SC_LINE_MAX},
6811 #endif
6812 #ifdef _SC_LOGIN_NAME_MAX
6813 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
6814 #endif
6815 #ifdef _SC_LOGNAME_MAX
6816 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
6817 #endif
6818 #ifdef _SC_LONG_BIT
6819 {"SC_LONG_BIT", _SC_LONG_BIT},
6820 #endif
6821 #ifdef _SC_MAC
6822 {"SC_MAC", _SC_MAC},
6823 #endif
6824 #ifdef _SC_MAPPED_FILES
6825 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
6826 #endif
6827 #ifdef _SC_MAXPID
6828 {"SC_MAXPID", _SC_MAXPID},
6829 #endif
6830 #ifdef _SC_MB_LEN_MAX
6831 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
6832 #endif
6833 #ifdef _SC_MEMLOCK
6834 {"SC_MEMLOCK", _SC_MEMLOCK},
6835 #endif
6836 #ifdef _SC_MEMLOCK_RANGE
6837 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
6838 #endif
6839 #ifdef _SC_MEMORY_PROTECTION
6840 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
6841 #endif
6842 #ifdef _SC_MESSAGE_PASSING
6843 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
6844 #endif
6845 #ifdef _SC_MMAP_FIXED_ALIGNMENT
6846 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
6847 #endif
6848 #ifdef _SC_MQ_OPEN_MAX
6849 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
6850 #endif
6851 #ifdef _SC_MQ_PRIO_MAX
6852 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
6853 #endif
6854 #ifdef _SC_NACLS_MAX
6855 {"SC_NACLS_MAX", _SC_NACLS_MAX},
6856 #endif
6857 #ifdef _SC_NGROUPS_MAX
6858 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
6859 #endif
6860 #ifdef _SC_NL_ARGMAX
6861 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
6862 #endif
6863 #ifdef _SC_NL_LANGMAX
6864 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
6865 #endif
6866 #ifdef _SC_NL_MSGMAX
6867 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
6868 #endif
6869 #ifdef _SC_NL_NMAX
6870 {"SC_NL_NMAX", _SC_NL_NMAX},
6871 #endif
6872 #ifdef _SC_NL_SETMAX
6873 {"SC_NL_SETMAX", _SC_NL_SETMAX},
6874 #endif
6875 #ifdef _SC_NL_TEXTMAX
6876 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
6877 #endif
6878 #ifdef _SC_NPROCESSORS_CONF
6879 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
6880 #endif
6881 #ifdef _SC_NPROCESSORS_ONLN
6882 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
6883 #endif
6884 #ifdef _SC_NPROC_CONF
6885 {"SC_NPROC_CONF", _SC_NPROC_CONF},
6886 #endif
6887 #ifdef _SC_NPROC_ONLN
6888 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
6889 #endif
6890 #ifdef _SC_NZERO
6891 {"SC_NZERO", _SC_NZERO},
6892 #endif
6893 #ifdef _SC_OPEN_MAX
6894 {"SC_OPEN_MAX", _SC_OPEN_MAX},
6895 #endif
6896 #ifdef _SC_PAGESIZE
6897 {"SC_PAGESIZE", _SC_PAGESIZE},
6898 #endif
6899 #ifdef _SC_PAGE_SIZE
6900 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
6901 #endif
6902 #ifdef _SC_PASS_MAX
6903 {"SC_PASS_MAX", _SC_PASS_MAX},
6904 #endif
6905 #ifdef _SC_PHYS_PAGES
6906 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
6907 #endif
6908 #ifdef _SC_PII
6909 {"SC_PII", _SC_PII},
6910 #endif
6911 #ifdef _SC_PII_INTERNET
6912 {"SC_PII_INTERNET", _SC_PII_INTERNET},
6913 #endif
6914 #ifdef _SC_PII_INTERNET_DGRAM
6915 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
6916 #endif
6917 #ifdef _SC_PII_INTERNET_STREAM
6918 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
6919 #endif
6920 #ifdef _SC_PII_OSI
6921 {"SC_PII_OSI", _SC_PII_OSI},
6922 #endif
6923 #ifdef _SC_PII_OSI_CLTS
6924 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
6925 #endif
6926 #ifdef _SC_PII_OSI_COTS
6927 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
6928 #endif
6929 #ifdef _SC_PII_OSI_M
6930 {"SC_PII_OSI_M", _SC_PII_OSI_M},
6931 #endif
6932 #ifdef _SC_PII_SOCKET
6933 {"SC_PII_SOCKET", _SC_PII_SOCKET},
6934 #endif
6935 #ifdef _SC_PII_XTI
6936 {"SC_PII_XTI", _SC_PII_XTI},
6937 #endif
6938 #ifdef _SC_POLL
6939 {"SC_POLL", _SC_POLL},
6940 #endif
6941 #ifdef _SC_PRIORITIZED_IO
6942 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
6943 #endif
6944 #ifdef _SC_PRIORITY_SCHEDULING
6945 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
6946 #endif
6947 #ifdef _SC_REALTIME_SIGNALS
6948 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
6949 #endif
6950 #ifdef _SC_RE_DUP_MAX
6951 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
6952 #endif
6953 #ifdef _SC_RTSIG_MAX
6954 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
6955 #endif
6956 #ifdef _SC_SAVED_IDS
6957 {"SC_SAVED_IDS", _SC_SAVED_IDS},
6958 #endif
6959 #ifdef _SC_SCHAR_MAX
6960 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
6961 #endif
6962 #ifdef _SC_SCHAR_MIN
6963 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
6964 #endif
6965 #ifdef _SC_SELECT
6966 {"SC_SELECT", _SC_SELECT},
6967 #endif
6968 #ifdef _SC_SEMAPHORES
6969 {"SC_SEMAPHORES", _SC_SEMAPHORES},
6970 #endif
6971 #ifdef _SC_SEM_NSEMS_MAX
6972 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
6973 #endif
6974 #ifdef _SC_SEM_VALUE_MAX
6975 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
6976 #endif
6977 #ifdef _SC_SHARED_MEMORY_OBJECTS
6978 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
6979 #endif
6980 #ifdef _SC_SHRT_MAX
6981 {"SC_SHRT_MAX", _SC_SHRT_MAX},
6982 #endif
6983 #ifdef _SC_SHRT_MIN
6984 {"SC_SHRT_MIN", _SC_SHRT_MIN},
6985 #endif
6986 #ifdef _SC_SIGQUEUE_MAX
6987 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
6988 #endif
6989 #ifdef _SC_SIGRT_MAX
6990 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
6991 #endif
6992 #ifdef _SC_SIGRT_MIN
6993 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
6994 #endif
6995 #ifdef _SC_SOFTPOWER
6996 {"SC_SOFTPOWER", _SC_SOFTPOWER},
6997 #endif
6998 #ifdef _SC_SPLIT_CACHE
6999 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
7000 #endif
7001 #ifdef _SC_SSIZE_MAX
7002 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
7003 #endif
7004 #ifdef _SC_STACK_PROT
7005 {"SC_STACK_PROT", _SC_STACK_PROT},
7006 #endif
7007 #ifdef _SC_STREAM_MAX
7008 {"SC_STREAM_MAX", _SC_STREAM_MAX},
7009 #endif
7010 #ifdef _SC_SYNCHRONIZED_IO
7011 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
7012 #endif
7013 #ifdef _SC_THREADS
7014 {"SC_THREADS", _SC_THREADS},
7015 #endif
7016 #ifdef _SC_THREAD_ATTR_STACKADDR
7017 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
7018 #endif
7019 #ifdef _SC_THREAD_ATTR_STACKSIZE
7020 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
7021 #endif
7022 #ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
7023 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
7024 #endif
7025 #ifdef _SC_THREAD_KEYS_MAX
7026 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
7027 #endif
7028 #ifdef _SC_THREAD_PRIORITY_SCHEDULING
7029 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
7030 #endif
7031 #ifdef _SC_THREAD_PRIO_INHERIT
7032 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
7033 #endif
7034 #ifdef _SC_THREAD_PRIO_PROTECT
7035 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
7036 #endif
7037 #ifdef _SC_THREAD_PROCESS_SHARED
7038 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
7039 #endif
7040 #ifdef _SC_THREAD_SAFE_FUNCTIONS
7041 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
7042 #endif
7043 #ifdef _SC_THREAD_STACK_MIN
7044 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
7045 #endif
7046 #ifdef _SC_THREAD_THREADS_MAX
7047 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
7048 #endif
7049 #ifdef _SC_TIMERS
7050 {"SC_TIMERS", _SC_TIMERS},
7051 #endif
7052 #ifdef _SC_TIMER_MAX
7053 {"SC_TIMER_MAX", _SC_TIMER_MAX},
7054 #endif
7055 #ifdef _SC_TTY_NAME_MAX
7056 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
7057 #endif
7058 #ifdef _SC_TZNAME_MAX
7059 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
7060 #endif
7061 #ifdef _SC_T_IOV_MAX
7062 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
7063 #endif
7064 #ifdef _SC_UCHAR_MAX
7065 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
7066 #endif
7067 #ifdef _SC_UINT_MAX
7068 {"SC_UINT_MAX", _SC_UINT_MAX},
7069 #endif
7070 #ifdef _SC_UIO_MAXIOV
7071 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
7072 #endif
7073 #ifdef _SC_ULONG_MAX
7074 {"SC_ULONG_MAX", _SC_ULONG_MAX},
7075 #endif
7076 #ifdef _SC_USHRT_MAX
7077 {"SC_USHRT_MAX", _SC_USHRT_MAX},
7078 #endif
7079 #ifdef _SC_VERSION
7080 {"SC_VERSION", _SC_VERSION},
7081 #endif
7082 #ifdef _SC_WORD_BIT
7083 {"SC_WORD_BIT", _SC_WORD_BIT},
7084 #endif
7085 #ifdef _SC_XBS5_ILP32_OFF32
7086 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
7087 #endif
7088 #ifdef _SC_XBS5_ILP32_OFFBIG
7089 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
7090 #endif
7091 #ifdef _SC_XBS5_LP64_OFF64
7092 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
7093 #endif
7094 #ifdef _SC_XBS5_LPBIG_OFFBIG
7095 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
7096 #endif
7097 #ifdef _SC_XOPEN_CRYPT
7098 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
7099 #endif
7100 #ifdef _SC_XOPEN_ENH_I18N
7101 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
7102 #endif
7103 #ifdef _SC_XOPEN_LEGACY
7104 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
7105 #endif
7106 #ifdef _SC_XOPEN_REALTIME
7107 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
7108 #endif
7109 #ifdef _SC_XOPEN_REALTIME_THREADS
7110 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
7111 #endif
7112 #ifdef _SC_XOPEN_SHM
7113 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
7114 #endif
7115 #ifdef _SC_XOPEN_UNIX
7116 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
7117 #endif
7118 #ifdef _SC_XOPEN_VERSION
7119 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
7120 #endif
7121 #ifdef _SC_XOPEN_XCU_VERSION
7122 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
7123 #endif
7124 #ifdef _SC_XOPEN_XPG2
7125 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
7126 #endif
7127 #ifdef _SC_XOPEN_XPG3
7128 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
7129 #endif
7130 #ifdef _SC_XOPEN_XPG4
7131 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
7132 #endif
7135 static int
7136 conv_sysconf_confname(PyObject *arg, int *valuep)
7138 return conv_confname(arg, valuep, posix_constants_sysconf,
7139 sizeof(posix_constants_sysconf)
7140 / sizeof(struct constdef));
7143 PyDoc_STRVAR(posix_sysconf__doc__,
7144 "sysconf(name) -> integer\n\n\
7145 Return an integer-valued system configuration variable.");
7147 static PyObject *
7148 posix_sysconf(PyObject *self, PyObject *args)
7150 PyObject *result = NULL;
7151 int name;
7153 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
7154 int value;
7156 errno = 0;
7157 value = sysconf(name);
7158 if (value == -1 && errno != 0)
7159 posix_error();
7160 else
7161 result = PyInt_FromLong(value);
7163 return result;
7165 #endif
7168 /* This code is used to ensure that the tables of configuration value names
7169 * are in sorted order as required by conv_confname(), and also to build the
7170 * the exported dictionaries that are used to publish information about the
7171 * names available on the host platform.
7173 * Sorting the table at runtime ensures that the table is properly ordered
7174 * when used, even for platforms we're not able to test on. It also makes
7175 * it easier to add additional entries to the tables.
7178 static int
7179 cmp_constdefs(const void *v1, const void *v2)
7181 const struct constdef *c1 =
7182 (const struct constdef *) v1;
7183 const struct constdef *c2 =
7184 (const struct constdef *) v2;
7186 return strcmp(c1->name, c2->name);
7189 static int
7190 setup_confname_table(struct constdef *table, size_t tablesize,
7191 char *tablename, PyObject *module)
7193 PyObject *d = NULL;
7194 size_t i;
7196 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
7197 d = PyDict_New();
7198 if (d == NULL)
7199 return -1;
7201 for (i=0; i < tablesize; ++i) {
7202 PyObject *o = PyInt_FromLong(table[i].value);
7203 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
7204 Py_XDECREF(o);
7205 Py_DECREF(d);
7206 return -1;
7208 Py_DECREF(o);
7210 return PyModule_AddObject(module, tablename, d);
7213 /* Return -1 on failure, 0 on success. */
7214 static int
7215 setup_confname_tables(PyObject *module)
7217 #if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
7218 if (setup_confname_table(posix_constants_pathconf,
7219 sizeof(posix_constants_pathconf)
7220 / sizeof(struct constdef),
7221 "pathconf_names", module))
7222 return -1;
7223 #endif
7224 #ifdef HAVE_CONFSTR
7225 if (setup_confname_table(posix_constants_confstr,
7226 sizeof(posix_constants_confstr)
7227 / sizeof(struct constdef),
7228 "confstr_names", module))
7229 return -1;
7230 #endif
7231 #ifdef HAVE_SYSCONF
7232 if (setup_confname_table(posix_constants_sysconf,
7233 sizeof(posix_constants_sysconf)
7234 / sizeof(struct constdef),
7235 "sysconf_names", module))
7236 return -1;
7237 #endif
7238 return 0;
7242 PyDoc_STRVAR(posix_abort__doc__,
7243 "abort() -> does not return!\n\n\
7244 Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
7245 in the hardest way possible on the hosting operating system.");
7247 static PyObject *
7248 posix_abort(PyObject *self, PyObject *noargs)
7250 abort();
7251 /*NOTREACHED*/
7252 Py_FatalError("abort() called from Python code didn't abort!");
7253 return NULL;
7256 #ifdef MS_WINDOWS
7257 PyDoc_STRVAR(win32_startfile__doc__,
7258 "startfile(filepath) - Start a file with its associated application.\n\
7260 This acts like double-clicking the file in Explorer, or giving the file\n\
7261 name as an argument to the DOS \"start\" command: the file is opened\n\
7262 with whatever application (if any) its extension is associated.\n\
7264 startfile returns as soon as the associated application is launched.\n\
7265 There is no option to wait for the application to close, and no way\n\
7266 to retrieve the application's exit status.\n\
7268 The filepath is relative to the current directory. If you want to use\n\
7269 an absolute path, make sure the first character is not a slash (\"/\");\n\
7270 the underlying Win32 ShellExecute function doesn't work if it is.");
7272 static PyObject *
7273 win32_startfile(PyObject *self, PyObject *args)
7275 char *filepath;
7276 HINSTANCE rc;
7277 if (!PyArg_ParseTuple(args, "et:startfile",
7278 Py_FileSystemDefaultEncoding, &filepath))
7279 return NULL;
7280 Py_BEGIN_ALLOW_THREADS
7281 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
7282 Py_END_ALLOW_THREADS
7283 if (rc <= (HINSTANCE)32) {
7284 PyObject *errval = win32_error("startfile", filepath);
7285 PyMem_Free(filepath);
7286 return errval;
7288 PyMem_Free(filepath);
7289 Py_INCREF(Py_None);
7290 return Py_None;
7292 #endif
7294 #ifdef HAVE_GETLOADAVG
7295 PyDoc_STRVAR(posix_getloadavg__doc__,
7296 "getloadavg() -> (float, float, float)\n\n\
7297 Return the number of processes in the system run queue averaged over\n\
7298 the last 1, 5, and 15 minutes or raises OSError if the load average\n\
7299 was unobtainable");
7301 static PyObject *
7302 posix_getloadavg(PyObject *self, PyObject *noargs)
7304 double loadavg[3];
7305 if (getloadavg(loadavg, 3)!=3) {
7306 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
7307 return NULL;
7308 } else
7309 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
7311 #endif
7313 #ifdef MS_WINDOWS
7315 PyDoc_STRVAR(win32_urandom__doc__,
7316 "urandom(n) -> str\n\n\
7317 Return a string of n random bytes suitable for cryptographic use.");
7319 typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
7320 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
7321 DWORD dwFlags );
7322 typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
7323 BYTE *pbBuffer );
7325 static CRYPTGENRANDOM pCryptGenRandom = NULL;
7326 static HCRYPTPROV hCryptProv = 0;
7328 static PyObject*
7329 win32_urandom(PyObject *self, PyObject *args)
7331 int howMany;
7332 PyObject* result;
7334 /* Read arguments */
7335 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
7336 return NULL;
7337 if (howMany < 0)
7338 return PyErr_Format(PyExc_ValueError,
7339 "negative argument not allowed");
7341 if (hCryptProv == 0) {
7342 HINSTANCE hAdvAPI32 = NULL;
7343 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
7345 /* Obtain handle to the DLL containing CryptoAPI
7346 This should not fail */
7347 hAdvAPI32 = GetModuleHandle("advapi32.dll");
7348 if(hAdvAPI32 == NULL)
7349 return win32_error("GetModuleHandle", NULL);
7351 /* Obtain pointers to the CryptoAPI functions
7352 This will fail on some early versions of Win95 */
7353 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
7354 hAdvAPI32,
7355 "CryptAcquireContextA");
7356 if (pCryptAcquireContext == NULL)
7357 return PyErr_Format(PyExc_NotImplementedError,
7358 "CryptAcquireContextA not found");
7360 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
7361 hAdvAPI32, "CryptGenRandom");
7362 if (pCryptAcquireContext == NULL)
7363 return PyErr_Format(PyExc_NotImplementedError,
7364 "CryptGenRandom not found");
7366 /* Acquire context */
7367 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
7368 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
7369 return win32_error("CryptAcquireContext", NULL);
7372 /* Allocate bytes */
7373 result = PyString_FromStringAndSize(NULL, howMany);
7374 if (result != NULL) {
7375 /* Get random data */
7376 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
7377 PyString_AS_STRING(result))) {
7378 Py_DECREF(result);
7379 return win32_error("CryptGenRandom", NULL);
7382 return result;
7384 #endif
7386 static PyMethodDef posix_methods[] = {
7387 {"access", posix_access, METH_VARARGS, posix_access__doc__},
7388 #ifdef HAVE_TTYNAME
7389 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
7390 #endif
7391 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
7392 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
7393 #ifdef HAVE_CHOWN
7394 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
7395 #endif /* HAVE_CHOWN */
7396 #ifdef HAVE_LCHOWN
7397 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
7398 #endif /* HAVE_LCHOWN */
7399 #ifdef HAVE_CHROOT
7400 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
7401 #endif
7402 #ifdef HAVE_CTERMID
7403 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
7404 #endif
7405 #ifdef HAVE_GETCWD
7406 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
7407 #ifdef Py_USING_UNICODE
7408 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
7409 #endif
7410 #endif
7411 #ifdef HAVE_LINK
7412 {"link", posix_link, METH_VARARGS, posix_link__doc__},
7413 #endif /* HAVE_LINK */
7414 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
7415 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
7416 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
7417 #ifdef HAVE_NICE
7418 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
7419 #endif /* HAVE_NICE */
7420 #ifdef HAVE_READLINK
7421 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
7422 #endif /* HAVE_READLINK */
7423 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
7424 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
7425 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
7426 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
7427 #ifdef HAVE_SYMLINK
7428 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
7429 #endif /* HAVE_SYMLINK */
7430 #ifdef HAVE_SYSTEM
7431 {"system", posix_system, METH_VARARGS, posix_system__doc__},
7432 #endif
7433 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
7434 #ifdef HAVE_UNAME
7435 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
7436 #endif /* HAVE_UNAME */
7437 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
7438 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
7439 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
7440 #ifdef HAVE_TIMES
7441 {"times", posix_times, METH_NOARGS, posix_times__doc__},
7442 #endif /* HAVE_TIMES */
7443 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
7444 #ifdef HAVE_EXECV
7445 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
7446 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
7447 #endif /* HAVE_EXECV */
7448 #ifdef HAVE_SPAWNV
7449 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
7450 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
7451 #if defined(PYOS_OS2)
7452 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
7453 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
7454 #endif /* PYOS_OS2 */
7455 #endif /* HAVE_SPAWNV */
7456 #ifdef HAVE_FORK1
7457 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
7458 #endif /* HAVE_FORK1 */
7459 #ifdef HAVE_FORK
7460 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
7461 #endif /* HAVE_FORK */
7462 #if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
7463 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
7464 #endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
7465 #ifdef HAVE_FORKPTY
7466 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
7467 #endif /* HAVE_FORKPTY */
7468 #ifdef HAVE_GETEGID
7469 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
7470 #endif /* HAVE_GETEGID */
7471 #ifdef HAVE_GETEUID
7472 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
7473 #endif /* HAVE_GETEUID */
7474 #ifdef HAVE_GETGID
7475 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
7476 #endif /* HAVE_GETGID */
7477 #ifdef HAVE_GETGROUPS
7478 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
7479 #endif
7480 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
7481 #ifdef HAVE_GETPGRP
7482 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
7483 #endif /* HAVE_GETPGRP */
7484 #ifdef HAVE_GETPPID
7485 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
7486 #endif /* HAVE_GETPPID */
7487 #ifdef HAVE_GETUID
7488 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
7489 #endif /* HAVE_GETUID */
7490 #ifdef HAVE_GETLOGIN
7491 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
7492 #endif
7493 #ifdef HAVE_KILL
7494 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
7495 #endif /* HAVE_KILL */
7496 #ifdef HAVE_KILLPG
7497 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
7498 #endif /* HAVE_KILLPG */
7499 #ifdef HAVE_PLOCK
7500 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
7501 #endif /* HAVE_PLOCK */
7502 #ifdef HAVE_POPEN
7503 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
7504 #ifdef MS_WINDOWS
7505 {"popen2", win32_popen2, METH_VARARGS},
7506 {"popen3", win32_popen3, METH_VARARGS},
7507 {"popen4", win32_popen4, METH_VARARGS},
7508 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
7509 #else
7510 #if defined(PYOS_OS2) && defined(PYCC_GCC)
7511 {"popen2", os2emx_popen2, METH_VARARGS},
7512 {"popen3", os2emx_popen3, METH_VARARGS},
7513 {"popen4", os2emx_popen4, METH_VARARGS},
7514 #endif
7515 #endif
7516 #endif /* HAVE_POPEN */
7517 #ifdef HAVE_SETUID
7518 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
7519 #endif /* HAVE_SETUID */
7520 #ifdef HAVE_SETEUID
7521 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
7522 #endif /* HAVE_SETEUID */
7523 #ifdef HAVE_SETEGID
7524 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
7525 #endif /* HAVE_SETEGID */
7526 #ifdef HAVE_SETREUID
7527 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
7528 #endif /* HAVE_SETREUID */
7529 #ifdef HAVE_SETREGID
7530 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
7531 #endif /* HAVE_SETREGID */
7532 #ifdef HAVE_SETGID
7533 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
7534 #endif /* HAVE_SETGID */
7535 #ifdef HAVE_SETGROUPS
7536 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
7537 #endif /* HAVE_SETGROUPS */
7538 #ifdef HAVE_GETPGID
7539 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
7540 #endif /* HAVE_GETPGID */
7541 #ifdef HAVE_SETPGRP
7542 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
7543 #endif /* HAVE_SETPGRP */
7544 #ifdef HAVE_WAIT
7545 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
7546 #endif /* HAVE_WAIT */
7547 #if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
7548 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
7549 #endif /* HAVE_WAITPID */
7550 #ifdef HAVE_GETSID
7551 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
7552 #endif /* HAVE_GETSID */
7553 #ifdef HAVE_SETSID
7554 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
7555 #endif /* HAVE_SETSID */
7556 #ifdef HAVE_SETPGID
7557 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
7558 #endif /* HAVE_SETPGID */
7559 #ifdef HAVE_TCGETPGRP
7560 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
7561 #endif /* HAVE_TCGETPGRP */
7562 #ifdef HAVE_TCSETPGRP
7563 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
7564 #endif /* HAVE_TCSETPGRP */
7565 {"open", posix_open, METH_VARARGS, posix_open__doc__},
7566 {"close", posix_close, METH_VARARGS, posix_close__doc__},
7567 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
7568 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
7569 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
7570 {"read", posix_read, METH_VARARGS, posix_read__doc__},
7571 {"write", posix_write, METH_VARARGS, posix_write__doc__},
7572 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
7573 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
7574 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
7575 #ifdef HAVE_PIPE
7576 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
7577 #endif
7578 #ifdef HAVE_MKFIFO
7579 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
7580 #endif
7581 #if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
7582 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
7583 #endif
7584 #ifdef HAVE_DEVICE_MACROS
7585 {"major", posix_major, METH_VARARGS, posix_major__doc__},
7586 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
7587 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
7588 #endif
7589 #ifdef HAVE_FTRUNCATE
7590 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
7591 #endif
7592 #ifdef HAVE_PUTENV
7593 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
7594 #endif
7595 #ifdef HAVE_UNSETENV
7596 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
7597 #endif
7598 #ifdef HAVE_STRERROR
7599 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
7600 #endif
7601 #ifdef HAVE_FCHDIR
7602 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
7603 #endif
7604 #ifdef HAVE_FSYNC
7605 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
7606 #endif
7607 #ifdef HAVE_FDATASYNC
7608 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
7609 #endif
7610 #ifdef HAVE_SYS_WAIT_H
7611 #ifdef WCOREDUMP
7612 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
7613 #endif /* WCOREDUMP */
7614 #ifdef WIFCONTINUED
7615 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
7616 #endif /* WIFCONTINUED */
7617 #ifdef WIFSTOPPED
7618 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
7619 #endif /* WIFSTOPPED */
7620 #ifdef WIFSIGNALED
7621 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
7622 #endif /* WIFSIGNALED */
7623 #ifdef WIFEXITED
7624 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
7625 #endif /* WIFEXITED */
7626 #ifdef WEXITSTATUS
7627 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
7628 #endif /* WEXITSTATUS */
7629 #ifdef WTERMSIG
7630 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
7631 #endif /* WTERMSIG */
7632 #ifdef WSTOPSIG
7633 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
7634 #endif /* WSTOPSIG */
7635 #endif /* HAVE_SYS_WAIT_H */
7636 #ifdef HAVE_FSTATVFS
7637 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
7638 #endif
7639 #ifdef HAVE_STATVFS
7640 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
7641 #endif
7642 #ifdef HAVE_TMPFILE
7643 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
7644 #endif
7645 #ifdef HAVE_TEMPNAM
7646 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
7647 #endif
7648 #ifdef HAVE_TMPNAM
7649 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
7650 #endif
7651 #ifdef HAVE_CONFSTR
7652 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
7653 #endif
7654 #ifdef HAVE_SYSCONF
7655 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
7656 #endif
7657 #ifdef HAVE_FPATHCONF
7658 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
7659 #endif
7660 #ifdef HAVE_PATHCONF
7661 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
7662 #endif
7663 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
7664 #ifdef MS_WINDOWS
7665 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
7666 #endif
7667 #ifdef HAVE_GETLOADAVG
7668 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
7669 #endif
7670 #ifdef MS_WINDOWS
7671 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
7672 #endif
7673 {NULL, NULL} /* Sentinel */
7677 static int
7678 ins(PyObject *module, char *symbol, long value)
7680 return PyModule_AddIntConstant(module, symbol, value);
7683 #if defined(PYOS_OS2)
7684 /* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
7685 static int insertvalues(PyObject *module)
7687 APIRET rc;
7688 ULONG values[QSV_MAX+1];
7689 PyObject *v;
7690 char *ver, tmp[50];
7692 Py_BEGIN_ALLOW_THREADS
7693 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
7694 Py_END_ALLOW_THREADS
7696 if (rc != NO_ERROR) {
7697 os2_error(rc);
7698 return -1;
7701 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
7702 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
7703 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
7704 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
7705 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
7706 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
7707 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
7709 switch (values[QSV_VERSION_MINOR]) {
7710 case 0: ver = "2.00"; break;
7711 case 10: ver = "2.10"; break;
7712 case 11: ver = "2.11"; break;
7713 case 30: ver = "3.00"; break;
7714 case 40: ver = "4.00"; break;
7715 case 50: ver = "5.00"; break;
7716 default:
7717 PyOS_snprintf(tmp, sizeof(tmp),
7718 "%d-%d", values[QSV_VERSION_MAJOR],
7719 values[QSV_VERSION_MINOR]);
7720 ver = &tmp[0];
7723 /* Add Indicator of the Version of the Operating System */
7724 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
7725 return -1;
7727 /* Add Indicator of Which Drive was Used to Boot the System */
7728 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
7729 tmp[1] = ':';
7730 tmp[2] = '\0';
7732 return PyModule_AddStringConstant(module, "bootdrive", tmp);
7734 #endif
7736 static int
7737 all_ins(PyObject *d)
7739 #ifdef F_OK
7740 if (ins(d, "F_OK", (long)F_OK)) return -1;
7741 #endif
7742 #ifdef R_OK
7743 if (ins(d, "R_OK", (long)R_OK)) return -1;
7744 #endif
7745 #ifdef W_OK
7746 if (ins(d, "W_OK", (long)W_OK)) return -1;
7747 #endif
7748 #ifdef X_OK
7749 if (ins(d, "X_OK", (long)X_OK)) return -1;
7750 #endif
7751 #ifdef NGROUPS_MAX
7752 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
7753 #endif
7754 #ifdef TMP_MAX
7755 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
7756 #endif
7757 #ifdef WCONTINUED
7758 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
7759 #endif
7760 #ifdef WNOHANG
7761 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
7762 #endif
7763 #ifdef WUNTRACED
7764 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
7765 #endif
7766 #ifdef O_RDONLY
7767 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
7768 #endif
7769 #ifdef O_WRONLY
7770 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
7771 #endif
7772 #ifdef O_RDWR
7773 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
7774 #endif
7775 #ifdef O_NDELAY
7776 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
7777 #endif
7778 #ifdef O_NONBLOCK
7779 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
7780 #endif
7781 #ifdef O_APPEND
7782 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
7783 #endif
7784 #ifdef O_DSYNC
7785 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
7786 #endif
7787 #ifdef O_RSYNC
7788 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
7789 #endif
7790 #ifdef O_SYNC
7791 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
7792 #endif
7793 #ifdef O_NOCTTY
7794 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
7795 #endif
7796 #ifdef O_CREAT
7797 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
7798 #endif
7799 #ifdef O_EXCL
7800 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
7801 #endif
7802 #ifdef O_TRUNC
7803 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
7804 #endif
7805 #ifdef O_BINARY
7806 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
7807 #endif
7808 #ifdef O_TEXT
7809 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
7810 #endif
7811 #ifdef O_LARGEFILE
7812 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
7813 #endif
7814 #ifdef O_SHLOCK
7815 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
7816 #endif
7817 #ifdef O_EXLOCK
7818 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
7819 #endif
7821 /* MS Windows */
7822 #ifdef O_NOINHERIT
7823 /* Don't inherit in child processes. */
7824 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
7825 #endif
7826 #ifdef _O_SHORT_LIVED
7827 /* Optimize for short life (keep in memory). */
7828 /* MS forgot to define this one with a non-underscore form too. */
7829 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
7830 #endif
7831 #ifdef O_TEMPORARY
7832 /* Automatically delete when last handle is closed. */
7833 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
7834 #endif
7835 #ifdef O_RANDOM
7836 /* Optimize for random access. */
7837 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
7838 #endif
7839 #ifdef O_SEQUENTIAL
7840 /* Optimize for sequential access. */
7841 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
7842 #endif
7844 /* GNU extensions. */
7845 #ifdef O_DIRECT
7846 /* Direct disk access. */
7847 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
7848 #endif
7849 #ifdef O_DIRECTORY
7850 /* Must be a directory. */
7851 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
7852 #endif
7853 #ifdef O_NOFOLLOW
7854 /* Do not follow links. */
7855 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
7856 #endif
7858 /* These come from sysexits.h */
7859 #ifdef EX_OK
7860 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
7861 #endif /* EX_OK */
7862 #ifdef EX_USAGE
7863 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
7864 #endif /* EX_USAGE */
7865 #ifdef EX_DATAERR
7866 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
7867 #endif /* EX_DATAERR */
7868 #ifdef EX_NOINPUT
7869 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
7870 #endif /* EX_NOINPUT */
7871 #ifdef EX_NOUSER
7872 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
7873 #endif /* EX_NOUSER */
7874 #ifdef EX_NOHOST
7875 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
7876 #endif /* EX_NOHOST */
7877 #ifdef EX_UNAVAILABLE
7878 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
7879 #endif /* EX_UNAVAILABLE */
7880 #ifdef EX_SOFTWARE
7881 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
7882 #endif /* EX_SOFTWARE */
7883 #ifdef EX_OSERR
7884 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
7885 #endif /* EX_OSERR */
7886 #ifdef EX_OSFILE
7887 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
7888 #endif /* EX_OSFILE */
7889 #ifdef EX_CANTCREAT
7890 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
7891 #endif /* EX_CANTCREAT */
7892 #ifdef EX_IOERR
7893 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
7894 #endif /* EX_IOERR */
7895 #ifdef EX_TEMPFAIL
7896 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
7897 #endif /* EX_TEMPFAIL */
7898 #ifdef EX_PROTOCOL
7899 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
7900 #endif /* EX_PROTOCOL */
7901 #ifdef EX_NOPERM
7902 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
7903 #endif /* EX_NOPERM */
7904 #ifdef EX_CONFIG
7905 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
7906 #endif /* EX_CONFIG */
7907 #ifdef EX_NOTFOUND
7908 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
7909 #endif /* EX_NOTFOUND */
7911 #ifdef HAVE_SPAWNV
7912 #if defined(PYOS_OS2) && defined(PYCC_GCC)
7913 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
7914 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
7915 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
7916 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
7917 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
7918 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
7919 if (ins(d, "P_PM", (long)P_PM)) return -1;
7920 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
7921 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
7922 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
7923 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
7924 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
7925 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
7926 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
7927 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
7928 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
7929 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
7930 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
7931 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
7932 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
7933 #else
7934 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
7935 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
7936 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
7937 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
7938 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
7939 #endif
7940 #endif
7942 #if defined(PYOS_OS2)
7943 if (insertvalues(d)) return -1;
7944 #endif
7945 return 0;
7949 #if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
7950 #define INITFUNC initnt
7951 #define MODNAME "nt"
7953 #elif defined(PYOS_OS2)
7954 #define INITFUNC initos2
7955 #define MODNAME "os2"
7957 #else
7958 #define INITFUNC initposix
7959 #define MODNAME "posix"
7960 #endif
7962 PyMODINIT_FUNC
7963 INITFUNC(void)
7965 PyObject *m, *v;
7967 m = Py_InitModule3(MODNAME,
7968 posix_methods,
7969 posix__doc__);
7971 /* Initialize environ dictionary */
7972 v = convertenviron();
7973 Py_XINCREF(v);
7974 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
7975 return;
7976 Py_DECREF(v);
7978 if (all_ins(m))
7979 return;
7981 if (setup_confname_tables(m))
7982 return;
7984 Py_INCREF(PyExc_OSError);
7985 PyModule_AddObject(m, "error", PyExc_OSError);
7987 #ifdef HAVE_PUTENV
7988 if (posix_putenv_garbage == NULL)
7989 posix_putenv_garbage = PyDict_New();
7990 #endif
7992 stat_result_desc.name = MODNAME ".stat_result";
7993 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
7994 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
7995 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
7996 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
7997 structseq_new = StatResultType.tp_new;
7998 StatResultType.tp_new = statresult_new;
7999 Py_INCREF((PyObject*) &StatResultType);
8000 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
8002 statvfs_result_desc.name = MODNAME ".statvfs_result";
8003 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
8004 Py_INCREF((PyObject*) &StatVFSResultType);
8005 PyModule_AddObject(m, "statvfs_result",
8006 (PyObject*) &StatVFSResultType);