Issue #789290: make sure that hash(2**63) == hash(2.**63) on 64-bit
[python.git] / Modules / posixmodule.c
blobcda8135c486858f48d0aa32a785672d20e1b4572
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 #ifdef __APPLE__
18 * Step 1 of support for weak-linking a number of symbols existing on
19 * OSX 10.4 and later, see the comment in the #ifdef __APPLE__ block
20 * at the end of this file for more information.
22 # pragma weak lchown
23 # pragma weak statvfs
24 # pragma weak fstatvfs
26 #endif /* __APPLE__ */
28 #define PY_SSIZE_T_CLEAN
30 #include "Python.h"
31 #include "structseq.h"
33 #if defined(__VMS)
34 # include <unixio.h>
35 #endif /* defined(__VMS) */
37 #ifdef __cplusplus
38 extern "C" {
39 #endif
41 PyDoc_STRVAR(posix__doc__,
42 "This module provides access to operating system functionality that is\n\
43 standardized by the C Standard and the POSIX standard (a thinly\n\
44 disguised Unix interface). Refer to the library manual and\n\
45 corresponding Unix manual entries for more information on calls.");
47 #ifndef Py_USING_UNICODE
48 /* This is used in signatures of functions. */
49 #define Py_UNICODE void
50 #endif
52 #if defined(PYOS_OS2)
53 #define INCL_DOS
54 #define INCL_DOSERRORS
55 #define INCL_DOSPROCESS
56 #define INCL_NOPMAPI
57 #include <os2.h>
58 #if defined(PYCC_GCC)
59 #include <ctype.h>
60 #include <io.h>
61 #include <stdio.h>
62 #include <process.h>
63 #endif
64 #include "osdefs.h"
65 #endif
67 #ifdef HAVE_SYS_TYPES_H
68 #include <sys/types.h>
69 #endif /* HAVE_SYS_TYPES_H */
71 #ifdef HAVE_SYS_STAT_H
72 #include <sys/stat.h>
73 #endif /* HAVE_SYS_STAT_H */
75 #ifdef HAVE_SYS_WAIT_H
76 #include <sys/wait.h> /* For WNOHANG */
77 #endif
79 #ifdef HAVE_SIGNAL_H
80 #include <signal.h>
81 #endif
83 #ifdef HAVE_FCNTL_H
84 #include <fcntl.h>
85 #endif /* HAVE_FCNTL_H */
87 #ifdef HAVE_GRP_H
88 #include <grp.h>
89 #endif
91 #ifdef HAVE_SYSEXITS_H
92 #include <sysexits.h>
93 #endif /* HAVE_SYSEXITS_H */
95 #ifdef HAVE_SYS_LOADAVG_H
96 #include <sys/loadavg.h>
97 #endif
99 /* Various compilers have only certain posix functions */
100 /* XXX Gosh I wish these were all moved into pyconfig.h */
101 #if defined(PYCC_VACPP) && defined(PYOS_OS2)
102 #include <process.h>
103 #else
104 #if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
105 #define HAVE_GETCWD 1
106 #define HAVE_OPENDIR 1
107 #define HAVE_SYSTEM 1
108 #if defined(__OS2__)
109 #define HAVE_EXECV 1
110 #define HAVE_WAIT 1
111 #endif
112 #include <process.h>
113 #else
114 #ifdef __BORLANDC__ /* Borland compiler */
115 #define HAVE_EXECV 1
116 #define HAVE_GETCWD 1
117 #define HAVE_OPENDIR 1
118 #define HAVE_PIPE 1
119 #define HAVE_POPEN 1
120 #define HAVE_SYSTEM 1
121 #define HAVE_WAIT 1
122 #else
123 #ifdef _MSC_VER /* Microsoft compiler */
124 #define HAVE_GETCWD 1
125 #define HAVE_SPAWNV 1
126 #define HAVE_EXECV 1
127 #define HAVE_PIPE 1
128 #define HAVE_POPEN 1
129 #define HAVE_SYSTEM 1
130 #define HAVE_CWAIT 1
131 #define HAVE_FSYNC 1
132 #define fsync _commit
133 #else
134 #if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
135 /* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
136 #else /* all other compilers */
137 /* Unix functions that the configure script doesn't check for */
138 #define HAVE_EXECV 1
139 #define HAVE_FORK 1
140 #if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
141 #define HAVE_FORK1 1
142 #endif
143 #define HAVE_GETCWD 1
144 #define HAVE_GETEGID 1
145 #define HAVE_GETEUID 1
146 #define HAVE_GETGID 1
147 #define HAVE_GETPPID 1
148 #define HAVE_GETUID 1
149 #define HAVE_KILL 1
150 #define HAVE_OPENDIR 1
151 #define HAVE_PIPE 1
152 #ifndef __rtems__
153 #define HAVE_POPEN 1
154 #endif
155 #define HAVE_SYSTEM 1
156 #define HAVE_WAIT 1
157 #define HAVE_TTYNAME 1
158 #endif /* PYOS_OS2 && PYCC_GCC && __VMS */
159 #endif /* _MSC_VER */
160 #endif /* __BORLANDC__ */
161 #endif /* ! __WATCOMC__ || __QNX__ */
162 #endif /* ! __IBMC__ */
164 #ifndef _MSC_VER
166 #if defined(__sgi)&&_COMPILER_VERSION>=700
167 /* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
168 (default) */
169 extern char *ctermid_r(char *);
170 #endif
172 #ifndef HAVE_UNISTD_H
173 #if defined(PYCC_VACPP)
174 extern int mkdir(char *);
175 #else
176 #if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
177 extern int mkdir(const char *);
178 #else
179 extern int mkdir(const char *, mode_t);
180 #endif
181 #endif
182 #if defined(__IBMC__) || defined(__IBMCPP__)
183 extern int chdir(char *);
184 extern int rmdir(char *);
185 #else
186 extern int chdir(const char *);
187 extern int rmdir(const char *);
188 #endif
189 #ifdef __BORLANDC__
190 extern int chmod(const char *, int);
191 #else
192 extern int chmod(const char *, mode_t);
193 #endif
194 /*#ifdef HAVE_FCHMOD
195 extern int fchmod(int, mode_t);
196 #endif*/
197 /*#ifdef HAVE_LCHMOD
198 extern int lchmod(const char *, mode_t);
199 #endif*/
200 extern int chown(const char *, uid_t, gid_t);
201 extern char *getcwd(char *, int);
202 extern char *strerror(int);
203 extern int link(const char *, const char *);
204 extern int rename(const char *, const char *);
205 extern int stat(const char *, struct stat *);
206 extern int unlink(const char *);
207 extern int pclose(FILE *);
208 #ifdef HAVE_SYMLINK
209 extern int symlink(const char *, const char *);
210 #endif /* HAVE_SYMLINK */
211 #ifdef HAVE_LSTAT
212 extern int lstat(const char *, struct stat *);
213 #endif /* HAVE_LSTAT */
214 #endif /* !HAVE_UNISTD_H */
216 #endif /* !_MSC_VER */
218 #ifdef HAVE_UTIME_H
219 #include <utime.h>
220 #endif /* HAVE_UTIME_H */
222 #ifdef HAVE_SYS_UTIME_H
223 #include <sys/utime.h>
224 #define HAVE_UTIME_H /* pretend we do for the rest of this file */
225 #endif /* HAVE_SYS_UTIME_H */
227 #ifdef HAVE_SYS_TIMES_H
228 #include <sys/times.h>
229 #endif /* HAVE_SYS_TIMES_H */
231 #ifdef HAVE_SYS_PARAM_H
232 #include <sys/param.h>
233 #endif /* HAVE_SYS_PARAM_H */
235 #ifdef HAVE_SYS_UTSNAME_H
236 #include <sys/utsname.h>
237 #endif /* HAVE_SYS_UTSNAME_H */
239 #ifdef HAVE_DIRENT_H
240 #include <dirent.h>
241 #define NAMLEN(dirent) strlen((dirent)->d_name)
242 #else
243 #if defined(__WATCOMC__) && !defined(__QNX__)
244 #include <direct.h>
245 #define NAMLEN(dirent) strlen((dirent)->d_name)
246 #else
247 #define dirent direct
248 #define NAMLEN(dirent) (dirent)->d_namlen
249 #endif
250 #ifdef HAVE_SYS_NDIR_H
251 #include <sys/ndir.h>
252 #endif
253 #ifdef HAVE_SYS_DIR_H
254 #include <sys/dir.h>
255 #endif
256 #ifdef HAVE_NDIR_H
257 #include <ndir.h>
258 #endif
259 #endif
261 #ifdef _MSC_VER
262 #ifdef HAVE_DIRECT_H
263 #include <direct.h>
264 #endif
265 #ifdef HAVE_IO_H
266 #include <io.h>
267 #endif
268 #ifdef HAVE_PROCESS_H
269 #include <process.h>
270 #endif
271 #include "osdefs.h"
272 #include <windows.h>
273 #include <shellapi.h> /* for ShellExecute() */
274 #define popen _popen
275 #define pclose _pclose
276 #endif /* _MSC_VER */
278 #if defined(PYCC_VACPP) && defined(PYOS_OS2)
279 #include <io.h>
280 #endif /* OS2 */
282 #ifndef MAXPATHLEN
283 #if defined(PATH_MAX) && PATH_MAX > 1024
284 #define MAXPATHLEN PATH_MAX
285 #else
286 #define MAXPATHLEN 1024
287 #endif
288 #endif /* MAXPATHLEN */
290 #ifdef UNION_WAIT
291 /* Emulate some macros on systems that have a union instead of macros */
293 #ifndef WIFEXITED
294 #define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
295 #endif
297 #ifndef WEXITSTATUS
298 #define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
299 #endif
301 #ifndef WTERMSIG
302 #define WTERMSIG(u_wait) ((u_wait).w_termsig)
303 #endif
305 #define WAIT_TYPE union wait
306 #define WAIT_STATUS_INT(s) (s.w_status)
308 #else /* !UNION_WAIT */
309 #define WAIT_TYPE int
310 #define WAIT_STATUS_INT(s) (s)
311 #endif /* UNION_WAIT */
313 /* Don't use the "_r" form if we don't need it (also, won't have a
314 prototype for it, at least on Solaris -- maybe others as well?). */
315 #if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
316 #define USE_CTERMID_R
317 #endif
319 #if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
320 #define USE_TMPNAM_R
321 #endif
323 /* choose the appropriate stat and fstat functions and return structs */
324 #undef STAT
325 #if defined(MS_WIN64) || defined(MS_WINDOWS)
326 # define STAT win32_stat
327 # define FSTAT win32_fstat
328 # define STRUCT_STAT struct win32_stat
329 #else
330 # define STAT stat
331 # define FSTAT fstat
332 # define STRUCT_STAT struct stat
333 #endif
335 #if defined(MAJOR_IN_MKDEV)
336 #include <sys/mkdev.h>
337 #else
338 #if defined(MAJOR_IN_SYSMACROS)
339 #include <sys/sysmacros.h>
340 #endif
341 #if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
342 #include <sys/mkdev.h>
343 #endif
344 #endif
346 /* Return a dictionary corresponding to the POSIX environment table */
347 #ifdef WITH_NEXT_FRAMEWORK
348 /* On Darwin/MacOSX a shared library or framework has no access to
349 ** environ directly, we must obtain it with _NSGetEnviron().
351 #include <crt_externs.h>
352 static char **environ;
353 #elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
354 extern char **environ;
355 #endif /* !_MSC_VER */
357 static PyObject *
358 convertenviron(void)
360 PyObject *d;
361 char **e;
362 d = PyDict_New();
363 if (d == NULL)
364 return NULL;
365 #ifdef WITH_NEXT_FRAMEWORK
366 if (environ == NULL)
367 environ = *_NSGetEnviron();
368 #endif
369 if (environ == NULL)
370 return d;
371 /* This part ignores errors */
372 for (e = environ; *e != NULL; e++) {
373 PyObject *k;
374 PyObject *v;
375 char *p = strchr(*e, '=');
376 if (p == NULL)
377 continue;
378 k = PyString_FromStringAndSize(*e, (int)(p-*e));
379 if (k == NULL) {
380 PyErr_Clear();
381 continue;
383 v = PyString_FromString(p+1);
384 if (v == NULL) {
385 PyErr_Clear();
386 Py_DECREF(k);
387 continue;
389 if (PyDict_GetItem(d, k) == NULL) {
390 if (PyDict_SetItem(d, k, v) != 0)
391 PyErr_Clear();
393 Py_DECREF(k);
394 Py_DECREF(v);
396 #if defined(PYOS_OS2)
398 APIRET rc;
399 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
401 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
402 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
403 PyObject *v = PyString_FromString(buffer);
404 PyDict_SetItemString(d, "BEGINLIBPATH", v);
405 Py_DECREF(v);
407 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
408 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
409 PyObject *v = PyString_FromString(buffer);
410 PyDict_SetItemString(d, "ENDLIBPATH", v);
411 Py_DECREF(v);
414 #endif
415 return d;
419 /* Set a POSIX-specific error from errno, and return NULL */
421 static PyObject *
422 posix_error(void)
424 return PyErr_SetFromErrno(PyExc_OSError);
426 static PyObject *
427 posix_error_with_filename(char* name)
429 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
432 #ifdef Py_WIN_WIDE_FILENAMES
433 static PyObject *
434 posix_error_with_unicode_filename(Py_UNICODE* name)
436 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
438 #endif /* Py_WIN_WIDE_FILENAMES */
441 static PyObject *
442 posix_error_with_allocated_filename(char* name)
444 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
445 PyMem_Free(name);
446 return rc;
449 #ifdef MS_WINDOWS
450 static PyObject *
451 win32_error(char* function, char* filename)
453 /* XXX We should pass the function name along in the future.
454 (_winreg.c also wants to pass the function name.)
455 This would however require an additional param to the
456 Windows error object, which is non-trivial.
458 errno = GetLastError();
459 if (filename)
460 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
461 else
462 return PyErr_SetFromWindowsErr(errno);
465 #ifdef Py_WIN_WIDE_FILENAMES
466 static PyObject *
467 win32_error_unicode(char* function, Py_UNICODE* filename)
469 /* XXX - see win32_error for comments on 'function' */
470 errno = GetLastError();
471 if (filename)
472 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
473 else
474 return PyErr_SetFromWindowsErr(errno);
477 static int
478 convert_to_unicode(PyObject **param)
480 if (PyUnicode_CheckExact(*param))
481 Py_INCREF(*param);
482 else if (PyUnicode_Check(*param))
483 /* For a Unicode subtype that's not a Unicode object,
484 return a true Unicode object with the same data. */
485 *param = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(*param),
486 PyUnicode_GET_SIZE(*param));
487 else
488 *param = PyUnicode_FromEncodedObject(*param,
489 Py_FileSystemDefaultEncoding,
490 "strict");
491 return (*param) != NULL;
494 #endif /* Py_WIN_WIDE_FILENAMES */
496 #endif
498 #if defined(PYOS_OS2)
499 /**********************************************************************
500 * Helper Function to Trim and Format OS/2 Messages
501 **********************************************************************/
502 static void
503 os2_formatmsg(char *msgbuf, int msglen, char *reason)
505 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
507 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
508 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
510 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
511 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
514 /* Add Optional Reason Text */
515 if (reason) {
516 strcat(msgbuf, " : ");
517 strcat(msgbuf, reason);
521 /**********************************************************************
522 * Decode an OS/2 Operating System Error Code
524 * A convenience function to lookup an OS/2 error code and return a
525 * text message we can use to raise a Python exception.
527 * Notes:
528 * The messages for errors returned from the OS/2 kernel reside in
529 * the file OSO001.MSG in the \OS2 directory hierarchy.
531 **********************************************************************/
532 static char *
533 os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
535 APIRET rc;
536 ULONG msglen;
538 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
539 Py_BEGIN_ALLOW_THREADS
540 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
541 errorcode, "oso001.msg", &msglen);
542 Py_END_ALLOW_THREADS
544 if (rc == NO_ERROR)
545 os2_formatmsg(msgbuf, msglen, reason);
546 else
547 PyOS_snprintf(msgbuf, msgbuflen,
548 "unknown OS error #%d", errorcode);
550 return msgbuf;
553 /* Set an OS/2-specific error and return NULL. OS/2 kernel
554 errors are not in a global variable e.g. 'errno' nor are
555 they congruent with posix error numbers. */
557 static PyObject * os2_error(int code)
559 char text[1024];
560 PyObject *v;
562 os2_strerror(text, sizeof(text), code, "");
564 v = Py_BuildValue("(is)", code, text);
565 if (v != NULL) {
566 PyErr_SetObject(PyExc_OSError, v);
567 Py_DECREF(v);
569 return NULL; /* Signal to Python that an Exception is Pending */
572 #endif /* OS2 */
574 /* POSIX generic methods */
576 static PyObject *
577 posix_fildes(PyObject *fdobj, int (*func)(int))
579 int fd;
580 int res;
581 fd = PyObject_AsFileDescriptor(fdobj);
582 if (fd < 0)
583 return NULL;
584 Py_BEGIN_ALLOW_THREADS
585 res = (*func)(fd);
586 Py_END_ALLOW_THREADS
587 if (res < 0)
588 return posix_error();
589 Py_INCREF(Py_None);
590 return Py_None;
593 #ifdef Py_WIN_WIDE_FILENAMES
594 static int
595 unicode_file_names(void)
597 static int canusewide = -1;
598 if (canusewide == -1) {
599 /* As per doc for ::GetVersion(), this is the correct test for
600 the Windows NT family. */
601 canusewide = (GetVersion() < 0x80000000) ? 1 : 0;
603 return canusewide;
605 #endif
607 static PyObject *
608 posix_1str(PyObject *args, char *format, int (*func)(const char*))
610 char *path1 = NULL;
611 int res;
612 if (!PyArg_ParseTuple(args, format,
613 Py_FileSystemDefaultEncoding, &path1))
614 return NULL;
615 Py_BEGIN_ALLOW_THREADS
616 res = (*func)(path1);
617 Py_END_ALLOW_THREADS
618 if (res < 0)
619 return posix_error_with_allocated_filename(path1);
620 PyMem_Free(path1);
621 Py_INCREF(Py_None);
622 return Py_None;
625 static PyObject *
626 posix_2str(PyObject *args,
627 char *format,
628 int (*func)(const char *, const char *))
630 char *path1 = NULL, *path2 = NULL;
631 int res;
632 if (!PyArg_ParseTuple(args, format,
633 Py_FileSystemDefaultEncoding, &path1,
634 Py_FileSystemDefaultEncoding, &path2))
635 return NULL;
636 Py_BEGIN_ALLOW_THREADS
637 res = (*func)(path1, path2);
638 Py_END_ALLOW_THREADS
639 PyMem_Free(path1);
640 PyMem_Free(path2);
641 if (res != 0)
642 /* XXX how to report both path1 and path2??? */
643 return posix_error();
644 Py_INCREF(Py_None);
645 return Py_None;
648 #ifdef Py_WIN_WIDE_FILENAMES
649 static PyObject*
650 win32_1str(PyObject* args, char* func,
651 char* format, BOOL (__stdcall *funcA)(LPCSTR),
652 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
654 PyObject *uni;
655 char *ansi;
656 BOOL result;
657 if (unicode_file_names()) {
658 if (!PyArg_ParseTuple(args, wformat, &uni))
659 PyErr_Clear();
660 else {
661 Py_BEGIN_ALLOW_THREADS
662 result = funcW(PyUnicode_AsUnicode(uni));
663 Py_END_ALLOW_THREADS
664 if (!result)
665 return win32_error_unicode(func, PyUnicode_AsUnicode(uni));
666 Py_INCREF(Py_None);
667 return Py_None;
670 if (!PyArg_ParseTuple(args, format, &ansi))
671 return NULL;
672 Py_BEGIN_ALLOW_THREADS
673 result = funcA(ansi);
674 Py_END_ALLOW_THREADS
675 if (!result)
676 return win32_error(func, ansi);
677 Py_INCREF(Py_None);
678 return Py_None;
682 /* This is a reimplementation of the C library's chdir function,
683 but one that produces Win32 errors instead of DOS error codes.
684 chdir is essentially a wrapper around SetCurrentDirectory; however,
685 it also needs to set "magic" environment variables indicating
686 the per-drive current directory, which are of the form =<drive>: */
687 static BOOL __stdcall
688 win32_chdir(LPCSTR path)
690 char new_path[MAX_PATH+1];
691 int result;
692 char env[4] = "=x:";
694 if(!SetCurrentDirectoryA(path))
695 return FALSE;
696 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
697 if (!result)
698 return FALSE;
699 /* In the ANSI API, there should not be any paths longer
700 than MAX_PATH. */
701 assert(result <= MAX_PATH+1);
702 if (strncmp(new_path, "\\\\", 2) == 0 ||
703 strncmp(new_path, "//", 2) == 0)
704 /* UNC path, nothing to do. */
705 return TRUE;
706 env[1] = new_path[0];
707 return SetEnvironmentVariableA(env, new_path);
710 /* The Unicode version differs from the ANSI version
711 since the current directory might exceed MAX_PATH characters */
712 static BOOL __stdcall
713 win32_wchdir(LPCWSTR path)
715 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
716 int result;
717 wchar_t env[4] = L"=x:";
719 if(!SetCurrentDirectoryW(path))
720 return FALSE;
721 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
722 if (!result)
723 return FALSE;
724 if (result > MAX_PATH+1) {
725 new_path = malloc(result * sizeof(wchar_t));
726 if (!new_path) {
727 SetLastError(ERROR_OUTOFMEMORY);
728 return FALSE;
730 result = GetCurrentDirectoryW(result, new_path);
731 if (!result) {
732 free(new_path);
733 return FALSE;
736 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
737 wcsncmp(new_path, L"//", 2) == 0)
738 /* UNC path, nothing to do. */
739 return TRUE;
740 env[1] = new_path[0];
741 result = SetEnvironmentVariableW(env, new_path);
742 if (new_path != _new_path)
743 free(new_path);
744 return result;
746 #endif
748 #ifdef MS_WINDOWS
749 /* The CRT of Windows has a number of flaws wrt. its stat() implementation:
750 - time stamps are restricted to second resolution
751 - file modification times suffer from forth-and-back conversions between
752 UTC and local time
753 Therefore, we implement our own stat, based on the Win32 API directly.
755 #define HAVE_STAT_NSEC 1
757 struct win32_stat{
758 int st_dev;
759 __int64 st_ino;
760 unsigned short st_mode;
761 int st_nlink;
762 int st_uid;
763 int st_gid;
764 int st_rdev;
765 __int64 st_size;
766 int st_atime;
767 int st_atime_nsec;
768 int st_mtime;
769 int st_mtime_nsec;
770 int st_ctime;
771 int st_ctime_nsec;
774 static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
776 static void
777 FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, int *time_out, int* nsec_out)
779 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
780 /* Cannot simply cast and dereference in_ptr,
781 since it might not be aligned properly */
782 __int64 in;
783 memcpy(&in, in_ptr, sizeof(in));
784 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
785 /* XXX Win32 supports time stamps past 2038; we currently don't */
786 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, int);
789 static void
790 time_t_to_FILE_TIME(int time_in, int nsec_in, FILETIME *out_ptr)
792 /* XXX endianness */
793 __int64 out;
794 out = time_in + secs_between_epochs;
795 out = out * 10000000 + nsec_in / 100;
796 memcpy(out_ptr, &out, sizeof(out));
799 /* Below, we *know* that ugo+r is 0444 */
800 #if _S_IREAD != 0400
801 #error Unsupported C library
802 #endif
803 static int
804 attributes_to_mode(DWORD attr)
806 int m = 0;
807 if (attr & FILE_ATTRIBUTE_DIRECTORY)
808 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
809 else
810 m |= _S_IFREG;
811 if (attr & FILE_ATTRIBUTE_READONLY)
812 m |= 0444;
813 else
814 m |= 0666;
815 return m;
818 static int
819 attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *result)
821 memset(result, 0, sizeof(*result));
822 result->st_mode = attributes_to_mode(info->dwFileAttributes);
823 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
824 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
825 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
826 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
828 return 0;
831 /* Emulate GetFileAttributesEx[AW] on Windows 95 */
832 static int checked = 0;
833 static BOOL (CALLBACK *gfaxa)(LPCSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
834 static BOOL (CALLBACK *gfaxw)(LPCWSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
835 static void
836 check_gfax()
838 HINSTANCE hKernel32;
839 if (checked)
840 return;
841 checked = 1;
842 hKernel32 = GetModuleHandle("KERNEL32");
843 *(FARPROC*)&gfaxa = GetProcAddress(hKernel32, "GetFileAttributesExA");
844 *(FARPROC*)&gfaxw = GetProcAddress(hKernel32, "GetFileAttributesExW");
847 static BOOL
848 attributes_from_dir(LPCSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
850 HANDLE hFindFile;
851 WIN32_FIND_DATAA FileData;
852 hFindFile = FindFirstFileA(pszFile, &FileData);
853 if (hFindFile == INVALID_HANDLE_VALUE)
854 return FALSE;
855 FindClose(hFindFile);
856 pfad->dwFileAttributes = FileData.dwFileAttributes;
857 pfad->ftCreationTime = FileData.ftCreationTime;
858 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
859 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
860 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
861 pfad->nFileSizeLow = FileData.nFileSizeLow;
862 return TRUE;
865 static BOOL
866 attributes_from_dir_w(LPCWSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
868 HANDLE hFindFile;
869 WIN32_FIND_DATAW FileData;
870 hFindFile = FindFirstFileW(pszFile, &FileData);
871 if (hFindFile == INVALID_HANDLE_VALUE)
872 return FALSE;
873 FindClose(hFindFile);
874 pfad->dwFileAttributes = FileData.dwFileAttributes;
875 pfad->ftCreationTime = FileData.ftCreationTime;
876 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
877 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
878 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
879 pfad->nFileSizeLow = FileData.nFileSizeLow;
880 return TRUE;
883 static BOOL WINAPI
884 Py_GetFileAttributesExA(LPCSTR pszFile,
885 GET_FILEEX_INFO_LEVELS level,
886 LPVOID pv)
888 BOOL result;
889 LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
890 /* First try to use the system's implementation, if that is
891 available and either succeeds to gives an error other than
892 that it isn't implemented. */
893 check_gfax();
894 if (gfaxa) {
895 result = gfaxa(pszFile, level, pv);
896 if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
897 return result;
899 /* It's either not present, or not implemented.
900 Emulate using FindFirstFile. */
901 if (level != GetFileExInfoStandard) {
902 SetLastError(ERROR_INVALID_PARAMETER);
903 return FALSE;
905 /* Use GetFileAttributes to validate that the file name
906 does not contain wildcards (which FindFirstFile would
907 accept). */
908 if (GetFileAttributesA(pszFile) == 0xFFFFFFFF)
909 return FALSE;
910 return attributes_from_dir(pszFile, pfad);
913 static BOOL WINAPI
914 Py_GetFileAttributesExW(LPCWSTR pszFile,
915 GET_FILEEX_INFO_LEVELS level,
916 LPVOID pv)
918 BOOL result;
919 LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
920 /* First try to use the system's implementation, if that is
921 available and either succeeds to gives an error other than
922 that it isn't implemented. */
923 check_gfax();
924 if (gfaxa) {
925 result = gfaxw(pszFile, level, pv);
926 if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
927 return result;
929 /* It's either not present, or not implemented.
930 Emulate using FindFirstFile. */
931 if (level != GetFileExInfoStandard) {
932 SetLastError(ERROR_INVALID_PARAMETER);
933 return FALSE;
935 /* Use GetFileAttributes to validate that the file name
936 does not contain wildcards (which FindFirstFile would
937 accept). */
938 if (GetFileAttributesW(pszFile) == 0xFFFFFFFF)
939 return FALSE;
940 return attributes_from_dir_w(pszFile, pfad);
943 static int
944 win32_stat(const char* path, struct win32_stat *result)
946 WIN32_FILE_ATTRIBUTE_DATA info;
947 int code;
948 char *dot;
949 /* XXX not supported on Win95 and NT 3.x */
950 if (!Py_GetFileAttributesExA(path, GetFileExInfoStandard, &info)) {
951 if (GetLastError() != ERROR_SHARING_VIOLATION) {
952 /* Protocol violation: we explicitly clear errno, instead of
953 setting it to a POSIX error. Callers should use GetLastError. */
954 errno = 0;
955 return -1;
956 } else {
957 /* Could not get attributes on open file. Fall back to
958 reading the directory. */
959 if (!attributes_from_dir(path, &info)) {
960 /* Very strange. This should not fail now */
961 errno = 0;
962 return -1;
966 code = attribute_data_to_stat(&info, result);
967 if (code != 0)
968 return code;
969 /* Set S_IFEXEC if it is an .exe, .bat, ... */
970 dot = strrchr(path, '.');
971 if (dot) {
972 if (stricmp(dot, ".bat") == 0 ||
973 stricmp(dot, ".cmd") == 0 ||
974 stricmp(dot, ".exe") == 0 ||
975 stricmp(dot, ".com") == 0)
976 result->st_mode |= 0111;
978 return code;
981 static int
982 win32_wstat(const wchar_t* path, struct win32_stat *result)
984 int code;
985 const wchar_t *dot;
986 WIN32_FILE_ATTRIBUTE_DATA info;
987 /* XXX not supported on Win95 and NT 3.x */
988 if (!Py_GetFileAttributesExW(path, GetFileExInfoStandard, &info)) {
989 if (GetLastError() != ERROR_SHARING_VIOLATION) {
990 /* Protocol violation: we explicitly clear errno, instead of
991 setting it to a POSIX error. Callers should use GetLastError. */
992 errno = 0;
993 return -1;
994 } else {
995 /* Could not get attributes on open file. Fall back to
996 reading the directory. */
997 if (!attributes_from_dir_w(path, &info)) {
998 /* Very strange. This should not fail now */
999 errno = 0;
1000 return -1;
1004 code = attribute_data_to_stat(&info, result);
1005 if (code < 0)
1006 return code;
1007 /* Set IFEXEC if it is an .exe, .bat, ... */
1008 dot = wcsrchr(path, '.');
1009 if (dot) {
1010 if (_wcsicmp(dot, L".bat") == 0 ||
1011 _wcsicmp(dot, L".cmd") == 0 ||
1012 _wcsicmp(dot, L".exe") == 0 ||
1013 _wcsicmp(dot, L".com") == 0)
1014 result->st_mode |= 0111;
1016 return code;
1019 static int
1020 win32_fstat(int file_number, struct win32_stat *result)
1022 BY_HANDLE_FILE_INFORMATION info;
1023 HANDLE h;
1024 int type;
1026 h = (HANDLE)_get_osfhandle(file_number);
1028 /* Protocol violation: we explicitly clear errno, instead of
1029 setting it to a POSIX error. Callers should use GetLastError. */
1030 errno = 0;
1032 if (h == INVALID_HANDLE_VALUE) {
1033 /* This is really a C library error (invalid file handle).
1034 We set the Win32 error to the closes one matching. */
1035 SetLastError(ERROR_INVALID_HANDLE);
1036 return -1;
1038 memset(result, 0, sizeof(*result));
1040 type = GetFileType(h);
1041 if (type == FILE_TYPE_UNKNOWN) {
1042 DWORD error = GetLastError();
1043 if (error != 0) {
1044 return -1;
1046 /* else: valid but unknown file */
1049 if (type != FILE_TYPE_DISK) {
1050 if (type == FILE_TYPE_CHAR)
1051 result->st_mode = _S_IFCHR;
1052 else if (type == FILE_TYPE_PIPE)
1053 result->st_mode = _S_IFIFO;
1054 return 0;
1057 if (!GetFileInformationByHandle(h, &info)) {
1058 return -1;
1061 /* similar to stat() */
1062 result->st_mode = attributes_to_mode(info.dwFileAttributes);
1063 result->st_size = (((__int64)info.nFileSizeHigh)<<32) + info.nFileSizeLow;
1064 FILE_TIME_to_time_t_nsec(&info.ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1065 FILE_TIME_to_time_t_nsec(&info.ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1066 FILE_TIME_to_time_t_nsec(&info.ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
1067 /* specific to fstat() */
1068 result->st_nlink = info.nNumberOfLinks;
1069 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1070 return 0;
1073 #endif /* MS_WINDOWS */
1075 PyDoc_STRVAR(stat_result__doc__,
1076 "stat_result: Result from stat or lstat.\n\n\
1077 This object may be accessed either as a tuple of\n\
1078 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
1079 or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1081 Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1082 or st_flags, they are available as attributes only.\n\
1084 See os.stat for more information.");
1086 static PyStructSequence_Field stat_result_fields[] = {
1087 {"st_mode", "protection bits"},
1088 {"st_ino", "inode"},
1089 {"st_dev", "device"},
1090 {"st_nlink", "number of hard links"},
1091 {"st_uid", "user ID of owner"},
1092 {"st_gid", "group ID of owner"},
1093 {"st_size", "total size, in bytes"},
1094 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1095 {NULL, "integer time of last access"},
1096 {NULL, "integer time of last modification"},
1097 {NULL, "integer time of last change"},
1098 {"st_atime", "time of last access"},
1099 {"st_mtime", "time of last modification"},
1100 {"st_ctime", "time of last change"},
1101 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
1102 {"st_blksize", "blocksize for filesystem I/O"},
1103 #endif
1104 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
1105 {"st_blocks", "number of blocks allocated"},
1106 #endif
1107 #ifdef HAVE_STRUCT_STAT_ST_RDEV
1108 {"st_rdev", "device type (if inode device)"},
1109 #endif
1110 #ifdef HAVE_STRUCT_STAT_ST_FLAGS
1111 {"st_flags", "user defined flags for file"},
1112 #endif
1113 #ifdef HAVE_STRUCT_STAT_ST_GEN
1114 {"st_gen", "generation number"},
1115 #endif
1116 #ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1117 {"st_birthtime", "time of creation"},
1118 #endif
1122 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
1123 #define ST_BLKSIZE_IDX 13
1124 #else
1125 #define ST_BLKSIZE_IDX 12
1126 #endif
1128 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
1129 #define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1130 #else
1131 #define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1132 #endif
1134 #ifdef HAVE_STRUCT_STAT_ST_RDEV
1135 #define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1136 #else
1137 #define ST_RDEV_IDX ST_BLOCKS_IDX
1138 #endif
1140 #ifdef HAVE_STRUCT_STAT_ST_FLAGS
1141 #define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1142 #else
1143 #define ST_FLAGS_IDX ST_RDEV_IDX
1144 #endif
1146 #ifdef HAVE_STRUCT_STAT_ST_GEN
1147 #define ST_GEN_IDX (ST_FLAGS_IDX+1)
1148 #else
1149 #define ST_GEN_IDX ST_FLAGS_IDX
1150 #endif
1152 #ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1153 #define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1154 #else
1155 #define ST_BIRTHTIME_IDX ST_GEN_IDX
1156 #endif
1158 static PyStructSequence_Desc stat_result_desc = {
1159 "stat_result", /* name */
1160 stat_result__doc__, /* doc */
1161 stat_result_fields,
1165 PyDoc_STRVAR(statvfs_result__doc__,
1166 "statvfs_result: Result from statvfs or fstatvfs.\n\n\
1167 This object may be accessed either as a tuple of\n\
1168 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
1169 or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
1171 See os.statvfs for more information.");
1173 static PyStructSequence_Field statvfs_result_fields[] = {
1174 {"f_bsize", },
1175 {"f_frsize", },
1176 {"f_blocks", },
1177 {"f_bfree", },
1178 {"f_bavail", },
1179 {"f_files", },
1180 {"f_ffree", },
1181 {"f_favail", },
1182 {"f_flag", },
1183 {"f_namemax",},
1187 static PyStructSequence_Desc statvfs_result_desc = {
1188 "statvfs_result", /* name */
1189 statvfs_result__doc__, /* doc */
1190 statvfs_result_fields,
1194 static int initialized;
1195 static PyTypeObject StatResultType;
1196 static PyTypeObject StatVFSResultType;
1197 static newfunc structseq_new;
1199 static PyObject *
1200 statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1202 PyStructSequence *result;
1203 int i;
1205 result = (PyStructSequence*)structseq_new(type, args, kwds);
1206 if (!result)
1207 return NULL;
1208 /* If we have been initialized from a tuple,
1209 st_?time might be set to None. Initialize it
1210 from the int slots. */
1211 for (i = 7; i <= 9; i++) {
1212 if (result->ob_item[i+3] == Py_None) {
1213 Py_DECREF(Py_None);
1214 Py_INCREF(result->ob_item[i]);
1215 result->ob_item[i+3] = result->ob_item[i];
1218 return (PyObject*)result;
1223 /* If true, st_?time is float. */
1224 static int _stat_float_times = 1;
1226 PyDoc_STRVAR(stat_float_times__doc__,
1227 "stat_float_times([newval]) -> oldval\n\n\
1228 Determine whether os.[lf]stat represents time stamps as float objects.\n\
1229 If newval is True, future calls to stat() return floats, if it is False,\n\
1230 future calls return ints. \n\
1231 If newval is omitted, return the current setting.\n");
1233 static PyObject*
1234 stat_float_times(PyObject* self, PyObject *args)
1236 int newval = -1;
1237 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1238 return NULL;
1239 if (newval == -1)
1240 /* Return old value */
1241 return PyBool_FromLong(_stat_float_times);
1242 _stat_float_times = newval;
1243 Py_INCREF(Py_None);
1244 return Py_None;
1247 static void
1248 fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1250 PyObject *fval,*ival;
1251 #if SIZEOF_TIME_T > SIZEOF_LONG
1252 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
1253 #else
1254 ival = PyInt_FromLong((long)sec);
1255 #endif
1256 if (!ival)
1257 return;
1258 if (_stat_float_times) {
1259 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1260 } else {
1261 fval = ival;
1262 Py_INCREF(fval);
1264 PyStructSequence_SET_ITEM(v, index, ival);
1265 PyStructSequence_SET_ITEM(v, index+3, fval);
1268 /* pack a system stat C structure into the Python stat tuple
1269 (used by posix_stat() and posix_fstat()) */
1270 static PyObject*
1271 _pystat_fromstructstat(STRUCT_STAT *st)
1273 unsigned long ansec, mnsec, cnsec;
1274 PyObject *v = PyStructSequence_New(&StatResultType);
1275 if (v == NULL)
1276 return NULL;
1278 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st->st_mode));
1279 #ifdef HAVE_LARGEFILE_SUPPORT
1280 PyStructSequence_SET_ITEM(v, 1,
1281 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
1282 #else
1283 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st->st_ino));
1284 #endif
1285 #if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
1286 PyStructSequence_SET_ITEM(v, 2,
1287 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
1288 #else
1289 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st->st_dev));
1290 #endif
1291 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st->st_nlink));
1292 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st->st_uid));
1293 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st->st_gid));
1294 #ifdef HAVE_LARGEFILE_SUPPORT
1295 PyStructSequence_SET_ITEM(v, 6,
1296 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
1297 #else
1298 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st->st_size));
1299 #endif
1301 #if defined(HAVE_STAT_TV_NSEC)
1302 ansec = st->st_atim.tv_nsec;
1303 mnsec = st->st_mtim.tv_nsec;
1304 cnsec = st->st_ctim.tv_nsec;
1305 #elif defined(HAVE_STAT_TV_NSEC2)
1306 ansec = st->st_atimespec.tv_nsec;
1307 mnsec = st->st_mtimespec.tv_nsec;
1308 cnsec = st->st_ctimespec.tv_nsec;
1309 #elif defined(HAVE_STAT_NSEC)
1310 ansec = st->st_atime_nsec;
1311 mnsec = st->st_mtime_nsec;
1312 cnsec = st->st_ctime_nsec;
1313 #else
1314 ansec = mnsec = cnsec = 0;
1315 #endif
1316 fill_time(v, 7, st->st_atime, ansec);
1317 fill_time(v, 8, st->st_mtime, mnsec);
1318 fill_time(v, 9, st->st_ctime, cnsec);
1320 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
1321 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
1322 PyInt_FromLong((long)st->st_blksize));
1323 #endif
1324 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
1325 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
1326 PyInt_FromLong((long)st->st_blocks));
1327 #endif
1328 #ifdef HAVE_STRUCT_STAT_ST_RDEV
1329 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
1330 PyInt_FromLong((long)st->st_rdev));
1331 #endif
1332 #ifdef HAVE_STRUCT_STAT_ST_GEN
1333 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
1334 PyInt_FromLong((long)st->st_gen));
1335 #endif
1336 #ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1338 PyObject *val;
1339 unsigned long bsec,bnsec;
1340 bsec = (long)st->st_birthtime;
1341 #ifdef HAVE_STAT_TV_NSEC2
1342 bnsec = st->st_birthtimespec.tv_nsec;
1343 #else
1344 bnsec = 0;
1345 #endif
1346 if (_stat_float_times) {
1347 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1348 } else {
1349 val = PyInt_FromLong((long)bsec);
1351 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1352 val);
1354 #endif
1355 #ifdef HAVE_STRUCT_STAT_ST_FLAGS
1356 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
1357 PyInt_FromLong((long)st->st_flags));
1358 #endif
1360 if (PyErr_Occurred()) {
1361 Py_DECREF(v);
1362 return NULL;
1365 return v;
1368 #ifdef MS_WINDOWS
1370 /* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
1371 where / can be used in place of \ and the trailing slash is optional.
1372 Both SERVER and SHARE must have at least one character.
1375 #define ISSLASHA(c) ((c) == '\\' || (c) == '/')
1376 #define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
1377 #ifndef ARRAYSIZE
1378 #define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
1379 #endif
1381 static BOOL
1382 IsUNCRootA(char *path, int pathlen)
1384 #define ISSLASH ISSLASHA
1386 int i, share;
1388 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1389 /* minimum UNCRoot is \\x\y */
1390 return FALSE;
1391 for (i = 2; i < pathlen ; i++)
1392 if (ISSLASH(path[i])) break;
1393 if (i == 2 || i == pathlen)
1394 /* do not allow \\\SHARE or \\SERVER */
1395 return FALSE;
1396 share = i+1;
1397 for (i = share; i < pathlen; i++)
1398 if (ISSLASH(path[i])) break;
1399 return (i != share && (i == pathlen || i == pathlen-1));
1401 #undef ISSLASH
1404 #ifdef Py_WIN_WIDE_FILENAMES
1405 static BOOL
1406 IsUNCRootW(Py_UNICODE *path, int pathlen)
1408 #define ISSLASH ISSLASHW
1410 int i, share;
1412 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1413 /* minimum UNCRoot is \\x\y */
1414 return FALSE;
1415 for (i = 2; i < pathlen ; i++)
1416 if (ISSLASH(path[i])) break;
1417 if (i == 2 || i == pathlen)
1418 /* do not allow \\\SHARE or \\SERVER */
1419 return FALSE;
1420 share = i+1;
1421 for (i = share; i < pathlen; i++)
1422 if (ISSLASH(path[i])) break;
1423 return (i != share && (i == pathlen || i == pathlen-1));
1425 #undef ISSLASH
1427 #endif /* Py_WIN_WIDE_FILENAMES */
1428 #endif /* MS_WINDOWS */
1430 static PyObject *
1431 posix_do_stat(PyObject *self, PyObject *args,
1432 char *format,
1433 #ifdef __VMS
1434 int (*statfunc)(const char *, STRUCT_STAT *, ...),
1435 #else
1436 int (*statfunc)(const char *, STRUCT_STAT *),
1437 #endif
1438 char *wformat,
1439 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
1441 STRUCT_STAT st;
1442 char *path = NULL; /* pass this to stat; do not free() it */
1443 char *pathfree = NULL; /* this memory must be free'd */
1444 int res;
1445 PyObject *result;
1447 #ifdef Py_WIN_WIDE_FILENAMES
1448 /* If on wide-character-capable OS see if argument
1449 is Unicode and if so use wide API. */
1450 if (unicode_file_names()) {
1451 PyUnicodeObject *po;
1452 if (PyArg_ParseTuple(args, wformat, &po)) {
1453 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
1455 Py_BEGIN_ALLOW_THREADS
1456 /* PyUnicode_AS_UNICODE result OK without
1457 thread lock as it is a simple dereference. */
1458 res = wstatfunc(wpath, &st);
1459 Py_END_ALLOW_THREADS
1461 if (res != 0)
1462 return win32_error_unicode("stat", wpath);
1463 return _pystat_fromstructstat(&st);
1465 /* Drop the argument parsing error as narrow strings
1466 are also valid. */
1467 PyErr_Clear();
1469 #endif
1471 if (!PyArg_ParseTuple(args, format,
1472 Py_FileSystemDefaultEncoding, &path))
1473 return NULL;
1474 pathfree = path;
1476 Py_BEGIN_ALLOW_THREADS
1477 res = (*statfunc)(path, &st);
1478 Py_END_ALLOW_THREADS
1480 if (res != 0) {
1481 #ifdef MS_WINDOWS
1482 result = win32_error("stat", pathfree);
1483 #else
1484 result = posix_error_with_filename(pathfree);
1485 #endif
1487 else
1488 result = _pystat_fromstructstat(&st);
1490 PyMem_Free(pathfree);
1491 return result;
1494 /* POSIX methods */
1496 PyDoc_STRVAR(posix_access__doc__,
1497 "access(path, mode) -> True if granted, False otherwise\n\n\
1498 Use the real uid/gid to test for access to a path. Note that most\n\
1499 operations will use the effective uid/gid, therefore this routine can\n\
1500 be used in a suid/sgid environment to test if the invoking user has the\n\
1501 specified access to the path. The mode argument can be F_OK to test\n\
1502 existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
1504 static PyObject *
1505 posix_access(PyObject *self, PyObject *args)
1507 char *path;
1508 int mode;
1510 #ifdef Py_WIN_WIDE_FILENAMES
1511 DWORD attr;
1512 if (unicode_file_names()) {
1513 PyUnicodeObject *po;
1514 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1515 Py_BEGIN_ALLOW_THREADS
1516 /* PyUnicode_AS_UNICODE OK without thread lock as
1517 it is a simple dereference. */
1518 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1519 Py_END_ALLOW_THREADS
1520 goto finish;
1522 /* Drop the argument parsing error as narrow strings
1523 are also valid. */
1524 PyErr_Clear();
1526 if (!PyArg_ParseTuple(args, "eti:access",
1527 Py_FileSystemDefaultEncoding, &path, &mode))
1528 return 0;
1529 Py_BEGIN_ALLOW_THREADS
1530 attr = GetFileAttributesA(path);
1531 Py_END_ALLOW_THREADS
1532 PyMem_Free(path);
1533 finish:
1534 if (attr == 0xFFFFFFFF)
1535 /* File does not exist, or cannot read attributes */
1536 return PyBool_FromLong(0);
1537 /* Access is possible if either write access wasn't requested, or
1538 the file isn't read-only, or if it's a directory, as there are
1539 no read-only directories on Windows. */
1540 return PyBool_FromLong(!(mode & 2)
1541 || !(attr & FILE_ATTRIBUTE_READONLY)
1542 || (attr & FILE_ATTRIBUTE_DIRECTORY));
1543 #else
1544 int res;
1545 if (!PyArg_ParseTuple(args, "eti:access",
1546 Py_FileSystemDefaultEncoding, &path, &mode))
1547 return NULL;
1548 Py_BEGIN_ALLOW_THREADS
1549 res = access(path, mode);
1550 Py_END_ALLOW_THREADS
1551 PyMem_Free(path);
1552 return PyBool_FromLong(res == 0);
1553 #endif
1556 #ifndef F_OK
1557 #define F_OK 0
1558 #endif
1559 #ifndef R_OK
1560 #define R_OK 4
1561 #endif
1562 #ifndef W_OK
1563 #define W_OK 2
1564 #endif
1565 #ifndef X_OK
1566 #define X_OK 1
1567 #endif
1569 #ifdef HAVE_TTYNAME
1570 PyDoc_STRVAR(posix_ttyname__doc__,
1571 "ttyname(fd) -> string\n\n\
1572 Return the name of the terminal device connected to 'fd'.");
1574 static PyObject *
1575 posix_ttyname(PyObject *self, PyObject *args)
1577 int id;
1578 char *ret;
1580 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
1581 return NULL;
1583 #if defined(__VMS)
1584 /* file descriptor 0 only, the default input device (stdin) */
1585 if (id == 0) {
1586 ret = ttyname();
1588 else {
1589 ret = NULL;
1591 #else
1592 ret = ttyname(id);
1593 #endif
1594 if (ret == NULL)
1595 return posix_error();
1596 return PyString_FromString(ret);
1598 #endif
1600 #ifdef HAVE_CTERMID
1601 PyDoc_STRVAR(posix_ctermid__doc__,
1602 "ctermid() -> string\n\n\
1603 Return the name of the controlling terminal for this process.");
1605 static PyObject *
1606 posix_ctermid(PyObject *self, PyObject *noargs)
1608 char *ret;
1609 char buffer[L_ctermid];
1611 #ifdef USE_CTERMID_R
1612 ret = ctermid_r(buffer);
1613 #else
1614 ret = ctermid(buffer);
1615 #endif
1616 if (ret == NULL)
1617 return posix_error();
1618 return PyString_FromString(buffer);
1620 #endif
1622 PyDoc_STRVAR(posix_chdir__doc__,
1623 "chdir(path)\n\n\
1624 Change the current working directory to the specified path.");
1626 static PyObject *
1627 posix_chdir(PyObject *self, PyObject *args)
1629 #ifdef MS_WINDOWS
1630 return win32_1str(args, "chdir", "s:chdir", win32_chdir, "U:chdir", win32_wchdir);
1631 #elif defined(PYOS_OS2) && defined(PYCC_GCC)
1632 return posix_1str(args, "et:chdir", _chdir2);
1633 #elif defined(__VMS)
1634 return posix_1str(args, "et:chdir", (int (*)(const char *))chdir);
1635 #else
1636 return posix_1str(args, "et:chdir", chdir);
1637 #endif
1640 #ifdef HAVE_FCHDIR
1641 PyDoc_STRVAR(posix_fchdir__doc__,
1642 "fchdir(fildes)\n\n\
1643 Change to the directory of the given file descriptor. fildes must be\n\
1644 opened on a directory, not a file.");
1646 static PyObject *
1647 posix_fchdir(PyObject *self, PyObject *fdobj)
1649 return posix_fildes(fdobj, fchdir);
1651 #endif /* HAVE_FCHDIR */
1654 PyDoc_STRVAR(posix_chmod__doc__,
1655 "chmod(path, mode)\n\n\
1656 Change the access permissions of a file.");
1658 static PyObject *
1659 posix_chmod(PyObject *self, PyObject *args)
1661 char *path = NULL;
1662 int i;
1663 int res;
1664 #ifdef Py_WIN_WIDE_FILENAMES
1665 DWORD attr;
1666 if (unicode_file_names()) {
1667 PyUnicodeObject *po;
1668 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1669 Py_BEGIN_ALLOW_THREADS
1670 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1671 if (attr != 0xFFFFFFFF) {
1672 if (i & _S_IWRITE)
1673 attr &= ~FILE_ATTRIBUTE_READONLY;
1674 else
1675 attr |= FILE_ATTRIBUTE_READONLY;
1676 res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
1678 else
1679 res = 0;
1680 Py_END_ALLOW_THREADS
1681 if (!res)
1682 return win32_error_unicode("chmod",
1683 PyUnicode_AS_UNICODE(po));
1684 Py_INCREF(Py_None);
1685 return Py_None;
1687 /* Drop the argument parsing error as narrow strings
1688 are also valid. */
1689 PyErr_Clear();
1691 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
1692 &path, &i))
1693 return NULL;
1694 Py_BEGIN_ALLOW_THREADS
1695 attr = GetFileAttributesA(path);
1696 if (attr != 0xFFFFFFFF) {
1697 if (i & _S_IWRITE)
1698 attr &= ~FILE_ATTRIBUTE_READONLY;
1699 else
1700 attr |= FILE_ATTRIBUTE_READONLY;
1701 res = SetFileAttributesA(path, attr);
1703 else
1704 res = 0;
1705 Py_END_ALLOW_THREADS
1706 if (!res) {
1707 win32_error("chmod", path);
1708 PyMem_Free(path);
1709 return NULL;
1711 PyMem_Free(path);
1712 Py_INCREF(Py_None);
1713 return Py_None;
1714 #else /* Py_WIN_WIDE_FILENAMES */
1715 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
1716 &path, &i))
1717 return NULL;
1718 Py_BEGIN_ALLOW_THREADS
1719 res = chmod(path, i);
1720 Py_END_ALLOW_THREADS
1721 if (res < 0)
1722 return posix_error_with_allocated_filename(path);
1723 PyMem_Free(path);
1724 Py_INCREF(Py_None);
1725 return Py_None;
1726 #endif
1729 #ifdef HAVE_FCHMOD
1730 PyDoc_STRVAR(posix_fchmod__doc__,
1731 "fchmod(fd, mode)\n\n\
1732 Change the access permissions of the file given by file\n\
1733 descriptor fd.");
1735 static PyObject *
1736 posix_fchmod(PyObject *self, PyObject *args)
1738 int fd, mode, res;
1739 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
1740 return NULL;
1741 Py_BEGIN_ALLOW_THREADS
1742 res = fchmod(fd, mode);
1743 Py_END_ALLOW_THREADS
1744 if (res < 0)
1745 return posix_error();
1746 Py_RETURN_NONE;
1748 #endif /* HAVE_FCHMOD */
1750 #ifdef HAVE_LCHMOD
1751 PyDoc_STRVAR(posix_lchmod__doc__,
1752 "lchmod(path, mode)\n\n\
1753 Change the access permissions of a file. If path is a symlink, this\n\
1754 affects the link itself rather than the target.");
1756 static PyObject *
1757 posix_lchmod(PyObject *self, PyObject *args)
1759 char *path = NULL;
1760 int i;
1761 int res;
1762 if (!PyArg_ParseTuple(args, "eti:lchmod", Py_FileSystemDefaultEncoding,
1763 &path, &i))
1764 return NULL;
1765 Py_BEGIN_ALLOW_THREADS
1766 res = lchmod(path, i);
1767 Py_END_ALLOW_THREADS
1768 if (res < 0)
1769 return posix_error_with_allocated_filename(path);
1770 PyMem_Free(path);
1771 Py_RETURN_NONE;
1773 #endif /* HAVE_LCHMOD */
1776 #ifdef HAVE_CHFLAGS
1777 PyDoc_STRVAR(posix_chflags__doc__,
1778 "chflags(path, flags)\n\n\
1779 Set file flags.");
1781 static PyObject *
1782 posix_chflags(PyObject *self, PyObject *args)
1784 char *path;
1785 unsigned long flags;
1786 int res;
1787 if (!PyArg_ParseTuple(args, "etk:chflags",
1788 Py_FileSystemDefaultEncoding, &path, &flags))
1789 return NULL;
1790 Py_BEGIN_ALLOW_THREADS
1791 res = chflags(path, flags);
1792 Py_END_ALLOW_THREADS
1793 if (res < 0)
1794 return posix_error_with_allocated_filename(path);
1795 PyMem_Free(path);
1796 Py_INCREF(Py_None);
1797 return Py_None;
1799 #endif /* HAVE_CHFLAGS */
1801 #ifdef HAVE_LCHFLAGS
1802 PyDoc_STRVAR(posix_lchflags__doc__,
1803 "lchflags(path, flags)\n\n\
1804 Set file flags.\n\
1805 This function will not follow symbolic links.");
1807 static PyObject *
1808 posix_lchflags(PyObject *self, PyObject *args)
1810 char *path;
1811 unsigned long flags;
1812 int res;
1813 if (!PyArg_ParseTuple(args, "etk:lchflags",
1814 Py_FileSystemDefaultEncoding, &path, &flags))
1815 return NULL;
1816 Py_BEGIN_ALLOW_THREADS
1817 res = lchflags(path, flags);
1818 Py_END_ALLOW_THREADS
1819 if (res < 0)
1820 return posix_error_with_allocated_filename(path);
1821 PyMem_Free(path);
1822 Py_INCREF(Py_None);
1823 return Py_None;
1825 #endif /* HAVE_LCHFLAGS */
1827 #ifdef HAVE_CHROOT
1828 PyDoc_STRVAR(posix_chroot__doc__,
1829 "chroot(path)\n\n\
1830 Change root directory to path.");
1832 static PyObject *
1833 posix_chroot(PyObject *self, PyObject *args)
1835 return posix_1str(args, "et:chroot", chroot);
1837 #endif
1839 #ifdef HAVE_FSYNC
1840 PyDoc_STRVAR(posix_fsync__doc__,
1841 "fsync(fildes)\n\n\
1842 force write of file with filedescriptor to disk.");
1844 static PyObject *
1845 posix_fsync(PyObject *self, PyObject *fdobj)
1847 return posix_fildes(fdobj, fsync);
1849 #endif /* HAVE_FSYNC */
1851 #ifdef HAVE_FDATASYNC
1853 #ifdef __hpux
1854 extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1855 #endif
1857 PyDoc_STRVAR(posix_fdatasync__doc__,
1858 "fdatasync(fildes)\n\n\
1859 force write of file with filedescriptor to disk.\n\
1860 does not force update of metadata.");
1862 static PyObject *
1863 posix_fdatasync(PyObject *self, PyObject *fdobj)
1865 return posix_fildes(fdobj, fdatasync);
1867 #endif /* HAVE_FDATASYNC */
1870 #ifdef HAVE_CHOWN
1871 PyDoc_STRVAR(posix_chown__doc__,
1872 "chown(path, uid, gid)\n\n\
1873 Change the owner and group id of path to the numeric uid and gid.");
1875 static PyObject *
1876 posix_chown(PyObject *self, PyObject *args)
1878 char *path = NULL;
1879 long uid, gid;
1880 int res;
1881 if (!PyArg_ParseTuple(args, "etll:chown",
1882 Py_FileSystemDefaultEncoding, &path,
1883 &uid, &gid))
1884 return NULL;
1885 Py_BEGIN_ALLOW_THREADS
1886 res = chown(path, (uid_t) uid, (gid_t) gid);
1887 Py_END_ALLOW_THREADS
1888 if (res < 0)
1889 return posix_error_with_allocated_filename(path);
1890 PyMem_Free(path);
1891 Py_INCREF(Py_None);
1892 return Py_None;
1894 #endif /* HAVE_CHOWN */
1896 #ifdef HAVE_FCHOWN
1897 PyDoc_STRVAR(posix_fchown__doc__,
1898 "fchown(fd, uid, gid)\n\n\
1899 Change the owner and group id of the file given by file descriptor\n\
1900 fd to the numeric uid and gid.");
1902 static PyObject *
1903 posix_fchown(PyObject *self, PyObject *args)
1905 int fd, uid, gid;
1906 int res;
1907 if (!PyArg_ParseTuple(args, "iii:chown", &fd, &uid, &gid))
1908 return NULL;
1909 Py_BEGIN_ALLOW_THREADS
1910 res = fchown(fd, (uid_t) uid, (gid_t) gid);
1911 Py_END_ALLOW_THREADS
1912 if (res < 0)
1913 return posix_error();
1914 Py_RETURN_NONE;
1916 #endif /* HAVE_FCHOWN */
1918 #ifdef HAVE_LCHOWN
1919 PyDoc_STRVAR(posix_lchown__doc__,
1920 "lchown(path, uid, gid)\n\n\
1921 Change the owner and group id of path to the numeric uid and gid.\n\
1922 This function will not follow symbolic links.");
1924 static PyObject *
1925 posix_lchown(PyObject *self, PyObject *args)
1927 char *path = NULL;
1928 int uid, gid;
1929 int res;
1930 if (!PyArg_ParseTuple(args, "etii:lchown",
1931 Py_FileSystemDefaultEncoding, &path,
1932 &uid, &gid))
1933 return NULL;
1934 Py_BEGIN_ALLOW_THREADS
1935 res = lchown(path, (uid_t) uid, (gid_t) gid);
1936 Py_END_ALLOW_THREADS
1937 if (res < 0)
1938 return posix_error_with_allocated_filename(path);
1939 PyMem_Free(path);
1940 Py_INCREF(Py_None);
1941 return Py_None;
1943 #endif /* HAVE_LCHOWN */
1946 #ifdef HAVE_GETCWD
1947 PyDoc_STRVAR(posix_getcwd__doc__,
1948 "getcwd() -> path\n\n\
1949 Return a string representing the current working directory.");
1951 static PyObject *
1952 posix_getcwd(PyObject *self, PyObject *noargs)
1954 int bufsize_incr = 1024;
1955 int bufsize = 0;
1956 char *tmpbuf = NULL;
1957 char *res = NULL;
1958 PyObject *dynamic_return;
1960 Py_BEGIN_ALLOW_THREADS
1961 do {
1962 bufsize = bufsize + bufsize_incr;
1963 tmpbuf = malloc(bufsize);
1964 if (tmpbuf == NULL) {
1965 break;
1967 #if defined(PYOS_OS2) && defined(PYCC_GCC)
1968 res = _getcwd2(tmpbuf, bufsize);
1969 #else
1970 res = getcwd(tmpbuf, bufsize);
1971 #endif
1973 if (res == NULL) {
1974 free(tmpbuf);
1976 } while ((res == NULL) && (errno == ERANGE));
1977 Py_END_ALLOW_THREADS
1979 if (res == NULL)
1980 return posix_error();
1982 dynamic_return = PyString_FromString(tmpbuf);
1983 free(tmpbuf);
1985 return dynamic_return;
1988 #ifdef Py_USING_UNICODE
1989 PyDoc_STRVAR(posix_getcwdu__doc__,
1990 "getcwdu() -> path\n\n\
1991 Return a unicode string representing the current working directory.");
1993 static PyObject *
1994 posix_getcwdu(PyObject *self, PyObject *noargs)
1996 char buf[1026];
1997 char *res;
1999 #ifdef Py_WIN_WIDE_FILENAMES
2000 DWORD len;
2001 if (unicode_file_names()) {
2002 wchar_t wbuf[1026];
2003 wchar_t *wbuf2 = wbuf;
2004 PyObject *resobj;
2005 Py_BEGIN_ALLOW_THREADS
2006 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
2007 /* If the buffer is large enough, len does not include the
2008 terminating \0. If the buffer is too small, len includes
2009 the space needed for the terminator. */
2010 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
2011 wbuf2 = malloc(len * sizeof(wchar_t));
2012 if (wbuf2)
2013 len = GetCurrentDirectoryW(len, wbuf2);
2015 Py_END_ALLOW_THREADS
2016 if (!wbuf2) {
2017 PyErr_NoMemory();
2018 return NULL;
2020 if (!len) {
2021 if (wbuf2 != wbuf) free(wbuf2);
2022 return win32_error("getcwdu", NULL);
2024 resobj = PyUnicode_FromWideChar(wbuf2, len);
2025 if (wbuf2 != wbuf) free(wbuf2);
2026 return resobj;
2028 #endif
2030 Py_BEGIN_ALLOW_THREADS
2031 #if defined(PYOS_OS2) && defined(PYCC_GCC)
2032 res = _getcwd2(buf, sizeof buf);
2033 #else
2034 res = getcwd(buf, sizeof buf);
2035 #endif
2036 Py_END_ALLOW_THREADS
2037 if (res == NULL)
2038 return posix_error();
2039 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
2041 #endif
2042 #endif
2045 #ifdef HAVE_LINK
2046 PyDoc_STRVAR(posix_link__doc__,
2047 "link(src, dst)\n\n\
2048 Create a hard link to a file.");
2050 static PyObject *
2051 posix_link(PyObject *self, PyObject *args)
2053 return posix_2str(args, "etet:link", link);
2055 #endif /* HAVE_LINK */
2058 PyDoc_STRVAR(posix_listdir__doc__,
2059 "listdir(path) -> list_of_strings\n\n\
2060 Return a list containing the names of the entries in the directory.\n\
2062 path: path of directory to list\n\
2064 The list is in arbitrary order. It does not include the special\n\
2065 entries '.' and '..' even if they are present in the directory.");
2067 static PyObject *
2068 posix_listdir(PyObject *self, PyObject *args)
2070 /* XXX Should redo this putting the (now four) versions of opendir
2071 in separate files instead of having them all here... */
2072 #if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
2074 PyObject *d, *v;
2075 HANDLE hFindFile;
2076 BOOL result;
2077 WIN32_FIND_DATA FileData;
2078 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
2079 char *bufptr = namebuf;
2080 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
2082 #ifdef Py_WIN_WIDE_FILENAMES
2083 /* If on wide-character-capable OS see if argument
2084 is Unicode and if so use wide API. */
2085 if (unicode_file_names()) {
2086 PyObject *po;
2087 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
2088 WIN32_FIND_DATAW wFileData;
2089 Py_UNICODE *wnamebuf;
2090 Py_UNICODE wch;
2091 /* Overallocate for \\*.*\0 */
2092 len = PyUnicode_GET_SIZE(po);
2093 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
2094 if (!wnamebuf) {
2095 PyErr_NoMemory();
2096 return NULL;
2098 wcscpy(wnamebuf, PyUnicode_AS_UNICODE(po));
2099 wch = len > 0 ? wnamebuf[len-1] : '\0';
2100 if (wch != L'/' && wch != L'\\' && wch != L':')
2101 wnamebuf[len++] = L'\\';
2102 wcscpy(wnamebuf + len, L"*.*");
2103 if ((d = PyList_New(0)) == NULL) {
2104 free(wnamebuf);
2105 return NULL;
2107 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
2108 if (hFindFile == INVALID_HANDLE_VALUE) {
2109 int error = GetLastError();
2110 if (error == ERROR_FILE_NOT_FOUND) {
2111 free(wnamebuf);
2112 return d;
2114 Py_DECREF(d);
2115 win32_error_unicode("FindFirstFileW", wnamebuf);
2116 free(wnamebuf);
2117 return NULL;
2119 do {
2120 /* Skip over . and .. */
2121 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2122 wcscmp(wFileData.cFileName, L"..") != 0) {
2123 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
2124 if (v == NULL) {
2125 Py_DECREF(d);
2126 d = NULL;
2127 break;
2129 if (PyList_Append(d, v) != 0) {
2130 Py_DECREF(v);
2131 Py_DECREF(d);
2132 d = NULL;
2133 break;
2135 Py_DECREF(v);
2137 Py_BEGIN_ALLOW_THREADS
2138 result = FindNextFileW(hFindFile, &wFileData);
2139 Py_END_ALLOW_THREADS
2140 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2141 it got to the end of the directory. */
2142 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2143 Py_DECREF(d);
2144 win32_error_unicode("FindNextFileW", wnamebuf);
2145 FindClose(hFindFile);
2146 free(wnamebuf);
2147 return NULL;
2149 } while (result == TRUE);
2151 if (FindClose(hFindFile) == FALSE) {
2152 Py_DECREF(d);
2153 win32_error_unicode("FindClose", wnamebuf);
2154 free(wnamebuf);
2155 return NULL;
2157 free(wnamebuf);
2158 return d;
2160 /* Drop the argument parsing error as narrow strings
2161 are also valid. */
2162 PyErr_Clear();
2164 #endif
2166 if (!PyArg_ParseTuple(args, "et#:listdir",
2167 Py_FileSystemDefaultEncoding, &bufptr, &len))
2168 return NULL;
2169 if (len > 0) {
2170 char ch = namebuf[len-1];
2171 if (ch != SEP && ch != ALTSEP && ch != ':')
2172 namebuf[len++] = '/';
2174 strcpy(namebuf + len, "*.*");
2176 if ((d = PyList_New(0)) == NULL)
2177 return NULL;
2179 hFindFile = FindFirstFile(namebuf, &FileData);
2180 if (hFindFile == INVALID_HANDLE_VALUE) {
2181 int error = GetLastError();
2182 if (error == ERROR_FILE_NOT_FOUND)
2183 return d;
2184 Py_DECREF(d);
2185 return win32_error("FindFirstFile", namebuf);
2187 do {
2188 /* Skip over . and .. */
2189 if (strcmp(FileData.cFileName, ".") != 0 &&
2190 strcmp(FileData.cFileName, "..") != 0) {
2191 v = PyString_FromString(FileData.cFileName);
2192 if (v == NULL) {
2193 Py_DECREF(d);
2194 d = NULL;
2195 break;
2197 if (PyList_Append(d, v) != 0) {
2198 Py_DECREF(v);
2199 Py_DECREF(d);
2200 d = NULL;
2201 break;
2203 Py_DECREF(v);
2205 Py_BEGIN_ALLOW_THREADS
2206 result = FindNextFile(hFindFile, &FileData);
2207 Py_END_ALLOW_THREADS
2208 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2209 it got to the end of the directory. */
2210 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2211 Py_DECREF(d);
2212 win32_error("FindNextFile", namebuf);
2213 FindClose(hFindFile);
2214 return NULL;
2216 } while (result == TRUE);
2218 if (FindClose(hFindFile) == FALSE) {
2219 Py_DECREF(d);
2220 return win32_error("FindClose", namebuf);
2223 return d;
2225 #elif defined(PYOS_OS2)
2227 #ifndef MAX_PATH
2228 #define MAX_PATH CCHMAXPATH
2229 #endif
2230 char *name, *pt;
2231 Py_ssize_t len;
2232 PyObject *d, *v;
2233 char namebuf[MAX_PATH+5];
2234 HDIR hdir = 1;
2235 ULONG srchcnt = 1;
2236 FILEFINDBUF3 ep;
2237 APIRET rc;
2239 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
2240 return NULL;
2241 if (len >= MAX_PATH) {
2242 PyErr_SetString(PyExc_ValueError, "path too long");
2243 return NULL;
2245 strcpy(namebuf, name);
2246 for (pt = namebuf; *pt; pt++)
2247 if (*pt == ALTSEP)
2248 *pt = SEP;
2249 if (namebuf[len-1] != SEP)
2250 namebuf[len++] = SEP;
2251 strcpy(namebuf + len, "*.*");
2253 if ((d = PyList_New(0)) == NULL)
2254 return NULL;
2256 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2257 &hdir, /* Handle to Use While Search Directory */
2258 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
2259 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2260 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2261 FIL_STANDARD); /* Format of Entry (EAs or Not) */
2263 if (rc != NO_ERROR) {
2264 errno = ENOENT;
2265 return posix_error_with_filename(name);
2268 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
2269 do {
2270 if (ep.achName[0] == '.'
2271 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
2272 continue; /* Skip Over "." and ".." Names */
2274 strcpy(namebuf, ep.achName);
2276 /* Leave Case of Name Alone -- In Native Form */
2277 /* (Removed Forced Lowercasing Code) */
2279 v = PyString_FromString(namebuf);
2280 if (v == NULL) {
2281 Py_DECREF(d);
2282 d = NULL;
2283 break;
2285 if (PyList_Append(d, v) != 0) {
2286 Py_DECREF(v);
2287 Py_DECREF(d);
2288 d = NULL;
2289 break;
2291 Py_DECREF(v);
2292 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2295 return d;
2296 #else
2298 char *name = NULL;
2299 PyObject *d, *v;
2300 DIR *dirp;
2301 struct dirent *ep;
2302 int arg_is_unicode = 1;
2304 errno = 0;
2305 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
2306 arg_is_unicode = 0;
2307 PyErr_Clear();
2309 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
2310 return NULL;
2311 if ((dirp = opendir(name)) == NULL) {
2312 return posix_error_with_allocated_filename(name);
2314 if ((d = PyList_New(0)) == NULL) {
2315 closedir(dirp);
2316 PyMem_Free(name);
2317 return NULL;
2319 for (;;) {
2320 errno = 0;
2321 Py_BEGIN_ALLOW_THREADS
2322 ep = readdir(dirp);
2323 Py_END_ALLOW_THREADS
2324 if (ep == NULL) {
2325 if (errno == 0) {
2326 break;
2327 } else {
2328 closedir(dirp);
2329 Py_DECREF(d);
2330 return posix_error_with_allocated_filename(name);
2333 if (ep->d_name[0] == '.' &&
2334 (NAMLEN(ep) == 1 ||
2335 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
2336 continue;
2337 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
2338 if (v == NULL) {
2339 Py_DECREF(d);
2340 d = NULL;
2341 break;
2343 #ifdef Py_USING_UNICODE
2344 if (arg_is_unicode) {
2345 PyObject *w;
2347 w = PyUnicode_FromEncodedObject(v,
2348 Py_FileSystemDefaultEncoding,
2349 "strict");
2350 if (w != NULL) {
2351 Py_DECREF(v);
2352 v = w;
2354 else {
2355 /* fall back to the original byte string, as
2356 discussed in patch #683592 */
2357 PyErr_Clear();
2360 #endif
2361 if (PyList_Append(d, v) != 0) {
2362 Py_DECREF(v);
2363 Py_DECREF(d);
2364 d = NULL;
2365 break;
2367 Py_DECREF(v);
2369 closedir(dirp);
2370 PyMem_Free(name);
2372 return d;
2374 #endif /* which OS */
2375 } /* end of posix_listdir */
2377 #ifdef MS_WINDOWS
2378 /* A helper function for abspath on win32 */
2379 static PyObject *
2380 posix__getfullpathname(PyObject *self, PyObject *args)
2382 /* assume encoded strings wont more than double no of chars */
2383 char inbuf[MAX_PATH*2];
2384 char *inbufp = inbuf;
2385 Py_ssize_t insize = sizeof(inbuf);
2386 char outbuf[MAX_PATH*2];
2387 char *temp;
2388 #ifdef Py_WIN_WIDE_FILENAMES
2389 if (unicode_file_names()) {
2390 PyUnicodeObject *po;
2391 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
2392 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
2393 Py_UNICODE woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
2394 Py_UNICODE *wtemp;
2395 DWORD result;
2396 PyObject *v;
2397 result = GetFullPathNameW(wpath,
2398 sizeof(woutbuf)/sizeof(woutbuf[0]),
2399 woutbuf, &wtemp);
2400 if (result > sizeof(woutbuf)/sizeof(woutbuf[0])) {
2401 woutbufp = malloc(result * sizeof(Py_UNICODE));
2402 if (!woutbufp)
2403 return PyErr_NoMemory();
2404 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
2406 if (result)
2407 v = PyUnicode_FromUnicode(woutbufp, wcslen(woutbufp));
2408 else
2409 v = win32_error_unicode("GetFullPathNameW", wpath);
2410 if (woutbufp != woutbuf)
2411 free(woutbufp);
2412 return v;
2414 /* Drop the argument parsing error as narrow strings
2415 are also valid. */
2416 PyErr_Clear();
2418 #endif
2419 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
2420 Py_FileSystemDefaultEncoding, &inbufp,
2421 &insize))
2422 return NULL;
2423 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
2424 outbuf, &temp))
2425 return win32_error("GetFullPathName", inbuf);
2426 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2427 return PyUnicode_Decode(outbuf, strlen(outbuf),
2428 Py_FileSystemDefaultEncoding, NULL);
2430 return PyString_FromString(outbuf);
2431 } /* end of posix__getfullpathname */
2432 #endif /* MS_WINDOWS */
2434 PyDoc_STRVAR(posix_mkdir__doc__,
2435 "mkdir(path [, mode=0777])\n\n\
2436 Create a directory.");
2438 static PyObject *
2439 posix_mkdir(PyObject *self, PyObject *args)
2441 int res;
2442 char *path = NULL;
2443 int mode = 0777;
2445 #ifdef Py_WIN_WIDE_FILENAMES
2446 if (unicode_file_names()) {
2447 PyUnicodeObject *po;
2448 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
2449 Py_BEGIN_ALLOW_THREADS
2450 /* PyUnicode_AS_UNICODE OK without thread lock as
2451 it is a simple dereference. */
2452 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
2453 Py_END_ALLOW_THREADS
2454 if (!res)
2455 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
2456 Py_INCREF(Py_None);
2457 return Py_None;
2459 /* Drop the argument parsing error as narrow strings
2460 are also valid. */
2461 PyErr_Clear();
2463 if (!PyArg_ParseTuple(args, "et|i:mkdir",
2464 Py_FileSystemDefaultEncoding, &path, &mode))
2465 return NULL;
2466 Py_BEGIN_ALLOW_THREADS
2467 /* PyUnicode_AS_UNICODE OK without thread lock as
2468 it is a simple dereference. */
2469 res = CreateDirectoryA(path, NULL);
2470 Py_END_ALLOW_THREADS
2471 if (!res) {
2472 win32_error("mkdir", path);
2473 PyMem_Free(path);
2474 return NULL;
2476 PyMem_Free(path);
2477 Py_INCREF(Py_None);
2478 return Py_None;
2479 #else
2481 if (!PyArg_ParseTuple(args, "et|i:mkdir",
2482 Py_FileSystemDefaultEncoding, &path, &mode))
2483 return NULL;
2484 Py_BEGIN_ALLOW_THREADS
2485 #if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
2486 res = mkdir(path);
2487 #else
2488 res = mkdir(path, mode);
2489 #endif
2490 Py_END_ALLOW_THREADS
2491 if (res < 0)
2492 return posix_error_with_allocated_filename(path);
2493 PyMem_Free(path);
2494 Py_INCREF(Py_None);
2495 return Py_None;
2496 #endif
2500 /* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2501 #if defined(HAVE_SYS_RESOURCE_H)
2502 #include <sys/resource.h>
2503 #endif
2506 #ifdef HAVE_NICE
2507 PyDoc_STRVAR(posix_nice__doc__,
2508 "nice(inc) -> new_priority\n\n\
2509 Decrease the priority of process by inc and return the new priority.");
2511 static PyObject *
2512 posix_nice(PyObject *self, PyObject *args)
2514 int increment, value;
2516 if (!PyArg_ParseTuple(args, "i:nice", &increment))
2517 return NULL;
2519 /* There are two flavours of 'nice': one that returns the new
2520 priority (as required by almost all standards out there) and the
2521 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2522 the use of getpriority() to get the new priority.
2524 If we are of the nice family that returns the new priority, we
2525 need to clear errno before the call, and check if errno is filled
2526 before calling posix_error() on a returnvalue of -1, because the
2527 -1 may be the actual new priority! */
2529 errno = 0;
2530 value = nice(increment);
2531 #if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
2532 if (value == 0)
2533 value = getpriority(PRIO_PROCESS, 0);
2534 #endif
2535 if (value == -1 && errno != 0)
2536 /* either nice() or getpriority() returned an error */
2537 return posix_error();
2538 return PyInt_FromLong((long) value);
2540 #endif /* HAVE_NICE */
2542 PyDoc_STRVAR(posix_rename__doc__,
2543 "rename(old, new)\n\n\
2544 Rename a file or directory.");
2546 static PyObject *
2547 posix_rename(PyObject *self, PyObject *args)
2549 #ifdef MS_WINDOWS
2550 PyObject *o1, *o2;
2551 char *p1, *p2;
2552 BOOL result;
2553 if (unicode_file_names()) {
2554 if (!PyArg_ParseTuple(args, "OO:rename", &o1, &o2))
2555 goto error;
2556 if (!convert_to_unicode(&o1))
2557 goto error;
2558 if (!convert_to_unicode(&o2)) {
2559 Py_DECREF(o1);
2560 goto error;
2562 Py_BEGIN_ALLOW_THREADS
2563 result = MoveFileW(PyUnicode_AsUnicode(o1),
2564 PyUnicode_AsUnicode(o2));
2565 Py_END_ALLOW_THREADS
2566 Py_DECREF(o1);
2567 Py_DECREF(o2);
2568 if (!result)
2569 return win32_error("rename", NULL);
2570 Py_INCREF(Py_None);
2571 return Py_None;
2572 error:
2573 PyErr_Clear();
2575 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
2576 return NULL;
2577 Py_BEGIN_ALLOW_THREADS
2578 result = MoveFileA(p1, p2);
2579 Py_END_ALLOW_THREADS
2580 if (!result)
2581 return win32_error("rename", NULL);
2582 Py_INCREF(Py_None);
2583 return Py_None;
2584 #else
2585 return posix_2str(args, "etet:rename", rename);
2586 #endif
2590 PyDoc_STRVAR(posix_rmdir__doc__,
2591 "rmdir(path)\n\n\
2592 Remove a directory.");
2594 static PyObject *
2595 posix_rmdir(PyObject *self, PyObject *args)
2597 #ifdef MS_WINDOWS
2598 return win32_1str(args, "rmdir", "s:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
2599 #else
2600 return posix_1str(args, "et:rmdir", rmdir);
2601 #endif
2605 PyDoc_STRVAR(posix_stat__doc__,
2606 "stat(path) -> stat result\n\n\
2607 Perform a stat system call on the given path.");
2609 static PyObject *
2610 posix_stat(PyObject *self, PyObject *args)
2612 #ifdef MS_WINDOWS
2613 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", win32_wstat);
2614 #else
2615 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
2616 #endif
2620 #ifdef HAVE_SYSTEM
2621 PyDoc_STRVAR(posix_system__doc__,
2622 "system(command) -> exit_status\n\n\
2623 Execute the command (a string) in a subshell.");
2625 static PyObject *
2626 posix_system(PyObject *self, PyObject *args)
2628 char *command;
2629 long sts;
2630 if (!PyArg_ParseTuple(args, "s:system", &command))
2631 return NULL;
2632 Py_BEGIN_ALLOW_THREADS
2633 sts = system(command);
2634 Py_END_ALLOW_THREADS
2635 return PyInt_FromLong(sts);
2637 #endif
2640 PyDoc_STRVAR(posix_umask__doc__,
2641 "umask(new_mask) -> old_mask\n\n\
2642 Set the current numeric umask and return the previous umask.");
2644 static PyObject *
2645 posix_umask(PyObject *self, PyObject *args)
2647 int i;
2648 if (!PyArg_ParseTuple(args, "i:umask", &i))
2649 return NULL;
2650 i = (int)umask(i);
2651 if (i < 0)
2652 return posix_error();
2653 return PyInt_FromLong((long)i);
2657 PyDoc_STRVAR(posix_unlink__doc__,
2658 "unlink(path)\n\n\
2659 Remove a file (same as remove(path)).");
2661 PyDoc_STRVAR(posix_remove__doc__,
2662 "remove(path)\n\n\
2663 Remove a file (same as unlink(path)).");
2665 static PyObject *
2666 posix_unlink(PyObject *self, PyObject *args)
2668 #ifdef MS_WINDOWS
2669 return win32_1str(args, "remove", "s:remove", DeleteFileA, "U:remove", DeleteFileW);
2670 #else
2671 return posix_1str(args, "et:remove", unlink);
2672 #endif
2676 #ifdef HAVE_UNAME
2677 PyDoc_STRVAR(posix_uname__doc__,
2678 "uname() -> (sysname, nodename, release, version, machine)\n\n\
2679 Return a tuple identifying the current operating system.");
2681 static PyObject *
2682 posix_uname(PyObject *self, PyObject *noargs)
2684 struct utsname u;
2685 int res;
2687 Py_BEGIN_ALLOW_THREADS
2688 res = uname(&u);
2689 Py_END_ALLOW_THREADS
2690 if (res < 0)
2691 return posix_error();
2692 return Py_BuildValue("(sssss)",
2693 u.sysname,
2694 u.nodename,
2695 u.release,
2696 u.version,
2697 u.machine);
2699 #endif /* HAVE_UNAME */
2701 static int
2702 extract_time(PyObject *t, long* sec, long* usec)
2704 long intval;
2705 if (PyFloat_Check(t)) {
2706 double tval = PyFloat_AsDouble(t);
2707 PyObject *intobj = Py_TYPE(t)->tp_as_number->nb_int(t);
2708 if (!intobj)
2709 return -1;
2710 intval = PyInt_AsLong(intobj);
2711 Py_DECREF(intobj);
2712 if (intval == -1 && PyErr_Occurred())
2713 return -1;
2714 *sec = intval;
2715 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
2716 if (*usec < 0)
2717 /* If rounding gave us a negative number,
2718 truncate. */
2719 *usec = 0;
2720 return 0;
2722 intval = PyInt_AsLong(t);
2723 if (intval == -1 && PyErr_Occurred())
2724 return -1;
2725 *sec = intval;
2726 *usec = 0;
2727 return 0;
2730 PyDoc_STRVAR(posix_utime__doc__,
2731 "utime(path, (atime, mtime))\n\
2732 utime(path, None)\n\n\
2733 Set the access and modified time of the file to the given values. If the\n\
2734 second form is used, set the access and modified times to the current time.");
2736 static PyObject *
2737 posix_utime(PyObject *self, PyObject *args)
2739 #ifdef Py_WIN_WIDE_FILENAMES
2740 PyObject *arg;
2741 PyUnicodeObject *obwpath;
2742 wchar_t *wpath = NULL;
2743 char *apath = NULL;
2744 HANDLE hFile;
2745 long atimesec, mtimesec, ausec, musec;
2746 FILETIME atime, mtime;
2747 PyObject *result = NULL;
2749 if (unicode_file_names()) {
2750 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
2751 wpath = PyUnicode_AS_UNICODE(obwpath);
2752 Py_BEGIN_ALLOW_THREADS
2753 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
2754 NULL, OPEN_EXISTING,
2755 FILE_FLAG_BACKUP_SEMANTICS, NULL);
2756 Py_END_ALLOW_THREADS
2757 if (hFile == INVALID_HANDLE_VALUE)
2758 return win32_error_unicode("utime", wpath);
2759 } else
2760 /* Drop the argument parsing error as narrow strings
2761 are also valid. */
2762 PyErr_Clear();
2764 if (!wpath) {
2765 if (!PyArg_ParseTuple(args, "etO:utime",
2766 Py_FileSystemDefaultEncoding, &apath, &arg))
2767 return NULL;
2768 Py_BEGIN_ALLOW_THREADS
2769 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
2770 NULL, OPEN_EXISTING,
2771 FILE_FLAG_BACKUP_SEMANTICS, NULL);
2772 Py_END_ALLOW_THREADS
2773 if (hFile == INVALID_HANDLE_VALUE) {
2774 win32_error("utime", apath);
2775 PyMem_Free(apath);
2776 return NULL;
2778 PyMem_Free(apath);
2781 if (arg == Py_None) {
2782 SYSTEMTIME now;
2783 GetSystemTime(&now);
2784 if (!SystemTimeToFileTime(&now, &mtime) ||
2785 !SystemTimeToFileTime(&now, &atime)) {
2786 win32_error("utime", NULL);
2787 goto done;
2790 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
2791 PyErr_SetString(PyExc_TypeError,
2792 "utime() arg 2 must be a tuple (atime, mtime)");
2793 goto done;
2795 else {
2796 if (extract_time(PyTuple_GET_ITEM(arg, 0),
2797 &atimesec, &ausec) == -1)
2798 goto done;
2799 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
2800 if (extract_time(PyTuple_GET_ITEM(arg, 1),
2801 &mtimesec, &musec) == -1)
2802 goto done;
2803 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
2805 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
2806 /* Avoid putting the file name into the error here,
2807 as that may confuse the user into believing that
2808 something is wrong with the file, when it also
2809 could be the time stamp that gives a problem. */
2810 win32_error("utime", NULL);
2812 Py_INCREF(Py_None);
2813 result = Py_None;
2814 done:
2815 CloseHandle(hFile);
2816 return result;
2817 #else /* Py_WIN_WIDE_FILENAMES */
2819 char *path = NULL;
2820 long atime, mtime, ausec, musec;
2821 int res;
2822 PyObject* arg;
2824 #if defined(HAVE_UTIMES)
2825 struct timeval buf[2];
2826 #define ATIME buf[0].tv_sec
2827 #define MTIME buf[1].tv_sec
2828 #elif defined(HAVE_UTIME_H)
2829 /* XXX should define struct utimbuf instead, above */
2830 struct utimbuf buf;
2831 #define ATIME buf.actime
2832 #define MTIME buf.modtime
2833 #define UTIME_ARG &buf
2834 #else /* HAVE_UTIMES */
2835 time_t buf[2];
2836 #define ATIME buf[0]
2837 #define MTIME buf[1]
2838 #define UTIME_ARG buf
2839 #endif /* HAVE_UTIMES */
2842 if (!PyArg_ParseTuple(args, "etO:utime",
2843 Py_FileSystemDefaultEncoding, &path, &arg))
2844 return NULL;
2845 if (arg == Py_None) {
2846 /* optional time values not given */
2847 Py_BEGIN_ALLOW_THREADS
2848 res = utime(path, NULL);
2849 Py_END_ALLOW_THREADS
2851 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
2852 PyErr_SetString(PyExc_TypeError,
2853 "utime() arg 2 must be a tuple (atime, mtime)");
2854 PyMem_Free(path);
2855 return NULL;
2857 else {
2858 if (extract_time(PyTuple_GET_ITEM(arg, 0),
2859 &atime, &ausec) == -1) {
2860 PyMem_Free(path);
2861 return NULL;
2863 if (extract_time(PyTuple_GET_ITEM(arg, 1),
2864 &mtime, &musec) == -1) {
2865 PyMem_Free(path);
2866 return NULL;
2868 ATIME = atime;
2869 MTIME = mtime;
2870 #ifdef HAVE_UTIMES
2871 buf[0].tv_usec = ausec;
2872 buf[1].tv_usec = musec;
2873 Py_BEGIN_ALLOW_THREADS
2874 res = utimes(path, buf);
2875 Py_END_ALLOW_THREADS
2876 #else
2877 Py_BEGIN_ALLOW_THREADS
2878 res = utime(path, UTIME_ARG);
2879 Py_END_ALLOW_THREADS
2880 #endif /* HAVE_UTIMES */
2882 if (res < 0) {
2883 return posix_error_with_allocated_filename(path);
2885 PyMem_Free(path);
2886 Py_INCREF(Py_None);
2887 return Py_None;
2888 #undef UTIME_ARG
2889 #undef ATIME
2890 #undef MTIME
2891 #endif /* Py_WIN_WIDE_FILENAMES */
2895 /* Process operations */
2897 PyDoc_STRVAR(posix__exit__doc__,
2898 "_exit(status)\n\n\
2899 Exit to the system with specified status, without normal exit processing.");
2901 static PyObject *
2902 posix__exit(PyObject *self, PyObject *args)
2904 int sts;
2905 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
2906 return NULL;
2907 _exit(sts);
2908 return NULL; /* Make gcc -Wall happy */
2911 #if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
2912 static void
2913 free_string_array(char **array, Py_ssize_t count)
2915 Py_ssize_t i;
2916 for (i = 0; i < count; i++)
2917 PyMem_Free(array[i]);
2918 PyMem_DEL(array);
2920 #endif
2923 #ifdef HAVE_EXECV
2924 PyDoc_STRVAR(posix_execv__doc__,
2925 "execv(path, args)\n\n\
2926 Execute an executable path with arguments, replacing current process.\n\
2928 path: path of executable file\n\
2929 args: tuple or list of strings");
2931 static PyObject *
2932 posix_execv(PyObject *self, PyObject *args)
2934 char *path;
2935 PyObject *argv;
2936 char **argvlist;
2937 Py_ssize_t i, argc;
2938 PyObject *(*getitem)(PyObject *, Py_ssize_t);
2940 /* execv has two arguments: (path, argv), where
2941 argv is a list or tuple of strings. */
2943 if (!PyArg_ParseTuple(args, "etO:execv",
2944 Py_FileSystemDefaultEncoding,
2945 &path, &argv))
2946 return NULL;
2947 if (PyList_Check(argv)) {
2948 argc = PyList_Size(argv);
2949 getitem = PyList_GetItem;
2951 else if (PyTuple_Check(argv)) {
2952 argc = PyTuple_Size(argv);
2953 getitem = PyTuple_GetItem;
2955 else {
2956 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
2957 PyMem_Free(path);
2958 return NULL;
2961 argvlist = PyMem_NEW(char *, argc+1);
2962 if (argvlist == NULL) {
2963 PyMem_Free(path);
2964 return PyErr_NoMemory();
2966 for (i = 0; i < argc; i++) {
2967 if (!PyArg_Parse((*getitem)(argv, i), "et",
2968 Py_FileSystemDefaultEncoding,
2969 &argvlist[i])) {
2970 free_string_array(argvlist, i);
2971 PyErr_SetString(PyExc_TypeError,
2972 "execv() arg 2 must contain only strings");
2973 PyMem_Free(path);
2974 return NULL;
2978 argvlist[argc] = NULL;
2980 execv(path, argvlist);
2982 /* If we get here it's definitely an error */
2984 free_string_array(argvlist, argc);
2985 PyMem_Free(path);
2986 return posix_error();
2990 PyDoc_STRVAR(posix_execve__doc__,
2991 "execve(path, args, env)\n\n\
2992 Execute a path with arguments and environment, replacing current process.\n\
2994 path: path of executable file\n\
2995 args: tuple or list of arguments\n\
2996 env: dictionary of strings mapping to strings");
2998 static PyObject *
2999 posix_execve(PyObject *self, PyObject *args)
3001 char *path;
3002 PyObject *argv, *env;
3003 char **argvlist;
3004 char **envlist;
3005 PyObject *key, *val, *keys=NULL, *vals=NULL;
3006 Py_ssize_t i, pos, argc, envc;
3007 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3008 Py_ssize_t lastarg = 0;
3010 /* execve has three arguments: (path, argv, env), where
3011 argv is a list or tuple of strings and env is a dictionary
3012 like posix.environ. */
3014 if (!PyArg_ParseTuple(args, "etOO:execve",
3015 Py_FileSystemDefaultEncoding,
3016 &path, &argv, &env))
3017 return NULL;
3018 if (PyList_Check(argv)) {
3019 argc = PyList_Size(argv);
3020 getitem = PyList_GetItem;
3022 else if (PyTuple_Check(argv)) {
3023 argc = PyTuple_Size(argv);
3024 getitem = PyTuple_GetItem;
3026 else {
3027 PyErr_SetString(PyExc_TypeError,
3028 "execve() arg 2 must be a tuple or list");
3029 goto fail_0;
3031 if (!PyMapping_Check(env)) {
3032 PyErr_SetString(PyExc_TypeError,
3033 "execve() arg 3 must be a mapping object");
3034 goto fail_0;
3037 argvlist = PyMem_NEW(char *, argc+1);
3038 if (argvlist == NULL) {
3039 PyErr_NoMemory();
3040 goto fail_0;
3042 for (i = 0; i < argc; i++) {
3043 if (!PyArg_Parse((*getitem)(argv, i),
3044 "et;execve() arg 2 must contain only strings",
3045 Py_FileSystemDefaultEncoding,
3046 &argvlist[i]))
3048 lastarg = i;
3049 goto fail_1;
3052 lastarg = argc;
3053 argvlist[argc] = NULL;
3055 i = PyMapping_Size(env);
3056 if (i < 0)
3057 goto fail_1;
3058 envlist = PyMem_NEW(char *, i + 1);
3059 if (envlist == NULL) {
3060 PyErr_NoMemory();
3061 goto fail_1;
3063 envc = 0;
3064 keys = PyMapping_Keys(env);
3065 vals = PyMapping_Values(env);
3066 if (!keys || !vals)
3067 goto fail_2;
3068 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3069 PyErr_SetString(PyExc_TypeError,
3070 "execve(): env.keys() or env.values() is not a list");
3071 goto fail_2;
3074 for (pos = 0; pos < i; pos++) {
3075 char *p, *k, *v;
3076 size_t len;
3078 key = PyList_GetItem(keys, pos);
3079 val = PyList_GetItem(vals, pos);
3080 if (!key || !val)
3081 goto fail_2;
3083 if (!PyArg_Parse(
3084 key,
3085 "s;execve() arg 3 contains a non-string key",
3086 &k) ||
3087 !PyArg_Parse(
3088 val,
3089 "s;execve() arg 3 contains a non-string value",
3090 &v))
3092 goto fail_2;
3095 #if defined(PYOS_OS2)
3096 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
3097 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
3098 #endif
3099 len = PyString_Size(key) + PyString_Size(val) + 2;
3100 p = PyMem_NEW(char, len);
3101 if (p == NULL) {
3102 PyErr_NoMemory();
3103 goto fail_2;
3105 PyOS_snprintf(p, len, "%s=%s", k, v);
3106 envlist[envc++] = p;
3107 #if defined(PYOS_OS2)
3109 #endif
3111 envlist[envc] = 0;
3113 execve(path, argvlist, envlist);
3115 /* If we get here it's definitely an error */
3117 (void) posix_error();
3119 fail_2:
3120 while (--envc >= 0)
3121 PyMem_DEL(envlist[envc]);
3122 PyMem_DEL(envlist);
3123 fail_1:
3124 free_string_array(argvlist, lastarg);
3125 Py_XDECREF(vals);
3126 Py_XDECREF(keys);
3127 fail_0:
3128 PyMem_Free(path);
3129 return NULL;
3131 #endif /* HAVE_EXECV */
3134 #ifdef HAVE_SPAWNV
3135 PyDoc_STRVAR(posix_spawnv__doc__,
3136 "spawnv(mode, path, args)\n\n\
3137 Execute the program 'path' in a new process.\n\
3139 mode: mode of process creation\n\
3140 path: path of executable file\n\
3141 args: tuple or list of strings");
3143 static PyObject *
3144 posix_spawnv(PyObject *self, PyObject *args)
3146 char *path;
3147 PyObject *argv;
3148 char **argvlist;
3149 int mode, i;
3150 Py_ssize_t argc;
3151 Py_intptr_t spawnval;
3152 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3154 /* spawnv has three arguments: (mode, path, argv), where
3155 argv is a list or tuple of strings. */
3157 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
3158 Py_FileSystemDefaultEncoding,
3159 &path, &argv))
3160 return NULL;
3161 if (PyList_Check(argv)) {
3162 argc = PyList_Size(argv);
3163 getitem = PyList_GetItem;
3165 else if (PyTuple_Check(argv)) {
3166 argc = PyTuple_Size(argv);
3167 getitem = PyTuple_GetItem;
3169 else {
3170 PyErr_SetString(PyExc_TypeError,
3171 "spawnv() arg 2 must be a tuple or list");
3172 PyMem_Free(path);
3173 return NULL;
3176 argvlist = PyMem_NEW(char *, argc+1);
3177 if (argvlist == NULL) {
3178 PyMem_Free(path);
3179 return PyErr_NoMemory();
3181 for (i = 0; i < argc; i++) {
3182 if (!PyArg_Parse((*getitem)(argv, i), "et",
3183 Py_FileSystemDefaultEncoding,
3184 &argvlist[i])) {
3185 free_string_array(argvlist, i);
3186 PyErr_SetString(
3187 PyExc_TypeError,
3188 "spawnv() arg 2 must contain only strings");
3189 PyMem_Free(path);
3190 return NULL;
3193 argvlist[argc] = NULL;
3195 #if defined(PYOS_OS2) && defined(PYCC_GCC)
3196 Py_BEGIN_ALLOW_THREADS
3197 spawnval = spawnv(mode, path, argvlist);
3198 Py_END_ALLOW_THREADS
3199 #else
3200 if (mode == _OLD_P_OVERLAY)
3201 mode = _P_OVERLAY;
3203 Py_BEGIN_ALLOW_THREADS
3204 spawnval = _spawnv(mode, path, argvlist);
3205 Py_END_ALLOW_THREADS
3206 #endif
3208 free_string_array(argvlist, argc);
3209 PyMem_Free(path);
3211 if (spawnval == -1)
3212 return posix_error();
3213 else
3214 #if SIZEOF_LONG == SIZEOF_VOID_P
3215 return Py_BuildValue("l", (long) spawnval);
3216 #else
3217 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
3218 #endif
3222 PyDoc_STRVAR(posix_spawnve__doc__,
3223 "spawnve(mode, path, args, env)\n\n\
3224 Execute the program 'path' in a new process.\n\
3226 mode: mode of process creation\n\
3227 path: path of executable file\n\
3228 args: tuple or list of arguments\n\
3229 env: dictionary of strings mapping to strings");
3231 static PyObject *
3232 posix_spawnve(PyObject *self, PyObject *args)
3234 char *path;
3235 PyObject *argv, *env;
3236 char **argvlist;
3237 char **envlist;
3238 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3239 int mode, pos, envc;
3240 Py_ssize_t argc, i;
3241 Py_intptr_t spawnval;
3242 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3243 Py_ssize_t lastarg = 0;
3245 /* spawnve has four arguments: (mode, path, argv, env), where
3246 argv is a list or tuple of strings and env is a dictionary
3247 like posix.environ. */
3249 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
3250 Py_FileSystemDefaultEncoding,
3251 &path, &argv, &env))
3252 return NULL;
3253 if (PyList_Check(argv)) {
3254 argc = PyList_Size(argv);
3255 getitem = PyList_GetItem;
3257 else if (PyTuple_Check(argv)) {
3258 argc = PyTuple_Size(argv);
3259 getitem = PyTuple_GetItem;
3261 else {
3262 PyErr_SetString(PyExc_TypeError,
3263 "spawnve() arg 2 must be a tuple or list");
3264 goto fail_0;
3266 if (!PyMapping_Check(env)) {
3267 PyErr_SetString(PyExc_TypeError,
3268 "spawnve() arg 3 must be a mapping object");
3269 goto fail_0;
3272 argvlist = PyMem_NEW(char *, argc+1);
3273 if (argvlist == NULL) {
3274 PyErr_NoMemory();
3275 goto fail_0;
3277 for (i = 0; i < argc; i++) {
3278 if (!PyArg_Parse((*getitem)(argv, i),
3279 "et;spawnve() arg 2 must contain only strings",
3280 Py_FileSystemDefaultEncoding,
3281 &argvlist[i]))
3283 lastarg = i;
3284 goto fail_1;
3287 lastarg = argc;
3288 argvlist[argc] = NULL;
3290 i = PyMapping_Size(env);
3291 if (i < 0)
3292 goto fail_1;
3293 envlist = PyMem_NEW(char *, i + 1);
3294 if (envlist == NULL) {
3295 PyErr_NoMemory();
3296 goto fail_1;
3298 envc = 0;
3299 keys = PyMapping_Keys(env);
3300 vals = PyMapping_Values(env);
3301 if (!keys || !vals)
3302 goto fail_2;
3303 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3304 PyErr_SetString(PyExc_TypeError,
3305 "spawnve(): env.keys() or env.values() is not a list");
3306 goto fail_2;
3309 for (pos = 0; pos < i; pos++) {
3310 char *p, *k, *v;
3311 size_t len;
3313 key = PyList_GetItem(keys, pos);
3314 val = PyList_GetItem(vals, pos);
3315 if (!key || !val)
3316 goto fail_2;
3318 if (!PyArg_Parse(
3319 key,
3320 "s;spawnve() arg 3 contains a non-string key",
3321 &k) ||
3322 !PyArg_Parse(
3323 val,
3324 "s;spawnve() arg 3 contains a non-string value",
3325 &v))
3327 goto fail_2;
3329 len = PyString_Size(key) + PyString_Size(val) + 2;
3330 p = PyMem_NEW(char, len);
3331 if (p == NULL) {
3332 PyErr_NoMemory();
3333 goto fail_2;
3335 PyOS_snprintf(p, len, "%s=%s", k, v);
3336 envlist[envc++] = p;
3338 envlist[envc] = 0;
3340 #if defined(PYOS_OS2) && defined(PYCC_GCC)
3341 Py_BEGIN_ALLOW_THREADS
3342 spawnval = spawnve(mode, path, argvlist, envlist);
3343 Py_END_ALLOW_THREADS
3344 #else
3345 if (mode == _OLD_P_OVERLAY)
3346 mode = _P_OVERLAY;
3348 Py_BEGIN_ALLOW_THREADS
3349 spawnval = _spawnve(mode, path, argvlist, envlist);
3350 Py_END_ALLOW_THREADS
3351 #endif
3353 if (spawnval == -1)
3354 (void) posix_error();
3355 else
3356 #if SIZEOF_LONG == SIZEOF_VOID_P
3357 res = Py_BuildValue("l", (long) spawnval);
3358 #else
3359 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
3360 #endif
3362 fail_2:
3363 while (--envc >= 0)
3364 PyMem_DEL(envlist[envc]);
3365 PyMem_DEL(envlist);
3366 fail_1:
3367 free_string_array(argvlist, lastarg);
3368 Py_XDECREF(vals);
3369 Py_XDECREF(keys);
3370 fail_0:
3371 PyMem_Free(path);
3372 return res;
3375 /* OS/2 supports spawnvp & spawnvpe natively */
3376 #if defined(PYOS_OS2)
3377 PyDoc_STRVAR(posix_spawnvp__doc__,
3378 "spawnvp(mode, file, args)\n\n\
3379 Execute the program 'file' in a new process, using the environment\n\
3380 search path to find the file.\n\
3382 mode: mode of process creation\n\
3383 file: executable file name\n\
3384 args: tuple or list of strings");
3386 static PyObject *
3387 posix_spawnvp(PyObject *self, PyObject *args)
3389 char *path;
3390 PyObject *argv;
3391 char **argvlist;
3392 int mode, i, argc;
3393 Py_intptr_t spawnval;
3394 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3396 /* spawnvp has three arguments: (mode, path, argv), where
3397 argv is a list or tuple of strings. */
3399 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
3400 Py_FileSystemDefaultEncoding,
3401 &path, &argv))
3402 return NULL;
3403 if (PyList_Check(argv)) {
3404 argc = PyList_Size(argv);
3405 getitem = PyList_GetItem;
3407 else if (PyTuple_Check(argv)) {
3408 argc = PyTuple_Size(argv);
3409 getitem = PyTuple_GetItem;
3411 else {
3412 PyErr_SetString(PyExc_TypeError,
3413 "spawnvp() arg 2 must be a tuple or list");
3414 PyMem_Free(path);
3415 return NULL;
3418 argvlist = PyMem_NEW(char *, argc+1);
3419 if (argvlist == NULL) {
3420 PyMem_Free(path);
3421 return PyErr_NoMemory();
3423 for (i = 0; i < argc; i++) {
3424 if (!PyArg_Parse((*getitem)(argv, i), "et",
3425 Py_FileSystemDefaultEncoding,
3426 &argvlist[i])) {
3427 free_string_array(argvlist, i);
3428 PyErr_SetString(
3429 PyExc_TypeError,
3430 "spawnvp() arg 2 must contain only strings");
3431 PyMem_Free(path);
3432 return NULL;
3435 argvlist[argc] = NULL;
3437 Py_BEGIN_ALLOW_THREADS
3438 #if defined(PYCC_GCC)
3439 spawnval = spawnvp(mode, path, argvlist);
3440 #else
3441 spawnval = _spawnvp(mode, path, argvlist);
3442 #endif
3443 Py_END_ALLOW_THREADS
3445 free_string_array(argvlist, argc);
3446 PyMem_Free(path);
3448 if (spawnval == -1)
3449 return posix_error();
3450 else
3451 return Py_BuildValue("l", (long) spawnval);
3455 PyDoc_STRVAR(posix_spawnvpe__doc__,
3456 "spawnvpe(mode, file, args, env)\n\n\
3457 Execute the program 'file' in a new process, using the environment\n\
3458 search path to find the file.\n\
3460 mode: mode of process creation\n\
3461 file: executable file name\n\
3462 args: tuple or list of arguments\n\
3463 env: dictionary of strings mapping to strings");
3465 static PyObject *
3466 posix_spawnvpe(PyObject *self, PyObject *args)
3468 char *path;
3469 PyObject *argv, *env;
3470 char **argvlist;
3471 char **envlist;
3472 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3473 int mode, i, pos, argc, envc;
3474 Py_intptr_t spawnval;
3475 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3476 int lastarg = 0;
3478 /* spawnvpe has four arguments: (mode, path, argv, env), where
3479 argv is a list or tuple of strings and env is a dictionary
3480 like posix.environ. */
3482 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
3483 Py_FileSystemDefaultEncoding,
3484 &path, &argv, &env))
3485 return NULL;
3486 if (PyList_Check(argv)) {
3487 argc = PyList_Size(argv);
3488 getitem = PyList_GetItem;
3490 else if (PyTuple_Check(argv)) {
3491 argc = PyTuple_Size(argv);
3492 getitem = PyTuple_GetItem;
3494 else {
3495 PyErr_SetString(PyExc_TypeError,
3496 "spawnvpe() arg 2 must be a tuple or list");
3497 goto fail_0;
3499 if (!PyMapping_Check(env)) {
3500 PyErr_SetString(PyExc_TypeError,
3501 "spawnvpe() arg 3 must be a mapping object");
3502 goto fail_0;
3505 argvlist = PyMem_NEW(char *, argc+1);
3506 if (argvlist == NULL) {
3507 PyErr_NoMemory();
3508 goto fail_0;
3510 for (i = 0; i < argc; i++) {
3511 if (!PyArg_Parse((*getitem)(argv, i),
3512 "et;spawnvpe() arg 2 must contain only strings",
3513 Py_FileSystemDefaultEncoding,
3514 &argvlist[i]))
3516 lastarg = i;
3517 goto fail_1;
3520 lastarg = argc;
3521 argvlist[argc] = NULL;
3523 i = PyMapping_Size(env);
3524 if (i < 0)
3525 goto fail_1;
3526 envlist = PyMem_NEW(char *, i + 1);
3527 if (envlist == NULL) {
3528 PyErr_NoMemory();
3529 goto fail_1;
3531 envc = 0;
3532 keys = PyMapping_Keys(env);
3533 vals = PyMapping_Values(env);
3534 if (!keys || !vals)
3535 goto fail_2;
3536 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3537 PyErr_SetString(PyExc_TypeError,
3538 "spawnvpe(): env.keys() or env.values() is not a list");
3539 goto fail_2;
3542 for (pos = 0; pos < i; pos++) {
3543 char *p, *k, *v;
3544 size_t len;
3546 key = PyList_GetItem(keys, pos);
3547 val = PyList_GetItem(vals, pos);
3548 if (!key || !val)
3549 goto fail_2;
3551 if (!PyArg_Parse(
3552 key,
3553 "s;spawnvpe() arg 3 contains a non-string key",
3554 &k) ||
3555 !PyArg_Parse(
3556 val,
3557 "s;spawnvpe() arg 3 contains a non-string value",
3558 &v))
3560 goto fail_2;
3562 len = PyString_Size(key) + PyString_Size(val) + 2;
3563 p = PyMem_NEW(char, len);
3564 if (p == NULL) {
3565 PyErr_NoMemory();
3566 goto fail_2;
3568 PyOS_snprintf(p, len, "%s=%s", k, v);
3569 envlist[envc++] = p;
3571 envlist[envc] = 0;
3573 Py_BEGIN_ALLOW_THREADS
3574 #if defined(PYCC_GCC)
3575 spawnval = spawnvpe(mode, path, argvlist, envlist);
3576 #else
3577 spawnval = _spawnvpe(mode, path, argvlist, envlist);
3578 #endif
3579 Py_END_ALLOW_THREADS
3581 if (spawnval == -1)
3582 (void) posix_error();
3583 else
3584 res = Py_BuildValue("l", (long) spawnval);
3586 fail_2:
3587 while (--envc >= 0)
3588 PyMem_DEL(envlist[envc]);
3589 PyMem_DEL(envlist);
3590 fail_1:
3591 free_string_array(argvlist, lastarg);
3592 Py_XDECREF(vals);
3593 Py_XDECREF(keys);
3594 fail_0:
3595 PyMem_Free(path);
3596 return res;
3598 #endif /* PYOS_OS2 */
3599 #endif /* HAVE_SPAWNV */
3602 #ifdef HAVE_FORK1
3603 PyDoc_STRVAR(posix_fork1__doc__,
3604 "fork1() -> pid\n\n\
3605 Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3607 Return 0 to child process and PID of child to parent process.");
3609 static PyObject *
3610 posix_fork1(PyObject *self, PyObject *noargs)
3612 pid_t pid = fork1();
3613 if (pid == -1)
3614 return posix_error();
3615 if (pid == 0)
3616 PyOS_AfterFork();
3617 return PyInt_FromLong(pid);
3619 #endif
3622 #ifdef HAVE_FORK
3623 PyDoc_STRVAR(posix_fork__doc__,
3624 "fork() -> pid\n\n\
3625 Fork a child process.\n\
3626 Return 0 to child process and PID of child to parent process.");
3628 static PyObject *
3629 posix_fork(PyObject *self, PyObject *noargs)
3631 pid_t pid = fork();
3632 if (pid == -1)
3633 return posix_error();
3634 if (pid == 0)
3635 PyOS_AfterFork();
3636 return PyInt_FromLong(pid);
3638 #endif
3640 /* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
3641 /* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3642 #if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
3643 #define DEV_PTY_FILE "/dev/ptc"
3644 #define HAVE_DEV_PTMX
3645 #else
3646 #define DEV_PTY_FILE "/dev/ptmx"
3647 #endif
3649 #if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
3650 #ifdef HAVE_PTY_H
3651 #include <pty.h>
3652 #else
3653 #ifdef HAVE_LIBUTIL_H
3654 #include <libutil.h>
3655 #endif /* HAVE_LIBUTIL_H */
3656 #endif /* HAVE_PTY_H */
3657 #ifdef HAVE_STROPTS_H
3658 #include <stropts.h>
3659 #endif
3660 #endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
3662 #if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
3663 PyDoc_STRVAR(posix_openpty__doc__,
3664 "openpty() -> (master_fd, slave_fd)\n\n\
3665 Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
3667 static PyObject *
3668 posix_openpty(PyObject *self, PyObject *noargs)
3670 int master_fd, slave_fd;
3671 #ifndef HAVE_OPENPTY
3672 char * slave_name;
3673 #endif
3674 #if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
3675 PyOS_sighandler_t sig_saved;
3676 #ifdef sun
3677 extern char *ptsname(int fildes);
3678 #endif
3679 #endif
3681 #ifdef HAVE_OPENPTY
3682 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
3683 return posix_error();
3684 #elif defined(HAVE__GETPTY)
3685 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
3686 if (slave_name == NULL)
3687 return posix_error();
3689 slave_fd = open(slave_name, O_RDWR);
3690 if (slave_fd < 0)
3691 return posix_error();
3692 #else
3693 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
3694 if (master_fd < 0)
3695 return posix_error();
3696 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
3697 /* change permission of slave */
3698 if (grantpt(master_fd) < 0) {
3699 PyOS_setsig(SIGCHLD, sig_saved);
3700 return posix_error();
3702 /* unlock slave */
3703 if (unlockpt(master_fd) < 0) {
3704 PyOS_setsig(SIGCHLD, sig_saved);
3705 return posix_error();
3707 PyOS_setsig(SIGCHLD, sig_saved);
3708 slave_name = ptsname(master_fd); /* get name of slave */
3709 if (slave_name == NULL)
3710 return posix_error();
3711 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
3712 if (slave_fd < 0)
3713 return posix_error();
3714 #if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
3715 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
3716 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
3717 #ifndef __hpux
3718 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
3719 #endif /* __hpux */
3720 #endif /* HAVE_CYGWIN */
3721 #endif /* HAVE_OPENPTY */
3723 return Py_BuildValue("(ii)", master_fd, slave_fd);
3726 #endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
3728 #ifdef HAVE_FORKPTY
3729 PyDoc_STRVAR(posix_forkpty__doc__,
3730 "forkpty() -> (pid, master_fd)\n\n\
3731 Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
3732 Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
3733 To both, return fd of newly opened pseudo-terminal.\n");
3735 static PyObject *
3736 posix_forkpty(PyObject *self, PyObject *noargs)
3738 int master_fd = -1;
3739 pid_t pid;
3741 pid = forkpty(&master_fd, NULL, NULL, NULL);
3742 if (pid == -1)
3743 return posix_error();
3744 if (pid == 0)
3745 PyOS_AfterFork();
3746 return Py_BuildValue("(li)", pid, master_fd);
3748 #endif
3750 #ifdef HAVE_GETEGID
3751 PyDoc_STRVAR(posix_getegid__doc__,
3752 "getegid() -> egid\n\n\
3753 Return the current process's effective group id.");
3755 static PyObject *
3756 posix_getegid(PyObject *self, PyObject *noargs)
3758 return PyInt_FromLong((long)getegid());
3760 #endif
3763 #ifdef HAVE_GETEUID
3764 PyDoc_STRVAR(posix_geteuid__doc__,
3765 "geteuid() -> euid\n\n\
3766 Return the current process's effective user id.");
3768 static PyObject *
3769 posix_geteuid(PyObject *self, PyObject *noargs)
3771 return PyInt_FromLong((long)geteuid());
3773 #endif
3776 #ifdef HAVE_GETGID
3777 PyDoc_STRVAR(posix_getgid__doc__,
3778 "getgid() -> gid\n\n\
3779 Return the current process's group id.");
3781 static PyObject *
3782 posix_getgid(PyObject *self, PyObject *noargs)
3784 return PyInt_FromLong((long)getgid());
3786 #endif
3789 PyDoc_STRVAR(posix_getpid__doc__,
3790 "getpid() -> pid\n\n\
3791 Return the current process id");
3793 static PyObject *
3794 posix_getpid(PyObject *self, PyObject *noargs)
3796 return PyInt_FromLong((long)getpid());
3800 #ifdef HAVE_GETGROUPS
3801 PyDoc_STRVAR(posix_getgroups__doc__,
3802 "getgroups() -> list of group IDs\n\n\
3803 Return list of supplemental group IDs for the process.");
3805 static PyObject *
3806 posix_getgroups(PyObject *self, PyObject *noargs)
3808 PyObject *result = NULL;
3810 #ifdef NGROUPS_MAX
3811 #define MAX_GROUPS NGROUPS_MAX
3812 #else
3813 /* defined to be 16 on Solaris7, so this should be a small number */
3814 #define MAX_GROUPS 64
3815 #endif
3816 gid_t grouplist[MAX_GROUPS];
3817 int n;
3819 n = getgroups(MAX_GROUPS, grouplist);
3820 if (n < 0)
3821 posix_error();
3822 else {
3823 result = PyList_New(n);
3824 if (result != NULL) {
3825 int i;
3826 for (i = 0; i < n; ++i) {
3827 PyObject *o = PyInt_FromLong((long)grouplist[i]);
3828 if (o == NULL) {
3829 Py_DECREF(result);
3830 result = NULL;
3831 break;
3833 PyList_SET_ITEM(result, i, o);
3838 return result;
3840 #endif
3842 #ifdef HAVE_GETPGID
3843 PyDoc_STRVAR(posix_getpgid__doc__,
3844 "getpgid(pid) -> pgid\n\n\
3845 Call the system call getpgid().");
3847 static PyObject *
3848 posix_getpgid(PyObject *self, PyObject *args)
3850 int pid, pgid;
3851 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
3852 return NULL;
3853 pgid = getpgid(pid);
3854 if (pgid < 0)
3855 return posix_error();
3856 return PyInt_FromLong((long)pgid);
3858 #endif /* HAVE_GETPGID */
3861 #ifdef HAVE_GETPGRP
3862 PyDoc_STRVAR(posix_getpgrp__doc__,
3863 "getpgrp() -> pgrp\n\n\
3864 Return the current process group id.");
3866 static PyObject *
3867 posix_getpgrp(PyObject *self, PyObject *noargs)
3869 #ifdef GETPGRP_HAVE_ARG
3870 return PyInt_FromLong((long)getpgrp(0));
3871 #else /* GETPGRP_HAVE_ARG */
3872 return PyInt_FromLong((long)getpgrp());
3873 #endif /* GETPGRP_HAVE_ARG */
3875 #endif /* HAVE_GETPGRP */
3878 #ifdef HAVE_SETPGRP
3879 PyDoc_STRVAR(posix_setpgrp__doc__,
3880 "setpgrp()\n\n\
3881 Make this process a session leader.");
3883 static PyObject *
3884 posix_setpgrp(PyObject *self, PyObject *noargs)
3886 #ifdef SETPGRP_HAVE_ARG
3887 if (setpgrp(0, 0) < 0)
3888 #else /* SETPGRP_HAVE_ARG */
3889 if (setpgrp() < 0)
3890 #endif /* SETPGRP_HAVE_ARG */
3891 return posix_error();
3892 Py_INCREF(Py_None);
3893 return Py_None;
3896 #endif /* HAVE_SETPGRP */
3898 #ifdef HAVE_GETPPID
3899 PyDoc_STRVAR(posix_getppid__doc__,
3900 "getppid() -> ppid\n\n\
3901 Return the parent's process id.");
3903 static PyObject *
3904 posix_getppid(PyObject *self, PyObject *noargs)
3906 return PyInt_FromLong(getppid());
3908 #endif
3911 #ifdef HAVE_GETLOGIN
3912 PyDoc_STRVAR(posix_getlogin__doc__,
3913 "getlogin() -> string\n\n\
3914 Return the actual login name.");
3916 static PyObject *
3917 posix_getlogin(PyObject *self, PyObject *noargs)
3919 PyObject *result = NULL;
3920 char *name;
3921 int old_errno = errno;
3923 errno = 0;
3924 name = getlogin();
3925 if (name == NULL) {
3926 if (errno)
3927 posix_error();
3928 else
3929 PyErr_SetString(PyExc_OSError,
3930 "unable to determine login name");
3932 else
3933 result = PyString_FromString(name);
3934 errno = old_errno;
3936 return result;
3938 #endif
3940 #ifdef HAVE_GETUID
3941 PyDoc_STRVAR(posix_getuid__doc__,
3942 "getuid() -> uid\n\n\
3943 Return the current process's user id.");
3945 static PyObject *
3946 posix_getuid(PyObject *self, PyObject *noargs)
3948 return PyInt_FromLong((long)getuid());
3950 #endif
3953 #ifdef HAVE_KILL
3954 PyDoc_STRVAR(posix_kill__doc__,
3955 "kill(pid, sig)\n\n\
3956 Kill a process with a signal.");
3958 static PyObject *
3959 posix_kill(PyObject *self, PyObject *args)
3961 pid_t pid;
3962 int sig;
3963 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
3964 return NULL;
3965 #if defined(PYOS_OS2) && !defined(PYCC_GCC)
3966 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
3967 APIRET rc;
3968 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
3969 return os2_error(rc);
3971 } else if (sig == XCPT_SIGNAL_KILLPROC) {
3972 APIRET rc;
3973 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
3974 return os2_error(rc);
3976 } else
3977 return NULL; /* Unrecognized Signal Requested */
3978 #else
3979 if (kill(pid, sig) == -1)
3980 return posix_error();
3981 #endif
3982 Py_INCREF(Py_None);
3983 return Py_None;
3985 #endif
3987 #ifdef HAVE_KILLPG
3988 PyDoc_STRVAR(posix_killpg__doc__,
3989 "killpg(pgid, sig)\n\n\
3990 Kill a process group with a signal.");
3992 static PyObject *
3993 posix_killpg(PyObject *self, PyObject *args)
3995 int pgid, sig;
3996 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
3997 return NULL;
3998 if (killpg(pgid, sig) == -1)
3999 return posix_error();
4000 Py_INCREF(Py_None);
4001 return Py_None;
4003 #endif
4005 #ifdef HAVE_PLOCK
4007 #ifdef HAVE_SYS_LOCK_H
4008 #include <sys/lock.h>
4009 #endif
4011 PyDoc_STRVAR(posix_plock__doc__,
4012 "plock(op)\n\n\
4013 Lock program segments into memory.");
4015 static PyObject *
4016 posix_plock(PyObject *self, PyObject *args)
4018 int op;
4019 if (!PyArg_ParseTuple(args, "i:plock", &op))
4020 return NULL;
4021 if (plock(op) == -1)
4022 return posix_error();
4023 Py_INCREF(Py_None);
4024 return Py_None;
4026 #endif
4029 #ifdef HAVE_POPEN
4030 PyDoc_STRVAR(posix_popen__doc__,
4031 "popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
4032 Open a pipe to/from a command returning a file object.");
4034 #if defined(PYOS_OS2)
4035 #if defined(PYCC_VACPP)
4036 static int
4037 async_system(const char *command)
4039 char errormsg[256], args[1024];
4040 RESULTCODES rcodes;
4041 APIRET rc;
4043 char *shell = getenv("COMSPEC");
4044 if (!shell)
4045 shell = "cmd";
4047 /* avoid overflowing the argument buffer */
4048 if (strlen(shell) + 3 + strlen(command) >= 1024)
4049 return ERROR_NOT_ENOUGH_MEMORY
4051 args[0] = '\0';
4052 strcat(args, shell);
4053 strcat(args, "/c ");
4054 strcat(args, command);
4056 /* execute asynchronously, inheriting the environment */
4057 rc = DosExecPgm(errormsg,
4058 sizeof(errormsg),
4059 EXEC_ASYNC,
4060 args,
4061 NULL,
4062 &rcodes,
4063 shell);
4064 return rc;
4067 static FILE *
4068 popen(const char *command, const char *mode, int pipesize, int *err)
4070 int oldfd, tgtfd;
4071 HFILE pipeh[2];
4072 APIRET rc;
4074 /* mode determines which of stdin or stdout is reconnected to
4075 * the pipe to the child
4077 if (strchr(mode, 'r') != NULL) {
4078 tgt_fd = 1; /* stdout */
4079 } else if (strchr(mode, 'w')) {
4080 tgt_fd = 0; /* stdin */
4081 } else {
4082 *err = ERROR_INVALID_ACCESS;
4083 return NULL;
4086 /* setup the pipe */
4087 if ((rc = DosCreatePipe(&pipeh[0], &pipeh[1], pipesize)) != NO_ERROR) {
4088 *err = rc;
4089 return NULL;
4092 /* prevent other threads accessing stdio */
4093 DosEnterCritSec();
4095 /* reconnect stdio and execute child */
4096 oldfd = dup(tgtfd);
4097 close(tgtfd);
4098 if (dup2(pipeh[tgtfd], tgtfd) == 0) {
4099 DosClose(pipeh[tgtfd]);
4100 rc = async_system(command);
4103 /* restore stdio */
4104 dup2(oldfd, tgtfd);
4105 close(oldfd);
4107 /* allow other threads access to stdio */
4108 DosExitCritSec();
4110 /* if execution of child was successful return file stream */
4111 if (rc == NO_ERROR)
4112 return fdopen(pipeh[1 - tgtfd], mode);
4113 else {
4114 DosClose(pipeh[1 - tgtfd]);
4115 *err = rc;
4116 return NULL;
4120 static PyObject *
4121 posix_popen(PyObject *self, PyObject *args)
4123 char *name;
4124 char *mode = "r";
4125 int err, bufsize = -1;
4126 FILE *fp;
4127 PyObject *f;
4128 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
4129 return NULL;
4130 Py_BEGIN_ALLOW_THREADS
4131 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
4132 Py_END_ALLOW_THREADS
4133 if (fp == NULL)
4134 return os2_error(err);
4136 f = PyFile_FromFile(fp, name, mode, fclose);
4137 if (f != NULL)
4138 PyFile_SetBufSize(f, bufsize);
4139 return f;
4142 #elif defined(PYCC_GCC)
4144 /* standard posix version of popen() support */
4145 static PyObject *
4146 posix_popen(PyObject *self, PyObject *args)
4148 char *name;
4149 char *mode = "r";
4150 int bufsize = -1;
4151 FILE *fp;
4152 PyObject *f;
4153 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
4154 return NULL;
4155 Py_BEGIN_ALLOW_THREADS
4156 fp = popen(name, mode);
4157 Py_END_ALLOW_THREADS
4158 if (fp == NULL)
4159 return posix_error();
4160 f = PyFile_FromFile(fp, name, mode, pclose);
4161 if (f != NULL)
4162 PyFile_SetBufSize(f, bufsize);
4163 return f;
4166 /* fork() under OS/2 has lots'o'warts
4167 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
4168 * most of this code is a ripoff of the win32 code, but using the
4169 * capabilities of EMX's C library routines
4172 /* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
4173 #define POPEN_1 1
4174 #define POPEN_2 2
4175 #define POPEN_3 3
4176 #define POPEN_4 4
4178 static PyObject *_PyPopen(char *, int, int, int);
4179 static int _PyPclose(FILE *file);
4182 * Internal dictionary mapping popen* file pointers to process handles,
4183 * for use when retrieving the process exit code. See _PyPclose() below
4184 * for more information on this dictionary's use.
4186 static PyObject *_PyPopenProcs = NULL;
4188 /* os2emx version of popen2()
4190 * The result of this function is a pipe (file) connected to the
4191 * process's stdin, and a pipe connected to the process's stdout.
4194 static PyObject *
4195 os2emx_popen2(PyObject *self, PyObject *args)
4197 PyObject *f;
4198 int tm=0;
4200 char *cmdstring;
4201 char *mode = "t";
4202 int bufsize = -1;
4203 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
4204 return NULL;
4206 if (*mode == 't')
4207 tm = O_TEXT;
4208 else if (*mode != 'b') {
4209 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4210 return NULL;
4211 } else
4212 tm = O_BINARY;
4214 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
4216 return f;
4220 * Variation on os2emx.popen2
4222 * The result of this function is 3 pipes - the process's stdin,
4223 * stdout and stderr
4226 static PyObject *
4227 os2emx_popen3(PyObject *self, PyObject *args)
4229 PyObject *f;
4230 int tm = 0;
4232 char *cmdstring;
4233 char *mode = "t";
4234 int bufsize = -1;
4235 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
4236 return NULL;
4238 if (*mode == 't')
4239 tm = O_TEXT;
4240 else if (*mode != 'b') {
4241 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4242 return NULL;
4243 } else
4244 tm = O_BINARY;
4246 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
4248 return f;
4252 * Variation on os2emx.popen2
4254 * The result of this function is 2 pipes - the processes stdin,
4255 * and stdout+stderr combined as a single pipe.
4258 static PyObject *
4259 os2emx_popen4(PyObject *self, PyObject *args)
4261 PyObject *f;
4262 int tm = 0;
4264 char *cmdstring;
4265 char *mode = "t";
4266 int bufsize = -1;
4267 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
4268 return NULL;
4270 if (*mode == 't')
4271 tm = O_TEXT;
4272 else if (*mode != 'b') {
4273 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4274 return NULL;
4275 } else
4276 tm = O_BINARY;
4278 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
4280 return f;
4283 /* a couple of structures for convenient handling of multiple
4284 * file handles and pipes
4286 struct file_ref
4288 int handle;
4289 int flags;
4292 struct pipe_ref
4294 int rd;
4295 int wr;
4298 /* The following code is derived from the win32 code */
4300 static PyObject *
4301 _PyPopen(char *cmdstring, int mode, int n, int bufsize)
4303 struct file_ref stdio[3];
4304 struct pipe_ref p_fd[3];
4305 FILE *p_s[3];
4306 int file_count, i, pipe_err;
4307 pid_t pipe_pid;
4308 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
4309 PyObject *f, *p_f[3];
4311 /* file modes for subsequent fdopen's on pipe handles */
4312 if (mode == O_TEXT)
4314 rd_mode = "rt";
4315 wr_mode = "wt";
4317 else
4319 rd_mode = "rb";
4320 wr_mode = "wb";
4323 /* prepare shell references */
4324 if ((shell = getenv("EMXSHELL")) == NULL)
4325 if ((shell = getenv("COMSPEC")) == NULL)
4327 errno = ENOENT;
4328 return posix_error();
4331 sh_name = _getname(shell);
4332 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
4333 opt = "/c";
4334 else
4335 opt = "-c";
4337 /* save current stdio fds + their flags, and set not inheritable */
4338 i = pipe_err = 0;
4339 while (pipe_err >= 0 && i < 3)
4341 pipe_err = stdio[i].handle = dup(i);
4342 stdio[i].flags = fcntl(i, F_GETFD, 0);
4343 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
4344 i++;
4346 if (pipe_err < 0)
4348 /* didn't get them all saved - clean up and bail out */
4349 int saved_err = errno;
4350 while (i-- > 0)
4352 close(stdio[i].handle);
4354 errno = saved_err;
4355 return posix_error();
4358 /* create pipe ends */
4359 file_count = 2;
4360 if (n == POPEN_3)
4361 file_count = 3;
4362 i = pipe_err = 0;
4363 while ((pipe_err == 0) && (i < file_count))
4364 pipe_err = pipe((int *)&p_fd[i++]);
4365 if (pipe_err < 0)
4367 /* didn't get them all made - clean up and bail out */
4368 while (i-- > 0)
4370 close(p_fd[i].wr);
4371 close(p_fd[i].rd);
4373 errno = EPIPE;
4374 return posix_error();
4377 /* change the actual standard IO streams over temporarily,
4378 * making the retained pipe ends non-inheritable
4380 pipe_err = 0;
4382 /* - stdin */
4383 if (dup2(p_fd[0].rd, 0) == 0)
4385 close(p_fd[0].rd);
4386 i = fcntl(p_fd[0].wr, F_GETFD, 0);
4387 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
4388 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
4390 close(p_fd[0].wr);
4391 pipe_err = -1;
4394 else
4396 pipe_err = -1;
4399 /* - stdout */
4400 if (pipe_err == 0)
4402 if (dup2(p_fd[1].wr, 1) == 1)
4404 close(p_fd[1].wr);
4405 i = fcntl(p_fd[1].rd, F_GETFD, 0);
4406 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
4407 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
4409 close(p_fd[1].rd);
4410 pipe_err = -1;
4413 else
4415 pipe_err = -1;
4419 /* - stderr, as required */
4420 if (pipe_err == 0)
4421 switch (n)
4423 case POPEN_3:
4425 if (dup2(p_fd[2].wr, 2) == 2)
4427 close(p_fd[2].wr);
4428 i = fcntl(p_fd[2].rd, F_GETFD, 0);
4429 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
4430 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
4432 close(p_fd[2].rd);
4433 pipe_err = -1;
4436 else
4438 pipe_err = -1;
4440 break;
4443 case POPEN_4:
4445 if (dup2(1, 2) != 2)
4447 pipe_err = -1;
4449 break;
4453 /* spawn the child process */
4454 if (pipe_err == 0)
4456 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
4457 if (pipe_pid == -1)
4459 pipe_err = -1;
4461 else
4463 /* save the PID into the FILE structure
4464 * NOTE: this implementation doesn't actually
4465 * take advantage of this, but do it for
4466 * completeness - AIM Apr01
4468 for (i = 0; i < file_count; i++)
4469 p_s[i]->_pid = pipe_pid;
4473 /* reset standard IO to normal */
4474 for (i = 0; i < 3; i++)
4476 dup2(stdio[i].handle, i);
4477 fcntl(i, F_SETFD, stdio[i].flags);
4478 close(stdio[i].handle);
4481 /* if any remnant problems, clean up and bail out */
4482 if (pipe_err < 0)
4484 for (i = 0; i < 3; i++)
4486 close(p_fd[i].rd);
4487 close(p_fd[i].wr);
4489 errno = EPIPE;
4490 return posix_error_with_filename(cmdstring);
4493 /* build tuple of file objects to return */
4494 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
4495 PyFile_SetBufSize(p_f[0], bufsize);
4496 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
4497 PyFile_SetBufSize(p_f[1], bufsize);
4498 if (n == POPEN_3)
4500 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
4501 PyFile_SetBufSize(p_f[0], bufsize);
4502 f = PyTuple_Pack(3, p_f[0], p_f[1], p_f[2]);
4504 else
4505 f = PyTuple_Pack(2, p_f[0], p_f[1]);
4508 * Insert the files we've created into the process dictionary
4509 * all referencing the list with the process handle and the
4510 * initial number of files (see description below in _PyPclose).
4511 * Since if _PyPclose later tried to wait on a process when all
4512 * handles weren't closed, it could create a deadlock with the
4513 * child, we spend some energy here to try to ensure that we
4514 * either insert all file handles into the dictionary or none
4515 * at all. It's a little clumsy with the various popen modes
4516 * and variable number of files involved.
4518 if (!_PyPopenProcs)
4520 _PyPopenProcs = PyDict_New();
4523 if (_PyPopenProcs)
4525 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
4526 int ins_rc[3];
4528 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4529 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4531 procObj = PyList_New(2);
4532 pidObj = PyInt_FromLong((long) pipe_pid);
4533 intObj = PyInt_FromLong((long) file_count);
4535 if (procObj && pidObj && intObj)
4537 PyList_SetItem(procObj, 0, pidObj);
4538 PyList_SetItem(procObj, 1, intObj);
4540 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
4541 if (fileObj[0])
4543 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4544 fileObj[0],
4545 procObj);
4547 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
4548 if (fileObj[1])
4550 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4551 fileObj[1],
4552 procObj);
4554 if (file_count >= 3)
4556 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
4557 if (fileObj[2])
4559 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4560 fileObj[2],
4561 procObj);
4565 if (ins_rc[0] < 0 || !fileObj[0] ||
4566 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4567 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
4569 /* Something failed - remove any dictionary
4570 * entries that did make it.
4572 if (!ins_rc[0] && fileObj[0])
4574 PyDict_DelItem(_PyPopenProcs,
4575 fileObj[0]);
4577 if (!ins_rc[1] && fileObj[1])
4579 PyDict_DelItem(_PyPopenProcs,
4580 fileObj[1]);
4582 if (!ins_rc[2] && fileObj[2])
4584 PyDict_DelItem(_PyPopenProcs,
4585 fileObj[2]);
4591 * Clean up our localized references for the dictionary keys
4592 * and value since PyDict_SetItem will Py_INCREF any copies
4593 * that got placed in the dictionary.
4595 Py_XDECREF(procObj);
4596 Py_XDECREF(fileObj[0]);
4597 Py_XDECREF(fileObj[1]);
4598 Py_XDECREF(fileObj[2]);
4601 /* Child is launched. */
4602 return f;
4606 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4607 * exit code for the child process and return as a result of the close.
4609 * This function uses the _PyPopenProcs dictionary in order to map the
4610 * input file pointer to information about the process that was
4611 * originally created by the popen* call that created the file pointer.
4612 * The dictionary uses the file pointer as a key (with one entry
4613 * inserted for each file returned by the original popen* call) and a
4614 * single list object as the value for all files from a single call.
4615 * The list object contains the Win32 process handle at [0], and a file
4616 * count at [1], which is initialized to the total number of file
4617 * handles using that list.
4619 * This function closes whichever handle it is passed, and decrements
4620 * the file count in the dictionary for the process handle pointed to
4621 * by this file. On the last close (when the file count reaches zero),
4622 * this function will wait for the child process and then return its
4623 * exit code as the result of the close() operation. This permits the
4624 * files to be closed in any order - it is always the close() of the
4625 * final handle that will return the exit code.
4627 * NOTE: This function is currently called with the GIL released.
4628 * hence we use the GILState API to manage our state.
4631 static int _PyPclose(FILE *file)
4633 int result;
4634 int exit_code;
4635 pid_t pipe_pid;
4636 PyObject *procObj, *pidObj, *intObj, *fileObj;
4637 int file_count;
4638 #ifdef WITH_THREAD
4639 PyGILState_STATE state;
4640 #endif
4642 /* Close the file handle first, to ensure it can't block the
4643 * child from exiting if it's the last handle.
4645 result = fclose(file);
4647 #ifdef WITH_THREAD
4648 state = PyGILState_Ensure();
4649 #endif
4650 if (_PyPopenProcs)
4652 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4653 (procObj = PyDict_GetItem(_PyPopenProcs,
4654 fileObj)) != NULL &&
4655 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
4656 (intObj = PyList_GetItem(procObj,1)) != NULL)
4658 pipe_pid = (int) PyInt_AsLong(pidObj);
4659 file_count = (int) PyInt_AsLong(intObj);
4661 if (file_count > 1)
4663 /* Still other files referencing process */
4664 file_count--;
4665 PyList_SetItem(procObj,1,
4666 PyInt_FromLong((long) file_count));
4668 else
4670 /* Last file for this process */
4671 if (result != EOF &&
4672 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
4674 /* extract exit status */
4675 if (WIFEXITED(exit_code))
4677 result = WEXITSTATUS(exit_code);
4679 else
4681 errno = EPIPE;
4682 result = -1;
4685 else
4687 /* Indicate failure - this will cause the file object
4688 * to raise an I/O error and translate the last
4689 * error code from errno. We do have a problem with
4690 * last errors that overlap the normal errno table,
4691 * but that's a consistent problem with the file object.
4693 result = -1;
4697 /* Remove this file pointer from dictionary */
4698 PyDict_DelItem(_PyPopenProcs, fileObj);
4700 if (PyDict_Size(_PyPopenProcs) == 0)
4702 Py_DECREF(_PyPopenProcs);
4703 _PyPopenProcs = NULL;
4706 } /* if object retrieval ok */
4708 Py_XDECREF(fileObj);
4709 } /* if _PyPopenProcs */
4711 #ifdef WITH_THREAD
4712 PyGILState_Release(state);
4713 #endif
4714 return result;
4717 #endif /* PYCC_??? */
4719 #elif defined(MS_WINDOWS)
4722 * Portable 'popen' replacement for Win32.
4724 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
4725 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
4726 * Return code handling by David Bolen <db3l@fitlinxx.com>.
4729 #include <malloc.h>
4730 #include <io.h>
4731 #include <fcntl.h>
4733 /* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
4734 #define POPEN_1 1
4735 #define POPEN_2 2
4736 #define POPEN_3 3
4737 #define POPEN_4 4
4739 static PyObject *_PyPopen(char *, int, int);
4740 static int _PyPclose(FILE *file);
4743 * Internal dictionary mapping popen* file pointers to process handles,
4744 * for use when retrieving the process exit code. See _PyPclose() below
4745 * for more information on this dictionary's use.
4747 static PyObject *_PyPopenProcs = NULL;
4750 /* popen that works from a GUI.
4752 * The result of this function is a pipe (file) connected to the
4753 * processes stdin or stdout, depending on the requested mode.
4756 static PyObject *
4757 posix_popen(PyObject *self, PyObject *args)
4759 PyObject *f;
4760 int tm = 0;
4762 char *cmdstring;
4763 char *mode = "r";
4764 int bufsize = -1;
4765 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
4766 return NULL;
4768 if (*mode == 'r')
4769 tm = _O_RDONLY;
4770 else if (*mode != 'w') {
4771 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
4772 return NULL;
4773 } else
4774 tm = _O_WRONLY;
4776 if (bufsize != -1) {
4777 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
4778 return NULL;
4781 if (*(mode+1) == 't')
4782 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
4783 else if (*(mode+1) == 'b')
4784 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
4785 else
4786 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
4788 return f;
4791 /* Variation on win32pipe.popen
4793 * The result of this function is a pipe (file) connected to the
4794 * process's stdin, and a pipe connected to the process's stdout.
4797 static PyObject *
4798 win32_popen2(PyObject *self, PyObject *args)
4800 PyObject *f;
4801 int tm=0;
4803 char *cmdstring;
4804 char *mode = "t";
4805 int bufsize = -1;
4806 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
4807 return NULL;
4809 if (*mode == 't')
4810 tm = _O_TEXT;
4811 else if (*mode != 'b') {
4812 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
4813 return NULL;
4814 } else
4815 tm = _O_BINARY;
4817 if (bufsize != -1) {
4818 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
4819 return NULL;
4822 f = _PyPopen(cmdstring, tm, POPEN_2);
4824 return f;
4828 * Variation on <om win32pipe.popen>
4830 * The result of this function is 3 pipes - the process's stdin,
4831 * stdout and stderr
4834 static PyObject *
4835 win32_popen3(PyObject *self, PyObject *args)
4837 PyObject *f;
4838 int tm = 0;
4840 char *cmdstring;
4841 char *mode = "t";
4842 int bufsize = -1;
4843 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
4844 return NULL;
4846 if (*mode == 't')
4847 tm = _O_TEXT;
4848 else if (*mode != 'b') {
4849 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
4850 return NULL;
4851 } else
4852 tm = _O_BINARY;
4854 if (bufsize != -1) {
4855 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
4856 return NULL;
4859 f = _PyPopen(cmdstring, tm, POPEN_3);
4861 return f;
4865 * Variation on win32pipe.popen
4867 * The result of this function is 2 pipes - the processes stdin,
4868 * and stdout+stderr combined as a single pipe.
4871 static PyObject *
4872 win32_popen4(PyObject *self, PyObject *args)
4874 PyObject *f;
4875 int tm = 0;
4877 char *cmdstring;
4878 char *mode = "t";
4879 int bufsize = -1;
4880 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
4881 return NULL;
4883 if (*mode == 't')
4884 tm = _O_TEXT;
4885 else if (*mode != 'b') {
4886 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
4887 return NULL;
4888 } else
4889 tm = _O_BINARY;
4891 if (bufsize != -1) {
4892 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
4893 return NULL;
4896 f = _PyPopen(cmdstring, tm, POPEN_4);
4898 return f;
4901 static BOOL
4902 _PyPopenCreateProcess(char *cmdstring,
4903 HANDLE hStdin,
4904 HANDLE hStdout,
4905 HANDLE hStderr,
4906 HANDLE *hProcess)
4908 PROCESS_INFORMATION piProcInfo;
4909 STARTUPINFO siStartInfo;
4910 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
4911 char *s1,*s2, *s3 = " /c ";
4912 const char *szConsoleSpawn = "w9xpopen.exe";
4913 int i;
4914 Py_ssize_t x;
4916 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
4917 char *comshell;
4919 s1 = (char *)alloca(i);
4920 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
4921 /* x < i, so x fits into an integer */
4922 return (int)x;
4924 /* Explicitly check if we are using COMMAND.COM. If we are
4925 * then use the w9xpopen hack.
4927 comshell = s1 + x;
4928 while (comshell >= s1 && *comshell != '\\')
4929 --comshell;
4930 ++comshell;
4932 if (GetVersion() < 0x80000000 &&
4933 _stricmp(comshell, "command.com") != 0) {
4934 /* NT/2000 and not using command.com. */
4935 x = i + strlen(s3) + strlen(cmdstring) + 1;
4936 s2 = (char *)alloca(x);
4937 ZeroMemory(s2, x);
4938 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
4940 else {
4942 * Oh gag, we're on Win9x or using COMMAND.COM. Use
4943 * the workaround listed in KB: Q150956
4945 char modulepath[_MAX_PATH];
4946 struct stat statinfo;
4947 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
4948 for (x = i = 0; modulepath[i]; i++)
4949 if (modulepath[i] == SEP)
4950 x = i+1;
4951 modulepath[x] = '\0';
4952 /* Create the full-name to w9xpopen, so we can test it exists */
4953 strncat(modulepath,
4954 szConsoleSpawn,
4955 (sizeof(modulepath)/sizeof(modulepath[0]))
4956 -strlen(modulepath));
4957 if (stat(modulepath, &statinfo) != 0) {
4958 size_t mplen = sizeof(modulepath)/sizeof(modulepath[0]);
4959 /* Eeek - file-not-found - possibly an embedding
4960 situation - see if we can locate it in sys.prefix
4962 strncpy(modulepath,
4963 Py_GetExecPrefix(),
4964 mplen);
4965 modulepath[mplen-1] = '\0';
4966 if (modulepath[strlen(modulepath)-1] != '\\')
4967 strcat(modulepath, "\\");
4968 strncat(modulepath,
4969 szConsoleSpawn,
4970 mplen-strlen(modulepath));
4971 /* No where else to look - raise an easily identifiable
4972 error, rather than leaving Windows to report
4973 "file not found" - as the user is probably blissfully
4974 unaware this shim EXE is used, and it will confuse them.
4975 (well, it confused me for a while ;-)
4977 if (stat(modulepath, &statinfo) != 0) {
4978 PyErr_Format(PyExc_RuntimeError,
4979 "Can not locate '%s' which is needed "
4980 "for popen to work with your shell "
4981 "or platform.",
4982 szConsoleSpawn);
4983 return FALSE;
4986 x = i + strlen(s3) + strlen(cmdstring) + 1 +
4987 strlen(modulepath) +
4988 strlen(szConsoleSpawn) + 1;
4990 s2 = (char *)alloca(x);
4991 ZeroMemory(s2, x);
4992 /* To maintain correct argument passing semantics,
4993 we pass the command-line as it stands, and allow
4994 quoting to be applied. w9xpopen.exe will then
4995 use its argv vector, and re-quote the necessary
4996 args for the ultimate child process.
4998 PyOS_snprintf(
4999 s2, x,
5000 "\"%s\" %s%s%s",
5001 modulepath,
5004 cmdstring);
5005 /* Not passing CREATE_NEW_CONSOLE has been known to
5006 cause random failures on win9x. Specifically a
5007 dialog:
5008 "Your program accessed mem currently in use at xxx"
5009 and a hopeful warning about the stability of your
5010 system.
5011 Cost is Ctrl+C wont kill children, but anyone
5012 who cares can have a go!
5014 dwProcessFlags |= CREATE_NEW_CONSOLE;
5018 /* Could be an else here to try cmd.exe / command.com in the path
5019 Now we'll just error out.. */
5020 else {
5021 PyErr_SetString(PyExc_RuntimeError,
5022 "Cannot locate a COMSPEC environment variable to "
5023 "use as the shell");
5024 return FALSE;
5027 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
5028 siStartInfo.cb = sizeof(STARTUPINFO);
5029 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
5030 siStartInfo.hStdInput = hStdin;
5031 siStartInfo.hStdOutput = hStdout;
5032 siStartInfo.hStdError = hStderr;
5033 siStartInfo.wShowWindow = SW_HIDE;
5035 if (CreateProcess(NULL,
5037 NULL,
5038 NULL,
5039 TRUE,
5040 dwProcessFlags,
5041 NULL,
5042 NULL,
5043 &siStartInfo,
5044 &piProcInfo) ) {
5045 /* Close the handles now so anyone waiting is woken. */
5046 CloseHandle(piProcInfo.hThread);
5048 /* Return process handle */
5049 *hProcess = piProcInfo.hProcess;
5050 return TRUE;
5052 win32_error("CreateProcess", s2);
5053 return FALSE;
5056 /* The following code is based off of KB: Q190351 */
5058 static PyObject *
5059 _PyPopen(char *cmdstring, int mode, int n)
5061 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
5062 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
5063 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
5065 SECURITY_ATTRIBUTES saAttr;
5066 BOOL fSuccess;
5067 int fd1, fd2, fd3;
5068 FILE *f1, *f2, *f3;
5069 long file_count;
5070 PyObject *f;
5072 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
5073 saAttr.bInheritHandle = TRUE;
5074 saAttr.lpSecurityDescriptor = NULL;
5076 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
5077 return win32_error("CreatePipe", NULL);
5079 /* Create new output read handle and the input write handle. Set
5080 * the inheritance properties to FALSE. Otherwise, the child inherits
5081 * these handles; resulting in non-closeable handles to the pipes
5082 * being created. */
5083 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
5084 GetCurrentProcess(), &hChildStdinWrDup, 0,
5085 FALSE,
5086 DUPLICATE_SAME_ACCESS);
5087 if (!fSuccess)
5088 return win32_error("DuplicateHandle", NULL);
5090 /* Close the inheritable version of ChildStdin
5091 that we're using. */
5092 CloseHandle(hChildStdinWr);
5094 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
5095 return win32_error("CreatePipe", NULL);
5097 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
5098 GetCurrentProcess(), &hChildStdoutRdDup, 0,
5099 FALSE, DUPLICATE_SAME_ACCESS);
5100 if (!fSuccess)
5101 return win32_error("DuplicateHandle", NULL);
5103 /* Close the inheritable version of ChildStdout
5104 that we're using. */
5105 CloseHandle(hChildStdoutRd);
5107 if (n != POPEN_4) {
5108 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
5109 return win32_error("CreatePipe", NULL);
5110 fSuccess = DuplicateHandle(GetCurrentProcess(),
5111 hChildStderrRd,
5112 GetCurrentProcess(),
5113 &hChildStderrRdDup, 0,
5114 FALSE, DUPLICATE_SAME_ACCESS);
5115 if (!fSuccess)
5116 return win32_error("DuplicateHandle", NULL);
5117 /* Close the inheritable version of ChildStdErr that we're using. */
5118 CloseHandle(hChildStderrRd);
5121 switch (n) {
5122 case POPEN_1:
5123 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
5124 case _O_WRONLY | _O_TEXT:
5125 /* Case for writing to child Stdin in text mode. */
5126 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5127 f1 = _fdopen(fd1, "w");
5128 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
5129 PyFile_SetBufSize(f, 0);
5130 /* We don't care about these pipes anymore, so close them. */
5131 CloseHandle(hChildStdoutRdDup);
5132 CloseHandle(hChildStderrRdDup);
5133 break;
5135 case _O_RDONLY | _O_TEXT:
5136 /* Case for reading from child Stdout in text mode. */
5137 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5138 f1 = _fdopen(fd1, "r");
5139 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
5140 PyFile_SetBufSize(f, 0);
5141 /* We don't care about these pipes anymore, so close them. */
5142 CloseHandle(hChildStdinWrDup);
5143 CloseHandle(hChildStderrRdDup);
5144 break;
5146 case _O_RDONLY | _O_BINARY:
5147 /* Case for readinig from child Stdout in binary mode. */
5148 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5149 f1 = _fdopen(fd1, "rb");
5150 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
5151 PyFile_SetBufSize(f, 0);
5152 /* We don't care about these pipes anymore, so close them. */
5153 CloseHandle(hChildStdinWrDup);
5154 CloseHandle(hChildStderrRdDup);
5155 break;
5157 case _O_WRONLY | _O_BINARY:
5158 /* Case for writing to child Stdin in binary mode. */
5159 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5160 f1 = _fdopen(fd1, "wb");
5161 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
5162 PyFile_SetBufSize(f, 0);
5163 /* We don't care about these pipes anymore, so close them. */
5164 CloseHandle(hChildStdoutRdDup);
5165 CloseHandle(hChildStderrRdDup);
5166 break;
5168 file_count = 1;
5169 break;
5171 case POPEN_2:
5172 case POPEN_4:
5174 char *m1, *m2;
5175 PyObject *p1, *p2;
5177 if (mode & _O_TEXT) {
5178 m1 = "r";
5179 m2 = "w";
5180 } else {
5181 m1 = "rb";
5182 m2 = "wb";
5185 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5186 f1 = _fdopen(fd1, m2);
5187 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5188 f2 = _fdopen(fd2, m1);
5189 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
5190 PyFile_SetBufSize(p1, 0);
5191 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
5192 PyFile_SetBufSize(p2, 0);
5194 if (n != 4)
5195 CloseHandle(hChildStderrRdDup);
5197 f = PyTuple_Pack(2,p1,p2);
5198 Py_XDECREF(p1);
5199 Py_XDECREF(p2);
5200 file_count = 2;
5201 break;
5204 case POPEN_3:
5206 char *m1, *m2;
5207 PyObject *p1, *p2, *p3;
5209 if (mode & _O_TEXT) {
5210 m1 = "r";
5211 m2 = "w";
5212 } else {
5213 m1 = "rb";
5214 m2 = "wb";
5217 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5218 f1 = _fdopen(fd1, m2);
5219 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5220 f2 = _fdopen(fd2, m1);
5221 fd3 = _open_osfhandle((Py_intptr_t)hChildStderrRdDup, mode);
5222 f3 = _fdopen(fd3, m1);
5223 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
5224 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
5225 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
5226 PyFile_SetBufSize(p1, 0);
5227 PyFile_SetBufSize(p2, 0);
5228 PyFile_SetBufSize(p3, 0);
5229 f = PyTuple_Pack(3,p1,p2,p3);
5230 Py_XDECREF(p1);
5231 Py_XDECREF(p2);
5232 Py_XDECREF(p3);
5233 file_count = 3;
5234 break;
5238 if (n == POPEN_4) {
5239 if (!_PyPopenCreateProcess(cmdstring,
5240 hChildStdinRd,
5241 hChildStdoutWr,
5242 hChildStdoutWr,
5243 &hProcess))
5244 return NULL;
5246 else {
5247 if (!_PyPopenCreateProcess(cmdstring,
5248 hChildStdinRd,
5249 hChildStdoutWr,
5250 hChildStderrWr,
5251 &hProcess))
5252 return NULL;
5256 * Insert the files we've created into the process dictionary
5257 * all referencing the list with the process handle and the
5258 * initial number of files (see description below in _PyPclose).
5259 * Since if _PyPclose later tried to wait on a process when all
5260 * handles weren't closed, it could create a deadlock with the
5261 * child, we spend some energy here to try to ensure that we
5262 * either insert all file handles into the dictionary or none
5263 * at all. It's a little clumsy with the various popen modes
5264 * and variable number of files involved.
5266 if (!_PyPopenProcs) {
5267 _PyPopenProcs = PyDict_New();
5270 if (_PyPopenProcs) {
5271 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
5272 int ins_rc[3];
5274 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
5275 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
5277 procObj = PyList_New(2);
5278 hProcessObj = PyLong_FromVoidPtr(hProcess);
5279 intObj = PyInt_FromLong(file_count);
5281 if (procObj && hProcessObj && intObj) {
5282 PyList_SetItem(procObj,0,hProcessObj);
5283 PyList_SetItem(procObj,1,intObj);
5285 fileObj[0] = PyLong_FromVoidPtr(f1);
5286 if (fileObj[0]) {
5287 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
5288 fileObj[0],
5289 procObj);
5291 if (file_count >= 2) {
5292 fileObj[1] = PyLong_FromVoidPtr(f2);
5293 if (fileObj[1]) {
5294 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
5295 fileObj[1],
5296 procObj);
5299 if (file_count >= 3) {
5300 fileObj[2] = PyLong_FromVoidPtr(f3);
5301 if (fileObj[2]) {
5302 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
5303 fileObj[2],
5304 procObj);
5308 if (ins_rc[0] < 0 || !fileObj[0] ||
5309 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
5310 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
5311 /* Something failed - remove any dictionary
5312 * entries that did make it.
5314 if (!ins_rc[0] && fileObj[0]) {
5315 PyDict_DelItem(_PyPopenProcs,
5316 fileObj[0]);
5318 if (!ins_rc[1] && fileObj[1]) {
5319 PyDict_DelItem(_PyPopenProcs,
5320 fileObj[1]);
5322 if (!ins_rc[2] && fileObj[2]) {
5323 PyDict_DelItem(_PyPopenProcs,
5324 fileObj[2]);
5330 * Clean up our localized references for the dictionary keys
5331 * and value since PyDict_SetItem will Py_INCREF any copies
5332 * that got placed in the dictionary.
5334 Py_XDECREF(procObj);
5335 Py_XDECREF(fileObj[0]);
5336 Py_XDECREF(fileObj[1]);
5337 Py_XDECREF(fileObj[2]);
5340 /* Child is launched. Close the parents copy of those pipe
5341 * handles that only the child should have open. You need to
5342 * make sure that no handles to the write end of the output pipe
5343 * are maintained in this process or else the pipe will not close
5344 * when the child process exits and the ReadFile will hang. */
5346 if (!CloseHandle(hChildStdinRd))
5347 return win32_error("CloseHandle", NULL);
5349 if (!CloseHandle(hChildStdoutWr))
5350 return win32_error("CloseHandle", NULL);
5352 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
5353 return win32_error("CloseHandle", NULL);
5355 return f;
5359 * Wrapper for fclose() to use for popen* files, so we can retrieve the
5360 * exit code for the child process and return as a result of the close.
5362 * This function uses the _PyPopenProcs dictionary in order to map the
5363 * input file pointer to information about the process that was
5364 * originally created by the popen* call that created the file pointer.
5365 * The dictionary uses the file pointer as a key (with one entry
5366 * inserted for each file returned by the original popen* call) and a
5367 * single list object as the value for all files from a single call.
5368 * The list object contains the Win32 process handle at [0], and a file
5369 * count at [1], which is initialized to the total number of file
5370 * handles using that list.
5372 * This function closes whichever handle it is passed, and decrements
5373 * the file count in the dictionary for the process handle pointed to
5374 * by this file. On the last close (when the file count reaches zero),
5375 * this function will wait for the child process and then return its
5376 * exit code as the result of the close() operation. This permits the
5377 * files to be closed in any order - it is always the close() of the
5378 * final handle that will return the exit code.
5380 * NOTE: This function is currently called with the GIL released.
5381 * hence we use the GILState API to manage our state.
5384 static int _PyPclose(FILE *file)
5386 int result;
5387 DWORD exit_code;
5388 HANDLE hProcess;
5389 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
5390 long file_count;
5391 #ifdef WITH_THREAD
5392 PyGILState_STATE state;
5393 #endif
5395 /* Close the file handle first, to ensure it can't block the
5396 * child from exiting if it's the last handle.
5398 result = fclose(file);
5399 #ifdef WITH_THREAD
5400 state = PyGILState_Ensure();
5401 #endif
5402 if (_PyPopenProcs) {
5403 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
5404 (procObj = PyDict_GetItem(_PyPopenProcs,
5405 fileObj)) != NULL &&
5406 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
5407 (intObj = PyList_GetItem(procObj,1)) != NULL) {
5409 hProcess = PyLong_AsVoidPtr(hProcessObj);
5410 file_count = PyInt_AsLong(intObj);
5412 if (file_count > 1) {
5413 /* Still other files referencing process */
5414 file_count--;
5415 PyList_SetItem(procObj,1,
5416 PyInt_FromLong(file_count));
5417 } else {
5418 /* Last file for this process */
5419 if (result != EOF &&
5420 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
5421 GetExitCodeProcess(hProcess, &exit_code)) {
5422 /* Possible truncation here in 16-bit environments, but
5423 * real exit codes are just the lower byte in any event.
5425 result = exit_code;
5426 } else {
5427 /* Indicate failure - this will cause the file object
5428 * to raise an I/O error and translate the last Win32
5429 * error code from errno. We do have a problem with
5430 * last errors that overlap the normal errno table,
5431 * but that's a consistent problem with the file object.
5433 if (result != EOF) {
5434 /* If the error wasn't from the fclose(), then
5435 * set errno for the file object error handling.
5437 errno = GetLastError();
5439 result = -1;
5442 /* Free up the native handle at this point */
5443 CloseHandle(hProcess);
5446 /* Remove this file pointer from dictionary */
5447 PyDict_DelItem(_PyPopenProcs, fileObj);
5449 if (PyDict_Size(_PyPopenProcs) == 0) {
5450 Py_DECREF(_PyPopenProcs);
5451 _PyPopenProcs = NULL;
5454 } /* if object retrieval ok */
5456 Py_XDECREF(fileObj);
5457 } /* if _PyPopenProcs */
5459 #ifdef WITH_THREAD
5460 PyGILState_Release(state);
5461 #endif
5462 return result;
5465 #else /* which OS? */
5466 static PyObject *
5467 posix_popen(PyObject *self, PyObject *args)
5469 char *name;
5470 char *mode = "r";
5471 int bufsize = -1;
5472 FILE *fp;
5473 PyObject *f;
5474 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
5475 return NULL;
5476 /* Strip mode of binary or text modifiers */
5477 if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
5478 mode = "r";
5479 else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
5480 mode = "w";
5481 Py_BEGIN_ALLOW_THREADS
5482 fp = popen(name, mode);
5483 Py_END_ALLOW_THREADS
5484 if (fp == NULL)
5485 return posix_error();
5486 f = PyFile_FromFile(fp, name, mode, pclose);
5487 if (f != NULL)
5488 PyFile_SetBufSize(f, bufsize);
5489 return f;
5492 #endif /* PYOS_??? */
5493 #endif /* HAVE_POPEN */
5496 #ifdef HAVE_SETUID
5497 PyDoc_STRVAR(posix_setuid__doc__,
5498 "setuid(uid)\n\n\
5499 Set the current process's user id.");
5501 static PyObject *
5502 posix_setuid(PyObject *self, PyObject *args)
5504 int uid;
5505 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
5506 return NULL;
5507 if (setuid(uid) < 0)
5508 return posix_error();
5509 Py_INCREF(Py_None);
5510 return Py_None;
5512 #endif /* HAVE_SETUID */
5515 #ifdef HAVE_SETEUID
5516 PyDoc_STRVAR(posix_seteuid__doc__,
5517 "seteuid(uid)\n\n\
5518 Set the current process's effective user id.");
5520 static PyObject *
5521 posix_seteuid (PyObject *self, PyObject *args)
5523 int euid;
5524 if (!PyArg_ParseTuple(args, "i", &euid)) {
5525 return NULL;
5526 } else if (seteuid(euid) < 0) {
5527 return posix_error();
5528 } else {
5529 Py_INCREF(Py_None);
5530 return Py_None;
5533 #endif /* HAVE_SETEUID */
5535 #ifdef HAVE_SETEGID
5536 PyDoc_STRVAR(posix_setegid__doc__,
5537 "setegid(gid)\n\n\
5538 Set the current process's effective group id.");
5540 static PyObject *
5541 posix_setegid (PyObject *self, PyObject *args)
5543 int egid;
5544 if (!PyArg_ParseTuple(args, "i", &egid)) {
5545 return NULL;
5546 } else if (setegid(egid) < 0) {
5547 return posix_error();
5548 } else {
5549 Py_INCREF(Py_None);
5550 return Py_None;
5553 #endif /* HAVE_SETEGID */
5555 #ifdef HAVE_SETREUID
5556 PyDoc_STRVAR(posix_setreuid__doc__,
5557 "setreuid(ruid, euid)\n\n\
5558 Set the current process's real and effective user ids.");
5560 static PyObject *
5561 posix_setreuid (PyObject *self, PyObject *args)
5563 int ruid, euid;
5564 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
5565 return NULL;
5566 } else if (setreuid(ruid, euid) < 0) {
5567 return posix_error();
5568 } else {
5569 Py_INCREF(Py_None);
5570 return Py_None;
5573 #endif /* HAVE_SETREUID */
5575 #ifdef HAVE_SETREGID
5576 PyDoc_STRVAR(posix_setregid__doc__,
5577 "setregid(rgid, egid)\n\n\
5578 Set the current process's real and effective group ids.");
5580 static PyObject *
5581 posix_setregid (PyObject *self, PyObject *args)
5583 int rgid, egid;
5584 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
5585 return NULL;
5586 } else if (setregid(rgid, egid) < 0) {
5587 return posix_error();
5588 } else {
5589 Py_INCREF(Py_None);
5590 return Py_None;
5593 #endif /* HAVE_SETREGID */
5595 #ifdef HAVE_SETGID
5596 PyDoc_STRVAR(posix_setgid__doc__,
5597 "setgid(gid)\n\n\
5598 Set the current process's group id.");
5600 static PyObject *
5601 posix_setgid(PyObject *self, PyObject *args)
5603 int gid;
5604 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
5605 return NULL;
5606 if (setgid(gid) < 0)
5607 return posix_error();
5608 Py_INCREF(Py_None);
5609 return Py_None;
5611 #endif /* HAVE_SETGID */
5613 #ifdef HAVE_SETGROUPS
5614 PyDoc_STRVAR(posix_setgroups__doc__,
5615 "setgroups(list)\n\n\
5616 Set the groups of the current process to list.");
5618 static PyObject *
5619 posix_setgroups(PyObject *self, PyObject *groups)
5621 int i, len;
5622 gid_t grouplist[MAX_GROUPS];
5624 if (!PySequence_Check(groups)) {
5625 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
5626 return NULL;
5628 len = PySequence_Size(groups);
5629 if (len > MAX_GROUPS) {
5630 PyErr_SetString(PyExc_ValueError, "too many groups");
5631 return NULL;
5633 for(i = 0; i < len; i++) {
5634 PyObject *elem;
5635 elem = PySequence_GetItem(groups, i);
5636 if (!elem)
5637 return NULL;
5638 if (!PyInt_Check(elem)) {
5639 if (!PyLong_Check(elem)) {
5640 PyErr_SetString(PyExc_TypeError,
5641 "groups must be integers");
5642 Py_DECREF(elem);
5643 return NULL;
5644 } else {
5645 unsigned long x = PyLong_AsUnsignedLong(elem);
5646 if (PyErr_Occurred()) {
5647 PyErr_SetString(PyExc_TypeError,
5648 "group id too big");
5649 Py_DECREF(elem);
5650 return NULL;
5652 grouplist[i] = x;
5653 /* read back the value to see if it fitted in gid_t */
5654 if (grouplist[i] != x) {
5655 PyErr_SetString(PyExc_TypeError,
5656 "group id too big");
5657 Py_DECREF(elem);
5658 return NULL;
5661 } else {
5662 long x = PyInt_AsLong(elem);
5663 grouplist[i] = x;
5664 if (grouplist[i] != x) {
5665 PyErr_SetString(PyExc_TypeError,
5666 "group id too big");
5667 Py_DECREF(elem);
5668 return NULL;
5671 Py_DECREF(elem);
5674 if (setgroups(len, grouplist) < 0)
5675 return posix_error();
5676 Py_INCREF(Py_None);
5677 return Py_None;
5679 #endif /* HAVE_SETGROUPS */
5681 #if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
5682 static PyObject *
5683 wait_helper(pid_t pid, int status, struct rusage *ru)
5685 PyObject *result;
5686 static PyObject *struct_rusage;
5688 if (pid == -1)
5689 return posix_error();
5691 if (struct_rusage == NULL) {
5692 PyObject *m = PyImport_ImportModuleNoBlock("resource");
5693 if (m == NULL)
5694 return NULL;
5695 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
5696 Py_DECREF(m);
5697 if (struct_rusage == NULL)
5698 return NULL;
5701 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
5702 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
5703 if (!result)
5704 return NULL;
5706 #ifndef doubletime
5707 #define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
5708 #endif
5710 PyStructSequence_SET_ITEM(result, 0,
5711 PyFloat_FromDouble(doubletime(ru->ru_utime)));
5712 PyStructSequence_SET_ITEM(result, 1,
5713 PyFloat_FromDouble(doubletime(ru->ru_stime)));
5714 #define SET_INT(result, index, value)\
5715 PyStructSequence_SET_ITEM(result, index, PyInt_FromLong(value))
5716 SET_INT(result, 2, ru->ru_maxrss);
5717 SET_INT(result, 3, ru->ru_ixrss);
5718 SET_INT(result, 4, ru->ru_idrss);
5719 SET_INT(result, 5, ru->ru_isrss);
5720 SET_INT(result, 6, ru->ru_minflt);
5721 SET_INT(result, 7, ru->ru_majflt);
5722 SET_INT(result, 8, ru->ru_nswap);
5723 SET_INT(result, 9, ru->ru_inblock);
5724 SET_INT(result, 10, ru->ru_oublock);
5725 SET_INT(result, 11, ru->ru_msgsnd);
5726 SET_INT(result, 12, ru->ru_msgrcv);
5727 SET_INT(result, 13, ru->ru_nsignals);
5728 SET_INT(result, 14, ru->ru_nvcsw);
5729 SET_INT(result, 15, ru->ru_nivcsw);
5730 #undef SET_INT
5732 if (PyErr_Occurred()) {
5733 Py_DECREF(result);
5734 return NULL;
5737 return Py_BuildValue("iiN", pid, status, result);
5739 #endif /* HAVE_WAIT3 || HAVE_WAIT4 */
5741 #ifdef HAVE_WAIT3
5742 PyDoc_STRVAR(posix_wait3__doc__,
5743 "wait3(options) -> (pid, status, rusage)\n\n\
5744 Wait for completion of a child process.");
5746 static PyObject *
5747 posix_wait3(PyObject *self, PyObject *args)
5749 pid_t pid;
5750 int options;
5751 struct rusage ru;
5752 WAIT_TYPE status;
5753 WAIT_STATUS_INT(status) = 0;
5755 if (!PyArg_ParseTuple(args, "i:wait3", &options))
5756 return NULL;
5758 Py_BEGIN_ALLOW_THREADS
5759 pid = wait3(&status, options, &ru);
5760 Py_END_ALLOW_THREADS
5762 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
5764 #endif /* HAVE_WAIT3 */
5766 #ifdef HAVE_WAIT4
5767 PyDoc_STRVAR(posix_wait4__doc__,
5768 "wait4(pid, options) -> (pid, status, rusage)\n\n\
5769 Wait for completion of a given child process.");
5771 static PyObject *
5772 posix_wait4(PyObject *self, PyObject *args)
5774 pid_t pid;
5775 int options;
5776 struct rusage ru;
5777 WAIT_TYPE status;
5778 WAIT_STATUS_INT(status) = 0;
5780 if (!PyArg_ParseTuple(args, "ii:wait4", &pid, &options))
5781 return NULL;
5783 Py_BEGIN_ALLOW_THREADS
5784 pid = wait4(pid, &status, options, &ru);
5785 Py_END_ALLOW_THREADS
5787 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
5789 #endif /* HAVE_WAIT4 */
5791 #ifdef HAVE_WAITPID
5792 PyDoc_STRVAR(posix_waitpid__doc__,
5793 "waitpid(pid, options) -> (pid, status)\n\n\
5794 Wait for completion of a given child process.");
5796 static PyObject *
5797 posix_waitpid(PyObject *self, PyObject *args)
5799 pid_t pid;
5800 int options;
5801 WAIT_TYPE status;
5802 WAIT_STATUS_INT(status) = 0;
5804 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
5805 return NULL;
5806 Py_BEGIN_ALLOW_THREADS
5807 pid = waitpid(pid, &status, options);
5808 Py_END_ALLOW_THREADS
5809 if (pid == -1)
5810 return posix_error();
5812 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
5815 #elif defined(HAVE_CWAIT)
5817 /* MS C has a variant of waitpid() that's usable for most purposes. */
5818 PyDoc_STRVAR(posix_waitpid__doc__,
5819 "waitpid(pid, options) -> (pid, status << 8)\n\n"
5820 "Wait for completion of a given process. options is ignored on Windows.");
5822 static PyObject *
5823 posix_waitpid(PyObject *self, PyObject *args)
5825 Py_intptr_t pid;
5826 int status, options;
5828 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
5829 return NULL;
5830 Py_BEGIN_ALLOW_THREADS
5831 pid = _cwait(&status, pid, options);
5832 Py_END_ALLOW_THREADS
5833 if (pid == -1)
5834 return posix_error();
5836 /* shift the status left a byte so this is more like the POSIX waitpid */
5837 return Py_BuildValue("ii", pid, status << 8);
5839 #endif /* HAVE_WAITPID || HAVE_CWAIT */
5841 #ifdef HAVE_WAIT
5842 PyDoc_STRVAR(posix_wait__doc__,
5843 "wait() -> (pid, status)\n\n\
5844 Wait for completion of a child process.");
5846 static PyObject *
5847 posix_wait(PyObject *self, PyObject *noargs)
5849 pid_t pid;
5850 WAIT_TYPE status;
5851 WAIT_STATUS_INT(status) = 0;
5853 Py_BEGIN_ALLOW_THREADS
5854 pid = wait(&status);
5855 Py_END_ALLOW_THREADS
5856 if (pid == -1)
5857 return posix_error();
5859 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
5861 #endif
5864 PyDoc_STRVAR(posix_lstat__doc__,
5865 "lstat(path) -> stat result\n\n\
5866 Like stat(path), but do not follow symbolic links.");
5868 static PyObject *
5869 posix_lstat(PyObject *self, PyObject *args)
5871 #ifdef HAVE_LSTAT
5872 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
5873 #else /* !HAVE_LSTAT */
5874 #ifdef MS_WINDOWS
5875 return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", win32_wstat);
5876 #else
5877 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
5878 #endif
5879 #endif /* !HAVE_LSTAT */
5883 #ifdef HAVE_READLINK
5884 PyDoc_STRVAR(posix_readlink__doc__,
5885 "readlink(path) -> path\n\n\
5886 Return a string representing the path to which the symbolic link points.");
5888 static PyObject *
5889 posix_readlink(PyObject *self, PyObject *args)
5891 PyObject* v;
5892 char buf[MAXPATHLEN];
5893 char *path;
5894 int n;
5895 #ifdef Py_USING_UNICODE
5896 int arg_is_unicode = 0;
5897 #endif
5899 if (!PyArg_ParseTuple(args, "et:readlink",
5900 Py_FileSystemDefaultEncoding, &path))
5901 return NULL;
5902 #ifdef Py_USING_UNICODE
5903 v = PySequence_GetItem(args, 0);
5904 if (v == NULL) {
5905 PyMem_Free(path);
5906 return NULL;
5909 if (PyUnicode_Check(v)) {
5910 arg_is_unicode = 1;
5912 Py_DECREF(v);
5913 #endif
5915 Py_BEGIN_ALLOW_THREADS
5916 n = readlink(path, buf, (int) sizeof buf);
5917 Py_END_ALLOW_THREADS
5918 if (n < 0)
5919 return posix_error_with_allocated_filename(path);
5921 PyMem_Free(path);
5922 v = PyString_FromStringAndSize(buf, n);
5923 #ifdef Py_USING_UNICODE
5924 if (arg_is_unicode) {
5925 PyObject *w;
5927 w = PyUnicode_FromEncodedObject(v,
5928 Py_FileSystemDefaultEncoding,
5929 "strict");
5930 if (w != NULL) {
5931 Py_DECREF(v);
5932 v = w;
5934 else {
5935 /* fall back to the original byte string, as
5936 discussed in patch #683592 */
5937 PyErr_Clear();
5940 #endif
5941 return v;
5943 #endif /* HAVE_READLINK */
5946 #ifdef HAVE_SYMLINK
5947 PyDoc_STRVAR(posix_symlink__doc__,
5948 "symlink(src, dst)\n\n\
5949 Create a symbolic link pointing to src named dst.");
5951 static PyObject *
5952 posix_symlink(PyObject *self, PyObject *args)
5954 return posix_2str(args, "etet:symlink", symlink);
5956 #endif /* HAVE_SYMLINK */
5959 #ifdef HAVE_TIMES
5960 #if defined(PYCC_VACPP) && defined(PYOS_OS2)
5961 static long
5962 system_uptime(void)
5964 ULONG value = 0;
5966 Py_BEGIN_ALLOW_THREADS
5967 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
5968 Py_END_ALLOW_THREADS
5970 return value;
5973 static PyObject *
5974 posix_times(PyObject *self, PyObject *noargs)
5976 /* Currently Only Uptime is Provided -- Others Later */
5977 return Py_BuildValue("ddddd",
5978 (double)0 /* t.tms_utime / HZ */,
5979 (double)0 /* t.tms_stime / HZ */,
5980 (double)0 /* t.tms_cutime / HZ */,
5981 (double)0 /* t.tms_cstime / HZ */,
5982 (double)system_uptime() / 1000);
5984 #else /* not OS2 */
5985 #define NEED_TICKS_PER_SECOND
5986 static long ticks_per_second = -1;
5987 static PyObject *
5988 posix_times(PyObject *self, PyObject *noargs)
5990 struct tms t;
5991 clock_t c;
5992 errno = 0;
5993 c = times(&t);
5994 if (c == (clock_t) -1)
5995 return posix_error();
5996 return Py_BuildValue("ddddd",
5997 (double)t.tms_utime / ticks_per_second,
5998 (double)t.tms_stime / ticks_per_second,
5999 (double)t.tms_cutime / ticks_per_second,
6000 (double)t.tms_cstime / ticks_per_second,
6001 (double)c / ticks_per_second);
6003 #endif /* not OS2 */
6004 #endif /* HAVE_TIMES */
6007 #ifdef MS_WINDOWS
6008 #define HAVE_TIMES /* so the method table will pick it up */
6009 static PyObject *
6010 posix_times(PyObject *self, PyObject *noargs)
6012 FILETIME create, exit, kernel, user;
6013 HANDLE hProc;
6014 hProc = GetCurrentProcess();
6015 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
6016 /* The fields of a FILETIME structure are the hi and lo part
6017 of a 64-bit value expressed in 100 nanosecond units.
6018 1e7 is one second in such units; 1e-7 the inverse.
6019 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
6021 return Py_BuildValue(
6022 "ddddd",
6023 (double)(user.dwHighDateTime*429.4967296 +
6024 user.dwLowDateTime*1e-7),
6025 (double)(kernel.dwHighDateTime*429.4967296 +
6026 kernel.dwLowDateTime*1e-7),
6027 (double)0,
6028 (double)0,
6029 (double)0);
6031 #endif /* MS_WINDOWS */
6033 #ifdef HAVE_TIMES
6034 PyDoc_STRVAR(posix_times__doc__,
6035 "times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
6036 Return a tuple of floating point numbers indicating process times.");
6037 #endif
6040 #ifdef HAVE_GETSID
6041 PyDoc_STRVAR(posix_getsid__doc__,
6042 "getsid(pid) -> sid\n\n\
6043 Call the system call getsid().");
6045 static PyObject *
6046 posix_getsid(PyObject *self, PyObject *args)
6048 pid_t pid;
6049 int sid;
6050 if (!PyArg_ParseTuple(args, "i:getsid", &pid))
6051 return NULL;
6052 sid = getsid(pid);
6053 if (sid < 0)
6054 return posix_error();
6055 return PyInt_FromLong((long)sid);
6057 #endif /* HAVE_GETSID */
6060 #ifdef HAVE_SETSID
6061 PyDoc_STRVAR(posix_setsid__doc__,
6062 "setsid()\n\n\
6063 Call the system call setsid().");
6065 static PyObject *
6066 posix_setsid(PyObject *self, PyObject *noargs)
6068 if (setsid() < 0)
6069 return posix_error();
6070 Py_INCREF(Py_None);
6071 return Py_None;
6073 #endif /* HAVE_SETSID */
6075 #ifdef HAVE_SETPGID
6076 PyDoc_STRVAR(posix_setpgid__doc__,
6077 "setpgid(pid, pgrp)\n\n\
6078 Call the system call setpgid().");
6080 static PyObject *
6081 posix_setpgid(PyObject *self, PyObject *args)
6083 pid_t pid;
6084 int pgrp;
6085 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
6086 return NULL;
6087 if (setpgid(pid, pgrp) < 0)
6088 return posix_error();
6089 Py_INCREF(Py_None);
6090 return Py_None;
6092 #endif /* HAVE_SETPGID */
6095 #ifdef HAVE_TCGETPGRP
6096 PyDoc_STRVAR(posix_tcgetpgrp__doc__,
6097 "tcgetpgrp(fd) -> pgid\n\n\
6098 Return the process group associated with the terminal given by a fd.");
6100 static PyObject *
6101 posix_tcgetpgrp(PyObject *self, PyObject *args)
6103 int fd;
6104 pid_t pgid;
6105 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
6106 return NULL;
6107 pgid = tcgetpgrp(fd);
6108 if (pgid < 0)
6109 return posix_error();
6110 return PyInt_FromLong((long)pgid);
6112 #endif /* HAVE_TCGETPGRP */
6115 #ifdef HAVE_TCSETPGRP
6116 PyDoc_STRVAR(posix_tcsetpgrp__doc__,
6117 "tcsetpgrp(fd, pgid)\n\n\
6118 Set the process group associated with the terminal given by a fd.");
6120 static PyObject *
6121 posix_tcsetpgrp(PyObject *self, PyObject *args)
6123 int fd, pgid;
6124 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
6125 return NULL;
6126 if (tcsetpgrp(fd, pgid) < 0)
6127 return posix_error();
6128 Py_INCREF(Py_None);
6129 return Py_None;
6131 #endif /* HAVE_TCSETPGRP */
6133 /* Functions acting on file descriptors */
6135 PyDoc_STRVAR(posix_open__doc__,
6136 "open(filename, flag [, mode=0777]) -> fd\n\n\
6137 Open a file (for low level IO).");
6139 static PyObject *
6140 posix_open(PyObject *self, PyObject *args)
6142 char *file = NULL;
6143 int flag;
6144 int mode = 0777;
6145 int fd;
6147 #ifdef MS_WINDOWS
6148 if (unicode_file_names()) {
6149 PyUnicodeObject *po;
6150 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
6151 Py_BEGIN_ALLOW_THREADS
6152 /* PyUnicode_AS_UNICODE OK without thread
6153 lock as it is a simple dereference. */
6154 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
6155 Py_END_ALLOW_THREADS
6156 if (fd < 0)
6157 return posix_error();
6158 return PyInt_FromLong((long)fd);
6160 /* Drop the argument parsing error as narrow strings
6161 are also valid. */
6162 PyErr_Clear();
6164 #endif
6166 if (!PyArg_ParseTuple(args, "eti|i",
6167 Py_FileSystemDefaultEncoding, &file,
6168 &flag, &mode))
6169 return NULL;
6171 Py_BEGIN_ALLOW_THREADS
6172 fd = open(file, flag, mode);
6173 Py_END_ALLOW_THREADS
6174 if (fd < 0)
6175 return posix_error_with_allocated_filename(file);
6176 PyMem_Free(file);
6177 return PyInt_FromLong((long)fd);
6181 PyDoc_STRVAR(posix_close__doc__,
6182 "close(fd)\n\n\
6183 Close a file descriptor (for low level IO).");
6185 static PyObject *
6186 posix_close(PyObject *self, PyObject *args)
6188 int fd, res;
6189 if (!PyArg_ParseTuple(args, "i:close", &fd))
6190 return NULL;
6191 Py_BEGIN_ALLOW_THREADS
6192 res = close(fd);
6193 Py_END_ALLOW_THREADS
6194 if (res < 0)
6195 return posix_error();
6196 Py_INCREF(Py_None);
6197 return Py_None;
6201 PyDoc_STRVAR(posix_closerange__doc__,
6202 "closerange(fd_low, fd_high)\n\n\
6203 Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
6205 static PyObject *
6206 posix_closerange(PyObject *self, PyObject *args)
6208 int fd_from, fd_to, i;
6209 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
6210 return NULL;
6211 Py_BEGIN_ALLOW_THREADS
6212 for (i = fd_from; i < fd_to; i++)
6213 close(i);
6214 Py_END_ALLOW_THREADS
6215 Py_RETURN_NONE;
6219 PyDoc_STRVAR(posix_dup__doc__,
6220 "dup(fd) -> fd2\n\n\
6221 Return a duplicate of a file descriptor.");
6223 static PyObject *
6224 posix_dup(PyObject *self, PyObject *args)
6226 int fd;
6227 if (!PyArg_ParseTuple(args, "i:dup", &fd))
6228 return NULL;
6229 Py_BEGIN_ALLOW_THREADS
6230 fd = dup(fd);
6231 Py_END_ALLOW_THREADS
6232 if (fd < 0)
6233 return posix_error();
6234 return PyInt_FromLong((long)fd);
6238 PyDoc_STRVAR(posix_dup2__doc__,
6239 "dup2(old_fd, new_fd)\n\n\
6240 Duplicate file descriptor.");
6242 static PyObject *
6243 posix_dup2(PyObject *self, PyObject *args)
6245 int fd, fd2, res;
6246 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
6247 return NULL;
6248 Py_BEGIN_ALLOW_THREADS
6249 res = dup2(fd, fd2);
6250 Py_END_ALLOW_THREADS
6251 if (res < 0)
6252 return posix_error();
6253 Py_INCREF(Py_None);
6254 return Py_None;
6258 PyDoc_STRVAR(posix_lseek__doc__,
6259 "lseek(fd, pos, how) -> newpos\n\n\
6260 Set the current position of a file descriptor.");
6262 static PyObject *
6263 posix_lseek(PyObject *self, PyObject *args)
6265 int fd, how;
6266 #if defined(MS_WIN64) || defined(MS_WINDOWS)
6267 PY_LONG_LONG pos, res;
6268 #else
6269 off_t pos, res;
6270 #endif
6271 PyObject *posobj;
6272 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
6273 return NULL;
6274 #ifdef SEEK_SET
6275 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
6276 switch (how) {
6277 case 0: how = SEEK_SET; break;
6278 case 1: how = SEEK_CUR; break;
6279 case 2: how = SEEK_END; break;
6281 #endif /* SEEK_END */
6283 #if !defined(HAVE_LARGEFILE_SUPPORT)
6284 pos = PyInt_AsLong(posobj);
6285 #else
6286 pos = PyLong_Check(posobj) ?
6287 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
6288 #endif
6289 if (PyErr_Occurred())
6290 return NULL;
6292 Py_BEGIN_ALLOW_THREADS
6293 #if defined(MS_WIN64) || defined(MS_WINDOWS)
6294 res = _lseeki64(fd, pos, how);
6295 #else
6296 res = lseek(fd, pos, how);
6297 #endif
6298 Py_END_ALLOW_THREADS
6299 if (res < 0)
6300 return posix_error();
6302 #if !defined(HAVE_LARGEFILE_SUPPORT)
6303 return PyInt_FromLong(res);
6304 #else
6305 return PyLong_FromLongLong(res);
6306 #endif
6310 PyDoc_STRVAR(posix_read__doc__,
6311 "read(fd, buffersize) -> string\n\n\
6312 Read a file descriptor.");
6314 static PyObject *
6315 posix_read(PyObject *self, PyObject *args)
6317 int fd, size, n;
6318 PyObject *buffer;
6319 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
6320 return NULL;
6321 if (size < 0) {
6322 errno = EINVAL;
6323 return posix_error();
6325 buffer = PyString_FromStringAndSize((char *)NULL, size);
6326 if (buffer == NULL)
6327 return NULL;
6328 Py_BEGIN_ALLOW_THREADS
6329 n = read(fd, PyString_AsString(buffer), size);
6330 Py_END_ALLOW_THREADS
6331 if (n < 0) {
6332 Py_DECREF(buffer);
6333 return posix_error();
6335 if (n != size)
6336 _PyString_Resize(&buffer, n);
6337 return buffer;
6341 PyDoc_STRVAR(posix_write__doc__,
6342 "write(fd, string) -> byteswritten\n\n\
6343 Write a string to a file descriptor.");
6345 static PyObject *
6346 posix_write(PyObject *self, PyObject *args)
6348 Py_buffer pbuf;
6349 int fd;
6350 Py_ssize_t size;
6352 if (!PyArg_ParseTuple(args, "is*:write", &fd, &pbuf))
6353 return NULL;
6354 Py_BEGIN_ALLOW_THREADS
6355 size = write(fd, pbuf.buf, (size_t)pbuf.len);
6356 Py_END_ALLOW_THREADS
6357 PyBuffer_Release(&pbuf);
6358 if (size < 0)
6359 return posix_error();
6360 return PyInt_FromSsize_t(size);
6364 PyDoc_STRVAR(posix_fstat__doc__,
6365 "fstat(fd) -> stat result\n\n\
6366 Like stat(), but for an open file descriptor.");
6368 static PyObject *
6369 posix_fstat(PyObject *self, PyObject *args)
6371 int fd;
6372 STRUCT_STAT st;
6373 int res;
6374 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
6375 return NULL;
6376 #ifdef __VMS
6377 /* on OpenVMS we must ensure that all bytes are written to the file */
6378 fsync(fd);
6379 #endif
6380 Py_BEGIN_ALLOW_THREADS
6381 res = FSTAT(fd, &st);
6382 Py_END_ALLOW_THREADS
6383 if (res != 0) {
6384 #ifdef MS_WINDOWS
6385 return win32_error("fstat", NULL);
6386 #else
6387 return posix_error();
6388 #endif
6391 return _pystat_fromstructstat(&st);
6395 PyDoc_STRVAR(posix_fdopen__doc__,
6396 "fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
6397 Return an open file object connected to a file descriptor.");
6399 static PyObject *
6400 posix_fdopen(PyObject *self, PyObject *args)
6402 int fd;
6403 char *orgmode = "r";
6404 int bufsize = -1;
6405 FILE *fp;
6406 PyObject *f;
6407 char *mode;
6408 if (!PyArg_ParseTuple(args, "i|si", &fd, &orgmode, &bufsize))
6409 return NULL;
6411 /* Sanitize mode. See fileobject.c */
6412 mode = PyMem_MALLOC(strlen(orgmode)+3);
6413 if (!mode) {
6414 PyErr_NoMemory();
6415 return NULL;
6417 strcpy(mode, orgmode);
6418 if (_PyFile_SanitizeMode(mode)) {
6419 PyMem_FREE(mode);
6420 return NULL;
6422 Py_BEGIN_ALLOW_THREADS
6423 #if !defined(MS_WINDOWS) && defined(HAVE_FCNTL_H)
6424 if (mode[0] == 'a') {
6425 /* try to make sure the O_APPEND flag is set */
6426 int flags;
6427 flags = fcntl(fd, F_GETFL);
6428 if (flags != -1)
6429 fcntl(fd, F_SETFL, flags | O_APPEND);
6430 fp = fdopen(fd, mode);
6431 if (fp == NULL && flags != -1)
6432 /* restore old mode if fdopen failed */
6433 fcntl(fd, F_SETFL, flags);
6434 } else {
6435 fp = fdopen(fd, mode);
6437 #else
6438 fp = fdopen(fd, mode);
6439 #endif
6440 Py_END_ALLOW_THREADS
6441 PyMem_FREE(mode);
6442 if (fp == NULL)
6443 return posix_error();
6444 f = PyFile_FromFile(fp, "<fdopen>", orgmode, fclose);
6445 if (f != NULL)
6446 PyFile_SetBufSize(f, bufsize);
6447 return f;
6450 PyDoc_STRVAR(posix_isatty__doc__,
6451 "isatty(fd) -> bool\n\n\
6452 Return True if the file descriptor 'fd' is an open file descriptor\n\
6453 connected to the slave end of a terminal.");
6455 static PyObject *
6456 posix_isatty(PyObject *self, PyObject *args)
6458 int fd;
6459 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
6460 return NULL;
6461 return PyBool_FromLong(isatty(fd));
6464 #ifdef HAVE_PIPE
6465 PyDoc_STRVAR(posix_pipe__doc__,
6466 "pipe() -> (read_end, write_end)\n\n\
6467 Create a pipe.");
6469 static PyObject *
6470 posix_pipe(PyObject *self, PyObject *noargs)
6472 #if defined(PYOS_OS2)
6473 HFILE read, write;
6474 APIRET rc;
6476 Py_BEGIN_ALLOW_THREADS
6477 rc = DosCreatePipe( &read, &write, 4096);
6478 Py_END_ALLOW_THREADS
6479 if (rc != NO_ERROR)
6480 return os2_error(rc);
6482 return Py_BuildValue("(ii)", read, write);
6483 #else
6484 #if !defined(MS_WINDOWS)
6485 int fds[2];
6486 int res;
6487 Py_BEGIN_ALLOW_THREADS
6488 res = pipe(fds);
6489 Py_END_ALLOW_THREADS
6490 if (res != 0)
6491 return posix_error();
6492 return Py_BuildValue("(ii)", fds[0], fds[1]);
6493 #else /* MS_WINDOWS */
6494 HANDLE read, write;
6495 int read_fd, write_fd;
6496 BOOL ok;
6497 Py_BEGIN_ALLOW_THREADS
6498 ok = CreatePipe(&read, &write, NULL, 0);
6499 Py_END_ALLOW_THREADS
6500 if (!ok)
6501 return win32_error("CreatePipe", NULL);
6502 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
6503 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
6504 return Py_BuildValue("(ii)", read_fd, write_fd);
6505 #endif /* MS_WINDOWS */
6506 #endif
6508 #endif /* HAVE_PIPE */
6511 #ifdef HAVE_MKFIFO
6512 PyDoc_STRVAR(posix_mkfifo__doc__,
6513 "mkfifo(filename [, mode=0666])\n\n\
6514 Create a FIFO (a POSIX named pipe).");
6516 static PyObject *
6517 posix_mkfifo(PyObject *self, PyObject *args)
6519 char *filename;
6520 int mode = 0666;
6521 int res;
6522 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
6523 return NULL;
6524 Py_BEGIN_ALLOW_THREADS
6525 res = mkfifo(filename, mode);
6526 Py_END_ALLOW_THREADS
6527 if (res < 0)
6528 return posix_error();
6529 Py_INCREF(Py_None);
6530 return Py_None;
6532 #endif
6535 #if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
6536 PyDoc_STRVAR(posix_mknod__doc__,
6537 "mknod(filename [, mode=0600, device])\n\n\
6538 Create a filesystem node (file, device special file or named pipe)\n\
6539 named filename. mode specifies both the permissions to use and the\n\
6540 type of node to be created, being combined (bitwise OR) with one of\n\
6541 S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
6542 device defines the newly created device special file (probably using\n\
6543 os.makedev()), otherwise it is ignored.");
6546 static PyObject *
6547 posix_mknod(PyObject *self, PyObject *args)
6549 char *filename;
6550 int mode = 0600;
6551 int device = 0;
6552 int res;
6553 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
6554 return NULL;
6555 Py_BEGIN_ALLOW_THREADS
6556 res = mknod(filename, mode, device);
6557 Py_END_ALLOW_THREADS
6558 if (res < 0)
6559 return posix_error();
6560 Py_INCREF(Py_None);
6561 return Py_None;
6563 #endif
6565 #ifdef HAVE_DEVICE_MACROS
6566 PyDoc_STRVAR(posix_major__doc__,
6567 "major(device) -> major number\n\
6568 Extracts a device major number from a raw device number.");
6570 static PyObject *
6571 posix_major(PyObject *self, PyObject *args)
6573 int device;
6574 if (!PyArg_ParseTuple(args, "i:major", &device))
6575 return NULL;
6576 return PyInt_FromLong((long)major(device));
6579 PyDoc_STRVAR(posix_minor__doc__,
6580 "minor(device) -> minor number\n\
6581 Extracts a device minor number from a raw device number.");
6583 static PyObject *
6584 posix_minor(PyObject *self, PyObject *args)
6586 int device;
6587 if (!PyArg_ParseTuple(args, "i:minor", &device))
6588 return NULL;
6589 return PyInt_FromLong((long)minor(device));
6592 PyDoc_STRVAR(posix_makedev__doc__,
6593 "makedev(major, minor) -> device number\n\
6594 Composes a raw device number from the major and minor device numbers.");
6596 static PyObject *
6597 posix_makedev(PyObject *self, PyObject *args)
6599 int major, minor;
6600 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
6601 return NULL;
6602 return PyInt_FromLong((long)makedev(major, minor));
6604 #endif /* device macros */
6607 #ifdef HAVE_FTRUNCATE
6608 PyDoc_STRVAR(posix_ftruncate__doc__,
6609 "ftruncate(fd, length)\n\n\
6610 Truncate a file to a specified length.");
6612 static PyObject *
6613 posix_ftruncate(PyObject *self, PyObject *args)
6615 int fd;
6616 off_t length;
6617 int res;
6618 PyObject *lenobj;
6620 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
6621 return NULL;
6623 #if !defined(HAVE_LARGEFILE_SUPPORT)
6624 length = PyInt_AsLong(lenobj);
6625 #else
6626 length = PyLong_Check(lenobj) ?
6627 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
6628 #endif
6629 if (PyErr_Occurred())
6630 return NULL;
6632 Py_BEGIN_ALLOW_THREADS
6633 res = ftruncate(fd, length);
6634 Py_END_ALLOW_THREADS
6635 if (res < 0)
6636 return posix_error();
6637 Py_INCREF(Py_None);
6638 return Py_None;
6640 #endif
6642 #ifdef HAVE_PUTENV
6643 PyDoc_STRVAR(posix_putenv__doc__,
6644 "putenv(key, value)\n\n\
6645 Change or add an environment variable.");
6647 /* Save putenv() parameters as values here, so we can collect them when they
6648 * get re-set with another call for the same key. */
6649 static PyObject *posix_putenv_garbage;
6651 static PyObject *
6652 posix_putenv(PyObject *self, PyObject *args)
6654 char *s1, *s2;
6655 char *newenv;
6656 PyObject *newstr;
6657 size_t len;
6659 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
6660 return NULL;
6662 #if defined(PYOS_OS2)
6663 if (stricmp(s1, "BEGINLIBPATH") == 0) {
6664 APIRET rc;
6666 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
6667 if (rc != NO_ERROR)
6668 return os2_error(rc);
6670 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
6671 APIRET rc;
6673 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
6674 if (rc != NO_ERROR)
6675 return os2_error(rc);
6676 } else {
6677 #endif
6679 /* XXX This can leak memory -- not easy to fix :-( */
6680 len = strlen(s1) + strlen(s2) + 2;
6681 /* len includes space for a trailing \0; the size arg to
6682 PyString_FromStringAndSize does not count that */
6683 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
6684 if (newstr == NULL)
6685 return PyErr_NoMemory();
6686 newenv = PyString_AS_STRING(newstr);
6687 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
6688 if (putenv(newenv)) {
6689 Py_DECREF(newstr);
6690 posix_error();
6691 return NULL;
6693 /* Install the first arg and newstr in posix_putenv_garbage;
6694 * this will cause previous value to be collected. This has to
6695 * happen after the real putenv() call because the old value
6696 * was still accessible until then. */
6697 if (PyDict_SetItem(posix_putenv_garbage,
6698 PyTuple_GET_ITEM(args, 0), newstr)) {
6699 /* really not much we can do; just leak */
6700 PyErr_Clear();
6702 else {
6703 Py_DECREF(newstr);
6706 #if defined(PYOS_OS2)
6708 #endif
6709 Py_INCREF(Py_None);
6710 return Py_None;
6712 #endif /* putenv */
6714 #ifdef HAVE_UNSETENV
6715 PyDoc_STRVAR(posix_unsetenv__doc__,
6716 "unsetenv(key)\n\n\
6717 Delete an environment variable.");
6719 static PyObject *
6720 posix_unsetenv(PyObject *self, PyObject *args)
6722 char *s1;
6724 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
6725 return NULL;
6727 unsetenv(s1);
6729 /* Remove the key from posix_putenv_garbage;
6730 * this will cause it to be collected. This has to
6731 * happen after the real unsetenv() call because the
6732 * old value was still accessible until then.
6734 if (PyDict_DelItem(posix_putenv_garbage,
6735 PyTuple_GET_ITEM(args, 0))) {
6736 /* really not much we can do; just leak */
6737 PyErr_Clear();
6740 Py_INCREF(Py_None);
6741 return Py_None;
6743 #endif /* unsetenv */
6745 PyDoc_STRVAR(posix_strerror__doc__,
6746 "strerror(code) -> string\n\n\
6747 Translate an error code to a message string.");
6749 static PyObject *
6750 posix_strerror(PyObject *self, PyObject *args)
6752 int code;
6753 char *message;
6754 if (!PyArg_ParseTuple(args, "i:strerror", &code))
6755 return NULL;
6756 message = strerror(code);
6757 if (message == NULL) {
6758 PyErr_SetString(PyExc_ValueError,
6759 "strerror() argument out of range");
6760 return NULL;
6762 return PyString_FromString(message);
6766 #ifdef HAVE_SYS_WAIT_H
6768 #ifdef WCOREDUMP
6769 PyDoc_STRVAR(posix_WCOREDUMP__doc__,
6770 "WCOREDUMP(status) -> bool\n\n\
6771 Return True if the process returning 'status' was dumped to a core file.");
6773 static PyObject *
6774 posix_WCOREDUMP(PyObject *self, PyObject *args)
6776 WAIT_TYPE status;
6777 WAIT_STATUS_INT(status) = 0;
6779 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
6780 return NULL;
6782 return PyBool_FromLong(WCOREDUMP(status));
6784 #endif /* WCOREDUMP */
6786 #ifdef WIFCONTINUED
6787 PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
6788 "WIFCONTINUED(status) -> bool\n\n\
6789 Return True if the process returning 'status' was continued from a\n\
6790 job control stop.");
6792 static PyObject *
6793 posix_WIFCONTINUED(PyObject *self, PyObject *args)
6795 WAIT_TYPE status;
6796 WAIT_STATUS_INT(status) = 0;
6798 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
6799 return NULL;
6801 return PyBool_FromLong(WIFCONTINUED(status));
6803 #endif /* WIFCONTINUED */
6805 #ifdef WIFSTOPPED
6806 PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
6807 "WIFSTOPPED(status) -> bool\n\n\
6808 Return True if the process returning 'status' was stopped.");
6810 static PyObject *
6811 posix_WIFSTOPPED(PyObject *self, PyObject *args)
6813 WAIT_TYPE status;
6814 WAIT_STATUS_INT(status) = 0;
6816 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
6817 return NULL;
6819 return PyBool_FromLong(WIFSTOPPED(status));
6821 #endif /* WIFSTOPPED */
6823 #ifdef WIFSIGNALED
6824 PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
6825 "WIFSIGNALED(status) -> bool\n\n\
6826 Return True if the process returning 'status' was terminated by a signal.");
6828 static PyObject *
6829 posix_WIFSIGNALED(PyObject *self, PyObject *args)
6831 WAIT_TYPE status;
6832 WAIT_STATUS_INT(status) = 0;
6834 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
6835 return NULL;
6837 return PyBool_FromLong(WIFSIGNALED(status));
6839 #endif /* WIFSIGNALED */
6841 #ifdef WIFEXITED
6842 PyDoc_STRVAR(posix_WIFEXITED__doc__,
6843 "WIFEXITED(status) -> bool\n\n\
6844 Return true if the process returning 'status' exited using the exit()\n\
6845 system call.");
6847 static PyObject *
6848 posix_WIFEXITED(PyObject *self, PyObject *args)
6850 WAIT_TYPE status;
6851 WAIT_STATUS_INT(status) = 0;
6853 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
6854 return NULL;
6856 return PyBool_FromLong(WIFEXITED(status));
6858 #endif /* WIFEXITED */
6860 #ifdef WEXITSTATUS
6861 PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
6862 "WEXITSTATUS(status) -> integer\n\n\
6863 Return the process return code from 'status'.");
6865 static PyObject *
6866 posix_WEXITSTATUS(PyObject *self, PyObject *args)
6868 WAIT_TYPE status;
6869 WAIT_STATUS_INT(status) = 0;
6871 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
6872 return NULL;
6874 return Py_BuildValue("i", WEXITSTATUS(status));
6876 #endif /* WEXITSTATUS */
6878 #ifdef WTERMSIG
6879 PyDoc_STRVAR(posix_WTERMSIG__doc__,
6880 "WTERMSIG(status) -> integer\n\n\
6881 Return the signal that terminated the process that provided the 'status'\n\
6882 value.");
6884 static PyObject *
6885 posix_WTERMSIG(PyObject *self, PyObject *args)
6887 WAIT_TYPE status;
6888 WAIT_STATUS_INT(status) = 0;
6890 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
6891 return NULL;
6893 return Py_BuildValue("i", WTERMSIG(status));
6895 #endif /* WTERMSIG */
6897 #ifdef WSTOPSIG
6898 PyDoc_STRVAR(posix_WSTOPSIG__doc__,
6899 "WSTOPSIG(status) -> integer\n\n\
6900 Return the signal that stopped the process that provided\n\
6901 the 'status' value.");
6903 static PyObject *
6904 posix_WSTOPSIG(PyObject *self, PyObject *args)
6906 WAIT_TYPE status;
6907 WAIT_STATUS_INT(status) = 0;
6909 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
6910 return NULL;
6912 return Py_BuildValue("i", WSTOPSIG(status));
6914 #endif /* WSTOPSIG */
6916 #endif /* HAVE_SYS_WAIT_H */
6919 #if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
6920 #ifdef _SCO_DS
6921 /* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
6922 needed definitions in sys/statvfs.h */
6923 #define _SVID3
6924 #endif
6925 #include <sys/statvfs.h>
6927 static PyObject*
6928 _pystatvfs_fromstructstatvfs(struct statvfs st) {
6929 PyObject *v = PyStructSequence_New(&StatVFSResultType);
6930 if (v == NULL)
6931 return NULL;
6933 #if !defined(HAVE_LARGEFILE_SUPPORT)
6934 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6935 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
6936 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
6937 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
6938 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
6939 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
6940 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
6941 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
6942 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6943 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6944 #else
6945 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6946 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
6947 PyStructSequence_SET_ITEM(v, 2,
6948 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
6949 PyStructSequence_SET_ITEM(v, 3,
6950 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
6951 PyStructSequence_SET_ITEM(v, 4,
6952 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
6953 PyStructSequence_SET_ITEM(v, 5,
6954 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
6955 PyStructSequence_SET_ITEM(v, 6,
6956 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
6957 PyStructSequence_SET_ITEM(v, 7,
6958 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
6959 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6960 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6961 #endif
6963 return v;
6966 PyDoc_STRVAR(posix_fstatvfs__doc__,
6967 "fstatvfs(fd) -> statvfs result\n\n\
6968 Perform an fstatvfs system call on the given fd.");
6970 static PyObject *
6971 posix_fstatvfs(PyObject *self, PyObject *args)
6973 int fd, res;
6974 struct statvfs st;
6976 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
6977 return NULL;
6978 Py_BEGIN_ALLOW_THREADS
6979 res = fstatvfs(fd, &st);
6980 Py_END_ALLOW_THREADS
6981 if (res != 0)
6982 return posix_error();
6984 return _pystatvfs_fromstructstatvfs(st);
6986 #endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
6989 #if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
6990 #include <sys/statvfs.h>
6992 PyDoc_STRVAR(posix_statvfs__doc__,
6993 "statvfs(path) -> statvfs result\n\n\
6994 Perform a statvfs system call on the given path.");
6996 static PyObject *
6997 posix_statvfs(PyObject *self, PyObject *args)
6999 char *path;
7000 int res;
7001 struct statvfs st;
7002 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
7003 return NULL;
7004 Py_BEGIN_ALLOW_THREADS
7005 res = statvfs(path, &st);
7006 Py_END_ALLOW_THREADS
7007 if (res != 0)
7008 return posix_error_with_filename(path);
7010 return _pystatvfs_fromstructstatvfs(st);
7012 #endif /* HAVE_STATVFS */
7015 #ifdef HAVE_TEMPNAM
7016 PyDoc_STRVAR(posix_tempnam__doc__,
7017 "tempnam([dir[, prefix]]) -> string\n\n\
7018 Return a unique name for a temporary file.\n\
7019 The directory and a prefix may be specified as strings; they may be omitted\n\
7020 or None if not needed.");
7022 static PyObject *
7023 posix_tempnam(PyObject *self, PyObject *args)
7025 PyObject *result = NULL;
7026 char *dir = NULL;
7027 char *pfx = NULL;
7028 char *name;
7030 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
7031 return NULL;
7033 if (PyErr_Warn(PyExc_RuntimeWarning,
7034 "tempnam is a potential security risk to your program") < 0)
7035 return NULL;
7037 #ifdef MS_WINDOWS
7038 name = _tempnam(dir, pfx);
7039 #else
7040 name = tempnam(dir, pfx);
7041 #endif
7042 if (name == NULL)
7043 return PyErr_NoMemory();
7044 result = PyString_FromString(name);
7045 free(name);
7046 return result;
7048 #endif
7051 #ifdef HAVE_TMPFILE
7052 PyDoc_STRVAR(posix_tmpfile__doc__,
7053 "tmpfile() -> file object\n\n\
7054 Create a temporary file with no directory entries.");
7056 static PyObject *
7057 posix_tmpfile(PyObject *self, PyObject *noargs)
7059 FILE *fp;
7061 fp = tmpfile();
7062 if (fp == NULL)
7063 return posix_error();
7064 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
7066 #endif
7069 #ifdef HAVE_TMPNAM
7070 PyDoc_STRVAR(posix_tmpnam__doc__,
7071 "tmpnam() -> string\n\n\
7072 Return a unique name for a temporary file.");
7074 static PyObject *
7075 posix_tmpnam(PyObject *self, PyObject *noargs)
7077 char buffer[L_tmpnam];
7078 char *name;
7080 if (PyErr_Warn(PyExc_RuntimeWarning,
7081 "tmpnam is a potential security risk to your program") < 0)
7082 return NULL;
7084 #ifdef USE_TMPNAM_R
7085 name = tmpnam_r(buffer);
7086 #else
7087 name = tmpnam(buffer);
7088 #endif
7089 if (name == NULL) {
7090 PyObject *err = Py_BuildValue("is", 0,
7091 #ifdef USE_TMPNAM_R
7092 "unexpected NULL from tmpnam_r"
7093 #else
7094 "unexpected NULL from tmpnam"
7095 #endif
7097 PyErr_SetObject(PyExc_OSError, err);
7098 Py_XDECREF(err);
7099 return NULL;
7101 return PyString_FromString(buffer);
7103 #endif
7106 /* This is used for fpathconf(), pathconf(), confstr() and sysconf().
7107 * It maps strings representing configuration variable names to
7108 * integer values, allowing those functions to be called with the
7109 * magic names instead of polluting the module's namespace with tons of
7110 * rarely-used constants. There are three separate tables that use
7111 * these definitions.
7113 * This code is always included, even if none of the interfaces that
7114 * need it are included. The #if hackery needed to avoid it would be
7115 * sufficiently pervasive that it's not worth the loss of readability.
7117 struct constdef {
7118 char *name;
7119 long value;
7122 static int
7123 conv_confname(PyObject *arg, int *valuep, struct constdef *table,
7124 size_t tablesize)
7126 if (PyInt_Check(arg)) {
7127 *valuep = PyInt_AS_LONG(arg);
7128 return 1;
7130 if (PyString_Check(arg)) {
7131 /* look up the value in the table using a binary search */
7132 size_t lo = 0;
7133 size_t mid;
7134 size_t hi = tablesize;
7135 int cmp;
7136 char *confname = PyString_AS_STRING(arg);
7137 while (lo < hi) {
7138 mid = (lo + hi) / 2;
7139 cmp = strcmp(confname, table[mid].name);
7140 if (cmp < 0)
7141 hi = mid;
7142 else if (cmp > 0)
7143 lo = mid + 1;
7144 else {
7145 *valuep = table[mid].value;
7146 return 1;
7149 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
7151 else
7152 PyErr_SetString(PyExc_TypeError,
7153 "configuration names must be strings or integers");
7154 return 0;
7158 #if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
7159 static struct constdef posix_constants_pathconf[] = {
7160 #ifdef _PC_ABI_AIO_XFER_MAX
7161 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
7162 #endif
7163 #ifdef _PC_ABI_ASYNC_IO
7164 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
7165 #endif
7166 #ifdef _PC_ASYNC_IO
7167 {"PC_ASYNC_IO", _PC_ASYNC_IO},
7168 #endif
7169 #ifdef _PC_CHOWN_RESTRICTED
7170 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
7171 #endif
7172 #ifdef _PC_FILESIZEBITS
7173 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
7174 #endif
7175 #ifdef _PC_LAST
7176 {"PC_LAST", _PC_LAST},
7177 #endif
7178 #ifdef _PC_LINK_MAX
7179 {"PC_LINK_MAX", _PC_LINK_MAX},
7180 #endif
7181 #ifdef _PC_MAX_CANON
7182 {"PC_MAX_CANON", _PC_MAX_CANON},
7183 #endif
7184 #ifdef _PC_MAX_INPUT
7185 {"PC_MAX_INPUT", _PC_MAX_INPUT},
7186 #endif
7187 #ifdef _PC_NAME_MAX
7188 {"PC_NAME_MAX", _PC_NAME_MAX},
7189 #endif
7190 #ifdef _PC_NO_TRUNC
7191 {"PC_NO_TRUNC", _PC_NO_TRUNC},
7192 #endif
7193 #ifdef _PC_PATH_MAX
7194 {"PC_PATH_MAX", _PC_PATH_MAX},
7195 #endif
7196 #ifdef _PC_PIPE_BUF
7197 {"PC_PIPE_BUF", _PC_PIPE_BUF},
7198 #endif
7199 #ifdef _PC_PRIO_IO
7200 {"PC_PRIO_IO", _PC_PRIO_IO},
7201 #endif
7202 #ifdef _PC_SOCK_MAXBUF
7203 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
7204 #endif
7205 #ifdef _PC_SYNC_IO
7206 {"PC_SYNC_IO", _PC_SYNC_IO},
7207 #endif
7208 #ifdef _PC_VDISABLE
7209 {"PC_VDISABLE", _PC_VDISABLE},
7210 #endif
7213 static int
7214 conv_path_confname(PyObject *arg, int *valuep)
7216 return conv_confname(arg, valuep, posix_constants_pathconf,
7217 sizeof(posix_constants_pathconf)
7218 / sizeof(struct constdef));
7220 #endif
7222 #ifdef HAVE_FPATHCONF
7223 PyDoc_STRVAR(posix_fpathconf__doc__,
7224 "fpathconf(fd, name) -> integer\n\n\
7225 Return the configuration limit name for the file descriptor fd.\n\
7226 If there is no limit, return -1.");
7228 static PyObject *
7229 posix_fpathconf(PyObject *self, PyObject *args)
7231 PyObject *result = NULL;
7232 int name, fd;
7234 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
7235 conv_path_confname, &name)) {
7236 long limit;
7238 errno = 0;
7239 limit = fpathconf(fd, name);
7240 if (limit == -1 && errno != 0)
7241 posix_error();
7242 else
7243 result = PyInt_FromLong(limit);
7245 return result;
7247 #endif
7250 #ifdef HAVE_PATHCONF
7251 PyDoc_STRVAR(posix_pathconf__doc__,
7252 "pathconf(path, name) -> integer\n\n\
7253 Return the configuration limit name for the file or directory path.\n\
7254 If there is no limit, return -1.");
7256 static PyObject *
7257 posix_pathconf(PyObject *self, PyObject *args)
7259 PyObject *result = NULL;
7260 int name;
7261 char *path;
7263 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
7264 conv_path_confname, &name)) {
7265 long limit;
7267 errno = 0;
7268 limit = pathconf(path, name);
7269 if (limit == -1 && errno != 0) {
7270 if (errno == EINVAL)
7271 /* could be a path or name problem */
7272 posix_error();
7273 else
7274 posix_error_with_filename(path);
7276 else
7277 result = PyInt_FromLong(limit);
7279 return result;
7281 #endif
7283 #ifdef HAVE_CONFSTR
7284 static struct constdef posix_constants_confstr[] = {
7285 #ifdef _CS_ARCHITECTURE
7286 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
7287 #endif
7288 #ifdef _CS_HOSTNAME
7289 {"CS_HOSTNAME", _CS_HOSTNAME},
7290 #endif
7291 #ifdef _CS_HW_PROVIDER
7292 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
7293 #endif
7294 #ifdef _CS_HW_SERIAL
7295 {"CS_HW_SERIAL", _CS_HW_SERIAL},
7296 #endif
7297 #ifdef _CS_INITTAB_NAME
7298 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
7299 #endif
7300 #ifdef _CS_LFS64_CFLAGS
7301 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
7302 #endif
7303 #ifdef _CS_LFS64_LDFLAGS
7304 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
7305 #endif
7306 #ifdef _CS_LFS64_LIBS
7307 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
7308 #endif
7309 #ifdef _CS_LFS64_LINTFLAGS
7310 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
7311 #endif
7312 #ifdef _CS_LFS_CFLAGS
7313 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
7314 #endif
7315 #ifdef _CS_LFS_LDFLAGS
7316 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
7317 #endif
7318 #ifdef _CS_LFS_LIBS
7319 {"CS_LFS_LIBS", _CS_LFS_LIBS},
7320 #endif
7321 #ifdef _CS_LFS_LINTFLAGS
7322 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
7323 #endif
7324 #ifdef _CS_MACHINE
7325 {"CS_MACHINE", _CS_MACHINE},
7326 #endif
7327 #ifdef _CS_PATH
7328 {"CS_PATH", _CS_PATH},
7329 #endif
7330 #ifdef _CS_RELEASE
7331 {"CS_RELEASE", _CS_RELEASE},
7332 #endif
7333 #ifdef _CS_SRPC_DOMAIN
7334 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
7335 #endif
7336 #ifdef _CS_SYSNAME
7337 {"CS_SYSNAME", _CS_SYSNAME},
7338 #endif
7339 #ifdef _CS_VERSION
7340 {"CS_VERSION", _CS_VERSION},
7341 #endif
7342 #ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
7343 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
7344 #endif
7345 #ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
7346 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
7347 #endif
7348 #ifdef _CS_XBS5_ILP32_OFF32_LIBS
7349 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
7350 #endif
7351 #ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
7352 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
7353 #endif
7354 #ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
7355 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
7356 #endif
7357 #ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
7358 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
7359 #endif
7360 #ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
7361 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
7362 #endif
7363 #ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
7364 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
7365 #endif
7366 #ifdef _CS_XBS5_LP64_OFF64_CFLAGS
7367 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
7368 #endif
7369 #ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
7370 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
7371 #endif
7372 #ifdef _CS_XBS5_LP64_OFF64_LIBS
7373 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
7374 #endif
7375 #ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
7376 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
7377 #endif
7378 #ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
7379 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
7380 #endif
7381 #ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
7382 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
7383 #endif
7384 #ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
7385 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
7386 #endif
7387 #ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
7388 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
7389 #endif
7390 #ifdef _MIPS_CS_AVAIL_PROCESSORS
7391 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
7392 #endif
7393 #ifdef _MIPS_CS_BASE
7394 {"MIPS_CS_BASE", _MIPS_CS_BASE},
7395 #endif
7396 #ifdef _MIPS_CS_HOSTID
7397 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
7398 #endif
7399 #ifdef _MIPS_CS_HW_NAME
7400 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
7401 #endif
7402 #ifdef _MIPS_CS_NUM_PROCESSORS
7403 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
7404 #endif
7405 #ifdef _MIPS_CS_OSREL_MAJ
7406 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
7407 #endif
7408 #ifdef _MIPS_CS_OSREL_MIN
7409 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
7410 #endif
7411 #ifdef _MIPS_CS_OSREL_PATCH
7412 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
7413 #endif
7414 #ifdef _MIPS_CS_OS_NAME
7415 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
7416 #endif
7417 #ifdef _MIPS_CS_OS_PROVIDER
7418 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
7419 #endif
7420 #ifdef _MIPS_CS_PROCESSORS
7421 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
7422 #endif
7423 #ifdef _MIPS_CS_SERIAL
7424 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
7425 #endif
7426 #ifdef _MIPS_CS_VENDOR
7427 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
7428 #endif
7431 static int
7432 conv_confstr_confname(PyObject *arg, int *valuep)
7434 return conv_confname(arg, valuep, posix_constants_confstr,
7435 sizeof(posix_constants_confstr)
7436 / sizeof(struct constdef));
7439 PyDoc_STRVAR(posix_confstr__doc__,
7440 "confstr(name) -> string\n\n\
7441 Return a string-valued system configuration variable.");
7443 static PyObject *
7444 posix_confstr(PyObject *self, PyObject *args)
7446 PyObject *result = NULL;
7447 int name;
7448 char buffer[256];
7450 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
7451 int len;
7453 errno = 0;
7454 len = confstr(name, buffer, sizeof(buffer));
7455 if (len == 0) {
7456 if (errno) {
7457 posix_error();
7459 else {
7460 result = Py_None;
7461 Py_INCREF(Py_None);
7464 else {
7465 if ((unsigned int)len >= sizeof(buffer)) {
7466 result = PyString_FromStringAndSize(NULL, len-1);
7467 if (result != NULL)
7468 confstr(name, PyString_AS_STRING(result), len);
7470 else
7471 result = PyString_FromStringAndSize(buffer, len-1);
7474 return result;
7476 #endif
7479 #ifdef HAVE_SYSCONF
7480 static struct constdef posix_constants_sysconf[] = {
7481 #ifdef _SC_2_CHAR_TERM
7482 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
7483 #endif
7484 #ifdef _SC_2_C_BIND
7485 {"SC_2_C_BIND", _SC_2_C_BIND},
7486 #endif
7487 #ifdef _SC_2_C_DEV
7488 {"SC_2_C_DEV", _SC_2_C_DEV},
7489 #endif
7490 #ifdef _SC_2_C_VERSION
7491 {"SC_2_C_VERSION", _SC_2_C_VERSION},
7492 #endif
7493 #ifdef _SC_2_FORT_DEV
7494 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
7495 #endif
7496 #ifdef _SC_2_FORT_RUN
7497 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
7498 #endif
7499 #ifdef _SC_2_LOCALEDEF
7500 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
7501 #endif
7502 #ifdef _SC_2_SW_DEV
7503 {"SC_2_SW_DEV", _SC_2_SW_DEV},
7504 #endif
7505 #ifdef _SC_2_UPE
7506 {"SC_2_UPE", _SC_2_UPE},
7507 #endif
7508 #ifdef _SC_2_VERSION
7509 {"SC_2_VERSION", _SC_2_VERSION},
7510 #endif
7511 #ifdef _SC_ABI_ASYNCHRONOUS_IO
7512 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
7513 #endif
7514 #ifdef _SC_ACL
7515 {"SC_ACL", _SC_ACL},
7516 #endif
7517 #ifdef _SC_AIO_LISTIO_MAX
7518 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
7519 #endif
7520 #ifdef _SC_AIO_MAX
7521 {"SC_AIO_MAX", _SC_AIO_MAX},
7522 #endif
7523 #ifdef _SC_AIO_PRIO_DELTA_MAX
7524 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
7525 #endif
7526 #ifdef _SC_ARG_MAX
7527 {"SC_ARG_MAX", _SC_ARG_MAX},
7528 #endif
7529 #ifdef _SC_ASYNCHRONOUS_IO
7530 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
7531 #endif
7532 #ifdef _SC_ATEXIT_MAX
7533 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
7534 #endif
7535 #ifdef _SC_AUDIT
7536 {"SC_AUDIT", _SC_AUDIT},
7537 #endif
7538 #ifdef _SC_AVPHYS_PAGES
7539 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
7540 #endif
7541 #ifdef _SC_BC_BASE_MAX
7542 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
7543 #endif
7544 #ifdef _SC_BC_DIM_MAX
7545 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
7546 #endif
7547 #ifdef _SC_BC_SCALE_MAX
7548 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
7549 #endif
7550 #ifdef _SC_BC_STRING_MAX
7551 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
7552 #endif
7553 #ifdef _SC_CAP
7554 {"SC_CAP", _SC_CAP},
7555 #endif
7556 #ifdef _SC_CHARCLASS_NAME_MAX
7557 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
7558 #endif
7559 #ifdef _SC_CHAR_BIT
7560 {"SC_CHAR_BIT", _SC_CHAR_BIT},
7561 #endif
7562 #ifdef _SC_CHAR_MAX
7563 {"SC_CHAR_MAX", _SC_CHAR_MAX},
7564 #endif
7565 #ifdef _SC_CHAR_MIN
7566 {"SC_CHAR_MIN", _SC_CHAR_MIN},
7567 #endif
7568 #ifdef _SC_CHILD_MAX
7569 {"SC_CHILD_MAX", _SC_CHILD_MAX},
7570 #endif
7571 #ifdef _SC_CLK_TCK
7572 {"SC_CLK_TCK", _SC_CLK_TCK},
7573 #endif
7574 #ifdef _SC_COHER_BLKSZ
7575 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
7576 #endif
7577 #ifdef _SC_COLL_WEIGHTS_MAX
7578 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
7579 #endif
7580 #ifdef _SC_DCACHE_ASSOC
7581 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
7582 #endif
7583 #ifdef _SC_DCACHE_BLKSZ
7584 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
7585 #endif
7586 #ifdef _SC_DCACHE_LINESZ
7587 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
7588 #endif
7589 #ifdef _SC_DCACHE_SZ
7590 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
7591 #endif
7592 #ifdef _SC_DCACHE_TBLKSZ
7593 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
7594 #endif
7595 #ifdef _SC_DELAYTIMER_MAX
7596 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
7597 #endif
7598 #ifdef _SC_EQUIV_CLASS_MAX
7599 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
7600 #endif
7601 #ifdef _SC_EXPR_NEST_MAX
7602 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
7603 #endif
7604 #ifdef _SC_FSYNC
7605 {"SC_FSYNC", _SC_FSYNC},
7606 #endif
7607 #ifdef _SC_GETGR_R_SIZE_MAX
7608 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
7609 #endif
7610 #ifdef _SC_GETPW_R_SIZE_MAX
7611 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
7612 #endif
7613 #ifdef _SC_ICACHE_ASSOC
7614 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
7615 #endif
7616 #ifdef _SC_ICACHE_BLKSZ
7617 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
7618 #endif
7619 #ifdef _SC_ICACHE_LINESZ
7620 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
7621 #endif
7622 #ifdef _SC_ICACHE_SZ
7623 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
7624 #endif
7625 #ifdef _SC_INF
7626 {"SC_INF", _SC_INF},
7627 #endif
7628 #ifdef _SC_INT_MAX
7629 {"SC_INT_MAX", _SC_INT_MAX},
7630 #endif
7631 #ifdef _SC_INT_MIN
7632 {"SC_INT_MIN", _SC_INT_MIN},
7633 #endif
7634 #ifdef _SC_IOV_MAX
7635 {"SC_IOV_MAX", _SC_IOV_MAX},
7636 #endif
7637 #ifdef _SC_IP_SECOPTS
7638 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
7639 #endif
7640 #ifdef _SC_JOB_CONTROL
7641 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
7642 #endif
7643 #ifdef _SC_KERN_POINTERS
7644 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
7645 #endif
7646 #ifdef _SC_KERN_SIM
7647 {"SC_KERN_SIM", _SC_KERN_SIM},
7648 #endif
7649 #ifdef _SC_LINE_MAX
7650 {"SC_LINE_MAX", _SC_LINE_MAX},
7651 #endif
7652 #ifdef _SC_LOGIN_NAME_MAX
7653 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
7654 #endif
7655 #ifdef _SC_LOGNAME_MAX
7656 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
7657 #endif
7658 #ifdef _SC_LONG_BIT
7659 {"SC_LONG_BIT", _SC_LONG_BIT},
7660 #endif
7661 #ifdef _SC_MAC
7662 {"SC_MAC", _SC_MAC},
7663 #endif
7664 #ifdef _SC_MAPPED_FILES
7665 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
7666 #endif
7667 #ifdef _SC_MAXPID
7668 {"SC_MAXPID", _SC_MAXPID},
7669 #endif
7670 #ifdef _SC_MB_LEN_MAX
7671 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
7672 #endif
7673 #ifdef _SC_MEMLOCK
7674 {"SC_MEMLOCK", _SC_MEMLOCK},
7675 #endif
7676 #ifdef _SC_MEMLOCK_RANGE
7677 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
7678 #endif
7679 #ifdef _SC_MEMORY_PROTECTION
7680 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
7681 #endif
7682 #ifdef _SC_MESSAGE_PASSING
7683 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
7684 #endif
7685 #ifdef _SC_MMAP_FIXED_ALIGNMENT
7686 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
7687 #endif
7688 #ifdef _SC_MQ_OPEN_MAX
7689 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
7690 #endif
7691 #ifdef _SC_MQ_PRIO_MAX
7692 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
7693 #endif
7694 #ifdef _SC_NACLS_MAX
7695 {"SC_NACLS_MAX", _SC_NACLS_MAX},
7696 #endif
7697 #ifdef _SC_NGROUPS_MAX
7698 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
7699 #endif
7700 #ifdef _SC_NL_ARGMAX
7701 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
7702 #endif
7703 #ifdef _SC_NL_LANGMAX
7704 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
7705 #endif
7706 #ifdef _SC_NL_MSGMAX
7707 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
7708 #endif
7709 #ifdef _SC_NL_NMAX
7710 {"SC_NL_NMAX", _SC_NL_NMAX},
7711 #endif
7712 #ifdef _SC_NL_SETMAX
7713 {"SC_NL_SETMAX", _SC_NL_SETMAX},
7714 #endif
7715 #ifdef _SC_NL_TEXTMAX
7716 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
7717 #endif
7718 #ifdef _SC_NPROCESSORS_CONF
7719 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
7720 #endif
7721 #ifdef _SC_NPROCESSORS_ONLN
7722 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
7723 #endif
7724 #ifdef _SC_NPROC_CONF
7725 {"SC_NPROC_CONF", _SC_NPROC_CONF},
7726 #endif
7727 #ifdef _SC_NPROC_ONLN
7728 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
7729 #endif
7730 #ifdef _SC_NZERO
7731 {"SC_NZERO", _SC_NZERO},
7732 #endif
7733 #ifdef _SC_OPEN_MAX
7734 {"SC_OPEN_MAX", _SC_OPEN_MAX},
7735 #endif
7736 #ifdef _SC_PAGESIZE
7737 {"SC_PAGESIZE", _SC_PAGESIZE},
7738 #endif
7739 #ifdef _SC_PAGE_SIZE
7740 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
7741 #endif
7742 #ifdef _SC_PASS_MAX
7743 {"SC_PASS_MAX", _SC_PASS_MAX},
7744 #endif
7745 #ifdef _SC_PHYS_PAGES
7746 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
7747 #endif
7748 #ifdef _SC_PII
7749 {"SC_PII", _SC_PII},
7750 #endif
7751 #ifdef _SC_PII_INTERNET
7752 {"SC_PII_INTERNET", _SC_PII_INTERNET},
7753 #endif
7754 #ifdef _SC_PII_INTERNET_DGRAM
7755 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
7756 #endif
7757 #ifdef _SC_PII_INTERNET_STREAM
7758 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
7759 #endif
7760 #ifdef _SC_PII_OSI
7761 {"SC_PII_OSI", _SC_PII_OSI},
7762 #endif
7763 #ifdef _SC_PII_OSI_CLTS
7764 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
7765 #endif
7766 #ifdef _SC_PII_OSI_COTS
7767 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
7768 #endif
7769 #ifdef _SC_PII_OSI_M
7770 {"SC_PII_OSI_M", _SC_PII_OSI_M},
7771 #endif
7772 #ifdef _SC_PII_SOCKET
7773 {"SC_PII_SOCKET", _SC_PII_SOCKET},
7774 #endif
7775 #ifdef _SC_PII_XTI
7776 {"SC_PII_XTI", _SC_PII_XTI},
7777 #endif
7778 #ifdef _SC_POLL
7779 {"SC_POLL", _SC_POLL},
7780 #endif
7781 #ifdef _SC_PRIORITIZED_IO
7782 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
7783 #endif
7784 #ifdef _SC_PRIORITY_SCHEDULING
7785 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
7786 #endif
7787 #ifdef _SC_REALTIME_SIGNALS
7788 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
7789 #endif
7790 #ifdef _SC_RE_DUP_MAX
7791 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
7792 #endif
7793 #ifdef _SC_RTSIG_MAX
7794 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
7795 #endif
7796 #ifdef _SC_SAVED_IDS
7797 {"SC_SAVED_IDS", _SC_SAVED_IDS},
7798 #endif
7799 #ifdef _SC_SCHAR_MAX
7800 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
7801 #endif
7802 #ifdef _SC_SCHAR_MIN
7803 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
7804 #endif
7805 #ifdef _SC_SELECT
7806 {"SC_SELECT", _SC_SELECT},
7807 #endif
7808 #ifdef _SC_SEMAPHORES
7809 {"SC_SEMAPHORES", _SC_SEMAPHORES},
7810 #endif
7811 #ifdef _SC_SEM_NSEMS_MAX
7812 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
7813 #endif
7814 #ifdef _SC_SEM_VALUE_MAX
7815 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
7816 #endif
7817 #ifdef _SC_SHARED_MEMORY_OBJECTS
7818 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
7819 #endif
7820 #ifdef _SC_SHRT_MAX
7821 {"SC_SHRT_MAX", _SC_SHRT_MAX},
7822 #endif
7823 #ifdef _SC_SHRT_MIN
7824 {"SC_SHRT_MIN", _SC_SHRT_MIN},
7825 #endif
7826 #ifdef _SC_SIGQUEUE_MAX
7827 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
7828 #endif
7829 #ifdef _SC_SIGRT_MAX
7830 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
7831 #endif
7832 #ifdef _SC_SIGRT_MIN
7833 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
7834 #endif
7835 #ifdef _SC_SOFTPOWER
7836 {"SC_SOFTPOWER", _SC_SOFTPOWER},
7837 #endif
7838 #ifdef _SC_SPLIT_CACHE
7839 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
7840 #endif
7841 #ifdef _SC_SSIZE_MAX
7842 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
7843 #endif
7844 #ifdef _SC_STACK_PROT
7845 {"SC_STACK_PROT", _SC_STACK_PROT},
7846 #endif
7847 #ifdef _SC_STREAM_MAX
7848 {"SC_STREAM_MAX", _SC_STREAM_MAX},
7849 #endif
7850 #ifdef _SC_SYNCHRONIZED_IO
7851 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
7852 #endif
7853 #ifdef _SC_THREADS
7854 {"SC_THREADS", _SC_THREADS},
7855 #endif
7856 #ifdef _SC_THREAD_ATTR_STACKADDR
7857 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
7858 #endif
7859 #ifdef _SC_THREAD_ATTR_STACKSIZE
7860 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
7861 #endif
7862 #ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
7863 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
7864 #endif
7865 #ifdef _SC_THREAD_KEYS_MAX
7866 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
7867 #endif
7868 #ifdef _SC_THREAD_PRIORITY_SCHEDULING
7869 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
7870 #endif
7871 #ifdef _SC_THREAD_PRIO_INHERIT
7872 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
7873 #endif
7874 #ifdef _SC_THREAD_PRIO_PROTECT
7875 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
7876 #endif
7877 #ifdef _SC_THREAD_PROCESS_SHARED
7878 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
7879 #endif
7880 #ifdef _SC_THREAD_SAFE_FUNCTIONS
7881 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
7882 #endif
7883 #ifdef _SC_THREAD_STACK_MIN
7884 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
7885 #endif
7886 #ifdef _SC_THREAD_THREADS_MAX
7887 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
7888 #endif
7889 #ifdef _SC_TIMERS
7890 {"SC_TIMERS", _SC_TIMERS},
7891 #endif
7892 #ifdef _SC_TIMER_MAX
7893 {"SC_TIMER_MAX", _SC_TIMER_MAX},
7894 #endif
7895 #ifdef _SC_TTY_NAME_MAX
7896 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
7897 #endif
7898 #ifdef _SC_TZNAME_MAX
7899 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
7900 #endif
7901 #ifdef _SC_T_IOV_MAX
7902 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
7903 #endif
7904 #ifdef _SC_UCHAR_MAX
7905 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
7906 #endif
7907 #ifdef _SC_UINT_MAX
7908 {"SC_UINT_MAX", _SC_UINT_MAX},
7909 #endif
7910 #ifdef _SC_UIO_MAXIOV
7911 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
7912 #endif
7913 #ifdef _SC_ULONG_MAX
7914 {"SC_ULONG_MAX", _SC_ULONG_MAX},
7915 #endif
7916 #ifdef _SC_USHRT_MAX
7917 {"SC_USHRT_MAX", _SC_USHRT_MAX},
7918 #endif
7919 #ifdef _SC_VERSION
7920 {"SC_VERSION", _SC_VERSION},
7921 #endif
7922 #ifdef _SC_WORD_BIT
7923 {"SC_WORD_BIT", _SC_WORD_BIT},
7924 #endif
7925 #ifdef _SC_XBS5_ILP32_OFF32
7926 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
7927 #endif
7928 #ifdef _SC_XBS5_ILP32_OFFBIG
7929 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
7930 #endif
7931 #ifdef _SC_XBS5_LP64_OFF64
7932 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
7933 #endif
7934 #ifdef _SC_XBS5_LPBIG_OFFBIG
7935 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
7936 #endif
7937 #ifdef _SC_XOPEN_CRYPT
7938 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
7939 #endif
7940 #ifdef _SC_XOPEN_ENH_I18N
7941 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
7942 #endif
7943 #ifdef _SC_XOPEN_LEGACY
7944 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
7945 #endif
7946 #ifdef _SC_XOPEN_REALTIME
7947 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
7948 #endif
7949 #ifdef _SC_XOPEN_REALTIME_THREADS
7950 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
7951 #endif
7952 #ifdef _SC_XOPEN_SHM
7953 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
7954 #endif
7955 #ifdef _SC_XOPEN_UNIX
7956 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
7957 #endif
7958 #ifdef _SC_XOPEN_VERSION
7959 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
7960 #endif
7961 #ifdef _SC_XOPEN_XCU_VERSION
7962 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
7963 #endif
7964 #ifdef _SC_XOPEN_XPG2
7965 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
7966 #endif
7967 #ifdef _SC_XOPEN_XPG3
7968 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
7969 #endif
7970 #ifdef _SC_XOPEN_XPG4
7971 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
7972 #endif
7975 static int
7976 conv_sysconf_confname(PyObject *arg, int *valuep)
7978 return conv_confname(arg, valuep, posix_constants_sysconf,
7979 sizeof(posix_constants_sysconf)
7980 / sizeof(struct constdef));
7983 PyDoc_STRVAR(posix_sysconf__doc__,
7984 "sysconf(name) -> integer\n\n\
7985 Return an integer-valued system configuration variable.");
7987 static PyObject *
7988 posix_sysconf(PyObject *self, PyObject *args)
7990 PyObject *result = NULL;
7991 int name;
7993 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
7994 int value;
7996 errno = 0;
7997 value = sysconf(name);
7998 if (value == -1 && errno != 0)
7999 posix_error();
8000 else
8001 result = PyInt_FromLong(value);
8003 return result;
8005 #endif
8008 /* This code is used to ensure that the tables of configuration value names
8009 * are in sorted order as required by conv_confname(), and also to build the
8010 * the exported dictionaries that are used to publish information about the
8011 * names available on the host platform.
8013 * Sorting the table at runtime ensures that the table is properly ordered
8014 * when used, even for platforms we're not able to test on. It also makes
8015 * it easier to add additional entries to the tables.
8018 static int
8019 cmp_constdefs(const void *v1, const void *v2)
8021 const struct constdef *c1 =
8022 (const struct constdef *) v1;
8023 const struct constdef *c2 =
8024 (const struct constdef *) v2;
8026 return strcmp(c1->name, c2->name);
8029 static int
8030 setup_confname_table(struct constdef *table, size_t tablesize,
8031 char *tablename, PyObject *module)
8033 PyObject *d = NULL;
8034 size_t i;
8036 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
8037 d = PyDict_New();
8038 if (d == NULL)
8039 return -1;
8041 for (i=0; i < tablesize; ++i) {
8042 PyObject *o = PyInt_FromLong(table[i].value);
8043 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
8044 Py_XDECREF(o);
8045 Py_DECREF(d);
8046 return -1;
8048 Py_DECREF(o);
8050 return PyModule_AddObject(module, tablename, d);
8053 /* Return -1 on failure, 0 on success. */
8054 static int
8055 setup_confname_tables(PyObject *module)
8057 #if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
8058 if (setup_confname_table(posix_constants_pathconf,
8059 sizeof(posix_constants_pathconf)
8060 / sizeof(struct constdef),
8061 "pathconf_names", module))
8062 return -1;
8063 #endif
8064 #ifdef HAVE_CONFSTR
8065 if (setup_confname_table(posix_constants_confstr,
8066 sizeof(posix_constants_confstr)
8067 / sizeof(struct constdef),
8068 "confstr_names", module))
8069 return -1;
8070 #endif
8071 #ifdef HAVE_SYSCONF
8072 if (setup_confname_table(posix_constants_sysconf,
8073 sizeof(posix_constants_sysconf)
8074 / sizeof(struct constdef),
8075 "sysconf_names", module))
8076 return -1;
8077 #endif
8078 return 0;
8082 PyDoc_STRVAR(posix_abort__doc__,
8083 "abort() -> does not return!\n\n\
8084 Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
8085 in the hardest way possible on the hosting operating system.");
8087 static PyObject *
8088 posix_abort(PyObject *self, PyObject *noargs)
8090 abort();
8091 /*NOTREACHED*/
8092 Py_FatalError("abort() called from Python code didn't abort!");
8093 return NULL;
8096 #ifdef MS_WINDOWS
8097 PyDoc_STRVAR(win32_startfile__doc__,
8098 "startfile(filepath [, operation]) - Start a file with its associated\n\
8099 application.\n\
8101 When \"operation\" is not specified or \"open\", this acts like\n\
8102 double-clicking the file in Explorer, or giving the file name as an\n\
8103 argument to the DOS \"start\" command: the file is opened with whatever\n\
8104 application (if any) its extension is associated.\n\
8105 When another \"operation\" is given, it specifies what should be done with\n\
8106 the file. A typical operation is \"print\".\n\
8108 startfile returns as soon as the associated application is launched.\n\
8109 There is no option to wait for the application to close, and no way\n\
8110 to retrieve the application's exit status.\n\
8112 The filepath is relative to the current directory. If you want to use\n\
8113 an absolute path, make sure the first character is not a slash (\"/\");\n\
8114 the underlying Win32 ShellExecute function doesn't work if it is.");
8116 static PyObject *
8117 win32_startfile(PyObject *self, PyObject *args)
8119 char *filepath;
8120 char *operation = NULL;
8121 HINSTANCE rc;
8122 #ifdef Py_WIN_WIDE_FILENAMES
8123 if (unicode_file_names()) {
8124 PyObject *unipath, *woperation = NULL;
8125 if (!PyArg_ParseTuple(args, "U|s:startfile",
8126 &unipath, &operation)) {
8127 PyErr_Clear();
8128 goto normal;
8132 if (operation) {
8133 woperation = PyUnicode_DecodeASCII(operation,
8134 strlen(operation), NULL);
8135 if (!woperation) {
8136 PyErr_Clear();
8137 operation = NULL;
8138 goto normal;
8142 Py_BEGIN_ALLOW_THREADS
8143 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
8144 PyUnicode_AS_UNICODE(unipath),
8145 NULL, NULL, SW_SHOWNORMAL);
8146 Py_END_ALLOW_THREADS
8148 Py_XDECREF(woperation);
8149 if (rc <= (HINSTANCE)32) {
8150 PyObject *errval = win32_error_unicode("startfile",
8151 PyUnicode_AS_UNICODE(unipath));
8152 return errval;
8154 Py_INCREF(Py_None);
8155 return Py_None;
8157 #endif
8159 normal:
8160 if (!PyArg_ParseTuple(args, "et|s:startfile",
8161 Py_FileSystemDefaultEncoding, &filepath,
8162 &operation))
8163 return NULL;
8164 Py_BEGIN_ALLOW_THREADS
8165 rc = ShellExecute((HWND)0, operation, filepath,
8166 NULL, NULL, SW_SHOWNORMAL);
8167 Py_END_ALLOW_THREADS
8168 if (rc <= (HINSTANCE)32) {
8169 PyObject *errval = win32_error("startfile", filepath);
8170 PyMem_Free(filepath);
8171 return errval;
8173 PyMem_Free(filepath);
8174 Py_INCREF(Py_None);
8175 return Py_None;
8177 #endif
8179 #ifdef HAVE_GETLOADAVG
8180 PyDoc_STRVAR(posix_getloadavg__doc__,
8181 "getloadavg() -> (float, float, float)\n\n\
8182 Return the number of processes in the system run queue averaged over\n\
8183 the last 1, 5, and 15 minutes or raises OSError if the load average\n\
8184 was unobtainable");
8186 static PyObject *
8187 posix_getloadavg(PyObject *self, PyObject *noargs)
8189 double loadavg[3];
8190 if (getloadavg(loadavg, 3)!=3) {
8191 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
8192 return NULL;
8193 } else
8194 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
8196 #endif
8198 #ifdef MS_WINDOWS
8200 PyDoc_STRVAR(win32_urandom__doc__,
8201 "urandom(n) -> str\n\n\
8202 Return a string of n random bytes suitable for cryptographic use.");
8204 typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
8205 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
8206 DWORD dwFlags );
8207 typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
8208 BYTE *pbBuffer );
8210 static CRYPTGENRANDOM pCryptGenRandom = NULL;
8211 /* This handle is never explicitly released. Instead, the operating
8212 system will release it when the process terminates. */
8213 static HCRYPTPROV hCryptProv = 0;
8215 static PyObject*
8216 win32_urandom(PyObject *self, PyObject *args)
8218 int howMany;
8219 PyObject* result;
8221 /* Read arguments */
8222 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
8223 return NULL;
8224 if (howMany < 0)
8225 return PyErr_Format(PyExc_ValueError,
8226 "negative argument not allowed");
8228 if (hCryptProv == 0) {
8229 HINSTANCE hAdvAPI32 = NULL;
8230 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
8232 /* Obtain handle to the DLL containing CryptoAPI
8233 This should not fail */
8234 hAdvAPI32 = GetModuleHandle("advapi32.dll");
8235 if(hAdvAPI32 == NULL)
8236 return win32_error("GetModuleHandle", NULL);
8238 /* Obtain pointers to the CryptoAPI functions
8239 This will fail on some early versions of Win95 */
8240 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
8241 hAdvAPI32,
8242 "CryptAcquireContextA");
8243 if (pCryptAcquireContext == NULL)
8244 return PyErr_Format(PyExc_NotImplementedError,
8245 "CryptAcquireContextA not found");
8247 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
8248 hAdvAPI32, "CryptGenRandom");
8249 if (pCryptGenRandom == NULL)
8250 return PyErr_Format(PyExc_NotImplementedError,
8251 "CryptGenRandom not found");
8253 /* Acquire context */
8254 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
8255 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
8256 return win32_error("CryptAcquireContext", NULL);
8259 /* Allocate bytes */
8260 result = PyString_FromStringAndSize(NULL, howMany);
8261 if (result != NULL) {
8262 /* Get random data */
8263 memset(PyString_AS_STRING(result), 0, howMany); /* zero seed */
8264 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
8265 PyString_AS_STRING(result))) {
8266 Py_DECREF(result);
8267 return win32_error("CryptGenRandom", NULL);
8270 return result;
8272 #endif
8274 #ifdef __VMS
8275 /* Use openssl random routine */
8276 #include <openssl/rand.h>
8277 PyDoc_STRVAR(vms_urandom__doc__,
8278 "urandom(n) -> str\n\n\
8279 Return a string of n random bytes suitable for cryptographic use.");
8281 static PyObject*
8282 vms_urandom(PyObject *self, PyObject *args)
8284 int howMany;
8285 PyObject* result;
8287 /* Read arguments */
8288 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
8289 return NULL;
8290 if (howMany < 0)
8291 return PyErr_Format(PyExc_ValueError,
8292 "negative argument not allowed");
8294 /* Allocate bytes */
8295 result = PyString_FromStringAndSize(NULL, howMany);
8296 if (result != NULL) {
8297 /* Get random data */
8298 if (RAND_pseudo_bytes((unsigned char*)
8299 PyString_AS_STRING(result),
8300 howMany) < 0) {
8301 Py_DECREF(result);
8302 return PyErr_Format(PyExc_ValueError,
8303 "RAND_pseudo_bytes");
8306 return result;
8308 #endif
8310 static PyMethodDef posix_methods[] = {
8311 {"access", posix_access, METH_VARARGS, posix_access__doc__},
8312 #ifdef HAVE_TTYNAME
8313 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
8314 #endif
8315 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
8316 #ifdef HAVE_CHFLAGS
8317 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
8318 #endif /* HAVE_CHFLAGS */
8319 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
8320 #ifdef HAVE_FCHMOD
8321 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
8322 #endif /* HAVE_FCHMOD */
8323 #ifdef HAVE_CHOWN
8324 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
8325 #endif /* HAVE_CHOWN */
8326 #ifdef HAVE_LCHMOD
8327 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
8328 #endif /* HAVE_LCHMOD */
8329 #ifdef HAVE_FCHOWN
8330 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
8331 #endif /* HAVE_FCHOWN */
8332 #ifdef HAVE_LCHFLAGS
8333 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
8334 #endif /* HAVE_LCHFLAGS */
8335 #ifdef HAVE_LCHOWN
8336 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
8337 #endif /* HAVE_LCHOWN */
8338 #ifdef HAVE_CHROOT
8339 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
8340 #endif
8341 #ifdef HAVE_CTERMID
8342 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
8343 #endif
8344 #ifdef HAVE_GETCWD
8345 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
8346 #ifdef Py_USING_UNICODE
8347 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
8348 #endif
8349 #endif
8350 #ifdef HAVE_LINK
8351 {"link", posix_link, METH_VARARGS, posix_link__doc__},
8352 #endif /* HAVE_LINK */
8353 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
8354 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
8355 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
8356 #ifdef HAVE_NICE
8357 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
8358 #endif /* HAVE_NICE */
8359 #ifdef HAVE_READLINK
8360 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
8361 #endif /* HAVE_READLINK */
8362 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
8363 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
8364 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
8365 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
8366 #ifdef HAVE_SYMLINK
8367 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
8368 #endif /* HAVE_SYMLINK */
8369 #ifdef HAVE_SYSTEM
8370 {"system", posix_system, METH_VARARGS, posix_system__doc__},
8371 #endif
8372 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
8373 #ifdef HAVE_UNAME
8374 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
8375 #endif /* HAVE_UNAME */
8376 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
8377 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
8378 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
8379 #ifdef HAVE_TIMES
8380 {"times", posix_times, METH_NOARGS, posix_times__doc__},
8381 #endif /* HAVE_TIMES */
8382 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
8383 #ifdef HAVE_EXECV
8384 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
8385 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
8386 #endif /* HAVE_EXECV */
8387 #ifdef HAVE_SPAWNV
8388 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
8389 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
8390 #if defined(PYOS_OS2)
8391 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
8392 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
8393 #endif /* PYOS_OS2 */
8394 #endif /* HAVE_SPAWNV */
8395 #ifdef HAVE_FORK1
8396 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
8397 #endif /* HAVE_FORK1 */
8398 #ifdef HAVE_FORK
8399 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
8400 #endif /* HAVE_FORK */
8401 #if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
8402 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
8403 #endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
8404 #ifdef HAVE_FORKPTY
8405 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
8406 #endif /* HAVE_FORKPTY */
8407 #ifdef HAVE_GETEGID
8408 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
8409 #endif /* HAVE_GETEGID */
8410 #ifdef HAVE_GETEUID
8411 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
8412 #endif /* HAVE_GETEUID */
8413 #ifdef HAVE_GETGID
8414 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
8415 #endif /* HAVE_GETGID */
8416 #ifdef HAVE_GETGROUPS
8417 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
8418 #endif
8419 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
8420 #ifdef HAVE_GETPGRP
8421 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
8422 #endif /* HAVE_GETPGRP */
8423 #ifdef HAVE_GETPPID
8424 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
8425 #endif /* HAVE_GETPPID */
8426 #ifdef HAVE_GETUID
8427 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
8428 #endif /* HAVE_GETUID */
8429 #ifdef HAVE_GETLOGIN
8430 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
8431 #endif
8432 #ifdef HAVE_KILL
8433 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
8434 #endif /* HAVE_KILL */
8435 #ifdef HAVE_KILLPG
8436 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
8437 #endif /* HAVE_KILLPG */
8438 #ifdef HAVE_PLOCK
8439 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
8440 #endif /* HAVE_PLOCK */
8441 #ifdef HAVE_POPEN
8442 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
8443 #ifdef MS_WINDOWS
8444 {"popen2", win32_popen2, METH_VARARGS},
8445 {"popen3", win32_popen3, METH_VARARGS},
8446 {"popen4", win32_popen4, METH_VARARGS},
8447 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
8448 #else
8449 #if defined(PYOS_OS2) && defined(PYCC_GCC)
8450 {"popen2", os2emx_popen2, METH_VARARGS},
8451 {"popen3", os2emx_popen3, METH_VARARGS},
8452 {"popen4", os2emx_popen4, METH_VARARGS},
8453 #endif
8454 #endif
8455 #endif /* HAVE_POPEN */
8456 #ifdef HAVE_SETUID
8457 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
8458 #endif /* HAVE_SETUID */
8459 #ifdef HAVE_SETEUID
8460 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
8461 #endif /* HAVE_SETEUID */
8462 #ifdef HAVE_SETEGID
8463 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
8464 #endif /* HAVE_SETEGID */
8465 #ifdef HAVE_SETREUID
8466 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
8467 #endif /* HAVE_SETREUID */
8468 #ifdef HAVE_SETREGID
8469 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
8470 #endif /* HAVE_SETREGID */
8471 #ifdef HAVE_SETGID
8472 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
8473 #endif /* HAVE_SETGID */
8474 #ifdef HAVE_SETGROUPS
8475 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
8476 #endif /* HAVE_SETGROUPS */
8477 #ifdef HAVE_GETPGID
8478 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
8479 #endif /* HAVE_GETPGID */
8480 #ifdef HAVE_SETPGRP
8481 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
8482 #endif /* HAVE_SETPGRP */
8483 #ifdef HAVE_WAIT
8484 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
8485 #endif /* HAVE_WAIT */
8486 #ifdef HAVE_WAIT3
8487 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
8488 #endif /* HAVE_WAIT3 */
8489 #ifdef HAVE_WAIT4
8490 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
8491 #endif /* HAVE_WAIT4 */
8492 #if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
8493 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
8494 #endif /* HAVE_WAITPID */
8495 #ifdef HAVE_GETSID
8496 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
8497 #endif /* HAVE_GETSID */
8498 #ifdef HAVE_SETSID
8499 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
8500 #endif /* HAVE_SETSID */
8501 #ifdef HAVE_SETPGID
8502 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
8503 #endif /* HAVE_SETPGID */
8504 #ifdef HAVE_TCGETPGRP
8505 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
8506 #endif /* HAVE_TCGETPGRP */
8507 #ifdef HAVE_TCSETPGRP
8508 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
8509 #endif /* HAVE_TCSETPGRP */
8510 {"open", posix_open, METH_VARARGS, posix_open__doc__},
8511 {"close", posix_close, METH_VARARGS, posix_close__doc__},
8512 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
8513 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
8514 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
8515 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
8516 {"read", posix_read, METH_VARARGS, posix_read__doc__},
8517 {"write", posix_write, METH_VARARGS, posix_write__doc__},
8518 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
8519 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
8520 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
8521 #ifdef HAVE_PIPE
8522 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
8523 #endif
8524 #ifdef HAVE_MKFIFO
8525 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
8526 #endif
8527 #if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
8528 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
8529 #endif
8530 #ifdef HAVE_DEVICE_MACROS
8531 {"major", posix_major, METH_VARARGS, posix_major__doc__},
8532 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
8533 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
8534 #endif
8535 #ifdef HAVE_FTRUNCATE
8536 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
8537 #endif
8538 #ifdef HAVE_PUTENV
8539 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
8540 #endif
8541 #ifdef HAVE_UNSETENV
8542 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
8543 #endif
8544 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
8545 #ifdef HAVE_FCHDIR
8546 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
8547 #endif
8548 #ifdef HAVE_FSYNC
8549 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
8550 #endif
8551 #ifdef HAVE_FDATASYNC
8552 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
8553 #endif
8554 #ifdef HAVE_SYS_WAIT_H
8555 #ifdef WCOREDUMP
8556 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
8557 #endif /* WCOREDUMP */
8558 #ifdef WIFCONTINUED
8559 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
8560 #endif /* WIFCONTINUED */
8561 #ifdef WIFSTOPPED
8562 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
8563 #endif /* WIFSTOPPED */
8564 #ifdef WIFSIGNALED
8565 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
8566 #endif /* WIFSIGNALED */
8567 #ifdef WIFEXITED
8568 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
8569 #endif /* WIFEXITED */
8570 #ifdef WEXITSTATUS
8571 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
8572 #endif /* WEXITSTATUS */
8573 #ifdef WTERMSIG
8574 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
8575 #endif /* WTERMSIG */
8576 #ifdef WSTOPSIG
8577 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
8578 #endif /* WSTOPSIG */
8579 #endif /* HAVE_SYS_WAIT_H */
8580 #if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
8581 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
8582 #endif
8583 #if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
8584 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
8585 #endif
8586 #ifdef HAVE_TMPFILE
8587 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
8588 #endif
8589 #ifdef HAVE_TEMPNAM
8590 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
8591 #endif
8592 #ifdef HAVE_TMPNAM
8593 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
8594 #endif
8595 #ifdef HAVE_CONFSTR
8596 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
8597 #endif
8598 #ifdef HAVE_SYSCONF
8599 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
8600 #endif
8601 #ifdef HAVE_FPATHCONF
8602 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
8603 #endif
8604 #ifdef HAVE_PATHCONF
8605 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
8606 #endif
8607 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
8608 #ifdef MS_WINDOWS
8609 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
8610 #endif
8611 #ifdef HAVE_GETLOADAVG
8612 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
8613 #endif
8614 #ifdef MS_WINDOWS
8615 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
8616 #endif
8617 #ifdef __VMS
8618 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
8619 #endif
8620 {NULL, NULL} /* Sentinel */
8624 static int
8625 ins(PyObject *module, char *symbol, long value)
8627 return PyModule_AddIntConstant(module, symbol, value);
8630 #if defined(PYOS_OS2)
8631 /* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
8632 static int insertvalues(PyObject *module)
8634 APIRET rc;
8635 ULONG values[QSV_MAX+1];
8636 PyObject *v;
8637 char *ver, tmp[50];
8639 Py_BEGIN_ALLOW_THREADS
8640 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
8641 Py_END_ALLOW_THREADS
8643 if (rc != NO_ERROR) {
8644 os2_error(rc);
8645 return -1;
8648 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
8649 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
8650 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
8651 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
8652 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
8653 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
8654 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
8656 switch (values[QSV_VERSION_MINOR]) {
8657 case 0: ver = "2.00"; break;
8658 case 10: ver = "2.10"; break;
8659 case 11: ver = "2.11"; break;
8660 case 30: ver = "3.00"; break;
8661 case 40: ver = "4.00"; break;
8662 case 50: ver = "5.00"; break;
8663 default:
8664 PyOS_snprintf(tmp, sizeof(tmp),
8665 "%d-%d", values[QSV_VERSION_MAJOR],
8666 values[QSV_VERSION_MINOR]);
8667 ver = &tmp[0];
8670 /* Add Indicator of the Version of the Operating System */
8671 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
8672 return -1;
8674 /* Add Indicator of Which Drive was Used to Boot the System */
8675 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
8676 tmp[1] = ':';
8677 tmp[2] = '\0';
8679 return PyModule_AddStringConstant(module, "bootdrive", tmp);
8681 #endif
8683 static int
8684 all_ins(PyObject *d)
8686 #ifdef F_OK
8687 if (ins(d, "F_OK", (long)F_OK)) return -1;
8688 #endif
8689 #ifdef R_OK
8690 if (ins(d, "R_OK", (long)R_OK)) return -1;
8691 #endif
8692 #ifdef W_OK
8693 if (ins(d, "W_OK", (long)W_OK)) return -1;
8694 #endif
8695 #ifdef X_OK
8696 if (ins(d, "X_OK", (long)X_OK)) return -1;
8697 #endif
8698 #ifdef NGROUPS_MAX
8699 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
8700 #endif
8701 #ifdef TMP_MAX
8702 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
8703 #endif
8704 #ifdef WCONTINUED
8705 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
8706 #endif
8707 #ifdef WNOHANG
8708 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
8709 #endif
8710 #ifdef WUNTRACED
8711 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
8712 #endif
8713 #ifdef O_RDONLY
8714 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
8715 #endif
8716 #ifdef O_WRONLY
8717 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
8718 #endif
8719 #ifdef O_RDWR
8720 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
8721 #endif
8722 #ifdef O_NDELAY
8723 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
8724 #endif
8725 #ifdef O_NONBLOCK
8726 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
8727 #endif
8728 #ifdef O_APPEND
8729 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
8730 #endif
8731 #ifdef O_DSYNC
8732 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
8733 #endif
8734 #ifdef O_RSYNC
8735 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
8736 #endif
8737 #ifdef O_SYNC
8738 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
8739 #endif
8740 #ifdef O_NOCTTY
8741 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
8742 #endif
8743 #ifdef O_CREAT
8744 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
8745 #endif
8746 #ifdef O_EXCL
8747 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
8748 #endif
8749 #ifdef O_TRUNC
8750 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
8751 #endif
8752 #ifdef O_BINARY
8753 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
8754 #endif
8755 #ifdef O_TEXT
8756 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
8757 #endif
8758 #ifdef O_LARGEFILE
8759 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
8760 #endif
8761 #ifdef O_SHLOCK
8762 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
8763 #endif
8764 #ifdef O_EXLOCK
8765 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
8766 #endif
8768 /* MS Windows */
8769 #ifdef O_NOINHERIT
8770 /* Don't inherit in child processes. */
8771 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
8772 #endif
8773 #ifdef _O_SHORT_LIVED
8774 /* Optimize for short life (keep in memory). */
8775 /* MS forgot to define this one with a non-underscore form too. */
8776 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
8777 #endif
8778 #ifdef O_TEMPORARY
8779 /* Automatically delete when last handle is closed. */
8780 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
8781 #endif
8782 #ifdef O_RANDOM
8783 /* Optimize for random access. */
8784 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
8785 #endif
8786 #ifdef O_SEQUENTIAL
8787 /* Optimize for sequential access. */
8788 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
8789 #endif
8791 /* GNU extensions. */
8792 #ifdef O_ASYNC
8793 /* Send a SIGIO signal whenever input or output
8794 becomes available on file descriptor */
8795 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
8796 #endif
8797 #ifdef O_DIRECT
8798 /* Direct disk access. */
8799 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
8800 #endif
8801 #ifdef O_DIRECTORY
8802 /* Must be a directory. */
8803 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
8804 #endif
8805 #ifdef O_NOFOLLOW
8806 /* Do not follow links. */
8807 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
8808 #endif
8809 #ifdef O_NOATIME
8810 /* Do not update the access time. */
8811 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
8812 #endif
8814 /* These come from sysexits.h */
8815 #ifdef EX_OK
8816 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
8817 #endif /* EX_OK */
8818 #ifdef EX_USAGE
8819 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
8820 #endif /* EX_USAGE */
8821 #ifdef EX_DATAERR
8822 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
8823 #endif /* EX_DATAERR */
8824 #ifdef EX_NOINPUT
8825 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
8826 #endif /* EX_NOINPUT */
8827 #ifdef EX_NOUSER
8828 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
8829 #endif /* EX_NOUSER */
8830 #ifdef EX_NOHOST
8831 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
8832 #endif /* EX_NOHOST */
8833 #ifdef EX_UNAVAILABLE
8834 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
8835 #endif /* EX_UNAVAILABLE */
8836 #ifdef EX_SOFTWARE
8837 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
8838 #endif /* EX_SOFTWARE */
8839 #ifdef EX_OSERR
8840 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
8841 #endif /* EX_OSERR */
8842 #ifdef EX_OSFILE
8843 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
8844 #endif /* EX_OSFILE */
8845 #ifdef EX_CANTCREAT
8846 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
8847 #endif /* EX_CANTCREAT */
8848 #ifdef EX_IOERR
8849 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
8850 #endif /* EX_IOERR */
8851 #ifdef EX_TEMPFAIL
8852 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
8853 #endif /* EX_TEMPFAIL */
8854 #ifdef EX_PROTOCOL
8855 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
8856 #endif /* EX_PROTOCOL */
8857 #ifdef EX_NOPERM
8858 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
8859 #endif /* EX_NOPERM */
8860 #ifdef EX_CONFIG
8861 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
8862 #endif /* EX_CONFIG */
8863 #ifdef EX_NOTFOUND
8864 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
8865 #endif /* EX_NOTFOUND */
8867 #ifdef HAVE_SPAWNV
8868 #if defined(PYOS_OS2) && defined(PYCC_GCC)
8869 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
8870 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
8871 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
8872 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
8873 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
8874 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
8875 if (ins(d, "P_PM", (long)P_PM)) return -1;
8876 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
8877 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
8878 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
8879 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
8880 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
8881 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
8882 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
8883 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
8884 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
8885 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
8886 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
8887 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
8888 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
8889 #else
8890 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
8891 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
8892 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
8893 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
8894 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
8895 #endif
8896 #endif
8898 #if defined(PYOS_OS2)
8899 if (insertvalues(d)) return -1;
8900 #endif
8901 return 0;
8905 #if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
8906 #define INITFUNC initnt
8907 #define MODNAME "nt"
8909 #elif defined(PYOS_OS2)
8910 #define INITFUNC initos2
8911 #define MODNAME "os2"
8913 #else
8914 #define INITFUNC initposix
8915 #define MODNAME "posix"
8916 #endif
8918 PyMODINIT_FUNC
8919 INITFUNC(void)
8921 PyObject *m, *v;
8923 m = Py_InitModule3(MODNAME,
8924 posix_methods,
8925 posix__doc__);
8926 if (m == NULL)
8927 return;
8929 /* Initialize environ dictionary */
8930 v = convertenviron();
8931 Py_XINCREF(v);
8932 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
8933 return;
8934 Py_DECREF(v);
8936 if (all_ins(m))
8937 return;
8939 if (setup_confname_tables(m))
8940 return;
8942 Py_INCREF(PyExc_OSError);
8943 PyModule_AddObject(m, "error", PyExc_OSError);
8945 #ifdef HAVE_PUTENV
8946 if (posix_putenv_garbage == NULL)
8947 posix_putenv_garbage = PyDict_New();
8948 #endif
8950 if (!initialized) {
8951 stat_result_desc.name = MODNAME ".stat_result";
8952 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
8953 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
8954 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
8955 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
8956 structseq_new = StatResultType.tp_new;
8957 StatResultType.tp_new = statresult_new;
8959 statvfs_result_desc.name = MODNAME ".statvfs_result";
8960 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
8961 #ifdef NEED_TICKS_PER_SECOND
8962 # if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
8963 ticks_per_second = sysconf(_SC_CLK_TCK);
8964 # elif defined(HZ)
8965 ticks_per_second = HZ;
8966 # else
8967 ticks_per_second = 60; /* magic fallback value; may be bogus */
8968 # endif
8969 #endif
8971 Py_INCREF((PyObject*) &StatResultType);
8972 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
8973 Py_INCREF((PyObject*) &StatVFSResultType);
8974 PyModule_AddObject(m, "statvfs_result",
8975 (PyObject*) &StatVFSResultType);
8976 initialized = 1;
8978 #ifdef __APPLE__
8980 * Step 2 of weak-linking support on Mac OS X.
8982 * The code below removes functions that are not available on the
8983 * currently active platform.
8985 * This block allow one to use a python binary that was build on
8986 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
8987 * OSX 10.4.
8989 #ifdef HAVE_FSTATVFS
8990 if (fstatvfs == NULL) {
8991 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
8992 return;
8995 #endif /* HAVE_FSTATVFS */
8997 #ifdef HAVE_STATVFS
8998 if (statvfs == NULL) {
8999 if (PyObject_DelAttrString(m, "statvfs") == -1) {
9000 return;
9003 #endif /* HAVE_STATVFS */
9005 # ifdef HAVE_LCHOWN
9006 if (lchown == NULL) {
9007 if (PyObject_DelAttrString(m, "lchown") == -1) {
9008 return;
9011 #endif /* HAVE_LCHOWN */
9014 #endif /* __APPLE__ */
9018 #ifdef __cplusplus
9020 #endif