Added information on function name added to LogRecord, and the 'extra' keyword parameter.
[python.git] / Modules / posixmodule.c
blobba7ea7058eef65e3e910416ff31b0be1191bd4cc
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 win32_stat
281 # define FSTAT win32_fstat
282 # define STRUCT_STAT struct win32_stat
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 #ifdef MS_WINDOWS
672 /* The CRT of Windows has a number of flaws wrt. its stat() implementation:
673 - time stamps are restricted to second resolution
674 - file modification times suffer from forth-and-back conversions between
675 UTC and local time
676 Therefore, we implement our own stat, based on the Win32 API directly.
678 #define HAVE_STAT_NSEC 1
680 struct win32_stat{
681 int st_dev;
682 __int64 st_ino;
683 unsigned short st_mode;
684 int st_nlink;
685 int st_uid;
686 int st_gid;
687 int st_rdev;
688 __int64 st_size;
689 int st_atime;
690 int st_atime_nsec;
691 int st_mtime;
692 int st_mtime_nsec;
693 int st_ctime;
694 int st_ctime_nsec;
697 static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
699 static void
700 FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, int *time_out, int* nsec_out)
702 /* XXX endianness */
703 __int64 in = *(__int64*)in_ptr;
704 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
705 /* XXX Win32 supports time stamps past 2038; we currently don't */
706 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, int);
709 /* Below, we *know* that ugo+r is 0444 */
710 #if _S_IREAD != 0400
711 #error Unsupported C library
712 #endif
713 static int
714 attributes_to_mode(DWORD attr)
716 int m = 0;
717 if (attr & FILE_ATTRIBUTE_DIRECTORY)
718 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
719 else
720 m |= _S_IFREG;
721 if (attr & FILE_ATTRIBUTE_READONLY)
722 m |= 0444;
723 else
724 m |= 0666;
725 return m;
728 static int
729 attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *result)
731 memset(result, 0, sizeof(*result));
732 result->st_mode = attributes_to_mode(info->dwFileAttributes);
733 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
734 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
735 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
736 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
738 return 0;
741 static int
742 win32_stat(const char* path, struct win32_stat *result)
744 WIN32_FILE_ATTRIBUTE_DATA info;
745 int code;
746 char *dot;
747 /* XXX not supported on Win95 and NT 3.x */
748 if (!GetFileAttributesExA(path, GetFileExInfoStandard, &info)) {
749 /* Protocol violation: we explicitly clear errno, instead of
750 setting it to a POSIX error. Callers should use GetLastError. */
751 errno = 0;
752 return -1;
754 code = attribute_data_to_stat(&info, result);
755 if (code != 0)
756 return code;
757 /* Set S_IFEXEC if it is an .exe, .bat, ... */
758 dot = strrchr(path, '.');
759 if (dot) {
760 if (stricmp(dot, ".bat") == 0 ||
761 stricmp(dot, ".cmd") == 0 ||
762 stricmp(dot, ".exe") == 0 ||
763 stricmp(dot, ".com") == 0)
764 result->st_mode |= 0111;
766 return code;
769 static int
770 win32_wstat(const wchar_t* path, struct win32_stat *result)
772 int code;
773 const wchar_t *dot;
774 WIN32_FILE_ATTRIBUTE_DATA info;
775 /* XXX not supported on Win95 and NT 3.x */
776 if (!GetFileAttributesExW(path, GetFileExInfoStandard, &info)) {
777 /* Protocol violation: we explicitly clear errno, instead of
778 setting it to a POSIX error. Callers should use GetLastError. */
779 errno = 0;
780 return -1;
782 code = attribute_data_to_stat(&info, result);
783 if (code < 0)
784 return code;
785 /* Set IFEXEC if it is an .exe, .bat, ... */
786 dot = wcsrchr(path, '.');
787 if (dot) {
788 if (_wcsicmp(dot, L".bat") == 0 ||
789 _wcsicmp(dot, L".cmd") == 0 ||
790 _wcsicmp(dot, L".exe") == 0 ||
791 _wcsicmp(dot, L".com") == 0)
792 result->st_mode |= 0111;
794 return code;
797 static int
798 win32_fstat(int file_number, struct win32_stat *result)
800 BY_HANDLE_FILE_INFORMATION info;
801 HANDLE h;
802 int type;
804 h = (HANDLE)_get_osfhandle(file_number);
806 /* Protocol violation: we explicitly clear errno, instead of
807 setting it to a POSIX error. Callers should use GetLastError. */
808 errno = 0;
810 if (h == INVALID_HANDLE_VALUE) {
811 /* This is really a C library error (invalid file handle).
812 We set the Win32 error to the closes one matching. */
813 SetLastError(ERROR_INVALID_HANDLE);
814 return -1;
816 memset(result, 0, sizeof(*result));
818 type = GetFileType(h);
819 if (type == FILE_TYPE_UNKNOWN) {
820 DWORD error = GetLastError();
821 if (error != 0) {
822 return -1;
824 /* else: valid but unknown file */
827 if (type != FILE_TYPE_DISK) {
828 if (type == FILE_TYPE_CHAR)
829 result->st_mode = _S_IFCHR;
830 else if (type == FILE_TYPE_PIPE)
831 result->st_mode = _S_IFIFO;
832 return 0;
835 if (!GetFileInformationByHandle(h, &info)) {
836 return -1;
839 /* similar to stat() */
840 result->st_mode = attributes_to_mode(info.dwFileAttributes);
841 result->st_size = (((__int64)info.nFileSizeHigh)<<32) + info.nFileSizeLow;
842 FILE_TIME_to_time_t_nsec(&info.ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
843 FILE_TIME_to_time_t_nsec(&info.ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
844 FILE_TIME_to_time_t_nsec(&info.ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
845 /* specific to fstat() */
846 result->st_nlink = info.nNumberOfLinks;
847 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
848 return 0;
851 #endif /* MS_WINDOWS */
853 PyDoc_STRVAR(stat_result__doc__,
854 "stat_result: Result from stat or lstat.\n\n\
855 This object may be accessed either as a tuple of\n\
856 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
857 or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
859 Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
860 or st_flags, they are available as attributes only.\n\
862 See os.stat for more information.");
864 static PyStructSequence_Field stat_result_fields[] = {
865 {"st_mode", "protection bits"},
866 {"st_ino", "inode"},
867 {"st_dev", "device"},
868 {"st_nlink", "number of hard links"},
869 {"st_uid", "user ID of owner"},
870 {"st_gid", "group ID of owner"},
871 {"st_size", "total size, in bytes"},
872 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
873 {NULL, "integer time of last access"},
874 {NULL, "integer time of last modification"},
875 {NULL, "integer time of last change"},
876 {"st_atime", "time of last access"},
877 {"st_mtime", "time of last modification"},
878 {"st_ctime", "time of last change"},
879 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
880 {"st_blksize", "blocksize for filesystem I/O"},
881 #endif
882 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
883 {"st_blocks", "number of blocks allocated"},
884 #endif
885 #ifdef HAVE_STRUCT_STAT_ST_RDEV
886 {"st_rdev", "device type (if inode device)"},
887 #endif
888 #ifdef HAVE_STRUCT_STAT_ST_FLAGS
889 {"st_flags", "user defined flags for file"},
890 #endif
891 #ifdef HAVE_STRUCT_STAT_ST_GEN
892 {"st_gen", "generation number"},
893 #endif
894 #ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
895 {"st_birthtime", "time of creation"},
896 #endif
900 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
901 #define ST_BLKSIZE_IDX 13
902 #else
903 #define ST_BLKSIZE_IDX 12
904 #endif
906 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
907 #define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
908 #else
909 #define ST_BLOCKS_IDX ST_BLKSIZE_IDX
910 #endif
912 #ifdef HAVE_STRUCT_STAT_ST_RDEV
913 #define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
914 #else
915 #define ST_RDEV_IDX ST_BLOCKS_IDX
916 #endif
918 #ifdef HAVE_STRUCT_STAT_ST_FLAGS
919 #define ST_FLAGS_IDX (ST_RDEV_IDX+1)
920 #else
921 #define ST_FLAGS_IDX ST_RDEV_IDX
922 #endif
924 #ifdef HAVE_STRUCT_STAT_ST_GEN
925 #define ST_GEN_IDX (ST_FLAGS_IDX+1)
926 #else
927 #define ST_GEN_IDX ST_FLAGS_IDX
928 #endif
930 #ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
931 #define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
932 #else
933 #define ST_BIRTHTIME_IDX ST_GEN_IDX
934 #endif
936 static PyStructSequence_Desc stat_result_desc = {
937 "stat_result", /* name */
938 stat_result__doc__, /* doc */
939 stat_result_fields,
943 PyDoc_STRVAR(statvfs_result__doc__,
944 "statvfs_result: Result from statvfs or fstatvfs.\n\n\
945 This object may be accessed either as a tuple of\n\
946 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
947 or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
949 See os.statvfs for more information.");
951 static PyStructSequence_Field statvfs_result_fields[] = {
952 {"f_bsize", },
953 {"f_frsize", },
954 {"f_blocks", },
955 {"f_bfree", },
956 {"f_bavail", },
957 {"f_files", },
958 {"f_ffree", },
959 {"f_favail", },
960 {"f_flag", },
961 {"f_namemax",},
965 static PyStructSequence_Desc statvfs_result_desc = {
966 "statvfs_result", /* name */
967 statvfs_result__doc__, /* doc */
968 statvfs_result_fields,
972 static PyTypeObject StatResultType;
973 static PyTypeObject StatVFSResultType;
974 static newfunc structseq_new;
976 static PyObject *
977 statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
979 PyStructSequence *result;
980 int i;
982 result = (PyStructSequence*)structseq_new(type, args, kwds);
983 if (!result)
984 return NULL;
985 /* If we have been initialized from a tuple,
986 st_?time might be set to None. Initialize it
987 from the int slots. */
988 for (i = 7; i <= 9; i++) {
989 if (result->ob_item[i+3] == Py_None) {
990 Py_DECREF(Py_None);
991 Py_INCREF(result->ob_item[i]);
992 result->ob_item[i+3] = result->ob_item[i];
995 return (PyObject*)result;
1000 /* If true, st_?time is float. */
1001 static int _stat_float_times = 1;
1003 PyDoc_STRVAR(stat_float_times__doc__,
1004 "stat_float_times([newval]) -> oldval\n\n\
1005 Determine whether os.[lf]stat represents time stamps as float objects.\n\
1006 If newval is True, future calls to stat() return floats, if it is False,\n\
1007 future calls return ints. \n\
1008 If newval is omitted, return the current setting.\n");
1010 static PyObject*
1011 stat_float_times(PyObject* self, PyObject *args)
1013 int newval = -1;
1014 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1015 return NULL;
1016 if (newval == -1)
1017 /* Return old value */
1018 return PyBool_FromLong(_stat_float_times);
1019 _stat_float_times = newval;
1020 Py_INCREF(Py_None);
1021 return Py_None;
1024 static void
1025 fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1027 PyObject *fval,*ival;
1028 #if SIZEOF_TIME_T > SIZEOF_LONG
1029 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
1030 #else
1031 ival = PyInt_FromLong((long)sec);
1032 #endif
1033 if (_stat_float_times) {
1034 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1035 } else {
1036 fval = ival;
1037 Py_INCREF(fval);
1039 PyStructSequence_SET_ITEM(v, index, ival);
1040 PyStructSequence_SET_ITEM(v, index+3, fval);
1043 /* pack a system stat C structure into the Python stat tuple
1044 (used by posix_stat() and posix_fstat()) */
1045 static PyObject*
1046 _pystat_fromstructstat(STRUCT_STAT *st)
1048 unsigned long ansec, mnsec, cnsec;
1049 PyObject *v = PyStructSequence_New(&StatResultType);
1050 if (v == NULL)
1051 return NULL;
1053 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st->st_mode));
1054 #ifdef HAVE_LARGEFILE_SUPPORT
1055 PyStructSequence_SET_ITEM(v, 1,
1056 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
1057 #else
1058 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st->st_ino));
1059 #endif
1060 #if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
1061 PyStructSequence_SET_ITEM(v, 2,
1062 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
1063 #else
1064 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st->st_dev));
1065 #endif
1066 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st->st_nlink));
1067 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st->st_uid));
1068 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st->st_gid));
1069 #ifdef HAVE_LARGEFILE_SUPPORT
1070 PyStructSequence_SET_ITEM(v, 6,
1071 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
1072 #else
1073 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st->st_size));
1074 #endif
1076 #if defined(HAVE_STAT_TV_NSEC)
1077 ansec = st->st_atim.tv_nsec;
1078 mnsec = st->st_mtim.tv_nsec;
1079 cnsec = st->st_ctim.tv_nsec;
1080 #elif defined(HAVE_STAT_TV_NSEC2)
1081 ansec = st->st_atimespec.tv_nsec;
1082 mnsec = st->st_mtimespec.tv_nsec;
1083 cnsec = st->st_ctimespec.tv_nsec;
1084 #elif defined(HAVE_STAT_NSEC)
1085 ansec = st->st_atime_nsec;
1086 mnsec = st->st_mtime_nsec;
1087 cnsec = st->st_ctime_nsec;
1088 #else
1089 ansec = mnsec = cnsec = 0;
1090 #endif
1091 fill_time(v, 7, st->st_atime, ansec);
1092 fill_time(v, 8, st->st_mtime, mnsec);
1093 fill_time(v, 9, st->st_ctime, cnsec);
1095 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
1096 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
1097 PyInt_FromLong((long)st->st_blksize));
1098 #endif
1099 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
1100 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
1101 PyInt_FromLong((long)st->st_blocks));
1102 #endif
1103 #ifdef HAVE_STRUCT_STAT_ST_RDEV
1104 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
1105 PyInt_FromLong((long)st->st_rdev));
1106 #endif
1107 #ifdef HAVE_STRUCT_STAT_ST_GEN
1108 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
1109 PyInt_FromLong((long)st->st_gen));
1110 #endif
1111 #ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1113 PyObject *val;
1114 unsigned long bsec,bnsec;
1115 bsec = (long)st->st_birthtime;
1116 #ifdef HAVE_STAT_TV_NSEC2
1117 bnsec = st.st_birthtimespec->tv_nsec;
1118 #else
1119 bnsec = 0;
1120 #endif
1121 if (_stat_float_times) {
1122 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1123 } else {
1124 val = PyInt_FromLong((long)bsec);
1126 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1127 val);
1129 #endif
1130 #ifdef HAVE_STRUCT_STAT_ST_FLAGS
1131 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
1132 PyInt_FromLong((long)st->st_flags));
1133 #endif
1135 if (PyErr_Occurred()) {
1136 Py_DECREF(v);
1137 return NULL;
1140 return v;
1143 #ifdef MS_WINDOWS
1145 /* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
1146 where / can be used in place of \ and the trailing slash is optional.
1147 Both SERVER and SHARE must have at least one character.
1150 #define ISSLASHA(c) ((c) == '\\' || (c) == '/')
1151 #define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
1152 #define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
1154 static BOOL
1155 IsUNCRootA(char *path, int pathlen)
1157 #define ISSLASH ISSLASHA
1159 int i, share;
1161 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1162 /* minimum UNCRoot is \\x\y */
1163 return FALSE;
1164 for (i = 2; i < pathlen ; i++)
1165 if (ISSLASH(path[i])) break;
1166 if (i == 2 || i == pathlen)
1167 /* do not allow \\\SHARE or \\SERVER */
1168 return FALSE;
1169 share = i+1;
1170 for (i = share; i < pathlen; i++)
1171 if (ISSLASH(path[i])) break;
1172 return (i != share && (i == pathlen || i == pathlen-1));
1174 #undef ISSLASH
1177 #ifdef Py_WIN_WIDE_FILENAMES
1178 static BOOL
1179 IsUNCRootW(Py_UNICODE *path, int pathlen)
1181 #define ISSLASH ISSLASHW
1183 int i, share;
1185 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1186 /* minimum UNCRoot is \\x\y */
1187 return FALSE;
1188 for (i = 2; i < pathlen ; i++)
1189 if (ISSLASH(path[i])) break;
1190 if (i == 2 || i == pathlen)
1191 /* do not allow \\\SHARE or \\SERVER */
1192 return FALSE;
1193 share = i+1;
1194 for (i = share; i < pathlen; i++)
1195 if (ISSLASH(path[i])) break;
1196 return (i != share && (i == pathlen || i == pathlen-1));
1198 #undef ISSLASH
1200 #endif /* Py_WIN_WIDE_FILENAMES */
1201 #endif /* MS_WINDOWS */
1203 static PyObject *
1204 posix_do_stat(PyObject *self, PyObject *args,
1205 char *format,
1206 #ifdef __VMS
1207 int (*statfunc)(const char *, STRUCT_STAT *, ...),
1208 #else
1209 int (*statfunc)(const char *, STRUCT_STAT *),
1210 #endif
1211 char *wformat,
1212 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
1214 STRUCT_STAT st;
1215 char *path = NULL; /* pass this to stat; do not free() it */
1216 char *pathfree = NULL; /* this memory must be free'd */
1217 int res;
1218 PyObject *result;
1220 #ifdef Py_WIN_WIDE_FILENAMES
1221 /* If on wide-character-capable OS see if argument
1222 is Unicode and if so use wide API. */
1223 if (unicode_file_names()) {
1224 PyUnicodeObject *po;
1225 if (PyArg_ParseTuple(args, wformat, &po)) {
1226 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
1228 Py_BEGIN_ALLOW_THREADS
1229 /* PyUnicode_AS_UNICODE result OK without
1230 thread lock as it is a simple dereference. */
1231 res = wstatfunc(wpath, &st);
1232 Py_END_ALLOW_THREADS
1234 if (res != 0)
1235 return win32_error_unicode("stat", wpath);
1236 return _pystat_fromstructstat(&st);
1238 /* Drop the argument parsing error as narrow strings
1239 are also valid. */
1240 PyErr_Clear();
1242 #endif
1244 if (!PyArg_ParseTuple(args, format,
1245 Py_FileSystemDefaultEncoding, &path))
1246 return NULL;
1247 pathfree = path;
1249 Py_BEGIN_ALLOW_THREADS
1250 res = (*statfunc)(path, &st);
1251 Py_END_ALLOW_THREADS
1253 if (res != 0) {
1254 #ifdef MS_WINDOWS
1255 result = win32_error("stat", pathfree);
1256 #else
1257 result = posix_error_with_filename(pathfree);
1258 #endif
1260 else
1261 result = _pystat_fromstructstat(&st);
1263 PyMem_Free(pathfree);
1264 return result;
1267 /* POSIX methods */
1269 PyDoc_STRVAR(posix_access__doc__,
1270 "access(path, mode) -> 1 if granted, 0 otherwise\n\n\
1271 Use the real uid/gid to test for access to a path. Note that most\n\
1272 operations will use the effective uid/gid, therefore this routine can\n\
1273 be used in a suid/sgid environment to test if the invoking user has the\n\
1274 specified access to the path. The mode argument can be F_OK to test\n\
1275 existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
1277 static PyObject *
1278 posix_access(PyObject *self, PyObject *args)
1280 char *path;
1281 int mode;
1282 int res;
1284 #ifdef Py_WIN_WIDE_FILENAMES
1285 if (unicode_file_names()) {
1286 PyUnicodeObject *po;
1287 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1288 Py_BEGIN_ALLOW_THREADS
1289 /* PyUnicode_AS_UNICODE OK without thread lock as
1290 it is a simple dereference. */
1291 res = _waccess(PyUnicode_AS_UNICODE(po), mode);
1292 Py_END_ALLOW_THREADS
1293 return PyBool_FromLong(res == 0);
1295 /* Drop the argument parsing error as narrow strings
1296 are also valid. */
1297 PyErr_Clear();
1299 #endif
1300 if (!PyArg_ParseTuple(args, "eti:access",
1301 Py_FileSystemDefaultEncoding, &path, &mode))
1302 return NULL;
1303 Py_BEGIN_ALLOW_THREADS
1304 res = access(path, mode);
1305 Py_END_ALLOW_THREADS
1306 PyMem_Free(path);
1307 return PyBool_FromLong(res == 0);
1310 #ifndef F_OK
1311 #define F_OK 0
1312 #endif
1313 #ifndef R_OK
1314 #define R_OK 4
1315 #endif
1316 #ifndef W_OK
1317 #define W_OK 2
1318 #endif
1319 #ifndef X_OK
1320 #define X_OK 1
1321 #endif
1323 #ifdef HAVE_TTYNAME
1324 PyDoc_STRVAR(posix_ttyname__doc__,
1325 "ttyname(fd) -> string\n\n\
1326 Return the name of the terminal device connected to 'fd'.");
1328 static PyObject *
1329 posix_ttyname(PyObject *self, PyObject *args)
1331 int id;
1332 char *ret;
1334 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
1335 return NULL;
1337 #if defined(__VMS)
1338 /* file descriptor 0 only, the default input device (stdin) */
1339 if (id == 0) {
1340 ret = ttyname();
1342 else {
1343 ret = NULL;
1345 #else
1346 ret = ttyname(id);
1347 #endif
1348 if (ret == NULL)
1349 return posix_error();
1350 return PyString_FromString(ret);
1352 #endif
1354 #ifdef HAVE_CTERMID
1355 PyDoc_STRVAR(posix_ctermid__doc__,
1356 "ctermid() -> string\n\n\
1357 Return the name of the controlling terminal for this process.");
1359 static PyObject *
1360 posix_ctermid(PyObject *self, PyObject *noargs)
1362 char *ret;
1363 char buffer[L_ctermid];
1365 #ifdef USE_CTERMID_R
1366 ret = ctermid_r(buffer);
1367 #else
1368 ret = ctermid(buffer);
1369 #endif
1370 if (ret == NULL)
1371 return posix_error();
1372 return PyString_FromString(buffer);
1374 #endif
1376 PyDoc_STRVAR(posix_chdir__doc__,
1377 "chdir(path)\n\n\
1378 Change the current working directory to the specified path.");
1380 static PyObject *
1381 posix_chdir(PyObject *self, PyObject *args)
1383 #ifdef MS_WINDOWS
1384 return posix_1str(args, "et:chdir", chdir, "U:chdir", _wchdir);
1385 #elif defined(PYOS_OS2) && defined(PYCC_GCC)
1386 return posix_1str(args, "et:chdir", _chdir2, NULL, NULL);
1387 #elif defined(__VMS)
1388 return posix_1str(args, "et:chdir", (int (*)(const char *))chdir,
1389 NULL, NULL);
1390 #else
1391 return posix_1str(args, "et:chdir", chdir, NULL, NULL);
1392 #endif
1395 #ifdef HAVE_FCHDIR
1396 PyDoc_STRVAR(posix_fchdir__doc__,
1397 "fchdir(fildes)\n\n\
1398 Change to the directory of the given file descriptor. fildes must be\n\
1399 opened on a directory, not a file.");
1401 static PyObject *
1402 posix_fchdir(PyObject *self, PyObject *fdobj)
1404 return posix_fildes(fdobj, fchdir);
1406 #endif /* HAVE_FCHDIR */
1409 PyDoc_STRVAR(posix_chmod__doc__,
1410 "chmod(path, mode)\n\n\
1411 Change the access permissions of a file.");
1413 static PyObject *
1414 posix_chmod(PyObject *self, PyObject *args)
1416 char *path = NULL;
1417 int i;
1418 int res;
1419 #ifdef Py_WIN_WIDE_FILENAMES
1420 if (unicode_file_names()) {
1421 PyUnicodeObject *po;
1422 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1423 Py_BEGIN_ALLOW_THREADS
1424 res = _wchmod(PyUnicode_AS_UNICODE(po), i);
1425 Py_END_ALLOW_THREADS
1426 if (res < 0)
1427 return posix_error_with_unicode_filename(
1428 PyUnicode_AS_UNICODE(po));
1429 Py_INCREF(Py_None);
1430 return Py_None;
1432 /* Drop the argument parsing error as narrow strings
1433 are also valid. */
1434 PyErr_Clear();
1436 #endif /* Py_WIN_WIDE_FILENAMES */
1437 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
1438 &path, &i))
1439 return NULL;
1440 Py_BEGIN_ALLOW_THREADS
1441 res = chmod(path, i);
1442 Py_END_ALLOW_THREADS
1443 if (res < 0)
1444 return posix_error_with_allocated_filename(path);
1445 PyMem_Free(path);
1446 Py_INCREF(Py_None);
1447 return Py_None;
1451 #ifdef HAVE_CHROOT
1452 PyDoc_STRVAR(posix_chroot__doc__,
1453 "chroot(path)\n\n\
1454 Change root directory to path.");
1456 static PyObject *
1457 posix_chroot(PyObject *self, PyObject *args)
1459 return posix_1str(args, "et:chroot", chroot, NULL, NULL);
1461 #endif
1463 #ifdef HAVE_FSYNC
1464 PyDoc_STRVAR(posix_fsync__doc__,
1465 "fsync(fildes)\n\n\
1466 force write of file with filedescriptor to disk.");
1468 static PyObject *
1469 posix_fsync(PyObject *self, PyObject *fdobj)
1471 return posix_fildes(fdobj, fsync);
1473 #endif /* HAVE_FSYNC */
1475 #ifdef HAVE_FDATASYNC
1477 #ifdef __hpux
1478 extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1479 #endif
1481 PyDoc_STRVAR(posix_fdatasync__doc__,
1482 "fdatasync(fildes)\n\n\
1483 force write of file with filedescriptor to disk.\n\
1484 does not force update of metadata.");
1486 static PyObject *
1487 posix_fdatasync(PyObject *self, PyObject *fdobj)
1489 return posix_fildes(fdobj, fdatasync);
1491 #endif /* HAVE_FDATASYNC */
1494 #ifdef HAVE_CHOWN
1495 PyDoc_STRVAR(posix_chown__doc__,
1496 "chown(path, uid, gid)\n\n\
1497 Change the owner and group id of path to the numeric uid and gid.");
1499 static PyObject *
1500 posix_chown(PyObject *self, PyObject *args)
1502 char *path = NULL;
1503 int uid, gid;
1504 int res;
1505 if (!PyArg_ParseTuple(args, "etii:chown",
1506 Py_FileSystemDefaultEncoding, &path,
1507 &uid, &gid))
1508 return NULL;
1509 Py_BEGIN_ALLOW_THREADS
1510 res = chown(path, (uid_t) uid, (gid_t) gid);
1511 Py_END_ALLOW_THREADS
1512 if (res < 0)
1513 return posix_error_with_allocated_filename(path);
1514 PyMem_Free(path);
1515 Py_INCREF(Py_None);
1516 return Py_None;
1518 #endif /* HAVE_CHOWN */
1520 #ifdef HAVE_LCHOWN
1521 PyDoc_STRVAR(posix_lchown__doc__,
1522 "lchown(path, uid, gid)\n\n\
1523 Change the owner and group id of path to the numeric uid and gid.\n\
1524 This function will not follow symbolic links.");
1526 static PyObject *
1527 posix_lchown(PyObject *self, PyObject *args)
1529 char *path = NULL;
1530 int uid, gid;
1531 int res;
1532 if (!PyArg_ParseTuple(args, "etii:lchown",
1533 Py_FileSystemDefaultEncoding, &path,
1534 &uid, &gid))
1535 return NULL;
1536 Py_BEGIN_ALLOW_THREADS
1537 res = lchown(path, (uid_t) uid, (gid_t) gid);
1538 Py_END_ALLOW_THREADS
1539 if (res < 0)
1540 return posix_error_with_allocated_filename(path);
1541 PyMem_Free(path);
1542 Py_INCREF(Py_None);
1543 return Py_None;
1545 #endif /* HAVE_LCHOWN */
1548 #ifdef HAVE_GETCWD
1549 PyDoc_STRVAR(posix_getcwd__doc__,
1550 "getcwd() -> path\n\n\
1551 Return a string representing the current working directory.");
1553 static PyObject *
1554 posix_getcwd(PyObject *self, PyObject *noargs)
1556 char buf[1026];
1557 char *res;
1559 Py_BEGIN_ALLOW_THREADS
1560 #if defined(PYOS_OS2) && defined(PYCC_GCC)
1561 res = _getcwd2(buf, sizeof buf);
1562 #else
1563 res = getcwd(buf, sizeof buf);
1564 #endif
1565 Py_END_ALLOW_THREADS
1566 if (res == NULL)
1567 return posix_error();
1568 return PyString_FromString(buf);
1571 #ifdef Py_USING_UNICODE
1572 PyDoc_STRVAR(posix_getcwdu__doc__,
1573 "getcwdu() -> path\n\n\
1574 Return a unicode string representing the current working directory.");
1576 static PyObject *
1577 posix_getcwdu(PyObject *self, PyObject *noargs)
1579 char buf[1026];
1580 char *res;
1582 #ifdef Py_WIN_WIDE_FILENAMES
1583 if (unicode_file_names()) {
1584 wchar_t *wres;
1585 wchar_t wbuf[1026];
1586 Py_BEGIN_ALLOW_THREADS
1587 wres = _wgetcwd(wbuf, sizeof wbuf/ sizeof wbuf[0]);
1588 Py_END_ALLOW_THREADS
1589 if (wres == NULL)
1590 return posix_error();
1591 return PyUnicode_FromWideChar(wbuf, wcslen(wbuf));
1593 #endif
1595 Py_BEGIN_ALLOW_THREADS
1596 #if defined(PYOS_OS2) && defined(PYCC_GCC)
1597 res = _getcwd2(buf, sizeof buf);
1598 #else
1599 res = getcwd(buf, sizeof buf);
1600 #endif
1601 Py_END_ALLOW_THREADS
1602 if (res == NULL)
1603 return posix_error();
1604 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
1606 #endif
1607 #endif
1610 #ifdef HAVE_LINK
1611 PyDoc_STRVAR(posix_link__doc__,
1612 "link(src, dst)\n\n\
1613 Create a hard link to a file.");
1615 static PyObject *
1616 posix_link(PyObject *self, PyObject *args)
1618 return posix_2str(args, "etet:link", link, NULL, NULL);
1620 #endif /* HAVE_LINK */
1623 PyDoc_STRVAR(posix_listdir__doc__,
1624 "listdir(path) -> list_of_strings\n\n\
1625 Return a list containing the names of the entries in the directory.\n\
1627 path: path of directory to list\n\
1629 The list is in arbitrary order. It does not include the special\n\
1630 entries '.' and '..' even if they are present in the directory.");
1632 static PyObject *
1633 posix_listdir(PyObject *self, PyObject *args)
1635 /* XXX Should redo this putting the (now four) versions of opendir
1636 in separate files instead of having them all here... */
1637 #if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
1639 PyObject *d, *v;
1640 HANDLE hFindFile;
1641 WIN32_FIND_DATA FileData;
1642 /* MAX_PATH characters could mean a bigger encoded string */
1643 char namebuf[MAX_PATH*2+5];
1644 char *bufptr = namebuf;
1645 int len = sizeof(namebuf)/sizeof(namebuf[0]);
1647 #ifdef Py_WIN_WIDE_FILENAMES
1648 /* If on wide-character-capable OS see if argument
1649 is Unicode and if so use wide API. */
1650 if (unicode_file_names()) {
1651 PyUnicodeObject *po;
1652 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
1653 WIN32_FIND_DATAW wFileData;
1654 Py_UNICODE wnamebuf[MAX_PATH*2+5];
1655 Py_UNICODE wch;
1656 wcsncpy(wnamebuf, PyUnicode_AS_UNICODE(po), MAX_PATH);
1657 wnamebuf[MAX_PATH] = L'\0';
1658 len = wcslen(wnamebuf);
1659 wch = (len > 0) ? wnamebuf[len-1] : L'\0';
1660 if (wch != L'/' && wch != L'\\' && wch != L':')
1661 wnamebuf[len++] = L'/';
1662 wcscpy(wnamebuf + len, L"*.*");
1663 if ((d = PyList_New(0)) == NULL)
1664 return NULL;
1665 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
1666 if (hFindFile == INVALID_HANDLE_VALUE) {
1667 errno = GetLastError();
1668 if (errno == ERROR_FILE_NOT_FOUND) {
1669 return d;
1671 Py_DECREF(d);
1672 return win32_error_unicode("FindFirstFileW", wnamebuf);
1674 do {
1675 if (wFileData.cFileName[0] == L'.' &&
1676 (wFileData.cFileName[1] == L'\0' ||
1677 wFileData.cFileName[1] == L'.' &&
1678 wFileData.cFileName[2] == L'\0'))
1679 continue;
1680 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
1681 if (v == NULL) {
1682 Py_DECREF(d);
1683 d = NULL;
1684 break;
1686 if (PyList_Append(d, v) != 0) {
1687 Py_DECREF(v);
1688 Py_DECREF(d);
1689 d = NULL;
1690 break;
1692 Py_DECREF(v);
1693 } while (FindNextFileW(hFindFile, &wFileData) == TRUE);
1695 if (FindClose(hFindFile) == FALSE) {
1696 Py_DECREF(d);
1697 return win32_error_unicode("FindClose", wnamebuf);
1699 return d;
1701 /* Drop the argument parsing error as narrow strings
1702 are also valid. */
1703 PyErr_Clear();
1705 #endif
1707 if (!PyArg_ParseTuple(args, "et#:listdir",
1708 Py_FileSystemDefaultEncoding, &bufptr, &len))
1709 return NULL;
1710 if (len > 0) {
1711 char ch = namebuf[len-1];
1712 if (ch != SEP && ch != ALTSEP && ch != ':')
1713 namebuf[len++] = '/';
1715 strcpy(namebuf + len, "*.*");
1717 if ((d = PyList_New(0)) == NULL)
1718 return NULL;
1720 hFindFile = FindFirstFile(namebuf, &FileData);
1721 if (hFindFile == INVALID_HANDLE_VALUE) {
1722 errno = GetLastError();
1723 if (errno == ERROR_FILE_NOT_FOUND)
1724 return d;
1725 Py_DECREF(d);
1726 return win32_error("FindFirstFile", namebuf);
1728 do {
1729 if (FileData.cFileName[0] == '.' &&
1730 (FileData.cFileName[1] == '\0' ||
1731 FileData.cFileName[1] == '.' &&
1732 FileData.cFileName[2] == '\0'))
1733 continue;
1734 v = PyString_FromString(FileData.cFileName);
1735 if (v == NULL) {
1736 Py_DECREF(d);
1737 d = NULL;
1738 break;
1740 if (PyList_Append(d, v) != 0) {
1741 Py_DECREF(v);
1742 Py_DECREF(d);
1743 d = NULL;
1744 break;
1746 Py_DECREF(v);
1747 } while (FindNextFile(hFindFile, &FileData) == TRUE);
1749 if (FindClose(hFindFile) == FALSE) {
1750 Py_DECREF(d);
1751 return win32_error("FindClose", namebuf);
1754 return d;
1756 #elif defined(PYOS_OS2)
1758 #ifndef MAX_PATH
1759 #define MAX_PATH CCHMAXPATH
1760 #endif
1761 char *name, *pt;
1762 int len;
1763 PyObject *d, *v;
1764 char namebuf[MAX_PATH+5];
1765 HDIR hdir = 1;
1766 ULONG srchcnt = 1;
1767 FILEFINDBUF3 ep;
1768 APIRET rc;
1770 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
1771 return NULL;
1772 if (len >= MAX_PATH) {
1773 PyErr_SetString(PyExc_ValueError, "path too long");
1774 return NULL;
1776 strcpy(namebuf, name);
1777 for (pt = namebuf; *pt; pt++)
1778 if (*pt == ALTSEP)
1779 *pt = SEP;
1780 if (namebuf[len-1] != SEP)
1781 namebuf[len++] = SEP;
1782 strcpy(namebuf + len, "*.*");
1784 if ((d = PyList_New(0)) == NULL)
1785 return NULL;
1787 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
1788 &hdir, /* Handle to Use While Search Directory */
1789 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
1790 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
1791 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
1792 FIL_STANDARD); /* Format of Entry (EAs or Not) */
1794 if (rc != NO_ERROR) {
1795 errno = ENOENT;
1796 return posix_error_with_filename(name);
1799 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
1800 do {
1801 if (ep.achName[0] == '.'
1802 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
1803 continue; /* Skip Over "." and ".." Names */
1805 strcpy(namebuf, ep.achName);
1807 /* Leave Case of Name Alone -- In Native Form */
1808 /* (Removed Forced Lowercasing Code) */
1810 v = PyString_FromString(namebuf);
1811 if (v == NULL) {
1812 Py_DECREF(d);
1813 d = NULL;
1814 break;
1816 if (PyList_Append(d, v) != 0) {
1817 Py_DECREF(v);
1818 Py_DECREF(d);
1819 d = NULL;
1820 break;
1822 Py_DECREF(v);
1823 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1826 return d;
1827 #else
1829 char *name = NULL;
1830 PyObject *d, *v;
1831 DIR *dirp;
1832 struct dirent *ep;
1833 int arg_is_unicode = 1;
1835 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
1836 arg_is_unicode = 0;
1837 PyErr_Clear();
1839 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
1840 return NULL;
1841 if ((dirp = opendir(name)) == NULL) {
1842 return posix_error_with_allocated_filename(name);
1844 if ((d = PyList_New(0)) == NULL) {
1845 closedir(dirp);
1846 PyMem_Free(name);
1847 return NULL;
1849 while ((ep = readdir(dirp)) != NULL) {
1850 if (ep->d_name[0] == '.' &&
1851 (NAMLEN(ep) == 1 ||
1852 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
1853 continue;
1854 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
1855 if (v == NULL) {
1856 Py_DECREF(d);
1857 d = NULL;
1858 break;
1860 #ifdef Py_USING_UNICODE
1861 if (arg_is_unicode) {
1862 PyObject *w;
1864 w = PyUnicode_FromEncodedObject(v,
1865 Py_FileSystemDefaultEncoding,
1866 "strict");
1867 if (w != NULL) {
1868 Py_DECREF(v);
1869 v = w;
1871 else {
1872 /* fall back to the original byte string, as
1873 discussed in patch #683592 */
1874 PyErr_Clear();
1877 #endif
1878 if (PyList_Append(d, v) != 0) {
1879 Py_DECREF(v);
1880 Py_DECREF(d);
1881 d = NULL;
1882 break;
1884 Py_DECREF(v);
1886 closedir(dirp);
1887 PyMem_Free(name);
1889 return d;
1891 #endif /* which OS */
1892 } /* end of posix_listdir */
1894 #ifdef MS_WINDOWS
1895 /* A helper function for abspath on win32 */
1896 static PyObject *
1897 posix__getfullpathname(PyObject *self, PyObject *args)
1899 /* assume encoded strings wont more than double no of chars */
1900 char inbuf[MAX_PATH*2];
1901 char *inbufp = inbuf;
1902 int insize = sizeof(inbuf)/sizeof(inbuf[0]);
1903 char outbuf[MAX_PATH*2];
1904 char *temp;
1905 #ifdef Py_WIN_WIDE_FILENAMES
1906 if (unicode_file_names()) {
1907 PyUnicodeObject *po;
1908 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
1909 Py_UNICODE woutbuf[MAX_PATH*2];
1910 Py_UNICODE *wtemp;
1911 if (!GetFullPathNameW(PyUnicode_AS_UNICODE(po),
1912 sizeof(woutbuf)/sizeof(woutbuf[0]),
1913 woutbuf, &wtemp))
1914 return win32_error("GetFullPathName", "");
1915 return PyUnicode_FromUnicode(woutbuf, wcslen(woutbuf));
1917 /* Drop the argument parsing error as narrow strings
1918 are also valid. */
1919 PyErr_Clear();
1921 #endif
1922 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
1923 Py_FileSystemDefaultEncoding, &inbufp,
1924 &insize))
1925 return NULL;
1926 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
1927 outbuf, &temp))
1928 return win32_error("GetFullPathName", inbuf);
1929 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
1930 return PyUnicode_Decode(outbuf, strlen(outbuf),
1931 Py_FileSystemDefaultEncoding, NULL);
1933 return PyString_FromString(outbuf);
1934 } /* end of posix__getfullpathname */
1935 #endif /* MS_WINDOWS */
1937 PyDoc_STRVAR(posix_mkdir__doc__,
1938 "mkdir(path [, mode=0777])\n\n\
1939 Create a directory.");
1941 static PyObject *
1942 posix_mkdir(PyObject *self, PyObject *args)
1944 int res;
1945 char *path = NULL;
1946 int mode = 0777;
1948 #ifdef Py_WIN_WIDE_FILENAMES
1949 if (unicode_file_names()) {
1950 PyUnicodeObject *po;
1951 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
1952 Py_BEGIN_ALLOW_THREADS
1953 /* PyUnicode_AS_UNICODE OK without thread lock as
1954 it is a simple dereference. */
1955 res = _wmkdir(PyUnicode_AS_UNICODE(po));
1956 Py_END_ALLOW_THREADS
1957 if (res < 0)
1958 return posix_error();
1959 Py_INCREF(Py_None);
1960 return Py_None;
1962 /* Drop the argument parsing error as narrow strings
1963 are also valid. */
1964 PyErr_Clear();
1966 #endif
1968 if (!PyArg_ParseTuple(args, "et|i:mkdir",
1969 Py_FileSystemDefaultEncoding, &path, &mode))
1970 return NULL;
1971 Py_BEGIN_ALLOW_THREADS
1972 #if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
1973 res = mkdir(path);
1974 #else
1975 res = mkdir(path, mode);
1976 #endif
1977 Py_END_ALLOW_THREADS
1978 if (res < 0)
1979 return posix_error_with_allocated_filename(path);
1980 PyMem_Free(path);
1981 Py_INCREF(Py_None);
1982 return Py_None;
1986 #ifdef HAVE_NICE
1987 #if defined(HAVE_BROKEN_NICE) && defined(HAVE_SYS_RESOURCE_H)
1988 #if defined(HAVE_GETPRIORITY) && !defined(PRIO_PROCESS)
1989 #include <sys/resource.h>
1990 #endif
1991 #endif
1993 PyDoc_STRVAR(posix_nice__doc__,
1994 "nice(inc) -> new_priority\n\n\
1995 Decrease the priority of process by inc and return the new priority.");
1997 static PyObject *
1998 posix_nice(PyObject *self, PyObject *args)
2000 int increment, value;
2002 if (!PyArg_ParseTuple(args, "i:nice", &increment))
2003 return NULL;
2005 /* There are two flavours of 'nice': one that returns the new
2006 priority (as required by almost all standards out there) and the
2007 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2008 the use of getpriority() to get the new priority.
2010 If we are of the nice family that returns the new priority, we
2011 need to clear errno before the call, and check if errno is filled
2012 before calling posix_error() on a returnvalue of -1, because the
2013 -1 may be the actual new priority! */
2015 errno = 0;
2016 value = nice(increment);
2017 #if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
2018 if (value == 0)
2019 value = getpriority(PRIO_PROCESS, 0);
2020 #endif
2021 if (value == -1 && errno != 0)
2022 /* either nice() or getpriority() returned an error */
2023 return posix_error();
2024 return PyInt_FromLong((long) value);
2026 #endif /* HAVE_NICE */
2029 PyDoc_STRVAR(posix_rename__doc__,
2030 "rename(old, new)\n\n\
2031 Rename a file or directory.");
2033 static PyObject *
2034 posix_rename(PyObject *self, PyObject *args)
2036 #ifdef MS_WINDOWS
2037 return posix_2str(args, "etet:rename", rename, "OO:rename", _wrename);
2038 #else
2039 return posix_2str(args, "etet:rename", rename, NULL, NULL);
2040 #endif
2044 PyDoc_STRVAR(posix_rmdir__doc__,
2045 "rmdir(path)\n\n\
2046 Remove a directory.");
2048 static PyObject *
2049 posix_rmdir(PyObject *self, PyObject *args)
2051 #ifdef MS_WINDOWS
2052 return posix_1str(args, "et:rmdir", rmdir, "U:rmdir", _wrmdir);
2053 #else
2054 return posix_1str(args, "et:rmdir", rmdir, NULL, NULL);
2055 #endif
2059 PyDoc_STRVAR(posix_stat__doc__,
2060 "stat(path) -> stat result\n\n\
2061 Perform a stat system call on the given path.");
2063 static PyObject *
2064 posix_stat(PyObject *self, PyObject *args)
2066 #ifdef MS_WINDOWS
2067 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", win32_wstat);
2068 #else
2069 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
2070 #endif
2074 #ifdef HAVE_SYSTEM
2075 PyDoc_STRVAR(posix_system__doc__,
2076 "system(command) -> exit_status\n\n\
2077 Execute the command (a string) in a subshell.");
2079 static PyObject *
2080 posix_system(PyObject *self, PyObject *args)
2082 char *command;
2083 long sts;
2084 if (!PyArg_ParseTuple(args, "s:system", &command))
2085 return NULL;
2086 Py_BEGIN_ALLOW_THREADS
2087 sts = system(command);
2088 Py_END_ALLOW_THREADS
2089 return PyInt_FromLong(sts);
2091 #endif
2094 PyDoc_STRVAR(posix_umask__doc__,
2095 "umask(new_mask) -> old_mask\n\n\
2096 Set the current numeric umask and return the previous umask.");
2098 static PyObject *
2099 posix_umask(PyObject *self, PyObject *args)
2101 int i;
2102 if (!PyArg_ParseTuple(args, "i:umask", &i))
2103 return NULL;
2104 i = (int)umask(i);
2105 if (i < 0)
2106 return posix_error();
2107 return PyInt_FromLong((long)i);
2111 PyDoc_STRVAR(posix_unlink__doc__,
2112 "unlink(path)\n\n\
2113 Remove a file (same as remove(path)).");
2115 PyDoc_STRVAR(posix_remove__doc__,
2116 "remove(path)\n\n\
2117 Remove a file (same as unlink(path)).");
2119 static PyObject *
2120 posix_unlink(PyObject *self, PyObject *args)
2122 #ifdef MS_WINDOWS
2123 return posix_1str(args, "et:remove", unlink, "U:remove", _wunlink);
2124 #else
2125 return posix_1str(args, "et:remove", unlink, NULL, NULL);
2126 #endif
2130 #ifdef HAVE_UNAME
2131 PyDoc_STRVAR(posix_uname__doc__,
2132 "uname() -> (sysname, nodename, release, version, machine)\n\n\
2133 Return a tuple identifying the current operating system.");
2135 static PyObject *
2136 posix_uname(PyObject *self, PyObject *noargs)
2138 struct utsname u;
2139 int res;
2141 Py_BEGIN_ALLOW_THREADS
2142 res = uname(&u);
2143 Py_END_ALLOW_THREADS
2144 if (res < 0)
2145 return posix_error();
2146 return Py_BuildValue("(sssss)",
2147 u.sysname,
2148 u.nodename,
2149 u.release,
2150 u.version,
2151 u.machine);
2153 #endif /* HAVE_UNAME */
2155 static int
2156 extract_time(PyObject *t, long* sec, long* usec)
2158 long intval;
2159 if (PyFloat_Check(t)) {
2160 double tval = PyFloat_AsDouble(t);
2161 PyObject *intobj = t->ob_type->tp_as_number->nb_int(t);
2162 if (!intobj)
2163 return -1;
2164 intval = PyInt_AsLong(intobj);
2165 Py_DECREF(intobj);
2166 if (intval == -1 && PyErr_Occurred())
2167 return -1;
2168 *sec = intval;
2169 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
2170 if (*usec < 0)
2171 /* If rounding gave us a negative number,
2172 truncate. */
2173 *usec = 0;
2174 return 0;
2176 intval = PyInt_AsLong(t);
2177 if (intval == -1 && PyErr_Occurred())
2178 return -1;
2179 *sec = intval;
2180 *usec = 0;
2181 return 0;
2184 PyDoc_STRVAR(posix_utime__doc__,
2185 "utime(path, (atime, utime))\n\
2186 utime(path, None)\n\n\
2187 Set the access and modified time of the file to the given values. If the\n\
2188 second form is used, set the access and modified times to the current time.");
2190 static PyObject *
2191 posix_utime(PyObject *self, PyObject *args)
2193 char *path = NULL;
2194 long atime, mtime, ausec, musec;
2195 int res;
2196 PyObject* arg;
2198 #if defined(HAVE_UTIMES)
2199 struct timeval buf[2];
2200 #define ATIME buf[0].tv_sec
2201 #define MTIME buf[1].tv_sec
2202 #elif defined(HAVE_UTIME_H)
2203 /* XXX should define struct utimbuf instead, above */
2204 struct utimbuf buf;
2205 #define ATIME buf.actime
2206 #define MTIME buf.modtime
2207 #define UTIME_ARG &buf
2208 #else /* HAVE_UTIMES */
2209 time_t buf[2];
2210 #define ATIME buf[0]
2211 #define MTIME buf[1]
2212 #define UTIME_ARG buf
2213 #endif /* HAVE_UTIMES */
2215 int have_unicode_filename = 0;
2216 #ifdef Py_WIN_WIDE_FILENAMES
2217 PyUnicodeObject *obwpath;
2218 wchar_t *wpath;
2219 if (unicode_file_names()) {
2220 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
2221 wpath = PyUnicode_AS_UNICODE(obwpath);
2222 have_unicode_filename = 1;
2223 } else
2224 /* Drop the argument parsing error as narrow strings
2225 are also valid. */
2226 PyErr_Clear();
2228 #endif /* Py_WIN_WIDE_FILENAMES */
2230 if (!have_unicode_filename && \
2231 !PyArg_ParseTuple(args, "etO:utime",
2232 Py_FileSystemDefaultEncoding, &path, &arg))
2233 return NULL;
2234 if (arg == Py_None) {
2235 /* optional time values not given */
2236 Py_BEGIN_ALLOW_THREADS
2237 #ifdef Py_WIN_WIDE_FILENAMES
2238 if (have_unicode_filename)
2239 res = _wutime(wpath, NULL);
2240 else
2241 #endif /* Py_WIN_WIDE_FILENAMES */
2242 res = utime(path, NULL);
2243 Py_END_ALLOW_THREADS
2245 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
2246 PyErr_SetString(PyExc_TypeError,
2247 "utime() arg 2 must be a tuple (atime, mtime)");
2248 PyMem_Free(path);
2249 return NULL;
2251 else {
2252 if (extract_time(PyTuple_GET_ITEM(arg, 0),
2253 &atime, &ausec) == -1) {
2254 PyMem_Free(path);
2255 return NULL;
2257 if (extract_time(PyTuple_GET_ITEM(arg, 1),
2258 &mtime, &musec) == -1) {
2259 PyMem_Free(path);
2260 return NULL;
2262 ATIME = atime;
2263 MTIME = mtime;
2264 #ifdef HAVE_UTIMES
2265 buf[0].tv_usec = ausec;
2266 buf[1].tv_usec = musec;
2267 Py_BEGIN_ALLOW_THREADS
2268 res = utimes(path, buf);
2269 Py_END_ALLOW_THREADS
2270 #else
2271 Py_BEGIN_ALLOW_THREADS
2272 #ifdef Py_WIN_WIDE_FILENAMES
2273 if (have_unicode_filename)
2274 /* utime is OK with utimbuf, but _wutime insists
2275 on _utimbuf (the msvc headers assert the
2276 underscore version is ansi) */
2277 res = _wutime(wpath, (struct _utimbuf *)UTIME_ARG);
2278 else
2279 #endif /* Py_WIN_WIDE_FILENAMES */
2280 res = utime(path, UTIME_ARG);
2281 Py_END_ALLOW_THREADS
2282 #endif /* HAVE_UTIMES */
2284 if (res < 0) {
2285 #ifdef Py_WIN_WIDE_FILENAMES
2286 if (have_unicode_filename)
2287 return posix_error_with_unicode_filename(wpath);
2288 #endif /* Py_WIN_WIDE_FILENAMES */
2289 return posix_error_with_allocated_filename(path);
2291 PyMem_Free(path);
2292 Py_INCREF(Py_None);
2293 return Py_None;
2294 #undef UTIME_ARG
2295 #undef ATIME
2296 #undef MTIME
2300 /* Process operations */
2302 PyDoc_STRVAR(posix__exit__doc__,
2303 "_exit(status)\n\n\
2304 Exit to the system with specified status, without normal exit processing.");
2306 static PyObject *
2307 posix__exit(PyObject *self, PyObject *args)
2309 int sts;
2310 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
2311 return NULL;
2312 _exit(sts);
2313 return NULL; /* Make gcc -Wall happy */
2316 #if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
2317 static void
2318 free_string_array(char **array, int count)
2320 int i;
2321 for (i = 0; i < count; i++)
2322 PyMem_Free(array[i]);
2323 PyMem_DEL(array);
2325 #endif
2328 #ifdef HAVE_EXECV
2329 PyDoc_STRVAR(posix_execv__doc__,
2330 "execv(path, args)\n\n\
2331 Execute an executable path with arguments, replacing current process.\n\
2333 path: path of executable file\n\
2334 args: tuple or list of strings");
2336 static PyObject *
2337 posix_execv(PyObject *self, PyObject *args)
2339 char *path;
2340 PyObject *argv;
2341 char **argvlist;
2342 int i, argc;
2343 PyObject *(*getitem)(PyObject *, int);
2345 /* execv has two arguments: (path, argv), where
2346 argv is a list or tuple of strings. */
2348 if (!PyArg_ParseTuple(args, "etO:execv",
2349 Py_FileSystemDefaultEncoding,
2350 &path, &argv))
2351 return NULL;
2352 if (PyList_Check(argv)) {
2353 argc = PyList_Size(argv);
2354 getitem = PyList_GetItem;
2356 else if (PyTuple_Check(argv)) {
2357 argc = PyTuple_Size(argv);
2358 getitem = PyTuple_GetItem;
2360 else {
2361 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
2362 PyMem_Free(path);
2363 return NULL;
2366 argvlist = PyMem_NEW(char *, argc+1);
2367 if (argvlist == NULL) {
2368 PyMem_Free(path);
2369 return PyErr_NoMemory();
2371 for (i = 0; i < argc; i++) {
2372 if (!PyArg_Parse((*getitem)(argv, i), "et",
2373 Py_FileSystemDefaultEncoding,
2374 &argvlist[i])) {
2375 free_string_array(argvlist, i);
2376 PyErr_SetString(PyExc_TypeError,
2377 "execv() arg 2 must contain only strings");
2378 PyMem_Free(path);
2379 return NULL;
2383 argvlist[argc] = NULL;
2385 execv(path, argvlist);
2387 /* If we get here it's definitely an error */
2389 free_string_array(argvlist, argc);
2390 PyMem_Free(path);
2391 return posix_error();
2395 PyDoc_STRVAR(posix_execve__doc__,
2396 "execve(path, args, env)\n\n\
2397 Execute a path with arguments and environment, replacing current process.\n\
2399 path: path of executable file\n\
2400 args: tuple or list of arguments\n\
2401 env: dictionary of strings mapping to strings");
2403 static PyObject *
2404 posix_execve(PyObject *self, PyObject *args)
2406 char *path;
2407 PyObject *argv, *env;
2408 char **argvlist;
2409 char **envlist;
2410 PyObject *key, *val, *keys=NULL, *vals=NULL;
2411 int i, pos, argc, envc;
2412 PyObject *(*getitem)(PyObject *, int);
2413 int lastarg = 0;
2415 /* execve has three arguments: (path, argv, env), where
2416 argv is a list or tuple of strings and env is a dictionary
2417 like posix.environ. */
2419 if (!PyArg_ParseTuple(args, "etOO:execve",
2420 Py_FileSystemDefaultEncoding,
2421 &path, &argv, &env))
2422 return NULL;
2423 if (PyList_Check(argv)) {
2424 argc = PyList_Size(argv);
2425 getitem = PyList_GetItem;
2427 else if (PyTuple_Check(argv)) {
2428 argc = PyTuple_Size(argv);
2429 getitem = PyTuple_GetItem;
2431 else {
2432 PyErr_SetString(PyExc_TypeError,
2433 "execve() arg 2 must be a tuple or list");
2434 goto fail_0;
2436 if (!PyMapping_Check(env)) {
2437 PyErr_SetString(PyExc_TypeError,
2438 "execve() arg 3 must be a mapping object");
2439 goto fail_0;
2442 argvlist = PyMem_NEW(char *, argc+1);
2443 if (argvlist == NULL) {
2444 PyErr_NoMemory();
2445 goto fail_0;
2447 for (i = 0; i < argc; i++) {
2448 if (!PyArg_Parse((*getitem)(argv, i),
2449 "et;execve() arg 2 must contain only strings",
2450 Py_FileSystemDefaultEncoding,
2451 &argvlist[i]))
2453 lastarg = i;
2454 goto fail_1;
2457 lastarg = argc;
2458 argvlist[argc] = NULL;
2460 i = PyMapping_Size(env);
2461 if (i < 0)
2462 goto fail_1;
2463 envlist = PyMem_NEW(char *, i + 1);
2464 if (envlist == NULL) {
2465 PyErr_NoMemory();
2466 goto fail_1;
2468 envc = 0;
2469 keys = PyMapping_Keys(env);
2470 vals = PyMapping_Values(env);
2471 if (!keys || !vals)
2472 goto fail_2;
2473 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2474 PyErr_SetString(PyExc_TypeError,
2475 "execve(): env.keys() or env.values() is not a list");
2476 goto fail_2;
2479 for (pos = 0; pos < i; pos++) {
2480 char *p, *k, *v;
2481 size_t len;
2483 key = PyList_GetItem(keys, pos);
2484 val = PyList_GetItem(vals, pos);
2485 if (!key || !val)
2486 goto fail_2;
2488 if (!PyArg_Parse(
2489 key,
2490 "s;execve() arg 3 contains a non-string key",
2491 &k) ||
2492 !PyArg_Parse(
2493 val,
2494 "s;execve() arg 3 contains a non-string value",
2495 &v))
2497 goto fail_2;
2500 #if defined(PYOS_OS2)
2501 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
2502 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
2503 #endif
2504 len = PyString_Size(key) + PyString_Size(val) + 2;
2505 p = PyMem_NEW(char, len);
2506 if (p == NULL) {
2507 PyErr_NoMemory();
2508 goto fail_2;
2510 PyOS_snprintf(p, len, "%s=%s", k, v);
2511 envlist[envc++] = p;
2512 #if defined(PYOS_OS2)
2514 #endif
2516 envlist[envc] = 0;
2518 execve(path, argvlist, envlist);
2520 /* If we get here it's definitely an error */
2522 (void) posix_error();
2524 fail_2:
2525 while (--envc >= 0)
2526 PyMem_DEL(envlist[envc]);
2527 PyMem_DEL(envlist);
2528 fail_1:
2529 free_string_array(argvlist, lastarg);
2530 Py_XDECREF(vals);
2531 Py_XDECREF(keys);
2532 fail_0:
2533 PyMem_Free(path);
2534 return NULL;
2536 #endif /* HAVE_EXECV */
2539 #ifdef HAVE_SPAWNV
2540 PyDoc_STRVAR(posix_spawnv__doc__,
2541 "spawnv(mode, path, args)\n\n\
2542 Execute the program 'path' in a new process.\n\
2544 mode: mode of process creation\n\
2545 path: path of executable file\n\
2546 args: tuple or list of strings");
2548 static PyObject *
2549 posix_spawnv(PyObject *self, PyObject *args)
2551 char *path;
2552 PyObject *argv;
2553 char **argvlist;
2554 int mode, i, argc;
2555 Py_intptr_t spawnval;
2556 PyObject *(*getitem)(PyObject *, int);
2558 /* spawnv has three arguments: (mode, path, argv), where
2559 argv is a list or tuple of strings. */
2561 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
2562 Py_FileSystemDefaultEncoding,
2563 &path, &argv))
2564 return NULL;
2565 if (PyList_Check(argv)) {
2566 argc = PyList_Size(argv);
2567 getitem = PyList_GetItem;
2569 else if (PyTuple_Check(argv)) {
2570 argc = PyTuple_Size(argv);
2571 getitem = PyTuple_GetItem;
2573 else {
2574 PyErr_SetString(PyExc_TypeError,
2575 "spawnv() arg 2 must be a tuple or list");
2576 PyMem_Free(path);
2577 return NULL;
2580 argvlist = PyMem_NEW(char *, argc+1);
2581 if (argvlist == NULL) {
2582 PyMem_Free(path);
2583 return PyErr_NoMemory();
2585 for (i = 0; i < argc; i++) {
2586 if (!PyArg_Parse((*getitem)(argv, i), "et",
2587 Py_FileSystemDefaultEncoding,
2588 &argvlist[i])) {
2589 free_string_array(argvlist, i);
2590 PyErr_SetString(
2591 PyExc_TypeError,
2592 "spawnv() arg 2 must contain only strings");
2593 PyMem_Free(path);
2594 return NULL;
2597 argvlist[argc] = NULL;
2599 #if defined(PYOS_OS2) && defined(PYCC_GCC)
2600 Py_BEGIN_ALLOW_THREADS
2601 spawnval = spawnv(mode, path, argvlist);
2602 Py_END_ALLOW_THREADS
2603 #else
2604 if (mode == _OLD_P_OVERLAY)
2605 mode = _P_OVERLAY;
2607 Py_BEGIN_ALLOW_THREADS
2608 spawnval = _spawnv(mode, path, argvlist);
2609 Py_END_ALLOW_THREADS
2610 #endif
2612 free_string_array(argvlist, argc);
2613 PyMem_Free(path);
2615 if (spawnval == -1)
2616 return posix_error();
2617 else
2618 #if SIZEOF_LONG == SIZEOF_VOID_P
2619 return Py_BuildValue("l", (long) spawnval);
2620 #else
2621 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
2622 #endif
2626 PyDoc_STRVAR(posix_spawnve__doc__,
2627 "spawnve(mode, path, args, env)\n\n\
2628 Execute the program 'path' in a new process.\n\
2630 mode: mode of process creation\n\
2631 path: path of executable file\n\
2632 args: tuple or list of arguments\n\
2633 env: dictionary of strings mapping to strings");
2635 static PyObject *
2636 posix_spawnve(PyObject *self, PyObject *args)
2638 char *path;
2639 PyObject *argv, *env;
2640 char **argvlist;
2641 char **envlist;
2642 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
2643 int mode, i, pos, argc, envc;
2644 Py_intptr_t spawnval;
2645 PyObject *(*getitem)(PyObject *, int);
2646 int lastarg = 0;
2648 /* spawnve has four arguments: (mode, path, argv, env), where
2649 argv is a list or tuple of strings and env is a dictionary
2650 like posix.environ. */
2652 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
2653 Py_FileSystemDefaultEncoding,
2654 &path, &argv, &env))
2655 return NULL;
2656 if (PyList_Check(argv)) {
2657 argc = PyList_Size(argv);
2658 getitem = PyList_GetItem;
2660 else if (PyTuple_Check(argv)) {
2661 argc = PyTuple_Size(argv);
2662 getitem = PyTuple_GetItem;
2664 else {
2665 PyErr_SetString(PyExc_TypeError,
2666 "spawnve() arg 2 must be a tuple or list");
2667 goto fail_0;
2669 if (!PyMapping_Check(env)) {
2670 PyErr_SetString(PyExc_TypeError,
2671 "spawnve() arg 3 must be a mapping object");
2672 goto fail_0;
2675 argvlist = PyMem_NEW(char *, argc+1);
2676 if (argvlist == NULL) {
2677 PyErr_NoMemory();
2678 goto fail_0;
2680 for (i = 0; i < argc; i++) {
2681 if (!PyArg_Parse((*getitem)(argv, i),
2682 "et;spawnve() arg 2 must contain only strings",
2683 Py_FileSystemDefaultEncoding,
2684 &argvlist[i]))
2686 lastarg = i;
2687 goto fail_1;
2690 lastarg = argc;
2691 argvlist[argc] = NULL;
2693 i = PyMapping_Size(env);
2694 if (i < 0)
2695 goto fail_1;
2696 envlist = PyMem_NEW(char *, i + 1);
2697 if (envlist == NULL) {
2698 PyErr_NoMemory();
2699 goto fail_1;
2701 envc = 0;
2702 keys = PyMapping_Keys(env);
2703 vals = PyMapping_Values(env);
2704 if (!keys || !vals)
2705 goto fail_2;
2706 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2707 PyErr_SetString(PyExc_TypeError,
2708 "spawnve(): env.keys() or env.values() is not a list");
2709 goto fail_2;
2712 for (pos = 0; pos < i; pos++) {
2713 char *p, *k, *v;
2714 size_t len;
2716 key = PyList_GetItem(keys, pos);
2717 val = PyList_GetItem(vals, pos);
2718 if (!key || !val)
2719 goto fail_2;
2721 if (!PyArg_Parse(
2722 key,
2723 "s;spawnve() arg 3 contains a non-string key",
2724 &k) ||
2725 !PyArg_Parse(
2726 val,
2727 "s;spawnve() arg 3 contains a non-string value",
2728 &v))
2730 goto fail_2;
2732 len = PyString_Size(key) + PyString_Size(val) + 2;
2733 p = PyMem_NEW(char, len);
2734 if (p == NULL) {
2735 PyErr_NoMemory();
2736 goto fail_2;
2738 PyOS_snprintf(p, len, "%s=%s", k, v);
2739 envlist[envc++] = p;
2741 envlist[envc] = 0;
2743 #if defined(PYOS_OS2) && defined(PYCC_GCC)
2744 Py_BEGIN_ALLOW_THREADS
2745 spawnval = spawnve(mode, path, argvlist, envlist);
2746 Py_END_ALLOW_THREADS
2747 #else
2748 if (mode == _OLD_P_OVERLAY)
2749 mode = _P_OVERLAY;
2751 Py_BEGIN_ALLOW_THREADS
2752 spawnval = _spawnve(mode, path, argvlist, envlist);
2753 Py_END_ALLOW_THREADS
2754 #endif
2756 if (spawnval == -1)
2757 (void) posix_error();
2758 else
2759 #if SIZEOF_LONG == SIZEOF_VOID_P
2760 res = Py_BuildValue("l", (long) spawnval);
2761 #else
2762 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
2763 #endif
2765 fail_2:
2766 while (--envc >= 0)
2767 PyMem_DEL(envlist[envc]);
2768 PyMem_DEL(envlist);
2769 fail_1:
2770 free_string_array(argvlist, lastarg);
2771 Py_XDECREF(vals);
2772 Py_XDECREF(keys);
2773 fail_0:
2774 PyMem_Free(path);
2775 return res;
2778 /* OS/2 supports spawnvp & spawnvpe natively */
2779 #if defined(PYOS_OS2)
2780 PyDoc_STRVAR(posix_spawnvp__doc__,
2781 "spawnvp(mode, file, args)\n\n\
2782 Execute the program 'file' in a new process, using the environment\n\
2783 search path to find the file.\n\
2785 mode: mode of process creation\n\
2786 file: executable file name\n\
2787 args: tuple or list of strings");
2789 static PyObject *
2790 posix_spawnvp(PyObject *self, PyObject *args)
2792 char *path;
2793 PyObject *argv;
2794 char **argvlist;
2795 int mode, i, argc;
2796 Py_intptr_t spawnval;
2797 PyObject *(*getitem)(PyObject *, int);
2799 /* spawnvp has three arguments: (mode, path, argv), where
2800 argv is a list or tuple of strings. */
2802 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
2803 Py_FileSystemDefaultEncoding,
2804 &path, &argv))
2805 return NULL;
2806 if (PyList_Check(argv)) {
2807 argc = PyList_Size(argv);
2808 getitem = PyList_GetItem;
2810 else if (PyTuple_Check(argv)) {
2811 argc = PyTuple_Size(argv);
2812 getitem = PyTuple_GetItem;
2814 else {
2815 PyErr_SetString(PyExc_TypeError,
2816 "spawnvp() arg 2 must be a tuple or list");
2817 PyMem_Free(path);
2818 return NULL;
2821 argvlist = PyMem_NEW(char *, argc+1);
2822 if (argvlist == NULL) {
2823 PyMem_Free(path);
2824 return PyErr_NoMemory();
2826 for (i = 0; i < argc; i++) {
2827 if (!PyArg_Parse((*getitem)(argv, i), "et",
2828 Py_FileSystemDefaultEncoding,
2829 &argvlist[i])) {
2830 free_string_array(argvlist, i);
2831 PyErr_SetString(
2832 PyExc_TypeError,
2833 "spawnvp() arg 2 must contain only strings");
2834 PyMem_Free(path);
2835 return NULL;
2838 argvlist[argc] = NULL;
2840 Py_BEGIN_ALLOW_THREADS
2841 #if defined(PYCC_GCC)
2842 spawnval = spawnvp(mode, path, argvlist);
2843 #else
2844 spawnval = _spawnvp(mode, path, argvlist);
2845 #endif
2846 Py_END_ALLOW_THREADS
2848 free_string_array(argvlist, argc);
2849 PyMem_Free(path);
2851 if (spawnval == -1)
2852 return posix_error();
2853 else
2854 return Py_BuildValue("l", (long) spawnval);
2858 PyDoc_STRVAR(posix_spawnvpe__doc__,
2859 "spawnvpe(mode, file, args, env)\n\n\
2860 Execute the program 'file' in a new process, using the environment\n\
2861 search path to find the file.\n\
2863 mode: mode of process creation\n\
2864 file: executable file name\n\
2865 args: tuple or list of arguments\n\
2866 env: dictionary of strings mapping to strings");
2868 static PyObject *
2869 posix_spawnvpe(PyObject *self, PyObject *args)
2871 char *path;
2872 PyObject *argv, *env;
2873 char **argvlist;
2874 char **envlist;
2875 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
2876 int mode, i, pos, argc, envc;
2877 Py_intptr_t spawnval;
2878 PyObject *(*getitem)(PyObject *, int);
2879 int lastarg = 0;
2881 /* spawnvpe has four arguments: (mode, path, argv, env), where
2882 argv is a list or tuple of strings and env is a dictionary
2883 like posix.environ. */
2885 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
2886 Py_FileSystemDefaultEncoding,
2887 &path, &argv, &env))
2888 return NULL;
2889 if (PyList_Check(argv)) {
2890 argc = PyList_Size(argv);
2891 getitem = PyList_GetItem;
2893 else if (PyTuple_Check(argv)) {
2894 argc = PyTuple_Size(argv);
2895 getitem = PyTuple_GetItem;
2897 else {
2898 PyErr_SetString(PyExc_TypeError,
2899 "spawnvpe() arg 2 must be a tuple or list");
2900 goto fail_0;
2902 if (!PyMapping_Check(env)) {
2903 PyErr_SetString(PyExc_TypeError,
2904 "spawnvpe() arg 3 must be a mapping object");
2905 goto fail_0;
2908 argvlist = PyMem_NEW(char *, argc+1);
2909 if (argvlist == NULL) {
2910 PyErr_NoMemory();
2911 goto fail_0;
2913 for (i = 0; i < argc; i++) {
2914 if (!PyArg_Parse((*getitem)(argv, i),
2915 "et;spawnvpe() arg 2 must contain only strings",
2916 Py_FileSystemDefaultEncoding,
2917 &argvlist[i]))
2919 lastarg = i;
2920 goto fail_1;
2923 lastarg = argc;
2924 argvlist[argc] = NULL;
2926 i = PyMapping_Size(env);
2927 if (i < 0)
2928 goto fail_1;
2929 envlist = PyMem_NEW(char *, i + 1);
2930 if (envlist == NULL) {
2931 PyErr_NoMemory();
2932 goto fail_1;
2934 envc = 0;
2935 keys = PyMapping_Keys(env);
2936 vals = PyMapping_Values(env);
2937 if (!keys || !vals)
2938 goto fail_2;
2939 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2940 PyErr_SetString(PyExc_TypeError,
2941 "spawnvpe(): env.keys() or env.values() is not a list");
2942 goto fail_2;
2945 for (pos = 0; pos < i; pos++) {
2946 char *p, *k, *v;
2947 size_t len;
2949 key = PyList_GetItem(keys, pos);
2950 val = PyList_GetItem(vals, pos);
2951 if (!key || !val)
2952 goto fail_2;
2954 if (!PyArg_Parse(
2955 key,
2956 "s;spawnvpe() arg 3 contains a non-string key",
2957 &k) ||
2958 !PyArg_Parse(
2959 val,
2960 "s;spawnvpe() arg 3 contains a non-string value",
2961 &v))
2963 goto fail_2;
2965 len = PyString_Size(key) + PyString_Size(val) + 2;
2966 p = PyMem_NEW(char, len);
2967 if (p == NULL) {
2968 PyErr_NoMemory();
2969 goto fail_2;
2971 PyOS_snprintf(p, len, "%s=%s", k, v);
2972 envlist[envc++] = p;
2974 envlist[envc] = 0;
2976 Py_BEGIN_ALLOW_THREADS
2977 #if defined(PYCC_GCC)
2978 spawnval = spawnve(mode, path, argvlist, envlist);
2979 #else
2980 spawnval = _spawnve(mode, path, argvlist, envlist);
2981 #endif
2982 Py_END_ALLOW_THREADS
2984 if (spawnval == -1)
2985 (void) posix_error();
2986 else
2987 res = Py_BuildValue("l", (long) spawnval);
2989 fail_2:
2990 while (--envc >= 0)
2991 PyMem_DEL(envlist[envc]);
2992 PyMem_DEL(envlist);
2993 fail_1:
2994 free_string_array(argvlist, lastarg);
2995 Py_XDECREF(vals);
2996 Py_XDECREF(keys);
2997 fail_0:
2998 PyMem_Free(path);
2999 return res;
3001 #endif /* PYOS_OS2 */
3002 #endif /* HAVE_SPAWNV */
3005 #ifdef HAVE_FORK1
3006 PyDoc_STRVAR(posix_fork1__doc__,
3007 "fork1() -> pid\n\n\
3008 Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3010 Return 0 to child process and PID of child to parent process.");
3012 static PyObject *
3013 posix_fork1(PyObject *self, PyObject *noargs)
3015 int pid = fork1();
3016 if (pid == -1)
3017 return posix_error();
3018 PyOS_AfterFork();
3019 return PyInt_FromLong((long)pid);
3021 #endif
3024 #ifdef HAVE_FORK
3025 PyDoc_STRVAR(posix_fork__doc__,
3026 "fork() -> pid\n\n\
3027 Fork a child process.\n\
3028 Return 0 to child process and PID of child to parent process.");
3030 static PyObject *
3031 posix_fork(PyObject *self, PyObject *noargs)
3033 int pid = fork();
3034 if (pid == -1)
3035 return posix_error();
3036 if (pid == 0)
3037 PyOS_AfterFork();
3038 return PyInt_FromLong((long)pid);
3040 #endif
3042 /* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
3043 /* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3044 #if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
3045 #define DEV_PTY_FILE "/dev/ptc"
3046 #define HAVE_DEV_PTMX
3047 #else
3048 #define DEV_PTY_FILE "/dev/ptmx"
3049 #endif
3051 #if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
3052 #ifdef HAVE_PTY_H
3053 #include <pty.h>
3054 #else
3055 #ifdef HAVE_LIBUTIL_H
3056 #include <libutil.h>
3057 #endif /* HAVE_LIBUTIL_H */
3058 #endif /* HAVE_PTY_H */
3059 #ifdef HAVE_STROPTS_H
3060 #include <stropts.h>
3061 #endif
3062 #endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
3064 #if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
3065 PyDoc_STRVAR(posix_openpty__doc__,
3066 "openpty() -> (master_fd, slave_fd)\n\n\
3067 Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
3069 static PyObject *
3070 posix_openpty(PyObject *self, PyObject *noargs)
3072 int master_fd, slave_fd;
3073 #ifndef HAVE_OPENPTY
3074 char * slave_name;
3075 #endif
3076 #if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
3077 PyOS_sighandler_t sig_saved;
3078 #ifdef sun
3079 extern char *ptsname();
3080 #endif
3081 #endif
3083 #ifdef HAVE_OPENPTY
3084 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
3085 return posix_error();
3086 #elif defined(HAVE__GETPTY)
3087 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
3088 if (slave_name == NULL)
3089 return posix_error();
3091 slave_fd = open(slave_name, O_RDWR);
3092 if (slave_fd < 0)
3093 return posix_error();
3094 #else
3095 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
3096 if (master_fd < 0)
3097 return posix_error();
3098 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
3099 /* change permission of slave */
3100 if (grantpt(master_fd) < 0) {
3101 PyOS_setsig(SIGCHLD, sig_saved);
3102 return posix_error();
3104 /* unlock slave */
3105 if (unlockpt(master_fd) < 0) {
3106 PyOS_setsig(SIGCHLD, sig_saved);
3107 return posix_error();
3109 PyOS_setsig(SIGCHLD, sig_saved);
3110 slave_name = ptsname(master_fd); /* get name of slave */
3111 if (slave_name == NULL)
3112 return posix_error();
3113 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
3114 if (slave_fd < 0)
3115 return posix_error();
3116 #if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
3117 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
3118 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
3119 #ifndef __hpux
3120 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
3121 #endif /* __hpux */
3122 #endif /* HAVE_CYGWIN */
3123 #endif /* HAVE_OPENPTY */
3125 return Py_BuildValue("(ii)", master_fd, slave_fd);
3128 #endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
3130 #ifdef HAVE_FORKPTY
3131 PyDoc_STRVAR(posix_forkpty__doc__,
3132 "forkpty() -> (pid, master_fd)\n\n\
3133 Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
3134 Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
3135 To both, return fd of newly opened pseudo-terminal.\n");
3137 static PyObject *
3138 posix_forkpty(PyObject *self, PyObject *noargs)
3140 int master_fd = -1, pid;
3142 pid = forkpty(&master_fd, NULL, NULL, NULL);
3143 if (pid == -1)
3144 return posix_error();
3145 if (pid == 0)
3146 PyOS_AfterFork();
3147 return Py_BuildValue("(ii)", pid, master_fd);
3149 #endif
3151 #ifdef HAVE_GETEGID
3152 PyDoc_STRVAR(posix_getegid__doc__,
3153 "getegid() -> egid\n\n\
3154 Return the current process's effective group id.");
3156 static PyObject *
3157 posix_getegid(PyObject *self, PyObject *noargs)
3159 return PyInt_FromLong((long)getegid());
3161 #endif
3164 #ifdef HAVE_GETEUID
3165 PyDoc_STRVAR(posix_geteuid__doc__,
3166 "geteuid() -> euid\n\n\
3167 Return the current process's effective user id.");
3169 static PyObject *
3170 posix_geteuid(PyObject *self, PyObject *noargs)
3172 return PyInt_FromLong((long)geteuid());
3174 #endif
3177 #ifdef HAVE_GETGID
3178 PyDoc_STRVAR(posix_getgid__doc__,
3179 "getgid() -> gid\n\n\
3180 Return the current process's group id.");
3182 static PyObject *
3183 posix_getgid(PyObject *self, PyObject *noargs)
3185 return PyInt_FromLong((long)getgid());
3187 #endif
3190 PyDoc_STRVAR(posix_getpid__doc__,
3191 "getpid() -> pid\n\n\
3192 Return the current process id");
3194 static PyObject *
3195 posix_getpid(PyObject *self, PyObject *noargs)
3197 return PyInt_FromLong((long)getpid());
3201 #ifdef HAVE_GETGROUPS
3202 PyDoc_STRVAR(posix_getgroups__doc__,
3203 "getgroups() -> list of group IDs\n\n\
3204 Return list of supplemental group IDs for the process.");
3206 static PyObject *
3207 posix_getgroups(PyObject *self, PyObject *noargs)
3209 PyObject *result = NULL;
3211 #ifdef NGROUPS_MAX
3212 #define MAX_GROUPS NGROUPS_MAX
3213 #else
3214 /* defined to be 16 on Solaris7, so this should be a small number */
3215 #define MAX_GROUPS 64
3216 #endif
3217 gid_t grouplist[MAX_GROUPS];
3218 int n;
3220 n = getgroups(MAX_GROUPS, grouplist);
3221 if (n < 0)
3222 posix_error();
3223 else {
3224 result = PyList_New(n);
3225 if (result != NULL) {
3226 int i;
3227 for (i = 0; i < n; ++i) {
3228 PyObject *o = PyInt_FromLong((long)grouplist[i]);
3229 if (o == NULL) {
3230 Py_DECREF(result);
3231 result = NULL;
3232 break;
3234 PyList_SET_ITEM(result, i, o);
3239 return result;
3241 #endif
3243 #ifdef HAVE_GETPGID
3244 PyDoc_STRVAR(posix_getpgid__doc__,
3245 "getpgid(pid) -> pgid\n\n\
3246 Call the system call getpgid().");
3248 static PyObject *
3249 posix_getpgid(PyObject *self, PyObject *args)
3251 int pid, pgid;
3252 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
3253 return NULL;
3254 pgid = getpgid(pid);
3255 if (pgid < 0)
3256 return posix_error();
3257 return PyInt_FromLong((long)pgid);
3259 #endif /* HAVE_GETPGID */
3262 #ifdef HAVE_GETPGRP
3263 PyDoc_STRVAR(posix_getpgrp__doc__,
3264 "getpgrp() -> pgrp\n\n\
3265 Return the current process group id.");
3267 static PyObject *
3268 posix_getpgrp(PyObject *self, PyObject *noargs)
3270 #ifdef GETPGRP_HAVE_ARG
3271 return PyInt_FromLong((long)getpgrp(0));
3272 #else /* GETPGRP_HAVE_ARG */
3273 return PyInt_FromLong((long)getpgrp());
3274 #endif /* GETPGRP_HAVE_ARG */
3276 #endif /* HAVE_GETPGRP */
3279 #ifdef HAVE_SETPGRP
3280 PyDoc_STRVAR(posix_setpgrp__doc__,
3281 "setpgrp()\n\n\
3282 Make this process a session leader.");
3284 static PyObject *
3285 posix_setpgrp(PyObject *self, PyObject *noargs)
3287 #ifdef SETPGRP_HAVE_ARG
3288 if (setpgrp(0, 0) < 0)
3289 #else /* SETPGRP_HAVE_ARG */
3290 if (setpgrp() < 0)
3291 #endif /* SETPGRP_HAVE_ARG */
3292 return posix_error();
3293 Py_INCREF(Py_None);
3294 return Py_None;
3297 #endif /* HAVE_SETPGRP */
3299 #ifdef HAVE_GETPPID
3300 PyDoc_STRVAR(posix_getppid__doc__,
3301 "getppid() -> ppid\n\n\
3302 Return the parent's process id.");
3304 static PyObject *
3305 posix_getppid(PyObject *self, PyObject *noargs)
3307 return PyInt_FromLong((long)getppid());
3309 #endif
3312 #ifdef HAVE_GETLOGIN
3313 PyDoc_STRVAR(posix_getlogin__doc__,
3314 "getlogin() -> string\n\n\
3315 Return the actual login name.");
3317 static PyObject *
3318 posix_getlogin(PyObject *self, PyObject *noargs)
3320 PyObject *result = NULL;
3321 char *name;
3322 int old_errno = errno;
3324 errno = 0;
3325 name = getlogin();
3326 if (name == NULL) {
3327 if (errno)
3328 posix_error();
3329 else
3330 PyErr_SetString(PyExc_OSError,
3331 "unable to determine login name");
3333 else
3334 result = PyString_FromString(name);
3335 errno = old_errno;
3337 return result;
3339 #endif
3341 #ifdef HAVE_GETUID
3342 PyDoc_STRVAR(posix_getuid__doc__,
3343 "getuid() -> uid\n\n\
3344 Return the current process's user id.");
3346 static PyObject *
3347 posix_getuid(PyObject *self, PyObject *noargs)
3349 return PyInt_FromLong((long)getuid());
3351 #endif
3354 #ifdef HAVE_KILL
3355 PyDoc_STRVAR(posix_kill__doc__,
3356 "kill(pid, sig)\n\n\
3357 Kill a process with a signal.");
3359 static PyObject *
3360 posix_kill(PyObject *self, PyObject *args)
3362 int pid, sig;
3363 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
3364 return NULL;
3365 #if defined(PYOS_OS2) && !defined(PYCC_GCC)
3366 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
3367 APIRET rc;
3368 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
3369 return os2_error(rc);
3371 } else if (sig == XCPT_SIGNAL_KILLPROC) {
3372 APIRET rc;
3373 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
3374 return os2_error(rc);
3376 } else
3377 return NULL; /* Unrecognized Signal Requested */
3378 #else
3379 if (kill(pid, sig) == -1)
3380 return posix_error();
3381 #endif
3382 Py_INCREF(Py_None);
3383 return Py_None;
3385 #endif
3387 #ifdef HAVE_KILLPG
3388 PyDoc_STRVAR(posix_killpg__doc__,
3389 "killpg(pgid, sig)\n\n\
3390 Kill a process group with a signal.");
3392 static PyObject *
3393 posix_killpg(PyObject *self, PyObject *args)
3395 int pgid, sig;
3396 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
3397 return NULL;
3398 if (killpg(pgid, sig) == -1)
3399 return posix_error();
3400 Py_INCREF(Py_None);
3401 return Py_None;
3403 #endif
3405 #ifdef HAVE_PLOCK
3407 #ifdef HAVE_SYS_LOCK_H
3408 #include <sys/lock.h>
3409 #endif
3411 PyDoc_STRVAR(posix_plock__doc__,
3412 "plock(op)\n\n\
3413 Lock program segments into memory.");
3415 static PyObject *
3416 posix_plock(PyObject *self, PyObject *args)
3418 int op;
3419 if (!PyArg_ParseTuple(args, "i:plock", &op))
3420 return NULL;
3421 if (plock(op) == -1)
3422 return posix_error();
3423 Py_INCREF(Py_None);
3424 return Py_None;
3426 #endif
3429 #ifdef HAVE_POPEN
3430 PyDoc_STRVAR(posix_popen__doc__,
3431 "popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
3432 Open a pipe to/from a command returning a file object.");
3434 #if defined(PYOS_OS2)
3435 #if defined(PYCC_VACPP)
3436 static int
3437 async_system(const char *command)
3439 char errormsg[256], args[1024];
3440 RESULTCODES rcodes;
3441 APIRET rc;
3443 char *shell = getenv("COMSPEC");
3444 if (!shell)
3445 shell = "cmd";
3447 /* avoid overflowing the argument buffer */
3448 if (strlen(shell) + 3 + strlen(command) >= 1024)
3449 return ERROR_NOT_ENOUGH_MEMORY
3451 args[0] = '\0';
3452 strcat(args, shell);
3453 strcat(args, "/c ");
3454 strcat(args, command);
3456 /* execute asynchronously, inheriting the environment */
3457 rc = DosExecPgm(errormsg,
3458 sizeof(errormsg),
3459 EXEC_ASYNC,
3460 args,
3461 NULL,
3462 &rcodes,
3463 shell);
3464 return rc;
3467 static FILE *
3468 popen(const char *command, const char *mode, int pipesize, int *err)
3470 int oldfd, tgtfd;
3471 HFILE pipeh[2];
3472 APIRET rc;
3474 /* mode determines which of stdin or stdout is reconnected to
3475 * the pipe to the child
3477 if (strchr(mode, 'r') != NULL) {
3478 tgt_fd = 1; /* stdout */
3479 } else if (strchr(mode, 'w')) {
3480 tgt_fd = 0; /* stdin */
3481 } else {
3482 *err = ERROR_INVALID_ACCESS;
3483 return NULL;
3486 /* setup the pipe */
3487 if ((rc = DosCreatePipe(&pipeh[0], &pipeh[1], pipesize)) != NO_ERROR) {
3488 *err = rc;
3489 return NULL;
3492 /* prevent other threads accessing stdio */
3493 DosEnterCritSec();
3495 /* reconnect stdio and execute child */
3496 oldfd = dup(tgtfd);
3497 close(tgtfd);
3498 if (dup2(pipeh[tgtfd], tgtfd) == 0) {
3499 DosClose(pipeh[tgtfd]);
3500 rc = async_system(command);
3503 /* restore stdio */
3504 dup2(oldfd, tgtfd);
3505 close(oldfd);
3507 /* allow other threads access to stdio */
3508 DosExitCritSec();
3510 /* if execution of child was successful return file stream */
3511 if (rc == NO_ERROR)
3512 return fdopen(pipeh[1 - tgtfd], mode);
3513 else {
3514 DosClose(pipeh[1 - tgtfd]);
3515 *err = rc;
3516 return NULL;
3520 static PyObject *
3521 posix_popen(PyObject *self, PyObject *args)
3523 char *name;
3524 char *mode = "r";
3525 int err, bufsize = -1;
3526 FILE *fp;
3527 PyObject *f;
3528 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
3529 return NULL;
3530 Py_BEGIN_ALLOW_THREADS
3531 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
3532 Py_END_ALLOW_THREADS
3533 if (fp == NULL)
3534 return os2_error(err);
3536 f = PyFile_FromFile(fp, name, mode, fclose);
3537 if (f != NULL)
3538 PyFile_SetBufSize(f, bufsize);
3539 return f;
3542 #elif defined(PYCC_GCC)
3544 /* standard posix version of popen() support */
3545 static PyObject *
3546 posix_popen(PyObject *self, PyObject *args)
3548 char *name;
3549 char *mode = "r";
3550 int bufsize = -1;
3551 FILE *fp;
3552 PyObject *f;
3553 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
3554 return NULL;
3555 Py_BEGIN_ALLOW_THREADS
3556 fp = popen(name, mode);
3557 Py_END_ALLOW_THREADS
3558 if (fp == NULL)
3559 return posix_error();
3560 f = PyFile_FromFile(fp, name, mode, pclose);
3561 if (f != NULL)
3562 PyFile_SetBufSize(f, bufsize);
3563 return f;
3566 /* fork() under OS/2 has lots'o'warts
3567 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
3568 * most of this code is a ripoff of the win32 code, but using the
3569 * capabilities of EMX's C library routines
3572 /* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
3573 #define POPEN_1 1
3574 #define POPEN_2 2
3575 #define POPEN_3 3
3576 #define POPEN_4 4
3578 static PyObject *_PyPopen(char *, int, int, int);
3579 static int _PyPclose(FILE *file);
3582 * Internal dictionary mapping popen* file pointers to process handles,
3583 * for use when retrieving the process exit code. See _PyPclose() below
3584 * for more information on this dictionary's use.
3586 static PyObject *_PyPopenProcs = NULL;
3588 /* os2emx version of popen2()
3590 * The result of this function is a pipe (file) connected to the
3591 * process's stdin, and a pipe connected to the process's stdout.
3594 static PyObject *
3595 os2emx_popen2(PyObject *self, PyObject *args)
3597 PyObject *f;
3598 int tm=0;
3600 char *cmdstring;
3601 char *mode = "t";
3602 int bufsize = -1;
3603 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
3604 return NULL;
3606 if (*mode == 't')
3607 tm = O_TEXT;
3608 else if (*mode != 'b') {
3609 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3610 return NULL;
3611 } else
3612 tm = O_BINARY;
3614 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
3616 return f;
3620 * Variation on os2emx.popen2
3622 * The result of this function is 3 pipes - the process's stdin,
3623 * stdout and stderr
3626 static PyObject *
3627 os2emx_popen3(PyObject *self, PyObject *args)
3629 PyObject *f;
3630 int tm = 0;
3632 char *cmdstring;
3633 char *mode = "t";
3634 int bufsize = -1;
3635 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
3636 return NULL;
3638 if (*mode == 't')
3639 tm = O_TEXT;
3640 else if (*mode != 'b') {
3641 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3642 return NULL;
3643 } else
3644 tm = O_BINARY;
3646 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
3648 return f;
3652 * Variation on os2emx.popen2
3654 * The result of this function is 2 pipes - the processes stdin,
3655 * and stdout+stderr combined as a single pipe.
3658 static PyObject *
3659 os2emx_popen4(PyObject *self, PyObject *args)
3661 PyObject *f;
3662 int tm = 0;
3664 char *cmdstring;
3665 char *mode = "t";
3666 int bufsize = -1;
3667 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
3668 return NULL;
3670 if (*mode == 't')
3671 tm = O_TEXT;
3672 else if (*mode != 'b') {
3673 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3674 return NULL;
3675 } else
3676 tm = O_BINARY;
3678 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
3680 return f;
3683 /* a couple of structures for convenient handling of multiple
3684 * file handles and pipes
3686 struct file_ref
3688 int handle;
3689 int flags;
3692 struct pipe_ref
3694 int rd;
3695 int wr;
3698 /* The following code is derived from the win32 code */
3700 static PyObject *
3701 _PyPopen(char *cmdstring, int mode, int n, int bufsize)
3703 struct file_ref stdio[3];
3704 struct pipe_ref p_fd[3];
3705 FILE *p_s[3];
3706 int file_count, i, pipe_err, pipe_pid;
3707 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
3708 PyObject *f, *p_f[3];
3710 /* file modes for subsequent fdopen's on pipe handles */
3711 if (mode == O_TEXT)
3713 rd_mode = "rt";
3714 wr_mode = "wt";
3716 else
3718 rd_mode = "rb";
3719 wr_mode = "wb";
3722 /* prepare shell references */
3723 if ((shell = getenv("EMXSHELL")) == NULL)
3724 if ((shell = getenv("COMSPEC")) == NULL)
3726 errno = ENOENT;
3727 return posix_error();
3730 sh_name = _getname(shell);
3731 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
3732 opt = "/c";
3733 else
3734 opt = "-c";
3736 /* save current stdio fds + their flags, and set not inheritable */
3737 i = pipe_err = 0;
3738 while (pipe_err >= 0 && i < 3)
3740 pipe_err = stdio[i].handle = dup(i);
3741 stdio[i].flags = fcntl(i, F_GETFD, 0);
3742 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
3743 i++;
3745 if (pipe_err < 0)
3747 /* didn't get them all saved - clean up and bail out */
3748 int saved_err = errno;
3749 while (i-- > 0)
3751 close(stdio[i].handle);
3753 errno = saved_err;
3754 return posix_error();
3757 /* create pipe ends */
3758 file_count = 2;
3759 if (n == POPEN_3)
3760 file_count = 3;
3761 i = pipe_err = 0;
3762 while ((pipe_err == 0) && (i < file_count))
3763 pipe_err = pipe((int *)&p_fd[i++]);
3764 if (pipe_err < 0)
3766 /* didn't get them all made - clean up and bail out */
3767 while (i-- > 0)
3769 close(p_fd[i].wr);
3770 close(p_fd[i].rd);
3772 errno = EPIPE;
3773 return posix_error();
3776 /* change the actual standard IO streams over temporarily,
3777 * making the retained pipe ends non-inheritable
3779 pipe_err = 0;
3781 /* - stdin */
3782 if (dup2(p_fd[0].rd, 0) == 0)
3784 close(p_fd[0].rd);
3785 i = fcntl(p_fd[0].wr, F_GETFD, 0);
3786 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
3787 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
3789 close(p_fd[0].wr);
3790 pipe_err = -1;
3793 else
3795 pipe_err = -1;
3798 /* - stdout */
3799 if (pipe_err == 0)
3801 if (dup2(p_fd[1].wr, 1) == 1)
3803 close(p_fd[1].wr);
3804 i = fcntl(p_fd[1].rd, F_GETFD, 0);
3805 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
3806 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
3808 close(p_fd[1].rd);
3809 pipe_err = -1;
3812 else
3814 pipe_err = -1;
3818 /* - stderr, as required */
3819 if (pipe_err == 0)
3820 switch (n)
3822 case POPEN_3:
3824 if (dup2(p_fd[2].wr, 2) == 2)
3826 close(p_fd[2].wr);
3827 i = fcntl(p_fd[2].rd, F_GETFD, 0);
3828 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
3829 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
3831 close(p_fd[2].rd);
3832 pipe_err = -1;
3835 else
3837 pipe_err = -1;
3839 break;
3842 case POPEN_4:
3844 if (dup2(1, 2) != 2)
3846 pipe_err = -1;
3848 break;
3852 /* spawn the child process */
3853 if (pipe_err == 0)
3855 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
3856 if (pipe_pid == -1)
3858 pipe_err = -1;
3860 else
3862 /* save the PID into the FILE structure
3863 * NOTE: this implementation doesn't actually
3864 * take advantage of this, but do it for
3865 * completeness - AIM Apr01
3867 for (i = 0; i < file_count; i++)
3868 p_s[i]->_pid = pipe_pid;
3872 /* reset standard IO to normal */
3873 for (i = 0; i < 3; i++)
3875 dup2(stdio[i].handle, i);
3876 fcntl(i, F_SETFD, stdio[i].flags);
3877 close(stdio[i].handle);
3880 /* if any remnant problems, clean up and bail out */
3881 if (pipe_err < 0)
3883 for (i = 0; i < 3; i++)
3885 close(p_fd[i].rd);
3886 close(p_fd[i].wr);
3888 errno = EPIPE;
3889 return posix_error_with_filename(cmdstring);
3892 /* build tuple of file objects to return */
3893 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
3894 PyFile_SetBufSize(p_f[0], bufsize);
3895 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
3896 PyFile_SetBufSize(p_f[1], bufsize);
3897 if (n == POPEN_3)
3899 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
3900 PyFile_SetBufSize(p_f[0], bufsize);
3901 f = PyTuple_Pack(3, p_f[0], p_f[1], p_f[2]);
3903 else
3904 f = PyTuple_Pack(2, p_f[0], p_f[1]);
3907 * Insert the files we've created into the process dictionary
3908 * all referencing the list with the process handle and the
3909 * initial number of files (see description below in _PyPclose).
3910 * Since if _PyPclose later tried to wait on a process when all
3911 * handles weren't closed, it could create a deadlock with the
3912 * child, we spend some energy here to try to ensure that we
3913 * either insert all file handles into the dictionary or none
3914 * at all. It's a little clumsy with the various popen modes
3915 * and variable number of files involved.
3917 if (!_PyPopenProcs)
3919 _PyPopenProcs = PyDict_New();
3922 if (_PyPopenProcs)
3924 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
3925 int ins_rc[3];
3927 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
3928 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
3930 procObj = PyList_New(2);
3931 pidObj = PyInt_FromLong((long) pipe_pid);
3932 intObj = PyInt_FromLong((long) file_count);
3934 if (procObj && pidObj && intObj)
3936 PyList_SetItem(procObj, 0, pidObj);
3937 PyList_SetItem(procObj, 1, intObj);
3939 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
3940 if (fileObj[0])
3942 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
3943 fileObj[0],
3944 procObj);
3946 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
3947 if (fileObj[1])
3949 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
3950 fileObj[1],
3951 procObj);
3953 if (file_count >= 3)
3955 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
3956 if (fileObj[2])
3958 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
3959 fileObj[2],
3960 procObj);
3964 if (ins_rc[0] < 0 || !fileObj[0] ||
3965 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
3966 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
3968 /* Something failed - remove any dictionary
3969 * entries that did make it.
3971 if (!ins_rc[0] && fileObj[0])
3973 PyDict_DelItem(_PyPopenProcs,
3974 fileObj[0]);
3976 if (!ins_rc[1] && fileObj[1])
3978 PyDict_DelItem(_PyPopenProcs,
3979 fileObj[1]);
3981 if (!ins_rc[2] && fileObj[2])
3983 PyDict_DelItem(_PyPopenProcs,
3984 fileObj[2]);
3990 * Clean up our localized references for the dictionary keys
3991 * and value since PyDict_SetItem will Py_INCREF any copies
3992 * that got placed in the dictionary.
3994 Py_XDECREF(procObj);
3995 Py_XDECREF(fileObj[0]);
3996 Py_XDECREF(fileObj[1]);
3997 Py_XDECREF(fileObj[2]);
4000 /* Child is launched. */
4001 return f;
4005 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4006 * exit code for the child process and return as a result of the close.
4008 * This function uses the _PyPopenProcs dictionary in order to map the
4009 * input file pointer to information about the process that was
4010 * originally created by the popen* call that created the file pointer.
4011 * The dictionary uses the file pointer as a key (with one entry
4012 * inserted for each file returned by the original popen* call) and a
4013 * single list object as the value for all files from a single call.
4014 * The list object contains the Win32 process handle at [0], and a file
4015 * count at [1], which is initialized to the total number of file
4016 * handles using that list.
4018 * This function closes whichever handle it is passed, and decrements
4019 * the file count in the dictionary for the process handle pointed to
4020 * by this file. On the last close (when the file count reaches zero),
4021 * this function will wait for the child process and then return its
4022 * exit code as the result of the close() operation. This permits the
4023 * files to be closed in any order - it is always the close() of the
4024 * final handle that will return the exit code.
4026 * NOTE: This function is currently called with the GIL released.
4027 * hence we use the GILState API to manage our state.
4030 static int _PyPclose(FILE *file)
4032 int result;
4033 int exit_code;
4034 int pipe_pid;
4035 PyObject *procObj, *pidObj, *intObj, *fileObj;
4036 int file_count;
4037 #ifdef WITH_THREAD
4038 PyGILState_STATE state;
4039 #endif
4041 /* Close the file handle first, to ensure it can't block the
4042 * child from exiting if it's the last handle.
4044 result = fclose(file);
4046 #ifdef WITH_THREAD
4047 state = PyGILState_Ensure();
4048 #endif
4049 if (_PyPopenProcs)
4051 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4052 (procObj = PyDict_GetItem(_PyPopenProcs,
4053 fileObj)) != NULL &&
4054 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
4055 (intObj = PyList_GetItem(procObj,1)) != NULL)
4057 pipe_pid = (int) PyInt_AsLong(pidObj);
4058 file_count = (int) PyInt_AsLong(intObj);
4060 if (file_count > 1)
4062 /* Still other files referencing process */
4063 file_count--;
4064 PyList_SetItem(procObj,1,
4065 PyInt_FromLong((long) file_count));
4067 else
4069 /* Last file for this process */
4070 if (result != EOF &&
4071 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
4073 /* extract exit status */
4074 if (WIFEXITED(exit_code))
4076 result = WEXITSTATUS(exit_code);
4078 else
4080 errno = EPIPE;
4081 result = -1;
4084 else
4086 /* Indicate failure - this will cause the file object
4087 * to raise an I/O error and translate the last
4088 * error code from errno. We do have a problem with
4089 * last errors that overlap the normal errno table,
4090 * but that's a consistent problem with the file object.
4092 result = -1;
4096 /* Remove this file pointer from dictionary */
4097 PyDict_DelItem(_PyPopenProcs, fileObj);
4099 if (PyDict_Size(_PyPopenProcs) == 0)
4101 Py_DECREF(_PyPopenProcs);
4102 _PyPopenProcs = NULL;
4105 } /* if object retrieval ok */
4107 Py_XDECREF(fileObj);
4108 } /* if _PyPopenProcs */
4110 #ifdef WITH_THREAD
4111 PyGILState_Release(state);
4112 #endif
4113 return result;
4116 #endif /* PYCC_??? */
4118 #elif defined(MS_WINDOWS)
4121 * Portable 'popen' replacement for Win32.
4123 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
4124 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
4125 * Return code handling by David Bolen <db3l@fitlinxx.com>.
4128 #include <malloc.h>
4129 #include <io.h>
4130 #include <fcntl.h>
4132 /* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
4133 #define POPEN_1 1
4134 #define POPEN_2 2
4135 #define POPEN_3 3
4136 #define POPEN_4 4
4138 static PyObject *_PyPopen(char *, int, int);
4139 static int _PyPclose(FILE *file);
4142 * Internal dictionary mapping popen* file pointers to process handles,
4143 * for use when retrieving the process exit code. See _PyPclose() below
4144 * for more information on this dictionary's use.
4146 static PyObject *_PyPopenProcs = NULL;
4149 /* popen that works from a GUI.
4151 * The result of this function is a pipe (file) connected to the
4152 * processes stdin or stdout, depending on the requested mode.
4155 static PyObject *
4156 posix_popen(PyObject *self, PyObject *args)
4158 PyObject *f;
4159 int tm = 0;
4161 char *cmdstring;
4162 char *mode = "r";
4163 int bufsize = -1;
4164 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
4165 return NULL;
4167 if (*mode == 'r')
4168 tm = _O_RDONLY;
4169 else if (*mode != 'w') {
4170 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
4171 return NULL;
4172 } else
4173 tm = _O_WRONLY;
4175 if (bufsize != -1) {
4176 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
4177 return NULL;
4180 if (*(mode+1) == 't')
4181 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
4182 else if (*(mode+1) == 'b')
4183 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
4184 else
4185 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
4187 return f;
4190 /* Variation on win32pipe.popen
4192 * The result of this function is a pipe (file) connected to the
4193 * process's stdin, and a pipe connected to the process's stdout.
4196 static PyObject *
4197 win32_popen2(PyObject *self, PyObject *args)
4199 PyObject *f;
4200 int tm=0;
4202 char *cmdstring;
4203 char *mode = "t";
4204 int bufsize = -1;
4205 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
4206 return NULL;
4208 if (*mode == 't')
4209 tm = _O_TEXT;
4210 else if (*mode != 'b') {
4211 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
4212 return NULL;
4213 } else
4214 tm = _O_BINARY;
4216 if (bufsize != -1) {
4217 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
4218 return NULL;
4221 f = _PyPopen(cmdstring, tm, POPEN_2);
4223 return f;
4227 * Variation on <om win32pipe.popen>
4229 * The result of this function is 3 pipes - the process's stdin,
4230 * stdout and stderr
4233 static PyObject *
4234 win32_popen3(PyObject *self, PyObject *args)
4236 PyObject *f;
4237 int tm = 0;
4239 char *cmdstring;
4240 char *mode = "t";
4241 int bufsize = -1;
4242 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
4243 return NULL;
4245 if (*mode == 't')
4246 tm = _O_TEXT;
4247 else if (*mode != 'b') {
4248 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
4249 return NULL;
4250 } else
4251 tm = _O_BINARY;
4253 if (bufsize != -1) {
4254 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
4255 return NULL;
4258 f = _PyPopen(cmdstring, tm, POPEN_3);
4260 return f;
4264 * Variation on win32pipe.popen
4266 * The result of this function is 2 pipes - the processes stdin,
4267 * and stdout+stderr combined as a single pipe.
4270 static PyObject *
4271 win32_popen4(PyObject *self, PyObject *args)
4273 PyObject *f;
4274 int tm = 0;
4276 char *cmdstring;
4277 char *mode = "t";
4278 int bufsize = -1;
4279 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
4280 return NULL;
4282 if (*mode == 't')
4283 tm = _O_TEXT;
4284 else if (*mode != 'b') {
4285 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
4286 return NULL;
4287 } else
4288 tm = _O_BINARY;
4290 if (bufsize != -1) {
4291 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
4292 return NULL;
4295 f = _PyPopen(cmdstring, tm, POPEN_4);
4297 return f;
4300 static BOOL
4301 _PyPopenCreateProcess(char *cmdstring,
4302 HANDLE hStdin,
4303 HANDLE hStdout,
4304 HANDLE hStderr,
4305 HANDLE *hProcess)
4307 PROCESS_INFORMATION piProcInfo;
4308 STARTUPINFO siStartInfo;
4309 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
4310 char *s1,*s2, *s3 = " /c ";
4311 const char *szConsoleSpawn = "w9xpopen.exe";
4312 int i;
4313 int x;
4315 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
4316 char *comshell;
4318 s1 = (char *)alloca(i);
4319 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
4320 return x;
4322 /* Explicitly check if we are using COMMAND.COM. If we are
4323 * then use the w9xpopen hack.
4325 comshell = s1 + x;
4326 while (comshell >= s1 && *comshell != '\\')
4327 --comshell;
4328 ++comshell;
4330 if (GetVersion() < 0x80000000 &&
4331 _stricmp(comshell, "command.com") != 0) {
4332 /* NT/2000 and not using command.com. */
4333 x = i + strlen(s3) + strlen(cmdstring) + 1;
4334 s2 = (char *)alloca(x);
4335 ZeroMemory(s2, x);
4336 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
4338 else {
4340 * Oh gag, we're on Win9x or using COMMAND.COM. Use
4341 * the workaround listed in KB: Q150956
4343 char modulepath[_MAX_PATH];
4344 struct stat statinfo;
4345 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
4346 for (i = x = 0; modulepath[i]; i++)
4347 if (modulepath[i] == SEP)
4348 x = i+1;
4349 modulepath[x] = '\0';
4350 /* Create the full-name to w9xpopen, so we can test it exists */
4351 strncat(modulepath,
4352 szConsoleSpawn,
4353 (sizeof(modulepath)/sizeof(modulepath[0]))
4354 -strlen(modulepath));
4355 if (stat(modulepath, &statinfo) != 0) {
4356 /* Eeek - file-not-found - possibly an embedding
4357 situation - see if we can locate it in sys.prefix
4359 strncpy(modulepath,
4360 Py_GetExecPrefix(),
4361 sizeof(modulepath)/sizeof(modulepath[0]));
4362 if (modulepath[strlen(modulepath)-1] != '\\')
4363 strcat(modulepath, "\\");
4364 strncat(modulepath,
4365 szConsoleSpawn,
4366 (sizeof(modulepath)/sizeof(modulepath[0]))
4367 -strlen(modulepath));
4368 /* No where else to look - raise an easily identifiable
4369 error, rather than leaving Windows to report
4370 "file not found" - as the user is probably blissfully
4371 unaware this shim EXE is used, and it will confuse them.
4372 (well, it confused me for a while ;-)
4374 if (stat(modulepath, &statinfo) != 0) {
4375 PyErr_Format(PyExc_RuntimeError,
4376 "Can not locate '%s' which is needed "
4377 "for popen to work with your shell "
4378 "or platform.",
4379 szConsoleSpawn);
4380 return FALSE;
4383 x = i + strlen(s3) + strlen(cmdstring) + 1 +
4384 strlen(modulepath) +
4385 strlen(szConsoleSpawn) + 1;
4387 s2 = (char *)alloca(x);
4388 ZeroMemory(s2, x);
4389 /* To maintain correct argument passing semantics,
4390 we pass the command-line as it stands, and allow
4391 quoting to be applied. w9xpopen.exe will then
4392 use its argv vector, and re-quote the necessary
4393 args for the ultimate child process.
4395 PyOS_snprintf(
4396 s2, x,
4397 "\"%s\" %s%s%s",
4398 modulepath,
4401 cmdstring);
4402 /* Not passing CREATE_NEW_CONSOLE has been known to
4403 cause random failures on win9x. Specifically a
4404 dialog:
4405 "Your program accessed mem currently in use at xxx"
4406 and a hopeful warning about the stability of your
4407 system.
4408 Cost is Ctrl+C wont kill children, but anyone
4409 who cares can have a go!
4411 dwProcessFlags |= CREATE_NEW_CONSOLE;
4415 /* Could be an else here to try cmd.exe / command.com in the path
4416 Now we'll just error out.. */
4417 else {
4418 PyErr_SetString(PyExc_RuntimeError,
4419 "Cannot locate a COMSPEC environment variable to "
4420 "use as the shell");
4421 return FALSE;
4424 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
4425 siStartInfo.cb = sizeof(STARTUPINFO);
4426 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
4427 siStartInfo.hStdInput = hStdin;
4428 siStartInfo.hStdOutput = hStdout;
4429 siStartInfo.hStdError = hStderr;
4430 siStartInfo.wShowWindow = SW_HIDE;
4432 if (CreateProcess(NULL,
4434 NULL,
4435 NULL,
4436 TRUE,
4437 dwProcessFlags,
4438 NULL,
4439 NULL,
4440 &siStartInfo,
4441 &piProcInfo) ) {
4442 /* Close the handles now so anyone waiting is woken. */
4443 CloseHandle(piProcInfo.hThread);
4445 /* Return process handle */
4446 *hProcess = piProcInfo.hProcess;
4447 return TRUE;
4449 win32_error("CreateProcess", s2);
4450 return FALSE;
4453 /* The following code is based off of KB: Q190351 */
4455 static PyObject *
4456 _PyPopen(char *cmdstring, int mode, int n)
4458 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
4459 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
4460 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
4462 SECURITY_ATTRIBUTES saAttr;
4463 BOOL fSuccess;
4464 int fd1, fd2, fd3;
4465 FILE *f1, *f2, *f3;
4466 long file_count;
4467 PyObject *f;
4469 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
4470 saAttr.bInheritHandle = TRUE;
4471 saAttr.lpSecurityDescriptor = NULL;
4473 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
4474 return win32_error("CreatePipe", NULL);
4476 /* Create new output read handle and the input write handle. Set
4477 * the inheritance properties to FALSE. Otherwise, the child inherits
4478 * these handles; resulting in non-closeable handles to the pipes
4479 * being created. */
4480 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
4481 GetCurrentProcess(), &hChildStdinWrDup, 0,
4482 FALSE,
4483 DUPLICATE_SAME_ACCESS);
4484 if (!fSuccess)
4485 return win32_error("DuplicateHandle", NULL);
4487 /* Close the inheritable version of ChildStdin
4488 that we're using. */
4489 CloseHandle(hChildStdinWr);
4491 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
4492 return win32_error("CreatePipe", NULL);
4494 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
4495 GetCurrentProcess(), &hChildStdoutRdDup, 0,
4496 FALSE, DUPLICATE_SAME_ACCESS);
4497 if (!fSuccess)
4498 return win32_error("DuplicateHandle", NULL);
4500 /* Close the inheritable version of ChildStdout
4501 that we're using. */
4502 CloseHandle(hChildStdoutRd);
4504 if (n != POPEN_4) {
4505 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
4506 return win32_error("CreatePipe", NULL);
4507 fSuccess = DuplicateHandle(GetCurrentProcess(),
4508 hChildStderrRd,
4509 GetCurrentProcess(),
4510 &hChildStderrRdDup, 0,
4511 FALSE, DUPLICATE_SAME_ACCESS);
4512 if (!fSuccess)
4513 return win32_error("DuplicateHandle", NULL);
4514 /* Close the inheritable version of ChildStdErr that we're using. */
4515 CloseHandle(hChildStderrRd);
4518 switch (n) {
4519 case POPEN_1:
4520 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
4521 case _O_WRONLY | _O_TEXT:
4522 /* Case for writing to child Stdin in text mode. */
4523 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4524 f1 = _fdopen(fd1, "w");
4525 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
4526 PyFile_SetBufSize(f, 0);
4527 /* We don't care about these pipes anymore, so close them. */
4528 CloseHandle(hChildStdoutRdDup);
4529 CloseHandle(hChildStderrRdDup);
4530 break;
4532 case _O_RDONLY | _O_TEXT:
4533 /* Case for reading from child Stdout in text mode. */
4534 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4535 f1 = _fdopen(fd1, "r");
4536 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
4537 PyFile_SetBufSize(f, 0);
4538 /* We don't care about these pipes anymore, so close them. */
4539 CloseHandle(hChildStdinWrDup);
4540 CloseHandle(hChildStderrRdDup);
4541 break;
4543 case _O_RDONLY | _O_BINARY:
4544 /* Case for readinig from child Stdout in binary mode. */
4545 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4546 f1 = _fdopen(fd1, "rb");
4547 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
4548 PyFile_SetBufSize(f, 0);
4549 /* We don't care about these pipes anymore, so close them. */
4550 CloseHandle(hChildStdinWrDup);
4551 CloseHandle(hChildStderrRdDup);
4552 break;
4554 case _O_WRONLY | _O_BINARY:
4555 /* Case for writing to child Stdin in binary mode. */
4556 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4557 f1 = _fdopen(fd1, "wb");
4558 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
4559 PyFile_SetBufSize(f, 0);
4560 /* We don't care about these pipes anymore, so close them. */
4561 CloseHandle(hChildStdoutRdDup);
4562 CloseHandle(hChildStderrRdDup);
4563 break;
4565 file_count = 1;
4566 break;
4568 case POPEN_2:
4569 case POPEN_4:
4571 char *m1, *m2;
4572 PyObject *p1, *p2;
4574 if (mode & _O_TEXT) {
4575 m1 = "r";
4576 m2 = "w";
4577 } else {
4578 m1 = "rb";
4579 m2 = "wb";
4582 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4583 f1 = _fdopen(fd1, m2);
4584 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4585 f2 = _fdopen(fd2, m1);
4586 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
4587 PyFile_SetBufSize(p1, 0);
4588 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
4589 PyFile_SetBufSize(p2, 0);
4591 if (n != 4)
4592 CloseHandle(hChildStderrRdDup);
4594 f = PyTuple_Pack(2,p1,p2);
4595 Py_XDECREF(p1);
4596 Py_XDECREF(p2);
4597 file_count = 2;
4598 break;
4601 case POPEN_3:
4603 char *m1, *m2;
4604 PyObject *p1, *p2, *p3;
4606 if (mode & _O_TEXT) {
4607 m1 = "r";
4608 m2 = "w";
4609 } else {
4610 m1 = "rb";
4611 m2 = "wb";
4614 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4615 f1 = _fdopen(fd1, m2);
4616 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4617 f2 = _fdopen(fd2, m1);
4618 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
4619 f3 = _fdopen(fd3, m1);
4620 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
4621 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
4622 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
4623 PyFile_SetBufSize(p1, 0);
4624 PyFile_SetBufSize(p2, 0);
4625 PyFile_SetBufSize(p3, 0);
4626 f = PyTuple_Pack(3,p1,p2,p3);
4627 Py_XDECREF(p1);
4628 Py_XDECREF(p2);
4629 Py_XDECREF(p3);
4630 file_count = 3;
4631 break;
4635 if (n == POPEN_4) {
4636 if (!_PyPopenCreateProcess(cmdstring,
4637 hChildStdinRd,
4638 hChildStdoutWr,
4639 hChildStdoutWr,
4640 &hProcess))
4641 return NULL;
4643 else {
4644 if (!_PyPopenCreateProcess(cmdstring,
4645 hChildStdinRd,
4646 hChildStdoutWr,
4647 hChildStderrWr,
4648 &hProcess))
4649 return NULL;
4653 * Insert the files we've created into the process dictionary
4654 * all referencing the list with the process handle and the
4655 * initial number of files (see description below in _PyPclose).
4656 * Since if _PyPclose later tried to wait on a process when all
4657 * handles weren't closed, it could create a deadlock with the
4658 * child, we spend some energy here to try to ensure that we
4659 * either insert all file handles into the dictionary or none
4660 * at all. It's a little clumsy with the various popen modes
4661 * and variable number of files involved.
4663 if (!_PyPopenProcs) {
4664 _PyPopenProcs = PyDict_New();
4667 if (_PyPopenProcs) {
4668 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
4669 int ins_rc[3];
4671 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4672 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4674 procObj = PyList_New(2);
4675 hProcessObj = PyLong_FromVoidPtr(hProcess);
4676 intObj = PyInt_FromLong(file_count);
4678 if (procObj && hProcessObj && intObj) {
4679 PyList_SetItem(procObj,0,hProcessObj);
4680 PyList_SetItem(procObj,1,intObj);
4682 fileObj[0] = PyLong_FromVoidPtr(f1);
4683 if (fileObj[0]) {
4684 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4685 fileObj[0],
4686 procObj);
4688 if (file_count >= 2) {
4689 fileObj[1] = PyLong_FromVoidPtr(f2);
4690 if (fileObj[1]) {
4691 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4692 fileObj[1],
4693 procObj);
4696 if (file_count >= 3) {
4697 fileObj[2] = PyLong_FromVoidPtr(f3);
4698 if (fileObj[2]) {
4699 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4700 fileObj[2],
4701 procObj);
4705 if (ins_rc[0] < 0 || !fileObj[0] ||
4706 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4707 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
4708 /* Something failed - remove any dictionary
4709 * entries that did make it.
4711 if (!ins_rc[0] && fileObj[0]) {
4712 PyDict_DelItem(_PyPopenProcs,
4713 fileObj[0]);
4715 if (!ins_rc[1] && fileObj[1]) {
4716 PyDict_DelItem(_PyPopenProcs,
4717 fileObj[1]);
4719 if (!ins_rc[2] && fileObj[2]) {
4720 PyDict_DelItem(_PyPopenProcs,
4721 fileObj[2]);
4727 * Clean up our localized references for the dictionary keys
4728 * and value since PyDict_SetItem will Py_INCREF any copies
4729 * that got placed in the dictionary.
4731 Py_XDECREF(procObj);
4732 Py_XDECREF(fileObj[0]);
4733 Py_XDECREF(fileObj[1]);
4734 Py_XDECREF(fileObj[2]);
4737 /* Child is launched. Close the parents copy of those pipe
4738 * handles that only the child should have open. You need to
4739 * make sure that no handles to the write end of the output pipe
4740 * are maintained in this process or else the pipe will not close
4741 * when the child process exits and the ReadFile will hang. */
4743 if (!CloseHandle(hChildStdinRd))
4744 return win32_error("CloseHandle", NULL);
4746 if (!CloseHandle(hChildStdoutWr))
4747 return win32_error("CloseHandle", NULL);
4749 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
4750 return win32_error("CloseHandle", NULL);
4752 return f;
4756 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4757 * exit code for the child process and return as a result of the close.
4759 * This function uses the _PyPopenProcs dictionary in order to map the
4760 * input file pointer to information about the process that was
4761 * originally created by the popen* call that created the file pointer.
4762 * The dictionary uses the file pointer as a key (with one entry
4763 * inserted for each file returned by the original popen* call) and a
4764 * single list object as the value for all files from a single call.
4765 * The list object contains the Win32 process handle at [0], and a file
4766 * count at [1], which is initialized to the total number of file
4767 * handles using that list.
4769 * This function closes whichever handle it is passed, and decrements
4770 * the file count in the dictionary for the process handle pointed to
4771 * by this file. On the last close (when the file count reaches zero),
4772 * this function will wait for the child process and then return its
4773 * exit code as the result of the close() operation. This permits the
4774 * files to be closed in any order - it is always the close() of the
4775 * final handle that will return the exit code.
4777 * NOTE: This function is currently called with the GIL released.
4778 * hence we use the GILState API to manage our state.
4781 static int _PyPclose(FILE *file)
4783 int result;
4784 DWORD exit_code;
4785 HANDLE hProcess;
4786 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
4787 long file_count;
4788 #ifdef WITH_THREAD
4789 PyGILState_STATE state;
4790 #endif
4792 /* Close the file handle first, to ensure it can't block the
4793 * child from exiting if it's the last handle.
4795 result = fclose(file);
4796 #ifdef WITH_THREAD
4797 state = PyGILState_Ensure();
4798 #endif
4799 if (_PyPopenProcs) {
4800 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4801 (procObj = PyDict_GetItem(_PyPopenProcs,
4802 fileObj)) != NULL &&
4803 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
4804 (intObj = PyList_GetItem(procObj,1)) != NULL) {
4806 hProcess = PyLong_AsVoidPtr(hProcessObj);
4807 file_count = PyInt_AsLong(intObj);
4809 if (file_count > 1) {
4810 /* Still other files referencing process */
4811 file_count--;
4812 PyList_SetItem(procObj,1,
4813 PyInt_FromLong(file_count));
4814 } else {
4815 /* Last file for this process */
4816 if (result != EOF &&
4817 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
4818 GetExitCodeProcess(hProcess, &exit_code)) {
4819 /* Possible truncation here in 16-bit environments, but
4820 * real exit codes are just the lower byte in any event.
4822 result = exit_code;
4823 } else {
4824 /* Indicate failure - this will cause the file object
4825 * to raise an I/O error and translate the last Win32
4826 * error code from errno. We do have a problem with
4827 * last errors that overlap the normal errno table,
4828 * but that's a consistent problem with the file object.
4830 if (result != EOF) {
4831 /* If the error wasn't from the fclose(), then
4832 * set errno for the file object error handling.
4834 errno = GetLastError();
4836 result = -1;
4839 /* Free up the native handle at this point */
4840 CloseHandle(hProcess);
4843 /* Remove this file pointer from dictionary */
4844 PyDict_DelItem(_PyPopenProcs, fileObj);
4846 if (PyDict_Size(_PyPopenProcs) == 0) {
4847 Py_DECREF(_PyPopenProcs);
4848 _PyPopenProcs = NULL;
4851 } /* if object retrieval ok */
4853 Py_XDECREF(fileObj);
4854 } /* if _PyPopenProcs */
4856 #ifdef WITH_THREAD
4857 PyGILState_Release(state);
4858 #endif
4859 return result;
4862 #else /* which OS? */
4863 static PyObject *
4864 posix_popen(PyObject *self, PyObject *args)
4866 char *name;
4867 char *mode = "r";
4868 int bufsize = -1;
4869 FILE *fp;
4870 PyObject *f;
4871 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
4872 return NULL;
4873 /* Strip mode of binary or text modifiers */
4874 if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
4875 mode = "r";
4876 else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
4877 mode = "w";
4878 Py_BEGIN_ALLOW_THREADS
4879 fp = popen(name, mode);
4880 Py_END_ALLOW_THREADS
4881 if (fp == NULL)
4882 return posix_error();
4883 f = PyFile_FromFile(fp, name, mode, pclose);
4884 if (f != NULL)
4885 PyFile_SetBufSize(f, bufsize);
4886 return f;
4889 #endif /* PYOS_??? */
4890 #endif /* HAVE_POPEN */
4893 #ifdef HAVE_SETUID
4894 PyDoc_STRVAR(posix_setuid__doc__,
4895 "setuid(uid)\n\n\
4896 Set the current process's user id.");
4898 static PyObject *
4899 posix_setuid(PyObject *self, PyObject *args)
4901 int uid;
4902 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
4903 return NULL;
4904 if (setuid(uid) < 0)
4905 return posix_error();
4906 Py_INCREF(Py_None);
4907 return Py_None;
4909 #endif /* HAVE_SETUID */
4912 #ifdef HAVE_SETEUID
4913 PyDoc_STRVAR(posix_seteuid__doc__,
4914 "seteuid(uid)\n\n\
4915 Set the current process's effective user id.");
4917 static PyObject *
4918 posix_seteuid (PyObject *self, PyObject *args)
4920 int euid;
4921 if (!PyArg_ParseTuple(args, "i", &euid)) {
4922 return NULL;
4923 } else if (seteuid(euid) < 0) {
4924 return posix_error();
4925 } else {
4926 Py_INCREF(Py_None);
4927 return Py_None;
4930 #endif /* HAVE_SETEUID */
4932 #ifdef HAVE_SETEGID
4933 PyDoc_STRVAR(posix_setegid__doc__,
4934 "setegid(gid)\n\n\
4935 Set the current process's effective group id.");
4937 static PyObject *
4938 posix_setegid (PyObject *self, PyObject *args)
4940 int egid;
4941 if (!PyArg_ParseTuple(args, "i", &egid)) {
4942 return NULL;
4943 } else if (setegid(egid) < 0) {
4944 return posix_error();
4945 } else {
4946 Py_INCREF(Py_None);
4947 return Py_None;
4950 #endif /* HAVE_SETEGID */
4952 #ifdef HAVE_SETREUID
4953 PyDoc_STRVAR(posix_setreuid__doc__,
4954 "setreuid(ruid, euid)\n\n\
4955 Set the current process's real and effective user ids.");
4957 static PyObject *
4958 posix_setreuid (PyObject *self, PyObject *args)
4960 int ruid, euid;
4961 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
4962 return NULL;
4963 } else if (setreuid(ruid, euid) < 0) {
4964 return posix_error();
4965 } else {
4966 Py_INCREF(Py_None);
4967 return Py_None;
4970 #endif /* HAVE_SETREUID */
4972 #ifdef HAVE_SETREGID
4973 PyDoc_STRVAR(posix_setregid__doc__,
4974 "setregid(rgid, egid)\n\n\
4975 Set the current process's real and effective group ids.");
4977 static PyObject *
4978 posix_setregid (PyObject *self, PyObject *args)
4980 int rgid, egid;
4981 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
4982 return NULL;
4983 } else if (setregid(rgid, egid) < 0) {
4984 return posix_error();
4985 } else {
4986 Py_INCREF(Py_None);
4987 return Py_None;
4990 #endif /* HAVE_SETREGID */
4992 #ifdef HAVE_SETGID
4993 PyDoc_STRVAR(posix_setgid__doc__,
4994 "setgid(gid)\n\n\
4995 Set the current process's group id.");
4997 static PyObject *
4998 posix_setgid(PyObject *self, PyObject *args)
5000 int gid;
5001 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
5002 return NULL;
5003 if (setgid(gid) < 0)
5004 return posix_error();
5005 Py_INCREF(Py_None);
5006 return Py_None;
5008 #endif /* HAVE_SETGID */
5010 #ifdef HAVE_SETGROUPS
5011 PyDoc_STRVAR(posix_setgroups__doc__,
5012 "setgroups(list)\n\n\
5013 Set the groups of the current process to list.");
5015 static PyObject *
5016 posix_setgroups(PyObject *self, PyObject *args)
5018 PyObject *groups;
5019 int i, len;
5020 gid_t grouplist[MAX_GROUPS];
5022 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
5023 return NULL;
5024 if (!PySequence_Check(groups)) {
5025 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
5026 return NULL;
5028 len = PySequence_Size(groups);
5029 if (len > MAX_GROUPS) {
5030 PyErr_SetString(PyExc_ValueError, "too many groups");
5031 return NULL;
5033 for(i = 0; i < len; i++) {
5034 PyObject *elem;
5035 elem = PySequence_GetItem(groups, i);
5036 if (!elem)
5037 return NULL;
5038 if (!PyInt_Check(elem)) {
5039 if (!PyLong_Check(elem)) {
5040 PyErr_SetString(PyExc_TypeError,
5041 "groups must be integers");
5042 Py_DECREF(elem);
5043 return NULL;
5044 } else {
5045 unsigned long x = PyLong_AsUnsignedLong(elem);
5046 if (PyErr_Occurred()) {
5047 PyErr_SetString(PyExc_TypeError,
5048 "group id too big");
5049 Py_DECREF(elem);
5050 return NULL;
5052 grouplist[i] = x;
5053 /* read back the value to see if it fitted in gid_t */
5054 if (grouplist[i] != x) {
5055 PyErr_SetString(PyExc_TypeError,
5056 "group id too big");
5057 Py_DECREF(elem);
5058 return NULL;
5061 } else {
5062 long x = PyInt_AsLong(elem);
5063 grouplist[i] = x;
5064 if (grouplist[i] != x) {
5065 PyErr_SetString(PyExc_TypeError,
5066 "group id too big");
5067 Py_DECREF(elem);
5068 return NULL;
5071 Py_DECREF(elem);
5074 if (setgroups(len, grouplist) < 0)
5075 return posix_error();
5076 Py_INCREF(Py_None);
5077 return Py_None;
5079 #endif /* HAVE_SETGROUPS */
5081 #ifdef HAVE_WAITPID
5082 PyDoc_STRVAR(posix_waitpid__doc__,
5083 "waitpid(pid, options) -> (pid, status)\n\n\
5084 Wait for completion of a given child process.");
5086 static PyObject *
5087 posix_waitpid(PyObject *self, PyObject *args)
5089 int pid, options;
5090 #ifdef UNION_WAIT
5091 union wait status;
5092 #define status_i (status.w_status)
5093 #else
5094 int status;
5095 #define status_i status
5096 #endif
5097 status_i = 0;
5099 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
5100 return NULL;
5101 Py_BEGIN_ALLOW_THREADS
5102 pid = waitpid(pid, &status, options);
5103 Py_END_ALLOW_THREADS
5104 if (pid == -1)
5105 return posix_error();
5106 else
5107 return Py_BuildValue("ii", pid, status_i);
5110 #elif defined(HAVE_CWAIT)
5112 /* MS C has a variant of waitpid() that's usable for most purposes. */
5113 PyDoc_STRVAR(posix_waitpid__doc__,
5114 "waitpid(pid, options) -> (pid, status << 8)\n\n"
5115 "Wait for completion of a given process. options is ignored on Windows.");
5117 static PyObject *
5118 posix_waitpid(PyObject *self, PyObject *args)
5120 int pid, options;
5121 int status;
5123 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
5124 return NULL;
5125 Py_BEGIN_ALLOW_THREADS
5126 pid = _cwait(&status, pid, options);
5127 Py_END_ALLOW_THREADS
5128 if (pid == -1)
5129 return posix_error();
5130 else
5131 /* shift the status left a byte so this is more like the
5132 POSIX waitpid */
5133 return Py_BuildValue("ii", pid, status << 8);
5135 #endif /* HAVE_WAITPID || HAVE_CWAIT */
5137 #ifdef HAVE_WAIT
5138 PyDoc_STRVAR(posix_wait__doc__,
5139 "wait() -> (pid, status)\n\n\
5140 Wait for completion of a child process.");
5142 static PyObject *
5143 posix_wait(PyObject *self, PyObject *noargs)
5145 int pid;
5146 #ifdef UNION_WAIT
5147 union wait status;
5148 #define status_i (status.w_status)
5149 #else
5150 int status;
5151 #define status_i status
5152 #endif
5154 status_i = 0;
5155 Py_BEGIN_ALLOW_THREADS
5156 pid = wait(&status);
5157 Py_END_ALLOW_THREADS
5158 if (pid == -1)
5159 return posix_error();
5160 else
5161 return Py_BuildValue("ii", pid, status_i);
5162 #undef status_i
5164 #endif
5167 PyDoc_STRVAR(posix_lstat__doc__,
5168 "lstat(path) -> stat result\n\n\
5169 Like stat(path), but do not follow symbolic links.");
5171 static PyObject *
5172 posix_lstat(PyObject *self, PyObject *args)
5174 #ifdef HAVE_LSTAT
5175 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
5176 #else /* !HAVE_LSTAT */
5177 #ifdef MS_WINDOWS
5178 return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", win32_wstat);
5179 #else
5180 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
5181 #endif
5182 #endif /* !HAVE_LSTAT */
5186 #ifdef HAVE_READLINK
5187 PyDoc_STRVAR(posix_readlink__doc__,
5188 "readlink(path) -> path\n\n\
5189 Return a string representing the path to which the symbolic link points.");
5191 static PyObject *
5192 posix_readlink(PyObject *self, PyObject *args)
5194 char buf[MAXPATHLEN];
5195 char *path;
5196 int n;
5197 if (!PyArg_ParseTuple(args, "s:readlink", &path))
5198 return NULL;
5199 Py_BEGIN_ALLOW_THREADS
5200 n = readlink(path, buf, (int) sizeof buf);
5201 Py_END_ALLOW_THREADS
5202 if (n < 0)
5203 return posix_error_with_filename(path);
5204 return PyString_FromStringAndSize(buf, n);
5206 #endif /* HAVE_READLINK */
5209 #ifdef HAVE_SYMLINK
5210 PyDoc_STRVAR(posix_symlink__doc__,
5211 "symlink(src, dst)\n\n\
5212 Create a symbolic link pointing to src named dst.");
5214 static PyObject *
5215 posix_symlink(PyObject *self, PyObject *args)
5217 return posix_2str(args, "etet:symlink", symlink, NULL, NULL);
5219 #endif /* HAVE_SYMLINK */
5222 #ifdef HAVE_TIMES
5223 #ifndef HZ
5224 #define HZ 60 /* Universal constant :-) */
5225 #endif /* HZ */
5227 #if defined(PYCC_VACPP) && defined(PYOS_OS2)
5228 static long
5229 system_uptime(void)
5231 ULONG value = 0;
5233 Py_BEGIN_ALLOW_THREADS
5234 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
5235 Py_END_ALLOW_THREADS
5237 return value;
5240 static PyObject *
5241 posix_times(PyObject *self, PyObject *noargs)
5243 /* Currently Only Uptime is Provided -- Others Later */
5244 return Py_BuildValue("ddddd",
5245 (double)0 /* t.tms_utime / HZ */,
5246 (double)0 /* t.tms_stime / HZ */,
5247 (double)0 /* t.tms_cutime / HZ */,
5248 (double)0 /* t.tms_cstime / HZ */,
5249 (double)system_uptime() / 1000);
5251 #else /* not OS2 */
5252 static PyObject *
5253 posix_times(PyObject *self, PyObject *noargs)
5255 struct tms t;
5256 clock_t c;
5257 errno = 0;
5258 c = times(&t);
5259 if (c == (clock_t) -1)
5260 return posix_error();
5261 return Py_BuildValue("ddddd",
5262 (double)t.tms_utime / HZ,
5263 (double)t.tms_stime / HZ,
5264 (double)t.tms_cutime / HZ,
5265 (double)t.tms_cstime / HZ,
5266 (double)c / HZ);
5268 #endif /* not OS2 */
5269 #endif /* HAVE_TIMES */
5272 #ifdef MS_WINDOWS
5273 #define HAVE_TIMES /* so the method table will pick it up */
5274 static PyObject *
5275 posix_times(PyObject *self, PyObject *noargs)
5277 FILETIME create, exit, kernel, user;
5278 HANDLE hProc;
5279 hProc = GetCurrentProcess();
5280 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
5281 /* The fields of a FILETIME structure are the hi and lo part
5282 of a 64-bit value expressed in 100 nanosecond units.
5283 1e7 is one second in such units; 1e-7 the inverse.
5284 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
5286 return Py_BuildValue(
5287 "ddddd",
5288 (double)(kernel.dwHighDateTime*429.4967296 +
5289 kernel.dwLowDateTime*1e-7),
5290 (double)(user.dwHighDateTime*429.4967296 +
5291 user.dwLowDateTime*1e-7),
5292 (double)0,
5293 (double)0,
5294 (double)0);
5296 #endif /* MS_WINDOWS */
5298 #ifdef HAVE_TIMES
5299 PyDoc_STRVAR(posix_times__doc__,
5300 "times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
5301 Return a tuple of floating point numbers indicating process times.");
5302 #endif
5305 #ifdef HAVE_GETSID
5306 PyDoc_STRVAR(posix_getsid__doc__,
5307 "getsid(pid) -> sid\n\n\
5308 Call the system call getsid().");
5310 static PyObject *
5311 posix_getsid(PyObject *self, PyObject *args)
5313 int pid, sid;
5314 if (!PyArg_ParseTuple(args, "i:getsid", &pid))
5315 return NULL;
5316 sid = getsid(pid);
5317 if (sid < 0)
5318 return posix_error();
5319 return PyInt_FromLong((long)sid);
5321 #endif /* HAVE_GETSID */
5324 #ifdef HAVE_SETSID
5325 PyDoc_STRVAR(posix_setsid__doc__,
5326 "setsid()\n\n\
5327 Call the system call setsid().");
5329 static PyObject *
5330 posix_setsid(PyObject *self, PyObject *noargs)
5332 if (setsid() < 0)
5333 return posix_error();
5334 Py_INCREF(Py_None);
5335 return Py_None;
5337 #endif /* HAVE_SETSID */
5339 #ifdef HAVE_SETPGID
5340 PyDoc_STRVAR(posix_setpgid__doc__,
5341 "setpgid(pid, pgrp)\n\n\
5342 Call the system call setpgid().");
5344 static PyObject *
5345 posix_setpgid(PyObject *self, PyObject *args)
5347 int pid, pgrp;
5348 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
5349 return NULL;
5350 if (setpgid(pid, pgrp) < 0)
5351 return posix_error();
5352 Py_INCREF(Py_None);
5353 return Py_None;
5355 #endif /* HAVE_SETPGID */
5358 #ifdef HAVE_TCGETPGRP
5359 PyDoc_STRVAR(posix_tcgetpgrp__doc__,
5360 "tcgetpgrp(fd) -> pgid\n\n\
5361 Return the process group associated with the terminal given by a fd.");
5363 static PyObject *
5364 posix_tcgetpgrp(PyObject *self, PyObject *args)
5366 int fd, pgid;
5367 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
5368 return NULL;
5369 pgid = tcgetpgrp(fd);
5370 if (pgid < 0)
5371 return posix_error();
5372 return PyInt_FromLong((long)pgid);
5374 #endif /* HAVE_TCGETPGRP */
5377 #ifdef HAVE_TCSETPGRP
5378 PyDoc_STRVAR(posix_tcsetpgrp__doc__,
5379 "tcsetpgrp(fd, pgid)\n\n\
5380 Set the process group associated with the terminal given by a fd.");
5382 static PyObject *
5383 posix_tcsetpgrp(PyObject *self, PyObject *args)
5385 int fd, pgid;
5386 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
5387 return NULL;
5388 if (tcsetpgrp(fd, pgid) < 0)
5389 return posix_error();
5390 Py_INCREF(Py_None);
5391 return Py_None;
5393 #endif /* HAVE_TCSETPGRP */
5395 /* Functions acting on file descriptors */
5397 PyDoc_STRVAR(posix_open__doc__,
5398 "open(filename, flag [, mode=0777]) -> fd\n\n\
5399 Open a file (for low level IO).");
5401 static PyObject *
5402 posix_open(PyObject *self, PyObject *args)
5404 char *file = NULL;
5405 int flag;
5406 int mode = 0777;
5407 int fd;
5409 #ifdef MS_WINDOWS
5410 if (unicode_file_names()) {
5411 PyUnicodeObject *po;
5412 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
5413 Py_BEGIN_ALLOW_THREADS
5414 /* PyUnicode_AS_UNICODE OK without thread
5415 lock as it is a simple dereference. */
5416 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
5417 Py_END_ALLOW_THREADS
5418 if (fd < 0)
5419 return posix_error();
5420 return PyInt_FromLong((long)fd);
5422 /* Drop the argument parsing error as narrow strings
5423 are also valid. */
5424 PyErr_Clear();
5426 #endif
5428 if (!PyArg_ParseTuple(args, "eti|i",
5429 Py_FileSystemDefaultEncoding, &file,
5430 &flag, &mode))
5431 return NULL;
5433 Py_BEGIN_ALLOW_THREADS
5434 fd = open(file, flag, mode);
5435 Py_END_ALLOW_THREADS
5436 if (fd < 0)
5437 return posix_error_with_allocated_filename(file);
5438 PyMem_Free(file);
5439 return PyInt_FromLong((long)fd);
5443 PyDoc_STRVAR(posix_close__doc__,
5444 "close(fd)\n\n\
5445 Close a file descriptor (for low level IO).");
5447 static PyObject *
5448 posix_close(PyObject *self, PyObject *args)
5450 int fd, res;
5451 if (!PyArg_ParseTuple(args, "i:close", &fd))
5452 return NULL;
5453 Py_BEGIN_ALLOW_THREADS
5454 res = close(fd);
5455 Py_END_ALLOW_THREADS
5456 if (res < 0)
5457 return posix_error();
5458 Py_INCREF(Py_None);
5459 return Py_None;
5463 PyDoc_STRVAR(posix_dup__doc__,
5464 "dup(fd) -> fd2\n\n\
5465 Return a duplicate of a file descriptor.");
5467 static PyObject *
5468 posix_dup(PyObject *self, PyObject *args)
5470 int fd;
5471 if (!PyArg_ParseTuple(args, "i:dup", &fd))
5472 return NULL;
5473 Py_BEGIN_ALLOW_THREADS
5474 fd = dup(fd);
5475 Py_END_ALLOW_THREADS
5476 if (fd < 0)
5477 return posix_error();
5478 return PyInt_FromLong((long)fd);
5482 PyDoc_STRVAR(posix_dup2__doc__,
5483 "dup2(old_fd, new_fd)\n\n\
5484 Duplicate file descriptor.");
5486 static PyObject *
5487 posix_dup2(PyObject *self, PyObject *args)
5489 int fd, fd2, res;
5490 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
5491 return NULL;
5492 Py_BEGIN_ALLOW_THREADS
5493 res = dup2(fd, fd2);
5494 Py_END_ALLOW_THREADS
5495 if (res < 0)
5496 return posix_error();
5497 Py_INCREF(Py_None);
5498 return Py_None;
5502 PyDoc_STRVAR(posix_lseek__doc__,
5503 "lseek(fd, pos, how) -> newpos\n\n\
5504 Set the current position of a file descriptor.");
5506 static PyObject *
5507 posix_lseek(PyObject *self, PyObject *args)
5509 int fd, how;
5510 #if defined(MS_WIN64) || defined(MS_WINDOWS)
5511 PY_LONG_LONG pos, res;
5512 #else
5513 off_t pos, res;
5514 #endif
5515 PyObject *posobj;
5516 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
5517 return NULL;
5518 #ifdef SEEK_SET
5519 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
5520 switch (how) {
5521 case 0: how = SEEK_SET; break;
5522 case 1: how = SEEK_CUR; break;
5523 case 2: how = SEEK_END; break;
5525 #endif /* SEEK_END */
5527 #if !defined(HAVE_LARGEFILE_SUPPORT)
5528 pos = PyInt_AsLong(posobj);
5529 #else
5530 pos = PyLong_Check(posobj) ?
5531 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
5532 #endif
5533 if (PyErr_Occurred())
5534 return NULL;
5536 Py_BEGIN_ALLOW_THREADS
5537 #if defined(MS_WIN64) || defined(MS_WINDOWS)
5538 res = _lseeki64(fd, pos, how);
5539 #else
5540 res = lseek(fd, pos, how);
5541 #endif
5542 Py_END_ALLOW_THREADS
5543 if (res < 0)
5544 return posix_error();
5546 #if !defined(HAVE_LARGEFILE_SUPPORT)
5547 return PyInt_FromLong(res);
5548 #else
5549 return PyLong_FromLongLong(res);
5550 #endif
5554 PyDoc_STRVAR(posix_read__doc__,
5555 "read(fd, buffersize) -> string\n\n\
5556 Read a file descriptor.");
5558 static PyObject *
5559 posix_read(PyObject *self, PyObject *args)
5561 int fd, size, n;
5562 PyObject *buffer;
5563 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
5564 return NULL;
5565 if (size < 0) {
5566 errno = EINVAL;
5567 return posix_error();
5569 buffer = PyString_FromStringAndSize((char *)NULL, size);
5570 if (buffer == NULL)
5571 return NULL;
5572 Py_BEGIN_ALLOW_THREADS
5573 n = read(fd, PyString_AsString(buffer), size);
5574 Py_END_ALLOW_THREADS
5575 if (n < 0) {
5576 Py_DECREF(buffer);
5577 return posix_error();
5579 if (n != size)
5580 _PyString_Resize(&buffer, n);
5581 return buffer;
5585 PyDoc_STRVAR(posix_write__doc__,
5586 "write(fd, string) -> byteswritten\n\n\
5587 Write a string to a file descriptor.");
5589 static PyObject *
5590 posix_write(PyObject *self, PyObject *args)
5592 int fd, size;
5593 char *buffer;
5594 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
5595 return NULL;
5596 Py_BEGIN_ALLOW_THREADS
5597 size = write(fd, buffer, size);
5598 Py_END_ALLOW_THREADS
5599 if (size < 0)
5600 return posix_error();
5601 return PyInt_FromLong((long)size);
5605 PyDoc_STRVAR(posix_fstat__doc__,
5606 "fstat(fd) -> stat result\n\n\
5607 Like stat(), but for an open file descriptor.");
5609 static PyObject *
5610 posix_fstat(PyObject *self, PyObject *args)
5612 int fd;
5613 STRUCT_STAT st;
5614 int res;
5615 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
5616 return NULL;
5617 #ifdef __VMS
5618 /* on OpenVMS we must ensure that all bytes are written to the file */
5619 fsync(fd);
5620 #endif
5621 Py_BEGIN_ALLOW_THREADS
5622 res = FSTAT(fd, &st);
5623 Py_END_ALLOW_THREADS
5624 if (res != 0) {
5625 #ifdef MS_WINDOWS
5626 return win32_error("fstat", NULL);
5627 #else
5628 return posix_error();
5629 #endif
5632 return _pystat_fromstructstat(&st);
5636 PyDoc_STRVAR(posix_fdopen__doc__,
5637 "fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
5638 Return an open file object connected to a file descriptor.");
5640 static PyObject *
5641 posix_fdopen(PyObject *self, PyObject *args)
5643 int fd;
5644 char *mode = "r";
5645 int bufsize = -1;
5646 FILE *fp;
5647 PyObject *f;
5648 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
5649 return NULL;
5651 if (mode[0] != 'r' && mode[0] != 'w' && mode[0] != 'a') {
5652 PyErr_Format(PyExc_ValueError,
5653 "invalid file mode '%s'", mode);
5654 return NULL;
5657 Py_BEGIN_ALLOW_THREADS
5658 fp = fdopen(fd, mode);
5659 Py_END_ALLOW_THREADS
5660 if (fp == NULL)
5661 return posix_error();
5662 f = PyFile_FromFile(fp, "<fdopen>", mode, fclose);
5663 if (f != NULL)
5664 PyFile_SetBufSize(f, bufsize);
5665 return f;
5668 PyDoc_STRVAR(posix_isatty__doc__,
5669 "isatty(fd) -> bool\n\n\
5670 Return True if the file descriptor 'fd' is an open file descriptor\n\
5671 connected to the slave end of a terminal.");
5673 static PyObject *
5674 posix_isatty(PyObject *self, PyObject *args)
5676 int fd;
5677 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
5678 return NULL;
5679 return PyBool_FromLong(isatty(fd));
5682 #ifdef HAVE_PIPE
5683 PyDoc_STRVAR(posix_pipe__doc__,
5684 "pipe() -> (read_end, write_end)\n\n\
5685 Create a pipe.");
5687 static PyObject *
5688 posix_pipe(PyObject *self, PyObject *noargs)
5690 #if defined(PYOS_OS2)
5691 HFILE read, write;
5692 APIRET rc;
5694 Py_BEGIN_ALLOW_THREADS
5695 rc = DosCreatePipe( &read, &write, 4096);
5696 Py_END_ALLOW_THREADS
5697 if (rc != NO_ERROR)
5698 return os2_error(rc);
5700 return Py_BuildValue("(ii)", read, write);
5701 #else
5702 #if !defined(MS_WINDOWS)
5703 int fds[2];
5704 int res;
5705 Py_BEGIN_ALLOW_THREADS
5706 res = pipe(fds);
5707 Py_END_ALLOW_THREADS
5708 if (res != 0)
5709 return posix_error();
5710 return Py_BuildValue("(ii)", fds[0], fds[1]);
5711 #else /* MS_WINDOWS */
5712 HANDLE read, write;
5713 int read_fd, write_fd;
5714 BOOL ok;
5715 Py_BEGIN_ALLOW_THREADS
5716 ok = CreatePipe(&read, &write, NULL, 0);
5717 Py_END_ALLOW_THREADS
5718 if (!ok)
5719 return win32_error("CreatePipe", NULL);
5720 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
5721 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
5722 return Py_BuildValue("(ii)", read_fd, write_fd);
5723 #endif /* MS_WINDOWS */
5724 #endif
5726 #endif /* HAVE_PIPE */
5729 #ifdef HAVE_MKFIFO
5730 PyDoc_STRVAR(posix_mkfifo__doc__,
5731 "mkfifo(filename [, mode=0666])\n\n\
5732 Create a FIFO (a POSIX named pipe).");
5734 static PyObject *
5735 posix_mkfifo(PyObject *self, PyObject *args)
5737 char *filename;
5738 int mode = 0666;
5739 int res;
5740 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
5741 return NULL;
5742 Py_BEGIN_ALLOW_THREADS
5743 res = mkfifo(filename, mode);
5744 Py_END_ALLOW_THREADS
5745 if (res < 0)
5746 return posix_error();
5747 Py_INCREF(Py_None);
5748 return Py_None;
5750 #endif
5753 #if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
5754 PyDoc_STRVAR(posix_mknod__doc__,
5755 "mknod(filename [, mode=0600, device])\n\n\
5756 Create a filesystem node (file, device special file or named pipe)\n\
5757 named filename. mode specifies both the permissions to use and the\n\
5758 type of node to be created, being combined (bitwise OR) with one of\n\
5759 S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
5760 device defines the newly created device special file (probably using\n\
5761 os.makedev()), otherwise it is ignored.");
5764 static PyObject *
5765 posix_mknod(PyObject *self, PyObject *args)
5767 char *filename;
5768 int mode = 0600;
5769 int device = 0;
5770 int res;
5771 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
5772 return NULL;
5773 Py_BEGIN_ALLOW_THREADS
5774 res = mknod(filename, mode, device);
5775 Py_END_ALLOW_THREADS
5776 if (res < 0)
5777 return posix_error();
5778 Py_INCREF(Py_None);
5779 return Py_None;
5781 #endif
5783 #ifdef HAVE_DEVICE_MACROS
5784 PyDoc_STRVAR(posix_major__doc__,
5785 "major(device) -> major number\n\
5786 Extracts a device major number from a raw device number.");
5788 static PyObject *
5789 posix_major(PyObject *self, PyObject *args)
5791 int device;
5792 if (!PyArg_ParseTuple(args, "i:major", &device))
5793 return NULL;
5794 return PyInt_FromLong((long)major(device));
5797 PyDoc_STRVAR(posix_minor__doc__,
5798 "minor(device) -> minor number\n\
5799 Extracts a device minor number from a raw device number.");
5801 static PyObject *
5802 posix_minor(PyObject *self, PyObject *args)
5804 int device;
5805 if (!PyArg_ParseTuple(args, "i:minor", &device))
5806 return NULL;
5807 return PyInt_FromLong((long)minor(device));
5810 PyDoc_STRVAR(posix_makedev__doc__,
5811 "makedev(major, minor) -> device number\n\
5812 Composes a raw device number from the major and minor device numbers.");
5814 static PyObject *
5815 posix_makedev(PyObject *self, PyObject *args)
5817 int major, minor;
5818 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
5819 return NULL;
5820 return PyInt_FromLong((long)makedev(major, minor));
5822 #endif /* device macros */
5825 #ifdef HAVE_FTRUNCATE
5826 PyDoc_STRVAR(posix_ftruncate__doc__,
5827 "ftruncate(fd, length)\n\n\
5828 Truncate a file to a specified length.");
5830 static PyObject *
5831 posix_ftruncate(PyObject *self, PyObject *args)
5833 int fd;
5834 off_t length;
5835 int res;
5836 PyObject *lenobj;
5838 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
5839 return NULL;
5841 #if !defined(HAVE_LARGEFILE_SUPPORT)
5842 length = PyInt_AsLong(lenobj);
5843 #else
5844 length = PyLong_Check(lenobj) ?
5845 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
5846 #endif
5847 if (PyErr_Occurred())
5848 return NULL;
5850 Py_BEGIN_ALLOW_THREADS
5851 res = ftruncate(fd, length);
5852 Py_END_ALLOW_THREADS
5853 if (res < 0) {
5854 PyErr_SetFromErrno(PyExc_IOError);
5855 return NULL;
5857 Py_INCREF(Py_None);
5858 return Py_None;
5860 #endif
5862 #ifdef HAVE_PUTENV
5863 PyDoc_STRVAR(posix_putenv__doc__,
5864 "putenv(key, value)\n\n\
5865 Change or add an environment variable.");
5867 /* Save putenv() parameters as values here, so we can collect them when they
5868 * get re-set with another call for the same key. */
5869 static PyObject *posix_putenv_garbage;
5871 static PyObject *
5872 posix_putenv(PyObject *self, PyObject *args)
5874 char *s1, *s2;
5875 char *new;
5876 PyObject *newstr;
5877 size_t len;
5879 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
5880 return NULL;
5882 #if defined(PYOS_OS2)
5883 if (stricmp(s1, "BEGINLIBPATH") == 0) {
5884 APIRET rc;
5886 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
5887 if (rc != NO_ERROR)
5888 return os2_error(rc);
5890 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
5891 APIRET rc;
5893 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
5894 if (rc != NO_ERROR)
5895 return os2_error(rc);
5896 } else {
5897 #endif
5899 /* XXX This can leak memory -- not easy to fix :-( */
5900 len = strlen(s1) + strlen(s2) + 2;
5901 /* len includes space for a trailing \0; the size arg to
5902 PyString_FromStringAndSize does not count that */
5903 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
5904 if (newstr == NULL)
5905 return PyErr_NoMemory();
5906 new = PyString_AS_STRING(newstr);
5907 PyOS_snprintf(new, len, "%s=%s", s1, s2);
5908 if (putenv(new)) {
5909 Py_DECREF(newstr);
5910 posix_error();
5911 return NULL;
5913 /* Install the first arg and newstr in posix_putenv_garbage;
5914 * this will cause previous value to be collected. This has to
5915 * happen after the real putenv() call because the old value
5916 * was still accessible until then. */
5917 if (PyDict_SetItem(posix_putenv_garbage,
5918 PyTuple_GET_ITEM(args, 0), newstr)) {
5919 /* really not much we can do; just leak */
5920 PyErr_Clear();
5922 else {
5923 Py_DECREF(newstr);
5926 #if defined(PYOS_OS2)
5928 #endif
5929 Py_INCREF(Py_None);
5930 return Py_None;
5932 #endif /* putenv */
5934 #ifdef HAVE_UNSETENV
5935 PyDoc_STRVAR(posix_unsetenv__doc__,
5936 "unsetenv(key)\n\n\
5937 Delete an environment variable.");
5939 static PyObject *
5940 posix_unsetenv(PyObject *self, PyObject *args)
5942 char *s1;
5944 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
5945 return NULL;
5947 unsetenv(s1);
5949 /* Remove the key from posix_putenv_garbage;
5950 * this will cause it to be collected. This has to
5951 * happen after the real unsetenv() call because the
5952 * old value was still accessible until then.
5954 if (PyDict_DelItem(posix_putenv_garbage,
5955 PyTuple_GET_ITEM(args, 0))) {
5956 /* really not much we can do; just leak */
5957 PyErr_Clear();
5960 Py_INCREF(Py_None);
5961 return Py_None;
5963 #endif /* unsetenv */
5965 #ifdef HAVE_STRERROR
5966 PyDoc_STRVAR(posix_strerror__doc__,
5967 "strerror(code) -> string\n\n\
5968 Translate an error code to a message string.");
5970 static PyObject *
5971 posix_strerror(PyObject *self, PyObject *args)
5973 int code;
5974 char *message;
5975 if (!PyArg_ParseTuple(args, "i:strerror", &code))
5976 return NULL;
5977 message = strerror(code);
5978 if (message == NULL) {
5979 PyErr_SetString(PyExc_ValueError,
5980 "strerror() argument out of range");
5981 return NULL;
5983 return PyString_FromString(message);
5985 #endif /* strerror */
5988 #ifdef HAVE_SYS_WAIT_H
5990 #ifdef WCOREDUMP
5991 PyDoc_STRVAR(posix_WCOREDUMP__doc__,
5992 "WCOREDUMP(status) -> bool\n\n\
5993 Return True if the process returning 'status' was dumped to a core file.");
5995 static PyObject *
5996 posix_WCOREDUMP(PyObject *self, PyObject *args)
5998 #ifdef UNION_WAIT
5999 union wait status;
6000 #define status_i (status.w_status)
6001 #else
6002 int status;
6003 #define status_i status
6004 #endif
6005 status_i = 0;
6007 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &status_i))
6009 return NULL;
6012 return PyBool_FromLong(WCOREDUMP(status));
6013 #undef status_i
6015 #endif /* WCOREDUMP */
6017 #ifdef WIFCONTINUED
6018 PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
6019 "WIFCONTINUED(status) -> bool\n\n\
6020 Return True if the process returning 'status' was continued from a\n\
6021 job control stop.");
6023 static PyObject *
6024 posix_WIFCONTINUED(PyObject *self, PyObject *args)
6026 #ifdef UNION_WAIT
6027 union wait status;
6028 #define status_i (status.w_status)
6029 #else
6030 int status;
6031 #define status_i status
6032 #endif
6033 status_i = 0;
6035 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &status_i))
6037 return NULL;
6040 return PyBool_FromLong(WIFCONTINUED(status));
6041 #undef status_i
6043 #endif /* WIFCONTINUED */
6045 #ifdef WIFSTOPPED
6046 PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
6047 "WIFSTOPPED(status) -> bool\n\n\
6048 Return True if the process returning 'status' was stopped.");
6050 static PyObject *
6051 posix_WIFSTOPPED(PyObject *self, PyObject *args)
6053 #ifdef UNION_WAIT
6054 union wait status;
6055 #define status_i (status.w_status)
6056 #else
6057 int status;
6058 #define status_i status
6059 #endif
6060 status_i = 0;
6062 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
6064 return NULL;
6067 return PyBool_FromLong(WIFSTOPPED(status));
6068 #undef status_i
6070 #endif /* WIFSTOPPED */
6072 #ifdef WIFSIGNALED
6073 PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
6074 "WIFSIGNALED(status) -> bool\n\n\
6075 Return True if the process returning 'status' was terminated by a signal.");
6077 static PyObject *
6078 posix_WIFSIGNALED(PyObject *self, PyObject *args)
6080 #ifdef UNION_WAIT
6081 union wait status;
6082 #define status_i (status.w_status)
6083 #else
6084 int status;
6085 #define status_i status
6086 #endif
6087 status_i = 0;
6089 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
6091 return NULL;
6094 return PyBool_FromLong(WIFSIGNALED(status));
6095 #undef status_i
6097 #endif /* WIFSIGNALED */
6099 #ifdef WIFEXITED
6100 PyDoc_STRVAR(posix_WIFEXITED__doc__,
6101 "WIFEXITED(status) -> bool\n\n\
6102 Return true if the process returning 'status' exited using the exit()\n\
6103 system call.");
6105 static PyObject *
6106 posix_WIFEXITED(PyObject *self, PyObject *args)
6108 #ifdef UNION_WAIT
6109 union wait status;
6110 #define status_i (status.w_status)
6111 #else
6112 int status;
6113 #define status_i status
6114 #endif
6115 status_i = 0;
6117 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
6119 return NULL;
6122 return PyBool_FromLong(WIFEXITED(status));
6123 #undef status_i
6125 #endif /* WIFEXITED */
6127 #ifdef WEXITSTATUS
6128 PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
6129 "WEXITSTATUS(status) -> integer\n\n\
6130 Return the process return code from 'status'.");
6132 static PyObject *
6133 posix_WEXITSTATUS(PyObject *self, PyObject *args)
6135 #ifdef UNION_WAIT
6136 union wait status;
6137 #define status_i (status.w_status)
6138 #else
6139 int status;
6140 #define status_i status
6141 #endif
6142 status_i = 0;
6144 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
6146 return NULL;
6149 return Py_BuildValue("i", WEXITSTATUS(status));
6150 #undef status_i
6152 #endif /* WEXITSTATUS */
6154 #ifdef WTERMSIG
6155 PyDoc_STRVAR(posix_WTERMSIG__doc__,
6156 "WTERMSIG(status) -> integer\n\n\
6157 Return the signal that terminated the process that provided the 'status'\n\
6158 value.");
6160 static PyObject *
6161 posix_WTERMSIG(PyObject *self, PyObject *args)
6163 #ifdef UNION_WAIT
6164 union wait status;
6165 #define status_i (status.w_status)
6166 #else
6167 int status;
6168 #define status_i status
6169 #endif
6170 status_i = 0;
6172 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
6174 return NULL;
6177 return Py_BuildValue("i", WTERMSIG(status));
6178 #undef status_i
6180 #endif /* WTERMSIG */
6182 #ifdef WSTOPSIG
6183 PyDoc_STRVAR(posix_WSTOPSIG__doc__,
6184 "WSTOPSIG(status) -> integer\n\n\
6185 Return the signal that stopped the process that provided\n\
6186 the 'status' value.");
6188 static PyObject *
6189 posix_WSTOPSIG(PyObject *self, PyObject *args)
6191 #ifdef UNION_WAIT
6192 union wait status;
6193 #define status_i (status.w_status)
6194 #else
6195 int status;
6196 #define status_i status
6197 #endif
6198 status_i = 0;
6200 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
6202 return NULL;
6205 return Py_BuildValue("i", WSTOPSIG(status));
6206 #undef status_i
6208 #endif /* WSTOPSIG */
6210 #endif /* HAVE_SYS_WAIT_H */
6213 #if defined(HAVE_FSTATVFS)
6214 #ifdef _SCO_DS
6215 /* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
6216 needed definitions in sys/statvfs.h */
6217 #define _SVID3
6218 #endif
6219 #include <sys/statvfs.h>
6221 static PyObject*
6222 _pystatvfs_fromstructstatvfs(struct statvfs st) {
6223 PyObject *v = PyStructSequence_New(&StatVFSResultType);
6224 if (v == NULL)
6225 return NULL;
6227 #if !defined(HAVE_LARGEFILE_SUPPORT)
6228 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6229 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
6230 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
6231 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
6232 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
6233 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
6234 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
6235 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
6236 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6237 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6238 #else
6239 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6240 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
6241 PyStructSequence_SET_ITEM(v, 2,
6242 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
6243 PyStructSequence_SET_ITEM(v, 3,
6244 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
6245 PyStructSequence_SET_ITEM(v, 4,
6246 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
6247 PyStructSequence_SET_ITEM(v, 5,
6248 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
6249 PyStructSequence_SET_ITEM(v, 6,
6250 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
6251 PyStructSequence_SET_ITEM(v, 7,
6252 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
6253 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6254 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6255 #endif
6257 return v;
6260 PyDoc_STRVAR(posix_fstatvfs__doc__,
6261 "fstatvfs(fd) -> statvfs result\n\n\
6262 Perform an fstatvfs system call on the given fd.");
6264 static PyObject *
6265 posix_fstatvfs(PyObject *self, PyObject *args)
6267 int fd, res;
6268 struct statvfs st;
6270 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
6271 return NULL;
6272 Py_BEGIN_ALLOW_THREADS
6273 res = fstatvfs(fd, &st);
6274 Py_END_ALLOW_THREADS
6275 if (res != 0)
6276 return posix_error();
6278 return _pystatvfs_fromstructstatvfs(st);
6280 #endif /* HAVE_FSTATVFS */
6283 #if defined(HAVE_STATVFS)
6284 #include <sys/statvfs.h>
6286 PyDoc_STRVAR(posix_statvfs__doc__,
6287 "statvfs(path) -> statvfs result\n\n\
6288 Perform a statvfs system call on the given path.");
6290 static PyObject *
6291 posix_statvfs(PyObject *self, PyObject *args)
6293 char *path;
6294 int res;
6295 struct statvfs st;
6296 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
6297 return NULL;
6298 Py_BEGIN_ALLOW_THREADS
6299 res = statvfs(path, &st);
6300 Py_END_ALLOW_THREADS
6301 if (res != 0)
6302 return posix_error_with_filename(path);
6304 return _pystatvfs_fromstructstatvfs(st);
6306 #endif /* HAVE_STATVFS */
6309 #ifdef HAVE_TEMPNAM
6310 PyDoc_STRVAR(posix_tempnam__doc__,
6311 "tempnam([dir[, prefix]]) -> string\n\n\
6312 Return a unique name for a temporary file.\n\
6313 The directory and a prefix may be specified as strings; they may be omitted\n\
6314 or None if not needed.");
6316 static PyObject *
6317 posix_tempnam(PyObject *self, PyObject *args)
6319 PyObject *result = NULL;
6320 char *dir = NULL;
6321 char *pfx = NULL;
6322 char *name;
6324 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
6325 return NULL;
6327 if (PyErr_Warn(PyExc_RuntimeWarning,
6328 "tempnam is a potential security risk to your program") < 0)
6329 return NULL;
6331 #ifdef MS_WINDOWS
6332 name = _tempnam(dir, pfx);
6333 #else
6334 name = tempnam(dir, pfx);
6335 #endif
6336 if (name == NULL)
6337 return PyErr_NoMemory();
6338 result = PyString_FromString(name);
6339 free(name);
6340 return result;
6342 #endif
6345 #ifdef HAVE_TMPFILE
6346 PyDoc_STRVAR(posix_tmpfile__doc__,
6347 "tmpfile() -> file object\n\n\
6348 Create a temporary file with no directory entries.");
6350 static PyObject *
6351 posix_tmpfile(PyObject *self, PyObject *noargs)
6353 FILE *fp;
6355 fp = tmpfile();
6356 if (fp == NULL)
6357 return posix_error();
6358 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
6360 #endif
6363 #ifdef HAVE_TMPNAM
6364 PyDoc_STRVAR(posix_tmpnam__doc__,
6365 "tmpnam() -> string\n\n\
6366 Return a unique name for a temporary file.");
6368 static PyObject *
6369 posix_tmpnam(PyObject *self, PyObject *noargs)
6371 char buffer[L_tmpnam];
6372 char *name;
6374 if (PyErr_Warn(PyExc_RuntimeWarning,
6375 "tmpnam is a potential security risk to your program") < 0)
6376 return NULL;
6378 #ifdef USE_TMPNAM_R
6379 name = tmpnam_r(buffer);
6380 #else
6381 name = tmpnam(buffer);
6382 #endif
6383 if (name == NULL) {
6384 PyErr_SetObject(PyExc_OSError,
6385 Py_BuildValue("is", 0,
6386 #ifdef USE_TMPNAM_R
6387 "unexpected NULL from tmpnam_r"
6388 #else
6389 "unexpected NULL from tmpnam"
6390 #endif
6392 return NULL;
6394 return PyString_FromString(buffer);
6396 #endif
6399 /* This is used for fpathconf(), pathconf(), confstr() and sysconf().
6400 * It maps strings representing configuration variable names to
6401 * integer values, allowing those functions to be called with the
6402 * magic names instead of polluting the module's namespace with tons of
6403 * rarely-used constants. There are three separate tables that use
6404 * these definitions.
6406 * This code is always included, even if none of the interfaces that
6407 * need it are included. The #if hackery needed to avoid it would be
6408 * sufficiently pervasive that it's not worth the loss of readability.
6410 struct constdef {
6411 char *name;
6412 long value;
6415 static int
6416 conv_confname(PyObject *arg, int *valuep, struct constdef *table,
6417 size_t tablesize)
6419 if (PyInt_Check(arg)) {
6420 *valuep = PyInt_AS_LONG(arg);
6421 return 1;
6423 if (PyString_Check(arg)) {
6424 /* look up the value in the table using a binary search */
6425 size_t lo = 0;
6426 size_t mid;
6427 size_t hi = tablesize;
6428 int cmp;
6429 char *confname = PyString_AS_STRING(arg);
6430 while (lo < hi) {
6431 mid = (lo + hi) / 2;
6432 cmp = strcmp(confname, table[mid].name);
6433 if (cmp < 0)
6434 hi = mid;
6435 else if (cmp > 0)
6436 lo = mid + 1;
6437 else {
6438 *valuep = table[mid].value;
6439 return 1;
6442 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
6444 else
6445 PyErr_SetString(PyExc_TypeError,
6446 "configuration names must be strings or integers");
6447 return 0;
6451 #if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
6452 static struct constdef posix_constants_pathconf[] = {
6453 #ifdef _PC_ABI_AIO_XFER_MAX
6454 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
6455 #endif
6456 #ifdef _PC_ABI_ASYNC_IO
6457 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
6458 #endif
6459 #ifdef _PC_ASYNC_IO
6460 {"PC_ASYNC_IO", _PC_ASYNC_IO},
6461 #endif
6462 #ifdef _PC_CHOWN_RESTRICTED
6463 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
6464 #endif
6465 #ifdef _PC_FILESIZEBITS
6466 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
6467 #endif
6468 #ifdef _PC_LAST
6469 {"PC_LAST", _PC_LAST},
6470 #endif
6471 #ifdef _PC_LINK_MAX
6472 {"PC_LINK_MAX", _PC_LINK_MAX},
6473 #endif
6474 #ifdef _PC_MAX_CANON
6475 {"PC_MAX_CANON", _PC_MAX_CANON},
6476 #endif
6477 #ifdef _PC_MAX_INPUT
6478 {"PC_MAX_INPUT", _PC_MAX_INPUT},
6479 #endif
6480 #ifdef _PC_NAME_MAX
6481 {"PC_NAME_MAX", _PC_NAME_MAX},
6482 #endif
6483 #ifdef _PC_NO_TRUNC
6484 {"PC_NO_TRUNC", _PC_NO_TRUNC},
6485 #endif
6486 #ifdef _PC_PATH_MAX
6487 {"PC_PATH_MAX", _PC_PATH_MAX},
6488 #endif
6489 #ifdef _PC_PIPE_BUF
6490 {"PC_PIPE_BUF", _PC_PIPE_BUF},
6491 #endif
6492 #ifdef _PC_PRIO_IO
6493 {"PC_PRIO_IO", _PC_PRIO_IO},
6494 #endif
6495 #ifdef _PC_SOCK_MAXBUF
6496 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
6497 #endif
6498 #ifdef _PC_SYNC_IO
6499 {"PC_SYNC_IO", _PC_SYNC_IO},
6500 #endif
6501 #ifdef _PC_VDISABLE
6502 {"PC_VDISABLE", _PC_VDISABLE},
6503 #endif
6506 static int
6507 conv_path_confname(PyObject *arg, int *valuep)
6509 return conv_confname(arg, valuep, posix_constants_pathconf,
6510 sizeof(posix_constants_pathconf)
6511 / sizeof(struct constdef));
6513 #endif
6515 #ifdef HAVE_FPATHCONF
6516 PyDoc_STRVAR(posix_fpathconf__doc__,
6517 "fpathconf(fd, name) -> integer\n\n\
6518 Return the configuration limit name for the file descriptor fd.\n\
6519 If there is no limit, return -1.");
6521 static PyObject *
6522 posix_fpathconf(PyObject *self, PyObject *args)
6524 PyObject *result = NULL;
6525 int name, fd;
6527 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
6528 conv_path_confname, &name)) {
6529 long limit;
6531 errno = 0;
6532 limit = fpathconf(fd, name);
6533 if (limit == -1 && errno != 0)
6534 posix_error();
6535 else
6536 result = PyInt_FromLong(limit);
6538 return result;
6540 #endif
6543 #ifdef HAVE_PATHCONF
6544 PyDoc_STRVAR(posix_pathconf__doc__,
6545 "pathconf(path, name) -> integer\n\n\
6546 Return the configuration limit name for the file or directory path.\n\
6547 If there is no limit, return -1.");
6549 static PyObject *
6550 posix_pathconf(PyObject *self, PyObject *args)
6552 PyObject *result = NULL;
6553 int name;
6554 char *path;
6556 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
6557 conv_path_confname, &name)) {
6558 long limit;
6560 errno = 0;
6561 limit = pathconf(path, name);
6562 if (limit == -1 && errno != 0) {
6563 if (errno == EINVAL)
6564 /* could be a path or name problem */
6565 posix_error();
6566 else
6567 posix_error_with_filename(path);
6569 else
6570 result = PyInt_FromLong(limit);
6572 return result;
6574 #endif
6576 #ifdef HAVE_CONFSTR
6577 static struct constdef posix_constants_confstr[] = {
6578 #ifdef _CS_ARCHITECTURE
6579 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
6580 #endif
6581 #ifdef _CS_HOSTNAME
6582 {"CS_HOSTNAME", _CS_HOSTNAME},
6583 #endif
6584 #ifdef _CS_HW_PROVIDER
6585 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
6586 #endif
6587 #ifdef _CS_HW_SERIAL
6588 {"CS_HW_SERIAL", _CS_HW_SERIAL},
6589 #endif
6590 #ifdef _CS_INITTAB_NAME
6591 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
6592 #endif
6593 #ifdef _CS_LFS64_CFLAGS
6594 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
6595 #endif
6596 #ifdef _CS_LFS64_LDFLAGS
6597 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
6598 #endif
6599 #ifdef _CS_LFS64_LIBS
6600 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
6601 #endif
6602 #ifdef _CS_LFS64_LINTFLAGS
6603 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
6604 #endif
6605 #ifdef _CS_LFS_CFLAGS
6606 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
6607 #endif
6608 #ifdef _CS_LFS_LDFLAGS
6609 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
6610 #endif
6611 #ifdef _CS_LFS_LIBS
6612 {"CS_LFS_LIBS", _CS_LFS_LIBS},
6613 #endif
6614 #ifdef _CS_LFS_LINTFLAGS
6615 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
6616 #endif
6617 #ifdef _CS_MACHINE
6618 {"CS_MACHINE", _CS_MACHINE},
6619 #endif
6620 #ifdef _CS_PATH
6621 {"CS_PATH", _CS_PATH},
6622 #endif
6623 #ifdef _CS_RELEASE
6624 {"CS_RELEASE", _CS_RELEASE},
6625 #endif
6626 #ifdef _CS_SRPC_DOMAIN
6627 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
6628 #endif
6629 #ifdef _CS_SYSNAME
6630 {"CS_SYSNAME", _CS_SYSNAME},
6631 #endif
6632 #ifdef _CS_VERSION
6633 {"CS_VERSION", _CS_VERSION},
6634 #endif
6635 #ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
6636 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
6637 #endif
6638 #ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
6639 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
6640 #endif
6641 #ifdef _CS_XBS5_ILP32_OFF32_LIBS
6642 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
6643 #endif
6644 #ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
6645 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
6646 #endif
6647 #ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
6648 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
6649 #endif
6650 #ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
6651 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
6652 #endif
6653 #ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
6654 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
6655 #endif
6656 #ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
6657 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
6658 #endif
6659 #ifdef _CS_XBS5_LP64_OFF64_CFLAGS
6660 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
6661 #endif
6662 #ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
6663 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
6664 #endif
6665 #ifdef _CS_XBS5_LP64_OFF64_LIBS
6666 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
6667 #endif
6668 #ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
6669 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
6670 #endif
6671 #ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
6672 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
6673 #endif
6674 #ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
6675 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
6676 #endif
6677 #ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
6678 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
6679 #endif
6680 #ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
6681 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
6682 #endif
6683 #ifdef _MIPS_CS_AVAIL_PROCESSORS
6684 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
6685 #endif
6686 #ifdef _MIPS_CS_BASE
6687 {"MIPS_CS_BASE", _MIPS_CS_BASE},
6688 #endif
6689 #ifdef _MIPS_CS_HOSTID
6690 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
6691 #endif
6692 #ifdef _MIPS_CS_HW_NAME
6693 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
6694 #endif
6695 #ifdef _MIPS_CS_NUM_PROCESSORS
6696 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
6697 #endif
6698 #ifdef _MIPS_CS_OSREL_MAJ
6699 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
6700 #endif
6701 #ifdef _MIPS_CS_OSREL_MIN
6702 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
6703 #endif
6704 #ifdef _MIPS_CS_OSREL_PATCH
6705 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
6706 #endif
6707 #ifdef _MIPS_CS_OS_NAME
6708 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
6709 #endif
6710 #ifdef _MIPS_CS_OS_PROVIDER
6711 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
6712 #endif
6713 #ifdef _MIPS_CS_PROCESSORS
6714 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
6715 #endif
6716 #ifdef _MIPS_CS_SERIAL
6717 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
6718 #endif
6719 #ifdef _MIPS_CS_VENDOR
6720 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
6721 #endif
6724 static int
6725 conv_confstr_confname(PyObject *arg, int *valuep)
6727 return conv_confname(arg, valuep, posix_constants_confstr,
6728 sizeof(posix_constants_confstr)
6729 / sizeof(struct constdef));
6732 PyDoc_STRVAR(posix_confstr__doc__,
6733 "confstr(name) -> string\n\n\
6734 Return a string-valued system configuration variable.");
6736 static PyObject *
6737 posix_confstr(PyObject *self, PyObject *args)
6739 PyObject *result = NULL;
6740 int name;
6741 char buffer[64];
6743 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
6744 int len = confstr(name, buffer, sizeof(buffer));
6746 errno = 0;
6747 if (len == 0) {
6748 if (errno != 0)
6749 posix_error();
6750 else
6751 result = PyString_FromString("");
6753 else {
6754 if (len >= sizeof(buffer)) {
6755 result = PyString_FromStringAndSize(NULL, len);
6756 if (result != NULL)
6757 confstr(name, PyString_AS_STRING(result), len+1);
6759 else
6760 result = PyString_FromString(buffer);
6763 return result;
6765 #endif
6768 #ifdef HAVE_SYSCONF
6769 static struct constdef posix_constants_sysconf[] = {
6770 #ifdef _SC_2_CHAR_TERM
6771 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
6772 #endif
6773 #ifdef _SC_2_C_BIND
6774 {"SC_2_C_BIND", _SC_2_C_BIND},
6775 #endif
6776 #ifdef _SC_2_C_DEV
6777 {"SC_2_C_DEV", _SC_2_C_DEV},
6778 #endif
6779 #ifdef _SC_2_C_VERSION
6780 {"SC_2_C_VERSION", _SC_2_C_VERSION},
6781 #endif
6782 #ifdef _SC_2_FORT_DEV
6783 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
6784 #endif
6785 #ifdef _SC_2_FORT_RUN
6786 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
6787 #endif
6788 #ifdef _SC_2_LOCALEDEF
6789 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
6790 #endif
6791 #ifdef _SC_2_SW_DEV
6792 {"SC_2_SW_DEV", _SC_2_SW_DEV},
6793 #endif
6794 #ifdef _SC_2_UPE
6795 {"SC_2_UPE", _SC_2_UPE},
6796 #endif
6797 #ifdef _SC_2_VERSION
6798 {"SC_2_VERSION", _SC_2_VERSION},
6799 #endif
6800 #ifdef _SC_ABI_ASYNCHRONOUS_IO
6801 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
6802 #endif
6803 #ifdef _SC_ACL
6804 {"SC_ACL", _SC_ACL},
6805 #endif
6806 #ifdef _SC_AIO_LISTIO_MAX
6807 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
6808 #endif
6809 #ifdef _SC_AIO_MAX
6810 {"SC_AIO_MAX", _SC_AIO_MAX},
6811 #endif
6812 #ifdef _SC_AIO_PRIO_DELTA_MAX
6813 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
6814 #endif
6815 #ifdef _SC_ARG_MAX
6816 {"SC_ARG_MAX", _SC_ARG_MAX},
6817 #endif
6818 #ifdef _SC_ASYNCHRONOUS_IO
6819 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
6820 #endif
6821 #ifdef _SC_ATEXIT_MAX
6822 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
6823 #endif
6824 #ifdef _SC_AUDIT
6825 {"SC_AUDIT", _SC_AUDIT},
6826 #endif
6827 #ifdef _SC_AVPHYS_PAGES
6828 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
6829 #endif
6830 #ifdef _SC_BC_BASE_MAX
6831 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
6832 #endif
6833 #ifdef _SC_BC_DIM_MAX
6834 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
6835 #endif
6836 #ifdef _SC_BC_SCALE_MAX
6837 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
6838 #endif
6839 #ifdef _SC_BC_STRING_MAX
6840 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
6841 #endif
6842 #ifdef _SC_CAP
6843 {"SC_CAP", _SC_CAP},
6844 #endif
6845 #ifdef _SC_CHARCLASS_NAME_MAX
6846 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
6847 #endif
6848 #ifdef _SC_CHAR_BIT
6849 {"SC_CHAR_BIT", _SC_CHAR_BIT},
6850 #endif
6851 #ifdef _SC_CHAR_MAX
6852 {"SC_CHAR_MAX", _SC_CHAR_MAX},
6853 #endif
6854 #ifdef _SC_CHAR_MIN
6855 {"SC_CHAR_MIN", _SC_CHAR_MIN},
6856 #endif
6857 #ifdef _SC_CHILD_MAX
6858 {"SC_CHILD_MAX", _SC_CHILD_MAX},
6859 #endif
6860 #ifdef _SC_CLK_TCK
6861 {"SC_CLK_TCK", _SC_CLK_TCK},
6862 #endif
6863 #ifdef _SC_COHER_BLKSZ
6864 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
6865 #endif
6866 #ifdef _SC_COLL_WEIGHTS_MAX
6867 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
6868 #endif
6869 #ifdef _SC_DCACHE_ASSOC
6870 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
6871 #endif
6872 #ifdef _SC_DCACHE_BLKSZ
6873 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
6874 #endif
6875 #ifdef _SC_DCACHE_LINESZ
6876 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
6877 #endif
6878 #ifdef _SC_DCACHE_SZ
6879 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
6880 #endif
6881 #ifdef _SC_DCACHE_TBLKSZ
6882 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
6883 #endif
6884 #ifdef _SC_DELAYTIMER_MAX
6885 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
6886 #endif
6887 #ifdef _SC_EQUIV_CLASS_MAX
6888 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
6889 #endif
6890 #ifdef _SC_EXPR_NEST_MAX
6891 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
6892 #endif
6893 #ifdef _SC_FSYNC
6894 {"SC_FSYNC", _SC_FSYNC},
6895 #endif
6896 #ifdef _SC_GETGR_R_SIZE_MAX
6897 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
6898 #endif
6899 #ifdef _SC_GETPW_R_SIZE_MAX
6900 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
6901 #endif
6902 #ifdef _SC_ICACHE_ASSOC
6903 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
6904 #endif
6905 #ifdef _SC_ICACHE_BLKSZ
6906 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
6907 #endif
6908 #ifdef _SC_ICACHE_LINESZ
6909 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
6910 #endif
6911 #ifdef _SC_ICACHE_SZ
6912 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
6913 #endif
6914 #ifdef _SC_INF
6915 {"SC_INF", _SC_INF},
6916 #endif
6917 #ifdef _SC_INT_MAX
6918 {"SC_INT_MAX", _SC_INT_MAX},
6919 #endif
6920 #ifdef _SC_INT_MIN
6921 {"SC_INT_MIN", _SC_INT_MIN},
6922 #endif
6923 #ifdef _SC_IOV_MAX
6924 {"SC_IOV_MAX", _SC_IOV_MAX},
6925 #endif
6926 #ifdef _SC_IP_SECOPTS
6927 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
6928 #endif
6929 #ifdef _SC_JOB_CONTROL
6930 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
6931 #endif
6932 #ifdef _SC_KERN_POINTERS
6933 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
6934 #endif
6935 #ifdef _SC_KERN_SIM
6936 {"SC_KERN_SIM", _SC_KERN_SIM},
6937 #endif
6938 #ifdef _SC_LINE_MAX
6939 {"SC_LINE_MAX", _SC_LINE_MAX},
6940 #endif
6941 #ifdef _SC_LOGIN_NAME_MAX
6942 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
6943 #endif
6944 #ifdef _SC_LOGNAME_MAX
6945 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
6946 #endif
6947 #ifdef _SC_LONG_BIT
6948 {"SC_LONG_BIT", _SC_LONG_BIT},
6949 #endif
6950 #ifdef _SC_MAC
6951 {"SC_MAC", _SC_MAC},
6952 #endif
6953 #ifdef _SC_MAPPED_FILES
6954 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
6955 #endif
6956 #ifdef _SC_MAXPID
6957 {"SC_MAXPID", _SC_MAXPID},
6958 #endif
6959 #ifdef _SC_MB_LEN_MAX
6960 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
6961 #endif
6962 #ifdef _SC_MEMLOCK
6963 {"SC_MEMLOCK", _SC_MEMLOCK},
6964 #endif
6965 #ifdef _SC_MEMLOCK_RANGE
6966 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
6967 #endif
6968 #ifdef _SC_MEMORY_PROTECTION
6969 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
6970 #endif
6971 #ifdef _SC_MESSAGE_PASSING
6972 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
6973 #endif
6974 #ifdef _SC_MMAP_FIXED_ALIGNMENT
6975 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
6976 #endif
6977 #ifdef _SC_MQ_OPEN_MAX
6978 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
6979 #endif
6980 #ifdef _SC_MQ_PRIO_MAX
6981 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
6982 #endif
6983 #ifdef _SC_NACLS_MAX
6984 {"SC_NACLS_MAX", _SC_NACLS_MAX},
6985 #endif
6986 #ifdef _SC_NGROUPS_MAX
6987 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
6988 #endif
6989 #ifdef _SC_NL_ARGMAX
6990 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
6991 #endif
6992 #ifdef _SC_NL_LANGMAX
6993 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
6994 #endif
6995 #ifdef _SC_NL_MSGMAX
6996 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
6997 #endif
6998 #ifdef _SC_NL_NMAX
6999 {"SC_NL_NMAX", _SC_NL_NMAX},
7000 #endif
7001 #ifdef _SC_NL_SETMAX
7002 {"SC_NL_SETMAX", _SC_NL_SETMAX},
7003 #endif
7004 #ifdef _SC_NL_TEXTMAX
7005 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
7006 #endif
7007 #ifdef _SC_NPROCESSORS_CONF
7008 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
7009 #endif
7010 #ifdef _SC_NPROCESSORS_ONLN
7011 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
7012 #endif
7013 #ifdef _SC_NPROC_CONF
7014 {"SC_NPROC_CONF", _SC_NPROC_CONF},
7015 #endif
7016 #ifdef _SC_NPROC_ONLN
7017 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
7018 #endif
7019 #ifdef _SC_NZERO
7020 {"SC_NZERO", _SC_NZERO},
7021 #endif
7022 #ifdef _SC_OPEN_MAX
7023 {"SC_OPEN_MAX", _SC_OPEN_MAX},
7024 #endif
7025 #ifdef _SC_PAGESIZE
7026 {"SC_PAGESIZE", _SC_PAGESIZE},
7027 #endif
7028 #ifdef _SC_PAGE_SIZE
7029 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
7030 #endif
7031 #ifdef _SC_PASS_MAX
7032 {"SC_PASS_MAX", _SC_PASS_MAX},
7033 #endif
7034 #ifdef _SC_PHYS_PAGES
7035 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
7036 #endif
7037 #ifdef _SC_PII
7038 {"SC_PII", _SC_PII},
7039 #endif
7040 #ifdef _SC_PII_INTERNET
7041 {"SC_PII_INTERNET", _SC_PII_INTERNET},
7042 #endif
7043 #ifdef _SC_PII_INTERNET_DGRAM
7044 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
7045 #endif
7046 #ifdef _SC_PII_INTERNET_STREAM
7047 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
7048 #endif
7049 #ifdef _SC_PII_OSI
7050 {"SC_PII_OSI", _SC_PII_OSI},
7051 #endif
7052 #ifdef _SC_PII_OSI_CLTS
7053 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
7054 #endif
7055 #ifdef _SC_PII_OSI_COTS
7056 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
7057 #endif
7058 #ifdef _SC_PII_OSI_M
7059 {"SC_PII_OSI_M", _SC_PII_OSI_M},
7060 #endif
7061 #ifdef _SC_PII_SOCKET
7062 {"SC_PII_SOCKET", _SC_PII_SOCKET},
7063 #endif
7064 #ifdef _SC_PII_XTI
7065 {"SC_PII_XTI", _SC_PII_XTI},
7066 #endif
7067 #ifdef _SC_POLL
7068 {"SC_POLL", _SC_POLL},
7069 #endif
7070 #ifdef _SC_PRIORITIZED_IO
7071 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
7072 #endif
7073 #ifdef _SC_PRIORITY_SCHEDULING
7074 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
7075 #endif
7076 #ifdef _SC_REALTIME_SIGNALS
7077 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
7078 #endif
7079 #ifdef _SC_RE_DUP_MAX
7080 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
7081 #endif
7082 #ifdef _SC_RTSIG_MAX
7083 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
7084 #endif
7085 #ifdef _SC_SAVED_IDS
7086 {"SC_SAVED_IDS", _SC_SAVED_IDS},
7087 #endif
7088 #ifdef _SC_SCHAR_MAX
7089 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
7090 #endif
7091 #ifdef _SC_SCHAR_MIN
7092 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
7093 #endif
7094 #ifdef _SC_SELECT
7095 {"SC_SELECT", _SC_SELECT},
7096 #endif
7097 #ifdef _SC_SEMAPHORES
7098 {"SC_SEMAPHORES", _SC_SEMAPHORES},
7099 #endif
7100 #ifdef _SC_SEM_NSEMS_MAX
7101 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
7102 #endif
7103 #ifdef _SC_SEM_VALUE_MAX
7104 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
7105 #endif
7106 #ifdef _SC_SHARED_MEMORY_OBJECTS
7107 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
7108 #endif
7109 #ifdef _SC_SHRT_MAX
7110 {"SC_SHRT_MAX", _SC_SHRT_MAX},
7111 #endif
7112 #ifdef _SC_SHRT_MIN
7113 {"SC_SHRT_MIN", _SC_SHRT_MIN},
7114 #endif
7115 #ifdef _SC_SIGQUEUE_MAX
7116 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
7117 #endif
7118 #ifdef _SC_SIGRT_MAX
7119 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
7120 #endif
7121 #ifdef _SC_SIGRT_MIN
7122 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
7123 #endif
7124 #ifdef _SC_SOFTPOWER
7125 {"SC_SOFTPOWER", _SC_SOFTPOWER},
7126 #endif
7127 #ifdef _SC_SPLIT_CACHE
7128 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
7129 #endif
7130 #ifdef _SC_SSIZE_MAX
7131 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
7132 #endif
7133 #ifdef _SC_STACK_PROT
7134 {"SC_STACK_PROT", _SC_STACK_PROT},
7135 #endif
7136 #ifdef _SC_STREAM_MAX
7137 {"SC_STREAM_MAX", _SC_STREAM_MAX},
7138 #endif
7139 #ifdef _SC_SYNCHRONIZED_IO
7140 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
7141 #endif
7142 #ifdef _SC_THREADS
7143 {"SC_THREADS", _SC_THREADS},
7144 #endif
7145 #ifdef _SC_THREAD_ATTR_STACKADDR
7146 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
7147 #endif
7148 #ifdef _SC_THREAD_ATTR_STACKSIZE
7149 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
7150 #endif
7151 #ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
7152 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
7153 #endif
7154 #ifdef _SC_THREAD_KEYS_MAX
7155 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
7156 #endif
7157 #ifdef _SC_THREAD_PRIORITY_SCHEDULING
7158 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
7159 #endif
7160 #ifdef _SC_THREAD_PRIO_INHERIT
7161 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
7162 #endif
7163 #ifdef _SC_THREAD_PRIO_PROTECT
7164 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
7165 #endif
7166 #ifdef _SC_THREAD_PROCESS_SHARED
7167 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
7168 #endif
7169 #ifdef _SC_THREAD_SAFE_FUNCTIONS
7170 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
7171 #endif
7172 #ifdef _SC_THREAD_STACK_MIN
7173 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
7174 #endif
7175 #ifdef _SC_THREAD_THREADS_MAX
7176 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
7177 #endif
7178 #ifdef _SC_TIMERS
7179 {"SC_TIMERS", _SC_TIMERS},
7180 #endif
7181 #ifdef _SC_TIMER_MAX
7182 {"SC_TIMER_MAX", _SC_TIMER_MAX},
7183 #endif
7184 #ifdef _SC_TTY_NAME_MAX
7185 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
7186 #endif
7187 #ifdef _SC_TZNAME_MAX
7188 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
7189 #endif
7190 #ifdef _SC_T_IOV_MAX
7191 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
7192 #endif
7193 #ifdef _SC_UCHAR_MAX
7194 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
7195 #endif
7196 #ifdef _SC_UINT_MAX
7197 {"SC_UINT_MAX", _SC_UINT_MAX},
7198 #endif
7199 #ifdef _SC_UIO_MAXIOV
7200 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
7201 #endif
7202 #ifdef _SC_ULONG_MAX
7203 {"SC_ULONG_MAX", _SC_ULONG_MAX},
7204 #endif
7205 #ifdef _SC_USHRT_MAX
7206 {"SC_USHRT_MAX", _SC_USHRT_MAX},
7207 #endif
7208 #ifdef _SC_VERSION
7209 {"SC_VERSION", _SC_VERSION},
7210 #endif
7211 #ifdef _SC_WORD_BIT
7212 {"SC_WORD_BIT", _SC_WORD_BIT},
7213 #endif
7214 #ifdef _SC_XBS5_ILP32_OFF32
7215 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
7216 #endif
7217 #ifdef _SC_XBS5_ILP32_OFFBIG
7218 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
7219 #endif
7220 #ifdef _SC_XBS5_LP64_OFF64
7221 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
7222 #endif
7223 #ifdef _SC_XBS5_LPBIG_OFFBIG
7224 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
7225 #endif
7226 #ifdef _SC_XOPEN_CRYPT
7227 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
7228 #endif
7229 #ifdef _SC_XOPEN_ENH_I18N
7230 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
7231 #endif
7232 #ifdef _SC_XOPEN_LEGACY
7233 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
7234 #endif
7235 #ifdef _SC_XOPEN_REALTIME
7236 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
7237 #endif
7238 #ifdef _SC_XOPEN_REALTIME_THREADS
7239 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
7240 #endif
7241 #ifdef _SC_XOPEN_SHM
7242 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
7243 #endif
7244 #ifdef _SC_XOPEN_UNIX
7245 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
7246 #endif
7247 #ifdef _SC_XOPEN_VERSION
7248 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
7249 #endif
7250 #ifdef _SC_XOPEN_XCU_VERSION
7251 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
7252 #endif
7253 #ifdef _SC_XOPEN_XPG2
7254 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
7255 #endif
7256 #ifdef _SC_XOPEN_XPG3
7257 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
7258 #endif
7259 #ifdef _SC_XOPEN_XPG4
7260 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
7261 #endif
7264 static int
7265 conv_sysconf_confname(PyObject *arg, int *valuep)
7267 return conv_confname(arg, valuep, posix_constants_sysconf,
7268 sizeof(posix_constants_sysconf)
7269 / sizeof(struct constdef));
7272 PyDoc_STRVAR(posix_sysconf__doc__,
7273 "sysconf(name) -> integer\n\n\
7274 Return an integer-valued system configuration variable.");
7276 static PyObject *
7277 posix_sysconf(PyObject *self, PyObject *args)
7279 PyObject *result = NULL;
7280 int name;
7282 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
7283 int value;
7285 errno = 0;
7286 value = sysconf(name);
7287 if (value == -1 && errno != 0)
7288 posix_error();
7289 else
7290 result = PyInt_FromLong(value);
7292 return result;
7294 #endif
7297 /* This code is used to ensure that the tables of configuration value names
7298 * are in sorted order as required by conv_confname(), and also to build the
7299 * the exported dictionaries that are used to publish information about the
7300 * names available on the host platform.
7302 * Sorting the table at runtime ensures that the table is properly ordered
7303 * when used, even for platforms we're not able to test on. It also makes
7304 * it easier to add additional entries to the tables.
7307 static int
7308 cmp_constdefs(const void *v1, const void *v2)
7310 const struct constdef *c1 =
7311 (const struct constdef *) v1;
7312 const struct constdef *c2 =
7313 (const struct constdef *) v2;
7315 return strcmp(c1->name, c2->name);
7318 static int
7319 setup_confname_table(struct constdef *table, size_t tablesize,
7320 char *tablename, PyObject *module)
7322 PyObject *d = NULL;
7323 size_t i;
7325 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
7326 d = PyDict_New();
7327 if (d == NULL)
7328 return -1;
7330 for (i=0; i < tablesize; ++i) {
7331 PyObject *o = PyInt_FromLong(table[i].value);
7332 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
7333 Py_XDECREF(o);
7334 Py_DECREF(d);
7335 return -1;
7337 Py_DECREF(o);
7339 return PyModule_AddObject(module, tablename, d);
7342 /* Return -1 on failure, 0 on success. */
7343 static int
7344 setup_confname_tables(PyObject *module)
7346 #if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
7347 if (setup_confname_table(posix_constants_pathconf,
7348 sizeof(posix_constants_pathconf)
7349 / sizeof(struct constdef),
7350 "pathconf_names", module))
7351 return -1;
7352 #endif
7353 #ifdef HAVE_CONFSTR
7354 if (setup_confname_table(posix_constants_confstr,
7355 sizeof(posix_constants_confstr)
7356 / sizeof(struct constdef),
7357 "confstr_names", module))
7358 return -1;
7359 #endif
7360 #ifdef HAVE_SYSCONF
7361 if (setup_confname_table(posix_constants_sysconf,
7362 sizeof(posix_constants_sysconf)
7363 / sizeof(struct constdef),
7364 "sysconf_names", module))
7365 return -1;
7366 #endif
7367 return 0;
7371 PyDoc_STRVAR(posix_abort__doc__,
7372 "abort() -> does not return!\n\n\
7373 Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
7374 in the hardest way possible on the hosting operating system.");
7376 static PyObject *
7377 posix_abort(PyObject *self, PyObject *noargs)
7379 abort();
7380 /*NOTREACHED*/
7381 Py_FatalError("abort() called from Python code didn't abort!");
7382 return NULL;
7385 #ifdef MS_WINDOWS
7386 PyDoc_STRVAR(win32_startfile__doc__,
7387 "startfile(filepath) - Start a file with its associated application.\n\
7389 This acts like double-clicking the file in Explorer, or giving the file\n\
7390 name as an argument to the DOS \"start\" command: the file is opened\n\
7391 with whatever application (if any) its extension is associated.\n\
7393 startfile returns as soon as the associated application is launched.\n\
7394 There is no option to wait for the application to close, and no way\n\
7395 to retrieve the application's exit status.\n\
7397 The filepath is relative to the current directory. If you want to use\n\
7398 an absolute path, make sure the first character is not a slash (\"/\");\n\
7399 the underlying Win32 ShellExecute function doesn't work if it is.");
7401 static PyObject *
7402 win32_startfile(PyObject *self, PyObject *args)
7404 char *filepath;
7405 HINSTANCE rc;
7406 if (!PyArg_ParseTuple(args, "et:startfile",
7407 Py_FileSystemDefaultEncoding, &filepath))
7408 return NULL;
7409 Py_BEGIN_ALLOW_THREADS
7410 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
7411 Py_END_ALLOW_THREADS
7412 if (rc <= (HINSTANCE)32) {
7413 PyObject *errval = win32_error("startfile", filepath);
7414 PyMem_Free(filepath);
7415 return errval;
7417 PyMem_Free(filepath);
7418 Py_INCREF(Py_None);
7419 return Py_None;
7421 #endif
7423 #ifdef HAVE_GETLOADAVG
7424 PyDoc_STRVAR(posix_getloadavg__doc__,
7425 "getloadavg() -> (float, float, float)\n\n\
7426 Return the number of processes in the system run queue averaged over\n\
7427 the last 1, 5, and 15 minutes or raises OSError if the load average\n\
7428 was unobtainable");
7430 static PyObject *
7431 posix_getloadavg(PyObject *self, PyObject *noargs)
7433 double loadavg[3];
7434 if (getloadavg(loadavg, 3)!=3) {
7435 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
7436 return NULL;
7437 } else
7438 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
7440 #endif
7442 #ifdef MS_WINDOWS
7444 PyDoc_STRVAR(win32_urandom__doc__,
7445 "urandom(n) -> str\n\n\
7446 Return a string of n random bytes suitable for cryptographic use.");
7448 typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
7449 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
7450 DWORD dwFlags );
7451 typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
7452 BYTE *pbBuffer );
7454 static CRYPTGENRANDOM pCryptGenRandom = NULL;
7455 static HCRYPTPROV hCryptProv = 0;
7457 static PyObject*
7458 win32_urandom(PyObject *self, PyObject *args)
7460 int howMany;
7461 PyObject* result;
7463 /* Read arguments */
7464 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
7465 return NULL;
7466 if (howMany < 0)
7467 return PyErr_Format(PyExc_ValueError,
7468 "negative argument not allowed");
7470 if (hCryptProv == 0) {
7471 HINSTANCE hAdvAPI32 = NULL;
7472 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
7474 /* Obtain handle to the DLL containing CryptoAPI
7475 This should not fail */
7476 hAdvAPI32 = GetModuleHandle("advapi32.dll");
7477 if(hAdvAPI32 == NULL)
7478 return win32_error("GetModuleHandle", NULL);
7480 /* Obtain pointers to the CryptoAPI functions
7481 This will fail on some early versions of Win95 */
7482 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
7483 hAdvAPI32,
7484 "CryptAcquireContextA");
7485 if (pCryptAcquireContext == NULL)
7486 return PyErr_Format(PyExc_NotImplementedError,
7487 "CryptAcquireContextA not found");
7489 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
7490 hAdvAPI32, "CryptGenRandom");
7491 if (pCryptAcquireContext == NULL)
7492 return PyErr_Format(PyExc_NotImplementedError,
7493 "CryptGenRandom not found");
7495 /* Acquire context */
7496 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
7497 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
7498 return win32_error("CryptAcquireContext", NULL);
7501 /* Allocate bytes */
7502 result = PyString_FromStringAndSize(NULL, howMany);
7503 if (result != NULL) {
7504 /* Get random data */
7505 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
7506 PyString_AS_STRING(result))) {
7507 Py_DECREF(result);
7508 return win32_error("CryptGenRandom", NULL);
7511 return result;
7513 #endif
7515 static PyMethodDef posix_methods[] = {
7516 {"access", posix_access, METH_VARARGS, posix_access__doc__},
7517 #ifdef HAVE_TTYNAME
7518 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
7519 #endif
7520 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
7521 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
7522 #ifdef HAVE_CHOWN
7523 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
7524 #endif /* HAVE_CHOWN */
7525 #ifdef HAVE_LCHOWN
7526 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
7527 #endif /* HAVE_LCHOWN */
7528 #ifdef HAVE_CHROOT
7529 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
7530 #endif
7531 #ifdef HAVE_CTERMID
7532 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
7533 #endif
7534 #ifdef HAVE_GETCWD
7535 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
7536 #ifdef Py_USING_UNICODE
7537 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
7538 #endif
7539 #endif
7540 #ifdef HAVE_LINK
7541 {"link", posix_link, METH_VARARGS, posix_link__doc__},
7542 #endif /* HAVE_LINK */
7543 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
7544 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
7545 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
7546 #ifdef HAVE_NICE
7547 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
7548 #endif /* HAVE_NICE */
7549 #ifdef HAVE_READLINK
7550 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
7551 #endif /* HAVE_READLINK */
7552 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
7553 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
7554 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
7555 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
7556 #ifdef HAVE_SYMLINK
7557 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
7558 #endif /* HAVE_SYMLINK */
7559 #ifdef HAVE_SYSTEM
7560 {"system", posix_system, METH_VARARGS, posix_system__doc__},
7561 #endif
7562 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
7563 #ifdef HAVE_UNAME
7564 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
7565 #endif /* HAVE_UNAME */
7566 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
7567 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
7568 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
7569 #ifdef HAVE_TIMES
7570 {"times", posix_times, METH_NOARGS, posix_times__doc__},
7571 #endif /* HAVE_TIMES */
7572 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
7573 #ifdef HAVE_EXECV
7574 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
7575 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
7576 #endif /* HAVE_EXECV */
7577 #ifdef HAVE_SPAWNV
7578 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
7579 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
7580 #if defined(PYOS_OS2)
7581 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
7582 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
7583 #endif /* PYOS_OS2 */
7584 #endif /* HAVE_SPAWNV */
7585 #ifdef HAVE_FORK1
7586 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
7587 #endif /* HAVE_FORK1 */
7588 #ifdef HAVE_FORK
7589 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
7590 #endif /* HAVE_FORK */
7591 #if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
7592 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
7593 #endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
7594 #ifdef HAVE_FORKPTY
7595 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
7596 #endif /* HAVE_FORKPTY */
7597 #ifdef HAVE_GETEGID
7598 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
7599 #endif /* HAVE_GETEGID */
7600 #ifdef HAVE_GETEUID
7601 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
7602 #endif /* HAVE_GETEUID */
7603 #ifdef HAVE_GETGID
7604 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
7605 #endif /* HAVE_GETGID */
7606 #ifdef HAVE_GETGROUPS
7607 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
7608 #endif
7609 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
7610 #ifdef HAVE_GETPGRP
7611 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
7612 #endif /* HAVE_GETPGRP */
7613 #ifdef HAVE_GETPPID
7614 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
7615 #endif /* HAVE_GETPPID */
7616 #ifdef HAVE_GETUID
7617 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
7618 #endif /* HAVE_GETUID */
7619 #ifdef HAVE_GETLOGIN
7620 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
7621 #endif
7622 #ifdef HAVE_KILL
7623 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
7624 #endif /* HAVE_KILL */
7625 #ifdef HAVE_KILLPG
7626 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
7627 #endif /* HAVE_KILLPG */
7628 #ifdef HAVE_PLOCK
7629 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
7630 #endif /* HAVE_PLOCK */
7631 #ifdef HAVE_POPEN
7632 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
7633 #ifdef MS_WINDOWS
7634 {"popen2", win32_popen2, METH_VARARGS},
7635 {"popen3", win32_popen3, METH_VARARGS},
7636 {"popen4", win32_popen4, METH_VARARGS},
7637 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
7638 #else
7639 #if defined(PYOS_OS2) && defined(PYCC_GCC)
7640 {"popen2", os2emx_popen2, METH_VARARGS},
7641 {"popen3", os2emx_popen3, METH_VARARGS},
7642 {"popen4", os2emx_popen4, METH_VARARGS},
7643 #endif
7644 #endif
7645 #endif /* HAVE_POPEN */
7646 #ifdef HAVE_SETUID
7647 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
7648 #endif /* HAVE_SETUID */
7649 #ifdef HAVE_SETEUID
7650 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
7651 #endif /* HAVE_SETEUID */
7652 #ifdef HAVE_SETEGID
7653 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
7654 #endif /* HAVE_SETEGID */
7655 #ifdef HAVE_SETREUID
7656 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
7657 #endif /* HAVE_SETREUID */
7658 #ifdef HAVE_SETREGID
7659 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
7660 #endif /* HAVE_SETREGID */
7661 #ifdef HAVE_SETGID
7662 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
7663 #endif /* HAVE_SETGID */
7664 #ifdef HAVE_SETGROUPS
7665 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
7666 #endif /* HAVE_SETGROUPS */
7667 #ifdef HAVE_GETPGID
7668 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
7669 #endif /* HAVE_GETPGID */
7670 #ifdef HAVE_SETPGRP
7671 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
7672 #endif /* HAVE_SETPGRP */
7673 #ifdef HAVE_WAIT
7674 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
7675 #endif /* HAVE_WAIT */
7676 #if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
7677 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
7678 #endif /* HAVE_WAITPID */
7679 #ifdef HAVE_GETSID
7680 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
7681 #endif /* HAVE_GETSID */
7682 #ifdef HAVE_SETSID
7683 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
7684 #endif /* HAVE_SETSID */
7685 #ifdef HAVE_SETPGID
7686 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
7687 #endif /* HAVE_SETPGID */
7688 #ifdef HAVE_TCGETPGRP
7689 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
7690 #endif /* HAVE_TCGETPGRP */
7691 #ifdef HAVE_TCSETPGRP
7692 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
7693 #endif /* HAVE_TCSETPGRP */
7694 {"open", posix_open, METH_VARARGS, posix_open__doc__},
7695 {"close", posix_close, METH_VARARGS, posix_close__doc__},
7696 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
7697 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
7698 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
7699 {"read", posix_read, METH_VARARGS, posix_read__doc__},
7700 {"write", posix_write, METH_VARARGS, posix_write__doc__},
7701 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
7702 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
7703 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
7704 #ifdef HAVE_PIPE
7705 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
7706 #endif
7707 #ifdef HAVE_MKFIFO
7708 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
7709 #endif
7710 #if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
7711 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
7712 #endif
7713 #ifdef HAVE_DEVICE_MACROS
7714 {"major", posix_major, METH_VARARGS, posix_major__doc__},
7715 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
7716 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
7717 #endif
7718 #ifdef HAVE_FTRUNCATE
7719 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
7720 #endif
7721 #ifdef HAVE_PUTENV
7722 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
7723 #endif
7724 #ifdef HAVE_UNSETENV
7725 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
7726 #endif
7727 #ifdef HAVE_STRERROR
7728 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
7729 #endif
7730 #ifdef HAVE_FCHDIR
7731 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
7732 #endif
7733 #ifdef HAVE_FSYNC
7734 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
7735 #endif
7736 #ifdef HAVE_FDATASYNC
7737 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
7738 #endif
7739 #ifdef HAVE_SYS_WAIT_H
7740 #ifdef WCOREDUMP
7741 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
7742 #endif /* WCOREDUMP */
7743 #ifdef WIFCONTINUED
7744 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
7745 #endif /* WIFCONTINUED */
7746 #ifdef WIFSTOPPED
7747 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
7748 #endif /* WIFSTOPPED */
7749 #ifdef WIFSIGNALED
7750 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
7751 #endif /* WIFSIGNALED */
7752 #ifdef WIFEXITED
7753 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
7754 #endif /* WIFEXITED */
7755 #ifdef WEXITSTATUS
7756 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
7757 #endif /* WEXITSTATUS */
7758 #ifdef WTERMSIG
7759 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
7760 #endif /* WTERMSIG */
7761 #ifdef WSTOPSIG
7762 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
7763 #endif /* WSTOPSIG */
7764 #endif /* HAVE_SYS_WAIT_H */
7765 #ifdef HAVE_FSTATVFS
7766 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
7767 #endif
7768 #ifdef HAVE_STATVFS
7769 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
7770 #endif
7771 #ifdef HAVE_TMPFILE
7772 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
7773 #endif
7774 #ifdef HAVE_TEMPNAM
7775 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
7776 #endif
7777 #ifdef HAVE_TMPNAM
7778 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
7779 #endif
7780 #ifdef HAVE_CONFSTR
7781 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
7782 #endif
7783 #ifdef HAVE_SYSCONF
7784 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
7785 #endif
7786 #ifdef HAVE_FPATHCONF
7787 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
7788 #endif
7789 #ifdef HAVE_PATHCONF
7790 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
7791 #endif
7792 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
7793 #ifdef MS_WINDOWS
7794 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
7795 #endif
7796 #ifdef HAVE_GETLOADAVG
7797 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
7798 #endif
7799 #ifdef MS_WINDOWS
7800 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
7801 #endif
7802 {NULL, NULL} /* Sentinel */
7806 static int
7807 ins(PyObject *module, char *symbol, long value)
7809 return PyModule_AddIntConstant(module, symbol, value);
7812 #if defined(PYOS_OS2)
7813 /* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
7814 static int insertvalues(PyObject *module)
7816 APIRET rc;
7817 ULONG values[QSV_MAX+1];
7818 PyObject *v;
7819 char *ver, tmp[50];
7821 Py_BEGIN_ALLOW_THREADS
7822 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
7823 Py_END_ALLOW_THREADS
7825 if (rc != NO_ERROR) {
7826 os2_error(rc);
7827 return -1;
7830 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
7831 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
7832 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
7833 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
7834 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
7835 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
7836 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
7838 switch (values[QSV_VERSION_MINOR]) {
7839 case 0: ver = "2.00"; break;
7840 case 10: ver = "2.10"; break;
7841 case 11: ver = "2.11"; break;
7842 case 30: ver = "3.00"; break;
7843 case 40: ver = "4.00"; break;
7844 case 50: ver = "5.00"; break;
7845 default:
7846 PyOS_snprintf(tmp, sizeof(tmp),
7847 "%d-%d", values[QSV_VERSION_MAJOR],
7848 values[QSV_VERSION_MINOR]);
7849 ver = &tmp[0];
7852 /* Add Indicator of the Version of the Operating System */
7853 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
7854 return -1;
7856 /* Add Indicator of Which Drive was Used to Boot the System */
7857 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
7858 tmp[1] = ':';
7859 tmp[2] = '\0';
7861 return PyModule_AddStringConstant(module, "bootdrive", tmp);
7863 #endif
7865 static int
7866 all_ins(PyObject *d)
7868 #ifdef F_OK
7869 if (ins(d, "F_OK", (long)F_OK)) return -1;
7870 #endif
7871 #ifdef R_OK
7872 if (ins(d, "R_OK", (long)R_OK)) return -1;
7873 #endif
7874 #ifdef W_OK
7875 if (ins(d, "W_OK", (long)W_OK)) return -1;
7876 #endif
7877 #ifdef X_OK
7878 if (ins(d, "X_OK", (long)X_OK)) return -1;
7879 #endif
7880 #ifdef NGROUPS_MAX
7881 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
7882 #endif
7883 #ifdef TMP_MAX
7884 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
7885 #endif
7886 #ifdef WCONTINUED
7887 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
7888 #endif
7889 #ifdef WNOHANG
7890 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
7891 #endif
7892 #ifdef WUNTRACED
7893 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
7894 #endif
7895 #ifdef O_RDONLY
7896 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
7897 #endif
7898 #ifdef O_WRONLY
7899 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
7900 #endif
7901 #ifdef O_RDWR
7902 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
7903 #endif
7904 #ifdef O_NDELAY
7905 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
7906 #endif
7907 #ifdef O_NONBLOCK
7908 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
7909 #endif
7910 #ifdef O_APPEND
7911 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
7912 #endif
7913 #ifdef O_DSYNC
7914 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
7915 #endif
7916 #ifdef O_RSYNC
7917 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
7918 #endif
7919 #ifdef O_SYNC
7920 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
7921 #endif
7922 #ifdef O_NOCTTY
7923 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
7924 #endif
7925 #ifdef O_CREAT
7926 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
7927 #endif
7928 #ifdef O_EXCL
7929 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
7930 #endif
7931 #ifdef O_TRUNC
7932 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
7933 #endif
7934 #ifdef O_BINARY
7935 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
7936 #endif
7937 #ifdef O_TEXT
7938 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
7939 #endif
7940 #ifdef O_LARGEFILE
7941 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
7942 #endif
7943 #ifdef O_SHLOCK
7944 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
7945 #endif
7946 #ifdef O_EXLOCK
7947 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
7948 #endif
7950 /* MS Windows */
7951 #ifdef O_NOINHERIT
7952 /* Don't inherit in child processes. */
7953 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
7954 #endif
7955 #ifdef _O_SHORT_LIVED
7956 /* Optimize for short life (keep in memory). */
7957 /* MS forgot to define this one with a non-underscore form too. */
7958 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
7959 #endif
7960 #ifdef O_TEMPORARY
7961 /* Automatically delete when last handle is closed. */
7962 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
7963 #endif
7964 #ifdef O_RANDOM
7965 /* Optimize for random access. */
7966 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
7967 #endif
7968 #ifdef O_SEQUENTIAL
7969 /* Optimize for sequential access. */
7970 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
7971 #endif
7973 /* GNU extensions. */
7974 #ifdef O_DIRECT
7975 /* Direct disk access. */
7976 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
7977 #endif
7978 #ifdef O_DIRECTORY
7979 /* Must be a directory. */
7980 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
7981 #endif
7982 #ifdef O_NOFOLLOW
7983 /* Do not follow links. */
7984 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
7985 #endif
7987 /* These come from sysexits.h */
7988 #ifdef EX_OK
7989 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
7990 #endif /* EX_OK */
7991 #ifdef EX_USAGE
7992 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
7993 #endif /* EX_USAGE */
7994 #ifdef EX_DATAERR
7995 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
7996 #endif /* EX_DATAERR */
7997 #ifdef EX_NOINPUT
7998 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
7999 #endif /* EX_NOINPUT */
8000 #ifdef EX_NOUSER
8001 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
8002 #endif /* EX_NOUSER */
8003 #ifdef EX_NOHOST
8004 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
8005 #endif /* EX_NOHOST */
8006 #ifdef EX_UNAVAILABLE
8007 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
8008 #endif /* EX_UNAVAILABLE */
8009 #ifdef EX_SOFTWARE
8010 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
8011 #endif /* EX_SOFTWARE */
8012 #ifdef EX_OSERR
8013 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
8014 #endif /* EX_OSERR */
8015 #ifdef EX_OSFILE
8016 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
8017 #endif /* EX_OSFILE */
8018 #ifdef EX_CANTCREAT
8019 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
8020 #endif /* EX_CANTCREAT */
8021 #ifdef EX_IOERR
8022 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
8023 #endif /* EX_IOERR */
8024 #ifdef EX_TEMPFAIL
8025 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
8026 #endif /* EX_TEMPFAIL */
8027 #ifdef EX_PROTOCOL
8028 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
8029 #endif /* EX_PROTOCOL */
8030 #ifdef EX_NOPERM
8031 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
8032 #endif /* EX_NOPERM */
8033 #ifdef EX_CONFIG
8034 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
8035 #endif /* EX_CONFIG */
8036 #ifdef EX_NOTFOUND
8037 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
8038 #endif /* EX_NOTFOUND */
8040 #ifdef HAVE_SPAWNV
8041 #if defined(PYOS_OS2) && defined(PYCC_GCC)
8042 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
8043 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
8044 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
8045 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
8046 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
8047 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
8048 if (ins(d, "P_PM", (long)P_PM)) return -1;
8049 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
8050 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
8051 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
8052 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
8053 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
8054 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
8055 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
8056 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
8057 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
8058 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
8059 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
8060 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
8061 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
8062 #else
8063 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
8064 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
8065 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
8066 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
8067 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
8068 #endif
8069 #endif
8071 #if defined(PYOS_OS2)
8072 if (insertvalues(d)) return -1;
8073 #endif
8074 return 0;
8078 #if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
8079 #define INITFUNC initnt
8080 #define MODNAME "nt"
8082 #elif defined(PYOS_OS2)
8083 #define INITFUNC initos2
8084 #define MODNAME "os2"
8086 #else
8087 #define INITFUNC initposix
8088 #define MODNAME "posix"
8089 #endif
8091 PyMODINIT_FUNC
8092 INITFUNC(void)
8094 PyObject *m, *v;
8096 m = Py_InitModule3(MODNAME,
8097 posix_methods,
8098 posix__doc__);
8099 if (m == NULL)
8100 return;
8102 /* Initialize environ dictionary */
8103 v = convertenviron();
8104 Py_XINCREF(v);
8105 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
8106 return;
8107 Py_DECREF(v);
8109 if (all_ins(m))
8110 return;
8112 if (setup_confname_tables(m))
8113 return;
8115 Py_INCREF(PyExc_OSError);
8116 PyModule_AddObject(m, "error", PyExc_OSError);
8118 #ifdef HAVE_PUTENV
8119 if (posix_putenv_garbage == NULL)
8120 posix_putenv_garbage = PyDict_New();
8121 #endif
8123 stat_result_desc.name = MODNAME ".stat_result";
8124 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
8125 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
8126 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
8127 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
8128 structseq_new = StatResultType.tp_new;
8129 StatResultType.tp_new = statresult_new;
8130 Py_INCREF((PyObject*) &StatResultType);
8131 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
8133 statvfs_result_desc.name = MODNAME ".statvfs_result";
8134 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
8135 Py_INCREF((PyObject*) &StatVFSResultType);
8136 PyModule_AddObject(m, "statvfs_result",
8137 (PyObject*) &StatVFSResultType);