This commit was manufactured by cvs2svn to create tag 'r241c1'.
[python/dscho.git] / Modules / posixmodule.c
blobb577ba947dad4c73a86989457296d3a7dbb26faf
2 /* POSIX module implementation */
4 /* This file is also used for Windows NT/MS-Win and OS/2. In that case the
5 module actually calls itself 'nt' or 'os2', not 'posix', and a few
6 functions are either unimplemented or implemented differently. The source
7 assumes that for Windows NT, the macro 'MS_WINDOWS' is defined independent
8 of the compiler used. Different compilers define their own feature
9 test macro, e.g. '__BORLANDC__' or '_MSC_VER'. For OS/2, the compiler
10 independent macro PYOS_OS2 should be defined. On OS/2 the default
11 compiler is assumed to be IBM's VisualAge C++ (VACPP). PYCC_GCC is used
12 as the compiler specific macro for the EMX port of gcc to OS/2. */
14 /* See also ../Dos/dosmodule.c */
16 #include "Python.h"
17 #include "structseq.h"
19 #if defined(__VMS)
20 # include <unixio.h>
21 #endif /* defined(__VMS) */
23 PyDoc_STRVAR(posix__doc__,
24 "This module provides access to operating system functionality that is\n\
25 standardized by the C Standard and the POSIX standard (a thinly\n\
26 disguised Unix interface). Refer to the library manual and\n\
27 corresponding Unix manual entries for more information on calls.");
29 #ifndef Py_USING_UNICODE
30 /* This is used in signatures of functions. */
31 #define Py_UNICODE void
32 #endif
34 #if defined(PYOS_OS2)
35 #define INCL_DOS
36 #define INCL_DOSERRORS
37 #define INCL_DOSPROCESS
38 #define INCL_NOPMAPI
39 #include <os2.h>
40 #if defined(PYCC_GCC)
41 #include <ctype.h>
42 #include <io.h>
43 #include <stdio.h>
44 #include <process.h>
45 #endif
46 #include "osdefs.h"
47 #endif
49 #include <sys/types.h>
50 #include <sys/stat.h>
52 #ifdef HAVE_SYS_WAIT_H
53 #include <sys/wait.h> /* For WNOHANG */
54 #endif
56 #include <signal.h>
58 #ifdef HAVE_FCNTL_H
59 #include <fcntl.h>
60 #endif /* HAVE_FCNTL_H */
62 #ifdef HAVE_GRP_H
63 #include <grp.h>
64 #endif
66 #ifdef HAVE_SYSEXITS_H
67 #include <sysexits.h>
68 #endif /* HAVE_SYSEXITS_H */
70 #ifdef HAVE_SYS_LOADAVG_H
71 #include <sys/loadavg.h>
72 #endif
74 /* Various compilers have only certain posix functions */
75 /* XXX Gosh I wish these were all moved into pyconfig.h */
76 #if defined(PYCC_VACPP) && defined(PYOS_OS2)
77 #include <process.h>
78 #else
79 #if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
80 #define HAVE_GETCWD 1
81 #define HAVE_OPENDIR 1
82 #define HAVE_SYSTEM 1
83 #if defined(__OS2__)
84 #define HAVE_EXECV 1
85 #define HAVE_WAIT 1
86 #endif
87 #include <process.h>
88 #else
89 #ifdef __BORLANDC__ /* Borland compiler */
90 #define HAVE_EXECV 1
91 #define HAVE_GETCWD 1
92 #define HAVE_OPENDIR 1
93 #define HAVE_PIPE 1
94 #define HAVE_POPEN 1
95 #define HAVE_SYSTEM 1
96 #define HAVE_WAIT 1
97 #else
98 #ifdef _MSC_VER /* Microsoft compiler */
99 #define HAVE_GETCWD 1
100 #define HAVE_SPAWNV 1
101 #define HAVE_EXECV 1
102 #define HAVE_PIPE 1
103 #define HAVE_POPEN 1
104 #define HAVE_SYSTEM 1
105 #define HAVE_CWAIT 1
106 #define HAVE_FSYNC 1
107 #define fsync _commit
108 #else
109 #if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
110 /* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
111 #else /* all other compilers */
112 /* Unix functions that the configure script doesn't check for */
113 #define HAVE_EXECV 1
114 #define HAVE_FORK 1
115 #if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
116 #define HAVE_FORK1 1
117 #endif
118 #define HAVE_GETCWD 1
119 #define HAVE_GETEGID 1
120 #define HAVE_GETEUID 1
121 #define HAVE_GETGID 1
122 #define HAVE_GETPPID 1
123 #define HAVE_GETUID 1
124 #define HAVE_KILL 1
125 #define HAVE_OPENDIR 1
126 #define HAVE_PIPE 1
127 #ifndef __rtems__
128 #define HAVE_POPEN 1
129 #endif
130 #define HAVE_SYSTEM 1
131 #define HAVE_WAIT 1
132 #define HAVE_TTYNAME 1
133 #endif /* PYOS_OS2 && PYCC_GCC && __VMS */
134 #endif /* _MSC_VER */
135 #endif /* __BORLANDC__ */
136 #endif /* ! __WATCOMC__ || __QNX__ */
137 #endif /* ! __IBMC__ */
139 #ifndef _MSC_VER
141 #if defined(__sgi)&&_COMPILER_VERSION>=700
142 /* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
143 (default) */
144 extern char *ctermid_r(char *);
145 #endif
147 #ifndef HAVE_UNISTD_H
148 #if defined(PYCC_VACPP)
149 extern int mkdir(char *);
150 #else
151 #if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
152 extern int mkdir(const char *);
153 #else
154 extern int mkdir(const char *, mode_t);
155 #endif
156 #endif
157 #if defined(__IBMC__) || defined(__IBMCPP__)
158 extern int chdir(char *);
159 extern int rmdir(char *);
160 #else
161 extern int chdir(const char *);
162 extern int rmdir(const char *);
163 #endif
164 #ifdef __BORLANDC__
165 extern int chmod(const char *, int);
166 #else
167 extern int chmod(const char *, mode_t);
168 #endif
169 extern int chown(const char *, uid_t, gid_t);
170 extern char *getcwd(char *, int);
171 extern char *strerror(int);
172 extern int link(const char *, const char *);
173 extern int rename(const char *, const char *);
174 extern int stat(const char *, struct stat *);
175 extern int unlink(const char *);
176 extern int pclose(FILE *);
177 #ifdef HAVE_SYMLINK
178 extern int symlink(const char *, const char *);
179 #endif /* HAVE_SYMLINK */
180 #ifdef HAVE_LSTAT
181 extern int lstat(const char *, struct stat *);
182 #endif /* HAVE_LSTAT */
183 #endif /* !HAVE_UNISTD_H */
185 #endif /* !_MSC_VER */
187 #ifdef HAVE_UTIME_H
188 #include <utime.h>
189 #endif /* HAVE_UTIME_H */
191 #ifdef HAVE_SYS_UTIME_H
192 #include <sys/utime.h>
193 #define HAVE_UTIME_H /* pretend we do for the rest of this file */
194 #endif /* HAVE_SYS_UTIME_H */
196 #ifdef HAVE_SYS_TIMES_H
197 #include <sys/times.h>
198 #endif /* HAVE_SYS_TIMES_H */
200 #ifdef HAVE_SYS_PARAM_H
201 #include <sys/param.h>
202 #endif /* HAVE_SYS_PARAM_H */
204 #ifdef HAVE_SYS_UTSNAME_H
205 #include <sys/utsname.h>
206 #endif /* HAVE_SYS_UTSNAME_H */
208 #ifdef HAVE_DIRENT_H
209 #include <dirent.h>
210 #define NAMLEN(dirent) strlen((dirent)->d_name)
211 #else
212 #if defined(__WATCOMC__) && !defined(__QNX__)
213 #include <direct.h>
214 #define NAMLEN(dirent) strlen((dirent)->d_name)
215 #else
216 #define dirent direct
217 #define NAMLEN(dirent) (dirent)->d_namlen
218 #endif
219 #ifdef HAVE_SYS_NDIR_H
220 #include <sys/ndir.h>
221 #endif
222 #ifdef HAVE_SYS_DIR_H
223 #include <sys/dir.h>
224 #endif
225 #ifdef HAVE_NDIR_H
226 #include <ndir.h>
227 #endif
228 #endif
230 #ifdef _MSC_VER
231 #include <direct.h>
232 #include <io.h>
233 #include <process.h>
234 #include "osdefs.h"
235 #define _WIN32_WINNT 0x0400 /* Needed for CryptoAPI on some systems */
236 #include <windows.h>
237 #include <shellapi.h> /* for ShellExecute() */
238 #define popen _popen
239 #define pclose _pclose
240 #endif /* _MSC_VER */
242 #if defined(PYCC_VACPP) && defined(PYOS_OS2)
243 #include <io.h>
244 #endif /* OS2 */
246 #ifndef MAXPATHLEN
247 #define MAXPATHLEN 1024
248 #endif /* MAXPATHLEN */
250 #ifdef UNION_WAIT
251 /* Emulate some macros on systems that have a union instead of macros */
253 #ifndef WIFEXITED
254 #define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
255 #endif
257 #ifndef WEXITSTATUS
258 #define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
259 #endif
261 #ifndef WTERMSIG
262 #define WTERMSIG(u_wait) ((u_wait).w_termsig)
263 #endif
265 #endif /* UNION_WAIT */
267 /* Don't use the "_r" form if we don't need it (also, won't have a
268 prototype for it, at least on Solaris -- maybe others as well?). */
269 #if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
270 #define USE_CTERMID_R
271 #endif
273 #if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
274 #define USE_TMPNAM_R
275 #endif
277 /* choose the appropriate stat and fstat functions and return structs */
278 #undef STAT
279 #if defined(MS_WIN64) || defined(MS_WINDOWS)
280 # define STAT _stati64
281 # define FSTAT _fstati64
282 # define STRUCT_STAT struct _stati64
283 #else
284 # define STAT stat
285 # define FSTAT fstat
286 # define STRUCT_STAT struct stat
287 #endif
289 #if defined(MAJOR_IN_MKDEV)
290 #include <sys/mkdev.h>
291 #else
292 #if defined(MAJOR_IN_SYSMACROS)
293 #include <sys/sysmacros.h>
294 #endif
295 #if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
296 #include <sys/mkdev.h>
297 #endif
298 #endif
300 /* Return a dictionary corresponding to the POSIX environment table */
301 #ifdef WITH_NEXT_FRAMEWORK
302 /* On Darwin/MacOSX a shared library or framework has no access to
303 ** environ directly, we must obtain it with _NSGetEnviron().
305 #include <crt_externs.h>
306 static char **environ;
307 #elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
308 extern char **environ;
309 #endif /* !_MSC_VER */
311 static PyObject *
312 convertenviron(void)
314 PyObject *d;
315 char **e;
316 d = PyDict_New();
317 if (d == NULL)
318 return NULL;
319 #ifdef WITH_NEXT_FRAMEWORK
320 if (environ == NULL)
321 environ = *_NSGetEnviron();
322 #endif
323 if (environ == NULL)
324 return d;
325 /* This part ignores errors */
326 for (e = environ; *e != NULL; e++) {
327 PyObject *k;
328 PyObject *v;
329 char *p = strchr(*e, '=');
330 if (p == NULL)
331 continue;
332 k = PyString_FromStringAndSize(*e, (int)(p-*e));
333 if (k == NULL) {
334 PyErr_Clear();
335 continue;
337 v = PyString_FromString(p+1);
338 if (v == NULL) {
339 PyErr_Clear();
340 Py_DECREF(k);
341 continue;
343 if (PyDict_GetItem(d, k) == NULL) {
344 if (PyDict_SetItem(d, k, v) != 0)
345 PyErr_Clear();
347 Py_DECREF(k);
348 Py_DECREF(v);
350 #if defined(PYOS_OS2)
352 APIRET rc;
353 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
355 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
356 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
357 PyObject *v = PyString_FromString(buffer);
358 PyDict_SetItemString(d, "BEGINLIBPATH", v);
359 Py_DECREF(v);
361 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
362 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
363 PyObject *v = PyString_FromString(buffer);
364 PyDict_SetItemString(d, "ENDLIBPATH", v);
365 Py_DECREF(v);
368 #endif
369 return d;
373 /* Set a POSIX-specific error from errno, and return NULL */
375 static PyObject *
376 posix_error(void)
378 return PyErr_SetFromErrno(PyExc_OSError);
380 static PyObject *
381 posix_error_with_filename(char* name)
383 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
386 #ifdef Py_WIN_WIDE_FILENAMES
387 static PyObject *
388 posix_error_with_unicode_filename(Py_UNICODE* name)
390 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
392 #endif /* Py_WIN_WIDE_FILENAMES */
395 static PyObject *
396 posix_error_with_allocated_filename(char* name)
398 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
399 PyMem_Free(name);
400 return rc;
403 #ifdef MS_WINDOWS
404 static PyObject *
405 win32_error(char* function, char* filename)
407 /* XXX We should pass the function name along in the future.
408 (_winreg.c also wants to pass the function name.)
409 This would however require an additional param to the
410 Windows error object, which is non-trivial.
412 errno = GetLastError();
413 if (filename)
414 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
415 else
416 return PyErr_SetFromWindowsErr(errno);
419 #ifdef Py_WIN_WIDE_FILENAMES
420 static PyObject *
421 win32_error_unicode(char* function, Py_UNICODE* filename)
423 /* XXX - see win32_error for comments on 'function' */
424 errno = GetLastError();
425 if (filename)
426 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
427 else
428 return PyErr_SetFromWindowsErr(errno);
431 static PyObject *_PyUnicode_FromFileSystemEncodedObject(register PyObject *obj)
433 /* XXX Perhaps we should make this API an alias of
434 PyObject_Unicode() instead ?! */
435 if (PyUnicode_CheckExact(obj)) {
436 Py_INCREF(obj);
437 return obj;
439 if (PyUnicode_Check(obj)) {
440 /* For a Unicode subtype that's not a Unicode object,
441 return a true Unicode object with the same data. */
442 return PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(obj),
443 PyUnicode_GET_SIZE(obj));
445 return PyUnicode_FromEncodedObject(obj,
446 Py_FileSystemDefaultEncoding,
447 "strict");
450 #endif /* Py_WIN_WIDE_FILENAMES */
452 #endif
454 #if defined(PYOS_OS2)
455 /**********************************************************************
456 * Helper Function to Trim and Format OS/2 Messages
457 **********************************************************************/
458 static void
459 os2_formatmsg(char *msgbuf, int msglen, char *reason)
461 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
463 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
464 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
466 while (lastc > msgbuf && isspace(*lastc))
467 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
470 /* Add Optional Reason Text */
471 if (reason) {
472 strcat(msgbuf, " : ");
473 strcat(msgbuf, reason);
477 /**********************************************************************
478 * Decode an OS/2 Operating System Error Code
480 * A convenience function to lookup an OS/2 error code and return a
481 * text message we can use to raise a Python exception.
483 * Notes:
484 * The messages for errors returned from the OS/2 kernel reside in
485 * the file OSO001.MSG in the \OS2 directory hierarchy.
487 **********************************************************************/
488 static char *
489 os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
491 APIRET rc;
492 ULONG msglen;
494 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
495 Py_BEGIN_ALLOW_THREADS
496 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
497 errorcode, "oso001.msg", &msglen);
498 Py_END_ALLOW_THREADS
500 if (rc == NO_ERROR)
501 os2_formatmsg(msgbuf, msglen, reason);
502 else
503 PyOS_snprintf(msgbuf, msgbuflen,
504 "unknown OS error #%d", errorcode);
506 return msgbuf;
509 /* Set an OS/2-specific error and return NULL. OS/2 kernel
510 errors are not in a global variable e.g. 'errno' nor are
511 they congruent with posix error numbers. */
513 static PyObject * os2_error(int code)
515 char text[1024];
516 PyObject *v;
518 os2_strerror(text, sizeof(text), code, "");
520 v = Py_BuildValue("(is)", code, text);
521 if (v != NULL) {
522 PyErr_SetObject(PyExc_OSError, v);
523 Py_DECREF(v);
525 return NULL; /* Signal to Python that an Exception is Pending */
528 #endif /* OS2 */
530 /* POSIX generic methods */
532 static PyObject *
533 posix_fildes(PyObject *fdobj, int (*func)(int))
535 int fd;
536 int res;
537 fd = PyObject_AsFileDescriptor(fdobj);
538 if (fd < 0)
539 return NULL;
540 Py_BEGIN_ALLOW_THREADS
541 res = (*func)(fd);
542 Py_END_ALLOW_THREADS
543 if (res < 0)
544 return posix_error();
545 Py_INCREF(Py_None);
546 return Py_None;
549 #ifdef Py_WIN_WIDE_FILENAMES
550 static int
551 unicode_file_names(void)
553 static int canusewide = -1;
554 if (canusewide == -1) {
555 /* As per doc for ::GetVersion(), this is the correct test for
556 the Windows NT family. */
557 canusewide = (GetVersion() < 0x80000000) ? 1 : 0;
559 return canusewide;
561 #endif
563 static PyObject *
564 posix_1str(PyObject *args, char *format, int (*func)(const char*),
565 char *wformat, int (*wfunc)(const Py_UNICODE*))
567 char *path1 = NULL;
568 int res;
569 #ifdef Py_WIN_WIDE_FILENAMES
570 if (unicode_file_names()) {
571 PyUnicodeObject *po;
572 if (PyArg_ParseTuple(args, wformat, &po)) {
573 Py_BEGIN_ALLOW_THREADS
574 /* PyUnicode_AS_UNICODE OK without thread
575 lock as it is a simple dereference. */
576 res = (*wfunc)(PyUnicode_AS_UNICODE(po));
577 Py_END_ALLOW_THREADS
578 if (res < 0)
579 return posix_error_with_unicode_filename(PyUnicode_AS_UNICODE(po));
580 Py_INCREF(Py_None);
581 return Py_None;
583 /* Drop the argument parsing error as narrow
584 strings are also valid. */
585 PyErr_Clear();
587 #else
588 /* Platforms that don't support Unicode filenames
589 shouldn't be passing these extra params */
590 assert(wformat==NULL && wfunc == NULL);
591 #endif
593 if (!PyArg_ParseTuple(args, format,
594 Py_FileSystemDefaultEncoding, &path1))
595 return NULL;
596 Py_BEGIN_ALLOW_THREADS
597 res = (*func)(path1);
598 Py_END_ALLOW_THREADS
599 if (res < 0)
600 return posix_error_with_allocated_filename(path1);
601 PyMem_Free(path1);
602 Py_INCREF(Py_None);
603 return Py_None;
606 static PyObject *
607 posix_2str(PyObject *args,
608 char *format,
609 int (*func)(const char *, const char *),
610 char *wformat,
611 int (*wfunc)(const Py_UNICODE *, const Py_UNICODE *))
613 char *path1 = NULL, *path2 = NULL;
614 int res;
615 #ifdef Py_WIN_WIDE_FILENAMES
616 if (unicode_file_names()) {
617 PyObject *po1;
618 PyObject *po2;
619 if (PyArg_ParseTuple(args, wformat, &po1, &po2)) {
620 if (PyUnicode_Check(po1) || PyUnicode_Check(po2)) {
621 PyObject *wpath1;
622 PyObject *wpath2;
623 wpath1 = _PyUnicode_FromFileSystemEncodedObject(po1);
624 wpath2 = _PyUnicode_FromFileSystemEncodedObject(po2);
625 if (!wpath1 || !wpath2) {
626 Py_XDECREF(wpath1);
627 Py_XDECREF(wpath2);
628 return NULL;
630 Py_BEGIN_ALLOW_THREADS
631 /* PyUnicode_AS_UNICODE OK without thread
632 lock as it is a simple dereference. */
633 res = (*wfunc)(PyUnicode_AS_UNICODE(wpath1),
634 PyUnicode_AS_UNICODE(wpath2));
635 Py_END_ALLOW_THREADS
636 Py_XDECREF(wpath1);
637 Py_XDECREF(wpath2);
638 if (res != 0)
639 return posix_error();
640 Py_INCREF(Py_None);
641 return Py_None;
643 /* Else flow through as neither is Unicode. */
645 /* Drop the argument parsing error as narrow
646 strings are also valid. */
647 PyErr_Clear();
649 #else
650 /* Platforms that don't support Unicode filenames
651 shouldn't be passing these extra params */
652 assert(wformat==NULL && wfunc == NULL);
653 #endif
655 if (!PyArg_ParseTuple(args, format,
656 Py_FileSystemDefaultEncoding, &path1,
657 Py_FileSystemDefaultEncoding, &path2))
658 return NULL;
659 Py_BEGIN_ALLOW_THREADS
660 res = (*func)(path1, path2);
661 Py_END_ALLOW_THREADS
662 PyMem_Free(path1);
663 PyMem_Free(path2);
664 if (res != 0)
665 /* XXX how to report both path1 and path2??? */
666 return posix_error();
667 Py_INCREF(Py_None);
668 return Py_None;
671 PyDoc_STRVAR(stat_result__doc__,
672 "stat_result: Result from stat or lstat.\n\n\
673 This object may be accessed either as a tuple of\n\
674 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
675 or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
677 Posix/windows: If your platform supports st_blksize, st_blocks, or st_rdev,\n\
678 they are available as attributes only.\n\
680 See os.stat for more information.");
682 static PyStructSequence_Field stat_result_fields[] = {
683 {"st_mode", "protection bits"},
684 {"st_ino", "inode"},
685 {"st_dev", "device"},
686 {"st_nlink", "number of hard links"},
687 {"st_uid", "user ID of owner"},
688 {"st_gid", "group ID of owner"},
689 {"st_size", "total size, in bytes"},
690 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
691 {NULL, "integer time of last access"},
692 {NULL, "integer time of last modification"},
693 {NULL, "integer time of last change"},
694 {"st_atime", "time of last access"},
695 {"st_mtime", "time of last modification"},
696 {"st_ctime", "time of last change"},
697 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
698 {"st_blksize", "blocksize for filesystem I/O"},
699 #endif
700 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
701 {"st_blocks", "number of blocks allocated"},
702 #endif
703 #ifdef HAVE_STRUCT_STAT_ST_RDEV
704 {"st_rdev", "device type (if inode device)"},
705 #endif
709 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
710 #define ST_BLKSIZE_IDX 13
711 #else
712 #define ST_BLKSIZE_IDX 12
713 #endif
715 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
716 #define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
717 #else
718 #define ST_BLOCKS_IDX ST_BLKSIZE_IDX
719 #endif
721 #ifdef HAVE_STRUCT_STAT_ST_RDEV
722 #define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
723 #else
724 #define ST_RDEV_IDX ST_BLOCKS_IDX
725 #endif
727 static PyStructSequence_Desc stat_result_desc = {
728 "stat_result", /* name */
729 stat_result__doc__, /* doc */
730 stat_result_fields,
734 PyDoc_STRVAR(statvfs_result__doc__,
735 "statvfs_result: Result from statvfs or fstatvfs.\n\n\
736 This object may be accessed either as a tuple of\n\
737 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
738 or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
740 See os.statvfs for more information.");
742 static PyStructSequence_Field statvfs_result_fields[] = {
743 {"f_bsize", },
744 {"f_frsize", },
745 {"f_blocks", },
746 {"f_bfree", },
747 {"f_bavail", },
748 {"f_files", },
749 {"f_ffree", },
750 {"f_favail", },
751 {"f_flag", },
752 {"f_namemax",},
756 static PyStructSequence_Desc statvfs_result_desc = {
757 "statvfs_result", /* name */
758 statvfs_result__doc__, /* doc */
759 statvfs_result_fields,
763 static PyTypeObject StatResultType;
764 static PyTypeObject StatVFSResultType;
765 static newfunc structseq_new;
767 static PyObject *
768 statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
770 PyStructSequence *result;
771 int i;
773 result = (PyStructSequence*)structseq_new(type, args, kwds);
774 if (!result)
775 return NULL;
776 /* If we have been initialized from a tuple,
777 st_?time might be set to None. Initialize it
778 from the int slots. */
779 for (i = 7; i <= 9; i++) {
780 if (result->ob_item[i+3] == Py_None) {
781 Py_DECREF(Py_None);
782 Py_INCREF(result->ob_item[i]);
783 result->ob_item[i+3] = result->ob_item[i];
786 return (PyObject*)result;
791 /* If true, st_?time is float. */
792 static int _stat_float_times = 0;
794 PyDoc_STRVAR(stat_float_times__doc__,
795 "stat_float_times([newval]) -> oldval\n\n\
796 Determine whether os.[lf]stat represents time stamps as float objects.\n\
797 If newval is True, future calls to stat() return floats, if it is False,\n\
798 future calls return ints. \n\
799 If newval is omitted, return the current setting.\n");
801 static PyObject*
802 stat_float_times(PyObject* self, PyObject *args)
804 int newval = -1;
805 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
806 return NULL;
807 if (newval == -1)
808 /* Return old value */
809 return PyBool_FromLong(_stat_float_times);
810 _stat_float_times = newval;
811 Py_INCREF(Py_None);
812 return Py_None;
815 static void
816 fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
818 PyObject *fval,*ival;
819 #if SIZEOF_TIME_T > SIZEOF_LONG
820 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
821 #else
822 ival = PyInt_FromLong((long)sec);
823 #endif
824 if (_stat_float_times) {
825 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
826 } else {
827 fval = ival;
828 Py_INCREF(fval);
830 PyStructSequence_SET_ITEM(v, index, ival);
831 PyStructSequence_SET_ITEM(v, index+3, fval);
834 /* pack a system stat C structure into the Python stat tuple
835 (used by posix_stat() and posix_fstat()) */
836 static PyObject*
837 _pystat_fromstructstat(STRUCT_STAT st)
839 unsigned long ansec, mnsec, cnsec;
840 PyObject *v = PyStructSequence_New(&StatResultType);
841 if (v == NULL)
842 return NULL;
844 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st.st_mode));
845 #ifdef HAVE_LARGEFILE_SUPPORT
846 PyStructSequence_SET_ITEM(v, 1,
847 PyLong_FromLongLong((PY_LONG_LONG)st.st_ino));
848 #else
849 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st.st_ino));
850 #endif
851 #if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
852 PyStructSequence_SET_ITEM(v, 2,
853 PyLong_FromLongLong((PY_LONG_LONG)st.st_dev));
854 #else
855 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st.st_dev));
856 #endif
857 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st.st_nlink));
858 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st.st_uid));
859 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st.st_gid));
860 #ifdef HAVE_LARGEFILE_SUPPORT
861 PyStructSequence_SET_ITEM(v, 6,
862 PyLong_FromLongLong((PY_LONG_LONG)st.st_size));
863 #else
864 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st.st_size));
865 #endif
867 #ifdef HAVE_STAT_TV_NSEC
868 ansec = st.st_atim.tv_nsec;
869 mnsec = st.st_mtim.tv_nsec;
870 cnsec = st.st_ctim.tv_nsec;
871 #else
872 ansec = mnsec = cnsec = 0;
873 #endif
874 fill_time(v, 7, st.st_atime, ansec);
875 fill_time(v, 8, st.st_mtime, mnsec);
876 fill_time(v, 9, st.st_ctime, cnsec);
878 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
879 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
880 PyInt_FromLong((long)st.st_blksize));
881 #endif
882 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
883 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
884 PyInt_FromLong((long)st.st_blocks));
885 #endif
886 #ifdef HAVE_STRUCT_STAT_ST_RDEV
887 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
888 PyInt_FromLong((long)st.st_rdev));
889 #endif
891 if (PyErr_Occurred()) {
892 Py_DECREF(v);
893 return NULL;
896 return v;
899 #ifdef MS_WINDOWS
901 /* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
902 where / can be used in place of \ and the trailing slash is optional.
903 Both SERVER and SHARE must have at least one character.
906 #define ISSLASHA(c) ((c) == '\\' || (c) == '/')
907 #define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
908 #define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
910 static BOOL
911 IsUNCRootA(char *path, int pathlen)
913 #define ISSLASH ISSLASHA
915 int i, share;
917 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
918 /* minimum UNCRoot is \\x\y */
919 return FALSE;
920 for (i = 2; i < pathlen ; i++)
921 if (ISSLASH(path[i])) break;
922 if (i == 2 || i == pathlen)
923 /* do not allow \\\SHARE or \\SERVER */
924 return FALSE;
925 share = i+1;
926 for (i = share; i < pathlen; i++)
927 if (ISSLASH(path[i])) break;
928 return (i != share && (i == pathlen || i == pathlen-1));
930 #undef ISSLASH
933 #ifdef Py_WIN_WIDE_FILENAMES
934 static BOOL
935 IsUNCRootW(Py_UNICODE *path, int pathlen)
937 #define ISSLASH ISSLASHW
939 int i, share;
941 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
942 /* minimum UNCRoot is \\x\y */
943 return FALSE;
944 for (i = 2; i < pathlen ; i++)
945 if (ISSLASH(path[i])) break;
946 if (i == 2 || i == pathlen)
947 /* do not allow \\\SHARE or \\SERVER */
948 return FALSE;
949 share = i+1;
950 for (i = share; i < pathlen; i++)
951 if (ISSLASH(path[i])) break;
952 return (i != share && (i == pathlen || i == pathlen-1));
954 #undef ISSLASH
956 #endif /* Py_WIN_WIDE_FILENAMES */
957 #endif /* MS_WINDOWS */
959 static PyObject *
960 posix_do_stat(PyObject *self, PyObject *args,
961 char *format,
962 #ifdef __VMS
963 int (*statfunc)(const char *, STRUCT_STAT *, ...),
964 #else
965 int (*statfunc)(const char *, STRUCT_STAT *),
966 #endif
967 char *wformat,
968 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
970 STRUCT_STAT st;
971 char *path = NULL; /* pass this to stat; do not free() it */
972 char *pathfree = NULL; /* this memory must be free'd */
973 int res;
975 #ifdef MS_WINDOWS
976 int pathlen;
977 char pathcopy[MAX_PATH];
978 #endif /* MS_WINDOWS */
981 #ifdef Py_WIN_WIDE_FILENAMES
982 /* If on wide-character-capable OS see if argument
983 is Unicode and if so use wide API. */
984 if (unicode_file_names()) {
985 PyUnicodeObject *po;
986 if (PyArg_ParseTuple(args, wformat, &po)) {
987 Py_UNICODE wpath[MAX_PATH+1];
988 pathlen = wcslen(PyUnicode_AS_UNICODE(po));
989 /* the library call can blow up if the file name is too long! */
990 if (pathlen > MAX_PATH) {
991 errno = ENAMETOOLONG;
992 return posix_error();
994 wcscpy(wpath, PyUnicode_AS_UNICODE(po));
995 /* Remove trailing slash or backslash, unless it's the current
996 drive root (/ or \) or a specific drive's root (like c:\ or c:/).
998 if (pathlen > 0) {
999 if (ISSLASHW(wpath[pathlen-1])) {
1000 /* It does end with a slash -- exempt the root drive cases. */
1001 if (pathlen == 1 || (pathlen == 3 && wpath[1] == L':') ||
1002 IsUNCRootW(wpath, pathlen))
1003 /* leave it alone */;
1004 else {
1005 /* nuke the trailing backslash */
1006 wpath[pathlen-1] = L'\0';
1009 else if (ISSLASHW(wpath[1]) && pathlen < ARRAYSIZE(wpath)-1 &&
1010 IsUNCRootW(wpath, pathlen)) {
1011 /* UNC root w/o trailing slash: add one when there's room */
1012 wpath[pathlen++] = L'\\';
1013 wpath[pathlen] = L'\0';
1016 Py_BEGIN_ALLOW_THREADS
1017 /* PyUnicode_AS_UNICODE result OK without
1018 thread lock as it is a simple dereference. */
1019 res = wstatfunc(wpath, &st);
1020 Py_END_ALLOW_THREADS
1021 if (res != 0)
1022 return posix_error_with_unicode_filename(wpath);
1023 return _pystat_fromstructstat(st);
1025 /* Drop the argument parsing error as narrow strings
1026 are also valid. */
1027 PyErr_Clear();
1029 #endif
1031 if (!PyArg_ParseTuple(args, format,
1032 Py_FileSystemDefaultEncoding, &path))
1033 return NULL;
1034 pathfree = path;
1036 #ifdef MS_WINDOWS
1037 pathlen = strlen(path);
1038 /* the library call can blow up if the file name is too long! */
1039 if (pathlen > MAX_PATH) {
1040 PyMem_Free(pathfree);
1041 errno = ENAMETOOLONG;
1042 return posix_error();
1045 /* Remove trailing slash or backslash, unless it's the current
1046 drive root (/ or \) or a specific drive's root (like c:\ or c:/).
1048 if (pathlen > 0) {
1049 if (ISSLASHA(path[pathlen-1])) {
1050 /* It does end with a slash -- exempt the root drive cases. */
1051 if (pathlen == 1 || (pathlen == 3 && path[1] == ':') ||
1052 IsUNCRootA(path, pathlen))
1053 /* leave it alone */;
1054 else {
1055 /* nuke the trailing backslash */
1056 strncpy(pathcopy, path, pathlen);
1057 pathcopy[pathlen-1] = '\0';
1058 path = pathcopy;
1061 else if (ISSLASHA(path[1]) && pathlen < ARRAYSIZE(pathcopy)-1 &&
1062 IsUNCRootA(path, pathlen)) {
1063 /* UNC root w/o trailing slash: add one when there's room */
1064 strncpy(pathcopy, path, pathlen);
1065 pathcopy[pathlen++] = '\\';
1066 pathcopy[pathlen] = '\0';
1067 path = pathcopy;
1070 #endif /* MS_WINDOWS */
1072 Py_BEGIN_ALLOW_THREADS
1073 res = (*statfunc)(path, &st);
1074 Py_END_ALLOW_THREADS
1075 if (res != 0)
1076 return posix_error_with_allocated_filename(pathfree);
1078 PyMem_Free(pathfree);
1079 return _pystat_fromstructstat(st);
1083 /* POSIX methods */
1085 PyDoc_STRVAR(posix_access__doc__,
1086 "access(path, mode) -> 1 if granted, 0 otherwise\n\n\
1087 Use the real uid/gid to test for access to a path. Note that most\n\
1088 operations will use the effective uid/gid, therefore this routine can\n\
1089 be used in a suid/sgid environment to test if the invoking user has the\n\
1090 specified access to the path. The mode argument can be F_OK to test\n\
1091 existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
1093 static PyObject *
1094 posix_access(PyObject *self, PyObject *args)
1096 char *path;
1097 int mode;
1098 int res;
1100 #ifdef Py_WIN_WIDE_FILENAMES
1101 if (unicode_file_names()) {
1102 PyUnicodeObject *po;
1103 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1104 Py_BEGIN_ALLOW_THREADS
1105 /* PyUnicode_AS_UNICODE OK without thread lock as
1106 it is a simple dereference. */
1107 res = _waccess(PyUnicode_AS_UNICODE(po), mode);
1108 Py_END_ALLOW_THREADS
1109 return(PyBool_FromLong(res == 0));
1111 /* Drop the argument parsing error as narrow strings
1112 are also valid. */
1113 PyErr_Clear();
1115 #endif
1116 if (!PyArg_ParseTuple(args, "si:access", &path, &mode))
1117 return NULL;
1118 Py_BEGIN_ALLOW_THREADS
1119 res = access(path, mode);
1120 Py_END_ALLOW_THREADS
1121 return(PyBool_FromLong(res == 0));
1124 #ifndef F_OK
1125 #define F_OK 0
1126 #endif
1127 #ifndef R_OK
1128 #define R_OK 4
1129 #endif
1130 #ifndef W_OK
1131 #define W_OK 2
1132 #endif
1133 #ifndef X_OK
1134 #define X_OK 1
1135 #endif
1137 #ifdef HAVE_TTYNAME
1138 PyDoc_STRVAR(posix_ttyname__doc__,
1139 "ttyname(fd) -> string\n\n\
1140 Return the name of the terminal device connected to 'fd'.");
1142 static PyObject *
1143 posix_ttyname(PyObject *self, PyObject *args)
1145 int id;
1146 char *ret;
1148 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
1149 return NULL;
1151 #if defined(__VMS)
1152 /* file descriptor 0 only, the default input device (stdin) */
1153 if (id == 0) {
1154 ret = ttyname();
1156 else {
1157 ret = NULL;
1159 #else
1160 ret = ttyname(id);
1161 #endif
1162 if (ret == NULL)
1163 return(posix_error());
1164 return(PyString_FromString(ret));
1166 #endif
1168 #ifdef HAVE_CTERMID
1169 PyDoc_STRVAR(posix_ctermid__doc__,
1170 "ctermid() -> string\n\n\
1171 Return the name of the controlling terminal for this process.");
1173 static PyObject *
1174 posix_ctermid(PyObject *self, PyObject *noargs)
1176 char *ret;
1177 char buffer[L_ctermid];
1179 #ifdef USE_CTERMID_R
1180 ret = ctermid_r(buffer);
1181 #else
1182 ret = ctermid(buffer);
1183 #endif
1184 if (ret == NULL)
1185 return(posix_error());
1186 return(PyString_FromString(buffer));
1188 #endif
1190 PyDoc_STRVAR(posix_chdir__doc__,
1191 "chdir(path)\n\n\
1192 Change the current working directory to the specified path.");
1194 static PyObject *
1195 posix_chdir(PyObject *self, PyObject *args)
1197 #ifdef MS_WINDOWS
1198 return posix_1str(args, "et:chdir", chdir, "U:chdir", _wchdir);
1199 #elif defined(PYOS_OS2) && defined(PYCC_GCC)
1200 return posix_1str(args, "et:chdir", _chdir2, NULL, NULL);
1201 #elif defined(__VMS)
1202 return posix_1str(args, "et:chdir", (int (*)(const char *))chdir,
1203 NULL, NULL);
1204 #else
1205 return posix_1str(args, "et:chdir", chdir, NULL, NULL);
1206 #endif
1209 #ifdef HAVE_FCHDIR
1210 PyDoc_STRVAR(posix_fchdir__doc__,
1211 "fchdir(fildes)\n\n\
1212 Change to the directory of the given file descriptor. fildes must be\n\
1213 opened on a directory, not a file.");
1215 static PyObject *
1216 posix_fchdir(PyObject *self, PyObject *fdobj)
1218 return posix_fildes(fdobj, fchdir);
1220 #endif /* HAVE_FCHDIR */
1223 PyDoc_STRVAR(posix_chmod__doc__,
1224 "chmod(path, mode)\n\n\
1225 Change the access permissions of a file.");
1227 static PyObject *
1228 posix_chmod(PyObject *self, PyObject *args)
1230 char *path = NULL;
1231 int i;
1232 int res;
1233 #ifdef Py_WIN_WIDE_FILENAMES
1234 if (unicode_file_names()) {
1235 PyUnicodeObject *po;
1236 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1237 Py_BEGIN_ALLOW_THREADS
1238 res = _wchmod(PyUnicode_AS_UNICODE(po), i);
1239 Py_END_ALLOW_THREADS
1240 if (res < 0)
1241 return posix_error_with_unicode_filename(
1242 PyUnicode_AS_UNICODE(po));
1243 Py_INCREF(Py_None);
1244 return Py_None;
1246 /* Drop the argument parsing error as narrow strings
1247 are also valid. */
1248 PyErr_Clear();
1250 #endif /* Py_WIN_WIDE_FILENAMES */
1251 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
1252 &path, &i))
1253 return NULL;
1254 Py_BEGIN_ALLOW_THREADS
1255 res = chmod(path, i);
1256 Py_END_ALLOW_THREADS
1257 if (res < 0)
1258 return posix_error_with_allocated_filename(path);
1259 PyMem_Free(path);
1260 Py_INCREF(Py_None);
1261 return Py_None;
1265 #ifdef HAVE_CHROOT
1266 PyDoc_STRVAR(posix_chroot__doc__,
1267 "chroot(path)\n\n\
1268 Change root directory to path.");
1270 static PyObject *
1271 posix_chroot(PyObject *self, PyObject *args)
1273 return posix_1str(args, "et:chroot", chroot, NULL, NULL);
1275 #endif
1277 #ifdef HAVE_FSYNC
1278 PyDoc_STRVAR(posix_fsync__doc__,
1279 "fsync(fildes)\n\n\
1280 force write of file with filedescriptor to disk.");
1282 static PyObject *
1283 posix_fsync(PyObject *self, PyObject *fdobj)
1285 return posix_fildes(fdobj, fsync);
1287 #endif /* HAVE_FSYNC */
1289 #ifdef HAVE_FDATASYNC
1291 #ifdef __hpux
1292 extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1293 #endif
1295 PyDoc_STRVAR(posix_fdatasync__doc__,
1296 "fdatasync(fildes)\n\n\
1297 force write of file with filedescriptor to disk.\n\
1298 does not force update of metadata.");
1300 static PyObject *
1301 posix_fdatasync(PyObject *self, PyObject *fdobj)
1303 return posix_fildes(fdobj, fdatasync);
1305 #endif /* HAVE_FDATASYNC */
1308 #ifdef HAVE_CHOWN
1309 PyDoc_STRVAR(posix_chown__doc__,
1310 "chown(path, uid, gid)\n\n\
1311 Change the owner and group id of path to the numeric uid and gid.");
1313 static PyObject *
1314 posix_chown(PyObject *self, PyObject *args)
1316 char *path = NULL;
1317 int uid, gid;
1318 int res;
1319 if (!PyArg_ParseTuple(args, "etii:chown",
1320 Py_FileSystemDefaultEncoding, &path,
1321 &uid, &gid))
1322 return NULL;
1323 Py_BEGIN_ALLOW_THREADS
1324 res = chown(path, (uid_t) uid, (gid_t) gid);
1325 Py_END_ALLOW_THREADS
1326 if (res < 0)
1327 return posix_error_with_allocated_filename(path);
1328 PyMem_Free(path);
1329 Py_INCREF(Py_None);
1330 return Py_None;
1332 #endif /* HAVE_CHOWN */
1334 #ifdef HAVE_LCHOWN
1335 PyDoc_STRVAR(posix_lchown__doc__,
1336 "lchown(path, uid, gid)\n\n\
1337 Change the owner and group id of path to the numeric uid and gid.\n\
1338 This function will not follow symbolic links.");
1340 static PyObject *
1341 posix_lchown(PyObject *self, PyObject *args)
1343 char *path = NULL;
1344 int uid, gid;
1345 int res;
1346 if (!PyArg_ParseTuple(args, "etii:lchown",
1347 Py_FileSystemDefaultEncoding, &path,
1348 &uid, &gid))
1349 return NULL;
1350 Py_BEGIN_ALLOW_THREADS
1351 res = lchown(path, (uid_t) uid, (gid_t) gid);
1352 Py_END_ALLOW_THREADS
1353 if (res < 0)
1354 return posix_error_with_allocated_filename(path);
1355 PyMem_Free(path);
1356 Py_INCREF(Py_None);
1357 return Py_None;
1359 #endif /* HAVE_LCHOWN */
1362 #ifdef HAVE_GETCWD
1363 PyDoc_STRVAR(posix_getcwd__doc__,
1364 "getcwd() -> path\n\n\
1365 Return a string representing the current working directory.");
1367 static PyObject *
1368 posix_getcwd(PyObject *self, PyObject *noargs)
1370 char buf[1026];
1371 char *res;
1373 Py_BEGIN_ALLOW_THREADS
1374 #if defined(PYOS_OS2) && defined(PYCC_GCC)
1375 res = _getcwd2(buf, sizeof buf);
1376 #else
1377 res = getcwd(buf, sizeof buf);
1378 #endif
1379 Py_END_ALLOW_THREADS
1380 if (res == NULL)
1381 return posix_error();
1382 return PyString_FromString(buf);
1385 #ifdef Py_USING_UNICODE
1386 PyDoc_STRVAR(posix_getcwdu__doc__,
1387 "getcwdu() -> path\n\n\
1388 Return a unicode string representing the current working directory.");
1390 static PyObject *
1391 posix_getcwdu(PyObject *self, PyObject *noargs)
1393 char buf[1026];
1394 char *res;
1396 #ifdef Py_WIN_WIDE_FILENAMES
1397 if (unicode_file_names()) {
1398 wchar_t *wres;
1399 wchar_t wbuf[1026];
1400 Py_BEGIN_ALLOW_THREADS
1401 wres = _wgetcwd(wbuf, sizeof wbuf/ sizeof wbuf[0]);
1402 Py_END_ALLOW_THREADS
1403 if (wres == NULL)
1404 return posix_error();
1405 return PyUnicode_FromWideChar(wbuf, wcslen(wbuf));
1407 #endif
1409 Py_BEGIN_ALLOW_THREADS
1410 #if defined(PYOS_OS2) && defined(PYCC_GCC)
1411 res = _getcwd2(buf, sizeof buf);
1412 #else
1413 res = getcwd(buf, sizeof buf);
1414 #endif
1415 Py_END_ALLOW_THREADS
1416 if (res == NULL)
1417 return posix_error();
1418 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
1420 #endif
1421 #endif
1424 #ifdef HAVE_LINK
1425 PyDoc_STRVAR(posix_link__doc__,
1426 "link(src, dst)\n\n\
1427 Create a hard link to a file.");
1429 static PyObject *
1430 posix_link(PyObject *self, PyObject *args)
1432 return posix_2str(args, "etet:link", link, NULL, NULL);
1434 #endif /* HAVE_LINK */
1437 PyDoc_STRVAR(posix_listdir__doc__,
1438 "listdir(path) -> list_of_strings\n\n\
1439 Return a list containing the names of the entries in the directory.\n\
1441 path: path of directory to list\n\
1443 The list is in arbitrary order. It does not include the special\n\
1444 entries '.' and '..' even if they are present in the directory.");
1446 static PyObject *
1447 posix_listdir(PyObject *self, PyObject *args)
1449 /* XXX Should redo this putting the (now four) versions of opendir
1450 in separate files instead of having them all here... */
1451 #if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
1453 PyObject *d, *v;
1454 HANDLE hFindFile;
1455 WIN32_FIND_DATA FileData;
1456 /* MAX_PATH characters could mean a bigger encoded string */
1457 char namebuf[MAX_PATH*2+5];
1458 char *bufptr = namebuf;
1459 int len = sizeof(namebuf)/sizeof(namebuf[0]);
1461 #ifdef Py_WIN_WIDE_FILENAMES
1462 /* If on wide-character-capable OS see if argument
1463 is Unicode and if so use wide API. */
1464 if (unicode_file_names()) {
1465 PyUnicodeObject *po;
1466 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
1467 WIN32_FIND_DATAW wFileData;
1468 Py_UNICODE wnamebuf[MAX_PATH*2+5];
1469 Py_UNICODE wch;
1470 wcsncpy(wnamebuf, PyUnicode_AS_UNICODE(po), MAX_PATH);
1471 wnamebuf[MAX_PATH] = L'\0';
1472 len = wcslen(wnamebuf);
1473 wch = (len > 0) ? wnamebuf[len-1] : L'\0';
1474 if (wch != L'/' && wch != L'\\' && wch != L':')
1475 wnamebuf[len++] = L'/';
1476 wcscpy(wnamebuf + len, L"*.*");
1477 if ((d = PyList_New(0)) == NULL)
1478 return NULL;
1479 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
1480 if (hFindFile == INVALID_HANDLE_VALUE) {
1481 errno = GetLastError();
1482 if (errno == ERROR_FILE_NOT_FOUND) {
1483 return d;
1485 Py_DECREF(d);
1486 return win32_error_unicode("FindFirstFileW", wnamebuf);
1488 do {
1489 if (wFileData.cFileName[0] == L'.' &&
1490 (wFileData.cFileName[1] == L'\0' ||
1491 wFileData.cFileName[1] == L'.' &&
1492 wFileData.cFileName[2] == L'\0'))
1493 continue;
1494 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
1495 if (v == NULL) {
1496 Py_DECREF(d);
1497 d = NULL;
1498 break;
1500 if (PyList_Append(d, v) != 0) {
1501 Py_DECREF(v);
1502 Py_DECREF(d);
1503 d = NULL;
1504 break;
1506 Py_DECREF(v);
1507 } while (FindNextFileW(hFindFile, &wFileData) == TRUE);
1509 if (FindClose(hFindFile) == FALSE) {
1510 Py_DECREF(d);
1511 return win32_error_unicode("FindClose", wnamebuf);
1513 return d;
1515 /* Drop the argument parsing error as narrow strings
1516 are also valid. */
1517 PyErr_Clear();
1519 #endif
1521 if (!PyArg_ParseTuple(args, "et#:listdir",
1522 Py_FileSystemDefaultEncoding, &bufptr, &len))
1523 return NULL;
1524 if (len > 0) {
1525 char ch = namebuf[len-1];
1526 if (ch != SEP && ch != ALTSEP && ch != ':')
1527 namebuf[len++] = '/';
1529 strcpy(namebuf + len, "*.*");
1531 if ((d = PyList_New(0)) == NULL)
1532 return NULL;
1534 hFindFile = FindFirstFile(namebuf, &FileData);
1535 if (hFindFile == INVALID_HANDLE_VALUE) {
1536 errno = GetLastError();
1537 if (errno == ERROR_FILE_NOT_FOUND)
1538 return d;
1539 Py_DECREF(d);
1540 return win32_error("FindFirstFile", namebuf);
1542 do {
1543 if (FileData.cFileName[0] == '.' &&
1544 (FileData.cFileName[1] == '\0' ||
1545 FileData.cFileName[1] == '.' &&
1546 FileData.cFileName[2] == '\0'))
1547 continue;
1548 v = PyString_FromString(FileData.cFileName);
1549 if (v == NULL) {
1550 Py_DECREF(d);
1551 d = NULL;
1552 break;
1554 if (PyList_Append(d, v) != 0) {
1555 Py_DECREF(v);
1556 Py_DECREF(d);
1557 d = NULL;
1558 break;
1560 Py_DECREF(v);
1561 } while (FindNextFile(hFindFile, &FileData) == TRUE);
1563 if (FindClose(hFindFile) == FALSE) {
1564 Py_DECREF(d);
1565 return win32_error("FindClose", namebuf);
1568 return d;
1570 #elif defined(PYOS_OS2)
1572 #ifndef MAX_PATH
1573 #define MAX_PATH CCHMAXPATH
1574 #endif
1575 char *name, *pt;
1576 int len;
1577 PyObject *d, *v;
1578 char namebuf[MAX_PATH+5];
1579 HDIR hdir = 1;
1580 ULONG srchcnt = 1;
1581 FILEFINDBUF3 ep;
1582 APIRET rc;
1584 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
1585 return NULL;
1586 if (len >= MAX_PATH) {
1587 PyErr_SetString(PyExc_ValueError, "path too long");
1588 return NULL;
1590 strcpy(namebuf, name);
1591 for (pt = namebuf; *pt; pt++)
1592 if (*pt == ALTSEP)
1593 *pt = SEP;
1594 if (namebuf[len-1] != SEP)
1595 namebuf[len++] = SEP;
1596 strcpy(namebuf + len, "*.*");
1598 if ((d = PyList_New(0)) == NULL)
1599 return NULL;
1601 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
1602 &hdir, /* Handle to Use While Search Directory */
1603 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
1604 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
1605 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
1606 FIL_STANDARD); /* Format of Entry (EAs or Not) */
1608 if (rc != NO_ERROR) {
1609 errno = ENOENT;
1610 return posix_error_with_filename(name);
1613 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
1614 do {
1615 if (ep.achName[0] == '.'
1616 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
1617 continue; /* Skip Over "." and ".." Names */
1619 strcpy(namebuf, ep.achName);
1621 /* Leave Case of Name Alone -- In Native Form */
1622 /* (Removed Forced Lowercasing Code) */
1624 v = PyString_FromString(namebuf);
1625 if (v == NULL) {
1626 Py_DECREF(d);
1627 d = NULL;
1628 break;
1630 if (PyList_Append(d, v) != 0) {
1631 Py_DECREF(v);
1632 Py_DECREF(d);
1633 d = NULL;
1634 break;
1636 Py_DECREF(v);
1637 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1640 return d;
1641 #else
1643 char *name = NULL;
1644 PyObject *d, *v;
1645 DIR *dirp;
1646 struct dirent *ep;
1647 int arg_is_unicode = 1;
1649 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
1650 arg_is_unicode = 0;
1651 PyErr_Clear();
1653 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
1654 return NULL;
1655 if ((dirp = opendir(name)) == NULL) {
1656 return posix_error_with_allocated_filename(name);
1658 if ((d = PyList_New(0)) == NULL) {
1659 closedir(dirp);
1660 PyMem_Free(name);
1661 return NULL;
1663 while ((ep = readdir(dirp)) != NULL) {
1664 if (ep->d_name[0] == '.' &&
1665 (NAMLEN(ep) == 1 ||
1666 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
1667 continue;
1668 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
1669 if (v == NULL) {
1670 Py_DECREF(d);
1671 d = NULL;
1672 break;
1674 #ifdef Py_USING_UNICODE
1675 if (arg_is_unicode) {
1676 PyObject *w;
1678 w = PyUnicode_FromEncodedObject(v,
1679 Py_FileSystemDefaultEncoding,
1680 "strict");
1681 if (w != NULL) {
1682 Py_DECREF(v);
1683 v = w;
1685 else {
1686 /* fall back to the original byte string, as
1687 discussed in patch #683592 */
1688 PyErr_Clear();
1691 #endif
1692 if (PyList_Append(d, v) != 0) {
1693 Py_DECREF(v);
1694 Py_DECREF(d);
1695 d = NULL;
1696 break;
1698 Py_DECREF(v);
1700 closedir(dirp);
1701 PyMem_Free(name);
1703 return d;
1705 #endif /* which OS */
1706 } /* end of posix_listdir */
1708 #ifdef MS_WINDOWS
1709 /* A helper function for abspath on win32 */
1710 static PyObject *
1711 posix__getfullpathname(PyObject *self, PyObject *args)
1713 /* assume encoded strings wont more than double no of chars */
1714 char inbuf[MAX_PATH*2];
1715 char *inbufp = inbuf;
1716 int insize = sizeof(inbuf)/sizeof(inbuf[0]);
1717 char outbuf[MAX_PATH*2];
1718 char *temp;
1719 #ifdef Py_WIN_WIDE_FILENAMES
1720 if (unicode_file_names()) {
1721 PyUnicodeObject *po;
1722 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
1723 Py_UNICODE woutbuf[MAX_PATH*2];
1724 Py_UNICODE *wtemp;
1725 if (!GetFullPathNameW(PyUnicode_AS_UNICODE(po),
1726 sizeof(woutbuf)/sizeof(woutbuf[0]),
1727 woutbuf, &wtemp))
1728 return win32_error("GetFullPathName", "");
1729 return PyUnicode_FromUnicode(woutbuf, wcslen(woutbuf));
1731 /* Drop the argument parsing error as narrow strings
1732 are also valid. */
1733 PyErr_Clear();
1735 #endif
1736 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
1737 Py_FileSystemDefaultEncoding, &inbufp,
1738 &insize))
1739 return NULL;
1740 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
1741 outbuf, &temp))
1742 return win32_error("GetFullPathName", inbuf);
1743 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
1744 return PyUnicode_Decode(outbuf, strlen(outbuf),
1745 Py_FileSystemDefaultEncoding, NULL);
1747 return PyString_FromString(outbuf);
1748 } /* end of posix__getfullpathname */
1749 #endif /* MS_WINDOWS */
1751 PyDoc_STRVAR(posix_mkdir__doc__,
1752 "mkdir(path [, mode=0777])\n\n\
1753 Create a directory.");
1755 static PyObject *
1756 posix_mkdir(PyObject *self, PyObject *args)
1758 int res;
1759 char *path = NULL;
1760 int mode = 0777;
1762 #ifdef Py_WIN_WIDE_FILENAMES
1763 if (unicode_file_names()) {
1764 PyUnicodeObject *po;
1765 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
1766 Py_BEGIN_ALLOW_THREADS
1767 /* PyUnicode_AS_UNICODE OK without thread lock as
1768 it is a simple dereference. */
1769 res = _wmkdir(PyUnicode_AS_UNICODE(po));
1770 Py_END_ALLOW_THREADS
1771 if (res < 0)
1772 return posix_error();
1773 Py_INCREF(Py_None);
1774 return Py_None;
1776 /* Drop the argument parsing error as narrow strings
1777 are also valid. */
1778 PyErr_Clear();
1780 #endif
1782 if (!PyArg_ParseTuple(args, "et|i:mkdir",
1783 Py_FileSystemDefaultEncoding, &path, &mode))
1784 return NULL;
1785 Py_BEGIN_ALLOW_THREADS
1786 #if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
1787 res = mkdir(path);
1788 #else
1789 res = mkdir(path, mode);
1790 #endif
1791 Py_END_ALLOW_THREADS
1792 if (res < 0)
1793 return posix_error_with_allocated_filename(path);
1794 PyMem_Free(path);
1795 Py_INCREF(Py_None);
1796 return Py_None;
1800 #ifdef HAVE_NICE
1801 #if defined(HAVE_BROKEN_NICE) && defined(HAVE_SYS_RESOURCE_H)
1802 #if defined(HAVE_GETPRIORITY) && !defined(PRIO_PROCESS)
1803 #include <sys/resource.h>
1804 #endif
1805 #endif
1807 PyDoc_STRVAR(posix_nice__doc__,
1808 "nice(inc) -> new_priority\n\n\
1809 Decrease the priority of process by inc and return the new priority.");
1811 static PyObject *
1812 posix_nice(PyObject *self, PyObject *args)
1814 int increment, value;
1816 if (!PyArg_ParseTuple(args, "i:nice", &increment))
1817 return NULL;
1819 /* There are two flavours of 'nice': one that returns the new
1820 priority (as required by almost all standards out there) and the
1821 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
1822 the use of getpriority() to get the new priority.
1824 If we are of the nice family that returns the new priority, we
1825 need to clear errno before the call, and check if errno is filled
1826 before calling posix_error() on a returnvalue of -1, because the
1827 -1 may be the actual new priority! */
1829 errno = 0;
1830 value = nice(increment);
1831 #if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
1832 if (value == 0)
1833 value = getpriority(PRIO_PROCESS, 0);
1834 #endif
1835 if (value == -1 && errno != 0)
1836 /* either nice() or getpriority() returned an error */
1837 return posix_error();
1838 return PyInt_FromLong((long) value);
1840 #endif /* HAVE_NICE */
1843 PyDoc_STRVAR(posix_rename__doc__,
1844 "rename(old, new)\n\n\
1845 Rename a file or directory.");
1847 static PyObject *
1848 posix_rename(PyObject *self, PyObject *args)
1850 #ifdef MS_WINDOWS
1851 return posix_2str(args, "etet:rename", rename, "OO:rename", _wrename);
1852 #else
1853 return posix_2str(args, "etet:rename", rename, NULL, NULL);
1854 #endif
1858 PyDoc_STRVAR(posix_rmdir__doc__,
1859 "rmdir(path)\n\n\
1860 Remove a directory.");
1862 static PyObject *
1863 posix_rmdir(PyObject *self, PyObject *args)
1865 #ifdef MS_WINDOWS
1866 return posix_1str(args, "et:rmdir", rmdir, "U:rmdir", _wrmdir);
1867 #else
1868 return posix_1str(args, "et:rmdir", rmdir, NULL, NULL);
1869 #endif
1873 PyDoc_STRVAR(posix_stat__doc__,
1874 "stat(path) -> stat result\n\n\
1875 Perform a stat system call on the given path.");
1877 static PyObject *
1878 posix_stat(PyObject *self, PyObject *args)
1880 #ifdef MS_WINDOWS
1881 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", _wstati64);
1882 #else
1883 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
1884 #endif
1888 #ifdef HAVE_SYSTEM
1889 PyDoc_STRVAR(posix_system__doc__,
1890 "system(command) -> exit_status\n\n\
1891 Execute the command (a string) in a subshell.");
1893 static PyObject *
1894 posix_system(PyObject *self, PyObject *args)
1896 char *command;
1897 long sts;
1898 if (!PyArg_ParseTuple(args, "s:system", &command))
1899 return NULL;
1900 Py_BEGIN_ALLOW_THREADS
1901 sts = system(command);
1902 Py_END_ALLOW_THREADS
1903 return PyInt_FromLong(sts);
1905 #endif
1908 PyDoc_STRVAR(posix_umask__doc__,
1909 "umask(new_mask) -> old_mask\n\n\
1910 Set the current numeric umask and return the previous umask.");
1912 static PyObject *
1913 posix_umask(PyObject *self, PyObject *args)
1915 int i;
1916 if (!PyArg_ParseTuple(args, "i:umask", &i))
1917 return NULL;
1918 i = (int)umask(i);
1919 if (i < 0)
1920 return posix_error();
1921 return PyInt_FromLong((long)i);
1925 PyDoc_STRVAR(posix_unlink__doc__,
1926 "unlink(path)\n\n\
1927 Remove a file (same as remove(path)).");
1929 PyDoc_STRVAR(posix_remove__doc__,
1930 "remove(path)\n\n\
1931 Remove a file (same as unlink(path)).");
1933 static PyObject *
1934 posix_unlink(PyObject *self, PyObject *args)
1936 #ifdef MS_WINDOWS
1937 return posix_1str(args, "et:remove", unlink, "U:remove", _wunlink);
1938 #else
1939 return posix_1str(args, "et:remove", unlink, NULL, NULL);
1940 #endif
1944 #ifdef HAVE_UNAME
1945 PyDoc_STRVAR(posix_uname__doc__,
1946 "uname() -> (sysname, nodename, release, version, machine)\n\n\
1947 Return a tuple identifying the current operating system.");
1949 static PyObject *
1950 posix_uname(PyObject *self, PyObject *noargs)
1952 struct utsname u;
1953 int res;
1955 Py_BEGIN_ALLOW_THREADS
1956 res = uname(&u);
1957 Py_END_ALLOW_THREADS
1958 if (res < 0)
1959 return posix_error();
1960 return Py_BuildValue("(sssss)",
1961 u.sysname,
1962 u.nodename,
1963 u.release,
1964 u.version,
1965 u.machine);
1967 #endif /* HAVE_UNAME */
1969 static int
1970 extract_time(PyObject *t, long* sec, long* usec)
1972 long intval;
1973 if (PyFloat_Check(t)) {
1974 double tval = PyFloat_AsDouble(t);
1975 PyObject *intobj = t->ob_type->tp_as_number->nb_int(t);
1976 if (!intobj)
1977 return -1;
1978 intval = PyInt_AsLong(intobj);
1979 Py_DECREF(intobj);
1980 *sec = intval;
1981 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
1982 if (*usec < 0)
1983 /* If rounding gave us a negative number,
1984 truncate. */
1985 *usec = 0;
1986 return 0;
1988 intval = PyInt_AsLong(t);
1989 if (intval == -1 && PyErr_Occurred())
1990 return -1;
1991 *sec = intval;
1992 *usec = 0;
1993 return 0;
1996 PyDoc_STRVAR(posix_utime__doc__,
1997 "utime(path, (atime, utime))\n\
1998 utime(path, None)\n\n\
1999 Set the access and modified time of the file to the given values. If the\n\
2000 second form is used, set the access and modified times to the current time.");
2002 static PyObject *
2003 posix_utime(PyObject *self, PyObject *args)
2005 char *path = NULL;
2006 long atime, mtime, ausec, musec;
2007 int res;
2008 PyObject* arg;
2010 #if defined(HAVE_UTIMES)
2011 struct timeval buf[2];
2012 #define ATIME buf[0].tv_sec
2013 #define MTIME buf[1].tv_sec
2014 #elif defined(HAVE_UTIME_H)
2015 /* XXX should define struct utimbuf instead, above */
2016 struct utimbuf buf;
2017 #define ATIME buf.actime
2018 #define MTIME buf.modtime
2019 #define UTIME_ARG &buf
2020 #else /* HAVE_UTIMES */
2021 time_t buf[2];
2022 #define ATIME buf[0]
2023 #define MTIME buf[1]
2024 #define UTIME_ARG buf
2025 #endif /* HAVE_UTIMES */
2027 int have_unicode_filename = 0;
2028 #ifdef Py_WIN_WIDE_FILENAMES
2029 PyUnicodeObject *obwpath;
2030 wchar_t *wpath;
2031 if (unicode_file_names()) {
2032 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
2033 wpath = PyUnicode_AS_UNICODE(obwpath);
2034 have_unicode_filename = 1;
2035 } else
2036 /* Drop the argument parsing error as narrow strings
2037 are also valid. */
2038 PyErr_Clear();
2040 #endif /* Py_WIN_WIDE_FILENAMES */
2042 if (!have_unicode_filename && \
2043 !PyArg_ParseTuple(args, "etO:utime",
2044 Py_FileSystemDefaultEncoding, &path, &arg))
2045 return NULL;
2046 if (arg == Py_None) {
2047 /* optional time values not given */
2048 Py_BEGIN_ALLOW_THREADS
2049 #ifdef Py_WIN_WIDE_FILENAMES
2050 if (have_unicode_filename)
2051 res = _wutime(wpath, NULL);
2052 else
2053 #endif /* Py_WIN_WIDE_FILENAMES */
2054 res = utime(path, NULL);
2055 Py_END_ALLOW_THREADS
2057 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
2058 PyErr_SetString(PyExc_TypeError,
2059 "utime() arg 2 must be a tuple (atime, mtime)");
2060 PyMem_Free(path);
2061 return NULL;
2063 else {
2064 if (extract_time(PyTuple_GET_ITEM(arg, 0),
2065 &atime, &ausec) == -1) {
2066 PyMem_Free(path);
2067 return NULL;
2069 if (extract_time(PyTuple_GET_ITEM(arg, 1),
2070 &mtime, &musec) == -1) {
2071 PyMem_Free(path);
2072 return NULL;
2074 ATIME = atime;
2075 MTIME = mtime;
2076 #ifdef HAVE_UTIMES
2077 buf[0].tv_usec = ausec;
2078 buf[1].tv_usec = musec;
2079 Py_BEGIN_ALLOW_THREADS
2080 res = utimes(path, buf);
2081 Py_END_ALLOW_THREADS
2082 #else
2083 Py_BEGIN_ALLOW_THREADS
2084 #ifdef Py_WIN_WIDE_FILENAMES
2085 if (have_unicode_filename)
2086 /* utime is OK with utimbuf, but _wutime insists
2087 on _utimbuf (the msvc headers assert the
2088 underscore version is ansi) */
2089 res = _wutime(wpath, (struct _utimbuf *)UTIME_ARG);
2090 else
2091 #endif /* Py_WIN_WIDE_FILENAMES */
2092 res = utime(path, UTIME_ARG);
2093 Py_END_ALLOW_THREADS
2094 #endif /* HAVE_UTIMES */
2096 if (res < 0) {
2097 #ifdef Py_WIN_WIDE_FILENAMES
2098 if (have_unicode_filename)
2099 return posix_error_with_unicode_filename(wpath);
2100 #endif /* Py_WIN_WIDE_FILENAMES */
2101 return posix_error_with_allocated_filename(path);
2103 PyMem_Free(path);
2104 Py_INCREF(Py_None);
2105 return Py_None;
2106 #undef UTIME_ARG
2107 #undef ATIME
2108 #undef MTIME
2112 /* Process operations */
2114 PyDoc_STRVAR(posix__exit__doc__,
2115 "_exit(status)\n\n\
2116 Exit to the system with specified status, without normal exit processing.");
2118 static PyObject *
2119 posix__exit(PyObject *self, PyObject *args)
2121 int sts;
2122 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
2123 return NULL;
2124 _exit(sts);
2125 return NULL; /* Make gcc -Wall happy */
2128 #if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
2129 static void
2130 free_string_array(char **array, int count)
2132 int i;
2133 for (i = 0; i < count; i++)
2134 PyMem_Free(array[i]);
2135 PyMem_DEL(array);
2137 #endif
2140 #ifdef HAVE_EXECV
2141 PyDoc_STRVAR(posix_execv__doc__,
2142 "execv(path, args)\n\n\
2143 Execute an executable path with arguments, replacing current process.\n\
2145 path: path of executable file\n\
2146 args: tuple or list of strings");
2148 static PyObject *
2149 posix_execv(PyObject *self, PyObject *args)
2151 char *path;
2152 PyObject *argv;
2153 char **argvlist;
2154 int i, argc;
2155 PyObject *(*getitem)(PyObject *, int);
2157 /* execv has two arguments: (path, argv), where
2158 argv is a list or tuple of strings. */
2160 if (!PyArg_ParseTuple(args, "etO:execv",
2161 Py_FileSystemDefaultEncoding,
2162 &path, &argv))
2163 return NULL;
2164 if (PyList_Check(argv)) {
2165 argc = PyList_Size(argv);
2166 getitem = PyList_GetItem;
2168 else if (PyTuple_Check(argv)) {
2169 argc = PyTuple_Size(argv);
2170 getitem = PyTuple_GetItem;
2172 else {
2173 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
2174 PyMem_Free(path);
2175 return NULL;
2178 argvlist = PyMem_NEW(char *, argc+1);
2179 if (argvlist == NULL) {
2180 PyMem_Free(path);
2181 return PyErr_NoMemory();
2183 for (i = 0; i < argc; i++) {
2184 if (!PyArg_Parse((*getitem)(argv, i), "et",
2185 Py_FileSystemDefaultEncoding,
2186 &argvlist[i])) {
2187 free_string_array(argvlist, i);
2188 PyErr_SetString(PyExc_TypeError,
2189 "execv() arg 2 must contain only strings");
2190 PyMem_Free(path);
2191 return NULL;
2195 argvlist[argc] = NULL;
2197 execv(path, argvlist);
2199 /* If we get here it's definitely an error */
2201 free_string_array(argvlist, argc);
2202 PyMem_Free(path);
2203 return posix_error();
2207 PyDoc_STRVAR(posix_execve__doc__,
2208 "execve(path, args, env)\n\n\
2209 Execute a path with arguments and environment, replacing current process.\n\
2211 path: path of executable file\n\
2212 args: tuple or list of arguments\n\
2213 env: dictionary of strings mapping to strings");
2215 static PyObject *
2216 posix_execve(PyObject *self, PyObject *args)
2218 char *path;
2219 PyObject *argv, *env;
2220 char **argvlist;
2221 char **envlist;
2222 PyObject *key, *val, *keys=NULL, *vals=NULL;
2223 int i, pos, argc, envc;
2224 PyObject *(*getitem)(PyObject *, int);
2225 int lastarg = 0;
2227 /* execve has three arguments: (path, argv, env), where
2228 argv is a list or tuple of strings and env is a dictionary
2229 like posix.environ. */
2231 if (!PyArg_ParseTuple(args, "etOO:execve",
2232 Py_FileSystemDefaultEncoding,
2233 &path, &argv, &env))
2234 return NULL;
2235 if (PyList_Check(argv)) {
2236 argc = PyList_Size(argv);
2237 getitem = PyList_GetItem;
2239 else if (PyTuple_Check(argv)) {
2240 argc = PyTuple_Size(argv);
2241 getitem = PyTuple_GetItem;
2243 else {
2244 PyErr_SetString(PyExc_TypeError,
2245 "execve() arg 2 must be a tuple or list");
2246 goto fail_0;
2248 if (!PyMapping_Check(env)) {
2249 PyErr_SetString(PyExc_TypeError,
2250 "execve() arg 3 must be a mapping object");
2251 goto fail_0;
2254 argvlist = PyMem_NEW(char *, argc+1);
2255 if (argvlist == NULL) {
2256 PyErr_NoMemory();
2257 goto fail_0;
2259 for (i = 0; i < argc; i++) {
2260 if (!PyArg_Parse((*getitem)(argv, i),
2261 "et;execve() arg 2 must contain only strings",
2262 Py_FileSystemDefaultEncoding,
2263 &argvlist[i]))
2265 lastarg = i;
2266 goto fail_1;
2269 lastarg = argc;
2270 argvlist[argc] = NULL;
2272 i = PyMapping_Size(env);
2273 if (i < 0)
2274 goto fail_1;
2275 envlist = PyMem_NEW(char *, i + 1);
2276 if (envlist == NULL) {
2277 PyErr_NoMemory();
2278 goto fail_1;
2280 envc = 0;
2281 keys = PyMapping_Keys(env);
2282 vals = PyMapping_Values(env);
2283 if (!keys || !vals)
2284 goto fail_2;
2285 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2286 PyErr_SetString(PyExc_TypeError,
2287 "execve(): env.keys() or env.values() is not a list");
2288 goto fail_2;
2291 for (pos = 0; pos < i; pos++) {
2292 char *p, *k, *v;
2293 size_t len;
2295 key = PyList_GetItem(keys, pos);
2296 val = PyList_GetItem(vals, pos);
2297 if (!key || !val)
2298 goto fail_2;
2300 if (!PyArg_Parse(
2301 key,
2302 "s;execve() arg 3 contains a non-string key",
2303 &k) ||
2304 !PyArg_Parse(
2305 val,
2306 "s;execve() arg 3 contains a non-string value",
2307 &v))
2309 goto fail_2;
2312 #if defined(PYOS_OS2)
2313 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
2314 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
2315 #endif
2316 len = PyString_Size(key) + PyString_Size(val) + 2;
2317 p = PyMem_NEW(char, len);
2318 if (p == NULL) {
2319 PyErr_NoMemory();
2320 goto fail_2;
2322 PyOS_snprintf(p, len, "%s=%s", k, v);
2323 envlist[envc++] = p;
2324 #if defined(PYOS_OS2)
2326 #endif
2328 envlist[envc] = 0;
2330 execve(path, argvlist, envlist);
2332 /* If we get here it's definitely an error */
2334 (void) posix_error();
2336 fail_2:
2337 while (--envc >= 0)
2338 PyMem_DEL(envlist[envc]);
2339 PyMem_DEL(envlist);
2340 fail_1:
2341 free_string_array(argvlist, lastarg);
2342 Py_XDECREF(vals);
2343 Py_XDECREF(keys);
2344 fail_0:
2345 PyMem_Free(path);
2346 return NULL;
2348 #endif /* HAVE_EXECV */
2351 #ifdef HAVE_SPAWNV
2352 PyDoc_STRVAR(posix_spawnv__doc__,
2353 "spawnv(mode, path, args)\n\n\
2354 Execute the program 'path' in a new process.\n\
2356 mode: mode of process creation\n\
2357 path: path of executable file\n\
2358 args: tuple or list of strings");
2360 static PyObject *
2361 posix_spawnv(PyObject *self, PyObject *args)
2363 char *path;
2364 PyObject *argv;
2365 char **argvlist;
2366 int mode, i, argc;
2367 Py_intptr_t spawnval;
2368 PyObject *(*getitem)(PyObject *, int);
2370 /* spawnv has three arguments: (mode, path, argv), where
2371 argv is a list or tuple of strings. */
2373 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
2374 Py_FileSystemDefaultEncoding,
2375 &path, &argv))
2376 return NULL;
2377 if (PyList_Check(argv)) {
2378 argc = PyList_Size(argv);
2379 getitem = PyList_GetItem;
2381 else if (PyTuple_Check(argv)) {
2382 argc = PyTuple_Size(argv);
2383 getitem = PyTuple_GetItem;
2385 else {
2386 PyErr_SetString(PyExc_TypeError,
2387 "spawnv() arg 2 must be a tuple or list");
2388 PyMem_Free(path);
2389 return NULL;
2392 argvlist = PyMem_NEW(char *, argc+1);
2393 if (argvlist == NULL) {
2394 PyMem_Free(path);
2395 return PyErr_NoMemory();
2397 for (i = 0; i < argc; i++) {
2398 if (!PyArg_Parse((*getitem)(argv, i), "et",
2399 Py_FileSystemDefaultEncoding,
2400 &argvlist[i])) {
2401 free_string_array(argvlist, i);
2402 PyErr_SetString(
2403 PyExc_TypeError,
2404 "spawnv() arg 2 must contain only strings");
2405 PyMem_Free(path);
2406 return NULL;
2409 argvlist[argc] = NULL;
2411 #if defined(PYOS_OS2) && defined(PYCC_GCC)
2412 Py_BEGIN_ALLOW_THREADS
2413 spawnval = spawnv(mode, path, argvlist);
2414 Py_END_ALLOW_THREADS
2415 #else
2416 if (mode == _OLD_P_OVERLAY)
2417 mode = _P_OVERLAY;
2419 Py_BEGIN_ALLOW_THREADS
2420 spawnval = _spawnv(mode, path, argvlist);
2421 Py_END_ALLOW_THREADS
2422 #endif
2424 free_string_array(argvlist, argc);
2425 PyMem_Free(path);
2427 if (spawnval == -1)
2428 return posix_error();
2429 else
2430 #if SIZEOF_LONG == SIZEOF_VOID_P
2431 return Py_BuildValue("l", (long) spawnval);
2432 #else
2433 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
2434 #endif
2438 PyDoc_STRVAR(posix_spawnve__doc__,
2439 "spawnve(mode, path, args, env)\n\n\
2440 Execute the program 'path' in a new process.\n\
2442 mode: mode of process creation\n\
2443 path: path of executable file\n\
2444 args: tuple or list of arguments\n\
2445 env: dictionary of strings mapping to strings");
2447 static PyObject *
2448 posix_spawnve(PyObject *self, PyObject *args)
2450 char *path;
2451 PyObject *argv, *env;
2452 char **argvlist;
2453 char **envlist;
2454 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
2455 int mode, i, pos, argc, envc;
2456 Py_intptr_t spawnval;
2457 PyObject *(*getitem)(PyObject *, int);
2458 int lastarg = 0;
2460 /* spawnve has four arguments: (mode, path, argv, env), where
2461 argv is a list or tuple of strings and env is a dictionary
2462 like posix.environ. */
2464 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
2465 Py_FileSystemDefaultEncoding,
2466 &path, &argv, &env))
2467 return NULL;
2468 if (PyList_Check(argv)) {
2469 argc = PyList_Size(argv);
2470 getitem = PyList_GetItem;
2472 else if (PyTuple_Check(argv)) {
2473 argc = PyTuple_Size(argv);
2474 getitem = PyTuple_GetItem;
2476 else {
2477 PyErr_SetString(PyExc_TypeError,
2478 "spawnve() arg 2 must be a tuple or list");
2479 goto fail_0;
2481 if (!PyMapping_Check(env)) {
2482 PyErr_SetString(PyExc_TypeError,
2483 "spawnve() arg 3 must be a mapping object");
2484 goto fail_0;
2487 argvlist = PyMem_NEW(char *, argc+1);
2488 if (argvlist == NULL) {
2489 PyErr_NoMemory();
2490 goto fail_0;
2492 for (i = 0; i < argc; i++) {
2493 if (!PyArg_Parse((*getitem)(argv, i),
2494 "et;spawnve() arg 2 must contain only strings",
2495 Py_FileSystemDefaultEncoding,
2496 &argvlist[i]))
2498 lastarg = i;
2499 goto fail_1;
2502 lastarg = argc;
2503 argvlist[argc] = NULL;
2505 i = PyMapping_Size(env);
2506 if (i < 0)
2507 goto fail_1;
2508 envlist = PyMem_NEW(char *, i + 1);
2509 if (envlist == NULL) {
2510 PyErr_NoMemory();
2511 goto fail_1;
2513 envc = 0;
2514 keys = PyMapping_Keys(env);
2515 vals = PyMapping_Values(env);
2516 if (!keys || !vals)
2517 goto fail_2;
2518 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2519 PyErr_SetString(PyExc_TypeError,
2520 "spawnve(): env.keys() or env.values() is not a list");
2521 goto fail_2;
2524 for (pos = 0; pos < i; pos++) {
2525 char *p, *k, *v;
2526 size_t len;
2528 key = PyList_GetItem(keys, pos);
2529 val = PyList_GetItem(vals, pos);
2530 if (!key || !val)
2531 goto fail_2;
2533 if (!PyArg_Parse(
2534 key,
2535 "s;spawnve() arg 3 contains a non-string key",
2536 &k) ||
2537 !PyArg_Parse(
2538 val,
2539 "s;spawnve() arg 3 contains a non-string value",
2540 &v))
2542 goto fail_2;
2544 len = PyString_Size(key) + PyString_Size(val) + 2;
2545 p = PyMem_NEW(char, len);
2546 if (p == NULL) {
2547 PyErr_NoMemory();
2548 goto fail_2;
2550 PyOS_snprintf(p, len, "%s=%s", k, v);
2551 envlist[envc++] = p;
2553 envlist[envc] = 0;
2555 #if defined(PYOS_OS2) && defined(PYCC_GCC)
2556 Py_BEGIN_ALLOW_THREADS
2557 spawnval = spawnve(mode, path, argvlist, envlist);
2558 Py_END_ALLOW_THREADS
2559 #else
2560 if (mode == _OLD_P_OVERLAY)
2561 mode = _P_OVERLAY;
2563 Py_BEGIN_ALLOW_THREADS
2564 spawnval = _spawnve(mode, path, argvlist, envlist);
2565 Py_END_ALLOW_THREADS
2566 #endif
2568 if (spawnval == -1)
2569 (void) posix_error();
2570 else
2571 #if SIZEOF_LONG == SIZEOF_VOID_P
2572 res = Py_BuildValue("l", (long) spawnval);
2573 #else
2574 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
2575 #endif
2577 fail_2:
2578 while (--envc >= 0)
2579 PyMem_DEL(envlist[envc]);
2580 PyMem_DEL(envlist);
2581 fail_1:
2582 free_string_array(argvlist, lastarg);
2583 Py_XDECREF(vals);
2584 Py_XDECREF(keys);
2585 fail_0:
2586 PyMem_Free(path);
2587 return res;
2590 /* OS/2 supports spawnvp & spawnvpe natively */
2591 #if defined(PYOS_OS2)
2592 PyDoc_STRVAR(posix_spawnvp__doc__,
2593 "spawnvp(mode, file, args)\n\n\
2594 Execute the program 'file' in a new process, using the environment\n\
2595 search path to find the file.\n\
2597 mode: mode of process creation\n\
2598 file: executable file name\n\
2599 args: tuple or list of strings");
2601 static PyObject *
2602 posix_spawnvp(PyObject *self, PyObject *args)
2604 char *path;
2605 PyObject *argv;
2606 char **argvlist;
2607 int mode, i, argc;
2608 Py_intptr_t spawnval;
2609 PyObject *(*getitem)(PyObject *, int);
2611 /* spawnvp has three arguments: (mode, path, argv), where
2612 argv is a list or tuple of strings. */
2614 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
2615 Py_FileSystemDefaultEncoding,
2616 &path, &argv))
2617 return NULL;
2618 if (PyList_Check(argv)) {
2619 argc = PyList_Size(argv);
2620 getitem = PyList_GetItem;
2622 else if (PyTuple_Check(argv)) {
2623 argc = PyTuple_Size(argv);
2624 getitem = PyTuple_GetItem;
2626 else {
2627 PyErr_SetString(PyExc_TypeError,
2628 "spawnvp() arg 2 must be a tuple or list");
2629 PyMem_Free(path);
2630 return NULL;
2633 argvlist = PyMem_NEW(char *, argc+1);
2634 if (argvlist == NULL) {
2635 PyMem_Free(path);
2636 return PyErr_NoMemory();
2638 for (i = 0; i < argc; i++) {
2639 if (!PyArg_Parse((*getitem)(argv, i), "et",
2640 Py_FileSystemDefaultEncoding,
2641 &argvlist[i])) {
2642 free_string_array(argvlist, i);
2643 PyErr_SetString(
2644 PyExc_TypeError,
2645 "spawnvp() arg 2 must contain only strings");
2646 PyMem_Free(path);
2647 return NULL;
2650 argvlist[argc] = NULL;
2652 Py_BEGIN_ALLOW_THREADS
2653 #if defined(PYCC_GCC)
2654 spawnval = spawnvp(mode, path, argvlist);
2655 #else
2656 spawnval = _spawnvp(mode, path, argvlist);
2657 #endif
2658 Py_END_ALLOW_THREADS
2660 free_string_array(argvlist, argc);
2661 PyMem_Free(path);
2663 if (spawnval == -1)
2664 return posix_error();
2665 else
2666 return Py_BuildValue("l", (long) spawnval);
2670 PyDoc_STRVAR(posix_spawnvpe__doc__,
2671 "spawnvpe(mode, file, args, env)\n\n\
2672 Execute the program 'file' in a new process, using the environment\n\
2673 search path to find the file.\n\
2675 mode: mode of process creation\n\
2676 file: executable file name\n\
2677 args: tuple or list of arguments\n\
2678 env: dictionary of strings mapping to strings");
2680 static PyObject *
2681 posix_spawnvpe(PyObject *self, PyObject *args)
2683 char *path;
2684 PyObject *argv, *env;
2685 char **argvlist;
2686 char **envlist;
2687 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
2688 int mode, i, pos, argc, envc;
2689 Py_intptr_t spawnval;
2690 PyObject *(*getitem)(PyObject *, int);
2691 int lastarg = 0;
2693 /* spawnvpe has four arguments: (mode, path, argv, env), where
2694 argv is a list or tuple of strings and env is a dictionary
2695 like posix.environ. */
2697 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
2698 Py_FileSystemDefaultEncoding,
2699 &path, &argv, &env))
2700 return NULL;
2701 if (PyList_Check(argv)) {
2702 argc = PyList_Size(argv);
2703 getitem = PyList_GetItem;
2705 else if (PyTuple_Check(argv)) {
2706 argc = PyTuple_Size(argv);
2707 getitem = PyTuple_GetItem;
2709 else {
2710 PyErr_SetString(PyExc_TypeError,
2711 "spawnvpe() arg 2 must be a tuple or list");
2712 goto fail_0;
2714 if (!PyMapping_Check(env)) {
2715 PyErr_SetString(PyExc_TypeError,
2716 "spawnvpe() arg 3 must be a mapping object");
2717 goto fail_0;
2720 argvlist = PyMem_NEW(char *, argc+1);
2721 if (argvlist == NULL) {
2722 PyErr_NoMemory();
2723 goto fail_0;
2725 for (i = 0; i < argc; i++) {
2726 if (!PyArg_Parse((*getitem)(argv, i),
2727 "et;spawnvpe() arg 2 must contain only strings",
2728 Py_FileSystemDefaultEncoding,
2729 &argvlist[i]))
2731 lastarg = i;
2732 goto fail_1;
2735 lastarg = argc;
2736 argvlist[argc] = NULL;
2738 i = PyMapping_Size(env);
2739 if (i < 0)
2740 goto fail_1;
2741 envlist = PyMem_NEW(char *, i + 1);
2742 if (envlist == NULL) {
2743 PyErr_NoMemory();
2744 goto fail_1;
2746 envc = 0;
2747 keys = PyMapping_Keys(env);
2748 vals = PyMapping_Values(env);
2749 if (!keys || !vals)
2750 goto fail_2;
2751 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2752 PyErr_SetString(PyExc_TypeError,
2753 "spawnvpe(): env.keys() or env.values() is not a list");
2754 goto fail_2;
2757 for (pos = 0; pos < i; pos++) {
2758 char *p, *k, *v;
2759 size_t len;
2761 key = PyList_GetItem(keys, pos);
2762 val = PyList_GetItem(vals, pos);
2763 if (!key || !val)
2764 goto fail_2;
2766 if (!PyArg_Parse(
2767 key,
2768 "s;spawnvpe() arg 3 contains a non-string key",
2769 &k) ||
2770 !PyArg_Parse(
2771 val,
2772 "s;spawnvpe() arg 3 contains a non-string value",
2773 &v))
2775 goto fail_2;
2777 len = PyString_Size(key) + PyString_Size(val) + 2;
2778 p = PyMem_NEW(char, len);
2779 if (p == NULL) {
2780 PyErr_NoMemory();
2781 goto fail_2;
2783 PyOS_snprintf(p, len, "%s=%s", k, v);
2784 envlist[envc++] = p;
2786 envlist[envc] = 0;
2788 Py_BEGIN_ALLOW_THREADS
2789 #if defined(PYCC_GCC)
2790 spawnval = spawnve(mode, path, argvlist, envlist);
2791 #else
2792 spawnval = _spawnve(mode, path, argvlist, envlist);
2793 #endif
2794 Py_END_ALLOW_THREADS
2796 if (spawnval == -1)
2797 (void) posix_error();
2798 else
2799 res = Py_BuildValue("l", (long) spawnval);
2801 fail_2:
2802 while (--envc >= 0)
2803 PyMem_DEL(envlist[envc]);
2804 PyMem_DEL(envlist);
2805 fail_1:
2806 free_string_array(argvlist, lastarg);
2807 Py_XDECREF(vals);
2808 Py_XDECREF(keys);
2809 fail_0:
2810 PyMem_Free(path);
2811 return res;
2813 #endif /* PYOS_OS2 */
2814 #endif /* HAVE_SPAWNV */
2817 #ifdef HAVE_FORK1
2818 PyDoc_STRVAR(posix_fork1__doc__,
2819 "fork1() -> pid\n\n\
2820 Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
2822 Return 0 to child process and PID of child to parent process.");
2824 static PyObject *
2825 posix_fork1(PyObject *self, PyObject *noargs)
2827 int pid = fork1();
2828 if (pid == -1)
2829 return posix_error();
2830 PyOS_AfterFork();
2831 return PyInt_FromLong((long)pid);
2833 #endif
2836 #ifdef HAVE_FORK
2837 PyDoc_STRVAR(posix_fork__doc__,
2838 "fork() -> pid\n\n\
2839 Fork a child process.\n\
2840 Return 0 to child process and PID of child to parent process.");
2842 static PyObject *
2843 posix_fork(PyObject *self, PyObject *noargs)
2845 int pid = fork();
2846 if (pid == -1)
2847 return posix_error();
2848 if (pid == 0)
2849 PyOS_AfterFork();
2850 return PyInt_FromLong((long)pid);
2852 #endif
2854 /* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
2855 /* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
2856 #if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
2857 #define DEV_PTY_FILE "/dev/ptc"
2858 #define HAVE_DEV_PTMX
2859 #else
2860 #define DEV_PTY_FILE "/dev/ptmx"
2861 #endif
2863 #if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
2864 #ifdef HAVE_PTY_H
2865 #include <pty.h>
2866 #else
2867 #ifdef HAVE_LIBUTIL_H
2868 #include <libutil.h>
2869 #endif /* HAVE_LIBUTIL_H */
2870 #endif /* HAVE_PTY_H */
2871 #ifdef HAVE_STROPTS_H
2872 #include <stropts.h>
2873 #endif
2874 #endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
2876 #if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
2877 PyDoc_STRVAR(posix_openpty__doc__,
2878 "openpty() -> (master_fd, slave_fd)\n\n\
2879 Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
2881 static PyObject *
2882 posix_openpty(PyObject *self, PyObject *noargs)
2884 int master_fd, slave_fd;
2885 #ifndef HAVE_OPENPTY
2886 char * slave_name;
2887 #endif
2888 #if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
2889 PyOS_sighandler_t sig_saved;
2890 #ifdef sun
2891 extern char *ptsname();
2892 #endif
2893 #endif
2895 #ifdef HAVE_OPENPTY
2896 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
2897 return posix_error();
2898 #elif defined(HAVE__GETPTY)
2899 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
2900 if (slave_name == NULL)
2901 return posix_error();
2903 slave_fd = open(slave_name, O_RDWR);
2904 if (slave_fd < 0)
2905 return posix_error();
2906 #else
2907 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
2908 if (master_fd < 0)
2909 return posix_error();
2910 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
2911 /* change permission of slave */
2912 if (grantpt(master_fd) < 0) {
2913 PyOS_setsig(SIGCHLD, sig_saved);
2914 return posix_error();
2916 /* unlock slave */
2917 if (unlockpt(master_fd) < 0) {
2918 PyOS_setsig(SIGCHLD, sig_saved);
2919 return posix_error();
2921 PyOS_setsig(SIGCHLD, sig_saved);
2922 slave_name = ptsname(master_fd); /* get name of slave */
2923 if (slave_name == NULL)
2924 return posix_error();
2925 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
2926 if (slave_fd < 0)
2927 return posix_error();
2928 #if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
2929 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
2930 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
2931 #ifndef __hpux
2932 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
2933 #endif /* __hpux */
2934 #endif /* HAVE_CYGWIN */
2935 #endif /* HAVE_OPENPTY */
2937 return Py_BuildValue("(ii)", master_fd, slave_fd);
2940 #endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
2942 #ifdef HAVE_FORKPTY
2943 PyDoc_STRVAR(posix_forkpty__doc__,
2944 "forkpty() -> (pid, master_fd)\n\n\
2945 Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
2946 Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
2947 To both, return fd of newly opened pseudo-terminal.\n");
2949 static PyObject *
2950 posix_forkpty(PyObject *self, PyObject *noargs)
2952 int master_fd, pid;
2954 pid = forkpty(&master_fd, NULL, NULL, NULL);
2955 if (pid == -1)
2956 return posix_error();
2957 if (pid == 0)
2958 PyOS_AfterFork();
2959 return Py_BuildValue("(ii)", pid, master_fd);
2961 #endif
2963 #ifdef HAVE_GETEGID
2964 PyDoc_STRVAR(posix_getegid__doc__,
2965 "getegid() -> egid\n\n\
2966 Return the current process's effective group id.");
2968 static PyObject *
2969 posix_getegid(PyObject *self, PyObject *noargs)
2971 return PyInt_FromLong((long)getegid());
2973 #endif
2976 #ifdef HAVE_GETEUID
2977 PyDoc_STRVAR(posix_geteuid__doc__,
2978 "geteuid() -> euid\n\n\
2979 Return the current process's effective user id.");
2981 static PyObject *
2982 posix_geteuid(PyObject *self, PyObject *noargs)
2984 return PyInt_FromLong((long)geteuid());
2986 #endif
2989 #ifdef HAVE_GETGID
2990 PyDoc_STRVAR(posix_getgid__doc__,
2991 "getgid() -> gid\n\n\
2992 Return the current process's group id.");
2994 static PyObject *
2995 posix_getgid(PyObject *self, PyObject *noargs)
2997 return PyInt_FromLong((long)getgid());
2999 #endif
3002 PyDoc_STRVAR(posix_getpid__doc__,
3003 "getpid() -> pid\n\n\
3004 Return the current process id");
3006 static PyObject *
3007 posix_getpid(PyObject *self, PyObject *noargs)
3009 return PyInt_FromLong((long)getpid());
3013 #ifdef HAVE_GETGROUPS
3014 PyDoc_STRVAR(posix_getgroups__doc__,
3015 "getgroups() -> list of group IDs\n\n\
3016 Return list of supplemental group IDs for the process.");
3018 static PyObject *
3019 posix_getgroups(PyObject *self, PyObject *noargs)
3021 PyObject *result = NULL;
3023 #ifdef NGROUPS_MAX
3024 #define MAX_GROUPS NGROUPS_MAX
3025 #else
3026 /* defined to be 16 on Solaris7, so this should be a small number */
3027 #define MAX_GROUPS 64
3028 #endif
3029 gid_t grouplist[MAX_GROUPS];
3030 int n;
3032 n = getgroups(MAX_GROUPS, grouplist);
3033 if (n < 0)
3034 posix_error();
3035 else {
3036 result = PyList_New(n);
3037 if (result != NULL) {
3038 int i;
3039 for (i = 0; i < n; ++i) {
3040 PyObject *o = PyInt_FromLong((long)grouplist[i]);
3041 if (o == NULL) {
3042 Py_DECREF(result);
3043 result = NULL;
3044 break;
3046 PyList_SET_ITEM(result, i, o);
3051 return result;
3053 #endif
3055 #ifdef HAVE_GETPGID
3056 PyDoc_STRVAR(posix_getpgid__doc__,
3057 "getpgid(pid) -> pgid\n\n\
3058 Call the system call getpgid().");
3060 static PyObject *
3061 posix_getpgid(PyObject *self, PyObject *args)
3063 int pid, pgid;
3064 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
3065 return NULL;
3066 pgid = getpgid(pid);
3067 if (pgid < 0)
3068 return posix_error();
3069 return PyInt_FromLong((long)pgid);
3071 #endif /* HAVE_GETPGID */
3074 #ifdef HAVE_GETPGRP
3075 PyDoc_STRVAR(posix_getpgrp__doc__,
3076 "getpgrp() -> pgrp\n\n\
3077 Return the current process group id.");
3079 static PyObject *
3080 posix_getpgrp(PyObject *self, PyObject *noargs)
3082 #ifdef GETPGRP_HAVE_ARG
3083 return PyInt_FromLong((long)getpgrp(0));
3084 #else /* GETPGRP_HAVE_ARG */
3085 return PyInt_FromLong((long)getpgrp());
3086 #endif /* GETPGRP_HAVE_ARG */
3088 #endif /* HAVE_GETPGRP */
3091 #ifdef HAVE_SETPGRP
3092 PyDoc_STRVAR(posix_setpgrp__doc__,
3093 "setpgrp()\n\n\
3094 Make this process a session leader.");
3096 static PyObject *
3097 posix_setpgrp(PyObject *self, PyObject *noargs)
3099 #ifdef SETPGRP_HAVE_ARG
3100 if (setpgrp(0, 0) < 0)
3101 #else /* SETPGRP_HAVE_ARG */
3102 if (setpgrp() < 0)
3103 #endif /* SETPGRP_HAVE_ARG */
3104 return posix_error();
3105 Py_INCREF(Py_None);
3106 return Py_None;
3109 #endif /* HAVE_SETPGRP */
3111 #ifdef HAVE_GETPPID
3112 PyDoc_STRVAR(posix_getppid__doc__,
3113 "getppid() -> ppid\n\n\
3114 Return the parent's process id.");
3116 static PyObject *
3117 posix_getppid(PyObject *self, PyObject *noargs)
3119 return PyInt_FromLong((long)getppid());
3121 #endif
3124 #ifdef HAVE_GETLOGIN
3125 PyDoc_STRVAR(posix_getlogin__doc__,
3126 "getlogin() -> string\n\n\
3127 Return the actual login name.");
3129 static PyObject *
3130 posix_getlogin(PyObject *self, PyObject *noargs)
3132 PyObject *result = NULL;
3133 char *name;
3134 int old_errno = errno;
3136 errno = 0;
3137 name = getlogin();
3138 if (name == NULL) {
3139 if (errno)
3140 posix_error();
3141 else
3142 PyErr_SetString(PyExc_OSError,
3143 "unable to determine login name");
3145 else
3146 result = PyString_FromString(name);
3147 errno = old_errno;
3149 return result;
3151 #endif
3153 #ifdef HAVE_GETUID
3154 PyDoc_STRVAR(posix_getuid__doc__,
3155 "getuid() -> uid\n\n\
3156 Return the current process's user id.");
3158 static PyObject *
3159 posix_getuid(PyObject *self, PyObject *noargs)
3161 return PyInt_FromLong((long)getuid());
3163 #endif
3166 #ifdef HAVE_KILL
3167 PyDoc_STRVAR(posix_kill__doc__,
3168 "kill(pid, sig)\n\n\
3169 Kill a process with a signal.");
3171 static PyObject *
3172 posix_kill(PyObject *self, PyObject *args)
3174 int pid, sig;
3175 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
3176 return NULL;
3177 #if defined(PYOS_OS2) && !defined(PYCC_GCC)
3178 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
3179 APIRET rc;
3180 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
3181 return os2_error(rc);
3183 } else if (sig == XCPT_SIGNAL_KILLPROC) {
3184 APIRET rc;
3185 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
3186 return os2_error(rc);
3188 } else
3189 return NULL; /* Unrecognized Signal Requested */
3190 #else
3191 if (kill(pid, sig) == -1)
3192 return posix_error();
3193 #endif
3194 Py_INCREF(Py_None);
3195 return Py_None;
3197 #endif
3199 #ifdef HAVE_KILLPG
3200 PyDoc_STRVAR(posix_killpg__doc__,
3201 "killpg(pgid, sig)\n\n\
3202 Kill a process group with a signal.");
3204 static PyObject *
3205 posix_killpg(PyObject *self, PyObject *args)
3207 int pgid, sig;
3208 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
3209 return NULL;
3210 if (killpg(pgid, sig) == -1)
3211 return posix_error();
3212 Py_INCREF(Py_None);
3213 return Py_None;
3215 #endif
3217 #ifdef HAVE_PLOCK
3219 #ifdef HAVE_SYS_LOCK_H
3220 #include <sys/lock.h>
3221 #endif
3223 PyDoc_STRVAR(posix_plock__doc__,
3224 "plock(op)\n\n\
3225 Lock program segments into memory.");
3227 static PyObject *
3228 posix_plock(PyObject *self, PyObject *args)
3230 int op;
3231 if (!PyArg_ParseTuple(args, "i:plock", &op))
3232 return NULL;
3233 if (plock(op) == -1)
3234 return posix_error();
3235 Py_INCREF(Py_None);
3236 return Py_None;
3238 #endif
3241 #ifdef HAVE_POPEN
3242 PyDoc_STRVAR(posix_popen__doc__,
3243 "popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
3244 Open a pipe to/from a command returning a file object.");
3246 #if defined(PYOS_OS2)
3247 #if defined(PYCC_VACPP)
3248 static int
3249 async_system(const char *command)
3251 char errormsg[256], args[1024];
3252 RESULTCODES rcodes;
3253 APIRET rc;
3255 char *shell = getenv("COMSPEC");
3256 if (!shell)
3257 shell = "cmd";
3259 /* avoid overflowing the argument buffer */
3260 if (strlen(shell) + 3 + strlen(command) >= 1024)
3261 return ERROR_NOT_ENOUGH_MEMORY
3263 args[0] = '\0';
3264 strcat(args, shell);
3265 strcat(args, "/c ");
3266 strcat(args, command);
3268 /* execute asynchronously, inheriting the environment */
3269 rc = DosExecPgm(errormsg,
3270 sizeof(errormsg),
3271 EXEC_ASYNC,
3272 args,
3273 NULL,
3274 &rcodes,
3275 shell);
3276 return rc;
3279 static FILE *
3280 popen(const char *command, const char *mode, int pipesize, int *err)
3282 int oldfd, tgtfd;
3283 HFILE pipeh[2];
3284 APIRET rc;
3286 /* mode determines which of stdin or stdout is reconnected to
3287 * the pipe to the child
3289 if (strchr(mode, 'r') != NULL) {
3290 tgt_fd = 1; /* stdout */
3291 } else if (strchr(mode, 'w')) {
3292 tgt_fd = 0; /* stdin */
3293 } else {
3294 *err = ERROR_INVALID_ACCESS;
3295 return NULL;
3298 /* setup the pipe */
3299 if ((rc = DosCreatePipe(&pipeh[0], &pipeh[1], pipesize)) != NO_ERROR) {
3300 *err = rc;
3301 return NULL;
3304 /* prevent other threads accessing stdio */
3305 DosEnterCritSec();
3307 /* reconnect stdio and execute child */
3308 oldfd = dup(tgtfd);
3309 close(tgtfd);
3310 if (dup2(pipeh[tgtfd], tgtfd) == 0) {
3311 DosClose(pipeh[tgtfd]);
3312 rc = async_system(command);
3315 /* restore stdio */
3316 dup2(oldfd, tgtfd);
3317 close(oldfd);
3319 /* allow other threads access to stdio */
3320 DosExitCritSec();
3322 /* if execution of child was successful return file stream */
3323 if (rc == NO_ERROR)
3324 return fdopen(pipeh[1 - tgtfd], mode);
3325 else {
3326 DosClose(pipeh[1 - tgtfd]);
3327 *err = rc;
3328 return NULL;
3332 static PyObject *
3333 posix_popen(PyObject *self, PyObject *args)
3335 char *name;
3336 char *mode = "r";
3337 int err, bufsize = -1;
3338 FILE *fp;
3339 PyObject *f;
3340 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
3341 return NULL;
3342 Py_BEGIN_ALLOW_THREADS
3343 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
3344 Py_END_ALLOW_THREADS
3345 if (fp == NULL)
3346 return os2_error(err);
3348 f = PyFile_FromFile(fp, name, mode, fclose);
3349 if (f != NULL)
3350 PyFile_SetBufSize(f, bufsize);
3351 return f;
3354 #elif defined(PYCC_GCC)
3356 /* standard posix version of popen() support */
3357 static PyObject *
3358 posix_popen(PyObject *self, PyObject *args)
3360 char *name;
3361 char *mode = "r";
3362 int bufsize = -1;
3363 FILE *fp;
3364 PyObject *f;
3365 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
3366 return NULL;
3367 Py_BEGIN_ALLOW_THREADS
3368 fp = popen(name, mode);
3369 Py_END_ALLOW_THREADS
3370 if (fp == NULL)
3371 return posix_error();
3372 f = PyFile_FromFile(fp, name, mode, pclose);
3373 if (f != NULL)
3374 PyFile_SetBufSize(f, bufsize);
3375 return f;
3378 /* fork() under OS/2 has lots'o'warts
3379 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
3380 * most of this code is a ripoff of the win32 code, but using the
3381 * capabilities of EMX's C library routines
3384 /* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
3385 #define POPEN_1 1
3386 #define POPEN_2 2
3387 #define POPEN_3 3
3388 #define POPEN_4 4
3390 static PyObject *_PyPopen(char *, int, int, int);
3391 static int _PyPclose(FILE *file);
3394 * Internal dictionary mapping popen* file pointers to process handles,
3395 * for use when retrieving the process exit code. See _PyPclose() below
3396 * for more information on this dictionary's use.
3398 static PyObject *_PyPopenProcs = NULL;
3400 /* os2emx version of popen2()
3402 * The result of this function is a pipe (file) connected to the
3403 * process's stdin, and a pipe connected to the process's stdout.
3406 static PyObject *
3407 os2emx_popen2(PyObject *self, PyObject *args)
3409 PyObject *f;
3410 int tm=0;
3412 char *cmdstring;
3413 char *mode = "t";
3414 int bufsize = -1;
3415 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
3416 return NULL;
3418 if (*mode == 't')
3419 tm = O_TEXT;
3420 else if (*mode != 'b') {
3421 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3422 return NULL;
3423 } else
3424 tm = O_BINARY;
3426 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
3428 return f;
3432 * Variation on os2emx.popen2
3434 * The result of this function is 3 pipes - the process's stdin,
3435 * stdout and stderr
3438 static PyObject *
3439 os2emx_popen3(PyObject *self, PyObject *args)
3441 PyObject *f;
3442 int tm = 0;
3444 char *cmdstring;
3445 char *mode = "t";
3446 int bufsize = -1;
3447 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
3448 return NULL;
3450 if (*mode == 't')
3451 tm = O_TEXT;
3452 else if (*mode != 'b') {
3453 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3454 return NULL;
3455 } else
3456 tm = O_BINARY;
3458 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
3460 return f;
3464 * Variation on os2emx.popen2
3466 * The result of this function is 2 pipes - the processes stdin,
3467 * and stdout+stderr combined as a single pipe.
3470 static PyObject *
3471 os2emx_popen4(PyObject *self, PyObject *args)
3473 PyObject *f;
3474 int tm = 0;
3476 char *cmdstring;
3477 char *mode = "t";
3478 int bufsize = -1;
3479 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
3480 return NULL;
3482 if (*mode == 't')
3483 tm = O_TEXT;
3484 else if (*mode != 'b') {
3485 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3486 return NULL;
3487 } else
3488 tm = O_BINARY;
3490 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
3492 return f;
3495 /* a couple of structures for convenient handling of multiple
3496 * file handles and pipes
3498 struct file_ref
3500 int handle;
3501 int flags;
3504 struct pipe_ref
3506 int rd;
3507 int wr;
3510 /* The following code is derived from the win32 code */
3512 static PyObject *
3513 _PyPopen(char *cmdstring, int mode, int n, int bufsize)
3515 struct file_ref stdio[3];
3516 struct pipe_ref p_fd[3];
3517 FILE *p_s[3];
3518 int file_count, i, pipe_err, pipe_pid;
3519 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
3520 PyObject *f, *p_f[3];
3522 /* file modes for subsequent fdopen's on pipe handles */
3523 if (mode == O_TEXT)
3525 rd_mode = "rt";
3526 wr_mode = "wt";
3528 else
3530 rd_mode = "rb";
3531 wr_mode = "wb";
3534 /* prepare shell references */
3535 if ((shell = getenv("EMXSHELL")) == NULL)
3536 if ((shell = getenv("COMSPEC")) == NULL)
3538 errno = ENOENT;
3539 return posix_error();
3542 sh_name = _getname(shell);
3543 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
3544 opt = "/c";
3545 else
3546 opt = "-c";
3548 /* save current stdio fds + their flags, and set not inheritable */
3549 i = pipe_err = 0;
3550 while (pipe_err >= 0 && i < 3)
3552 pipe_err = stdio[i].handle = dup(i);
3553 stdio[i].flags = fcntl(i, F_GETFD, 0);
3554 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
3555 i++;
3557 if (pipe_err < 0)
3559 /* didn't get them all saved - clean up and bail out */
3560 int saved_err = errno;
3561 while (i-- > 0)
3563 close(stdio[i].handle);
3565 errno = saved_err;
3566 return posix_error();
3569 /* create pipe ends */
3570 file_count = 2;
3571 if (n == POPEN_3)
3572 file_count = 3;
3573 i = pipe_err = 0;
3574 while ((pipe_err == 0) && (i < file_count))
3575 pipe_err = pipe((int *)&p_fd[i++]);
3576 if (pipe_err < 0)
3578 /* didn't get them all made - clean up and bail out */
3579 while (i-- > 0)
3581 close(p_fd[i].wr);
3582 close(p_fd[i].rd);
3584 errno = EPIPE;
3585 return posix_error();
3588 /* change the actual standard IO streams over temporarily,
3589 * making the retained pipe ends non-inheritable
3591 pipe_err = 0;
3593 /* - stdin */
3594 if (dup2(p_fd[0].rd, 0) == 0)
3596 close(p_fd[0].rd);
3597 i = fcntl(p_fd[0].wr, F_GETFD, 0);
3598 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
3599 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
3601 close(p_fd[0].wr);
3602 pipe_err = -1;
3605 else
3607 pipe_err = -1;
3610 /* - stdout */
3611 if (pipe_err == 0)
3613 if (dup2(p_fd[1].wr, 1) == 1)
3615 close(p_fd[1].wr);
3616 i = fcntl(p_fd[1].rd, F_GETFD, 0);
3617 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
3618 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
3620 close(p_fd[1].rd);
3621 pipe_err = -1;
3624 else
3626 pipe_err = -1;
3630 /* - stderr, as required */
3631 if (pipe_err == 0)
3632 switch (n)
3634 case POPEN_3:
3636 if (dup2(p_fd[2].wr, 2) == 2)
3638 close(p_fd[2].wr);
3639 i = fcntl(p_fd[2].rd, F_GETFD, 0);
3640 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
3641 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
3643 close(p_fd[2].rd);
3644 pipe_err = -1;
3647 else
3649 pipe_err = -1;
3651 break;
3654 case POPEN_4:
3656 if (dup2(1, 2) != 2)
3658 pipe_err = -1;
3660 break;
3664 /* spawn the child process */
3665 if (pipe_err == 0)
3667 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
3668 if (pipe_pid == -1)
3670 pipe_err = -1;
3672 else
3674 /* save the PID into the FILE structure
3675 * NOTE: this implementation doesn't actually
3676 * take advantage of this, but do it for
3677 * completeness - AIM Apr01
3679 for (i = 0; i < file_count; i++)
3680 p_s[i]->_pid = pipe_pid;
3684 /* reset standard IO to normal */
3685 for (i = 0; i < 3; i++)
3687 dup2(stdio[i].handle, i);
3688 fcntl(i, F_SETFD, stdio[i].flags);
3689 close(stdio[i].handle);
3692 /* if any remnant problems, clean up and bail out */
3693 if (pipe_err < 0)
3695 for (i = 0; i < 3; i++)
3697 close(p_fd[i].rd);
3698 close(p_fd[i].wr);
3700 errno = EPIPE;
3701 return posix_error_with_filename(cmdstring);
3704 /* build tuple of file objects to return */
3705 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
3706 PyFile_SetBufSize(p_f[0], bufsize);
3707 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
3708 PyFile_SetBufSize(p_f[1], bufsize);
3709 if (n == POPEN_3)
3711 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
3712 PyFile_SetBufSize(p_f[0], bufsize);
3713 f = PyTuple_Pack(3, p_f[0], p_f[1], p_f[2]);
3715 else
3716 f = PyTuple_Pack(2, p_f[0], p_f[1]);
3719 * Insert the files we've created into the process dictionary
3720 * all referencing the list with the process handle and the
3721 * initial number of files (see description below in _PyPclose).
3722 * Since if _PyPclose later tried to wait on a process when all
3723 * handles weren't closed, it could create a deadlock with the
3724 * child, we spend some energy here to try to ensure that we
3725 * either insert all file handles into the dictionary or none
3726 * at all. It's a little clumsy with the various popen modes
3727 * and variable number of files involved.
3729 if (!_PyPopenProcs)
3731 _PyPopenProcs = PyDict_New();
3734 if (_PyPopenProcs)
3736 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
3737 int ins_rc[3];
3739 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
3740 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
3742 procObj = PyList_New(2);
3743 pidObj = PyInt_FromLong((long) pipe_pid);
3744 intObj = PyInt_FromLong((long) file_count);
3746 if (procObj && pidObj && intObj)
3748 PyList_SetItem(procObj, 0, pidObj);
3749 PyList_SetItem(procObj, 1, intObj);
3751 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
3752 if (fileObj[0])
3754 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
3755 fileObj[0],
3756 procObj);
3758 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
3759 if (fileObj[1])
3761 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
3762 fileObj[1],
3763 procObj);
3765 if (file_count >= 3)
3767 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
3768 if (fileObj[2])
3770 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
3771 fileObj[2],
3772 procObj);
3776 if (ins_rc[0] < 0 || !fileObj[0] ||
3777 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
3778 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
3780 /* Something failed - remove any dictionary
3781 * entries that did make it.
3783 if (!ins_rc[0] && fileObj[0])
3785 PyDict_DelItem(_PyPopenProcs,
3786 fileObj[0]);
3788 if (!ins_rc[1] && fileObj[1])
3790 PyDict_DelItem(_PyPopenProcs,
3791 fileObj[1]);
3793 if (!ins_rc[2] && fileObj[2])
3795 PyDict_DelItem(_PyPopenProcs,
3796 fileObj[2]);
3802 * Clean up our localized references for the dictionary keys
3803 * and value since PyDict_SetItem will Py_INCREF any copies
3804 * that got placed in the dictionary.
3806 Py_XDECREF(procObj);
3807 Py_XDECREF(fileObj[0]);
3808 Py_XDECREF(fileObj[1]);
3809 Py_XDECREF(fileObj[2]);
3812 /* Child is launched. */
3813 return f;
3817 * Wrapper for fclose() to use for popen* files, so we can retrieve the
3818 * exit code for the child process and return as a result of the close.
3820 * This function uses the _PyPopenProcs dictionary in order to map the
3821 * input file pointer to information about the process that was
3822 * originally created by the popen* call that created the file pointer.
3823 * The dictionary uses the file pointer as a key (with one entry
3824 * inserted for each file returned by the original popen* call) and a
3825 * single list object as the value for all files from a single call.
3826 * The list object contains the Win32 process handle at [0], and a file
3827 * count at [1], which is initialized to the total number of file
3828 * handles using that list.
3830 * This function closes whichever handle it is passed, and decrements
3831 * the file count in the dictionary for the process handle pointed to
3832 * by this file. On the last close (when the file count reaches zero),
3833 * this function will wait for the child process and then return its
3834 * exit code as the result of the close() operation. This permits the
3835 * files to be closed in any order - it is always the close() of the
3836 * final handle that will return the exit code.
3838 * NOTE: This function is currently called with the GIL released.
3839 * hence we use the GILState API to manage our state.
3842 static int _PyPclose(FILE *file)
3844 int result;
3845 int exit_code;
3846 int pipe_pid;
3847 PyObject *procObj, *pidObj, *intObj, *fileObj;
3848 int file_count;
3849 #ifdef WITH_THREAD
3850 PyGILState_STATE state;
3851 #endif
3853 /* Close the file handle first, to ensure it can't block the
3854 * child from exiting if it's the last handle.
3856 result = fclose(file);
3858 #ifdef WITH_THREAD
3859 state = PyGILState_Ensure();
3860 #endif
3861 if (_PyPopenProcs)
3863 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
3864 (procObj = PyDict_GetItem(_PyPopenProcs,
3865 fileObj)) != NULL &&
3866 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
3867 (intObj = PyList_GetItem(procObj,1)) != NULL)
3869 pipe_pid = (int) PyInt_AsLong(pidObj);
3870 file_count = (int) PyInt_AsLong(intObj);
3872 if (file_count > 1)
3874 /* Still other files referencing process */
3875 file_count--;
3876 PyList_SetItem(procObj,1,
3877 PyInt_FromLong((long) file_count));
3879 else
3881 /* Last file for this process */
3882 if (result != EOF &&
3883 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
3885 /* extract exit status */
3886 if (WIFEXITED(exit_code))
3888 result = WEXITSTATUS(exit_code);
3890 else
3892 errno = EPIPE;
3893 result = -1;
3896 else
3898 /* Indicate failure - this will cause the file object
3899 * to raise an I/O error and translate the last
3900 * error code from errno. We do have a problem with
3901 * last errors that overlap the normal errno table,
3902 * but that's a consistent problem with the file object.
3904 result = -1;
3908 /* Remove this file pointer from dictionary */
3909 PyDict_DelItem(_PyPopenProcs, fileObj);
3911 if (PyDict_Size(_PyPopenProcs) == 0)
3913 Py_DECREF(_PyPopenProcs);
3914 _PyPopenProcs = NULL;
3917 } /* if object retrieval ok */
3919 Py_XDECREF(fileObj);
3920 } /* if _PyPopenProcs */
3922 #ifdef WITH_THREAD
3923 PyGILState_Release(state);
3924 #endif
3925 return result;
3928 #endif /* PYCC_??? */
3930 #elif defined(MS_WINDOWS)
3933 * Portable 'popen' replacement for Win32.
3935 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
3936 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
3937 * Return code handling by David Bolen <db3l@fitlinxx.com>.
3940 #include <malloc.h>
3941 #include <io.h>
3942 #include <fcntl.h>
3944 /* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
3945 #define POPEN_1 1
3946 #define POPEN_2 2
3947 #define POPEN_3 3
3948 #define POPEN_4 4
3950 static PyObject *_PyPopen(char *, int, int);
3951 static int _PyPclose(FILE *file);
3954 * Internal dictionary mapping popen* file pointers to process handles,
3955 * for use when retrieving the process exit code. See _PyPclose() below
3956 * for more information on this dictionary's use.
3958 static PyObject *_PyPopenProcs = NULL;
3961 /* popen that works from a GUI.
3963 * The result of this function is a pipe (file) connected to the
3964 * processes stdin or stdout, depending on the requested mode.
3967 static PyObject *
3968 posix_popen(PyObject *self, PyObject *args)
3970 PyObject *f;
3971 int tm = 0;
3973 char *cmdstring;
3974 char *mode = "r";
3975 int bufsize = -1;
3976 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
3977 return NULL;
3979 if (*mode == 'r')
3980 tm = _O_RDONLY;
3981 else if (*mode != 'w') {
3982 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
3983 return NULL;
3984 } else
3985 tm = _O_WRONLY;
3987 if (bufsize != -1) {
3988 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
3989 return NULL;
3992 if (*(mode+1) == 't')
3993 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
3994 else if (*(mode+1) == 'b')
3995 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
3996 else
3997 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
3999 return f;
4002 /* Variation on win32pipe.popen
4004 * The result of this function is a pipe (file) connected to the
4005 * process's stdin, and a pipe connected to the process's stdout.
4008 static PyObject *
4009 win32_popen2(PyObject *self, PyObject *args)
4011 PyObject *f;
4012 int tm=0;
4014 char *cmdstring;
4015 char *mode = "t";
4016 int bufsize = -1;
4017 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
4018 return NULL;
4020 if (*mode == 't')
4021 tm = _O_TEXT;
4022 else if (*mode != 'b') {
4023 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
4024 return NULL;
4025 } else
4026 tm = _O_BINARY;
4028 if (bufsize != -1) {
4029 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
4030 return NULL;
4033 f = _PyPopen(cmdstring, tm, POPEN_2);
4035 return f;
4039 * Variation on <om win32pipe.popen>
4041 * The result of this function is 3 pipes - the process's stdin,
4042 * stdout and stderr
4045 static PyObject *
4046 win32_popen3(PyObject *self, PyObject *args)
4048 PyObject *f;
4049 int tm = 0;
4051 char *cmdstring;
4052 char *mode = "t";
4053 int bufsize = -1;
4054 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
4055 return NULL;
4057 if (*mode == 't')
4058 tm = _O_TEXT;
4059 else if (*mode != 'b') {
4060 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
4061 return NULL;
4062 } else
4063 tm = _O_BINARY;
4065 if (bufsize != -1) {
4066 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
4067 return NULL;
4070 f = _PyPopen(cmdstring, tm, POPEN_3);
4072 return f;
4076 * Variation on win32pipe.popen
4078 * The result of this function is 2 pipes - the processes stdin,
4079 * and stdout+stderr combined as a single pipe.
4082 static PyObject *
4083 win32_popen4(PyObject *self, PyObject *args)
4085 PyObject *f;
4086 int tm = 0;
4088 char *cmdstring;
4089 char *mode = "t";
4090 int bufsize = -1;
4091 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
4092 return NULL;
4094 if (*mode == 't')
4095 tm = _O_TEXT;
4096 else if (*mode != 'b') {
4097 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
4098 return NULL;
4099 } else
4100 tm = _O_BINARY;
4102 if (bufsize != -1) {
4103 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
4104 return NULL;
4107 f = _PyPopen(cmdstring, tm, POPEN_4);
4109 return f;
4112 static BOOL
4113 _PyPopenCreateProcess(char *cmdstring,
4114 HANDLE hStdin,
4115 HANDLE hStdout,
4116 HANDLE hStderr,
4117 HANDLE *hProcess)
4119 PROCESS_INFORMATION piProcInfo;
4120 STARTUPINFO siStartInfo;
4121 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
4122 char *s1,*s2, *s3 = " /c ";
4123 const char *szConsoleSpawn = "w9xpopen.exe";
4124 int i;
4125 int x;
4127 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
4128 char *comshell;
4130 s1 = (char *)alloca(i);
4131 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
4132 return x;
4134 /* Explicitly check if we are using COMMAND.COM. If we are
4135 * then use the w9xpopen hack.
4137 comshell = s1 + x;
4138 while (comshell >= s1 && *comshell != '\\')
4139 --comshell;
4140 ++comshell;
4142 if (GetVersion() < 0x80000000 &&
4143 _stricmp(comshell, "command.com") != 0) {
4144 /* NT/2000 and not using command.com. */
4145 x = i + strlen(s3) + strlen(cmdstring) + 1;
4146 s2 = (char *)alloca(x);
4147 ZeroMemory(s2, x);
4148 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
4150 else {
4152 * Oh gag, we're on Win9x or using COMMAND.COM. Use
4153 * the workaround listed in KB: Q150956
4155 char modulepath[_MAX_PATH];
4156 struct stat statinfo;
4157 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
4158 for (i = x = 0; modulepath[i]; i++)
4159 if (modulepath[i] == SEP)
4160 x = i+1;
4161 modulepath[x] = '\0';
4162 /* Create the full-name to w9xpopen, so we can test it exists */
4163 strncat(modulepath,
4164 szConsoleSpawn,
4165 (sizeof(modulepath)/sizeof(modulepath[0]))
4166 -strlen(modulepath));
4167 if (stat(modulepath, &statinfo) != 0) {
4168 /* Eeek - file-not-found - possibly an embedding
4169 situation - see if we can locate it in sys.prefix
4171 strncpy(modulepath,
4172 Py_GetExecPrefix(),
4173 sizeof(modulepath)/sizeof(modulepath[0]));
4174 if (modulepath[strlen(modulepath)-1] != '\\')
4175 strcat(modulepath, "\\");
4176 strncat(modulepath,
4177 szConsoleSpawn,
4178 (sizeof(modulepath)/sizeof(modulepath[0]))
4179 -strlen(modulepath));
4180 /* No where else to look - raise an easily identifiable
4181 error, rather than leaving Windows to report
4182 "file not found" - as the user is probably blissfully
4183 unaware this shim EXE is used, and it will confuse them.
4184 (well, it confused me for a while ;-)
4186 if (stat(modulepath, &statinfo) != 0) {
4187 PyErr_Format(PyExc_RuntimeError,
4188 "Can not locate '%s' which is needed "
4189 "for popen to work with your shell "
4190 "or platform.",
4191 szConsoleSpawn);
4192 return FALSE;
4195 x = i + strlen(s3) + strlen(cmdstring) + 1 +
4196 strlen(modulepath) +
4197 strlen(szConsoleSpawn) + 1;
4199 s2 = (char *)alloca(x);
4200 ZeroMemory(s2, x);
4201 /* To maintain correct argument passing semantics,
4202 we pass the command-line as it stands, and allow
4203 quoting to be applied. w9xpopen.exe will then
4204 use its argv vector, and re-quote the necessary
4205 args for the ultimate child process.
4207 PyOS_snprintf(
4208 s2, x,
4209 "\"%s\" %s%s%s",
4210 modulepath,
4213 cmdstring);
4214 /* Not passing CREATE_NEW_CONSOLE has been known to
4215 cause random failures on win9x. Specifically a
4216 dialog:
4217 "Your program accessed mem currently in use at xxx"
4218 and a hopeful warning about the stability of your
4219 system.
4220 Cost is Ctrl+C wont kill children, but anyone
4221 who cares can have a go!
4223 dwProcessFlags |= CREATE_NEW_CONSOLE;
4227 /* Could be an else here to try cmd.exe / command.com in the path
4228 Now we'll just error out.. */
4229 else {
4230 PyErr_SetString(PyExc_RuntimeError,
4231 "Cannot locate a COMSPEC environment variable to "
4232 "use as the shell");
4233 return FALSE;
4236 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
4237 siStartInfo.cb = sizeof(STARTUPINFO);
4238 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
4239 siStartInfo.hStdInput = hStdin;
4240 siStartInfo.hStdOutput = hStdout;
4241 siStartInfo.hStdError = hStderr;
4242 siStartInfo.wShowWindow = SW_HIDE;
4244 if (CreateProcess(NULL,
4246 NULL,
4247 NULL,
4248 TRUE,
4249 dwProcessFlags,
4250 NULL,
4251 NULL,
4252 &siStartInfo,
4253 &piProcInfo) ) {
4254 /* Close the handles now so anyone waiting is woken. */
4255 CloseHandle(piProcInfo.hThread);
4257 /* Return process handle */
4258 *hProcess = piProcInfo.hProcess;
4259 return TRUE;
4261 win32_error("CreateProcess", s2);
4262 return FALSE;
4265 /* The following code is based off of KB: Q190351 */
4267 static PyObject *
4268 _PyPopen(char *cmdstring, int mode, int n)
4270 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
4271 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
4272 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
4274 SECURITY_ATTRIBUTES saAttr;
4275 BOOL fSuccess;
4276 int fd1, fd2, fd3;
4277 FILE *f1, *f2, *f3;
4278 long file_count;
4279 PyObject *f;
4281 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
4282 saAttr.bInheritHandle = TRUE;
4283 saAttr.lpSecurityDescriptor = NULL;
4285 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
4286 return win32_error("CreatePipe", NULL);
4288 /* Create new output read handle and the input write handle. Set
4289 * the inheritance properties to FALSE. Otherwise, the child inherits
4290 * these handles; resulting in non-closeable handles to the pipes
4291 * being created. */
4292 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
4293 GetCurrentProcess(), &hChildStdinWrDup, 0,
4294 FALSE,
4295 DUPLICATE_SAME_ACCESS);
4296 if (!fSuccess)
4297 return win32_error("DuplicateHandle", NULL);
4299 /* Close the inheritable version of ChildStdin
4300 that we're using. */
4301 CloseHandle(hChildStdinWr);
4303 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
4304 return win32_error("CreatePipe", NULL);
4306 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
4307 GetCurrentProcess(), &hChildStdoutRdDup, 0,
4308 FALSE, DUPLICATE_SAME_ACCESS);
4309 if (!fSuccess)
4310 return win32_error("DuplicateHandle", NULL);
4312 /* Close the inheritable version of ChildStdout
4313 that we're using. */
4314 CloseHandle(hChildStdoutRd);
4316 if (n != POPEN_4) {
4317 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
4318 return win32_error("CreatePipe", NULL);
4319 fSuccess = DuplicateHandle(GetCurrentProcess(),
4320 hChildStderrRd,
4321 GetCurrentProcess(),
4322 &hChildStderrRdDup, 0,
4323 FALSE, DUPLICATE_SAME_ACCESS);
4324 if (!fSuccess)
4325 return win32_error("DuplicateHandle", NULL);
4326 /* Close the inheritable version of ChildStdErr that we're using. */
4327 CloseHandle(hChildStderrRd);
4330 switch (n) {
4331 case POPEN_1:
4332 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
4333 case _O_WRONLY | _O_TEXT:
4334 /* Case for writing to child Stdin in text mode. */
4335 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4336 f1 = _fdopen(fd1, "w");
4337 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
4338 PyFile_SetBufSize(f, 0);
4339 /* We don't care about these pipes anymore, so close them. */
4340 CloseHandle(hChildStdoutRdDup);
4341 CloseHandle(hChildStderrRdDup);
4342 break;
4344 case _O_RDONLY | _O_TEXT:
4345 /* Case for reading from child Stdout in text mode. */
4346 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4347 f1 = _fdopen(fd1, "r");
4348 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
4349 PyFile_SetBufSize(f, 0);
4350 /* We don't care about these pipes anymore, so close them. */
4351 CloseHandle(hChildStdinWrDup);
4352 CloseHandle(hChildStderrRdDup);
4353 break;
4355 case _O_RDONLY | _O_BINARY:
4356 /* Case for readinig from child Stdout in binary mode. */
4357 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4358 f1 = _fdopen(fd1, "rb");
4359 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
4360 PyFile_SetBufSize(f, 0);
4361 /* We don't care about these pipes anymore, so close them. */
4362 CloseHandle(hChildStdinWrDup);
4363 CloseHandle(hChildStderrRdDup);
4364 break;
4366 case _O_WRONLY | _O_BINARY:
4367 /* Case for writing to child Stdin in binary mode. */
4368 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4369 f1 = _fdopen(fd1, "wb");
4370 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
4371 PyFile_SetBufSize(f, 0);
4372 /* We don't care about these pipes anymore, so close them. */
4373 CloseHandle(hChildStdoutRdDup);
4374 CloseHandle(hChildStderrRdDup);
4375 break;
4377 file_count = 1;
4378 break;
4380 case POPEN_2:
4381 case POPEN_4:
4383 char *m1, *m2;
4384 PyObject *p1, *p2;
4386 if (mode & _O_TEXT) {
4387 m1 = "r";
4388 m2 = "w";
4389 } else {
4390 m1 = "rb";
4391 m2 = "wb";
4394 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4395 f1 = _fdopen(fd1, m2);
4396 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4397 f2 = _fdopen(fd2, m1);
4398 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
4399 PyFile_SetBufSize(p1, 0);
4400 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
4401 PyFile_SetBufSize(p2, 0);
4403 if (n != 4)
4404 CloseHandle(hChildStderrRdDup);
4406 f = PyTuple_Pack(2,p1,p2);
4407 Py_XDECREF(p1);
4408 Py_XDECREF(p2);
4409 file_count = 2;
4410 break;
4413 case POPEN_3:
4415 char *m1, *m2;
4416 PyObject *p1, *p2, *p3;
4418 if (mode & _O_TEXT) {
4419 m1 = "r";
4420 m2 = "w";
4421 } else {
4422 m1 = "rb";
4423 m2 = "wb";
4426 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4427 f1 = _fdopen(fd1, m2);
4428 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4429 f2 = _fdopen(fd2, m1);
4430 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
4431 f3 = _fdopen(fd3, m1);
4432 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
4433 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
4434 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
4435 PyFile_SetBufSize(p1, 0);
4436 PyFile_SetBufSize(p2, 0);
4437 PyFile_SetBufSize(p3, 0);
4438 f = PyTuple_Pack(3,p1,p2,p3);
4439 Py_XDECREF(p1);
4440 Py_XDECREF(p2);
4441 Py_XDECREF(p3);
4442 file_count = 3;
4443 break;
4447 if (n == POPEN_4) {
4448 if (!_PyPopenCreateProcess(cmdstring,
4449 hChildStdinRd,
4450 hChildStdoutWr,
4451 hChildStdoutWr,
4452 &hProcess))
4453 return NULL;
4455 else {
4456 if (!_PyPopenCreateProcess(cmdstring,
4457 hChildStdinRd,
4458 hChildStdoutWr,
4459 hChildStderrWr,
4460 &hProcess))
4461 return NULL;
4465 * Insert the files we've created into the process dictionary
4466 * all referencing the list with the process handle and the
4467 * initial number of files (see description below in _PyPclose).
4468 * Since if _PyPclose later tried to wait on a process when all
4469 * handles weren't closed, it could create a deadlock with the
4470 * child, we spend some energy here to try to ensure that we
4471 * either insert all file handles into the dictionary or none
4472 * at all. It's a little clumsy with the various popen modes
4473 * and variable number of files involved.
4475 if (!_PyPopenProcs) {
4476 _PyPopenProcs = PyDict_New();
4479 if (_PyPopenProcs) {
4480 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
4481 int ins_rc[3];
4483 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4484 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4486 procObj = PyList_New(2);
4487 hProcessObj = PyLong_FromVoidPtr(hProcess);
4488 intObj = PyInt_FromLong(file_count);
4490 if (procObj && hProcessObj && intObj) {
4491 PyList_SetItem(procObj,0,hProcessObj);
4492 PyList_SetItem(procObj,1,intObj);
4494 fileObj[0] = PyLong_FromVoidPtr(f1);
4495 if (fileObj[0]) {
4496 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4497 fileObj[0],
4498 procObj);
4500 if (file_count >= 2) {
4501 fileObj[1] = PyLong_FromVoidPtr(f2);
4502 if (fileObj[1]) {
4503 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4504 fileObj[1],
4505 procObj);
4508 if (file_count >= 3) {
4509 fileObj[2] = PyLong_FromVoidPtr(f3);
4510 if (fileObj[2]) {
4511 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4512 fileObj[2],
4513 procObj);
4517 if (ins_rc[0] < 0 || !fileObj[0] ||
4518 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4519 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
4520 /* Something failed - remove any dictionary
4521 * entries that did make it.
4523 if (!ins_rc[0] && fileObj[0]) {
4524 PyDict_DelItem(_PyPopenProcs,
4525 fileObj[0]);
4527 if (!ins_rc[1] && fileObj[1]) {
4528 PyDict_DelItem(_PyPopenProcs,
4529 fileObj[1]);
4531 if (!ins_rc[2] && fileObj[2]) {
4532 PyDict_DelItem(_PyPopenProcs,
4533 fileObj[2]);
4539 * Clean up our localized references for the dictionary keys
4540 * and value since PyDict_SetItem will Py_INCREF any copies
4541 * that got placed in the dictionary.
4543 Py_XDECREF(procObj);
4544 Py_XDECREF(fileObj[0]);
4545 Py_XDECREF(fileObj[1]);
4546 Py_XDECREF(fileObj[2]);
4549 /* Child is launched. Close the parents copy of those pipe
4550 * handles that only the child should have open. You need to
4551 * make sure that no handles to the write end of the output pipe
4552 * are maintained in this process or else the pipe will not close
4553 * when the child process exits and the ReadFile will hang. */
4555 if (!CloseHandle(hChildStdinRd))
4556 return win32_error("CloseHandle", NULL);
4558 if (!CloseHandle(hChildStdoutWr))
4559 return win32_error("CloseHandle", NULL);
4561 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
4562 return win32_error("CloseHandle", NULL);
4564 return f;
4568 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4569 * exit code for the child process and return as a result of the close.
4571 * This function uses the _PyPopenProcs dictionary in order to map the
4572 * input file pointer to information about the process that was
4573 * originally created by the popen* call that created the file pointer.
4574 * The dictionary uses the file pointer as a key (with one entry
4575 * inserted for each file returned by the original popen* call) and a
4576 * single list object as the value for all files from a single call.
4577 * The list object contains the Win32 process handle at [0], and a file
4578 * count at [1], which is initialized to the total number of file
4579 * handles using that list.
4581 * This function closes whichever handle it is passed, and decrements
4582 * the file count in the dictionary for the process handle pointed to
4583 * by this file. On the last close (when the file count reaches zero),
4584 * this function will wait for the child process and then return its
4585 * exit code as the result of the close() operation. This permits the
4586 * files to be closed in any order - it is always the close() of the
4587 * final handle that will return the exit code.
4589 * NOTE: This function is currently called with the GIL released.
4590 * hence we use the GILState API to manage our state.
4593 static int _PyPclose(FILE *file)
4595 int result;
4596 DWORD exit_code;
4597 HANDLE hProcess;
4598 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
4599 long file_count;
4600 #ifdef WITH_THREAD
4601 PyGILState_STATE state;
4602 #endif
4604 /* Close the file handle first, to ensure it can't block the
4605 * child from exiting if it's the last handle.
4607 result = fclose(file);
4608 #ifdef WITH_THREAD
4609 state = PyGILState_Ensure();
4610 #endif
4611 if (_PyPopenProcs) {
4612 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4613 (procObj = PyDict_GetItem(_PyPopenProcs,
4614 fileObj)) != NULL &&
4615 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
4616 (intObj = PyList_GetItem(procObj,1)) != NULL) {
4618 hProcess = PyLong_AsVoidPtr(hProcessObj);
4619 file_count = PyInt_AsLong(intObj);
4621 if (file_count > 1) {
4622 /* Still other files referencing process */
4623 file_count--;
4624 PyList_SetItem(procObj,1,
4625 PyInt_FromLong(file_count));
4626 } else {
4627 /* Last file for this process */
4628 if (result != EOF &&
4629 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
4630 GetExitCodeProcess(hProcess, &exit_code)) {
4631 /* Possible truncation here in 16-bit environments, but
4632 * real exit codes are just the lower byte in any event.
4634 result = exit_code;
4635 } else {
4636 /* Indicate failure - this will cause the file object
4637 * to raise an I/O error and translate the last Win32
4638 * error code from errno. We do have a problem with
4639 * last errors that overlap the normal errno table,
4640 * but that's a consistent problem with the file object.
4642 if (result != EOF) {
4643 /* If the error wasn't from the fclose(), then
4644 * set errno for the file object error handling.
4646 errno = GetLastError();
4648 result = -1;
4651 /* Free up the native handle at this point */
4652 CloseHandle(hProcess);
4655 /* Remove this file pointer from dictionary */
4656 PyDict_DelItem(_PyPopenProcs, fileObj);
4658 if (PyDict_Size(_PyPopenProcs) == 0) {
4659 Py_DECREF(_PyPopenProcs);
4660 _PyPopenProcs = NULL;
4663 } /* if object retrieval ok */
4665 Py_XDECREF(fileObj);
4666 } /* if _PyPopenProcs */
4668 #ifdef WITH_THREAD
4669 PyGILState_Release(state);
4670 #endif
4671 return result;
4674 #else /* which OS? */
4675 static PyObject *
4676 posix_popen(PyObject *self, PyObject *args)
4678 char *name;
4679 char *mode = "r";
4680 int bufsize = -1;
4681 FILE *fp;
4682 PyObject *f;
4683 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
4684 return NULL;
4685 /* Strip mode of binary or text modifiers */
4686 if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
4687 mode = "r";
4688 else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
4689 mode = "w";
4690 Py_BEGIN_ALLOW_THREADS
4691 fp = popen(name, mode);
4692 Py_END_ALLOW_THREADS
4693 if (fp == NULL)
4694 return posix_error();
4695 f = PyFile_FromFile(fp, name, mode, pclose);
4696 if (f != NULL)
4697 PyFile_SetBufSize(f, bufsize);
4698 return f;
4701 #endif /* PYOS_??? */
4702 #endif /* HAVE_POPEN */
4705 #ifdef HAVE_SETUID
4706 PyDoc_STRVAR(posix_setuid__doc__,
4707 "setuid(uid)\n\n\
4708 Set the current process's user id.");
4710 static PyObject *
4711 posix_setuid(PyObject *self, PyObject *args)
4713 int uid;
4714 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
4715 return NULL;
4716 if (setuid(uid) < 0)
4717 return posix_error();
4718 Py_INCREF(Py_None);
4719 return Py_None;
4721 #endif /* HAVE_SETUID */
4724 #ifdef HAVE_SETEUID
4725 PyDoc_STRVAR(posix_seteuid__doc__,
4726 "seteuid(uid)\n\n\
4727 Set the current process's effective user id.");
4729 static PyObject *
4730 posix_seteuid (PyObject *self, PyObject *args)
4732 int euid;
4733 if (!PyArg_ParseTuple(args, "i", &euid)) {
4734 return NULL;
4735 } else if (seteuid(euid) < 0) {
4736 return posix_error();
4737 } else {
4738 Py_INCREF(Py_None);
4739 return Py_None;
4742 #endif /* HAVE_SETEUID */
4744 #ifdef HAVE_SETEGID
4745 PyDoc_STRVAR(posix_setegid__doc__,
4746 "setegid(gid)\n\n\
4747 Set the current process's effective group id.");
4749 static PyObject *
4750 posix_setegid (PyObject *self, PyObject *args)
4752 int egid;
4753 if (!PyArg_ParseTuple(args, "i", &egid)) {
4754 return NULL;
4755 } else if (setegid(egid) < 0) {
4756 return posix_error();
4757 } else {
4758 Py_INCREF(Py_None);
4759 return Py_None;
4762 #endif /* HAVE_SETEGID */
4764 #ifdef HAVE_SETREUID
4765 PyDoc_STRVAR(posix_setreuid__doc__,
4766 "setreuid(ruid, euid)\n\n\
4767 Set the current process's real and effective user ids.");
4769 static PyObject *
4770 posix_setreuid (PyObject *self, PyObject *args)
4772 int ruid, euid;
4773 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
4774 return NULL;
4775 } else if (setreuid(ruid, euid) < 0) {
4776 return posix_error();
4777 } else {
4778 Py_INCREF(Py_None);
4779 return Py_None;
4782 #endif /* HAVE_SETREUID */
4784 #ifdef HAVE_SETREGID
4785 PyDoc_STRVAR(posix_setregid__doc__,
4786 "setregid(rgid, egid)\n\n\
4787 Set the current process's real and effective group ids.");
4789 static PyObject *
4790 posix_setregid (PyObject *self, PyObject *args)
4792 int rgid, egid;
4793 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
4794 return NULL;
4795 } else if (setregid(rgid, egid) < 0) {
4796 return posix_error();
4797 } else {
4798 Py_INCREF(Py_None);
4799 return Py_None;
4802 #endif /* HAVE_SETREGID */
4804 #ifdef HAVE_SETGID
4805 PyDoc_STRVAR(posix_setgid__doc__,
4806 "setgid(gid)\n\n\
4807 Set the current process's group id.");
4809 static PyObject *
4810 posix_setgid(PyObject *self, PyObject *args)
4812 int gid;
4813 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
4814 return NULL;
4815 if (setgid(gid) < 0)
4816 return posix_error();
4817 Py_INCREF(Py_None);
4818 return Py_None;
4820 #endif /* HAVE_SETGID */
4822 #ifdef HAVE_SETGROUPS
4823 PyDoc_STRVAR(posix_setgroups__doc__,
4824 "setgroups(list)\n\n\
4825 Set the groups of the current process to list.");
4827 static PyObject *
4828 posix_setgroups(PyObject *self, PyObject *args)
4830 PyObject *groups;
4831 int i, len;
4832 gid_t grouplist[MAX_GROUPS];
4834 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
4835 return NULL;
4836 if (!PySequence_Check(groups)) {
4837 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
4838 return NULL;
4840 len = PySequence_Size(groups);
4841 if (len > MAX_GROUPS) {
4842 PyErr_SetString(PyExc_ValueError, "too many groups");
4843 return NULL;
4845 for(i = 0; i < len; i++) {
4846 PyObject *elem;
4847 elem = PySequence_GetItem(groups, i);
4848 if (!elem)
4849 return NULL;
4850 if (!PyInt_Check(elem)) {
4851 PyErr_SetString(PyExc_TypeError,
4852 "groups must be integers");
4853 Py_DECREF(elem);
4854 return NULL;
4856 /* XXX: check that value fits into gid_t. */
4857 grouplist[i] = PyInt_AsLong(elem);
4858 Py_DECREF(elem);
4861 if (setgroups(len, grouplist) < 0)
4862 return posix_error();
4863 Py_INCREF(Py_None);
4864 return Py_None;
4866 #endif /* HAVE_SETGROUPS */
4868 #ifdef HAVE_WAITPID
4869 PyDoc_STRVAR(posix_waitpid__doc__,
4870 "waitpid(pid, options) -> (pid, status)\n\n\
4871 Wait for completion of a given child process.");
4873 static PyObject *
4874 posix_waitpid(PyObject *self, PyObject *args)
4876 int pid, options;
4877 #ifdef UNION_WAIT
4878 union wait status;
4879 #define status_i (status.w_status)
4880 #else
4881 int status;
4882 #define status_i status
4883 #endif
4884 status_i = 0;
4886 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
4887 return NULL;
4888 Py_BEGIN_ALLOW_THREADS
4889 pid = waitpid(pid, &status, options);
4890 Py_END_ALLOW_THREADS
4891 if (pid == -1)
4892 return posix_error();
4893 else
4894 return Py_BuildValue("ii", pid, status_i);
4897 #elif defined(HAVE_CWAIT)
4899 /* MS C has a variant of waitpid() that's usable for most purposes. */
4900 PyDoc_STRVAR(posix_waitpid__doc__,
4901 "waitpid(pid, options) -> (pid, status << 8)\n\n"
4902 "Wait for completion of a given process. options is ignored on Windows.");
4904 static PyObject *
4905 posix_waitpid(PyObject *self, PyObject *args)
4907 int pid, options;
4908 int status;
4910 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
4911 return NULL;
4912 Py_BEGIN_ALLOW_THREADS
4913 pid = _cwait(&status, pid, options);
4914 Py_END_ALLOW_THREADS
4915 if (pid == -1)
4916 return posix_error();
4917 else
4918 /* shift the status left a byte so this is more like the
4919 POSIX waitpid */
4920 return Py_BuildValue("ii", pid, status << 8);
4922 #endif /* HAVE_WAITPID || HAVE_CWAIT */
4924 #ifdef HAVE_WAIT
4925 PyDoc_STRVAR(posix_wait__doc__,
4926 "wait() -> (pid, status)\n\n\
4927 Wait for completion of a child process.");
4929 static PyObject *
4930 posix_wait(PyObject *self, PyObject *noargs)
4932 int pid;
4933 #ifdef UNION_WAIT
4934 union wait status;
4935 #define status_i (status.w_status)
4936 #else
4937 int status;
4938 #define status_i status
4939 #endif
4941 status_i = 0;
4942 Py_BEGIN_ALLOW_THREADS
4943 pid = wait(&status);
4944 Py_END_ALLOW_THREADS
4945 if (pid == -1)
4946 return posix_error();
4947 else
4948 return Py_BuildValue("ii", pid, status_i);
4949 #undef status_i
4951 #endif
4954 PyDoc_STRVAR(posix_lstat__doc__,
4955 "lstat(path) -> stat result\n\n\
4956 Like stat(path), but do not follow symbolic links.");
4958 static PyObject *
4959 posix_lstat(PyObject *self, PyObject *args)
4961 #ifdef HAVE_LSTAT
4962 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
4963 #else /* !HAVE_LSTAT */
4964 #ifdef MS_WINDOWS
4965 return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", _wstati64);
4966 #else
4967 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
4968 #endif
4969 #endif /* !HAVE_LSTAT */
4973 #ifdef HAVE_READLINK
4974 PyDoc_STRVAR(posix_readlink__doc__,
4975 "readlink(path) -> path\n\n\
4976 Return a string representing the path to which the symbolic link points.");
4978 static PyObject *
4979 posix_readlink(PyObject *self, PyObject *args)
4981 char buf[MAXPATHLEN];
4982 char *path;
4983 int n;
4984 if (!PyArg_ParseTuple(args, "s:readlink", &path))
4985 return NULL;
4986 Py_BEGIN_ALLOW_THREADS
4987 n = readlink(path, buf, (int) sizeof buf);
4988 Py_END_ALLOW_THREADS
4989 if (n < 0)
4990 return posix_error_with_filename(path);
4991 return PyString_FromStringAndSize(buf, n);
4993 #endif /* HAVE_READLINK */
4996 #ifdef HAVE_SYMLINK
4997 PyDoc_STRVAR(posix_symlink__doc__,
4998 "symlink(src, dst)\n\n\
4999 Create a symbolic link pointing to src named dst.");
5001 static PyObject *
5002 posix_symlink(PyObject *self, PyObject *args)
5004 return posix_2str(args, "etet:symlink", symlink, NULL, NULL);
5006 #endif /* HAVE_SYMLINK */
5009 #ifdef HAVE_TIMES
5010 #ifndef HZ
5011 #define HZ 60 /* Universal constant :-) */
5012 #endif /* HZ */
5014 #if defined(PYCC_VACPP) && defined(PYOS_OS2)
5015 static long
5016 system_uptime(void)
5018 ULONG value = 0;
5020 Py_BEGIN_ALLOW_THREADS
5021 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
5022 Py_END_ALLOW_THREADS
5024 return value;
5027 static PyObject *
5028 posix_times(PyObject *self, PyObject *noargs)
5030 /* Currently Only Uptime is Provided -- Others Later */
5031 return Py_BuildValue("ddddd",
5032 (double)0 /* t.tms_utime / HZ */,
5033 (double)0 /* t.tms_stime / HZ */,
5034 (double)0 /* t.tms_cutime / HZ */,
5035 (double)0 /* t.tms_cstime / HZ */,
5036 (double)system_uptime() / 1000);
5038 #else /* not OS2 */
5039 static PyObject *
5040 posix_times(PyObject *self, PyObject *noargs)
5042 struct tms t;
5043 clock_t c;
5044 errno = 0;
5045 c = times(&t);
5046 if (c == (clock_t) -1)
5047 return posix_error();
5048 return Py_BuildValue("ddddd",
5049 (double)t.tms_utime / HZ,
5050 (double)t.tms_stime / HZ,
5051 (double)t.tms_cutime / HZ,
5052 (double)t.tms_cstime / HZ,
5053 (double)c / HZ);
5055 #endif /* not OS2 */
5056 #endif /* HAVE_TIMES */
5059 #ifdef MS_WINDOWS
5060 #define HAVE_TIMES /* so the method table will pick it up */
5061 static PyObject *
5062 posix_times(PyObject *self, PyObject *noargs)
5064 FILETIME create, exit, kernel, user;
5065 HANDLE hProc;
5066 hProc = GetCurrentProcess();
5067 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
5068 /* The fields of a FILETIME structure are the hi and lo part
5069 of a 64-bit value expressed in 100 nanosecond units.
5070 1e7 is one second in such units; 1e-7 the inverse.
5071 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
5073 return Py_BuildValue(
5074 "ddddd",
5075 (double)(kernel.dwHighDateTime*429.4967296 +
5076 kernel.dwLowDateTime*1e-7),
5077 (double)(user.dwHighDateTime*429.4967296 +
5078 user.dwLowDateTime*1e-7),
5079 (double)0,
5080 (double)0,
5081 (double)0);
5083 #endif /* MS_WINDOWS */
5085 #ifdef HAVE_TIMES
5086 PyDoc_STRVAR(posix_times__doc__,
5087 "times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
5088 Return a tuple of floating point numbers indicating process times.");
5089 #endif
5092 #ifdef HAVE_GETSID
5093 PyDoc_STRVAR(posix_getsid__doc__,
5094 "getsid(pid) -> sid\n\n\
5095 Call the system call getsid().");
5097 static PyObject *
5098 posix_getsid(PyObject *self, PyObject *args)
5100 int pid, sid;
5101 if (!PyArg_ParseTuple(args, "i:getsid", &pid))
5102 return NULL;
5103 sid = getsid(pid);
5104 if (sid < 0)
5105 return posix_error();
5106 return PyInt_FromLong((long)sid);
5108 #endif /* HAVE_GETSID */
5111 #ifdef HAVE_SETSID
5112 PyDoc_STRVAR(posix_setsid__doc__,
5113 "setsid()\n\n\
5114 Call the system call setsid().");
5116 static PyObject *
5117 posix_setsid(PyObject *self, PyObject *noargs)
5119 if (setsid() < 0)
5120 return posix_error();
5121 Py_INCREF(Py_None);
5122 return Py_None;
5124 #endif /* HAVE_SETSID */
5126 #ifdef HAVE_SETPGID
5127 PyDoc_STRVAR(posix_setpgid__doc__,
5128 "setpgid(pid, pgrp)\n\n\
5129 Call the system call setpgid().");
5131 static PyObject *
5132 posix_setpgid(PyObject *self, PyObject *args)
5134 int pid, pgrp;
5135 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
5136 return NULL;
5137 if (setpgid(pid, pgrp) < 0)
5138 return posix_error();
5139 Py_INCREF(Py_None);
5140 return Py_None;
5142 #endif /* HAVE_SETPGID */
5145 #ifdef HAVE_TCGETPGRP
5146 PyDoc_STRVAR(posix_tcgetpgrp__doc__,
5147 "tcgetpgrp(fd) -> pgid\n\n\
5148 Return the process group associated with the terminal given by a fd.");
5150 static PyObject *
5151 posix_tcgetpgrp(PyObject *self, PyObject *args)
5153 int fd, pgid;
5154 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
5155 return NULL;
5156 pgid = tcgetpgrp(fd);
5157 if (pgid < 0)
5158 return posix_error();
5159 return PyInt_FromLong((long)pgid);
5161 #endif /* HAVE_TCGETPGRP */
5164 #ifdef HAVE_TCSETPGRP
5165 PyDoc_STRVAR(posix_tcsetpgrp__doc__,
5166 "tcsetpgrp(fd, pgid)\n\n\
5167 Set the process group associated with the terminal given by a fd.");
5169 static PyObject *
5170 posix_tcsetpgrp(PyObject *self, PyObject *args)
5172 int fd, pgid;
5173 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
5174 return NULL;
5175 if (tcsetpgrp(fd, pgid) < 0)
5176 return posix_error();
5177 Py_INCREF(Py_None);
5178 return Py_None;
5180 #endif /* HAVE_TCSETPGRP */
5182 /* Functions acting on file descriptors */
5184 PyDoc_STRVAR(posix_open__doc__,
5185 "open(filename, flag [, mode=0777]) -> fd\n\n\
5186 Open a file (for low level IO).");
5188 static PyObject *
5189 posix_open(PyObject *self, PyObject *args)
5191 char *file = NULL;
5192 int flag;
5193 int mode = 0777;
5194 int fd;
5196 #ifdef MS_WINDOWS
5197 if (unicode_file_names()) {
5198 PyUnicodeObject *po;
5199 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
5200 Py_BEGIN_ALLOW_THREADS
5201 /* PyUnicode_AS_UNICODE OK without thread
5202 lock as it is a simple dereference. */
5203 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
5204 Py_END_ALLOW_THREADS
5205 if (fd < 0)
5206 return posix_error();
5207 return PyInt_FromLong((long)fd);
5209 /* Drop the argument parsing error as narrow strings
5210 are also valid. */
5211 PyErr_Clear();
5213 #endif
5215 if (!PyArg_ParseTuple(args, "eti|i",
5216 Py_FileSystemDefaultEncoding, &file,
5217 &flag, &mode))
5218 return NULL;
5220 Py_BEGIN_ALLOW_THREADS
5221 fd = open(file, flag, mode);
5222 Py_END_ALLOW_THREADS
5223 if (fd < 0)
5224 return posix_error_with_allocated_filename(file);
5225 PyMem_Free(file);
5226 return PyInt_FromLong((long)fd);
5230 PyDoc_STRVAR(posix_close__doc__,
5231 "close(fd)\n\n\
5232 Close a file descriptor (for low level IO).");
5234 static PyObject *
5235 posix_close(PyObject *self, PyObject *args)
5237 int fd, res;
5238 if (!PyArg_ParseTuple(args, "i:close", &fd))
5239 return NULL;
5240 Py_BEGIN_ALLOW_THREADS
5241 res = close(fd);
5242 Py_END_ALLOW_THREADS
5243 if (res < 0)
5244 return posix_error();
5245 Py_INCREF(Py_None);
5246 return Py_None;
5250 PyDoc_STRVAR(posix_dup__doc__,
5251 "dup(fd) -> fd2\n\n\
5252 Return a duplicate of a file descriptor.");
5254 static PyObject *
5255 posix_dup(PyObject *self, PyObject *args)
5257 int fd;
5258 if (!PyArg_ParseTuple(args, "i:dup", &fd))
5259 return NULL;
5260 Py_BEGIN_ALLOW_THREADS
5261 fd = dup(fd);
5262 Py_END_ALLOW_THREADS
5263 if (fd < 0)
5264 return posix_error();
5265 return PyInt_FromLong((long)fd);
5269 PyDoc_STRVAR(posix_dup2__doc__,
5270 "dup2(old_fd, new_fd)\n\n\
5271 Duplicate file descriptor.");
5273 static PyObject *
5274 posix_dup2(PyObject *self, PyObject *args)
5276 int fd, fd2, res;
5277 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
5278 return NULL;
5279 Py_BEGIN_ALLOW_THREADS
5280 res = dup2(fd, fd2);
5281 Py_END_ALLOW_THREADS
5282 if (res < 0)
5283 return posix_error();
5284 Py_INCREF(Py_None);
5285 return Py_None;
5289 PyDoc_STRVAR(posix_lseek__doc__,
5290 "lseek(fd, pos, how) -> newpos\n\n\
5291 Set the current position of a file descriptor.");
5293 static PyObject *
5294 posix_lseek(PyObject *self, PyObject *args)
5296 int fd, how;
5297 #if defined(MS_WIN64) || defined(MS_WINDOWS)
5298 PY_LONG_LONG pos, res;
5299 #else
5300 off_t pos, res;
5301 #endif
5302 PyObject *posobj;
5303 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
5304 return NULL;
5305 #ifdef SEEK_SET
5306 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
5307 switch (how) {
5308 case 0: how = SEEK_SET; break;
5309 case 1: how = SEEK_CUR; break;
5310 case 2: how = SEEK_END; break;
5312 #endif /* SEEK_END */
5314 #if !defined(HAVE_LARGEFILE_SUPPORT)
5315 pos = PyInt_AsLong(posobj);
5316 #else
5317 pos = PyLong_Check(posobj) ?
5318 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
5319 #endif
5320 if (PyErr_Occurred())
5321 return NULL;
5323 Py_BEGIN_ALLOW_THREADS
5324 #if defined(MS_WIN64) || defined(MS_WINDOWS)
5325 res = _lseeki64(fd, pos, how);
5326 #else
5327 res = lseek(fd, pos, how);
5328 #endif
5329 Py_END_ALLOW_THREADS
5330 if (res < 0)
5331 return posix_error();
5333 #if !defined(HAVE_LARGEFILE_SUPPORT)
5334 return PyInt_FromLong(res);
5335 #else
5336 return PyLong_FromLongLong(res);
5337 #endif
5341 PyDoc_STRVAR(posix_read__doc__,
5342 "read(fd, buffersize) -> string\n\n\
5343 Read a file descriptor.");
5345 static PyObject *
5346 posix_read(PyObject *self, PyObject *args)
5348 int fd, size, n;
5349 PyObject *buffer;
5350 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
5351 return NULL;
5352 buffer = PyString_FromStringAndSize((char *)NULL, size);
5353 if (buffer == NULL)
5354 return NULL;
5355 Py_BEGIN_ALLOW_THREADS
5356 n = read(fd, PyString_AsString(buffer), size);
5357 Py_END_ALLOW_THREADS
5358 if (n < 0) {
5359 Py_DECREF(buffer);
5360 return posix_error();
5362 if (n != size)
5363 _PyString_Resize(&buffer, n);
5364 return buffer;
5368 PyDoc_STRVAR(posix_write__doc__,
5369 "write(fd, string) -> byteswritten\n\n\
5370 Write a string to a file descriptor.");
5372 static PyObject *
5373 posix_write(PyObject *self, PyObject *args)
5375 int fd, size;
5376 char *buffer;
5377 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
5378 return NULL;
5379 Py_BEGIN_ALLOW_THREADS
5380 size = write(fd, buffer, size);
5381 Py_END_ALLOW_THREADS
5382 if (size < 0)
5383 return posix_error();
5384 return PyInt_FromLong((long)size);
5388 PyDoc_STRVAR(posix_fstat__doc__,
5389 "fstat(fd) -> stat result\n\n\
5390 Like stat(), but for an open file descriptor.");
5392 static PyObject *
5393 posix_fstat(PyObject *self, PyObject *args)
5395 int fd;
5396 STRUCT_STAT st;
5397 int res;
5398 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
5399 return NULL;
5400 #ifdef __VMS
5401 /* on OpenVMS we must ensure that all bytes are written to the file */
5402 fsync(fd);
5403 #endif
5404 Py_BEGIN_ALLOW_THREADS
5405 res = FSTAT(fd, &st);
5406 Py_END_ALLOW_THREADS
5407 if (res != 0)
5408 return posix_error();
5410 return _pystat_fromstructstat(st);
5414 PyDoc_STRVAR(posix_fdopen__doc__,
5415 "fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
5416 Return an open file object connected to a file descriptor.");
5418 static PyObject *
5419 posix_fdopen(PyObject *self, PyObject *args)
5421 int fd;
5422 char *mode = "r";
5423 int bufsize = -1;
5424 FILE *fp;
5425 PyObject *f;
5426 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
5427 return NULL;
5429 if (mode[0] != 'r' && mode[0] != 'w' && mode[0] != 'a') {
5430 PyErr_Format(PyExc_ValueError,
5431 "invalid file mode '%s'", mode);
5432 return NULL;
5435 Py_BEGIN_ALLOW_THREADS
5436 fp = fdopen(fd, mode);
5437 Py_END_ALLOW_THREADS
5438 if (fp == NULL)
5439 return posix_error();
5440 f = PyFile_FromFile(fp, "<fdopen>", mode, fclose);
5441 if (f != NULL)
5442 PyFile_SetBufSize(f, bufsize);
5443 return f;
5446 PyDoc_STRVAR(posix_isatty__doc__,
5447 "isatty(fd) -> bool\n\n\
5448 Return True if the file descriptor 'fd' is an open file descriptor\n\
5449 connected to the slave end of a terminal.");
5451 static PyObject *
5452 posix_isatty(PyObject *self, PyObject *args)
5454 int fd;
5455 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
5456 return NULL;
5457 return PyBool_FromLong(isatty(fd));
5460 #ifdef HAVE_PIPE
5461 PyDoc_STRVAR(posix_pipe__doc__,
5462 "pipe() -> (read_end, write_end)\n\n\
5463 Create a pipe.");
5465 static PyObject *
5466 posix_pipe(PyObject *self, PyObject *noargs)
5468 #if defined(PYOS_OS2)
5469 HFILE read, write;
5470 APIRET rc;
5472 Py_BEGIN_ALLOW_THREADS
5473 rc = DosCreatePipe( &read, &write, 4096);
5474 Py_END_ALLOW_THREADS
5475 if (rc != NO_ERROR)
5476 return os2_error(rc);
5478 return Py_BuildValue("(ii)", read, write);
5479 #else
5480 #if !defined(MS_WINDOWS)
5481 int fds[2];
5482 int res;
5483 Py_BEGIN_ALLOW_THREADS
5484 res = pipe(fds);
5485 Py_END_ALLOW_THREADS
5486 if (res != 0)
5487 return posix_error();
5488 return Py_BuildValue("(ii)", fds[0], fds[1]);
5489 #else /* MS_WINDOWS */
5490 HANDLE read, write;
5491 int read_fd, write_fd;
5492 BOOL ok;
5493 Py_BEGIN_ALLOW_THREADS
5494 ok = CreatePipe(&read, &write, NULL, 0);
5495 Py_END_ALLOW_THREADS
5496 if (!ok)
5497 return win32_error("CreatePipe", NULL);
5498 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
5499 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
5500 return Py_BuildValue("(ii)", read_fd, write_fd);
5501 #endif /* MS_WINDOWS */
5502 #endif
5504 #endif /* HAVE_PIPE */
5507 #ifdef HAVE_MKFIFO
5508 PyDoc_STRVAR(posix_mkfifo__doc__,
5509 "mkfifo(filename [, mode=0666])\n\n\
5510 Create a FIFO (a POSIX named pipe).");
5512 static PyObject *
5513 posix_mkfifo(PyObject *self, PyObject *args)
5515 char *filename;
5516 int mode = 0666;
5517 int res;
5518 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
5519 return NULL;
5520 Py_BEGIN_ALLOW_THREADS
5521 res = mkfifo(filename, mode);
5522 Py_END_ALLOW_THREADS
5523 if (res < 0)
5524 return posix_error();
5525 Py_INCREF(Py_None);
5526 return Py_None;
5528 #endif
5531 #if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
5532 PyDoc_STRVAR(posix_mknod__doc__,
5533 "mknod(filename [, mode=0600, device])\n\n\
5534 Create a filesystem node (file, device special file or named pipe)\n\
5535 named filename. mode specifies both the permissions to use and the\n\
5536 type of node to be created, being combined (bitwise OR) with one of\n\
5537 S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
5538 device defines the newly created device special file (probably using\n\
5539 os.makedev()), otherwise it is ignored.");
5542 static PyObject *
5543 posix_mknod(PyObject *self, PyObject *args)
5545 char *filename;
5546 int mode = 0600;
5547 int device = 0;
5548 int res;
5549 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
5550 return NULL;
5551 Py_BEGIN_ALLOW_THREADS
5552 res = mknod(filename, mode, device);
5553 Py_END_ALLOW_THREADS
5554 if (res < 0)
5555 return posix_error();
5556 Py_INCREF(Py_None);
5557 return Py_None;
5559 #endif
5561 #ifdef HAVE_DEVICE_MACROS
5562 PyDoc_STRVAR(posix_major__doc__,
5563 "major(device) -> major number\n\
5564 Extracts a device major number from a raw device number.");
5566 static PyObject *
5567 posix_major(PyObject *self, PyObject *args)
5569 int device;
5570 if (!PyArg_ParseTuple(args, "i:major", &device))
5571 return NULL;
5572 return PyInt_FromLong((long)major(device));
5575 PyDoc_STRVAR(posix_minor__doc__,
5576 "minor(device) -> minor number\n\
5577 Extracts a device minor number from a raw device number.");
5579 static PyObject *
5580 posix_minor(PyObject *self, PyObject *args)
5582 int device;
5583 if (!PyArg_ParseTuple(args, "i:minor", &device))
5584 return NULL;
5585 return PyInt_FromLong((long)minor(device));
5588 PyDoc_STRVAR(posix_makedev__doc__,
5589 "makedev(major, minor) -> device number\n\
5590 Composes a raw device number from the major and minor device numbers.");
5592 static PyObject *
5593 posix_makedev(PyObject *self, PyObject *args)
5595 int major, minor;
5596 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
5597 return NULL;
5598 return PyInt_FromLong((long)makedev(major, minor));
5600 #endif /* device macros */
5603 #ifdef HAVE_FTRUNCATE
5604 PyDoc_STRVAR(posix_ftruncate__doc__,
5605 "ftruncate(fd, length)\n\n\
5606 Truncate a file to a specified length.");
5608 static PyObject *
5609 posix_ftruncate(PyObject *self, PyObject *args)
5611 int fd;
5612 off_t length;
5613 int res;
5614 PyObject *lenobj;
5616 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
5617 return NULL;
5619 #if !defined(HAVE_LARGEFILE_SUPPORT)
5620 length = PyInt_AsLong(lenobj);
5621 #else
5622 length = PyLong_Check(lenobj) ?
5623 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
5624 #endif
5625 if (PyErr_Occurred())
5626 return NULL;
5628 Py_BEGIN_ALLOW_THREADS
5629 res = ftruncate(fd, length);
5630 Py_END_ALLOW_THREADS
5631 if (res < 0) {
5632 PyErr_SetFromErrno(PyExc_IOError);
5633 return NULL;
5635 Py_INCREF(Py_None);
5636 return Py_None;
5638 #endif
5640 #ifdef HAVE_PUTENV
5641 PyDoc_STRVAR(posix_putenv__doc__,
5642 "putenv(key, value)\n\n\
5643 Change or add an environment variable.");
5645 /* Save putenv() parameters as values here, so we can collect them when they
5646 * get re-set with another call for the same key. */
5647 static PyObject *posix_putenv_garbage;
5649 static PyObject *
5650 posix_putenv(PyObject *self, PyObject *args)
5652 char *s1, *s2;
5653 char *new;
5654 PyObject *newstr;
5655 size_t len;
5657 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
5658 return NULL;
5660 #if defined(PYOS_OS2)
5661 if (stricmp(s1, "BEGINLIBPATH") == 0) {
5662 APIRET rc;
5664 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
5665 if (rc != NO_ERROR)
5666 return os2_error(rc);
5668 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
5669 APIRET rc;
5671 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
5672 if (rc != NO_ERROR)
5673 return os2_error(rc);
5674 } else {
5675 #endif
5677 /* XXX This can leak memory -- not easy to fix :-( */
5678 len = strlen(s1) + strlen(s2) + 2;
5679 /* len includes space for a trailing \0; the size arg to
5680 PyString_FromStringAndSize does not count that */
5681 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
5682 if (newstr == NULL)
5683 return PyErr_NoMemory();
5684 new = PyString_AS_STRING(newstr);
5685 PyOS_snprintf(new, len, "%s=%s", s1, s2);
5686 if (putenv(new)) {
5687 Py_DECREF(newstr);
5688 posix_error();
5689 return NULL;
5691 /* Install the first arg and newstr in posix_putenv_garbage;
5692 * this will cause previous value to be collected. This has to
5693 * happen after the real putenv() call because the old value
5694 * was still accessible until then. */
5695 if (PyDict_SetItem(posix_putenv_garbage,
5696 PyTuple_GET_ITEM(args, 0), newstr)) {
5697 /* really not much we can do; just leak */
5698 PyErr_Clear();
5700 else {
5701 Py_DECREF(newstr);
5704 #if defined(PYOS_OS2)
5706 #endif
5707 Py_INCREF(Py_None);
5708 return Py_None;
5710 #endif /* putenv */
5712 #ifdef HAVE_UNSETENV
5713 PyDoc_STRVAR(posix_unsetenv__doc__,
5714 "unsetenv(key)\n\n\
5715 Delete an environment variable.");
5717 static PyObject *
5718 posix_unsetenv(PyObject *self, PyObject *args)
5720 char *s1;
5722 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
5723 return NULL;
5725 unsetenv(s1);
5727 /* Remove the key from posix_putenv_garbage;
5728 * this will cause it to be collected. This has to
5729 * happen after the real unsetenv() call because the
5730 * old value was still accessible until then.
5732 if (PyDict_DelItem(posix_putenv_garbage,
5733 PyTuple_GET_ITEM(args, 0))) {
5734 /* really not much we can do; just leak */
5735 PyErr_Clear();
5738 Py_INCREF(Py_None);
5739 return Py_None;
5741 #endif /* unsetenv */
5743 #ifdef HAVE_STRERROR
5744 PyDoc_STRVAR(posix_strerror__doc__,
5745 "strerror(code) -> string\n\n\
5746 Translate an error code to a message string.");
5748 static PyObject *
5749 posix_strerror(PyObject *self, PyObject *args)
5751 int code;
5752 char *message;
5753 if (!PyArg_ParseTuple(args, "i:strerror", &code))
5754 return NULL;
5755 message = strerror(code);
5756 if (message == NULL) {
5757 PyErr_SetString(PyExc_ValueError,
5758 "strerror() argument out of range");
5759 return NULL;
5761 return PyString_FromString(message);
5763 #endif /* strerror */
5766 #ifdef HAVE_SYS_WAIT_H
5768 #ifdef WCOREDUMP
5769 PyDoc_STRVAR(posix_WCOREDUMP__doc__,
5770 "WCOREDUMP(status) -> bool\n\n\
5771 Return True if the process returning 'status' was dumped to a core file.");
5773 static PyObject *
5774 posix_WCOREDUMP(PyObject *self, PyObject *args)
5776 #ifdef UNION_WAIT
5777 union wait status;
5778 #define status_i (status.w_status)
5779 #else
5780 int status;
5781 #define status_i status
5782 #endif
5783 status_i = 0;
5785 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &status_i))
5787 return NULL;
5790 return PyBool_FromLong(WCOREDUMP(status));
5791 #undef status_i
5793 #endif /* WCOREDUMP */
5795 #ifdef WIFCONTINUED
5796 PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
5797 "WIFCONTINUED(status) -> bool\n\n\
5798 Return True if the process returning 'status' was continued from a\n\
5799 job control stop.");
5801 static PyObject *
5802 posix_WIFCONTINUED(PyObject *self, PyObject *args)
5804 #ifdef UNION_WAIT
5805 union wait status;
5806 #define status_i (status.w_status)
5807 #else
5808 int status;
5809 #define status_i status
5810 #endif
5811 status_i = 0;
5813 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &status_i))
5815 return NULL;
5818 return PyBool_FromLong(WIFCONTINUED(status));
5819 #undef status_i
5821 #endif /* WIFCONTINUED */
5823 #ifdef WIFSTOPPED
5824 PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
5825 "WIFSTOPPED(status) -> bool\n\n\
5826 Return True if the process returning 'status' was stopped.");
5828 static PyObject *
5829 posix_WIFSTOPPED(PyObject *self, PyObject *args)
5831 #ifdef UNION_WAIT
5832 union wait status;
5833 #define status_i (status.w_status)
5834 #else
5835 int status;
5836 #define status_i status
5837 #endif
5838 status_i = 0;
5840 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
5842 return NULL;
5845 return PyBool_FromLong(WIFSTOPPED(status));
5846 #undef status_i
5848 #endif /* WIFSTOPPED */
5850 #ifdef WIFSIGNALED
5851 PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
5852 "WIFSIGNALED(status) -> bool\n\n\
5853 Return True if the process returning 'status' was terminated by a signal.");
5855 static PyObject *
5856 posix_WIFSIGNALED(PyObject *self, PyObject *args)
5858 #ifdef UNION_WAIT
5859 union wait status;
5860 #define status_i (status.w_status)
5861 #else
5862 int status;
5863 #define status_i status
5864 #endif
5865 status_i = 0;
5867 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
5869 return NULL;
5872 return PyBool_FromLong(WIFSIGNALED(status));
5873 #undef status_i
5875 #endif /* WIFSIGNALED */
5877 #ifdef WIFEXITED
5878 PyDoc_STRVAR(posix_WIFEXITED__doc__,
5879 "WIFEXITED(status) -> bool\n\n\
5880 Return true if the process returning 'status' exited using the exit()\n\
5881 system call.");
5883 static PyObject *
5884 posix_WIFEXITED(PyObject *self, PyObject *args)
5886 #ifdef UNION_WAIT
5887 union wait status;
5888 #define status_i (status.w_status)
5889 #else
5890 int status;
5891 #define status_i status
5892 #endif
5893 status_i = 0;
5895 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
5897 return NULL;
5900 return PyBool_FromLong(WIFEXITED(status));
5901 #undef status_i
5903 #endif /* WIFEXITED */
5905 #ifdef WEXITSTATUS
5906 PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
5907 "WEXITSTATUS(status) -> integer\n\n\
5908 Return the process return code from 'status'.");
5910 static PyObject *
5911 posix_WEXITSTATUS(PyObject *self, PyObject *args)
5913 #ifdef UNION_WAIT
5914 union wait status;
5915 #define status_i (status.w_status)
5916 #else
5917 int status;
5918 #define status_i status
5919 #endif
5920 status_i = 0;
5922 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
5924 return NULL;
5927 return Py_BuildValue("i", WEXITSTATUS(status));
5928 #undef status_i
5930 #endif /* WEXITSTATUS */
5932 #ifdef WTERMSIG
5933 PyDoc_STRVAR(posix_WTERMSIG__doc__,
5934 "WTERMSIG(status) -> integer\n\n\
5935 Return the signal that terminated the process that provided the 'status'\n\
5936 value.");
5938 static PyObject *
5939 posix_WTERMSIG(PyObject *self, PyObject *args)
5941 #ifdef UNION_WAIT
5942 union wait status;
5943 #define status_i (status.w_status)
5944 #else
5945 int status;
5946 #define status_i status
5947 #endif
5948 status_i = 0;
5950 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
5952 return NULL;
5955 return Py_BuildValue("i", WTERMSIG(status));
5956 #undef status_i
5958 #endif /* WTERMSIG */
5960 #ifdef WSTOPSIG
5961 PyDoc_STRVAR(posix_WSTOPSIG__doc__,
5962 "WSTOPSIG(status) -> integer\n\n\
5963 Return the signal that stopped the process that provided\n\
5964 the 'status' value.");
5966 static PyObject *
5967 posix_WSTOPSIG(PyObject *self, PyObject *args)
5969 #ifdef UNION_WAIT
5970 union wait status;
5971 #define status_i (status.w_status)
5972 #else
5973 int status;
5974 #define status_i status
5975 #endif
5976 status_i = 0;
5978 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
5980 return NULL;
5983 return Py_BuildValue("i", WSTOPSIG(status));
5984 #undef status_i
5986 #endif /* WSTOPSIG */
5988 #endif /* HAVE_SYS_WAIT_H */
5991 #if defined(HAVE_FSTATVFS)
5992 #ifdef _SCO_DS
5993 /* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
5994 needed definitions in sys/statvfs.h */
5995 #define _SVID3
5996 #endif
5997 #include <sys/statvfs.h>
5999 static PyObject*
6000 _pystatvfs_fromstructstatvfs(struct statvfs st) {
6001 PyObject *v = PyStructSequence_New(&StatVFSResultType);
6002 if (v == NULL)
6003 return NULL;
6005 #if !defined(HAVE_LARGEFILE_SUPPORT)
6006 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6007 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
6008 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
6009 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
6010 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
6011 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
6012 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
6013 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
6014 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6015 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6016 #else
6017 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6018 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
6019 PyStructSequence_SET_ITEM(v, 2,
6020 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
6021 PyStructSequence_SET_ITEM(v, 3,
6022 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
6023 PyStructSequence_SET_ITEM(v, 4,
6024 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
6025 PyStructSequence_SET_ITEM(v, 5,
6026 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
6027 PyStructSequence_SET_ITEM(v, 6,
6028 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
6029 PyStructSequence_SET_ITEM(v, 7,
6030 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
6031 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6032 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6033 #endif
6035 return v;
6038 PyDoc_STRVAR(posix_fstatvfs__doc__,
6039 "fstatvfs(fd) -> statvfs result\n\n\
6040 Perform an fstatvfs system call on the given fd.");
6042 static PyObject *
6043 posix_fstatvfs(PyObject *self, PyObject *args)
6045 int fd, res;
6046 struct statvfs st;
6048 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
6049 return NULL;
6050 Py_BEGIN_ALLOW_THREADS
6051 res = fstatvfs(fd, &st);
6052 Py_END_ALLOW_THREADS
6053 if (res != 0)
6054 return posix_error();
6056 return _pystatvfs_fromstructstatvfs(st);
6058 #endif /* HAVE_FSTATVFS */
6061 #if defined(HAVE_STATVFS)
6062 #include <sys/statvfs.h>
6064 PyDoc_STRVAR(posix_statvfs__doc__,
6065 "statvfs(path) -> statvfs result\n\n\
6066 Perform a statvfs system call on the given path.");
6068 static PyObject *
6069 posix_statvfs(PyObject *self, PyObject *args)
6071 char *path;
6072 int res;
6073 struct statvfs st;
6074 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
6075 return NULL;
6076 Py_BEGIN_ALLOW_THREADS
6077 res = statvfs(path, &st);
6078 Py_END_ALLOW_THREADS
6079 if (res != 0)
6080 return posix_error_with_filename(path);
6082 return _pystatvfs_fromstructstatvfs(st);
6084 #endif /* HAVE_STATVFS */
6087 #ifdef HAVE_TEMPNAM
6088 PyDoc_STRVAR(posix_tempnam__doc__,
6089 "tempnam([dir[, prefix]]) -> string\n\n\
6090 Return a unique name for a temporary file.\n\
6091 The directory and a prefix may be specified as strings; they may be omitted\n\
6092 or None if not needed.");
6094 static PyObject *
6095 posix_tempnam(PyObject *self, PyObject *args)
6097 PyObject *result = NULL;
6098 char *dir = NULL;
6099 char *pfx = NULL;
6100 char *name;
6102 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
6103 return NULL;
6105 if (PyErr_Warn(PyExc_RuntimeWarning,
6106 "tempnam is a potential security risk to your program") < 0)
6107 return NULL;
6109 #ifdef MS_WINDOWS
6110 name = _tempnam(dir, pfx);
6111 #else
6112 name = tempnam(dir, pfx);
6113 #endif
6114 if (name == NULL)
6115 return PyErr_NoMemory();
6116 result = PyString_FromString(name);
6117 free(name);
6118 return result;
6120 #endif
6123 #ifdef HAVE_TMPFILE
6124 PyDoc_STRVAR(posix_tmpfile__doc__,
6125 "tmpfile() -> file object\n\n\
6126 Create a temporary file with no directory entries.");
6128 static PyObject *
6129 posix_tmpfile(PyObject *self, PyObject *noargs)
6131 FILE *fp;
6133 fp = tmpfile();
6134 if (fp == NULL)
6135 return posix_error();
6136 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
6138 #endif
6141 #ifdef HAVE_TMPNAM
6142 PyDoc_STRVAR(posix_tmpnam__doc__,
6143 "tmpnam() -> string\n\n\
6144 Return a unique name for a temporary file.");
6146 static PyObject *
6147 posix_tmpnam(PyObject *self, PyObject *noargs)
6149 char buffer[L_tmpnam];
6150 char *name;
6152 if (PyErr_Warn(PyExc_RuntimeWarning,
6153 "tmpnam is a potential security risk to your program") < 0)
6154 return NULL;
6156 #ifdef USE_TMPNAM_R
6157 name = tmpnam_r(buffer);
6158 #else
6159 name = tmpnam(buffer);
6160 #endif
6161 if (name == NULL) {
6162 PyErr_SetObject(PyExc_OSError,
6163 Py_BuildValue("is", 0,
6164 #ifdef USE_TMPNAM_R
6165 "unexpected NULL from tmpnam_r"
6166 #else
6167 "unexpected NULL from tmpnam"
6168 #endif
6170 return NULL;
6172 return PyString_FromString(buffer);
6174 #endif
6177 /* This is used for fpathconf(), pathconf(), confstr() and sysconf().
6178 * It maps strings representing configuration variable names to
6179 * integer values, allowing those functions to be called with the
6180 * magic names instead of polluting the module's namespace with tons of
6181 * rarely-used constants. There are three separate tables that use
6182 * these definitions.
6184 * This code is always included, even if none of the interfaces that
6185 * need it are included. The #if hackery needed to avoid it would be
6186 * sufficiently pervasive that it's not worth the loss of readability.
6188 struct constdef {
6189 char *name;
6190 long value;
6193 static int
6194 conv_confname(PyObject *arg, int *valuep, struct constdef *table,
6195 size_t tablesize)
6197 if (PyInt_Check(arg)) {
6198 *valuep = PyInt_AS_LONG(arg);
6199 return 1;
6201 if (PyString_Check(arg)) {
6202 /* look up the value in the table using a binary search */
6203 size_t lo = 0;
6204 size_t mid;
6205 size_t hi = tablesize;
6206 int cmp;
6207 char *confname = PyString_AS_STRING(arg);
6208 while (lo < hi) {
6209 mid = (lo + hi) / 2;
6210 cmp = strcmp(confname, table[mid].name);
6211 if (cmp < 0)
6212 hi = mid;
6213 else if (cmp > 0)
6214 lo = mid + 1;
6215 else {
6216 *valuep = table[mid].value;
6217 return 1;
6220 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
6222 else
6223 PyErr_SetString(PyExc_TypeError,
6224 "configuration names must be strings or integers");
6225 return 0;
6229 #if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
6230 static struct constdef posix_constants_pathconf[] = {
6231 #ifdef _PC_ABI_AIO_XFER_MAX
6232 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
6233 #endif
6234 #ifdef _PC_ABI_ASYNC_IO
6235 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
6236 #endif
6237 #ifdef _PC_ASYNC_IO
6238 {"PC_ASYNC_IO", _PC_ASYNC_IO},
6239 #endif
6240 #ifdef _PC_CHOWN_RESTRICTED
6241 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
6242 #endif
6243 #ifdef _PC_FILESIZEBITS
6244 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
6245 #endif
6246 #ifdef _PC_LAST
6247 {"PC_LAST", _PC_LAST},
6248 #endif
6249 #ifdef _PC_LINK_MAX
6250 {"PC_LINK_MAX", _PC_LINK_MAX},
6251 #endif
6252 #ifdef _PC_MAX_CANON
6253 {"PC_MAX_CANON", _PC_MAX_CANON},
6254 #endif
6255 #ifdef _PC_MAX_INPUT
6256 {"PC_MAX_INPUT", _PC_MAX_INPUT},
6257 #endif
6258 #ifdef _PC_NAME_MAX
6259 {"PC_NAME_MAX", _PC_NAME_MAX},
6260 #endif
6261 #ifdef _PC_NO_TRUNC
6262 {"PC_NO_TRUNC", _PC_NO_TRUNC},
6263 #endif
6264 #ifdef _PC_PATH_MAX
6265 {"PC_PATH_MAX", _PC_PATH_MAX},
6266 #endif
6267 #ifdef _PC_PIPE_BUF
6268 {"PC_PIPE_BUF", _PC_PIPE_BUF},
6269 #endif
6270 #ifdef _PC_PRIO_IO
6271 {"PC_PRIO_IO", _PC_PRIO_IO},
6272 #endif
6273 #ifdef _PC_SOCK_MAXBUF
6274 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
6275 #endif
6276 #ifdef _PC_SYNC_IO
6277 {"PC_SYNC_IO", _PC_SYNC_IO},
6278 #endif
6279 #ifdef _PC_VDISABLE
6280 {"PC_VDISABLE", _PC_VDISABLE},
6281 #endif
6284 static int
6285 conv_path_confname(PyObject *arg, int *valuep)
6287 return conv_confname(arg, valuep, posix_constants_pathconf,
6288 sizeof(posix_constants_pathconf)
6289 / sizeof(struct constdef));
6291 #endif
6293 #ifdef HAVE_FPATHCONF
6294 PyDoc_STRVAR(posix_fpathconf__doc__,
6295 "fpathconf(fd, name) -> integer\n\n\
6296 Return the configuration limit name for the file descriptor fd.\n\
6297 If there is no limit, return -1.");
6299 static PyObject *
6300 posix_fpathconf(PyObject *self, PyObject *args)
6302 PyObject *result = NULL;
6303 int name, fd;
6305 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
6306 conv_path_confname, &name)) {
6307 long limit;
6309 errno = 0;
6310 limit = fpathconf(fd, name);
6311 if (limit == -1 && errno != 0)
6312 posix_error();
6313 else
6314 result = PyInt_FromLong(limit);
6316 return result;
6318 #endif
6321 #ifdef HAVE_PATHCONF
6322 PyDoc_STRVAR(posix_pathconf__doc__,
6323 "pathconf(path, name) -> integer\n\n\
6324 Return the configuration limit name for the file or directory path.\n\
6325 If there is no limit, return -1.");
6327 static PyObject *
6328 posix_pathconf(PyObject *self, PyObject *args)
6330 PyObject *result = NULL;
6331 int name;
6332 char *path;
6334 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
6335 conv_path_confname, &name)) {
6336 long limit;
6338 errno = 0;
6339 limit = pathconf(path, name);
6340 if (limit == -1 && errno != 0) {
6341 if (errno == EINVAL)
6342 /* could be a path or name problem */
6343 posix_error();
6344 else
6345 posix_error_with_filename(path);
6347 else
6348 result = PyInt_FromLong(limit);
6350 return result;
6352 #endif
6354 #ifdef HAVE_CONFSTR
6355 static struct constdef posix_constants_confstr[] = {
6356 #ifdef _CS_ARCHITECTURE
6357 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
6358 #endif
6359 #ifdef _CS_HOSTNAME
6360 {"CS_HOSTNAME", _CS_HOSTNAME},
6361 #endif
6362 #ifdef _CS_HW_PROVIDER
6363 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
6364 #endif
6365 #ifdef _CS_HW_SERIAL
6366 {"CS_HW_SERIAL", _CS_HW_SERIAL},
6367 #endif
6368 #ifdef _CS_INITTAB_NAME
6369 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
6370 #endif
6371 #ifdef _CS_LFS64_CFLAGS
6372 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
6373 #endif
6374 #ifdef _CS_LFS64_LDFLAGS
6375 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
6376 #endif
6377 #ifdef _CS_LFS64_LIBS
6378 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
6379 #endif
6380 #ifdef _CS_LFS64_LINTFLAGS
6381 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
6382 #endif
6383 #ifdef _CS_LFS_CFLAGS
6384 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
6385 #endif
6386 #ifdef _CS_LFS_LDFLAGS
6387 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
6388 #endif
6389 #ifdef _CS_LFS_LIBS
6390 {"CS_LFS_LIBS", _CS_LFS_LIBS},
6391 #endif
6392 #ifdef _CS_LFS_LINTFLAGS
6393 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
6394 #endif
6395 #ifdef _CS_MACHINE
6396 {"CS_MACHINE", _CS_MACHINE},
6397 #endif
6398 #ifdef _CS_PATH
6399 {"CS_PATH", _CS_PATH},
6400 #endif
6401 #ifdef _CS_RELEASE
6402 {"CS_RELEASE", _CS_RELEASE},
6403 #endif
6404 #ifdef _CS_SRPC_DOMAIN
6405 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
6406 #endif
6407 #ifdef _CS_SYSNAME
6408 {"CS_SYSNAME", _CS_SYSNAME},
6409 #endif
6410 #ifdef _CS_VERSION
6411 {"CS_VERSION", _CS_VERSION},
6412 #endif
6413 #ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
6414 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
6415 #endif
6416 #ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
6417 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
6418 #endif
6419 #ifdef _CS_XBS5_ILP32_OFF32_LIBS
6420 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
6421 #endif
6422 #ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
6423 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
6424 #endif
6425 #ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
6426 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
6427 #endif
6428 #ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
6429 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
6430 #endif
6431 #ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
6432 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
6433 #endif
6434 #ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
6435 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
6436 #endif
6437 #ifdef _CS_XBS5_LP64_OFF64_CFLAGS
6438 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
6439 #endif
6440 #ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
6441 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
6442 #endif
6443 #ifdef _CS_XBS5_LP64_OFF64_LIBS
6444 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
6445 #endif
6446 #ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
6447 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
6448 #endif
6449 #ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
6450 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
6451 #endif
6452 #ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
6453 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
6454 #endif
6455 #ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
6456 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
6457 #endif
6458 #ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
6459 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
6460 #endif
6461 #ifdef _MIPS_CS_AVAIL_PROCESSORS
6462 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
6463 #endif
6464 #ifdef _MIPS_CS_BASE
6465 {"MIPS_CS_BASE", _MIPS_CS_BASE},
6466 #endif
6467 #ifdef _MIPS_CS_HOSTID
6468 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
6469 #endif
6470 #ifdef _MIPS_CS_HW_NAME
6471 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
6472 #endif
6473 #ifdef _MIPS_CS_NUM_PROCESSORS
6474 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
6475 #endif
6476 #ifdef _MIPS_CS_OSREL_MAJ
6477 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
6478 #endif
6479 #ifdef _MIPS_CS_OSREL_MIN
6480 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
6481 #endif
6482 #ifdef _MIPS_CS_OSREL_PATCH
6483 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
6484 #endif
6485 #ifdef _MIPS_CS_OS_NAME
6486 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
6487 #endif
6488 #ifdef _MIPS_CS_OS_PROVIDER
6489 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
6490 #endif
6491 #ifdef _MIPS_CS_PROCESSORS
6492 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
6493 #endif
6494 #ifdef _MIPS_CS_SERIAL
6495 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
6496 #endif
6497 #ifdef _MIPS_CS_VENDOR
6498 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
6499 #endif
6502 static int
6503 conv_confstr_confname(PyObject *arg, int *valuep)
6505 return conv_confname(arg, valuep, posix_constants_confstr,
6506 sizeof(posix_constants_confstr)
6507 / sizeof(struct constdef));
6510 PyDoc_STRVAR(posix_confstr__doc__,
6511 "confstr(name) -> string\n\n\
6512 Return a string-valued system configuration variable.");
6514 static PyObject *
6515 posix_confstr(PyObject *self, PyObject *args)
6517 PyObject *result = NULL;
6518 int name;
6519 char buffer[64];
6521 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
6522 int len = confstr(name, buffer, sizeof(buffer));
6524 errno = 0;
6525 if (len == 0) {
6526 if (errno != 0)
6527 posix_error();
6528 else
6529 result = PyString_FromString("");
6531 else {
6532 if (len >= sizeof(buffer)) {
6533 result = PyString_FromStringAndSize(NULL, len);
6534 if (result != NULL)
6535 confstr(name, PyString_AS_STRING(result), len+1);
6537 else
6538 result = PyString_FromString(buffer);
6541 return result;
6543 #endif
6546 #ifdef HAVE_SYSCONF
6547 static struct constdef posix_constants_sysconf[] = {
6548 #ifdef _SC_2_CHAR_TERM
6549 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
6550 #endif
6551 #ifdef _SC_2_C_BIND
6552 {"SC_2_C_BIND", _SC_2_C_BIND},
6553 #endif
6554 #ifdef _SC_2_C_DEV
6555 {"SC_2_C_DEV", _SC_2_C_DEV},
6556 #endif
6557 #ifdef _SC_2_C_VERSION
6558 {"SC_2_C_VERSION", _SC_2_C_VERSION},
6559 #endif
6560 #ifdef _SC_2_FORT_DEV
6561 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
6562 #endif
6563 #ifdef _SC_2_FORT_RUN
6564 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
6565 #endif
6566 #ifdef _SC_2_LOCALEDEF
6567 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
6568 #endif
6569 #ifdef _SC_2_SW_DEV
6570 {"SC_2_SW_DEV", _SC_2_SW_DEV},
6571 #endif
6572 #ifdef _SC_2_UPE
6573 {"SC_2_UPE", _SC_2_UPE},
6574 #endif
6575 #ifdef _SC_2_VERSION
6576 {"SC_2_VERSION", _SC_2_VERSION},
6577 #endif
6578 #ifdef _SC_ABI_ASYNCHRONOUS_IO
6579 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
6580 #endif
6581 #ifdef _SC_ACL
6582 {"SC_ACL", _SC_ACL},
6583 #endif
6584 #ifdef _SC_AIO_LISTIO_MAX
6585 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
6586 #endif
6587 #ifdef _SC_AIO_MAX
6588 {"SC_AIO_MAX", _SC_AIO_MAX},
6589 #endif
6590 #ifdef _SC_AIO_PRIO_DELTA_MAX
6591 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
6592 #endif
6593 #ifdef _SC_ARG_MAX
6594 {"SC_ARG_MAX", _SC_ARG_MAX},
6595 #endif
6596 #ifdef _SC_ASYNCHRONOUS_IO
6597 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
6598 #endif
6599 #ifdef _SC_ATEXIT_MAX
6600 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
6601 #endif
6602 #ifdef _SC_AUDIT
6603 {"SC_AUDIT", _SC_AUDIT},
6604 #endif
6605 #ifdef _SC_AVPHYS_PAGES
6606 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
6607 #endif
6608 #ifdef _SC_BC_BASE_MAX
6609 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
6610 #endif
6611 #ifdef _SC_BC_DIM_MAX
6612 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
6613 #endif
6614 #ifdef _SC_BC_SCALE_MAX
6615 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
6616 #endif
6617 #ifdef _SC_BC_STRING_MAX
6618 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
6619 #endif
6620 #ifdef _SC_CAP
6621 {"SC_CAP", _SC_CAP},
6622 #endif
6623 #ifdef _SC_CHARCLASS_NAME_MAX
6624 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
6625 #endif
6626 #ifdef _SC_CHAR_BIT
6627 {"SC_CHAR_BIT", _SC_CHAR_BIT},
6628 #endif
6629 #ifdef _SC_CHAR_MAX
6630 {"SC_CHAR_MAX", _SC_CHAR_MAX},
6631 #endif
6632 #ifdef _SC_CHAR_MIN
6633 {"SC_CHAR_MIN", _SC_CHAR_MIN},
6634 #endif
6635 #ifdef _SC_CHILD_MAX
6636 {"SC_CHILD_MAX", _SC_CHILD_MAX},
6637 #endif
6638 #ifdef _SC_CLK_TCK
6639 {"SC_CLK_TCK", _SC_CLK_TCK},
6640 #endif
6641 #ifdef _SC_COHER_BLKSZ
6642 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
6643 #endif
6644 #ifdef _SC_COLL_WEIGHTS_MAX
6645 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
6646 #endif
6647 #ifdef _SC_DCACHE_ASSOC
6648 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
6649 #endif
6650 #ifdef _SC_DCACHE_BLKSZ
6651 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
6652 #endif
6653 #ifdef _SC_DCACHE_LINESZ
6654 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
6655 #endif
6656 #ifdef _SC_DCACHE_SZ
6657 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
6658 #endif
6659 #ifdef _SC_DCACHE_TBLKSZ
6660 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
6661 #endif
6662 #ifdef _SC_DELAYTIMER_MAX
6663 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
6664 #endif
6665 #ifdef _SC_EQUIV_CLASS_MAX
6666 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
6667 #endif
6668 #ifdef _SC_EXPR_NEST_MAX
6669 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
6670 #endif
6671 #ifdef _SC_FSYNC
6672 {"SC_FSYNC", _SC_FSYNC},
6673 #endif
6674 #ifdef _SC_GETGR_R_SIZE_MAX
6675 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
6676 #endif
6677 #ifdef _SC_GETPW_R_SIZE_MAX
6678 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
6679 #endif
6680 #ifdef _SC_ICACHE_ASSOC
6681 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
6682 #endif
6683 #ifdef _SC_ICACHE_BLKSZ
6684 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
6685 #endif
6686 #ifdef _SC_ICACHE_LINESZ
6687 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
6688 #endif
6689 #ifdef _SC_ICACHE_SZ
6690 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
6691 #endif
6692 #ifdef _SC_INF
6693 {"SC_INF", _SC_INF},
6694 #endif
6695 #ifdef _SC_INT_MAX
6696 {"SC_INT_MAX", _SC_INT_MAX},
6697 #endif
6698 #ifdef _SC_INT_MIN
6699 {"SC_INT_MIN", _SC_INT_MIN},
6700 #endif
6701 #ifdef _SC_IOV_MAX
6702 {"SC_IOV_MAX", _SC_IOV_MAX},
6703 #endif
6704 #ifdef _SC_IP_SECOPTS
6705 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
6706 #endif
6707 #ifdef _SC_JOB_CONTROL
6708 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
6709 #endif
6710 #ifdef _SC_KERN_POINTERS
6711 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
6712 #endif
6713 #ifdef _SC_KERN_SIM
6714 {"SC_KERN_SIM", _SC_KERN_SIM},
6715 #endif
6716 #ifdef _SC_LINE_MAX
6717 {"SC_LINE_MAX", _SC_LINE_MAX},
6718 #endif
6719 #ifdef _SC_LOGIN_NAME_MAX
6720 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
6721 #endif
6722 #ifdef _SC_LOGNAME_MAX
6723 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
6724 #endif
6725 #ifdef _SC_LONG_BIT
6726 {"SC_LONG_BIT", _SC_LONG_BIT},
6727 #endif
6728 #ifdef _SC_MAC
6729 {"SC_MAC", _SC_MAC},
6730 #endif
6731 #ifdef _SC_MAPPED_FILES
6732 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
6733 #endif
6734 #ifdef _SC_MAXPID
6735 {"SC_MAXPID", _SC_MAXPID},
6736 #endif
6737 #ifdef _SC_MB_LEN_MAX
6738 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
6739 #endif
6740 #ifdef _SC_MEMLOCK
6741 {"SC_MEMLOCK", _SC_MEMLOCK},
6742 #endif
6743 #ifdef _SC_MEMLOCK_RANGE
6744 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
6745 #endif
6746 #ifdef _SC_MEMORY_PROTECTION
6747 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
6748 #endif
6749 #ifdef _SC_MESSAGE_PASSING
6750 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
6751 #endif
6752 #ifdef _SC_MMAP_FIXED_ALIGNMENT
6753 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
6754 #endif
6755 #ifdef _SC_MQ_OPEN_MAX
6756 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
6757 #endif
6758 #ifdef _SC_MQ_PRIO_MAX
6759 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
6760 #endif
6761 #ifdef _SC_NACLS_MAX
6762 {"SC_NACLS_MAX", _SC_NACLS_MAX},
6763 #endif
6764 #ifdef _SC_NGROUPS_MAX
6765 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
6766 #endif
6767 #ifdef _SC_NL_ARGMAX
6768 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
6769 #endif
6770 #ifdef _SC_NL_LANGMAX
6771 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
6772 #endif
6773 #ifdef _SC_NL_MSGMAX
6774 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
6775 #endif
6776 #ifdef _SC_NL_NMAX
6777 {"SC_NL_NMAX", _SC_NL_NMAX},
6778 #endif
6779 #ifdef _SC_NL_SETMAX
6780 {"SC_NL_SETMAX", _SC_NL_SETMAX},
6781 #endif
6782 #ifdef _SC_NL_TEXTMAX
6783 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
6784 #endif
6785 #ifdef _SC_NPROCESSORS_CONF
6786 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
6787 #endif
6788 #ifdef _SC_NPROCESSORS_ONLN
6789 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
6790 #endif
6791 #ifdef _SC_NPROC_CONF
6792 {"SC_NPROC_CONF", _SC_NPROC_CONF},
6793 #endif
6794 #ifdef _SC_NPROC_ONLN
6795 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
6796 #endif
6797 #ifdef _SC_NZERO
6798 {"SC_NZERO", _SC_NZERO},
6799 #endif
6800 #ifdef _SC_OPEN_MAX
6801 {"SC_OPEN_MAX", _SC_OPEN_MAX},
6802 #endif
6803 #ifdef _SC_PAGESIZE
6804 {"SC_PAGESIZE", _SC_PAGESIZE},
6805 #endif
6806 #ifdef _SC_PAGE_SIZE
6807 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
6808 #endif
6809 #ifdef _SC_PASS_MAX
6810 {"SC_PASS_MAX", _SC_PASS_MAX},
6811 #endif
6812 #ifdef _SC_PHYS_PAGES
6813 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
6814 #endif
6815 #ifdef _SC_PII
6816 {"SC_PII", _SC_PII},
6817 #endif
6818 #ifdef _SC_PII_INTERNET
6819 {"SC_PII_INTERNET", _SC_PII_INTERNET},
6820 #endif
6821 #ifdef _SC_PII_INTERNET_DGRAM
6822 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
6823 #endif
6824 #ifdef _SC_PII_INTERNET_STREAM
6825 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
6826 #endif
6827 #ifdef _SC_PII_OSI
6828 {"SC_PII_OSI", _SC_PII_OSI},
6829 #endif
6830 #ifdef _SC_PII_OSI_CLTS
6831 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
6832 #endif
6833 #ifdef _SC_PII_OSI_COTS
6834 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
6835 #endif
6836 #ifdef _SC_PII_OSI_M
6837 {"SC_PII_OSI_M", _SC_PII_OSI_M},
6838 #endif
6839 #ifdef _SC_PII_SOCKET
6840 {"SC_PII_SOCKET", _SC_PII_SOCKET},
6841 #endif
6842 #ifdef _SC_PII_XTI
6843 {"SC_PII_XTI", _SC_PII_XTI},
6844 #endif
6845 #ifdef _SC_POLL
6846 {"SC_POLL", _SC_POLL},
6847 #endif
6848 #ifdef _SC_PRIORITIZED_IO
6849 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
6850 #endif
6851 #ifdef _SC_PRIORITY_SCHEDULING
6852 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
6853 #endif
6854 #ifdef _SC_REALTIME_SIGNALS
6855 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
6856 #endif
6857 #ifdef _SC_RE_DUP_MAX
6858 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
6859 #endif
6860 #ifdef _SC_RTSIG_MAX
6861 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
6862 #endif
6863 #ifdef _SC_SAVED_IDS
6864 {"SC_SAVED_IDS", _SC_SAVED_IDS},
6865 #endif
6866 #ifdef _SC_SCHAR_MAX
6867 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
6868 #endif
6869 #ifdef _SC_SCHAR_MIN
6870 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
6871 #endif
6872 #ifdef _SC_SELECT
6873 {"SC_SELECT", _SC_SELECT},
6874 #endif
6875 #ifdef _SC_SEMAPHORES
6876 {"SC_SEMAPHORES", _SC_SEMAPHORES},
6877 #endif
6878 #ifdef _SC_SEM_NSEMS_MAX
6879 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
6880 #endif
6881 #ifdef _SC_SEM_VALUE_MAX
6882 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
6883 #endif
6884 #ifdef _SC_SHARED_MEMORY_OBJECTS
6885 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
6886 #endif
6887 #ifdef _SC_SHRT_MAX
6888 {"SC_SHRT_MAX", _SC_SHRT_MAX},
6889 #endif
6890 #ifdef _SC_SHRT_MIN
6891 {"SC_SHRT_MIN", _SC_SHRT_MIN},
6892 #endif
6893 #ifdef _SC_SIGQUEUE_MAX
6894 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
6895 #endif
6896 #ifdef _SC_SIGRT_MAX
6897 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
6898 #endif
6899 #ifdef _SC_SIGRT_MIN
6900 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
6901 #endif
6902 #ifdef _SC_SOFTPOWER
6903 {"SC_SOFTPOWER", _SC_SOFTPOWER},
6904 #endif
6905 #ifdef _SC_SPLIT_CACHE
6906 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
6907 #endif
6908 #ifdef _SC_SSIZE_MAX
6909 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
6910 #endif
6911 #ifdef _SC_STACK_PROT
6912 {"SC_STACK_PROT", _SC_STACK_PROT},
6913 #endif
6914 #ifdef _SC_STREAM_MAX
6915 {"SC_STREAM_MAX", _SC_STREAM_MAX},
6916 #endif
6917 #ifdef _SC_SYNCHRONIZED_IO
6918 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
6919 #endif
6920 #ifdef _SC_THREADS
6921 {"SC_THREADS", _SC_THREADS},
6922 #endif
6923 #ifdef _SC_THREAD_ATTR_STACKADDR
6924 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
6925 #endif
6926 #ifdef _SC_THREAD_ATTR_STACKSIZE
6927 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
6928 #endif
6929 #ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
6930 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
6931 #endif
6932 #ifdef _SC_THREAD_KEYS_MAX
6933 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
6934 #endif
6935 #ifdef _SC_THREAD_PRIORITY_SCHEDULING
6936 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
6937 #endif
6938 #ifdef _SC_THREAD_PRIO_INHERIT
6939 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
6940 #endif
6941 #ifdef _SC_THREAD_PRIO_PROTECT
6942 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
6943 #endif
6944 #ifdef _SC_THREAD_PROCESS_SHARED
6945 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
6946 #endif
6947 #ifdef _SC_THREAD_SAFE_FUNCTIONS
6948 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
6949 #endif
6950 #ifdef _SC_THREAD_STACK_MIN
6951 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
6952 #endif
6953 #ifdef _SC_THREAD_THREADS_MAX
6954 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
6955 #endif
6956 #ifdef _SC_TIMERS
6957 {"SC_TIMERS", _SC_TIMERS},
6958 #endif
6959 #ifdef _SC_TIMER_MAX
6960 {"SC_TIMER_MAX", _SC_TIMER_MAX},
6961 #endif
6962 #ifdef _SC_TTY_NAME_MAX
6963 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
6964 #endif
6965 #ifdef _SC_TZNAME_MAX
6966 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
6967 #endif
6968 #ifdef _SC_T_IOV_MAX
6969 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
6970 #endif
6971 #ifdef _SC_UCHAR_MAX
6972 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
6973 #endif
6974 #ifdef _SC_UINT_MAX
6975 {"SC_UINT_MAX", _SC_UINT_MAX},
6976 #endif
6977 #ifdef _SC_UIO_MAXIOV
6978 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
6979 #endif
6980 #ifdef _SC_ULONG_MAX
6981 {"SC_ULONG_MAX", _SC_ULONG_MAX},
6982 #endif
6983 #ifdef _SC_USHRT_MAX
6984 {"SC_USHRT_MAX", _SC_USHRT_MAX},
6985 #endif
6986 #ifdef _SC_VERSION
6987 {"SC_VERSION", _SC_VERSION},
6988 #endif
6989 #ifdef _SC_WORD_BIT
6990 {"SC_WORD_BIT", _SC_WORD_BIT},
6991 #endif
6992 #ifdef _SC_XBS5_ILP32_OFF32
6993 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
6994 #endif
6995 #ifdef _SC_XBS5_ILP32_OFFBIG
6996 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
6997 #endif
6998 #ifdef _SC_XBS5_LP64_OFF64
6999 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
7000 #endif
7001 #ifdef _SC_XBS5_LPBIG_OFFBIG
7002 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
7003 #endif
7004 #ifdef _SC_XOPEN_CRYPT
7005 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
7006 #endif
7007 #ifdef _SC_XOPEN_ENH_I18N
7008 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
7009 #endif
7010 #ifdef _SC_XOPEN_LEGACY
7011 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
7012 #endif
7013 #ifdef _SC_XOPEN_REALTIME
7014 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
7015 #endif
7016 #ifdef _SC_XOPEN_REALTIME_THREADS
7017 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
7018 #endif
7019 #ifdef _SC_XOPEN_SHM
7020 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
7021 #endif
7022 #ifdef _SC_XOPEN_UNIX
7023 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
7024 #endif
7025 #ifdef _SC_XOPEN_VERSION
7026 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
7027 #endif
7028 #ifdef _SC_XOPEN_XCU_VERSION
7029 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
7030 #endif
7031 #ifdef _SC_XOPEN_XPG2
7032 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
7033 #endif
7034 #ifdef _SC_XOPEN_XPG3
7035 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
7036 #endif
7037 #ifdef _SC_XOPEN_XPG4
7038 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
7039 #endif
7042 static int
7043 conv_sysconf_confname(PyObject *arg, int *valuep)
7045 return conv_confname(arg, valuep, posix_constants_sysconf,
7046 sizeof(posix_constants_sysconf)
7047 / sizeof(struct constdef));
7050 PyDoc_STRVAR(posix_sysconf__doc__,
7051 "sysconf(name) -> integer\n\n\
7052 Return an integer-valued system configuration variable.");
7054 static PyObject *
7055 posix_sysconf(PyObject *self, PyObject *args)
7057 PyObject *result = NULL;
7058 int name;
7060 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
7061 int value;
7063 errno = 0;
7064 value = sysconf(name);
7065 if (value == -1 && errno != 0)
7066 posix_error();
7067 else
7068 result = PyInt_FromLong(value);
7070 return result;
7072 #endif
7075 /* This code is used to ensure that the tables of configuration value names
7076 * are in sorted order as required by conv_confname(), and also to build the
7077 * the exported dictionaries that are used to publish information about the
7078 * names available on the host platform.
7080 * Sorting the table at runtime ensures that the table is properly ordered
7081 * when used, even for platforms we're not able to test on. It also makes
7082 * it easier to add additional entries to the tables.
7085 static int
7086 cmp_constdefs(const void *v1, const void *v2)
7088 const struct constdef *c1 =
7089 (const struct constdef *) v1;
7090 const struct constdef *c2 =
7091 (const struct constdef *) v2;
7093 return strcmp(c1->name, c2->name);
7096 static int
7097 setup_confname_table(struct constdef *table, size_t tablesize,
7098 char *tablename, PyObject *module)
7100 PyObject *d = NULL;
7101 size_t i;
7103 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
7104 d = PyDict_New();
7105 if (d == NULL)
7106 return -1;
7108 for (i=0; i < tablesize; ++i) {
7109 PyObject *o = PyInt_FromLong(table[i].value);
7110 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
7111 Py_XDECREF(o);
7112 Py_DECREF(d);
7113 return -1;
7115 Py_DECREF(o);
7117 return PyModule_AddObject(module, tablename, d);
7120 /* Return -1 on failure, 0 on success. */
7121 static int
7122 setup_confname_tables(PyObject *module)
7124 #if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
7125 if (setup_confname_table(posix_constants_pathconf,
7126 sizeof(posix_constants_pathconf)
7127 / sizeof(struct constdef),
7128 "pathconf_names", module))
7129 return -1;
7130 #endif
7131 #ifdef HAVE_CONFSTR
7132 if (setup_confname_table(posix_constants_confstr,
7133 sizeof(posix_constants_confstr)
7134 / sizeof(struct constdef),
7135 "confstr_names", module))
7136 return -1;
7137 #endif
7138 #ifdef HAVE_SYSCONF
7139 if (setup_confname_table(posix_constants_sysconf,
7140 sizeof(posix_constants_sysconf)
7141 / sizeof(struct constdef),
7142 "sysconf_names", module))
7143 return -1;
7144 #endif
7145 return 0;
7149 PyDoc_STRVAR(posix_abort__doc__,
7150 "abort() -> does not return!\n\n\
7151 Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
7152 in the hardest way possible on the hosting operating system.");
7154 static PyObject *
7155 posix_abort(PyObject *self, PyObject *noargs)
7157 abort();
7158 /*NOTREACHED*/
7159 Py_FatalError("abort() called from Python code didn't abort!");
7160 return NULL;
7163 #ifdef MS_WINDOWS
7164 PyDoc_STRVAR(win32_startfile__doc__,
7165 "startfile(filepath) - Start a file with its associated application.\n\
7167 This acts like double-clicking the file in Explorer, or giving the file\n\
7168 name as an argument to the DOS \"start\" command: the file is opened\n\
7169 with whatever application (if any) its extension is associated.\n\
7171 startfile returns as soon as the associated application is launched.\n\
7172 There is no option to wait for the application to close, and no way\n\
7173 to retrieve the application's exit status.\n\
7175 The filepath is relative to the current directory. If you want to use\n\
7176 an absolute path, make sure the first character is not a slash (\"/\");\n\
7177 the underlying Win32 ShellExecute function doesn't work if it is.");
7179 static PyObject *
7180 win32_startfile(PyObject *self, PyObject *args)
7182 char *filepath;
7183 HINSTANCE rc;
7184 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
7185 return NULL;
7186 Py_BEGIN_ALLOW_THREADS
7187 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
7188 Py_END_ALLOW_THREADS
7189 if (rc <= (HINSTANCE)32)
7190 return win32_error("startfile", filepath);
7191 Py_INCREF(Py_None);
7192 return Py_None;
7194 #endif
7196 #ifdef HAVE_GETLOADAVG
7197 PyDoc_STRVAR(posix_getloadavg__doc__,
7198 "getloadavg() -> (float, float, float)\n\n\
7199 Return the number of processes in the system run queue averaged over\n\
7200 the last 1, 5, and 15 minutes or raises OSError if the load average\n\
7201 was unobtainable");
7203 static PyObject *
7204 posix_getloadavg(PyObject *self, PyObject *noargs)
7206 double loadavg[3];
7207 if (getloadavg(loadavg, 3)!=3) {
7208 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
7209 return NULL;
7210 } else
7211 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
7213 #endif
7215 #ifdef MS_WINDOWS
7217 PyDoc_STRVAR(win32_urandom__doc__,
7218 "urandom(n) -> str\n\n\
7219 Return a string of n random bytes suitable for cryptographic use.");
7221 typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
7222 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
7223 DWORD dwFlags );
7224 typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
7225 BYTE *pbBuffer );
7227 static CRYPTGENRANDOM pCryptGenRandom = NULL;
7228 static HCRYPTPROV hCryptProv = 0;
7230 static PyObject*
7231 win32_urandom(PyObject *self, PyObject *args)
7233 int howMany;
7234 PyObject* result;
7236 /* Read arguments */
7237 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
7238 return NULL;
7239 if (howMany < 0)
7240 return PyErr_Format(PyExc_ValueError,
7241 "negative argument not allowed");
7243 if (hCryptProv == 0) {
7244 HINSTANCE hAdvAPI32 = NULL;
7245 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
7247 /* Obtain handle to the DLL containing CryptoAPI
7248 This should not fail */
7249 hAdvAPI32 = GetModuleHandle("advapi32.dll");
7250 if(hAdvAPI32 == NULL)
7251 return win32_error("GetModuleHandle", NULL);
7253 /* Obtain pointers to the CryptoAPI functions
7254 This will fail on some early versions of Win95 */
7255 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
7256 hAdvAPI32,
7257 "CryptAcquireContextA");
7258 if (pCryptAcquireContext == NULL)
7259 return PyErr_Format(PyExc_NotImplementedError,
7260 "CryptAcquireContextA not found");
7262 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
7263 hAdvAPI32, "CryptGenRandom");
7264 if (pCryptAcquireContext == NULL)
7265 return PyErr_Format(PyExc_NotImplementedError,
7266 "CryptGenRandom not found");
7268 /* Acquire context */
7269 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
7270 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
7271 return win32_error("CryptAcquireContext", NULL);
7274 /* Allocate bytes */
7275 result = PyString_FromStringAndSize(NULL, howMany);
7276 if (result != NULL) {
7277 /* Get random data */
7278 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
7279 PyString_AS_STRING(result))) {
7280 Py_DECREF(result);
7281 return win32_error("CryptGenRandom", NULL);
7284 return result;
7286 #endif
7288 static PyMethodDef posix_methods[] = {
7289 {"access", posix_access, METH_VARARGS, posix_access__doc__},
7290 #ifdef HAVE_TTYNAME
7291 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
7292 #endif
7293 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
7294 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
7295 #ifdef HAVE_CHOWN
7296 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
7297 #endif /* HAVE_CHOWN */
7298 #ifdef HAVE_LCHOWN
7299 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
7300 #endif /* HAVE_LCHOWN */
7301 #ifdef HAVE_CHROOT
7302 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
7303 #endif
7304 #ifdef HAVE_CTERMID
7305 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
7306 #endif
7307 #ifdef HAVE_GETCWD
7308 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
7309 #ifdef Py_USING_UNICODE
7310 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
7311 #endif
7312 #endif
7313 #ifdef HAVE_LINK
7314 {"link", posix_link, METH_VARARGS, posix_link__doc__},
7315 #endif /* HAVE_LINK */
7316 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
7317 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
7318 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
7319 #ifdef HAVE_NICE
7320 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
7321 #endif /* HAVE_NICE */
7322 #ifdef HAVE_READLINK
7323 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
7324 #endif /* HAVE_READLINK */
7325 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
7326 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
7327 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
7328 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
7329 #ifdef HAVE_SYMLINK
7330 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
7331 #endif /* HAVE_SYMLINK */
7332 #ifdef HAVE_SYSTEM
7333 {"system", posix_system, METH_VARARGS, posix_system__doc__},
7334 #endif
7335 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
7336 #ifdef HAVE_UNAME
7337 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
7338 #endif /* HAVE_UNAME */
7339 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
7340 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
7341 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
7342 #ifdef HAVE_TIMES
7343 {"times", posix_times, METH_NOARGS, posix_times__doc__},
7344 #endif /* HAVE_TIMES */
7345 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
7346 #ifdef HAVE_EXECV
7347 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
7348 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
7349 #endif /* HAVE_EXECV */
7350 #ifdef HAVE_SPAWNV
7351 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
7352 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
7353 #if defined(PYOS_OS2)
7354 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
7355 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
7356 #endif /* PYOS_OS2 */
7357 #endif /* HAVE_SPAWNV */
7358 #ifdef HAVE_FORK1
7359 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
7360 #endif /* HAVE_FORK1 */
7361 #ifdef HAVE_FORK
7362 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
7363 #endif /* HAVE_FORK */
7364 #if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
7365 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
7366 #endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
7367 #ifdef HAVE_FORKPTY
7368 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
7369 #endif /* HAVE_FORKPTY */
7370 #ifdef HAVE_GETEGID
7371 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
7372 #endif /* HAVE_GETEGID */
7373 #ifdef HAVE_GETEUID
7374 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
7375 #endif /* HAVE_GETEUID */
7376 #ifdef HAVE_GETGID
7377 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
7378 #endif /* HAVE_GETGID */
7379 #ifdef HAVE_GETGROUPS
7380 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
7381 #endif
7382 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
7383 #ifdef HAVE_GETPGRP
7384 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
7385 #endif /* HAVE_GETPGRP */
7386 #ifdef HAVE_GETPPID
7387 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
7388 #endif /* HAVE_GETPPID */
7389 #ifdef HAVE_GETUID
7390 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
7391 #endif /* HAVE_GETUID */
7392 #ifdef HAVE_GETLOGIN
7393 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
7394 #endif
7395 #ifdef HAVE_KILL
7396 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
7397 #endif /* HAVE_KILL */
7398 #ifdef HAVE_KILLPG
7399 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
7400 #endif /* HAVE_KILLPG */
7401 #ifdef HAVE_PLOCK
7402 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
7403 #endif /* HAVE_PLOCK */
7404 #ifdef HAVE_POPEN
7405 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
7406 #ifdef MS_WINDOWS
7407 {"popen2", win32_popen2, METH_VARARGS},
7408 {"popen3", win32_popen3, METH_VARARGS},
7409 {"popen4", win32_popen4, METH_VARARGS},
7410 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
7411 #else
7412 #if defined(PYOS_OS2) && defined(PYCC_GCC)
7413 {"popen2", os2emx_popen2, METH_VARARGS},
7414 {"popen3", os2emx_popen3, METH_VARARGS},
7415 {"popen4", os2emx_popen4, METH_VARARGS},
7416 #endif
7417 #endif
7418 #endif /* HAVE_POPEN */
7419 #ifdef HAVE_SETUID
7420 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
7421 #endif /* HAVE_SETUID */
7422 #ifdef HAVE_SETEUID
7423 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
7424 #endif /* HAVE_SETEUID */
7425 #ifdef HAVE_SETEGID
7426 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
7427 #endif /* HAVE_SETEGID */
7428 #ifdef HAVE_SETREUID
7429 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
7430 #endif /* HAVE_SETREUID */
7431 #ifdef HAVE_SETREGID
7432 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
7433 #endif /* HAVE_SETREGID */
7434 #ifdef HAVE_SETGID
7435 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
7436 #endif /* HAVE_SETGID */
7437 #ifdef HAVE_SETGROUPS
7438 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
7439 #endif /* HAVE_SETGROUPS */
7440 #ifdef HAVE_GETPGID
7441 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
7442 #endif /* HAVE_GETPGID */
7443 #ifdef HAVE_SETPGRP
7444 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
7445 #endif /* HAVE_SETPGRP */
7446 #ifdef HAVE_WAIT
7447 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
7448 #endif /* HAVE_WAIT */
7449 #if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
7450 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
7451 #endif /* HAVE_WAITPID */
7452 #ifdef HAVE_GETSID
7453 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
7454 #endif /* HAVE_GETSID */
7455 #ifdef HAVE_SETSID
7456 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
7457 #endif /* HAVE_SETSID */
7458 #ifdef HAVE_SETPGID
7459 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
7460 #endif /* HAVE_SETPGID */
7461 #ifdef HAVE_TCGETPGRP
7462 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
7463 #endif /* HAVE_TCGETPGRP */
7464 #ifdef HAVE_TCSETPGRP
7465 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
7466 #endif /* HAVE_TCSETPGRP */
7467 {"open", posix_open, METH_VARARGS, posix_open__doc__},
7468 {"close", posix_close, METH_VARARGS, posix_close__doc__},
7469 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
7470 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
7471 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
7472 {"read", posix_read, METH_VARARGS, posix_read__doc__},
7473 {"write", posix_write, METH_VARARGS, posix_write__doc__},
7474 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
7475 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
7476 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
7477 #ifdef HAVE_PIPE
7478 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
7479 #endif
7480 #ifdef HAVE_MKFIFO
7481 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
7482 #endif
7483 #if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
7484 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
7485 #endif
7486 #ifdef HAVE_DEVICE_MACROS
7487 {"major", posix_major, METH_VARARGS, posix_major__doc__},
7488 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
7489 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
7490 #endif
7491 #ifdef HAVE_FTRUNCATE
7492 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
7493 #endif
7494 #ifdef HAVE_PUTENV
7495 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
7496 #endif
7497 #ifdef HAVE_UNSETENV
7498 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
7499 #endif
7500 #ifdef HAVE_STRERROR
7501 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
7502 #endif
7503 #ifdef HAVE_FCHDIR
7504 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
7505 #endif
7506 #ifdef HAVE_FSYNC
7507 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
7508 #endif
7509 #ifdef HAVE_FDATASYNC
7510 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
7511 #endif
7512 #ifdef HAVE_SYS_WAIT_H
7513 #ifdef WCOREDUMP
7514 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
7515 #endif /* WCOREDUMP */
7516 #ifdef WIFCONTINUED
7517 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
7518 #endif /* WIFCONTINUED */
7519 #ifdef WIFSTOPPED
7520 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
7521 #endif /* WIFSTOPPED */
7522 #ifdef WIFSIGNALED
7523 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
7524 #endif /* WIFSIGNALED */
7525 #ifdef WIFEXITED
7526 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
7527 #endif /* WIFEXITED */
7528 #ifdef WEXITSTATUS
7529 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
7530 #endif /* WEXITSTATUS */
7531 #ifdef WTERMSIG
7532 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
7533 #endif /* WTERMSIG */
7534 #ifdef WSTOPSIG
7535 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
7536 #endif /* WSTOPSIG */
7537 #endif /* HAVE_SYS_WAIT_H */
7538 #ifdef HAVE_FSTATVFS
7539 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
7540 #endif
7541 #ifdef HAVE_STATVFS
7542 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
7543 #endif
7544 #ifdef HAVE_TMPFILE
7545 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
7546 #endif
7547 #ifdef HAVE_TEMPNAM
7548 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
7549 #endif
7550 #ifdef HAVE_TMPNAM
7551 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
7552 #endif
7553 #ifdef HAVE_CONFSTR
7554 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
7555 #endif
7556 #ifdef HAVE_SYSCONF
7557 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
7558 #endif
7559 #ifdef HAVE_FPATHCONF
7560 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
7561 #endif
7562 #ifdef HAVE_PATHCONF
7563 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
7564 #endif
7565 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
7566 #ifdef MS_WINDOWS
7567 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
7568 #endif
7569 #ifdef HAVE_GETLOADAVG
7570 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
7571 #endif
7572 #ifdef MS_WINDOWS
7573 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
7574 #endif
7575 {NULL, NULL} /* Sentinel */
7579 static int
7580 ins(PyObject *module, char *symbol, long value)
7582 return PyModule_AddIntConstant(module, symbol, value);
7585 #if defined(PYOS_OS2)
7586 /* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
7587 static int insertvalues(PyObject *module)
7589 APIRET rc;
7590 ULONG values[QSV_MAX+1];
7591 PyObject *v;
7592 char *ver, tmp[50];
7594 Py_BEGIN_ALLOW_THREADS
7595 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
7596 Py_END_ALLOW_THREADS
7598 if (rc != NO_ERROR) {
7599 os2_error(rc);
7600 return -1;
7603 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
7604 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
7605 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
7606 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
7607 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
7608 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
7609 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
7611 switch (values[QSV_VERSION_MINOR]) {
7612 case 0: ver = "2.00"; break;
7613 case 10: ver = "2.10"; break;
7614 case 11: ver = "2.11"; break;
7615 case 30: ver = "3.00"; break;
7616 case 40: ver = "4.00"; break;
7617 case 50: ver = "5.00"; break;
7618 default:
7619 PyOS_snprintf(tmp, sizeof(tmp),
7620 "%d-%d", values[QSV_VERSION_MAJOR],
7621 values[QSV_VERSION_MINOR]);
7622 ver = &tmp[0];
7625 /* Add Indicator of the Version of the Operating System */
7626 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
7627 return -1;
7629 /* Add Indicator of Which Drive was Used to Boot the System */
7630 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
7631 tmp[1] = ':';
7632 tmp[2] = '\0';
7634 return PyModule_AddStringConstant(module, "bootdrive", tmp);
7636 #endif
7638 static int
7639 all_ins(PyObject *d)
7641 #ifdef F_OK
7642 if (ins(d, "F_OK", (long)F_OK)) return -1;
7643 #endif
7644 #ifdef R_OK
7645 if (ins(d, "R_OK", (long)R_OK)) return -1;
7646 #endif
7647 #ifdef W_OK
7648 if (ins(d, "W_OK", (long)W_OK)) return -1;
7649 #endif
7650 #ifdef X_OK
7651 if (ins(d, "X_OK", (long)X_OK)) return -1;
7652 #endif
7653 #ifdef NGROUPS_MAX
7654 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
7655 #endif
7656 #ifdef TMP_MAX
7657 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
7658 #endif
7659 #ifdef WCONTINUED
7660 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
7661 #endif
7662 #ifdef WNOHANG
7663 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
7664 #endif
7665 #ifdef WUNTRACED
7666 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
7667 #endif
7668 #ifdef O_RDONLY
7669 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
7670 #endif
7671 #ifdef O_WRONLY
7672 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
7673 #endif
7674 #ifdef O_RDWR
7675 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
7676 #endif
7677 #ifdef O_NDELAY
7678 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
7679 #endif
7680 #ifdef O_NONBLOCK
7681 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
7682 #endif
7683 #ifdef O_APPEND
7684 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
7685 #endif
7686 #ifdef O_DSYNC
7687 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
7688 #endif
7689 #ifdef O_RSYNC
7690 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
7691 #endif
7692 #ifdef O_SYNC
7693 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
7694 #endif
7695 #ifdef O_NOCTTY
7696 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
7697 #endif
7698 #ifdef O_CREAT
7699 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
7700 #endif
7701 #ifdef O_EXCL
7702 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
7703 #endif
7704 #ifdef O_TRUNC
7705 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
7706 #endif
7707 #ifdef O_BINARY
7708 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
7709 #endif
7710 #ifdef O_TEXT
7711 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
7712 #endif
7713 #ifdef O_LARGEFILE
7714 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
7715 #endif
7717 /* MS Windows */
7718 #ifdef O_NOINHERIT
7719 /* Don't inherit in child processes. */
7720 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
7721 #endif
7722 #ifdef _O_SHORT_LIVED
7723 /* Optimize for short life (keep in memory). */
7724 /* MS forgot to define this one with a non-underscore form too. */
7725 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
7726 #endif
7727 #ifdef O_TEMPORARY
7728 /* Automatically delete when last handle is closed. */
7729 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
7730 #endif
7731 #ifdef O_RANDOM
7732 /* Optimize for random access. */
7733 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
7734 #endif
7735 #ifdef O_SEQUENTIAL
7736 /* Optimize for sequential access. */
7737 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
7738 #endif
7740 /* GNU extensions. */
7741 #ifdef O_DIRECT
7742 /* Direct disk access. */
7743 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
7744 #endif
7745 #ifdef O_DIRECTORY
7746 /* Must be a directory. */
7747 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
7748 #endif
7749 #ifdef O_NOFOLLOW
7750 /* Do not follow links. */
7751 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
7752 #endif
7754 /* These come from sysexits.h */
7755 #ifdef EX_OK
7756 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
7757 #endif /* EX_OK */
7758 #ifdef EX_USAGE
7759 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
7760 #endif /* EX_USAGE */
7761 #ifdef EX_DATAERR
7762 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
7763 #endif /* EX_DATAERR */
7764 #ifdef EX_NOINPUT
7765 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
7766 #endif /* EX_NOINPUT */
7767 #ifdef EX_NOUSER
7768 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
7769 #endif /* EX_NOUSER */
7770 #ifdef EX_NOHOST
7771 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
7772 #endif /* EX_NOHOST */
7773 #ifdef EX_UNAVAILABLE
7774 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
7775 #endif /* EX_UNAVAILABLE */
7776 #ifdef EX_SOFTWARE
7777 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
7778 #endif /* EX_SOFTWARE */
7779 #ifdef EX_OSERR
7780 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
7781 #endif /* EX_OSERR */
7782 #ifdef EX_OSFILE
7783 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
7784 #endif /* EX_OSFILE */
7785 #ifdef EX_CANTCREAT
7786 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
7787 #endif /* EX_CANTCREAT */
7788 #ifdef EX_IOERR
7789 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
7790 #endif /* EX_IOERR */
7791 #ifdef EX_TEMPFAIL
7792 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
7793 #endif /* EX_TEMPFAIL */
7794 #ifdef EX_PROTOCOL
7795 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
7796 #endif /* EX_PROTOCOL */
7797 #ifdef EX_NOPERM
7798 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
7799 #endif /* EX_NOPERM */
7800 #ifdef EX_CONFIG
7801 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
7802 #endif /* EX_CONFIG */
7803 #ifdef EX_NOTFOUND
7804 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
7805 #endif /* EX_NOTFOUND */
7807 #ifdef HAVE_SPAWNV
7808 #if defined(PYOS_OS2) && defined(PYCC_GCC)
7809 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
7810 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
7811 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
7812 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
7813 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
7814 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
7815 if (ins(d, "P_PM", (long)P_PM)) return -1;
7816 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
7817 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
7818 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
7819 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
7820 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
7821 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
7822 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
7823 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
7824 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
7825 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
7826 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
7827 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
7828 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
7829 #else
7830 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
7831 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
7832 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
7833 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
7834 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
7835 #endif
7836 #endif
7838 #if defined(PYOS_OS2)
7839 if (insertvalues(d)) return -1;
7840 #endif
7841 return 0;
7845 #if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
7846 #define INITFUNC initnt
7847 #define MODNAME "nt"
7849 #elif defined(PYOS_OS2)
7850 #define INITFUNC initos2
7851 #define MODNAME "os2"
7853 #else
7854 #define INITFUNC initposix
7855 #define MODNAME "posix"
7856 #endif
7858 PyMODINIT_FUNC
7859 INITFUNC(void)
7861 PyObject *m, *v;
7863 m = Py_InitModule3(MODNAME,
7864 posix_methods,
7865 posix__doc__);
7867 /* Initialize environ dictionary */
7868 v = convertenviron();
7869 Py_XINCREF(v);
7870 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
7871 return;
7872 Py_DECREF(v);
7874 if (all_ins(m))
7875 return;
7877 if (setup_confname_tables(m))
7878 return;
7880 Py_INCREF(PyExc_OSError);
7881 PyModule_AddObject(m, "error", PyExc_OSError);
7883 #ifdef HAVE_PUTENV
7884 if (posix_putenv_garbage == NULL)
7885 posix_putenv_garbage = PyDict_New();
7886 #endif
7888 stat_result_desc.name = MODNAME ".stat_result";
7889 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
7890 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
7891 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
7892 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
7893 structseq_new = StatResultType.tp_new;
7894 StatResultType.tp_new = statresult_new;
7895 Py_INCREF((PyObject*) &StatResultType);
7896 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
7898 statvfs_result_desc.name = MODNAME ".statvfs_result";
7899 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
7900 Py_INCREF((PyObject*) &StatVFSResultType);
7901 PyModule_AddObject(m, "statvfs_result",
7902 (PyObject*) &StatVFSResultType);