Convert from long to Py_ssize_t.
[python.git] / Modules / posixmodule.c
blobf18e1546eb0b3ae14720e5e5aaeb70dfed619be7
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 PyObject *_PyUnicode_FromFileSystemEncodedObject(register PyObject *obj)
481 /* Function suitable for O& conversion */
482 static int
483 convert_to_unicode(PyObject *arg, void* _param)
485 PyObject **param = (PyObject**)_param;
486 if (PyUnicode_CheckExact(arg)) {
487 Py_INCREF(arg);
488 *param = arg;
490 else if (PyUnicode_Check(arg)) {
491 /* For a Unicode subtype that's not a Unicode object,
492 return a true Unicode object with the same data. */
493 *param = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(arg),
494 PyUnicode_GET_SIZE(arg));
495 return *param != NULL;
497 else
498 *param = PyUnicode_FromEncodedObject(arg,
499 Py_FileSystemDefaultEncoding,
500 "strict");
501 return (*param) != NULL;
504 #endif /* Py_WIN_WIDE_FILENAMES */
506 #endif
508 #if defined(PYOS_OS2)
509 /**********************************************************************
510 * Helper Function to Trim and Format OS/2 Messages
511 **********************************************************************/
512 static void
513 os2_formatmsg(char *msgbuf, int msglen, char *reason)
515 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
517 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
518 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
520 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
521 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
524 /* Add Optional Reason Text */
525 if (reason) {
526 strcat(msgbuf, " : ");
527 strcat(msgbuf, reason);
531 /**********************************************************************
532 * Decode an OS/2 Operating System Error Code
534 * A convenience function to lookup an OS/2 error code and return a
535 * text message we can use to raise a Python exception.
537 * Notes:
538 * The messages for errors returned from the OS/2 kernel reside in
539 * the file OSO001.MSG in the \OS2 directory hierarchy.
541 **********************************************************************/
542 static char *
543 os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
545 APIRET rc;
546 ULONG msglen;
548 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
549 Py_BEGIN_ALLOW_THREADS
550 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
551 errorcode, "oso001.msg", &msglen);
552 Py_END_ALLOW_THREADS
554 if (rc == NO_ERROR)
555 os2_formatmsg(msgbuf, msglen, reason);
556 else
557 PyOS_snprintf(msgbuf, msgbuflen,
558 "unknown OS error #%d", errorcode);
560 return msgbuf;
563 /* Set an OS/2-specific error and return NULL. OS/2 kernel
564 errors are not in a global variable e.g. 'errno' nor are
565 they congruent with posix error numbers. */
567 static PyObject * os2_error(int code)
569 char text[1024];
570 PyObject *v;
572 os2_strerror(text, sizeof(text), code, "");
574 v = Py_BuildValue("(is)", code, text);
575 if (v != NULL) {
576 PyErr_SetObject(PyExc_OSError, v);
577 Py_DECREF(v);
579 return NULL; /* Signal to Python that an Exception is Pending */
582 #endif /* OS2 */
584 /* POSIX generic methods */
586 static PyObject *
587 posix_fildes(PyObject *fdobj, int (*func)(int))
589 int fd;
590 int res;
591 fd = PyObject_AsFileDescriptor(fdobj);
592 if (fd < 0)
593 return NULL;
594 Py_BEGIN_ALLOW_THREADS
595 res = (*func)(fd);
596 Py_END_ALLOW_THREADS
597 if (res < 0)
598 return posix_error();
599 Py_INCREF(Py_None);
600 return Py_None;
603 #ifdef Py_WIN_WIDE_FILENAMES
604 static int
605 unicode_file_names(void)
607 static int canusewide = -1;
608 if (canusewide == -1) {
609 /* As per doc for ::GetVersion(), this is the correct test for
610 the Windows NT family. */
611 canusewide = (GetVersion() < 0x80000000) ? 1 : 0;
613 return canusewide;
615 #endif
617 static PyObject *
618 posix_1str(PyObject *args, char *format, int (*func)(const char*))
620 char *path1 = NULL;
621 int res;
622 if (!PyArg_ParseTuple(args, format,
623 Py_FileSystemDefaultEncoding, &path1))
624 return NULL;
625 Py_BEGIN_ALLOW_THREADS
626 res = (*func)(path1);
627 Py_END_ALLOW_THREADS
628 if (res < 0)
629 return posix_error_with_allocated_filename(path1);
630 PyMem_Free(path1);
631 Py_INCREF(Py_None);
632 return Py_None;
635 static PyObject *
636 posix_2str(PyObject *args,
637 char *format,
638 int (*func)(const char *, const char *))
640 char *path1 = NULL, *path2 = NULL;
641 int res;
642 if (!PyArg_ParseTuple(args, format,
643 Py_FileSystemDefaultEncoding, &path1,
644 Py_FileSystemDefaultEncoding, &path2))
645 return NULL;
646 Py_BEGIN_ALLOW_THREADS
647 res = (*func)(path1, path2);
648 Py_END_ALLOW_THREADS
649 PyMem_Free(path1);
650 PyMem_Free(path2);
651 if (res != 0)
652 /* XXX how to report both path1 and path2??? */
653 return posix_error();
654 Py_INCREF(Py_None);
655 return Py_None;
658 #ifdef Py_WIN_WIDE_FILENAMES
659 static PyObject*
660 win32_1str(PyObject* args, char* func,
661 char* format, BOOL (__stdcall *funcA)(LPCSTR),
662 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
664 PyObject *uni;
665 char *ansi;
666 BOOL result;
667 if (unicode_file_names()) {
668 if (!PyArg_ParseTuple(args, wformat, &uni))
669 PyErr_Clear();
670 else {
671 Py_BEGIN_ALLOW_THREADS
672 result = funcW(PyUnicode_AsUnicode(uni));
673 Py_END_ALLOW_THREADS
674 if (!result)
675 return win32_error_unicode(func, PyUnicode_AsUnicode(uni));
676 Py_INCREF(Py_None);
677 return Py_None;
680 if (!PyArg_ParseTuple(args, format, &ansi))
681 return NULL;
682 Py_BEGIN_ALLOW_THREADS
683 result = funcA(ansi);
684 Py_END_ALLOW_THREADS
685 if (!result)
686 return win32_error(func, ansi);
687 Py_INCREF(Py_None);
688 return Py_None;
692 /* This is a reimplementation of the C library's chdir function,
693 but one that produces Win32 errors instead of DOS error codes.
694 chdir is essentially a wrapper around SetCurrentDirectory; however,
695 it also needs to set "magic" environment variables indicating
696 the per-drive current directory, which are of the form =<drive>: */
697 BOOL __stdcall
698 win32_chdir(LPCSTR path)
700 char new_path[MAX_PATH+1];
701 int result;
702 char env[4] = "=x:";
704 if(!SetCurrentDirectoryA(path))
705 return FALSE;
706 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
707 if (!result)
708 return FALSE;
709 /* In the ANSI API, there should not be any paths longer
710 than MAX_PATH. */
711 assert(result <= MAX_PATH+1);
712 if (strncmp(new_path, "\\\\", 2) == 0 ||
713 strncmp(new_path, "//", 2) == 0)
714 /* UNC path, nothing to do. */
715 return TRUE;
716 env[1] = new_path[0];
717 return SetEnvironmentVariableA(env, new_path);
720 /* The Unicode version differs from the ANSI version
721 since the current directory might exceed MAX_PATH characters */
722 BOOL __stdcall
723 win32_wchdir(LPCWSTR path)
725 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
726 int result;
727 wchar_t env[4] = L"=x:";
729 if(!SetCurrentDirectoryW(path))
730 return FALSE;
731 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
732 if (!result)
733 return FALSE;
734 if (result > MAX_PATH+1) {
735 new_path = malloc(result);
736 if (!new_path) {
737 SetLastError(ERROR_OUTOFMEMORY);
738 return FALSE;
741 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
742 wcsncmp(new_path, L"//", 2) == 0)
743 /* UNC path, nothing to do. */
744 return TRUE;
745 env[1] = new_path[0];
746 result = SetEnvironmentVariableW(env, new_path);
747 if (new_path != _new_path)
748 free(new_path);
749 return result;
751 #endif
753 #ifdef MS_WINDOWS
754 /* The CRT of Windows has a number of flaws wrt. its stat() implementation:
755 - time stamps are restricted to second resolution
756 - file modification times suffer from forth-and-back conversions between
757 UTC and local time
758 Therefore, we implement our own stat, based on the Win32 API directly.
760 #define HAVE_STAT_NSEC 1
762 struct win32_stat{
763 int st_dev;
764 __int64 st_ino;
765 unsigned short st_mode;
766 int st_nlink;
767 int st_uid;
768 int st_gid;
769 int st_rdev;
770 __int64 st_size;
771 int st_atime;
772 int st_atime_nsec;
773 int st_mtime;
774 int st_mtime_nsec;
775 int st_ctime;
776 int st_ctime_nsec;
779 static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
781 static void
782 FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, int *time_out, int* nsec_out)
784 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
785 /* Cannot simply cast and dereference in_ptr,
786 since it might not be aligned properly */
787 __int64 in;
788 memcpy(&in, in_ptr, sizeof(in));
789 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
790 /* XXX Win32 supports time stamps past 2038; we currently don't */
791 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, int);
794 static void
795 time_t_to_FILE_TIME(int time_in, int nsec_in, FILETIME *out_ptr)
797 /* XXX endianness */
798 __int64 out;
799 out = time_in + secs_between_epochs;
800 out = out * 10000000 + nsec_in / 100;
801 memcpy(out_ptr, &out, sizeof(out));
804 /* Below, we *know* that ugo+r is 0444 */
805 #if _S_IREAD != 0400
806 #error Unsupported C library
807 #endif
808 static int
809 attributes_to_mode(DWORD attr)
811 int m = 0;
812 if (attr & FILE_ATTRIBUTE_DIRECTORY)
813 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
814 else
815 m |= _S_IFREG;
816 if (attr & FILE_ATTRIBUTE_READONLY)
817 m |= 0444;
818 else
819 m |= 0666;
820 return m;
823 static int
824 attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *result)
826 memset(result, 0, sizeof(*result));
827 result->st_mode = attributes_to_mode(info->dwFileAttributes);
828 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
829 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
830 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
831 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
833 return 0;
836 /* Emulate GetFileAttributesEx[AW] on Windows 95 */
837 static int checked = 0;
838 static BOOL (CALLBACK *gfaxa)(LPCSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
839 static BOOL (CALLBACK *gfaxw)(LPCWSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
840 static void
841 check_gfax()
843 HINSTANCE hKernel32;
844 if (checked)
845 return;
846 checked = 1;
847 hKernel32 = GetModuleHandle("KERNEL32");
848 *(FARPROC*)&gfaxa = GetProcAddress(hKernel32, "GetFileAttributesExA");
849 *(FARPROC*)&gfaxw = GetProcAddress(hKernel32, "GetFileAttributesExW");
852 static BOOL
853 attributes_from_dir(LPCSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
855 HANDLE hFindFile;
856 WIN32_FIND_DATAA FileData;
857 hFindFile = FindFirstFileA(pszFile, &FileData);
858 if (hFindFile == INVALID_HANDLE_VALUE)
859 return FALSE;
860 FindClose(hFindFile);
861 pfad->dwFileAttributes = FileData.dwFileAttributes;
862 pfad->ftCreationTime = FileData.ftCreationTime;
863 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
864 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
865 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
866 pfad->nFileSizeLow = FileData.nFileSizeLow;
867 return TRUE;
870 static BOOL
871 attributes_from_dir_w(LPCWSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
873 HANDLE hFindFile;
874 WIN32_FIND_DATAW FileData;
875 hFindFile = FindFirstFileW(pszFile, &FileData);
876 if (hFindFile == INVALID_HANDLE_VALUE)
877 return FALSE;
878 FindClose(hFindFile);
879 pfad->dwFileAttributes = FileData.dwFileAttributes;
880 pfad->ftCreationTime = FileData.ftCreationTime;
881 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
882 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
883 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
884 pfad->nFileSizeLow = FileData.nFileSizeLow;
885 return TRUE;
888 static BOOL WINAPI
889 Py_GetFileAttributesExA(LPCSTR pszFile,
890 GET_FILEEX_INFO_LEVELS level,
891 LPVOID pv)
893 BOOL result;
894 LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
895 /* First try to use the system's implementation, if that is
896 available and either succeeds to gives an error other than
897 that it isn't implemented. */
898 check_gfax();
899 if (gfaxa) {
900 result = gfaxa(pszFile, level, pv);
901 if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
902 return result;
904 /* It's either not present, or not implemented.
905 Emulate using FindFirstFile. */
906 if (level != GetFileExInfoStandard) {
907 SetLastError(ERROR_INVALID_PARAMETER);
908 return FALSE;
910 /* Use GetFileAttributes to validate that the file name
911 does not contain wildcards (which FindFirstFile would
912 accept). */
913 if (GetFileAttributesA(pszFile) == 0xFFFFFFFF)
914 return FALSE;
915 return attributes_from_dir(pszFile, pfad);
918 static BOOL WINAPI
919 Py_GetFileAttributesExW(LPCWSTR pszFile,
920 GET_FILEEX_INFO_LEVELS level,
921 LPVOID pv)
923 BOOL result;
924 LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
925 /* First try to use the system's implementation, if that is
926 available and either succeeds to gives an error other than
927 that it isn't implemented. */
928 check_gfax();
929 if (gfaxa) {
930 result = gfaxw(pszFile, level, pv);
931 if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
932 return result;
934 /* It's either not present, or not implemented.
935 Emulate using FindFirstFile. */
936 if (level != GetFileExInfoStandard) {
937 SetLastError(ERROR_INVALID_PARAMETER);
938 return FALSE;
940 /* Use GetFileAttributes to validate that the file name
941 does not contain wildcards (which FindFirstFile would
942 accept). */
943 if (GetFileAttributesW(pszFile) == 0xFFFFFFFF)
944 return FALSE;
945 return attributes_from_dir_w(pszFile, pfad);
948 static int
949 win32_stat(const char* path, struct win32_stat *result)
951 WIN32_FILE_ATTRIBUTE_DATA info;
952 int code;
953 char *dot;
954 /* XXX not supported on Win95 and NT 3.x */
955 if (!Py_GetFileAttributesExA(path, GetFileExInfoStandard, &info)) {
956 if (GetLastError() != ERROR_SHARING_VIOLATION) {
957 /* Protocol violation: we explicitly clear errno, instead of
958 setting it to a POSIX error. Callers should use GetLastError. */
959 errno = 0;
960 return -1;
961 } else {
962 /* Could not get attributes on open file. Fall back to
963 reading the directory. */
964 if (!attributes_from_dir(path, &info)) {
965 /* Very strange. This should not fail now */
966 errno = 0;
967 return -1;
971 code = attribute_data_to_stat(&info, result);
972 if (code != 0)
973 return code;
974 /* Set S_IFEXEC if it is an .exe, .bat, ... */
975 dot = strrchr(path, '.');
976 if (dot) {
977 if (stricmp(dot, ".bat") == 0 ||
978 stricmp(dot, ".cmd") == 0 ||
979 stricmp(dot, ".exe") == 0 ||
980 stricmp(dot, ".com") == 0)
981 result->st_mode |= 0111;
983 return code;
986 static int
987 win32_wstat(const wchar_t* path, struct win32_stat *result)
989 int code;
990 const wchar_t *dot;
991 WIN32_FILE_ATTRIBUTE_DATA info;
992 /* XXX not supported on Win95 and NT 3.x */
993 if (!Py_GetFileAttributesExW(path, GetFileExInfoStandard, &info)) {
994 if (GetLastError() != ERROR_SHARING_VIOLATION) {
995 /* Protocol violation: we explicitly clear errno, instead of
996 setting it to a POSIX error. Callers should use GetLastError. */
997 errno = 0;
998 return -1;
999 } else {
1000 /* Could not get attributes on open file. Fall back to
1001 reading the directory. */
1002 if (!attributes_from_dir_w(path, &info)) {
1003 /* Very strange. This should not fail now */
1004 errno = 0;
1005 return -1;
1009 code = attribute_data_to_stat(&info, result);
1010 if (code < 0)
1011 return code;
1012 /* Set IFEXEC if it is an .exe, .bat, ... */
1013 dot = wcsrchr(path, '.');
1014 if (dot) {
1015 if (_wcsicmp(dot, L".bat") == 0 ||
1016 _wcsicmp(dot, L".cmd") == 0 ||
1017 _wcsicmp(dot, L".exe") == 0 ||
1018 _wcsicmp(dot, L".com") == 0)
1019 result->st_mode |= 0111;
1021 return code;
1024 static int
1025 win32_fstat(int file_number, struct win32_stat *result)
1027 BY_HANDLE_FILE_INFORMATION info;
1028 HANDLE h;
1029 int type;
1031 h = (HANDLE)_get_osfhandle(file_number);
1033 /* Protocol violation: we explicitly clear errno, instead of
1034 setting it to a POSIX error. Callers should use GetLastError. */
1035 errno = 0;
1037 if (h == INVALID_HANDLE_VALUE) {
1038 /* This is really a C library error (invalid file handle).
1039 We set the Win32 error to the closes one matching. */
1040 SetLastError(ERROR_INVALID_HANDLE);
1041 return -1;
1043 memset(result, 0, sizeof(*result));
1045 type = GetFileType(h);
1046 if (type == FILE_TYPE_UNKNOWN) {
1047 DWORD error = GetLastError();
1048 if (error != 0) {
1049 return -1;
1051 /* else: valid but unknown file */
1054 if (type != FILE_TYPE_DISK) {
1055 if (type == FILE_TYPE_CHAR)
1056 result->st_mode = _S_IFCHR;
1057 else if (type == FILE_TYPE_PIPE)
1058 result->st_mode = _S_IFIFO;
1059 return 0;
1062 if (!GetFileInformationByHandle(h, &info)) {
1063 return -1;
1066 /* similar to stat() */
1067 result->st_mode = attributes_to_mode(info.dwFileAttributes);
1068 result->st_size = (((__int64)info.nFileSizeHigh)<<32) + info.nFileSizeLow;
1069 FILE_TIME_to_time_t_nsec(&info.ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1070 FILE_TIME_to_time_t_nsec(&info.ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1071 FILE_TIME_to_time_t_nsec(&info.ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
1072 /* specific to fstat() */
1073 result->st_nlink = info.nNumberOfLinks;
1074 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1075 return 0;
1078 #endif /* MS_WINDOWS */
1080 PyDoc_STRVAR(stat_result__doc__,
1081 "stat_result: Result from stat or lstat.\n\n\
1082 This object may be accessed either as a tuple of\n\
1083 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
1084 or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1086 Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1087 or st_flags, they are available as attributes only.\n\
1089 See os.stat for more information.");
1091 static PyStructSequence_Field stat_result_fields[] = {
1092 {"st_mode", "protection bits"},
1093 {"st_ino", "inode"},
1094 {"st_dev", "device"},
1095 {"st_nlink", "number of hard links"},
1096 {"st_uid", "user ID of owner"},
1097 {"st_gid", "group ID of owner"},
1098 {"st_size", "total size, in bytes"},
1099 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1100 {NULL, "integer time of last access"},
1101 {NULL, "integer time of last modification"},
1102 {NULL, "integer time of last change"},
1103 {"st_atime", "time of last access"},
1104 {"st_mtime", "time of last modification"},
1105 {"st_ctime", "time of last change"},
1106 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
1107 {"st_blksize", "blocksize for filesystem I/O"},
1108 #endif
1109 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
1110 {"st_blocks", "number of blocks allocated"},
1111 #endif
1112 #ifdef HAVE_STRUCT_STAT_ST_RDEV
1113 {"st_rdev", "device type (if inode device)"},
1114 #endif
1115 #ifdef HAVE_STRUCT_STAT_ST_FLAGS
1116 {"st_flags", "user defined flags for file"},
1117 #endif
1118 #ifdef HAVE_STRUCT_STAT_ST_GEN
1119 {"st_gen", "generation number"},
1120 #endif
1121 #ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1122 {"st_birthtime", "time of creation"},
1123 #endif
1127 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
1128 #define ST_BLKSIZE_IDX 13
1129 #else
1130 #define ST_BLKSIZE_IDX 12
1131 #endif
1133 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
1134 #define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1135 #else
1136 #define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1137 #endif
1139 #ifdef HAVE_STRUCT_STAT_ST_RDEV
1140 #define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1141 #else
1142 #define ST_RDEV_IDX ST_BLOCKS_IDX
1143 #endif
1145 #ifdef HAVE_STRUCT_STAT_ST_FLAGS
1146 #define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1147 #else
1148 #define ST_FLAGS_IDX ST_RDEV_IDX
1149 #endif
1151 #ifdef HAVE_STRUCT_STAT_ST_GEN
1152 #define ST_GEN_IDX (ST_FLAGS_IDX+1)
1153 #else
1154 #define ST_GEN_IDX ST_FLAGS_IDX
1155 #endif
1157 #ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1158 #define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1159 #else
1160 #define ST_BIRTHTIME_IDX ST_GEN_IDX
1161 #endif
1163 static PyStructSequence_Desc stat_result_desc = {
1164 "stat_result", /* name */
1165 stat_result__doc__, /* doc */
1166 stat_result_fields,
1170 PyDoc_STRVAR(statvfs_result__doc__,
1171 "statvfs_result: Result from statvfs or fstatvfs.\n\n\
1172 This object may be accessed either as a tuple of\n\
1173 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
1174 or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
1176 See os.statvfs for more information.");
1178 static PyStructSequence_Field statvfs_result_fields[] = {
1179 {"f_bsize", },
1180 {"f_frsize", },
1181 {"f_blocks", },
1182 {"f_bfree", },
1183 {"f_bavail", },
1184 {"f_files", },
1185 {"f_ffree", },
1186 {"f_favail", },
1187 {"f_flag", },
1188 {"f_namemax",},
1192 static PyStructSequence_Desc statvfs_result_desc = {
1193 "statvfs_result", /* name */
1194 statvfs_result__doc__, /* doc */
1195 statvfs_result_fields,
1199 static int initialized;
1200 static PyTypeObject StatResultType;
1201 static PyTypeObject StatVFSResultType;
1202 static newfunc structseq_new;
1204 static PyObject *
1205 statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1207 PyStructSequence *result;
1208 int i;
1210 result = (PyStructSequence*)structseq_new(type, args, kwds);
1211 if (!result)
1212 return NULL;
1213 /* If we have been initialized from a tuple,
1214 st_?time might be set to None. Initialize it
1215 from the int slots. */
1216 for (i = 7; i <= 9; i++) {
1217 if (result->ob_item[i+3] == Py_None) {
1218 Py_DECREF(Py_None);
1219 Py_INCREF(result->ob_item[i]);
1220 result->ob_item[i+3] = result->ob_item[i];
1223 return (PyObject*)result;
1228 /* If true, st_?time is float. */
1229 static int _stat_float_times = 1;
1231 PyDoc_STRVAR(stat_float_times__doc__,
1232 "stat_float_times([newval]) -> oldval\n\n\
1233 Determine whether os.[lf]stat represents time stamps as float objects.\n\
1234 If newval is True, future calls to stat() return floats, if it is False,\n\
1235 future calls return ints. \n\
1236 If newval is omitted, return the current setting.\n");
1238 static PyObject*
1239 stat_float_times(PyObject* self, PyObject *args)
1241 int newval = -1;
1242 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1243 return NULL;
1244 if (newval == -1)
1245 /* Return old value */
1246 return PyBool_FromLong(_stat_float_times);
1247 _stat_float_times = newval;
1248 Py_INCREF(Py_None);
1249 return Py_None;
1252 static void
1253 fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1255 PyObject *fval,*ival;
1256 #if SIZEOF_TIME_T > SIZEOF_LONG
1257 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
1258 #else
1259 ival = PyInt_FromLong((long)sec);
1260 #endif
1261 if (!ival)
1262 return;
1263 if (_stat_float_times) {
1264 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1265 } else {
1266 fval = ival;
1267 Py_INCREF(fval);
1269 PyStructSequence_SET_ITEM(v, index, ival);
1270 PyStructSequence_SET_ITEM(v, index+3, fval);
1273 /* pack a system stat C structure into the Python stat tuple
1274 (used by posix_stat() and posix_fstat()) */
1275 static PyObject*
1276 _pystat_fromstructstat(STRUCT_STAT *st)
1278 unsigned long ansec, mnsec, cnsec;
1279 PyObject *v = PyStructSequence_New(&StatResultType);
1280 if (v == NULL)
1281 return NULL;
1283 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st->st_mode));
1284 #ifdef HAVE_LARGEFILE_SUPPORT
1285 PyStructSequence_SET_ITEM(v, 1,
1286 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
1287 #else
1288 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st->st_ino));
1289 #endif
1290 #if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
1291 PyStructSequence_SET_ITEM(v, 2,
1292 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
1293 #else
1294 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st->st_dev));
1295 #endif
1296 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st->st_nlink));
1297 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st->st_uid));
1298 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st->st_gid));
1299 #ifdef HAVE_LARGEFILE_SUPPORT
1300 PyStructSequence_SET_ITEM(v, 6,
1301 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
1302 #else
1303 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st->st_size));
1304 #endif
1306 #if defined(HAVE_STAT_TV_NSEC)
1307 ansec = st->st_atim.tv_nsec;
1308 mnsec = st->st_mtim.tv_nsec;
1309 cnsec = st->st_ctim.tv_nsec;
1310 #elif defined(HAVE_STAT_TV_NSEC2)
1311 ansec = st->st_atimespec.tv_nsec;
1312 mnsec = st->st_mtimespec.tv_nsec;
1313 cnsec = st->st_ctimespec.tv_nsec;
1314 #elif defined(HAVE_STAT_NSEC)
1315 ansec = st->st_atime_nsec;
1316 mnsec = st->st_mtime_nsec;
1317 cnsec = st->st_ctime_nsec;
1318 #else
1319 ansec = mnsec = cnsec = 0;
1320 #endif
1321 fill_time(v, 7, st->st_atime, ansec);
1322 fill_time(v, 8, st->st_mtime, mnsec);
1323 fill_time(v, 9, st->st_ctime, cnsec);
1325 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
1326 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
1327 PyInt_FromLong((long)st->st_blksize));
1328 #endif
1329 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
1330 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
1331 PyInt_FromLong((long)st->st_blocks));
1332 #endif
1333 #ifdef HAVE_STRUCT_STAT_ST_RDEV
1334 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
1335 PyInt_FromLong((long)st->st_rdev));
1336 #endif
1337 #ifdef HAVE_STRUCT_STAT_ST_GEN
1338 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
1339 PyInt_FromLong((long)st->st_gen));
1340 #endif
1341 #ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1343 PyObject *val;
1344 unsigned long bsec,bnsec;
1345 bsec = (long)st->st_birthtime;
1346 #ifdef HAVE_STAT_TV_NSEC2
1347 bnsec = st->st_birthtimespec.tv_nsec;
1348 #else
1349 bnsec = 0;
1350 #endif
1351 if (_stat_float_times) {
1352 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1353 } else {
1354 val = PyInt_FromLong((long)bsec);
1356 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1357 val);
1359 #endif
1360 #ifdef HAVE_STRUCT_STAT_ST_FLAGS
1361 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
1362 PyInt_FromLong((long)st->st_flags));
1363 #endif
1365 if (PyErr_Occurred()) {
1366 Py_DECREF(v);
1367 return NULL;
1370 return v;
1373 #ifdef MS_WINDOWS
1375 /* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
1376 where / can be used in place of \ and the trailing slash is optional.
1377 Both SERVER and SHARE must have at least one character.
1380 #define ISSLASHA(c) ((c) == '\\' || (c) == '/')
1381 #define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
1382 #ifndef ARRAYSIZE
1383 #define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
1384 #endif
1386 static BOOL
1387 IsUNCRootA(char *path, int pathlen)
1389 #define ISSLASH ISSLASHA
1391 int i, share;
1393 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1394 /* minimum UNCRoot is \\x\y */
1395 return FALSE;
1396 for (i = 2; i < pathlen ; i++)
1397 if (ISSLASH(path[i])) break;
1398 if (i == 2 || i == pathlen)
1399 /* do not allow \\\SHARE or \\SERVER */
1400 return FALSE;
1401 share = i+1;
1402 for (i = share; i < pathlen; i++)
1403 if (ISSLASH(path[i])) break;
1404 return (i != share && (i == pathlen || i == pathlen-1));
1406 #undef ISSLASH
1409 #ifdef Py_WIN_WIDE_FILENAMES
1410 static BOOL
1411 IsUNCRootW(Py_UNICODE *path, int pathlen)
1413 #define ISSLASH ISSLASHW
1415 int i, share;
1417 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1418 /* minimum UNCRoot is \\x\y */
1419 return FALSE;
1420 for (i = 2; i < pathlen ; i++)
1421 if (ISSLASH(path[i])) break;
1422 if (i == 2 || i == pathlen)
1423 /* do not allow \\\SHARE or \\SERVER */
1424 return FALSE;
1425 share = i+1;
1426 for (i = share; i < pathlen; i++)
1427 if (ISSLASH(path[i])) break;
1428 return (i != share && (i == pathlen || i == pathlen-1));
1430 #undef ISSLASH
1432 #endif /* Py_WIN_WIDE_FILENAMES */
1433 #endif /* MS_WINDOWS */
1435 static PyObject *
1436 posix_do_stat(PyObject *self, PyObject *args,
1437 char *format,
1438 #ifdef __VMS
1439 int (*statfunc)(const char *, STRUCT_STAT *, ...),
1440 #else
1441 int (*statfunc)(const char *, STRUCT_STAT *),
1442 #endif
1443 char *wformat,
1444 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
1446 STRUCT_STAT st;
1447 char *path = NULL; /* pass this to stat; do not free() it */
1448 char *pathfree = NULL; /* this memory must be free'd */
1449 int res;
1450 PyObject *result;
1452 #ifdef Py_WIN_WIDE_FILENAMES
1453 /* If on wide-character-capable OS see if argument
1454 is Unicode and if so use wide API. */
1455 if (unicode_file_names()) {
1456 PyUnicodeObject *po;
1457 if (PyArg_ParseTuple(args, wformat, &po)) {
1458 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
1460 Py_BEGIN_ALLOW_THREADS
1461 /* PyUnicode_AS_UNICODE result OK without
1462 thread lock as it is a simple dereference. */
1463 res = wstatfunc(wpath, &st);
1464 Py_END_ALLOW_THREADS
1466 if (res != 0)
1467 return win32_error_unicode("stat", wpath);
1468 return _pystat_fromstructstat(&st);
1470 /* Drop the argument parsing error as narrow strings
1471 are also valid. */
1472 PyErr_Clear();
1474 #endif
1476 if (!PyArg_ParseTuple(args, format,
1477 Py_FileSystemDefaultEncoding, &path))
1478 return NULL;
1479 pathfree = path;
1481 Py_BEGIN_ALLOW_THREADS
1482 res = (*statfunc)(path, &st);
1483 Py_END_ALLOW_THREADS
1485 if (res != 0) {
1486 #ifdef MS_WINDOWS
1487 result = win32_error("stat", pathfree);
1488 #else
1489 result = posix_error_with_filename(pathfree);
1490 #endif
1492 else
1493 result = _pystat_fromstructstat(&st);
1495 PyMem_Free(pathfree);
1496 return result;
1499 /* POSIX methods */
1501 PyDoc_STRVAR(posix_access__doc__,
1502 "access(path, mode) -> True if granted, False otherwise\n\n\
1503 Use the real uid/gid to test for access to a path. Note that most\n\
1504 operations will use the effective uid/gid, therefore this routine can\n\
1505 be used in a suid/sgid environment to test if the invoking user has the\n\
1506 specified access to the path. The mode argument can be F_OK to test\n\
1507 existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
1509 static PyObject *
1510 posix_access(PyObject *self, PyObject *args)
1512 char *path;
1513 int mode;
1515 #ifdef Py_WIN_WIDE_FILENAMES
1516 DWORD attr;
1517 if (unicode_file_names()) {
1518 PyUnicodeObject *po;
1519 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1520 Py_BEGIN_ALLOW_THREADS
1521 /* PyUnicode_AS_UNICODE OK without thread lock as
1522 it is a simple dereference. */
1523 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1524 Py_END_ALLOW_THREADS
1525 goto finish;
1527 /* Drop the argument parsing error as narrow strings
1528 are also valid. */
1529 PyErr_Clear();
1531 if (!PyArg_ParseTuple(args, "eti:access",
1532 Py_FileSystemDefaultEncoding, &path, &mode))
1533 return 0;
1534 Py_BEGIN_ALLOW_THREADS
1535 attr = GetFileAttributesA(path);
1536 Py_END_ALLOW_THREADS
1537 PyMem_Free(path);
1538 finish:
1539 if (attr == 0xFFFFFFFF)
1540 /* File does not exist, or cannot read attributes */
1541 return PyBool_FromLong(0);
1542 /* Access is possible if either write access wasn't requested, or
1543 the file isn't read-only, or if it's a directory, as there are
1544 no read-only directories on Windows. */
1545 return PyBool_FromLong(!(mode & 2)
1546 || !(attr & FILE_ATTRIBUTE_READONLY)
1547 || (attr & FILE_ATTRIBUTE_DIRECTORY));
1548 #else
1549 int res;
1550 if (!PyArg_ParseTuple(args, "eti:access",
1551 Py_FileSystemDefaultEncoding, &path, &mode))
1552 return NULL;
1553 Py_BEGIN_ALLOW_THREADS
1554 res = access(path, mode);
1555 Py_END_ALLOW_THREADS
1556 PyMem_Free(path);
1557 return PyBool_FromLong(res == 0);
1558 #endif
1561 #ifndef F_OK
1562 #define F_OK 0
1563 #endif
1564 #ifndef R_OK
1565 #define R_OK 4
1566 #endif
1567 #ifndef W_OK
1568 #define W_OK 2
1569 #endif
1570 #ifndef X_OK
1571 #define X_OK 1
1572 #endif
1574 #ifdef HAVE_TTYNAME
1575 PyDoc_STRVAR(posix_ttyname__doc__,
1576 "ttyname(fd) -> string\n\n\
1577 Return the name of the terminal device connected to 'fd'.");
1579 static PyObject *
1580 posix_ttyname(PyObject *self, PyObject *args)
1582 int id;
1583 char *ret;
1585 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
1586 return NULL;
1588 #if defined(__VMS)
1589 /* file descriptor 0 only, the default input device (stdin) */
1590 if (id == 0) {
1591 ret = ttyname();
1593 else {
1594 ret = NULL;
1596 #else
1597 ret = ttyname(id);
1598 #endif
1599 if (ret == NULL)
1600 return posix_error();
1601 return PyString_FromString(ret);
1603 #endif
1605 #ifdef HAVE_CTERMID
1606 PyDoc_STRVAR(posix_ctermid__doc__,
1607 "ctermid() -> string\n\n\
1608 Return the name of the controlling terminal for this process.");
1610 static PyObject *
1611 posix_ctermid(PyObject *self, PyObject *noargs)
1613 char *ret;
1614 char buffer[L_ctermid];
1616 #ifdef USE_CTERMID_R
1617 ret = ctermid_r(buffer);
1618 #else
1619 ret = ctermid(buffer);
1620 #endif
1621 if (ret == NULL)
1622 return posix_error();
1623 return PyString_FromString(buffer);
1625 #endif
1627 PyDoc_STRVAR(posix_chdir__doc__,
1628 "chdir(path)\n\n\
1629 Change the current working directory to the specified path.");
1631 static PyObject *
1632 posix_chdir(PyObject *self, PyObject *args)
1634 #ifdef MS_WINDOWS
1635 return win32_1str(args, "chdir", "s:chdir", win32_chdir, "U:chdir", win32_wchdir);
1636 #elif defined(PYOS_OS2) && defined(PYCC_GCC)
1637 return posix_1str(args, "et:chdir", _chdir2);
1638 #elif defined(__VMS)
1639 return posix_1str(args, "et:chdir", (int (*)(const char *))chdir);
1640 #else
1641 return posix_1str(args, "et:chdir", chdir);
1642 #endif
1645 #ifdef HAVE_FCHDIR
1646 PyDoc_STRVAR(posix_fchdir__doc__,
1647 "fchdir(fildes)\n\n\
1648 Change to the directory of the given file descriptor. fildes must be\n\
1649 opened on a directory, not a file.");
1651 static PyObject *
1652 posix_fchdir(PyObject *self, PyObject *fdobj)
1654 return posix_fildes(fdobj, fchdir);
1656 #endif /* HAVE_FCHDIR */
1659 PyDoc_STRVAR(posix_chmod__doc__,
1660 "chmod(path, mode)\n\n\
1661 Change the access permissions of a file.");
1663 static PyObject *
1664 posix_chmod(PyObject *self, PyObject *args)
1666 char *path = NULL;
1667 int i;
1668 int res;
1669 #ifdef Py_WIN_WIDE_FILENAMES
1670 DWORD attr;
1671 if (unicode_file_names()) {
1672 PyUnicodeObject *po;
1673 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1674 Py_BEGIN_ALLOW_THREADS
1675 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1676 if (attr != 0xFFFFFFFF) {
1677 if (i & _S_IWRITE)
1678 attr &= ~FILE_ATTRIBUTE_READONLY;
1679 else
1680 attr |= FILE_ATTRIBUTE_READONLY;
1681 res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
1683 else
1684 res = 0;
1685 Py_END_ALLOW_THREADS
1686 if (!res)
1687 return win32_error_unicode("chmod",
1688 PyUnicode_AS_UNICODE(po));
1689 Py_INCREF(Py_None);
1690 return Py_None;
1692 /* Drop the argument parsing error as narrow strings
1693 are also valid. */
1694 PyErr_Clear();
1696 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
1697 &path, &i))
1698 return NULL;
1699 Py_BEGIN_ALLOW_THREADS
1700 attr = GetFileAttributesA(path);
1701 if (attr != 0xFFFFFFFF) {
1702 if (i & _S_IWRITE)
1703 attr &= ~FILE_ATTRIBUTE_READONLY;
1704 else
1705 attr |= FILE_ATTRIBUTE_READONLY;
1706 res = SetFileAttributesA(path, attr);
1708 else
1709 res = 0;
1710 Py_END_ALLOW_THREADS
1711 if (!res) {
1712 win32_error("chmod", path);
1713 PyMem_Free(path);
1714 return NULL;
1716 PyMem_Free(path);
1717 Py_INCREF(Py_None);
1718 return Py_None;
1719 #else /* Py_WIN_WIDE_FILENAMES */
1720 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
1721 &path, &i))
1722 return NULL;
1723 Py_BEGIN_ALLOW_THREADS
1724 res = chmod(path, i);
1725 Py_END_ALLOW_THREADS
1726 if (res < 0)
1727 return posix_error_with_allocated_filename(path);
1728 PyMem_Free(path);
1729 Py_INCREF(Py_None);
1730 return Py_None;
1731 #endif
1734 #ifdef HAVE_FCHMOD
1735 PyDoc_STRVAR(posix_fchmod__doc__,
1736 "fchmod(fd, mode)\n\n\
1737 Change the access permissions of the file given by file\n\
1738 descriptor fd.");
1740 static PyObject *
1741 posix_fchmod(PyObject *self, PyObject *args)
1743 int fd, mode, res;
1744 if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
1745 return NULL;
1746 Py_BEGIN_ALLOW_THREADS
1747 res = fchmod(fd, mode);
1748 Py_END_ALLOW_THREADS
1749 if (res < 0)
1750 return posix_error();
1751 Py_RETURN_NONE;
1753 #endif /* HAVE_FCHMOD */
1755 #ifdef HAVE_LCHMOD
1756 PyDoc_STRVAR(posix_lchmod__doc__,
1757 "lchmod(path, mode)\n\n\
1758 Change the access permissions of a file. If path is a symlink, this\n\
1759 affects the link itself rather than the target.");
1761 static PyObject *
1762 posix_lchmod(PyObject *self, PyObject *args)
1764 char *path = NULL;
1765 int i;
1766 int res;
1767 if (!PyArg_ParseTuple(args, "eti:lchmod", Py_FileSystemDefaultEncoding,
1768 &path, &i))
1769 return NULL;
1770 Py_BEGIN_ALLOW_THREADS
1771 res = lchmod(path, i);
1772 Py_END_ALLOW_THREADS
1773 if (res < 0)
1774 return posix_error_with_allocated_filename(path);
1775 PyMem_Free(path);
1776 Py_RETURN_NONE;
1778 #endif /* HAVE_LCHMOD */
1781 #ifdef HAVE_CHFLAGS
1782 PyDoc_STRVAR(posix_chflags__doc__,
1783 "chflags(path, flags)\n\n\
1784 Set file flags.");
1786 static PyObject *
1787 posix_chflags(PyObject *self, PyObject *args)
1789 char *path;
1790 unsigned long flags;
1791 int res;
1792 if (!PyArg_ParseTuple(args, "etk:chflags",
1793 Py_FileSystemDefaultEncoding, &path, &flags))
1794 return NULL;
1795 Py_BEGIN_ALLOW_THREADS
1796 res = chflags(path, flags);
1797 Py_END_ALLOW_THREADS
1798 if (res < 0)
1799 return posix_error_with_allocated_filename(path);
1800 PyMem_Free(path);
1801 Py_INCREF(Py_None);
1802 return Py_None;
1804 #endif /* HAVE_CHFLAGS */
1806 #ifdef HAVE_LCHFLAGS
1807 PyDoc_STRVAR(posix_lchflags__doc__,
1808 "lchflags(path, flags)\n\n\
1809 Set file flags.\n\
1810 This function will not follow symbolic links.");
1812 static PyObject *
1813 posix_lchflags(PyObject *self, PyObject *args)
1815 char *path;
1816 unsigned long flags;
1817 int res;
1818 if (!PyArg_ParseTuple(args, "etk:lchflags",
1819 Py_FileSystemDefaultEncoding, &path, &flags))
1820 return NULL;
1821 Py_BEGIN_ALLOW_THREADS
1822 res = lchflags(path, flags);
1823 Py_END_ALLOW_THREADS
1824 if (res < 0)
1825 return posix_error_with_allocated_filename(path);
1826 PyMem_Free(path);
1827 Py_INCREF(Py_None);
1828 return Py_None;
1830 #endif /* HAVE_LCHFLAGS */
1832 #ifdef HAVE_CHROOT
1833 PyDoc_STRVAR(posix_chroot__doc__,
1834 "chroot(path)\n\n\
1835 Change root directory to path.");
1837 static PyObject *
1838 posix_chroot(PyObject *self, PyObject *args)
1840 return posix_1str(args, "et:chroot", chroot);
1842 #endif
1844 #ifdef HAVE_FSYNC
1845 PyDoc_STRVAR(posix_fsync__doc__,
1846 "fsync(fildes)\n\n\
1847 force write of file with filedescriptor to disk.");
1849 static PyObject *
1850 posix_fsync(PyObject *self, PyObject *fdobj)
1852 return posix_fildes(fdobj, fsync);
1854 #endif /* HAVE_FSYNC */
1856 #ifdef HAVE_FDATASYNC
1858 #ifdef __hpux
1859 extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1860 #endif
1862 PyDoc_STRVAR(posix_fdatasync__doc__,
1863 "fdatasync(fildes)\n\n\
1864 force write of file with filedescriptor to disk.\n\
1865 does not force update of metadata.");
1867 static PyObject *
1868 posix_fdatasync(PyObject *self, PyObject *fdobj)
1870 return posix_fildes(fdobj, fdatasync);
1872 #endif /* HAVE_FDATASYNC */
1875 #ifdef HAVE_CHOWN
1876 PyDoc_STRVAR(posix_chown__doc__,
1877 "chown(path, uid, gid)\n\n\
1878 Change the owner and group id of path to the numeric uid and gid.");
1880 static PyObject *
1881 posix_chown(PyObject *self, PyObject *args)
1883 char *path = NULL;
1884 long uid, gid;
1885 int res;
1886 if (!PyArg_ParseTuple(args, "etll:chown",
1887 Py_FileSystemDefaultEncoding, &path,
1888 &uid, &gid))
1889 return NULL;
1890 Py_BEGIN_ALLOW_THREADS
1891 res = chown(path, (uid_t) uid, (gid_t) gid);
1892 Py_END_ALLOW_THREADS
1893 if (res < 0)
1894 return posix_error_with_allocated_filename(path);
1895 PyMem_Free(path);
1896 Py_INCREF(Py_None);
1897 return Py_None;
1899 #endif /* HAVE_CHOWN */
1901 #ifdef HAVE_FCHOWN
1902 PyDoc_STRVAR(posix_fchown__doc__,
1903 "fchown(fd, uid, gid)\n\n\
1904 Change the owner and group id of the file given by file descriptor\n\
1905 fd to the numeric uid and gid.");
1907 static PyObject *
1908 posix_fchown(PyObject *self, PyObject *args)
1910 int fd, uid, gid;
1911 int res;
1912 if (!PyArg_ParseTuple(args, "iii:chown", &fd, &uid, &gid))
1913 return NULL;
1914 Py_BEGIN_ALLOW_THREADS
1915 res = fchown(fd, (uid_t) uid, (gid_t) gid);
1916 Py_END_ALLOW_THREADS
1917 if (res < 0)
1918 return posix_error();
1919 Py_RETURN_NONE;
1921 #endif /* HAVE_FCHOWN */
1923 #ifdef HAVE_LCHOWN
1924 PyDoc_STRVAR(posix_lchown__doc__,
1925 "lchown(path, uid, gid)\n\n\
1926 Change the owner and group id of path to the numeric uid and gid.\n\
1927 This function will not follow symbolic links.");
1929 static PyObject *
1930 posix_lchown(PyObject *self, PyObject *args)
1932 char *path = NULL;
1933 int uid, gid;
1934 int res;
1935 if (!PyArg_ParseTuple(args, "etii:lchown",
1936 Py_FileSystemDefaultEncoding, &path,
1937 &uid, &gid))
1938 return NULL;
1939 Py_BEGIN_ALLOW_THREADS
1940 res = lchown(path, (uid_t) uid, (gid_t) gid);
1941 Py_END_ALLOW_THREADS
1942 if (res < 0)
1943 return posix_error_with_allocated_filename(path);
1944 PyMem_Free(path);
1945 Py_INCREF(Py_None);
1946 return Py_None;
1948 #endif /* HAVE_LCHOWN */
1951 #ifdef HAVE_GETCWD
1952 PyDoc_STRVAR(posix_getcwd__doc__,
1953 "getcwd() -> path\n\n\
1954 Return a string representing the current working directory.");
1956 static PyObject *
1957 posix_getcwd(PyObject *self, PyObject *noargs)
1959 int bufsize_incr = 1024;
1960 int bufsize = 0;
1961 char *tmpbuf = NULL;
1962 char *res = NULL;
1963 PyObject *dynamic_return;
1965 Py_BEGIN_ALLOW_THREADS
1966 do {
1967 bufsize = bufsize + bufsize_incr;
1968 tmpbuf = malloc(bufsize);
1969 if (tmpbuf == NULL) {
1970 break;
1972 #if defined(PYOS_OS2) && defined(PYCC_GCC)
1973 res = _getcwd2(tmpbuf, bufsize);
1974 #else
1975 res = getcwd(tmpbuf, bufsize);
1976 #endif
1978 if (res == NULL) {
1979 free(tmpbuf);
1981 } while ((res == NULL) && (errno == ERANGE));
1982 Py_END_ALLOW_THREADS
1984 if (res == NULL)
1985 return posix_error();
1987 dynamic_return = PyString_FromString(tmpbuf);
1988 free(tmpbuf);
1990 return dynamic_return;
1993 #ifdef Py_USING_UNICODE
1994 PyDoc_STRVAR(posix_getcwdu__doc__,
1995 "getcwdu() -> path\n\n\
1996 Return a unicode string representing the current working directory.");
1998 static PyObject *
1999 posix_getcwdu(PyObject *self, PyObject *noargs)
2001 char buf[1026];
2002 char *res;
2004 #ifdef Py_WIN_WIDE_FILENAMES
2005 DWORD len;
2006 if (unicode_file_names()) {
2007 wchar_t wbuf[1026];
2008 wchar_t *wbuf2 = wbuf;
2009 PyObject *resobj;
2010 Py_BEGIN_ALLOW_THREADS
2011 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
2012 /* If the buffer is large enough, len does not include the
2013 terminating \0. If the buffer is too small, len includes
2014 the space needed for the terminator. */
2015 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
2016 wbuf2 = malloc(len * sizeof(wchar_t));
2017 if (wbuf2)
2018 len = GetCurrentDirectoryW(len, wbuf2);
2020 Py_END_ALLOW_THREADS
2021 if (!wbuf2) {
2022 PyErr_NoMemory();
2023 return NULL;
2025 if (!len) {
2026 if (wbuf2 != wbuf) free(wbuf2);
2027 return win32_error("getcwdu", NULL);
2029 resobj = PyUnicode_FromWideChar(wbuf2, len);
2030 if (wbuf2 != wbuf) free(wbuf2);
2031 return resobj;
2033 #endif
2035 Py_BEGIN_ALLOW_THREADS
2036 #if defined(PYOS_OS2) && defined(PYCC_GCC)
2037 res = _getcwd2(buf, sizeof buf);
2038 #else
2039 res = getcwd(buf, sizeof buf);
2040 #endif
2041 Py_END_ALLOW_THREADS
2042 if (res == NULL)
2043 return posix_error();
2044 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
2046 #endif
2047 #endif
2050 #ifdef HAVE_LINK
2051 PyDoc_STRVAR(posix_link__doc__,
2052 "link(src, dst)\n\n\
2053 Create a hard link to a file.");
2055 static PyObject *
2056 posix_link(PyObject *self, PyObject *args)
2058 return posix_2str(args, "etet:link", link);
2060 #endif /* HAVE_LINK */
2063 PyDoc_STRVAR(posix_listdir__doc__,
2064 "listdir(path) -> list_of_strings\n\n\
2065 Return a list containing the names of the entries in the directory.\n\
2067 path: path of directory to list\n\
2069 The list is in arbitrary order. It does not include the special\n\
2070 entries '.' and '..' even if they are present in the directory.");
2072 static PyObject *
2073 posix_listdir(PyObject *self, PyObject *args)
2075 /* XXX Should redo this putting the (now four) versions of opendir
2076 in separate files instead of having them all here... */
2077 #if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
2079 PyObject *d, *v;
2080 HANDLE hFindFile;
2081 BOOL result;
2082 WIN32_FIND_DATA FileData;
2083 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
2084 char *bufptr = namebuf;
2085 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
2087 #ifdef Py_WIN_WIDE_FILENAMES
2088 /* If on wide-character-capable OS see if argument
2089 is Unicode and if so use wide API. */
2090 if (unicode_file_names()) {
2091 PyObject *po;
2092 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
2093 WIN32_FIND_DATAW wFileData;
2094 Py_UNICODE *wnamebuf;
2095 Py_UNICODE wch;
2096 /* Overallocate for \\*.*\0 */
2097 len = PyUnicode_GET_SIZE(po);
2098 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
2099 if (!wnamebuf) {
2100 PyErr_NoMemory();
2101 return NULL;
2103 wcscpy(wnamebuf, PyUnicode_AS_UNICODE(po));
2104 wch = len > 0 ? wnamebuf[len-1] : '\0';
2105 if (wch != L'/' && wch != L'\\' && wch != L':')
2106 wnamebuf[len++] = L'\\';
2107 wcscpy(wnamebuf + len, L"*.*");
2108 if ((d = PyList_New(0)) == NULL) {
2109 free(wnamebuf);
2110 return NULL;
2112 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
2113 if (hFindFile == INVALID_HANDLE_VALUE) {
2114 int error = GetLastError();
2115 if (error == ERROR_FILE_NOT_FOUND) {
2116 free(wnamebuf);
2117 return d;
2119 Py_DECREF(d);
2120 win32_error_unicode("FindFirstFileW", wnamebuf);
2121 free(wnamebuf);
2122 return NULL;
2124 do {
2125 /* Skip over . and .. */
2126 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2127 wcscmp(wFileData.cFileName, L"..") != 0) {
2128 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
2129 if (v == NULL) {
2130 Py_DECREF(d);
2131 d = NULL;
2132 break;
2134 if (PyList_Append(d, v) != 0) {
2135 Py_DECREF(v);
2136 Py_DECREF(d);
2137 d = NULL;
2138 break;
2140 Py_DECREF(v);
2142 Py_BEGIN_ALLOW_THREADS
2143 result = FindNextFileW(hFindFile, &wFileData);
2144 Py_END_ALLOW_THREADS
2145 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2146 it got to the end of the directory. */
2147 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2148 Py_DECREF(d);
2149 win32_error_unicode("FindNextFileW", wnamebuf);
2150 FindClose(hFindFile);
2151 free(wnamebuf);
2152 return NULL;
2154 } while (result == TRUE);
2156 if (FindClose(hFindFile) == FALSE) {
2157 Py_DECREF(d);
2158 win32_error_unicode("FindClose", wnamebuf);
2159 free(wnamebuf);
2160 return NULL;
2162 free(wnamebuf);
2163 return d;
2165 /* Drop the argument parsing error as narrow strings
2166 are also valid. */
2167 PyErr_Clear();
2169 #endif
2171 if (!PyArg_ParseTuple(args, "et#:listdir",
2172 Py_FileSystemDefaultEncoding, &bufptr, &len))
2173 return NULL;
2174 if (len > 0) {
2175 char ch = namebuf[len-1];
2176 if (ch != SEP && ch != ALTSEP && ch != ':')
2177 namebuf[len++] = '/';
2179 strcpy(namebuf + len, "*.*");
2181 if ((d = PyList_New(0)) == NULL)
2182 return NULL;
2184 hFindFile = FindFirstFile(namebuf, &FileData);
2185 if (hFindFile == INVALID_HANDLE_VALUE) {
2186 int error = GetLastError();
2187 if (error == ERROR_FILE_NOT_FOUND)
2188 return d;
2189 Py_DECREF(d);
2190 return win32_error("FindFirstFile", namebuf);
2192 do {
2193 /* Skip over . and .. */
2194 if (strcmp(FileData.cFileName, ".") != 0 &&
2195 strcmp(FileData.cFileName, "..") != 0) {
2196 v = PyString_FromString(FileData.cFileName);
2197 if (v == NULL) {
2198 Py_DECREF(d);
2199 d = NULL;
2200 break;
2202 if (PyList_Append(d, v) != 0) {
2203 Py_DECREF(v);
2204 Py_DECREF(d);
2205 d = NULL;
2206 break;
2208 Py_DECREF(v);
2210 Py_BEGIN_ALLOW_THREADS
2211 result = FindNextFile(hFindFile, &FileData);
2212 Py_END_ALLOW_THREADS
2213 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2214 it got to the end of the directory. */
2215 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2216 Py_DECREF(d);
2217 win32_error("FindNextFile", namebuf);
2218 FindClose(hFindFile);
2219 return NULL;
2221 } while (result == TRUE);
2223 if (FindClose(hFindFile) == FALSE) {
2224 Py_DECREF(d);
2225 return win32_error("FindClose", namebuf);
2228 return d;
2230 #elif defined(PYOS_OS2)
2232 #ifndef MAX_PATH
2233 #define MAX_PATH CCHMAXPATH
2234 #endif
2235 char *name, *pt;
2236 Py_ssize_t len;
2237 PyObject *d, *v;
2238 char namebuf[MAX_PATH+5];
2239 HDIR hdir = 1;
2240 ULONG srchcnt = 1;
2241 FILEFINDBUF3 ep;
2242 APIRET rc;
2244 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
2245 return NULL;
2246 if (len >= MAX_PATH) {
2247 PyErr_SetString(PyExc_ValueError, "path too long");
2248 return NULL;
2250 strcpy(namebuf, name);
2251 for (pt = namebuf; *pt; pt++)
2252 if (*pt == ALTSEP)
2253 *pt = SEP;
2254 if (namebuf[len-1] != SEP)
2255 namebuf[len++] = SEP;
2256 strcpy(namebuf + len, "*.*");
2258 if ((d = PyList_New(0)) == NULL)
2259 return NULL;
2261 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2262 &hdir, /* Handle to Use While Search Directory */
2263 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
2264 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2265 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2266 FIL_STANDARD); /* Format of Entry (EAs or Not) */
2268 if (rc != NO_ERROR) {
2269 errno = ENOENT;
2270 return posix_error_with_filename(name);
2273 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
2274 do {
2275 if (ep.achName[0] == '.'
2276 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
2277 continue; /* Skip Over "." and ".." Names */
2279 strcpy(namebuf, ep.achName);
2281 /* Leave Case of Name Alone -- In Native Form */
2282 /* (Removed Forced Lowercasing Code) */
2284 v = PyString_FromString(namebuf);
2285 if (v == NULL) {
2286 Py_DECREF(d);
2287 d = NULL;
2288 break;
2290 if (PyList_Append(d, v) != 0) {
2291 Py_DECREF(v);
2292 Py_DECREF(d);
2293 d = NULL;
2294 break;
2296 Py_DECREF(v);
2297 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2300 return d;
2301 #else
2303 char *name = NULL;
2304 PyObject *d, *v;
2305 DIR *dirp;
2306 struct dirent *ep;
2307 int arg_is_unicode = 1;
2309 errno = 0;
2310 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
2311 arg_is_unicode = 0;
2312 PyErr_Clear();
2314 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
2315 return NULL;
2316 if ((dirp = opendir(name)) == NULL) {
2317 return posix_error_with_allocated_filename(name);
2319 if ((d = PyList_New(0)) == NULL) {
2320 closedir(dirp);
2321 PyMem_Free(name);
2322 return NULL;
2324 for (;;) {
2325 errno = 0;
2326 Py_BEGIN_ALLOW_THREADS
2327 ep = readdir(dirp);
2328 Py_END_ALLOW_THREADS
2329 if (ep == NULL) {
2330 if (errno == 0) {
2331 break;
2332 } else {
2333 closedir(dirp);
2334 Py_DECREF(d);
2335 return posix_error_with_allocated_filename(name);
2338 if (ep->d_name[0] == '.' &&
2339 (NAMLEN(ep) == 1 ||
2340 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
2341 continue;
2342 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
2343 if (v == NULL) {
2344 Py_DECREF(d);
2345 d = NULL;
2346 break;
2348 #ifdef Py_USING_UNICODE
2349 if (arg_is_unicode) {
2350 PyObject *w;
2352 w = PyUnicode_FromEncodedObject(v,
2353 Py_FileSystemDefaultEncoding,
2354 "strict");
2355 if (w != NULL) {
2356 Py_DECREF(v);
2357 v = w;
2359 else {
2360 /* fall back to the original byte string, as
2361 discussed in patch #683592 */
2362 PyErr_Clear();
2365 #endif
2366 if (PyList_Append(d, v) != 0) {
2367 Py_DECREF(v);
2368 Py_DECREF(d);
2369 d = NULL;
2370 break;
2372 Py_DECREF(v);
2374 closedir(dirp);
2375 PyMem_Free(name);
2377 return d;
2379 #endif /* which OS */
2380 } /* end of posix_listdir */
2382 #ifdef MS_WINDOWS
2383 /* A helper function for abspath on win32 */
2384 static PyObject *
2385 posix__getfullpathname(PyObject *self, PyObject *args)
2387 /* assume encoded strings wont more than double no of chars */
2388 char inbuf[MAX_PATH*2];
2389 char *inbufp = inbuf;
2390 Py_ssize_t insize = sizeof(inbuf);
2391 char outbuf[MAX_PATH*2];
2392 char *temp;
2393 #ifdef Py_WIN_WIDE_FILENAMES
2394 if (unicode_file_names()) {
2395 PyUnicodeObject *po;
2396 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
2397 Py_UNICODE woutbuf[MAX_PATH*2];
2398 Py_UNICODE *wtemp;
2399 if (!GetFullPathNameW(PyUnicode_AS_UNICODE(po),
2400 sizeof(woutbuf)/sizeof(woutbuf[0]),
2401 woutbuf, &wtemp))
2402 return win32_error("GetFullPathName", "");
2403 return PyUnicode_FromUnicode(woutbuf, wcslen(woutbuf));
2405 /* Drop the argument parsing error as narrow strings
2406 are also valid. */
2407 PyErr_Clear();
2409 #endif
2410 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
2411 Py_FileSystemDefaultEncoding, &inbufp,
2412 &insize))
2413 return NULL;
2414 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
2415 outbuf, &temp))
2416 return win32_error("GetFullPathName", inbuf);
2417 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2418 return PyUnicode_Decode(outbuf, strlen(outbuf),
2419 Py_FileSystemDefaultEncoding, NULL);
2421 return PyString_FromString(outbuf);
2422 } /* end of posix__getfullpathname */
2423 #endif /* MS_WINDOWS */
2425 PyDoc_STRVAR(posix_mkdir__doc__,
2426 "mkdir(path [, mode=0777])\n\n\
2427 Create a directory.");
2429 static PyObject *
2430 posix_mkdir(PyObject *self, PyObject *args)
2432 int res;
2433 char *path = NULL;
2434 int mode = 0777;
2436 #ifdef Py_WIN_WIDE_FILENAMES
2437 if (unicode_file_names()) {
2438 PyUnicodeObject *po;
2439 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
2440 Py_BEGIN_ALLOW_THREADS
2441 /* PyUnicode_AS_UNICODE OK without thread lock as
2442 it is a simple dereference. */
2443 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
2444 Py_END_ALLOW_THREADS
2445 if (!res)
2446 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
2447 Py_INCREF(Py_None);
2448 return Py_None;
2450 /* Drop the argument parsing error as narrow strings
2451 are also valid. */
2452 PyErr_Clear();
2454 if (!PyArg_ParseTuple(args, "et|i:mkdir",
2455 Py_FileSystemDefaultEncoding, &path, &mode))
2456 return NULL;
2457 Py_BEGIN_ALLOW_THREADS
2458 /* PyUnicode_AS_UNICODE OK without thread lock as
2459 it is a simple dereference. */
2460 res = CreateDirectoryA(path, NULL);
2461 Py_END_ALLOW_THREADS
2462 if (!res) {
2463 win32_error("mkdir", path);
2464 PyMem_Free(path);
2465 return NULL;
2467 PyMem_Free(path);
2468 Py_INCREF(Py_None);
2469 return Py_None;
2470 #else
2472 if (!PyArg_ParseTuple(args, "et|i:mkdir",
2473 Py_FileSystemDefaultEncoding, &path, &mode))
2474 return NULL;
2475 Py_BEGIN_ALLOW_THREADS
2476 #if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
2477 res = mkdir(path);
2478 #else
2479 res = mkdir(path, mode);
2480 #endif
2481 Py_END_ALLOW_THREADS
2482 if (res < 0)
2483 return posix_error_with_allocated_filename(path);
2484 PyMem_Free(path);
2485 Py_INCREF(Py_None);
2486 return Py_None;
2487 #endif
2491 /* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2492 #if defined(HAVE_SYS_RESOURCE_H)
2493 #include <sys/resource.h>
2494 #endif
2497 #ifdef HAVE_NICE
2498 PyDoc_STRVAR(posix_nice__doc__,
2499 "nice(inc) -> new_priority\n\n\
2500 Decrease the priority of process by inc and return the new priority.");
2502 static PyObject *
2503 posix_nice(PyObject *self, PyObject *args)
2505 int increment, value;
2507 if (!PyArg_ParseTuple(args, "i:nice", &increment))
2508 return NULL;
2510 /* There are two flavours of 'nice': one that returns the new
2511 priority (as required by almost all standards out there) and the
2512 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2513 the use of getpriority() to get the new priority.
2515 If we are of the nice family that returns the new priority, we
2516 need to clear errno before the call, and check if errno is filled
2517 before calling posix_error() on a returnvalue of -1, because the
2518 -1 may be the actual new priority! */
2520 errno = 0;
2521 value = nice(increment);
2522 #if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
2523 if (value == 0)
2524 value = getpriority(PRIO_PROCESS, 0);
2525 #endif
2526 if (value == -1 && errno != 0)
2527 /* either nice() or getpriority() returned an error */
2528 return posix_error();
2529 return PyInt_FromLong((long) value);
2531 #endif /* HAVE_NICE */
2533 PyDoc_STRVAR(posix_rename__doc__,
2534 "rename(old, new)\n\n\
2535 Rename a file or directory.");
2537 static PyObject *
2538 posix_rename(PyObject *self, PyObject *args)
2540 #ifdef MS_WINDOWS
2541 PyObject *o1, *o2;
2542 char *p1, *p2;
2543 BOOL result;
2544 if (unicode_file_names()) {
2545 if (!PyArg_ParseTuple(args, "O&O&:rename",
2546 convert_to_unicode, &o1,
2547 convert_to_unicode, &o2))
2548 PyErr_Clear();
2549 else {
2550 Py_BEGIN_ALLOW_THREADS
2551 result = MoveFileW(PyUnicode_AsUnicode(o1),
2552 PyUnicode_AsUnicode(o2));
2553 Py_END_ALLOW_THREADS
2554 Py_DECREF(o1);
2555 Py_DECREF(o2);
2556 if (!result)
2557 return win32_error("rename", NULL);
2558 Py_INCREF(Py_None);
2559 return Py_None;
2562 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
2563 return NULL;
2564 Py_BEGIN_ALLOW_THREADS
2565 result = MoveFileA(p1, p2);
2566 Py_END_ALLOW_THREADS
2567 if (!result)
2568 return win32_error("rename", NULL);
2569 Py_INCREF(Py_None);
2570 return Py_None;
2571 #else
2572 return posix_2str(args, "etet:rename", rename);
2573 #endif
2577 PyDoc_STRVAR(posix_rmdir__doc__,
2578 "rmdir(path)\n\n\
2579 Remove a directory.");
2581 static PyObject *
2582 posix_rmdir(PyObject *self, PyObject *args)
2584 #ifdef MS_WINDOWS
2585 return win32_1str(args, "rmdir", "s:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
2586 #else
2587 return posix_1str(args, "et:rmdir", rmdir);
2588 #endif
2592 PyDoc_STRVAR(posix_stat__doc__,
2593 "stat(path) -> stat result\n\n\
2594 Perform a stat system call on the given path.");
2596 static PyObject *
2597 posix_stat(PyObject *self, PyObject *args)
2599 #ifdef MS_WINDOWS
2600 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", win32_wstat);
2601 #else
2602 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
2603 #endif
2607 #ifdef HAVE_SYSTEM
2608 PyDoc_STRVAR(posix_system__doc__,
2609 "system(command) -> exit_status\n\n\
2610 Execute the command (a string) in a subshell.");
2612 static PyObject *
2613 posix_system(PyObject *self, PyObject *args)
2615 char *command;
2616 long sts;
2617 if (!PyArg_ParseTuple(args, "s:system", &command))
2618 return NULL;
2619 Py_BEGIN_ALLOW_THREADS
2620 sts = system(command);
2621 Py_END_ALLOW_THREADS
2622 return PyInt_FromLong(sts);
2624 #endif
2627 PyDoc_STRVAR(posix_umask__doc__,
2628 "umask(new_mask) -> old_mask\n\n\
2629 Set the current numeric umask and return the previous umask.");
2631 static PyObject *
2632 posix_umask(PyObject *self, PyObject *args)
2634 int i;
2635 if (!PyArg_ParseTuple(args, "i:umask", &i))
2636 return NULL;
2637 i = (int)umask(i);
2638 if (i < 0)
2639 return posix_error();
2640 return PyInt_FromLong((long)i);
2644 PyDoc_STRVAR(posix_unlink__doc__,
2645 "unlink(path)\n\n\
2646 Remove a file (same as remove(path)).");
2648 PyDoc_STRVAR(posix_remove__doc__,
2649 "remove(path)\n\n\
2650 Remove a file (same as unlink(path)).");
2652 static PyObject *
2653 posix_unlink(PyObject *self, PyObject *args)
2655 #ifdef MS_WINDOWS
2656 return win32_1str(args, "remove", "s:remove", DeleteFileA, "U:remove", DeleteFileW);
2657 #else
2658 return posix_1str(args, "et:remove", unlink);
2659 #endif
2663 #ifdef HAVE_UNAME
2664 PyDoc_STRVAR(posix_uname__doc__,
2665 "uname() -> (sysname, nodename, release, version, machine)\n\n\
2666 Return a tuple identifying the current operating system.");
2668 static PyObject *
2669 posix_uname(PyObject *self, PyObject *noargs)
2671 struct utsname u;
2672 int res;
2674 Py_BEGIN_ALLOW_THREADS
2675 res = uname(&u);
2676 Py_END_ALLOW_THREADS
2677 if (res < 0)
2678 return posix_error();
2679 return Py_BuildValue("(sssss)",
2680 u.sysname,
2681 u.nodename,
2682 u.release,
2683 u.version,
2684 u.machine);
2686 #endif /* HAVE_UNAME */
2688 static int
2689 extract_time(PyObject *t, long* sec, long* usec)
2691 long intval;
2692 if (PyFloat_Check(t)) {
2693 double tval = PyFloat_AsDouble(t);
2694 PyObject *intobj = Py_TYPE(t)->tp_as_number->nb_int(t);
2695 if (!intobj)
2696 return -1;
2697 intval = PyInt_AsLong(intobj);
2698 Py_DECREF(intobj);
2699 if (intval == -1 && PyErr_Occurred())
2700 return -1;
2701 *sec = intval;
2702 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
2703 if (*usec < 0)
2704 /* If rounding gave us a negative number,
2705 truncate. */
2706 *usec = 0;
2707 return 0;
2709 intval = PyInt_AsLong(t);
2710 if (intval == -1 && PyErr_Occurred())
2711 return -1;
2712 *sec = intval;
2713 *usec = 0;
2714 return 0;
2717 PyDoc_STRVAR(posix_utime__doc__,
2718 "utime(path, (atime, mtime))\n\
2719 utime(path, None)\n\n\
2720 Set the access and modified time of the file to the given values. If the\n\
2721 second form is used, set the access and modified times to the current time.");
2723 static PyObject *
2724 posix_utime(PyObject *self, PyObject *args)
2726 #ifdef Py_WIN_WIDE_FILENAMES
2727 PyObject *arg;
2728 PyUnicodeObject *obwpath;
2729 wchar_t *wpath = NULL;
2730 char *apath = NULL;
2731 HANDLE hFile;
2732 long atimesec, mtimesec, ausec, musec;
2733 FILETIME atime, mtime;
2734 PyObject *result = NULL;
2736 if (unicode_file_names()) {
2737 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
2738 wpath = PyUnicode_AS_UNICODE(obwpath);
2739 Py_BEGIN_ALLOW_THREADS
2740 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
2741 NULL, OPEN_EXISTING,
2742 FILE_FLAG_BACKUP_SEMANTICS, NULL);
2743 Py_END_ALLOW_THREADS
2744 if (hFile == INVALID_HANDLE_VALUE)
2745 return win32_error_unicode("utime", wpath);
2746 } else
2747 /* Drop the argument parsing error as narrow strings
2748 are also valid. */
2749 PyErr_Clear();
2751 if (!wpath) {
2752 if (!PyArg_ParseTuple(args, "etO:utime",
2753 Py_FileSystemDefaultEncoding, &apath, &arg))
2754 return NULL;
2755 Py_BEGIN_ALLOW_THREADS
2756 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
2757 NULL, OPEN_EXISTING,
2758 FILE_FLAG_BACKUP_SEMANTICS, NULL);
2759 Py_END_ALLOW_THREADS
2760 if (hFile == INVALID_HANDLE_VALUE) {
2761 win32_error("utime", apath);
2762 PyMem_Free(apath);
2763 return NULL;
2765 PyMem_Free(apath);
2768 if (arg == Py_None) {
2769 SYSTEMTIME now;
2770 GetSystemTime(&now);
2771 if (!SystemTimeToFileTime(&now, &mtime) ||
2772 !SystemTimeToFileTime(&now, &atime)) {
2773 win32_error("utime", NULL);
2774 goto done;
2777 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
2778 PyErr_SetString(PyExc_TypeError,
2779 "utime() arg 2 must be a tuple (atime, mtime)");
2780 goto done;
2782 else {
2783 if (extract_time(PyTuple_GET_ITEM(arg, 0),
2784 &atimesec, &ausec) == -1)
2785 goto done;
2786 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
2787 if (extract_time(PyTuple_GET_ITEM(arg, 1),
2788 &mtimesec, &musec) == -1)
2789 goto done;
2790 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
2792 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
2793 /* Avoid putting the file name into the error here,
2794 as that may confuse the user into believing that
2795 something is wrong with the file, when it also
2796 could be the time stamp that gives a problem. */
2797 win32_error("utime", NULL);
2799 Py_INCREF(Py_None);
2800 result = Py_None;
2801 done:
2802 CloseHandle(hFile);
2803 return result;
2804 #else /* Py_WIN_WIDE_FILENAMES */
2806 char *path = NULL;
2807 long atime, mtime, ausec, musec;
2808 int res;
2809 PyObject* arg;
2811 #if defined(HAVE_UTIMES)
2812 struct timeval buf[2];
2813 #define ATIME buf[0].tv_sec
2814 #define MTIME buf[1].tv_sec
2815 #elif defined(HAVE_UTIME_H)
2816 /* XXX should define struct utimbuf instead, above */
2817 struct utimbuf buf;
2818 #define ATIME buf.actime
2819 #define MTIME buf.modtime
2820 #define UTIME_ARG &buf
2821 #else /* HAVE_UTIMES */
2822 time_t buf[2];
2823 #define ATIME buf[0]
2824 #define MTIME buf[1]
2825 #define UTIME_ARG buf
2826 #endif /* HAVE_UTIMES */
2829 if (!PyArg_ParseTuple(args, "etO:utime",
2830 Py_FileSystemDefaultEncoding, &path, &arg))
2831 return NULL;
2832 if (arg == Py_None) {
2833 /* optional time values not given */
2834 Py_BEGIN_ALLOW_THREADS
2835 res = utime(path, NULL);
2836 Py_END_ALLOW_THREADS
2838 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
2839 PyErr_SetString(PyExc_TypeError,
2840 "utime() arg 2 must be a tuple (atime, mtime)");
2841 PyMem_Free(path);
2842 return NULL;
2844 else {
2845 if (extract_time(PyTuple_GET_ITEM(arg, 0),
2846 &atime, &ausec) == -1) {
2847 PyMem_Free(path);
2848 return NULL;
2850 if (extract_time(PyTuple_GET_ITEM(arg, 1),
2851 &mtime, &musec) == -1) {
2852 PyMem_Free(path);
2853 return NULL;
2855 ATIME = atime;
2856 MTIME = mtime;
2857 #ifdef HAVE_UTIMES
2858 buf[0].tv_usec = ausec;
2859 buf[1].tv_usec = musec;
2860 Py_BEGIN_ALLOW_THREADS
2861 res = utimes(path, buf);
2862 Py_END_ALLOW_THREADS
2863 #else
2864 Py_BEGIN_ALLOW_THREADS
2865 res = utime(path, UTIME_ARG);
2866 Py_END_ALLOW_THREADS
2867 #endif /* HAVE_UTIMES */
2869 if (res < 0) {
2870 return posix_error_with_allocated_filename(path);
2872 PyMem_Free(path);
2873 Py_INCREF(Py_None);
2874 return Py_None;
2875 #undef UTIME_ARG
2876 #undef ATIME
2877 #undef MTIME
2878 #endif /* Py_WIN_WIDE_FILENAMES */
2882 /* Process operations */
2884 PyDoc_STRVAR(posix__exit__doc__,
2885 "_exit(status)\n\n\
2886 Exit to the system with specified status, without normal exit processing.");
2888 static PyObject *
2889 posix__exit(PyObject *self, PyObject *args)
2891 int sts;
2892 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
2893 return NULL;
2894 _exit(sts);
2895 return NULL; /* Make gcc -Wall happy */
2898 #if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
2899 static void
2900 free_string_array(char **array, Py_ssize_t count)
2902 Py_ssize_t i;
2903 for (i = 0; i < count; i++)
2904 PyMem_Free(array[i]);
2905 PyMem_DEL(array);
2907 #endif
2910 #ifdef HAVE_EXECV
2911 PyDoc_STRVAR(posix_execv__doc__,
2912 "execv(path, args)\n\n\
2913 Execute an executable path with arguments, replacing current process.\n\
2915 path: path of executable file\n\
2916 args: tuple or list of strings");
2918 static PyObject *
2919 posix_execv(PyObject *self, PyObject *args)
2921 char *path;
2922 PyObject *argv;
2923 char **argvlist;
2924 Py_ssize_t i, argc;
2925 PyObject *(*getitem)(PyObject *, Py_ssize_t);
2927 /* execv has two arguments: (path, argv), where
2928 argv is a list or tuple of strings. */
2930 if (!PyArg_ParseTuple(args, "etO:execv",
2931 Py_FileSystemDefaultEncoding,
2932 &path, &argv))
2933 return NULL;
2934 if (PyList_Check(argv)) {
2935 argc = PyList_Size(argv);
2936 getitem = PyList_GetItem;
2938 else if (PyTuple_Check(argv)) {
2939 argc = PyTuple_Size(argv);
2940 getitem = PyTuple_GetItem;
2942 else {
2943 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
2944 PyMem_Free(path);
2945 return NULL;
2948 argvlist = PyMem_NEW(char *, argc+1);
2949 if (argvlist == NULL) {
2950 PyMem_Free(path);
2951 return PyErr_NoMemory();
2953 for (i = 0; i < argc; i++) {
2954 if (!PyArg_Parse((*getitem)(argv, i), "et",
2955 Py_FileSystemDefaultEncoding,
2956 &argvlist[i])) {
2957 free_string_array(argvlist, i);
2958 PyErr_SetString(PyExc_TypeError,
2959 "execv() arg 2 must contain only strings");
2960 PyMem_Free(path);
2961 return NULL;
2965 argvlist[argc] = NULL;
2967 execv(path, argvlist);
2969 /* If we get here it's definitely an error */
2971 free_string_array(argvlist, argc);
2972 PyMem_Free(path);
2973 return posix_error();
2977 PyDoc_STRVAR(posix_execve__doc__,
2978 "execve(path, args, env)\n\n\
2979 Execute a path with arguments and environment, replacing current process.\n\
2981 path: path of executable file\n\
2982 args: tuple or list of arguments\n\
2983 env: dictionary of strings mapping to strings");
2985 static PyObject *
2986 posix_execve(PyObject *self, PyObject *args)
2988 char *path;
2989 PyObject *argv, *env;
2990 char **argvlist;
2991 char **envlist;
2992 PyObject *key, *val, *keys=NULL, *vals=NULL;
2993 Py_ssize_t i, pos, argc, envc;
2994 PyObject *(*getitem)(PyObject *, Py_ssize_t);
2995 Py_ssize_t lastarg = 0;
2997 /* execve has three arguments: (path, argv, env), where
2998 argv is a list or tuple of strings and env is a dictionary
2999 like posix.environ. */
3001 if (!PyArg_ParseTuple(args, "etOO:execve",
3002 Py_FileSystemDefaultEncoding,
3003 &path, &argv, &env))
3004 return NULL;
3005 if (PyList_Check(argv)) {
3006 argc = PyList_Size(argv);
3007 getitem = PyList_GetItem;
3009 else if (PyTuple_Check(argv)) {
3010 argc = PyTuple_Size(argv);
3011 getitem = PyTuple_GetItem;
3013 else {
3014 PyErr_SetString(PyExc_TypeError,
3015 "execve() arg 2 must be a tuple or list");
3016 goto fail_0;
3018 if (!PyMapping_Check(env)) {
3019 PyErr_SetString(PyExc_TypeError,
3020 "execve() arg 3 must be a mapping object");
3021 goto fail_0;
3024 argvlist = PyMem_NEW(char *, argc+1);
3025 if (argvlist == NULL) {
3026 PyErr_NoMemory();
3027 goto fail_0;
3029 for (i = 0; i < argc; i++) {
3030 if (!PyArg_Parse((*getitem)(argv, i),
3031 "et;execve() arg 2 must contain only strings",
3032 Py_FileSystemDefaultEncoding,
3033 &argvlist[i]))
3035 lastarg = i;
3036 goto fail_1;
3039 lastarg = argc;
3040 argvlist[argc] = NULL;
3042 i = PyMapping_Size(env);
3043 if (i < 0)
3044 goto fail_1;
3045 envlist = PyMem_NEW(char *, i + 1);
3046 if (envlist == NULL) {
3047 PyErr_NoMemory();
3048 goto fail_1;
3050 envc = 0;
3051 keys = PyMapping_Keys(env);
3052 vals = PyMapping_Values(env);
3053 if (!keys || !vals)
3054 goto fail_2;
3055 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3056 PyErr_SetString(PyExc_TypeError,
3057 "execve(): env.keys() or env.values() is not a list");
3058 goto fail_2;
3061 for (pos = 0; pos < i; pos++) {
3062 char *p, *k, *v;
3063 size_t len;
3065 key = PyList_GetItem(keys, pos);
3066 val = PyList_GetItem(vals, pos);
3067 if (!key || !val)
3068 goto fail_2;
3070 if (!PyArg_Parse(
3071 key,
3072 "s;execve() arg 3 contains a non-string key",
3073 &k) ||
3074 !PyArg_Parse(
3075 val,
3076 "s;execve() arg 3 contains a non-string value",
3077 &v))
3079 goto fail_2;
3082 #if defined(PYOS_OS2)
3083 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
3084 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
3085 #endif
3086 len = PyString_Size(key) + PyString_Size(val) + 2;
3087 p = PyMem_NEW(char, len);
3088 if (p == NULL) {
3089 PyErr_NoMemory();
3090 goto fail_2;
3092 PyOS_snprintf(p, len, "%s=%s", k, v);
3093 envlist[envc++] = p;
3094 #if defined(PYOS_OS2)
3096 #endif
3098 envlist[envc] = 0;
3100 execve(path, argvlist, envlist);
3102 /* If we get here it's definitely an error */
3104 (void) posix_error();
3106 fail_2:
3107 while (--envc >= 0)
3108 PyMem_DEL(envlist[envc]);
3109 PyMem_DEL(envlist);
3110 fail_1:
3111 free_string_array(argvlist, lastarg);
3112 Py_XDECREF(vals);
3113 Py_XDECREF(keys);
3114 fail_0:
3115 PyMem_Free(path);
3116 return NULL;
3118 #endif /* HAVE_EXECV */
3121 #ifdef HAVE_SPAWNV
3122 PyDoc_STRVAR(posix_spawnv__doc__,
3123 "spawnv(mode, path, args)\n\n\
3124 Execute the program 'path' in a new process.\n\
3126 mode: mode of process creation\n\
3127 path: path of executable file\n\
3128 args: tuple or list of strings");
3130 static PyObject *
3131 posix_spawnv(PyObject *self, PyObject *args)
3133 char *path;
3134 PyObject *argv;
3135 char **argvlist;
3136 int mode, i;
3137 Py_ssize_t argc;
3138 Py_intptr_t spawnval;
3139 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3141 /* spawnv has three arguments: (mode, path, argv), where
3142 argv is a list or tuple of strings. */
3144 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
3145 Py_FileSystemDefaultEncoding,
3146 &path, &argv))
3147 return NULL;
3148 if (PyList_Check(argv)) {
3149 argc = PyList_Size(argv);
3150 getitem = PyList_GetItem;
3152 else if (PyTuple_Check(argv)) {
3153 argc = PyTuple_Size(argv);
3154 getitem = PyTuple_GetItem;
3156 else {
3157 PyErr_SetString(PyExc_TypeError,
3158 "spawnv() arg 2 must be a tuple or list");
3159 PyMem_Free(path);
3160 return NULL;
3163 argvlist = PyMem_NEW(char *, argc+1);
3164 if (argvlist == NULL) {
3165 PyMem_Free(path);
3166 return PyErr_NoMemory();
3168 for (i = 0; i < argc; i++) {
3169 if (!PyArg_Parse((*getitem)(argv, i), "et",
3170 Py_FileSystemDefaultEncoding,
3171 &argvlist[i])) {
3172 free_string_array(argvlist, i);
3173 PyErr_SetString(
3174 PyExc_TypeError,
3175 "spawnv() arg 2 must contain only strings");
3176 PyMem_Free(path);
3177 return NULL;
3180 argvlist[argc] = NULL;
3182 #if defined(PYOS_OS2) && defined(PYCC_GCC)
3183 Py_BEGIN_ALLOW_THREADS
3184 spawnval = spawnv(mode, path, argvlist);
3185 Py_END_ALLOW_THREADS
3186 #else
3187 if (mode == _OLD_P_OVERLAY)
3188 mode = _P_OVERLAY;
3190 Py_BEGIN_ALLOW_THREADS
3191 spawnval = _spawnv(mode, path, argvlist);
3192 Py_END_ALLOW_THREADS
3193 #endif
3195 free_string_array(argvlist, argc);
3196 PyMem_Free(path);
3198 if (spawnval == -1)
3199 return posix_error();
3200 else
3201 #if SIZEOF_LONG == SIZEOF_VOID_P
3202 return Py_BuildValue("l", (long) spawnval);
3203 #else
3204 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
3205 #endif
3209 PyDoc_STRVAR(posix_spawnve__doc__,
3210 "spawnve(mode, path, args, env)\n\n\
3211 Execute the program 'path' in a new process.\n\
3213 mode: mode of process creation\n\
3214 path: path of executable file\n\
3215 args: tuple or list of arguments\n\
3216 env: dictionary of strings mapping to strings");
3218 static PyObject *
3219 posix_spawnve(PyObject *self, PyObject *args)
3221 char *path;
3222 PyObject *argv, *env;
3223 char **argvlist;
3224 char **envlist;
3225 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3226 int mode, pos, envc;
3227 Py_ssize_t argc, i;
3228 Py_intptr_t spawnval;
3229 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3230 Py_ssize_t lastarg = 0;
3232 /* spawnve has four arguments: (mode, path, argv, env), where
3233 argv is a list or tuple of strings and env is a dictionary
3234 like posix.environ. */
3236 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
3237 Py_FileSystemDefaultEncoding,
3238 &path, &argv, &env))
3239 return NULL;
3240 if (PyList_Check(argv)) {
3241 argc = PyList_Size(argv);
3242 getitem = PyList_GetItem;
3244 else if (PyTuple_Check(argv)) {
3245 argc = PyTuple_Size(argv);
3246 getitem = PyTuple_GetItem;
3248 else {
3249 PyErr_SetString(PyExc_TypeError,
3250 "spawnve() arg 2 must be a tuple or list");
3251 goto fail_0;
3253 if (!PyMapping_Check(env)) {
3254 PyErr_SetString(PyExc_TypeError,
3255 "spawnve() arg 3 must be a mapping object");
3256 goto fail_0;
3259 argvlist = PyMem_NEW(char *, argc+1);
3260 if (argvlist == NULL) {
3261 PyErr_NoMemory();
3262 goto fail_0;
3264 for (i = 0; i < argc; i++) {
3265 if (!PyArg_Parse((*getitem)(argv, i),
3266 "et;spawnve() arg 2 must contain only strings",
3267 Py_FileSystemDefaultEncoding,
3268 &argvlist[i]))
3270 lastarg = i;
3271 goto fail_1;
3274 lastarg = argc;
3275 argvlist[argc] = NULL;
3277 i = PyMapping_Size(env);
3278 if (i < 0)
3279 goto fail_1;
3280 envlist = PyMem_NEW(char *, i + 1);
3281 if (envlist == NULL) {
3282 PyErr_NoMemory();
3283 goto fail_1;
3285 envc = 0;
3286 keys = PyMapping_Keys(env);
3287 vals = PyMapping_Values(env);
3288 if (!keys || !vals)
3289 goto fail_2;
3290 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3291 PyErr_SetString(PyExc_TypeError,
3292 "spawnve(): env.keys() or env.values() is not a list");
3293 goto fail_2;
3296 for (pos = 0; pos < i; pos++) {
3297 char *p, *k, *v;
3298 size_t len;
3300 key = PyList_GetItem(keys, pos);
3301 val = PyList_GetItem(vals, pos);
3302 if (!key || !val)
3303 goto fail_2;
3305 if (!PyArg_Parse(
3306 key,
3307 "s;spawnve() arg 3 contains a non-string key",
3308 &k) ||
3309 !PyArg_Parse(
3310 val,
3311 "s;spawnve() arg 3 contains a non-string value",
3312 &v))
3314 goto fail_2;
3316 len = PyString_Size(key) + PyString_Size(val) + 2;
3317 p = PyMem_NEW(char, len);
3318 if (p == NULL) {
3319 PyErr_NoMemory();
3320 goto fail_2;
3322 PyOS_snprintf(p, len, "%s=%s", k, v);
3323 envlist[envc++] = p;
3325 envlist[envc] = 0;
3327 #if defined(PYOS_OS2) && defined(PYCC_GCC)
3328 Py_BEGIN_ALLOW_THREADS
3329 spawnval = spawnve(mode, path, argvlist, envlist);
3330 Py_END_ALLOW_THREADS
3331 #else
3332 if (mode == _OLD_P_OVERLAY)
3333 mode = _P_OVERLAY;
3335 Py_BEGIN_ALLOW_THREADS
3336 spawnval = _spawnve(mode, path, argvlist, envlist);
3337 Py_END_ALLOW_THREADS
3338 #endif
3340 if (spawnval == -1)
3341 (void) posix_error();
3342 else
3343 #if SIZEOF_LONG == SIZEOF_VOID_P
3344 res = Py_BuildValue("l", (long) spawnval);
3345 #else
3346 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
3347 #endif
3349 fail_2:
3350 while (--envc >= 0)
3351 PyMem_DEL(envlist[envc]);
3352 PyMem_DEL(envlist);
3353 fail_1:
3354 free_string_array(argvlist, lastarg);
3355 Py_XDECREF(vals);
3356 Py_XDECREF(keys);
3357 fail_0:
3358 PyMem_Free(path);
3359 return res;
3362 /* OS/2 supports spawnvp & spawnvpe natively */
3363 #if defined(PYOS_OS2)
3364 PyDoc_STRVAR(posix_spawnvp__doc__,
3365 "spawnvp(mode, file, args)\n\n\
3366 Execute the program 'file' in a new process, using the environment\n\
3367 search path to find the file.\n\
3369 mode: mode of process creation\n\
3370 file: executable file name\n\
3371 args: tuple or list of strings");
3373 static PyObject *
3374 posix_spawnvp(PyObject *self, PyObject *args)
3376 char *path;
3377 PyObject *argv;
3378 char **argvlist;
3379 int mode, i, argc;
3380 Py_intptr_t spawnval;
3381 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3383 /* spawnvp has three arguments: (mode, path, argv), where
3384 argv is a list or tuple of strings. */
3386 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
3387 Py_FileSystemDefaultEncoding,
3388 &path, &argv))
3389 return NULL;
3390 if (PyList_Check(argv)) {
3391 argc = PyList_Size(argv);
3392 getitem = PyList_GetItem;
3394 else if (PyTuple_Check(argv)) {
3395 argc = PyTuple_Size(argv);
3396 getitem = PyTuple_GetItem;
3398 else {
3399 PyErr_SetString(PyExc_TypeError,
3400 "spawnvp() arg 2 must be a tuple or list");
3401 PyMem_Free(path);
3402 return NULL;
3405 argvlist = PyMem_NEW(char *, argc+1);
3406 if (argvlist == NULL) {
3407 PyMem_Free(path);
3408 return PyErr_NoMemory();
3410 for (i = 0; i < argc; i++) {
3411 if (!PyArg_Parse((*getitem)(argv, i), "et",
3412 Py_FileSystemDefaultEncoding,
3413 &argvlist[i])) {
3414 free_string_array(argvlist, i);
3415 PyErr_SetString(
3416 PyExc_TypeError,
3417 "spawnvp() arg 2 must contain only strings");
3418 PyMem_Free(path);
3419 return NULL;
3422 argvlist[argc] = NULL;
3424 Py_BEGIN_ALLOW_THREADS
3425 #if defined(PYCC_GCC)
3426 spawnval = spawnvp(mode, path, argvlist);
3427 #else
3428 spawnval = _spawnvp(mode, path, argvlist);
3429 #endif
3430 Py_END_ALLOW_THREADS
3432 free_string_array(argvlist, argc);
3433 PyMem_Free(path);
3435 if (spawnval == -1)
3436 return posix_error();
3437 else
3438 return Py_BuildValue("l", (long) spawnval);
3442 PyDoc_STRVAR(posix_spawnvpe__doc__,
3443 "spawnvpe(mode, file, args, env)\n\n\
3444 Execute the program 'file' in a new process, using the environment\n\
3445 search path to find the file.\n\
3447 mode: mode of process creation\n\
3448 file: executable file name\n\
3449 args: tuple or list of arguments\n\
3450 env: dictionary of strings mapping to strings");
3452 static PyObject *
3453 posix_spawnvpe(PyObject *self, PyObject *args)
3455 char *path;
3456 PyObject *argv, *env;
3457 char **argvlist;
3458 char **envlist;
3459 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3460 int mode, i, pos, argc, envc;
3461 Py_intptr_t spawnval;
3462 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3463 int lastarg = 0;
3465 /* spawnvpe has four arguments: (mode, path, argv, env), where
3466 argv is a list or tuple of strings and env is a dictionary
3467 like posix.environ. */
3469 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
3470 Py_FileSystemDefaultEncoding,
3471 &path, &argv, &env))
3472 return NULL;
3473 if (PyList_Check(argv)) {
3474 argc = PyList_Size(argv);
3475 getitem = PyList_GetItem;
3477 else if (PyTuple_Check(argv)) {
3478 argc = PyTuple_Size(argv);
3479 getitem = PyTuple_GetItem;
3481 else {
3482 PyErr_SetString(PyExc_TypeError,
3483 "spawnvpe() arg 2 must be a tuple or list");
3484 goto fail_0;
3486 if (!PyMapping_Check(env)) {
3487 PyErr_SetString(PyExc_TypeError,
3488 "spawnvpe() arg 3 must be a mapping object");
3489 goto fail_0;
3492 argvlist = PyMem_NEW(char *, argc+1);
3493 if (argvlist == NULL) {
3494 PyErr_NoMemory();
3495 goto fail_0;
3497 for (i = 0; i < argc; i++) {
3498 if (!PyArg_Parse((*getitem)(argv, i),
3499 "et;spawnvpe() arg 2 must contain only strings",
3500 Py_FileSystemDefaultEncoding,
3501 &argvlist[i]))
3503 lastarg = i;
3504 goto fail_1;
3507 lastarg = argc;
3508 argvlist[argc] = NULL;
3510 i = PyMapping_Size(env);
3511 if (i < 0)
3512 goto fail_1;
3513 envlist = PyMem_NEW(char *, i + 1);
3514 if (envlist == NULL) {
3515 PyErr_NoMemory();
3516 goto fail_1;
3518 envc = 0;
3519 keys = PyMapping_Keys(env);
3520 vals = PyMapping_Values(env);
3521 if (!keys || !vals)
3522 goto fail_2;
3523 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3524 PyErr_SetString(PyExc_TypeError,
3525 "spawnvpe(): env.keys() or env.values() is not a list");
3526 goto fail_2;
3529 for (pos = 0; pos < i; pos++) {
3530 char *p, *k, *v;
3531 size_t len;
3533 key = PyList_GetItem(keys, pos);
3534 val = PyList_GetItem(vals, pos);
3535 if (!key || !val)
3536 goto fail_2;
3538 if (!PyArg_Parse(
3539 key,
3540 "s;spawnvpe() arg 3 contains a non-string key",
3541 &k) ||
3542 !PyArg_Parse(
3543 val,
3544 "s;spawnvpe() arg 3 contains a non-string value",
3545 &v))
3547 goto fail_2;
3549 len = PyString_Size(key) + PyString_Size(val) + 2;
3550 p = PyMem_NEW(char, len);
3551 if (p == NULL) {
3552 PyErr_NoMemory();
3553 goto fail_2;
3555 PyOS_snprintf(p, len, "%s=%s", k, v);
3556 envlist[envc++] = p;
3558 envlist[envc] = 0;
3560 Py_BEGIN_ALLOW_THREADS
3561 #if defined(PYCC_GCC)
3562 spawnval = spawnvpe(mode, path, argvlist, envlist);
3563 #else
3564 spawnval = _spawnvpe(mode, path, argvlist, envlist);
3565 #endif
3566 Py_END_ALLOW_THREADS
3568 if (spawnval == -1)
3569 (void) posix_error();
3570 else
3571 res = Py_BuildValue("l", (long) spawnval);
3573 fail_2:
3574 while (--envc >= 0)
3575 PyMem_DEL(envlist[envc]);
3576 PyMem_DEL(envlist);
3577 fail_1:
3578 free_string_array(argvlist, lastarg);
3579 Py_XDECREF(vals);
3580 Py_XDECREF(keys);
3581 fail_0:
3582 PyMem_Free(path);
3583 return res;
3585 #endif /* PYOS_OS2 */
3586 #endif /* HAVE_SPAWNV */
3589 #ifdef HAVE_FORK1
3590 PyDoc_STRVAR(posix_fork1__doc__,
3591 "fork1() -> pid\n\n\
3592 Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3594 Return 0 to child process and PID of child to parent process.");
3596 static PyObject *
3597 posix_fork1(PyObject *self, PyObject *noargs)
3599 pid_t pid = fork1();
3600 if (pid == -1)
3601 return posix_error();
3602 if (pid == 0)
3603 PyOS_AfterFork();
3604 return PyInt_FromLong(pid);
3606 #endif
3609 #ifdef HAVE_FORK
3610 PyDoc_STRVAR(posix_fork__doc__,
3611 "fork() -> pid\n\n\
3612 Fork a child process.\n\
3613 Return 0 to child process and PID of child to parent process.");
3615 static PyObject *
3616 posix_fork(PyObject *self, PyObject *noargs)
3618 pid_t pid = fork();
3619 if (pid == -1)
3620 return posix_error();
3621 if (pid == 0)
3622 PyOS_AfterFork();
3623 return PyInt_FromLong(pid);
3625 #endif
3627 /* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
3628 /* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3629 #if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
3630 #define DEV_PTY_FILE "/dev/ptc"
3631 #define HAVE_DEV_PTMX
3632 #else
3633 #define DEV_PTY_FILE "/dev/ptmx"
3634 #endif
3636 #if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
3637 #ifdef HAVE_PTY_H
3638 #include <pty.h>
3639 #else
3640 #ifdef HAVE_LIBUTIL_H
3641 #include <libutil.h>
3642 #endif /* HAVE_LIBUTIL_H */
3643 #endif /* HAVE_PTY_H */
3644 #ifdef HAVE_STROPTS_H
3645 #include <stropts.h>
3646 #endif
3647 #endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
3649 #if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
3650 PyDoc_STRVAR(posix_openpty__doc__,
3651 "openpty() -> (master_fd, slave_fd)\n\n\
3652 Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
3654 static PyObject *
3655 posix_openpty(PyObject *self, PyObject *noargs)
3657 int master_fd, slave_fd;
3658 #ifndef HAVE_OPENPTY
3659 char * slave_name;
3660 #endif
3661 #if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
3662 PyOS_sighandler_t sig_saved;
3663 #ifdef sun
3664 extern char *ptsname(int fildes);
3665 #endif
3666 #endif
3668 #ifdef HAVE_OPENPTY
3669 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
3670 return posix_error();
3671 #elif defined(HAVE__GETPTY)
3672 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
3673 if (slave_name == NULL)
3674 return posix_error();
3676 slave_fd = open(slave_name, O_RDWR);
3677 if (slave_fd < 0)
3678 return posix_error();
3679 #else
3680 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
3681 if (master_fd < 0)
3682 return posix_error();
3683 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
3684 /* change permission of slave */
3685 if (grantpt(master_fd) < 0) {
3686 PyOS_setsig(SIGCHLD, sig_saved);
3687 return posix_error();
3689 /* unlock slave */
3690 if (unlockpt(master_fd) < 0) {
3691 PyOS_setsig(SIGCHLD, sig_saved);
3692 return posix_error();
3694 PyOS_setsig(SIGCHLD, sig_saved);
3695 slave_name = ptsname(master_fd); /* get name of slave */
3696 if (slave_name == NULL)
3697 return posix_error();
3698 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
3699 if (slave_fd < 0)
3700 return posix_error();
3701 #if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
3702 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
3703 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
3704 #ifndef __hpux
3705 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
3706 #endif /* __hpux */
3707 #endif /* HAVE_CYGWIN */
3708 #endif /* HAVE_OPENPTY */
3710 return Py_BuildValue("(ii)", master_fd, slave_fd);
3713 #endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
3715 #ifdef HAVE_FORKPTY
3716 PyDoc_STRVAR(posix_forkpty__doc__,
3717 "forkpty() -> (pid, master_fd)\n\n\
3718 Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
3719 Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
3720 To both, return fd of newly opened pseudo-terminal.\n");
3722 static PyObject *
3723 posix_forkpty(PyObject *self, PyObject *noargs)
3725 int master_fd = -1;
3726 pid_t pid;
3728 pid = forkpty(&master_fd, NULL, NULL, NULL);
3729 if (pid == -1)
3730 return posix_error();
3731 if (pid == 0)
3732 PyOS_AfterFork();
3733 return Py_BuildValue("(li)", pid, master_fd);
3735 #endif
3737 #ifdef HAVE_GETEGID
3738 PyDoc_STRVAR(posix_getegid__doc__,
3739 "getegid() -> egid\n\n\
3740 Return the current process's effective group id.");
3742 static PyObject *
3743 posix_getegid(PyObject *self, PyObject *noargs)
3745 return PyInt_FromLong((long)getegid());
3747 #endif
3750 #ifdef HAVE_GETEUID
3751 PyDoc_STRVAR(posix_geteuid__doc__,
3752 "geteuid() -> euid\n\n\
3753 Return the current process's effective user id.");
3755 static PyObject *
3756 posix_geteuid(PyObject *self, PyObject *noargs)
3758 return PyInt_FromLong((long)geteuid());
3760 #endif
3763 #ifdef HAVE_GETGID
3764 PyDoc_STRVAR(posix_getgid__doc__,
3765 "getgid() -> gid\n\n\
3766 Return the current process's group id.");
3768 static PyObject *
3769 posix_getgid(PyObject *self, PyObject *noargs)
3771 return PyInt_FromLong((long)getgid());
3773 #endif
3776 PyDoc_STRVAR(posix_getpid__doc__,
3777 "getpid() -> pid\n\n\
3778 Return the current process id");
3780 static PyObject *
3781 posix_getpid(PyObject *self, PyObject *noargs)
3783 return PyInt_FromLong((long)getpid());
3787 #ifdef HAVE_GETGROUPS
3788 PyDoc_STRVAR(posix_getgroups__doc__,
3789 "getgroups() -> list of group IDs\n\n\
3790 Return list of supplemental group IDs for the process.");
3792 static PyObject *
3793 posix_getgroups(PyObject *self, PyObject *noargs)
3795 PyObject *result = NULL;
3797 #ifdef NGROUPS_MAX
3798 #define MAX_GROUPS NGROUPS_MAX
3799 #else
3800 /* defined to be 16 on Solaris7, so this should be a small number */
3801 #define MAX_GROUPS 64
3802 #endif
3803 gid_t grouplist[MAX_GROUPS];
3804 int n;
3806 n = getgroups(MAX_GROUPS, grouplist);
3807 if (n < 0)
3808 posix_error();
3809 else {
3810 result = PyList_New(n);
3811 if (result != NULL) {
3812 int i;
3813 for (i = 0; i < n; ++i) {
3814 PyObject *o = PyInt_FromLong((long)grouplist[i]);
3815 if (o == NULL) {
3816 Py_DECREF(result);
3817 result = NULL;
3818 break;
3820 PyList_SET_ITEM(result, i, o);
3825 return result;
3827 #endif
3829 #ifdef HAVE_GETPGID
3830 PyDoc_STRVAR(posix_getpgid__doc__,
3831 "getpgid(pid) -> pgid\n\n\
3832 Call the system call getpgid().");
3834 static PyObject *
3835 posix_getpgid(PyObject *self, PyObject *args)
3837 int pid, pgid;
3838 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
3839 return NULL;
3840 pgid = getpgid(pid);
3841 if (pgid < 0)
3842 return posix_error();
3843 return PyInt_FromLong((long)pgid);
3845 #endif /* HAVE_GETPGID */
3848 #ifdef HAVE_GETPGRP
3849 PyDoc_STRVAR(posix_getpgrp__doc__,
3850 "getpgrp() -> pgrp\n\n\
3851 Return the current process group id.");
3853 static PyObject *
3854 posix_getpgrp(PyObject *self, PyObject *noargs)
3856 #ifdef GETPGRP_HAVE_ARG
3857 return PyInt_FromLong((long)getpgrp(0));
3858 #else /* GETPGRP_HAVE_ARG */
3859 return PyInt_FromLong((long)getpgrp());
3860 #endif /* GETPGRP_HAVE_ARG */
3862 #endif /* HAVE_GETPGRP */
3865 #ifdef HAVE_SETPGRP
3866 PyDoc_STRVAR(posix_setpgrp__doc__,
3867 "setpgrp()\n\n\
3868 Make this process a session leader.");
3870 static PyObject *
3871 posix_setpgrp(PyObject *self, PyObject *noargs)
3873 #ifdef SETPGRP_HAVE_ARG
3874 if (setpgrp(0, 0) < 0)
3875 #else /* SETPGRP_HAVE_ARG */
3876 if (setpgrp() < 0)
3877 #endif /* SETPGRP_HAVE_ARG */
3878 return posix_error();
3879 Py_INCREF(Py_None);
3880 return Py_None;
3883 #endif /* HAVE_SETPGRP */
3885 #ifdef HAVE_GETPPID
3886 PyDoc_STRVAR(posix_getppid__doc__,
3887 "getppid() -> ppid\n\n\
3888 Return the parent's process id.");
3890 static PyObject *
3891 posix_getppid(PyObject *self, PyObject *noargs)
3893 return PyInt_FromLong(getppid());
3895 #endif
3898 #ifdef HAVE_GETLOGIN
3899 PyDoc_STRVAR(posix_getlogin__doc__,
3900 "getlogin() -> string\n\n\
3901 Return the actual login name.");
3903 static PyObject *
3904 posix_getlogin(PyObject *self, PyObject *noargs)
3906 PyObject *result = NULL;
3907 char *name;
3908 int old_errno = errno;
3910 errno = 0;
3911 name = getlogin();
3912 if (name == NULL) {
3913 if (errno)
3914 posix_error();
3915 else
3916 PyErr_SetString(PyExc_OSError,
3917 "unable to determine login name");
3919 else
3920 result = PyString_FromString(name);
3921 errno = old_errno;
3923 return result;
3925 #endif
3927 #ifdef HAVE_GETUID
3928 PyDoc_STRVAR(posix_getuid__doc__,
3929 "getuid() -> uid\n\n\
3930 Return the current process's user id.");
3932 static PyObject *
3933 posix_getuid(PyObject *self, PyObject *noargs)
3935 return PyInt_FromLong((long)getuid());
3937 #endif
3940 #ifdef HAVE_KILL
3941 PyDoc_STRVAR(posix_kill__doc__,
3942 "kill(pid, sig)\n\n\
3943 Kill a process with a signal.");
3945 static PyObject *
3946 posix_kill(PyObject *self, PyObject *args)
3948 pid_t pid;
3949 int sig;
3950 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
3951 return NULL;
3952 #if defined(PYOS_OS2) && !defined(PYCC_GCC)
3953 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
3954 APIRET rc;
3955 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
3956 return os2_error(rc);
3958 } else if (sig == XCPT_SIGNAL_KILLPROC) {
3959 APIRET rc;
3960 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
3961 return os2_error(rc);
3963 } else
3964 return NULL; /* Unrecognized Signal Requested */
3965 #else
3966 if (kill(pid, sig) == -1)
3967 return posix_error();
3968 #endif
3969 Py_INCREF(Py_None);
3970 return Py_None;
3972 #endif
3974 #ifdef HAVE_KILLPG
3975 PyDoc_STRVAR(posix_killpg__doc__,
3976 "killpg(pgid, sig)\n\n\
3977 Kill a process group with a signal.");
3979 static PyObject *
3980 posix_killpg(PyObject *self, PyObject *args)
3982 int pgid, sig;
3983 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
3984 return NULL;
3985 if (killpg(pgid, sig) == -1)
3986 return posix_error();
3987 Py_INCREF(Py_None);
3988 return Py_None;
3990 #endif
3992 #ifdef HAVE_PLOCK
3994 #ifdef HAVE_SYS_LOCK_H
3995 #include <sys/lock.h>
3996 #endif
3998 PyDoc_STRVAR(posix_plock__doc__,
3999 "plock(op)\n\n\
4000 Lock program segments into memory.");
4002 static PyObject *
4003 posix_plock(PyObject *self, PyObject *args)
4005 int op;
4006 if (!PyArg_ParseTuple(args, "i:plock", &op))
4007 return NULL;
4008 if (plock(op) == -1)
4009 return posix_error();
4010 Py_INCREF(Py_None);
4011 return Py_None;
4013 #endif
4016 #ifdef HAVE_POPEN
4017 PyDoc_STRVAR(posix_popen__doc__,
4018 "popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
4019 Open a pipe to/from a command returning a file object.");
4021 #if defined(PYOS_OS2)
4022 #if defined(PYCC_VACPP)
4023 static int
4024 async_system(const char *command)
4026 char errormsg[256], args[1024];
4027 RESULTCODES rcodes;
4028 APIRET rc;
4030 char *shell = getenv("COMSPEC");
4031 if (!shell)
4032 shell = "cmd";
4034 /* avoid overflowing the argument buffer */
4035 if (strlen(shell) + 3 + strlen(command) >= 1024)
4036 return ERROR_NOT_ENOUGH_MEMORY
4038 args[0] = '\0';
4039 strcat(args, shell);
4040 strcat(args, "/c ");
4041 strcat(args, command);
4043 /* execute asynchronously, inheriting the environment */
4044 rc = DosExecPgm(errormsg,
4045 sizeof(errormsg),
4046 EXEC_ASYNC,
4047 args,
4048 NULL,
4049 &rcodes,
4050 shell);
4051 return rc;
4054 static FILE *
4055 popen(const char *command, const char *mode, int pipesize, int *err)
4057 int oldfd, tgtfd;
4058 HFILE pipeh[2];
4059 APIRET rc;
4061 /* mode determines which of stdin or stdout is reconnected to
4062 * the pipe to the child
4064 if (strchr(mode, 'r') != NULL) {
4065 tgt_fd = 1; /* stdout */
4066 } else if (strchr(mode, 'w')) {
4067 tgt_fd = 0; /* stdin */
4068 } else {
4069 *err = ERROR_INVALID_ACCESS;
4070 return NULL;
4073 /* setup the pipe */
4074 if ((rc = DosCreatePipe(&pipeh[0], &pipeh[1], pipesize)) != NO_ERROR) {
4075 *err = rc;
4076 return NULL;
4079 /* prevent other threads accessing stdio */
4080 DosEnterCritSec();
4082 /* reconnect stdio and execute child */
4083 oldfd = dup(tgtfd);
4084 close(tgtfd);
4085 if (dup2(pipeh[tgtfd], tgtfd) == 0) {
4086 DosClose(pipeh[tgtfd]);
4087 rc = async_system(command);
4090 /* restore stdio */
4091 dup2(oldfd, tgtfd);
4092 close(oldfd);
4094 /* allow other threads access to stdio */
4095 DosExitCritSec();
4097 /* if execution of child was successful return file stream */
4098 if (rc == NO_ERROR)
4099 return fdopen(pipeh[1 - tgtfd], mode);
4100 else {
4101 DosClose(pipeh[1 - tgtfd]);
4102 *err = rc;
4103 return NULL;
4107 static PyObject *
4108 posix_popen(PyObject *self, PyObject *args)
4110 char *name;
4111 char *mode = "r";
4112 int err, bufsize = -1;
4113 FILE *fp;
4114 PyObject *f;
4115 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
4116 return NULL;
4117 Py_BEGIN_ALLOW_THREADS
4118 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
4119 Py_END_ALLOW_THREADS
4120 if (fp == NULL)
4121 return os2_error(err);
4123 f = PyFile_FromFile(fp, name, mode, fclose);
4124 if (f != NULL)
4125 PyFile_SetBufSize(f, bufsize);
4126 return f;
4129 #elif defined(PYCC_GCC)
4131 /* standard posix version of popen() support */
4132 static PyObject *
4133 posix_popen(PyObject *self, PyObject *args)
4135 char *name;
4136 char *mode = "r";
4137 int bufsize = -1;
4138 FILE *fp;
4139 PyObject *f;
4140 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
4141 return NULL;
4142 Py_BEGIN_ALLOW_THREADS
4143 fp = popen(name, mode);
4144 Py_END_ALLOW_THREADS
4145 if (fp == NULL)
4146 return posix_error();
4147 f = PyFile_FromFile(fp, name, mode, pclose);
4148 if (f != NULL)
4149 PyFile_SetBufSize(f, bufsize);
4150 return f;
4153 /* fork() under OS/2 has lots'o'warts
4154 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
4155 * most of this code is a ripoff of the win32 code, but using the
4156 * capabilities of EMX's C library routines
4159 /* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
4160 #define POPEN_1 1
4161 #define POPEN_2 2
4162 #define POPEN_3 3
4163 #define POPEN_4 4
4165 static PyObject *_PyPopen(char *, int, int, int);
4166 static int _PyPclose(FILE *file);
4169 * Internal dictionary mapping popen* file pointers to process handles,
4170 * for use when retrieving the process exit code. See _PyPclose() below
4171 * for more information on this dictionary's use.
4173 static PyObject *_PyPopenProcs = NULL;
4175 /* os2emx version of popen2()
4177 * The result of this function is a pipe (file) connected to the
4178 * process's stdin, and a pipe connected to the process's stdout.
4181 static PyObject *
4182 os2emx_popen2(PyObject *self, PyObject *args)
4184 PyObject *f;
4185 int tm=0;
4187 char *cmdstring;
4188 char *mode = "t";
4189 int bufsize = -1;
4190 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
4191 return NULL;
4193 if (*mode == 't')
4194 tm = O_TEXT;
4195 else if (*mode != 'b') {
4196 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4197 return NULL;
4198 } else
4199 tm = O_BINARY;
4201 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
4203 return f;
4207 * Variation on os2emx.popen2
4209 * The result of this function is 3 pipes - the process's stdin,
4210 * stdout and stderr
4213 static PyObject *
4214 os2emx_popen3(PyObject *self, PyObject *args)
4216 PyObject *f;
4217 int tm = 0;
4219 char *cmdstring;
4220 char *mode = "t";
4221 int bufsize = -1;
4222 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
4223 return NULL;
4225 if (*mode == 't')
4226 tm = O_TEXT;
4227 else if (*mode != 'b') {
4228 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4229 return NULL;
4230 } else
4231 tm = O_BINARY;
4233 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
4235 return f;
4239 * Variation on os2emx.popen2
4241 * The result of this function is 2 pipes - the processes stdin,
4242 * and stdout+stderr combined as a single pipe.
4245 static PyObject *
4246 os2emx_popen4(PyObject *self, PyObject *args)
4248 PyObject *f;
4249 int tm = 0;
4251 char *cmdstring;
4252 char *mode = "t";
4253 int bufsize = -1;
4254 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
4255 return NULL;
4257 if (*mode == 't')
4258 tm = O_TEXT;
4259 else if (*mode != 'b') {
4260 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4261 return NULL;
4262 } else
4263 tm = O_BINARY;
4265 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
4267 return f;
4270 /* a couple of structures for convenient handling of multiple
4271 * file handles and pipes
4273 struct file_ref
4275 int handle;
4276 int flags;
4279 struct pipe_ref
4281 int rd;
4282 int wr;
4285 /* The following code is derived from the win32 code */
4287 static PyObject *
4288 _PyPopen(char *cmdstring, int mode, int n, int bufsize)
4290 struct file_ref stdio[3];
4291 struct pipe_ref p_fd[3];
4292 FILE *p_s[3];
4293 int file_count, i, pipe_err;
4294 pid_t pipe_pid;
4295 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
4296 PyObject *f, *p_f[3];
4298 /* file modes for subsequent fdopen's on pipe handles */
4299 if (mode == O_TEXT)
4301 rd_mode = "rt";
4302 wr_mode = "wt";
4304 else
4306 rd_mode = "rb";
4307 wr_mode = "wb";
4310 /* prepare shell references */
4311 if ((shell = getenv("EMXSHELL")) == NULL)
4312 if ((shell = getenv("COMSPEC")) == NULL)
4314 errno = ENOENT;
4315 return posix_error();
4318 sh_name = _getname(shell);
4319 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
4320 opt = "/c";
4321 else
4322 opt = "-c";
4324 /* save current stdio fds + their flags, and set not inheritable */
4325 i = pipe_err = 0;
4326 while (pipe_err >= 0 && i < 3)
4328 pipe_err = stdio[i].handle = dup(i);
4329 stdio[i].flags = fcntl(i, F_GETFD, 0);
4330 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
4331 i++;
4333 if (pipe_err < 0)
4335 /* didn't get them all saved - clean up and bail out */
4336 int saved_err = errno;
4337 while (i-- > 0)
4339 close(stdio[i].handle);
4341 errno = saved_err;
4342 return posix_error();
4345 /* create pipe ends */
4346 file_count = 2;
4347 if (n == POPEN_3)
4348 file_count = 3;
4349 i = pipe_err = 0;
4350 while ((pipe_err == 0) && (i < file_count))
4351 pipe_err = pipe((int *)&p_fd[i++]);
4352 if (pipe_err < 0)
4354 /* didn't get them all made - clean up and bail out */
4355 while (i-- > 0)
4357 close(p_fd[i].wr);
4358 close(p_fd[i].rd);
4360 errno = EPIPE;
4361 return posix_error();
4364 /* change the actual standard IO streams over temporarily,
4365 * making the retained pipe ends non-inheritable
4367 pipe_err = 0;
4369 /* - stdin */
4370 if (dup2(p_fd[0].rd, 0) == 0)
4372 close(p_fd[0].rd);
4373 i = fcntl(p_fd[0].wr, F_GETFD, 0);
4374 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
4375 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
4377 close(p_fd[0].wr);
4378 pipe_err = -1;
4381 else
4383 pipe_err = -1;
4386 /* - stdout */
4387 if (pipe_err == 0)
4389 if (dup2(p_fd[1].wr, 1) == 1)
4391 close(p_fd[1].wr);
4392 i = fcntl(p_fd[1].rd, F_GETFD, 0);
4393 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
4394 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
4396 close(p_fd[1].rd);
4397 pipe_err = -1;
4400 else
4402 pipe_err = -1;
4406 /* - stderr, as required */
4407 if (pipe_err == 0)
4408 switch (n)
4410 case POPEN_3:
4412 if (dup2(p_fd[2].wr, 2) == 2)
4414 close(p_fd[2].wr);
4415 i = fcntl(p_fd[2].rd, F_GETFD, 0);
4416 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
4417 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
4419 close(p_fd[2].rd);
4420 pipe_err = -1;
4423 else
4425 pipe_err = -1;
4427 break;
4430 case POPEN_4:
4432 if (dup2(1, 2) != 2)
4434 pipe_err = -1;
4436 break;
4440 /* spawn the child process */
4441 if (pipe_err == 0)
4443 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
4444 if (pipe_pid == -1)
4446 pipe_err = -1;
4448 else
4450 /* save the PID into the FILE structure
4451 * NOTE: this implementation doesn't actually
4452 * take advantage of this, but do it for
4453 * completeness - AIM Apr01
4455 for (i = 0; i < file_count; i++)
4456 p_s[i]->_pid = pipe_pid;
4460 /* reset standard IO to normal */
4461 for (i = 0; i < 3; i++)
4463 dup2(stdio[i].handle, i);
4464 fcntl(i, F_SETFD, stdio[i].flags);
4465 close(stdio[i].handle);
4468 /* if any remnant problems, clean up and bail out */
4469 if (pipe_err < 0)
4471 for (i = 0; i < 3; i++)
4473 close(p_fd[i].rd);
4474 close(p_fd[i].wr);
4476 errno = EPIPE;
4477 return posix_error_with_filename(cmdstring);
4480 /* build tuple of file objects to return */
4481 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
4482 PyFile_SetBufSize(p_f[0], bufsize);
4483 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
4484 PyFile_SetBufSize(p_f[1], bufsize);
4485 if (n == POPEN_3)
4487 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
4488 PyFile_SetBufSize(p_f[0], bufsize);
4489 f = PyTuple_Pack(3, p_f[0], p_f[1], p_f[2]);
4491 else
4492 f = PyTuple_Pack(2, p_f[0], p_f[1]);
4495 * Insert the files we've created into the process dictionary
4496 * all referencing the list with the process handle and the
4497 * initial number of files (see description below in _PyPclose).
4498 * Since if _PyPclose later tried to wait on a process when all
4499 * handles weren't closed, it could create a deadlock with the
4500 * child, we spend some energy here to try to ensure that we
4501 * either insert all file handles into the dictionary or none
4502 * at all. It's a little clumsy with the various popen modes
4503 * and variable number of files involved.
4505 if (!_PyPopenProcs)
4507 _PyPopenProcs = PyDict_New();
4510 if (_PyPopenProcs)
4512 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
4513 int ins_rc[3];
4515 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4516 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4518 procObj = PyList_New(2);
4519 pidObj = PyInt_FromLong((long) pipe_pid);
4520 intObj = PyInt_FromLong((long) file_count);
4522 if (procObj && pidObj && intObj)
4524 PyList_SetItem(procObj, 0, pidObj);
4525 PyList_SetItem(procObj, 1, intObj);
4527 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
4528 if (fileObj[0])
4530 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4531 fileObj[0],
4532 procObj);
4534 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
4535 if (fileObj[1])
4537 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4538 fileObj[1],
4539 procObj);
4541 if (file_count >= 3)
4543 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
4544 if (fileObj[2])
4546 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4547 fileObj[2],
4548 procObj);
4552 if (ins_rc[0] < 0 || !fileObj[0] ||
4553 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4554 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
4556 /* Something failed - remove any dictionary
4557 * entries that did make it.
4559 if (!ins_rc[0] && fileObj[0])
4561 PyDict_DelItem(_PyPopenProcs,
4562 fileObj[0]);
4564 if (!ins_rc[1] && fileObj[1])
4566 PyDict_DelItem(_PyPopenProcs,
4567 fileObj[1]);
4569 if (!ins_rc[2] && fileObj[2])
4571 PyDict_DelItem(_PyPopenProcs,
4572 fileObj[2]);
4578 * Clean up our localized references for the dictionary keys
4579 * and value since PyDict_SetItem will Py_INCREF any copies
4580 * that got placed in the dictionary.
4582 Py_XDECREF(procObj);
4583 Py_XDECREF(fileObj[0]);
4584 Py_XDECREF(fileObj[1]);
4585 Py_XDECREF(fileObj[2]);
4588 /* Child is launched. */
4589 return f;
4593 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4594 * exit code for the child process and return as a result of the close.
4596 * This function uses the _PyPopenProcs dictionary in order to map the
4597 * input file pointer to information about the process that was
4598 * originally created by the popen* call that created the file pointer.
4599 * The dictionary uses the file pointer as a key (with one entry
4600 * inserted for each file returned by the original popen* call) and a
4601 * single list object as the value for all files from a single call.
4602 * The list object contains the Win32 process handle at [0], and a file
4603 * count at [1], which is initialized to the total number of file
4604 * handles using that list.
4606 * This function closes whichever handle it is passed, and decrements
4607 * the file count in the dictionary for the process handle pointed to
4608 * by this file. On the last close (when the file count reaches zero),
4609 * this function will wait for the child process and then return its
4610 * exit code as the result of the close() operation. This permits the
4611 * files to be closed in any order - it is always the close() of the
4612 * final handle that will return the exit code.
4614 * NOTE: This function is currently called with the GIL released.
4615 * hence we use the GILState API to manage our state.
4618 static int _PyPclose(FILE *file)
4620 int result;
4621 int exit_code;
4622 pid_t pipe_pid;
4623 PyObject *procObj, *pidObj, *intObj, *fileObj;
4624 int file_count;
4625 #ifdef WITH_THREAD
4626 PyGILState_STATE state;
4627 #endif
4629 /* Close the file handle first, to ensure it can't block the
4630 * child from exiting if it's the last handle.
4632 result = fclose(file);
4634 #ifdef WITH_THREAD
4635 state = PyGILState_Ensure();
4636 #endif
4637 if (_PyPopenProcs)
4639 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4640 (procObj = PyDict_GetItem(_PyPopenProcs,
4641 fileObj)) != NULL &&
4642 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
4643 (intObj = PyList_GetItem(procObj,1)) != NULL)
4645 pipe_pid = (int) PyInt_AsLong(pidObj);
4646 file_count = (int) PyInt_AsLong(intObj);
4648 if (file_count > 1)
4650 /* Still other files referencing process */
4651 file_count--;
4652 PyList_SetItem(procObj,1,
4653 PyInt_FromLong((long) file_count));
4655 else
4657 /* Last file for this process */
4658 if (result != EOF &&
4659 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
4661 /* extract exit status */
4662 if (WIFEXITED(exit_code))
4664 result = WEXITSTATUS(exit_code);
4666 else
4668 errno = EPIPE;
4669 result = -1;
4672 else
4674 /* Indicate failure - this will cause the file object
4675 * to raise an I/O error and translate the last
4676 * error code from errno. We do have a problem with
4677 * last errors that overlap the normal errno table,
4678 * but that's a consistent problem with the file object.
4680 result = -1;
4684 /* Remove this file pointer from dictionary */
4685 PyDict_DelItem(_PyPopenProcs, fileObj);
4687 if (PyDict_Size(_PyPopenProcs) == 0)
4689 Py_DECREF(_PyPopenProcs);
4690 _PyPopenProcs = NULL;
4693 } /* if object retrieval ok */
4695 Py_XDECREF(fileObj);
4696 } /* if _PyPopenProcs */
4698 #ifdef WITH_THREAD
4699 PyGILState_Release(state);
4700 #endif
4701 return result;
4704 #endif /* PYCC_??? */
4706 #elif defined(MS_WINDOWS)
4709 * Portable 'popen' replacement for Win32.
4711 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
4712 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
4713 * Return code handling by David Bolen <db3l@fitlinxx.com>.
4716 #include <malloc.h>
4717 #include <io.h>
4718 #include <fcntl.h>
4720 /* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
4721 #define POPEN_1 1
4722 #define POPEN_2 2
4723 #define POPEN_3 3
4724 #define POPEN_4 4
4726 static PyObject *_PyPopen(char *, int, int);
4727 static int _PyPclose(FILE *file);
4730 * Internal dictionary mapping popen* file pointers to process handles,
4731 * for use when retrieving the process exit code. See _PyPclose() below
4732 * for more information on this dictionary's use.
4734 static PyObject *_PyPopenProcs = NULL;
4737 /* popen that works from a GUI.
4739 * The result of this function is a pipe (file) connected to the
4740 * processes stdin or stdout, depending on the requested mode.
4743 static PyObject *
4744 posix_popen(PyObject *self, PyObject *args)
4746 PyObject *f;
4747 int tm = 0;
4749 char *cmdstring;
4750 char *mode = "r";
4751 int bufsize = -1;
4752 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
4753 return NULL;
4755 if (*mode == 'r')
4756 tm = _O_RDONLY;
4757 else if (*mode != 'w') {
4758 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
4759 return NULL;
4760 } else
4761 tm = _O_WRONLY;
4763 if (bufsize != -1) {
4764 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
4765 return NULL;
4768 if (*(mode+1) == 't')
4769 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
4770 else if (*(mode+1) == 'b')
4771 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
4772 else
4773 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
4775 return f;
4778 /* Variation on win32pipe.popen
4780 * The result of this function is a pipe (file) connected to the
4781 * process's stdin, and a pipe connected to the process's stdout.
4784 static PyObject *
4785 win32_popen2(PyObject *self, PyObject *args)
4787 PyObject *f;
4788 int tm=0;
4790 char *cmdstring;
4791 char *mode = "t";
4792 int bufsize = -1;
4793 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
4794 return NULL;
4796 if (*mode == 't')
4797 tm = _O_TEXT;
4798 else if (*mode != 'b') {
4799 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
4800 return NULL;
4801 } else
4802 tm = _O_BINARY;
4804 if (bufsize != -1) {
4805 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
4806 return NULL;
4809 f = _PyPopen(cmdstring, tm, POPEN_2);
4811 return f;
4815 * Variation on <om win32pipe.popen>
4817 * The result of this function is 3 pipes - the process's stdin,
4818 * stdout and stderr
4821 static PyObject *
4822 win32_popen3(PyObject *self, PyObject *args)
4824 PyObject *f;
4825 int tm = 0;
4827 char *cmdstring;
4828 char *mode = "t";
4829 int bufsize = -1;
4830 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
4831 return NULL;
4833 if (*mode == 't')
4834 tm = _O_TEXT;
4835 else if (*mode != 'b') {
4836 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
4837 return NULL;
4838 } else
4839 tm = _O_BINARY;
4841 if (bufsize != -1) {
4842 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
4843 return NULL;
4846 f = _PyPopen(cmdstring, tm, POPEN_3);
4848 return f;
4852 * Variation on win32pipe.popen
4854 * The result of this function is 2 pipes - the processes stdin,
4855 * and stdout+stderr combined as a single pipe.
4858 static PyObject *
4859 win32_popen4(PyObject *self, PyObject *args)
4861 PyObject *f;
4862 int tm = 0;
4864 char *cmdstring;
4865 char *mode = "t";
4866 int bufsize = -1;
4867 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
4868 return NULL;
4870 if (*mode == 't')
4871 tm = _O_TEXT;
4872 else if (*mode != 'b') {
4873 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
4874 return NULL;
4875 } else
4876 tm = _O_BINARY;
4878 if (bufsize != -1) {
4879 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
4880 return NULL;
4883 f = _PyPopen(cmdstring, tm, POPEN_4);
4885 return f;
4888 static BOOL
4889 _PyPopenCreateProcess(char *cmdstring,
4890 HANDLE hStdin,
4891 HANDLE hStdout,
4892 HANDLE hStderr,
4893 HANDLE *hProcess)
4895 PROCESS_INFORMATION piProcInfo;
4896 STARTUPINFO siStartInfo;
4897 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
4898 char *s1,*s2, *s3 = " /c ";
4899 const char *szConsoleSpawn = "w9xpopen.exe";
4900 int i;
4901 Py_ssize_t x;
4903 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
4904 char *comshell;
4906 s1 = (char *)alloca(i);
4907 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
4908 /* x < i, so x fits into an integer */
4909 return (int)x;
4911 /* Explicitly check if we are using COMMAND.COM. If we are
4912 * then use the w9xpopen hack.
4914 comshell = s1 + x;
4915 while (comshell >= s1 && *comshell != '\\')
4916 --comshell;
4917 ++comshell;
4919 if (GetVersion() < 0x80000000 &&
4920 _stricmp(comshell, "command.com") != 0) {
4921 /* NT/2000 and not using command.com. */
4922 x = i + strlen(s3) + strlen(cmdstring) + 1;
4923 s2 = (char *)alloca(x);
4924 ZeroMemory(s2, x);
4925 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
4927 else {
4929 * Oh gag, we're on Win9x or using COMMAND.COM. Use
4930 * the workaround listed in KB: Q150956
4932 char modulepath[_MAX_PATH];
4933 struct stat statinfo;
4934 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
4935 for (x = i = 0; modulepath[i]; i++)
4936 if (modulepath[i] == SEP)
4937 x = i+1;
4938 modulepath[x] = '\0';
4939 /* Create the full-name to w9xpopen, so we can test it exists */
4940 strncat(modulepath,
4941 szConsoleSpawn,
4942 (sizeof(modulepath)/sizeof(modulepath[0]))
4943 -strlen(modulepath));
4944 if (stat(modulepath, &statinfo) != 0) {
4945 size_t mplen = sizeof(modulepath)/sizeof(modulepath[0]);
4946 /* Eeek - file-not-found - possibly an embedding
4947 situation - see if we can locate it in sys.prefix
4949 strncpy(modulepath,
4950 Py_GetExecPrefix(),
4951 mplen);
4952 modulepath[mplen-1] = '\0';
4953 if (modulepath[strlen(modulepath)-1] != '\\')
4954 strcat(modulepath, "\\");
4955 strncat(modulepath,
4956 szConsoleSpawn,
4957 mplen-strlen(modulepath));
4958 /* No where else to look - raise an easily identifiable
4959 error, rather than leaving Windows to report
4960 "file not found" - as the user is probably blissfully
4961 unaware this shim EXE is used, and it will confuse them.
4962 (well, it confused me for a while ;-)
4964 if (stat(modulepath, &statinfo) != 0) {
4965 PyErr_Format(PyExc_RuntimeError,
4966 "Can not locate '%s' which is needed "
4967 "for popen to work with your shell "
4968 "or platform.",
4969 szConsoleSpawn);
4970 return FALSE;
4973 x = i + strlen(s3) + strlen(cmdstring) + 1 +
4974 strlen(modulepath) +
4975 strlen(szConsoleSpawn) + 1;
4977 s2 = (char *)alloca(x);
4978 ZeroMemory(s2, x);
4979 /* To maintain correct argument passing semantics,
4980 we pass the command-line as it stands, and allow
4981 quoting to be applied. w9xpopen.exe will then
4982 use its argv vector, and re-quote the necessary
4983 args for the ultimate child process.
4985 PyOS_snprintf(
4986 s2, x,
4987 "\"%s\" %s%s%s",
4988 modulepath,
4991 cmdstring);
4992 /* Not passing CREATE_NEW_CONSOLE has been known to
4993 cause random failures on win9x. Specifically a
4994 dialog:
4995 "Your program accessed mem currently in use at xxx"
4996 and a hopeful warning about the stability of your
4997 system.
4998 Cost is Ctrl+C wont kill children, but anyone
4999 who cares can have a go!
5001 dwProcessFlags |= CREATE_NEW_CONSOLE;
5005 /* Could be an else here to try cmd.exe / command.com in the path
5006 Now we'll just error out.. */
5007 else {
5008 PyErr_SetString(PyExc_RuntimeError,
5009 "Cannot locate a COMSPEC environment variable to "
5010 "use as the shell");
5011 return FALSE;
5014 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
5015 siStartInfo.cb = sizeof(STARTUPINFO);
5016 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
5017 siStartInfo.hStdInput = hStdin;
5018 siStartInfo.hStdOutput = hStdout;
5019 siStartInfo.hStdError = hStderr;
5020 siStartInfo.wShowWindow = SW_HIDE;
5022 if (CreateProcess(NULL,
5024 NULL,
5025 NULL,
5026 TRUE,
5027 dwProcessFlags,
5028 NULL,
5029 NULL,
5030 &siStartInfo,
5031 &piProcInfo) ) {
5032 /* Close the handles now so anyone waiting is woken. */
5033 CloseHandle(piProcInfo.hThread);
5035 /* Return process handle */
5036 *hProcess = piProcInfo.hProcess;
5037 return TRUE;
5039 win32_error("CreateProcess", s2);
5040 return FALSE;
5043 /* The following code is based off of KB: Q190351 */
5045 static PyObject *
5046 _PyPopen(char *cmdstring, int mode, int n)
5048 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
5049 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
5050 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
5052 SECURITY_ATTRIBUTES saAttr;
5053 BOOL fSuccess;
5054 int fd1, fd2, fd3;
5055 FILE *f1, *f2, *f3;
5056 long file_count;
5057 PyObject *f;
5059 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
5060 saAttr.bInheritHandle = TRUE;
5061 saAttr.lpSecurityDescriptor = NULL;
5063 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
5064 return win32_error("CreatePipe", NULL);
5066 /* Create new output read handle and the input write handle. Set
5067 * the inheritance properties to FALSE. Otherwise, the child inherits
5068 * these handles; resulting in non-closeable handles to the pipes
5069 * being created. */
5070 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
5071 GetCurrentProcess(), &hChildStdinWrDup, 0,
5072 FALSE,
5073 DUPLICATE_SAME_ACCESS);
5074 if (!fSuccess)
5075 return win32_error("DuplicateHandle", NULL);
5077 /* Close the inheritable version of ChildStdin
5078 that we're using. */
5079 CloseHandle(hChildStdinWr);
5081 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
5082 return win32_error("CreatePipe", NULL);
5084 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
5085 GetCurrentProcess(), &hChildStdoutRdDup, 0,
5086 FALSE, DUPLICATE_SAME_ACCESS);
5087 if (!fSuccess)
5088 return win32_error("DuplicateHandle", NULL);
5090 /* Close the inheritable version of ChildStdout
5091 that we're using. */
5092 CloseHandle(hChildStdoutRd);
5094 if (n != POPEN_4) {
5095 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
5096 return win32_error("CreatePipe", NULL);
5097 fSuccess = DuplicateHandle(GetCurrentProcess(),
5098 hChildStderrRd,
5099 GetCurrentProcess(),
5100 &hChildStderrRdDup, 0,
5101 FALSE, DUPLICATE_SAME_ACCESS);
5102 if (!fSuccess)
5103 return win32_error("DuplicateHandle", NULL);
5104 /* Close the inheritable version of ChildStdErr that we're using. */
5105 CloseHandle(hChildStderrRd);
5108 switch (n) {
5109 case POPEN_1:
5110 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
5111 case _O_WRONLY | _O_TEXT:
5112 /* Case for writing to child Stdin in text mode. */
5113 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5114 f1 = _fdopen(fd1, "w");
5115 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
5116 PyFile_SetBufSize(f, 0);
5117 /* We don't care about these pipes anymore, so close them. */
5118 CloseHandle(hChildStdoutRdDup);
5119 CloseHandle(hChildStderrRdDup);
5120 break;
5122 case _O_RDONLY | _O_TEXT:
5123 /* Case for reading from child Stdout in text mode. */
5124 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5125 f1 = _fdopen(fd1, "r");
5126 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
5127 PyFile_SetBufSize(f, 0);
5128 /* We don't care about these pipes anymore, so close them. */
5129 CloseHandle(hChildStdinWrDup);
5130 CloseHandle(hChildStderrRdDup);
5131 break;
5133 case _O_RDONLY | _O_BINARY:
5134 /* Case for readinig from child Stdout in binary mode. */
5135 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5136 f1 = _fdopen(fd1, "rb");
5137 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
5138 PyFile_SetBufSize(f, 0);
5139 /* We don't care about these pipes anymore, so close them. */
5140 CloseHandle(hChildStdinWrDup);
5141 CloseHandle(hChildStderrRdDup);
5142 break;
5144 case _O_WRONLY | _O_BINARY:
5145 /* Case for writing to child Stdin in binary mode. */
5146 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5147 f1 = _fdopen(fd1, "wb");
5148 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
5149 PyFile_SetBufSize(f, 0);
5150 /* We don't care about these pipes anymore, so close them. */
5151 CloseHandle(hChildStdoutRdDup);
5152 CloseHandle(hChildStderrRdDup);
5153 break;
5155 file_count = 1;
5156 break;
5158 case POPEN_2:
5159 case POPEN_4:
5161 char *m1, *m2;
5162 PyObject *p1, *p2;
5164 if (mode & _O_TEXT) {
5165 m1 = "r";
5166 m2 = "w";
5167 } else {
5168 m1 = "rb";
5169 m2 = "wb";
5172 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5173 f1 = _fdopen(fd1, m2);
5174 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5175 f2 = _fdopen(fd2, m1);
5176 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
5177 PyFile_SetBufSize(p1, 0);
5178 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
5179 PyFile_SetBufSize(p2, 0);
5181 if (n != 4)
5182 CloseHandle(hChildStderrRdDup);
5184 f = PyTuple_Pack(2,p1,p2);
5185 Py_XDECREF(p1);
5186 Py_XDECREF(p2);
5187 file_count = 2;
5188 break;
5191 case POPEN_3:
5193 char *m1, *m2;
5194 PyObject *p1, *p2, *p3;
5196 if (mode & _O_TEXT) {
5197 m1 = "r";
5198 m2 = "w";
5199 } else {
5200 m1 = "rb";
5201 m2 = "wb";
5204 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5205 f1 = _fdopen(fd1, m2);
5206 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5207 f2 = _fdopen(fd2, m1);
5208 fd3 = _open_osfhandle((Py_intptr_t)hChildStderrRdDup, mode);
5209 f3 = _fdopen(fd3, m1);
5210 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
5211 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
5212 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
5213 PyFile_SetBufSize(p1, 0);
5214 PyFile_SetBufSize(p2, 0);
5215 PyFile_SetBufSize(p3, 0);
5216 f = PyTuple_Pack(3,p1,p2,p3);
5217 Py_XDECREF(p1);
5218 Py_XDECREF(p2);
5219 Py_XDECREF(p3);
5220 file_count = 3;
5221 break;
5225 if (n == POPEN_4) {
5226 if (!_PyPopenCreateProcess(cmdstring,
5227 hChildStdinRd,
5228 hChildStdoutWr,
5229 hChildStdoutWr,
5230 &hProcess))
5231 return NULL;
5233 else {
5234 if (!_PyPopenCreateProcess(cmdstring,
5235 hChildStdinRd,
5236 hChildStdoutWr,
5237 hChildStderrWr,
5238 &hProcess))
5239 return NULL;
5243 * Insert the files we've created into the process dictionary
5244 * all referencing the list with the process handle and the
5245 * initial number of files (see description below in _PyPclose).
5246 * Since if _PyPclose later tried to wait on a process when all
5247 * handles weren't closed, it could create a deadlock with the
5248 * child, we spend some energy here to try to ensure that we
5249 * either insert all file handles into the dictionary or none
5250 * at all. It's a little clumsy with the various popen modes
5251 * and variable number of files involved.
5253 if (!_PyPopenProcs) {
5254 _PyPopenProcs = PyDict_New();
5257 if (_PyPopenProcs) {
5258 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
5259 int ins_rc[3];
5261 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
5262 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
5264 procObj = PyList_New(2);
5265 hProcessObj = PyLong_FromVoidPtr(hProcess);
5266 intObj = PyInt_FromLong(file_count);
5268 if (procObj && hProcessObj && intObj) {
5269 PyList_SetItem(procObj,0,hProcessObj);
5270 PyList_SetItem(procObj,1,intObj);
5272 fileObj[0] = PyLong_FromVoidPtr(f1);
5273 if (fileObj[0]) {
5274 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
5275 fileObj[0],
5276 procObj);
5278 if (file_count >= 2) {
5279 fileObj[1] = PyLong_FromVoidPtr(f2);
5280 if (fileObj[1]) {
5281 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
5282 fileObj[1],
5283 procObj);
5286 if (file_count >= 3) {
5287 fileObj[2] = PyLong_FromVoidPtr(f3);
5288 if (fileObj[2]) {
5289 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
5290 fileObj[2],
5291 procObj);
5295 if (ins_rc[0] < 0 || !fileObj[0] ||
5296 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
5297 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
5298 /* Something failed - remove any dictionary
5299 * entries that did make it.
5301 if (!ins_rc[0] && fileObj[0]) {
5302 PyDict_DelItem(_PyPopenProcs,
5303 fileObj[0]);
5305 if (!ins_rc[1] && fileObj[1]) {
5306 PyDict_DelItem(_PyPopenProcs,
5307 fileObj[1]);
5309 if (!ins_rc[2] && fileObj[2]) {
5310 PyDict_DelItem(_PyPopenProcs,
5311 fileObj[2]);
5317 * Clean up our localized references for the dictionary keys
5318 * and value since PyDict_SetItem will Py_INCREF any copies
5319 * that got placed in the dictionary.
5321 Py_XDECREF(procObj);
5322 Py_XDECREF(fileObj[0]);
5323 Py_XDECREF(fileObj[1]);
5324 Py_XDECREF(fileObj[2]);
5327 /* Child is launched. Close the parents copy of those pipe
5328 * handles that only the child should have open. You need to
5329 * make sure that no handles to the write end of the output pipe
5330 * are maintained in this process or else the pipe will not close
5331 * when the child process exits and the ReadFile will hang. */
5333 if (!CloseHandle(hChildStdinRd))
5334 return win32_error("CloseHandle", NULL);
5336 if (!CloseHandle(hChildStdoutWr))
5337 return win32_error("CloseHandle", NULL);
5339 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
5340 return win32_error("CloseHandle", NULL);
5342 return f;
5346 * Wrapper for fclose() to use for popen* files, so we can retrieve the
5347 * exit code for the child process and return as a result of the close.
5349 * This function uses the _PyPopenProcs dictionary in order to map the
5350 * input file pointer to information about the process that was
5351 * originally created by the popen* call that created the file pointer.
5352 * The dictionary uses the file pointer as a key (with one entry
5353 * inserted for each file returned by the original popen* call) and a
5354 * single list object as the value for all files from a single call.
5355 * The list object contains the Win32 process handle at [0], and a file
5356 * count at [1], which is initialized to the total number of file
5357 * handles using that list.
5359 * This function closes whichever handle it is passed, and decrements
5360 * the file count in the dictionary for the process handle pointed to
5361 * by this file. On the last close (when the file count reaches zero),
5362 * this function will wait for the child process and then return its
5363 * exit code as the result of the close() operation. This permits the
5364 * files to be closed in any order - it is always the close() of the
5365 * final handle that will return the exit code.
5367 * NOTE: This function is currently called with the GIL released.
5368 * hence we use the GILState API to manage our state.
5371 static int _PyPclose(FILE *file)
5373 int result;
5374 DWORD exit_code;
5375 HANDLE hProcess;
5376 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
5377 long file_count;
5378 #ifdef WITH_THREAD
5379 PyGILState_STATE state;
5380 #endif
5382 /* Close the file handle first, to ensure it can't block the
5383 * child from exiting if it's the last handle.
5385 result = fclose(file);
5386 #ifdef WITH_THREAD
5387 state = PyGILState_Ensure();
5388 #endif
5389 if (_PyPopenProcs) {
5390 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
5391 (procObj = PyDict_GetItem(_PyPopenProcs,
5392 fileObj)) != NULL &&
5393 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
5394 (intObj = PyList_GetItem(procObj,1)) != NULL) {
5396 hProcess = PyLong_AsVoidPtr(hProcessObj);
5397 file_count = PyInt_AsLong(intObj);
5399 if (file_count > 1) {
5400 /* Still other files referencing process */
5401 file_count--;
5402 PyList_SetItem(procObj,1,
5403 PyInt_FromLong(file_count));
5404 } else {
5405 /* Last file for this process */
5406 if (result != EOF &&
5407 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
5408 GetExitCodeProcess(hProcess, &exit_code)) {
5409 /* Possible truncation here in 16-bit environments, but
5410 * real exit codes are just the lower byte in any event.
5412 result = exit_code;
5413 } else {
5414 /* Indicate failure - this will cause the file object
5415 * to raise an I/O error and translate the last Win32
5416 * error code from errno. We do have a problem with
5417 * last errors that overlap the normal errno table,
5418 * but that's a consistent problem with the file object.
5420 if (result != EOF) {
5421 /* If the error wasn't from the fclose(), then
5422 * set errno for the file object error handling.
5424 errno = GetLastError();
5426 result = -1;
5429 /* Free up the native handle at this point */
5430 CloseHandle(hProcess);
5433 /* Remove this file pointer from dictionary */
5434 PyDict_DelItem(_PyPopenProcs, fileObj);
5436 if (PyDict_Size(_PyPopenProcs) == 0) {
5437 Py_DECREF(_PyPopenProcs);
5438 _PyPopenProcs = NULL;
5441 } /* if object retrieval ok */
5443 Py_XDECREF(fileObj);
5444 } /* if _PyPopenProcs */
5446 #ifdef WITH_THREAD
5447 PyGILState_Release(state);
5448 #endif
5449 return result;
5452 #else /* which OS? */
5453 static PyObject *
5454 posix_popen(PyObject *self, PyObject *args)
5456 char *name;
5457 char *mode = "r";
5458 int bufsize = -1;
5459 FILE *fp;
5460 PyObject *f;
5461 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
5462 return NULL;
5463 /* Strip mode of binary or text modifiers */
5464 if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
5465 mode = "r";
5466 else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
5467 mode = "w";
5468 Py_BEGIN_ALLOW_THREADS
5469 fp = popen(name, mode);
5470 Py_END_ALLOW_THREADS
5471 if (fp == NULL)
5472 return posix_error();
5473 f = PyFile_FromFile(fp, name, mode, pclose);
5474 if (f != NULL)
5475 PyFile_SetBufSize(f, bufsize);
5476 return f;
5479 #endif /* PYOS_??? */
5480 #endif /* HAVE_POPEN */
5483 #ifdef HAVE_SETUID
5484 PyDoc_STRVAR(posix_setuid__doc__,
5485 "setuid(uid)\n\n\
5486 Set the current process's user id.");
5488 static PyObject *
5489 posix_setuid(PyObject *self, PyObject *args)
5491 int uid;
5492 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
5493 return NULL;
5494 if (setuid(uid) < 0)
5495 return posix_error();
5496 Py_INCREF(Py_None);
5497 return Py_None;
5499 #endif /* HAVE_SETUID */
5502 #ifdef HAVE_SETEUID
5503 PyDoc_STRVAR(posix_seteuid__doc__,
5504 "seteuid(uid)\n\n\
5505 Set the current process's effective user id.");
5507 static PyObject *
5508 posix_seteuid (PyObject *self, PyObject *args)
5510 int euid;
5511 if (!PyArg_ParseTuple(args, "i", &euid)) {
5512 return NULL;
5513 } else if (seteuid(euid) < 0) {
5514 return posix_error();
5515 } else {
5516 Py_INCREF(Py_None);
5517 return Py_None;
5520 #endif /* HAVE_SETEUID */
5522 #ifdef HAVE_SETEGID
5523 PyDoc_STRVAR(posix_setegid__doc__,
5524 "setegid(gid)\n\n\
5525 Set the current process's effective group id.");
5527 static PyObject *
5528 posix_setegid (PyObject *self, PyObject *args)
5530 int egid;
5531 if (!PyArg_ParseTuple(args, "i", &egid)) {
5532 return NULL;
5533 } else if (setegid(egid) < 0) {
5534 return posix_error();
5535 } else {
5536 Py_INCREF(Py_None);
5537 return Py_None;
5540 #endif /* HAVE_SETEGID */
5542 #ifdef HAVE_SETREUID
5543 PyDoc_STRVAR(posix_setreuid__doc__,
5544 "setreuid(ruid, euid)\n\n\
5545 Set the current process's real and effective user ids.");
5547 static PyObject *
5548 posix_setreuid (PyObject *self, PyObject *args)
5550 int ruid, euid;
5551 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
5552 return NULL;
5553 } else if (setreuid(ruid, euid) < 0) {
5554 return posix_error();
5555 } else {
5556 Py_INCREF(Py_None);
5557 return Py_None;
5560 #endif /* HAVE_SETREUID */
5562 #ifdef HAVE_SETREGID
5563 PyDoc_STRVAR(posix_setregid__doc__,
5564 "setregid(rgid, egid)\n\n\
5565 Set the current process's real and effective group ids.");
5567 static PyObject *
5568 posix_setregid (PyObject *self, PyObject *args)
5570 int rgid, egid;
5571 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
5572 return NULL;
5573 } else if (setregid(rgid, egid) < 0) {
5574 return posix_error();
5575 } else {
5576 Py_INCREF(Py_None);
5577 return Py_None;
5580 #endif /* HAVE_SETREGID */
5582 #ifdef HAVE_SETGID
5583 PyDoc_STRVAR(posix_setgid__doc__,
5584 "setgid(gid)\n\n\
5585 Set the current process's group id.");
5587 static PyObject *
5588 posix_setgid(PyObject *self, PyObject *args)
5590 int gid;
5591 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
5592 return NULL;
5593 if (setgid(gid) < 0)
5594 return posix_error();
5595 Py_INCREF(Py_None);
5596 return Py_None;
5598 #endif /* HAVE_SETGID */
5600 #ifdef HAVE_SETGROUPS
5601 PyDoc_STRVAR(posix_setgroups__doc__,
5602 "setgroups(list)\n\n\
5603 Set the groups of the current process to list.");
5605 static PyObject *
5606 posix_setgroups(PyObject *self, PyObject *groups)
5608 int i, len;
5609 gid_t grouplist[MAX_GROUPS];
5611 if (!PySequence_Check(groups)) {
5612 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
5613 return NULL;
5615 len = PySequence_Size(groups);
5616 if (len > MAX_GROUPS) {
5617 PyErr_SetString(PyExc_ValueError, "too many groups");
5618 return NULL;
5620 for(i = 0; i < len; i++) {
5621 PyObject *elem;
5622 elem = PySequence_GetItem(groups, i);
5623 if (!elem)
5624 return NULL;
5625 if (!PyInt_Check(elem)) {
5626 if (!PyLong_Check(elem)) {
5627 PyErr_SetString(PyExc_TypeError,
5628 "groups must be integers");
5629 Py_DECREF(elem);
5630 return NULL;
5631 } else {
5632 unsigned long x = PyLong_AsUnsignedLong(elem);
5633 if (PyErr_Occurred()) {
5634 PyErr_SetString(PyExc_TypeError,
5635 "group id too big");
5636 Py_DECREF(elem);
5637 return NULL;
5639 grouplist[i] = x;
5640 /* read back the value to see if it fitted in gid_t */
5641 if (grouplist[i] != x) {
5642 PyErr_SetString(PyExc_TypeError,
5643 "group id too big");
5644 Py_DECREF(elem);
5645 return NULL;
5648 } else {
5649 long x = PyInt_AsLong(elem);
5650 grouplist[i] = x;
5651 if (grouplist[i] != x) {
5652 PyErr_SetString(PyExc_TypeError,
5653 "group id too big");
5654 Py_DECREF(elem);
5655 return NULL;
5658 Py_DECREF(elem);
5661 if (setgroups(len, grouplist) < 0)
5662 return posix_error();
5663 Py_INCREF(Py_None);
5664 return Py_None;
5666 #endif /* HAVE_SETGROUPS */
5668 #if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
5669 static PyObject *
5670 wait_helper(pid_t pid, int status, struct rusage *ru)
5672 PyObject *result;
5673 static PyObject *struct_rusage;
5675 if (pid == -1)
5676 return posix_error();
5678 if (struct_rusage == NULL) {
5679 PyObject *m = PyImport_ImportModuleNoBlock("resource");
5680 if (m == NULL)
5681 return NULL;
5682 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
5683 Py_DECREF(m);
5684 if (struct_rusage == NULL)
5685 return NULL;
5688 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
5689 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
5690 if (!result)
5691 return NULL;
5693 #ifndef doubletime
5694 #define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
5695 #endif
5697 PyStructSequence_SET_ITEM(result, 0,
5698 PyFloat_FromDouble(doubletime(ru->ru_utime)));
5699 PyStructSequence_SET_ITEM(result, 1,
5700 PyFloat_FromDouble(doubletime(ru->ru_stime)));
5701 #define SET_INT(result, index, value)\
5702 PyStructSequence_SET_ITEM(result, index, PyInt_FromLong(value))
5703 SET_INT(result, 2, ru->ru_maxrss);
5704 SET_INT(result, 3, ru->ru_ixrss);
5705 SET_INT(result, 4, ru->ru_idrss);
5706 SET_INT(result, 5, ru->ru_isrss);
5707 SET_INT(result, 6, ru->ru_minflt);
5708 SET_INT(result, 7, ru->ru_majflt);
5709 SET_INT(result, 8, ru->ru_nswap);
5710 SET_INT(result, 9, ru->ru_inblock);
5711 SET_INT(result, 10, ru->ru_oublock);
5712 SET_INT(result, 11, ru->ru_msgsnd);
5713 SET_INT(result, 12, ru->ru_msgrcv);
5714 SET_INT(result, 13, ru->ru_nsignals);
5715 SET_INT(result, 14, ru->ru_nvcsw);
5716 SET_INT(result, 15, ru->ru_nivcsw);
5717 #undef SET_INT
5719 if (PyErr_Occurred()) {
5720 Py_DECREF(result);
5721 return NULL;
5724 return Py_BuildValue("iiN", pid, status, result);
5726 #endif /* HAVE_WAIT3 || HAVE_WAIT4 */
5728 #ifdef HAVE_WAIT3
5729 PyDoc_STRVAR(posix_wait3__doc__,
5730 "wait3(options) -> (pid, status, rusage)\n\n\
5731 Wait for completion of a child process.");
5733 static PyObject *
5734 posix_wait3(PyObject *self, PyObject *args)
5736 pid_t pid;
5737 int options;
5738 struct rusage ru;
5739 WAIT_TYPE status;
5740 WAIT_STATUS_INT(status) = 0;
5742 if (!PyArg_ParseTuple(args, "i:wait3", &options))
5743 return NULL;
5745 Py_BEGIN_ALLOW_THREADS
5746 pid = wait3(&status, options, &ru);
5747 Py_END_ALLOW_THREADS
5749 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
5751 #endif /* HAVE_WAIT3 */
5753 #ifdef HAVE_WAIT4
5754 PyDoc_STRVAR(posix_wait4__doc__,
5755 "wait4(pid, options) -> (pid, status, rusage)\n\n\
5756 Wait for completion of a given child process.");
5758 static PyObject *
5759 posix_wait4(PyObject *self, PyObject *args)
5761 pid_t pid;
5762 int options;
5763 struct rusage ru;
5764 WAIT_TYPE status;
5765 WAIT_STATUS_INT(status) = 0;
5767 if (!PyArg_ParseTuple(args, "ii:wait4", &pid, &options))
5768 return NULL;
5770 Py_BEGIN_ALLOW_THREADS
5771 pid = wait4(pid, &status, options, &ru);
5772 Py_END_ALLOW_THREADS
5774 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
5776 #endif /* HAVE_WAIT4 */
5778 #ifdef HAVE_WAITPID
5779 PyDoc_STRVAR(posix_waitpid__doc__,
5780 "waitpid(pid, options) -> (pid, status)\n\n\
5781 Wait for completion of a given child process.");
5783 static PyObject *
5784 posix_waitpid(PyObject *self, PyObject *args)
5786 pid_t pid;
5787 int options;
5788 WAIT_TYPE status;
5789 WAIT_STATUS_INT(status) = 0;
5791 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
5792 return NULL;
5793 Py_BEGIN_ALLOW_THREADS
5794 pid = waitpid(pid, &status, options);
5795 Py_END_ALLOW_THREADS
5796 if (pid == -1)
5797 return posix_error();
5799 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
5802 #elif defined(HAVE_CWAIT)
5804 /* MS C has a variant of waitpid() that's usable for most purposes. */
5805 PyDoc_STRVAR(posix_waitpid__doc__,
5806 "waitpid(pid, options) -> (pid, status << 8)\n\n"
5807 "Wait for completion of a given process. options is ignored on Windows.");
5809 static PyObject *
5810 posix_waitpid(PyObject *self, PyObject *args)
5812 Py_intptr_t pid;
5813 int status, options;
5815 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
5816 return NULL;
5817 Py_BEGIN_ALLOW_THREADS
5818 pid = _cwait(&status, pid, options);
5819 Py_END_ALLOW_THREADS
5820 if (pid == -1)
5821 return posix_error();
5823 /* shift the status left a byte so this is more like the POSIX waitpid */
5824 return Py_BuildValue("ii", pid, status << 8);
5826 #endif /* HAVE_WAITPID || HAVE_CWAIT */
5828 #ifdef HAVE_WAIT
5829 PyDoc_STRVAR(posix_wait__doc__,
5830 "wait() -> (pid, status)\n\n\
5831 Wait for completion of a child process.");
5833 static PyObject *
5834 posix_wait(PyObject *self, PyObject *noargs)
5836 pid_t pid;
5837 WAIT_TYPE status;
5838 WAIT_STATUS_INT(status) = 0;
5840 Py_BEGIN_ALLOW_THREADS
5841 pid = wait(&status);
5842 Py_END_ALLOW_THREADS
5843 if (pid == -1)
5844 return posix_error();
5846 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
5848 #endif
5851 PyDoc_STRVAR(posix_lstat__doc__,
5852 "lstat(path) -> stat result\n\n\
5853 Like stat(path), but do not follow symbolic links.");
5855 static PyObject *
5856 posix_lstat(PyObject *self, PyObject *args)
5858 #ifdef HAVE_LSTAT
5859 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
5860 #else /* !HAVE_LSTAT */
5861 #ifdef MS_WINDOWS
5862 return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", win32_wstat);
5863 #else
5864 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
5865 #endif
5866 #endif /* !HAVE_LSTAT */
5870 #ifdef HAVE_READLINK
5871 PyDoc_STRVAR(posix_readlink__doc__,
5872 "readlink(path) -> path\n\n\
5873 Return a string representing the path to which the symbolic link points.");
5875 static PyObject *
5876 posix_readlink(PyObject *self, PyObject *args)
5878 PyObject* v;
5879 char buf[MAXPATHLEN];
5880 char *path;
5881 int n;
5882 #ifdef Py_USING_UNICODE
5883 int arg_is_unicode = 0;
5884 #endif
5886 if (!PyArg_ParseTuple(args, "et:readlink",
5887 Py_FileSystemDefaultEncoding, &path))
5888 return NULL;
5889 #ifdef Py_USING_UNICODE
5890 v = PySequence_GetItem(args, 0);
5891 if (v == NULL) {
5892 PyMem_Free(path);
5893 return NULL;
5896 if (PyUnicode_Check(v)) {
5897 arg_is_unicode = 1;
5899 Py_DECREF(v);
5900 #endif
5902 Py_BEGIN_ALLOW_THREADS
5903 n = readlink(path, buf, (int) sizeof buf);
5904 Py_END_ALLOW_THREADS
5905 if (n < 0)
5906 return posix_error_with_allocated_filename(path);
5908 PyMem_Free(path);
5909 v = PyString_FromStringAndSize(buf, n);
5910 #ifdef Py_USING_UNICODE
5911 if (arg_is_unicode) {
5912 PyObject *w;
5914 w = PyUnicode_FromEncodedObject(v,
5915 Py_FileSystemDefaultEncoding,
5916 "strict");
5917 if (w != NULL) {
5918 Py_DECREF(v);
5919 v = w;
5921 else {
5922 /* fall back to the original byte string, as
5923 discussed in patch #683592 */
5924 PyErr_Clear();
5927 #endif
5928 return v;
5930 #endif /* HAVE_READLINK */
5933 #ifdef HAVE_SYMLINK
5934 PyDoc_STRVAR(posix_symlink__doc__,
5935 "symlink(src, dst)\n\n\
5936 Create a symbolic link pointing to src named dst.");
5938 static PyObject *
5939 posix_symlink(PyObject *self, PyObject *args)
5941 return posix_2str(args, "etet:symlink", symlink);
5943 #endif /* HAVE_SYMLINK */
5946 #ifdef HAVE_TIMES
5947 #ifndef HZ
5948 #define HZ 60 /* Universal constant :-) */
5949 #endif /* HZ */
5951 #if defined(PYCC_VACPP) && defined(PYOS_OS2)
5952 static long
5953 system_uptime(void)
5955 ULONG value = 0;
5957 Py_BEGIN_ALLOW_THREADS
5958 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
5959 Py_END_ALLOW_THREADS
5961 return value;
5964 static PyObject *
5965 posix_times(PyObject *self, PyObject *noargs)
5967 /* Currently Only Uptime is Provided -- Others Later */
5968 return Py_BuildValue("ddddd",
5969 (double)0 /* t.tms_utime / HZ */,
5970 (double)0 /* t.tms_stime / HZ */,
5971 (double)0 /* t.tms_cutime / HZ */,
5972 (double)0 /* t.tms_cstime / HZ */,
5973 (double)system_uptime() / 1000);
5975 #else /* not OS2 */
5976 static PyObject *
5977 posix_times(PyObject *self, PyObject *noargs)
5979 struct tms t;
5980 clock_t c;
5981 errno = 0;
5982 c = times(&t);
5983 if (c == (clock_t) -1)
5984 return posix_error();
5985 return Py_BuildValue("ddddd",
5986 (double)t.tms_utime / HZ,
5987 (double)t.tms_stime / HZ,
5988 (double)t.tms_cutime / HZ,
5989 (double)t.tms_cstime / HZ,
5990 (double)c / HZ);
5992 #endif /* not OS2 */
5993 #endif /* HAVE_TIMES */
5996 #ifdef MS_WINDOWS
5997 #define HAVE_TIMES /* so the method table will pick it up */
5998 static PyObject *
5999 posix_times(PyObject *self, PyObject *noargs)
6001 FILETIME create, exit, kernel, user;
6002 HANDLE hProc;
6003 hProc = GetCurrentProcess();
6004 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
6005 /* The fields of a FILETIME structure are the hi and lo part
6006 of a 64-bit value expressed in 100 nanosecond units.
6007 1e7 is one second in such units; 1e-7 the inverse.
6008 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
6010 return Py_BuildValue(
6011 "ddddd",
6012 (double)(user.dwHighDateTime*429.4967296 +
6013 user.dwLowDateTime*1e-7),
6014 (double)(kernel.dwHighDateTime*429.4967296 +
6015 kernel.dwLowDateTime*1e-7),
6016 (double)0,
6017 (double)0,
6018 (double)0);
6020 #endif /* MS_WINDOWS */
6022 #ifdef HAVE_TIMES
6023 PyDoc_STRVAR(posix_times__doc__,
6024 "times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
6025 Return a tuple of floating point numbers indicating process times.");
6026 #endif
6029 #ifdef HAVE_GETSID
6030 PyDoc_STRVAR(posix_getsid__doc__,
6031 "getsid(pid) -> sid\n\n\
6032 Call the system call getsid().");
6034 static PyObject *
6035 posix_getsid(PyObject *self, PyObject *args)
6037 pid_t pid;
6038 int sid;
6039 if (!PyArg_ParseTuple(args, "i:getsid", &pid))
6040 return NULL;
6041 sid = getsid(pid);
6042 if (sid < 0)
6043 return posix_error();
6044 return PyInt_FromLong((long)sid);
6046 #endif /* HAVE_GETSID */
6049 #ifdef HAVE_SETSID
6050 PyDoc_STRVAR(posix_setsid__doc__,
6051 "setsid()\n\n\
6052 Call the system call setsid().");
6054 static PyObject *
6055 posix_setsid(PyObject *self, PyObject *noargs)
6057 if (setsid() < 0)
6058 return posix_error();
6059 Py_INCREF(Py_None);
6060 return Py_None;
6062 #endif /* HAVE_SETSID */
6064 #ifdef HAVE_SETPGID
6065 PyDoc_STRVAR(posix_setpgid__doc__,
6066 "setpgid(pid, pgrp)\n\n\
6067 Call the system call setpgid().");
6069 static PyObject *
6070 posix_setpgid(PyObject *self, PyObject *args)
6072 pid_t pid;
6073 int pgrp;
6074 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
6075 return NULL;
6076 if (setpgid(pid, pgrp) < 0)
6077 return posix_error();
6078 Py_INCREF(Py_None);
6079 return Py_None;
6081 #endif /* HAVE_SETPGID */
6084 #ifdef HAVE_TCGETPGRP
6085 PyDoc_STRVAR(posix_tcgetpgrp__doc__,
6086 "tcgetpgrp(fd) -> pgid\n\n\
6087 Return the process group associated with the terminal given by a fd.");
6089 static PyObject *
6090 posix_tcgetpgrp(PyObject *self, PyObject *args)
6092 int fd;
6093 pid_t pgid;
6094 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
6095 return NULL;
6096 pgid = tcgetpgrp(fd);
6097 if (pgid < 0)
6098 return posix_error();
6099 return PyInt_FromLong((long)pgid);
6101 #endif /* HAVE_TCGETPGRP */
6104 #ifdef HAVE_TCSETPGRP
6105 PyDoc_STRVAR(posix_tcsetpgrp__doc__,
6106 "tcsetpgrp(fd, pgid)\n\n\
6107 Set the process group associated with the terminal given by a fd.");
6109 static PyObject *
6110 posix_tcsetpgrp(PyObject *self, PyObject *args)
6112 int fd, pgid;
6113 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
6114 return NULL;
6115 if (tcsetpgrp(fd, pgid) < 0)
6116 return posix_error();
6117 Py_INCREF(Py_None);
6118 return Py_None;
6120 #endif /* HAVE_TCSETPGRP */
6122 /* Functions acting on file descriptors */
6124 PyDoc_STRVAR(posix_open__doc__,
6125 "open(filename, flag [, mode=0777]) -> fd\n\n\
6126 Open a file (for low level IO).");
6128 static PyObject *
6129 posix_open(PyObject *self, PyObject *args)
6131 char *file = NULL;
6132 int flag;
6133 int mode = 0777;
6134 int fd;
6136 #ifdef MS_WINDOWS
6137 if (unicode_file_names()) {
6138 PyUnicodeObject *po;
6139 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
6140 Py_BEGIN_ALLOW_THREADS
6141 /* PyUnicode_AS_UNICODE OK without thread
6142 lock as it is a simple dereference. */
6143 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
6144 Py_END_ALLOW_THREADS
6145 if (fd < 0)
6146 return posix_error();
6147 return PyInt_FromLong((long)fd);
6149 /* Drop the argument parsing error as narrow strings
6150 are also valid. */
6151 PyErr_Clear();
6153 #endif
6155 if (!PyArg_ParseTuple(args, "eti|i",
6156 Py_FileSystemDefaultEncoding, &file,
6157 &flag, &mode))
6158 return NULL;
6160 Py_BEGIN_ALLOW_THREADS
6161 fd = open(file, flag, mode);
6162 Py_END_ALLOW_THREADS
6163 if (fd < 0)
6164 return posix_error_with_allocated_filename(file);
6165 PyMem_Free(file);
6166 return PyInt_FromLong((long)fd);
6170 PyDoc_STRVAR(posix_close__doc__,
6171 "close(fd)\n\n\
6172 Close a file descriptor (for low level IO).");
6174 static PyObject *
6175 posix_close(PyObject *self, PyObject *args)
6177 int fd, res;
6178 if (!PyArg_ParseTuple(args, "i:close", &fd))
6179 return NULL;
6180 Py_BEGIN_ALLOW_THREADS
6181 res = close(fd);
6182 Py_END_ALLOW_THREADS
6183 if (res < 0)
6184 return posix_error();
6185 Py_INCREF(Py_None);
6186 return Py_None;
6190 PyDoc_STRVAR(posix_closerange__doc__,
6191 "closerange(fd_low, fd_high)\n\n\
6192 Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
6194 static PyObject *
6195 posix_closerange(PyObject *self, PyObject *args)
6197 int fd_from, fd_to, i;
6198 if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
6199 return NULL;
6200 Py_BEGIN_ALLOW_THREADS
6201 for (i = fd_from; i < fd_to; i++)
6202 close(i);
6203 Py_END_ALLOW_THREADS
6204 Py_RETURN_NONE;
6208 PyDoc_STRVAR(posix_dup__doc__,
6209 "dup(fd) -> fd2\n\n\
6210 Return a duplicate of a file descriptor.");
6212 static PyObject *
6213 posix_dup(PyObject *self, PyObject *args)
6215 int fd;
6216 if (!PyArg_ParseTuple(args, "i:dup", &fd))
6217 return NULL;
6218 Py_BEGIN_ALLOW_THREADS
6219 fd = dup(fd);
6220 Py_END_ALLOW_THREADS
6221 if (fd < 0)
6222 return posix_error();
6223 return PyInt_FromLong((long)fd);
6227 PyDoc_STRVAR(posix_dup2__doc__,
6228 "dup2(old_fd, new_fd)\n\n\
6229 Duplicate file descriptor.");
6231 static PyObject *
6232 posix_dup2(PyObject *self, PyObject *args)
6234 int fd, fd2, res;
6235 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
6236 return NULL;
6237 Py_BEGIN_ALLOW_THREADS
6238 res = dup2(fd, fd2);
6239 Py_END_ALLOW_THREADS
6240 if (res < 0)
6241 return posix_error();
6242 Py_INCREF(Py_None);
6243 return Py_None;
6247 PyDoc_STRVAR(posix_lseek__doc__,
6248 "lseek(fd, pos, how) -> newpos\n\n\
6249 Set the current position of a file descriptor.");
6251 static PyObject *
6252 posix_lseek(PyObject *self, PyObject *args)
6254 int fd, how;
6255 #if defined(MS_WIN64) || defined(MS_WINDOWS)
6256 PY_LONG_LONG pos, res;
6257 #else
6258 off_t pos, res;
6259 #endif
6260 PyObject *posobj;
6261 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
6262 return NULL;
6263 #ifdef SEEK_SET
6264 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
6265 switch (how) {
6266 case 0: how = SEEK_SET; break;
6267 case 1: how = SEEK_CUR; break;
6268 case 2: how = SEEK_END; break;
6270 #endif /* SEEK_END */
6272 #if !defined(HAVE_LARGEFILE_SUPPORT)
6273 pos = PyInt_AsLong(posobj);
6274 #else
6275 pos = PyLong_Check(posobj) ?
6276 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
6277 #endif
6278 if (PyErr_Occurred())
6279 return NULL;
6281 Py_BEGIN_ALLOW_THREADS
6282 #if defined(MS_WIN64) || defined(MS_WINDOWS)
6283 res = _lseeki64(fd, pos, how);
6284 #else
6285 res = lseek(fd, pos, how);
6286 #endif
6287 Py_END_ALLOW_THREADS
6288 if (res < 0)
6289 return posix_error();
6291 #if !defined(HAVE_LARGEFILE_SUPPORT)
6292 return PyInt_FromLong(res);
6293 #else
6294 return PyLong_FromLongLong(res);
6295 #endif
6299 PyDoc_STRVAR(posix_read__doc__,
6300 "read(fd, buffersize) -> string\n\n\
6301 Read a file descriptor.");
6303 static PyObject *
6304 posix_read(PyObject *self, PyObject *args)
6306 int fd, size, n;
6307 PyObject *buffer;
6308 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
6309 return NULL;
6310 if (size < 0) {
6311 errno = EINVAL;
6312 return posix_error();
6314 buffer = PyString_FromStringAndSize((char *)NULL, size);
6315 if (buffer == NULL)
6316 return NULL;
6317 Py_BEGIN_ALLOW_THREADS
6318 n = read(fd, PyString_AsString(buffer), size);
6319 Py_END_ALLOW_THREADS
6320 if (n < 0) {
6321 Py_DECREF(buffer);
6322 return posix_error();
6324 if (n != size)
6325 _PyString_Resize(&buffer, n);
6326 return buffer;
6330 PyDoc_STRVAR(posix_write__doc__,
6331 "write(fd, string) -> byteswritten\n\n\
6332 Write a string to a file descriptor.");
6334 static PyObject *
6335 posix_write(PyObject *self, PyObject *args)
6337 int fd;
6338 Py_ssize_t size;
6339 char *buffer;
6341 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
6342 return NULL;
6343 Py_BEGIN_ALLOW_THREADS
6344 size = write(fd, buffer, (size_t)size);
6345 Py_END_ALLOW_THREADS
6346 if (size < 0)
6347 return posix_error();
6348 return PyInt_FromSsize_t(size);
6352 PyDoc_STRVAR(posix_fstat__doc__,
6353 "fstat(fd) -> stat result\n\n\
6354 Like stat(), but for an open file descriptor.");
6356 static PyObject *
6357 posix_fstat(PyObject *self, PyObject *args)
6359 int fd;
6360 STRUCT_STAT st;
6361 int res;
6362 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
6363 return NULL;
6364 #ifdef __VMS
6365 /* on OpenVMS we must ensure that all bytes are written to the file */
6366 fsync(fd);
6367 #endif
6368 Py_BEGIN_ALLOW_THREADS
6369 res = FSTAT(fd, &st);
6370 Py_END_ALLOW_THREADS
6371 if (res != 0) {
6372 #ifdef MS_WINDOWS
6373 return win32_error("fstat", NULL);
6374 #else
6375 return posix_error();
6376 #endif
6379 return _pystat_fromstructstat(&st);
6383 PyDoc_STRVAR(posix_fdopen__doc__,
6384 "fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
6385 Return an open file object connected to a file descriptor.");
6387 static PyObject *
6388 posix_fdopen(PyObject *self, PyObject *args)
6390 int fd;
6391 char *orgmode = "r";
6392 int bufsize = -1;
6393 FILE *fp;
6394 PyObject *f;
6395 char *mode;
6396 if (!PyArg_ParseTuple(args, "i|si", &fd, &orgmode, &bufsize))
6397 return NULL;
6399 /* Sanitize mode. See fileobject.c */
6400 mode = PyMem_MALLOC(strlen(orgmode)+3);
6401 if (!mode) {
6402 PyErr_NoMemory();
6403 return NULL;
6405 strcpy(mode, orgmode);
6406 if (_PyFile_SanitizeMode(mode)) {
6407 PyMem_FREE(mode);
6408 return NULL;
6410 Py_BEGIN_ALLOW_THREADS
6411 #if !defined(MS_WINDOWS) && defined(HAVE_FCNTL_H)
6412 if (mode[0] == 'a') {
6413 /* try to make sure the O_APPEND flag is set */
6414 int flags;
6415 flags = fcntl(fd, F_GETFL);
6416 if (flags != -1)
6417 fcntl(fd, F_SETFL, flags | O_APPEND);
6418 fp = fdopen(fd, mode);
6419 if (fp == NULL && flags != -1)
6420 /* restore old mode if fdopen failed */
6421 fcntl(fd, F_SETFL, flags);
6422 } else {
6423 fp = fdopen(fd, mode);
6425 #else
6426 fp = fdopen(fd, mode);
6427 #endif
6428 Py_END_ALLOW_THREADS
6429 PyMem_FREE(mode);
6430 if (fp == NULL)
6431 return posix_error();
6432 f = PyFile_FromFile(fp, "<fdopen>", orgmode, fclose);
6433 if (f != NULL)
6434 PyFile_SetBufSize(f, bufsize);
6435 return f;
6438 PyDoc_STRVAR(posix_isatty__doc__,
6439 "isatty(fd) -> bool\n\n\
6440 Return True if the file descriptor 'fd' is an open file descriptor\n\
6441 connected to the slave end of a terminal.");
6443 static PyObject *
6444 posix_isatty(PyObject *self, PyObject *args)
6446 int fd;
6447 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
6448 return NULL;
6449 return PyBool_FromLong(isatty(fd));
6452 #ifdef HAVE_PIPE
6453 PyDoc_STRVAR(posix_pipe__doc__,
6454 "pipe() -> (read_end, write_end)\n\n\
6455 Create a pipe.");
6457 static PyObject *
6458 posix_pipe(PyObject *self, PyObject *noargs)
6460 #if defined(PYOS_OS2)
6461 HFILE read, write;
6462 APIRET rc;
6464 Py_BEGIN_ALLOW_THREADS
6465 rc = DosCreatePipe( &read, &write, 4096);
6466 Py_END_ALLOW_THREADS
6467 if (rc != NO_ERROR)
6468 return os2_error(rc);
6470 return Py_BuildValue("(ii)", read, write);
6471 #else
6472 #if !defined(MS_WINDOWS)
6473 int fds[2];
6474 int res;
6475 Py_BEGIN_ALLOW_THREADS
6476 res = pipe(fds);
6477 Py_END_ALLOW_THREADS
6478 if (res != 0)
6479 return posix_error();
6480 return Py_BuildValue("(ii)", fds[0], fds[1]);
6481 #else /* MS_WINDOWS */
6482 HANDLE read, write;
6483 int read_fd, write_fd;
6484 BOOL ok;
6485 Py_BEGIN_ALLOW_THREADS
6486 ok = CreatePipe(&read, &write, NULL, 0);
6487 Py_END_ALLOW_THREADS
6488 if (!ok)
6489 return win32_error("CreatePipe", NULL);
6490 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
6491 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
6492 return Py_BuildValue("(ii)", read_fd, write_fd);
6493 #endif /* MS_WINDOWS */
6494 #endif
6496 #endif /* HAVE_PIPE */
6499 #ifdef HAVE_MKFIFO
6500 PyDoc_STRVAR(posix_mkfifo__doc__,
6501 "mkfifo(filename [, mode=0666])\n\n\
6502 Create a FIFO (a POSIX named pipe).");
6504 static PyObject *
6505 posix_mkfifo(PyObject *self, PyObject *args)
6507 char *filename;
6508 int mode = 0666;
6509 int res;
6510 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
6511 return NULL;
6512 Py_BEGIN_ALLOW_THREADS
6513 res = mkfifo(filename, mode);
6514 Py_END_ALLOW_THREADS
6515 if (res < 0)
6516 return posix_error();
6517 Py_INCREF(Py_None);
6518 return Py_None;
6520 #endif
6523 #if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
6524 PyDoc_STRVAR(posix_mknod__doc__,
6525 "mknod(filename [, mode=0600, device])\n\n\
6526 Create a filesystem node (file, device special file or named pipe)\n\
6527 named filename. mode specifies both the permissions to use and the\n\
6528 type of node to be created, being combined (bitwise OR) with one of\n\
6529 S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
6530 device defines the newly created device special file (probably using\n\
6531 os.makedev()), otherwise it is ignored.");
6534 static PyObject *
6535 posix_mknod(PyObject *self, PyObject *args)
6537 char *filename;
6538 int mode = 0600;
6539 int device = 0;
6540 int res;
6541 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
6542 return NULL;
6543 Py_BEGIN_ALLOW_THREADS
6544 res = mknod(filename, mode, device);
6545 Py_END_ALLOW_THREADS
6546 if (res < 0)
6547 return posix_error();
6548 Py_INCREF(Py_None);
6549 return Py_None;
6551 #endif
6553 #ifdef HAVE_DEVICE_MACROS
6554 PyDoc_STRVAR(posix_major__doc__,
6555 "major(device) -> major number\n\
6556 Extracts a device major number from a raw device number.");
6558 static PyObject *
6559 posix_major(PyObject *self, PyObject *args)
6561 int device;
6562 if (!PyArg_ParseTuple(args, "i:major", &device))
6563 return NULL;
6564 return PyInt_FromLong((long)major(device));
6567 PyDoc_STRVAR(posix_minor__doc__,
6568 "minor(device) -> minor number\n\
6569 Extracts a device minor number from a raw device number.");
6571 static PyObject *
6572 posix_minor(PyObject *self, PyObject *args)
6574 int device;
6575 if (!PyArg_ParseTuple(args, "i:minor", &device))
6576 return NULL;
6577 return PyInt_FromLong((long)minor(device));
6580 PyDoc_STRVAR(posix_makedev__doc__,
6581 "makedev(major, minor) -> device number\n\
6582 Composes a raw device number from the major and minor device numbers.");
6584 static PyObject *
6585 posix_makedev(PyObject *self, PyObject *args)
6587 int major, minor;
6588 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
6589 return NULL;
6590 return PyInt_FromLong((long)makedev(major, minor));
6592 #endif /* device macros */
6595 #ifdef HAVE_FTRUNCATE
6596 PyDoc_STRVAR(posix_ftruncate__doc__,
6597 "ftruncate(fd, length)\n\n\
6598 Truncate a file to a specified length.");
6600 static PyObject *
6601 posix_ftruncate(PyObject *self, PyObject *args)
6603 int fd;
6604 off_t length;
6605 int res;
6606 PyObject *lenobj;
6608 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
6609 return NULL;
6611 #if !defined(HAVE_LARGEFILE_SUPPORT)
6612 length = PyInt_AsLong(lenobj);
6613 #else
6614 length = PyLong_Check(lenobj) ?
6615 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
6616 #endif
6617 if (PyErr_Occurred())
6618 return NULL;
6620 Py_BEGIN_ALLOW_THREADS
6621 res = ftruncate(fd, length);
6622 Py_END_ALLOW_THREADS
6623 if (res < 0) {
6624 PyErr_SetFromErrno(PyExc_IOError);
6625 return NULL;
6627 Py_INCREF(Py_None);
6628 return Py_None;
6630 #endif
6632 #ifdef HAVE_PUTENV
6633 PyDoc_STRVAR(posix_putenv__doc__,
6634 "putenv(key, value)\n\n\
6635 Change or add an environment variable.");
6637 /* Save putenv() parameters as values here, so we can collect them when they
6638 * get re-set with another call for the same key. */
6639 static PyObject *posix_putenv_garbage;
6641 static PyObject *
6642 posix_putenv(PyObject *self, PyObject *args)
6644 char *s1, *s2;
6645 char *newenv;
6646 PyObject *newstr;
6647 size_t len;
6649 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
6650 return NULL;
6652 #if defined(PYOS_OS2)
6653 if (stricmp(s1, "BEGINLIBPATH") == 0) {
6654 APIRET rc;
6656 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
6657 if (rc != NO_ERROR)
6658 return os2_error(rc);
6660 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
6661 APIRET rc;
6663 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
6664 if (rc != NO_ERROR)
6665 return os2_error(rc);
6666 } else {
6667 #endif
6669 /* XXX This can leak memory -- not easy to fix :-( */
6670 len = strlen(s1) + strlen(s2) + 2;
6671 /* len includes space for a trailing \0; the size arg to
6672 PyString_FromStringAndSize does not count that */
6673 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
6674 if (newstr == NULL)
6675 return PyErr_NoMemory();
6676 newenv = PyString_AS_STRING(newstr);
6677 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
6678 if (putenv(newenv)) {
6679 Py_DECREF(newstr);
6680 posix_error();
6681 return NULL;
6683 /* Install the first arg and newstr in posix_putenv_garbage;
6684 * this will cause previous value to be collected. This has to
6685 * happen after the real putenv() call because the old value
6686 * was still accessible until then. */
6687 if (PyDict_SetItem(posix_putenv_garbage,
6688 PyTuple_GET_ITEM(args, 0), newstr)) {
6689 /* really not much we can do; just leak */
6690 PyErr_Clear();
6692 else {
6693 Py_DECREF(newstr);
6696 #if defined(PYOS_OS2)
6698 #endif
6699 Py_INCREF(Py_None);
6700 return Py_None;
6702 #endif /* putenv */
6704 #ifdef HAVE_UNSETENV
6705 PyDoc_STRVAR(posix_unsetenv__doc__,
6706 "unsetenv(key)\n\n\
6707 Delete an environment variable.");
6709 static PyObject *
6710 posix_unsetenv(PyObject *self, PyObject *args)
6712 char *s1;
6714 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
6715 return NULL;
6717 unsetenv(s1);
6719 /* Remove the key from posix_putenv_garbage;
6720 * this will cause it to be collected. This has to
6721 * happen after the real unsetenv() call because the
6722 * old value was still accessible until then.
6724 if (PyDict_DelItem(posix_putenv_garbage,
6725 PyTuple_GET_ITEM(args, 0))) {
6726 /* really not much we can do; just leak */
6727 PyErr_Clear();
6730 Py_INCREF(Py_None);
6731 return Py_None;
6733 #endif /* unsetenv */
6735 PyDoc_STRVAR(posix_strerror__doc__,
6736 "strerror(code) -> string\n\n\
6737 Translate an error code to a message string.");
6739 static PyObject *
6740 posix_strerror(PyObject *self, PyObject *args)
6742 int code;
6743 char *message;
6744 if (!PyArg_ParseTuple(args, "i:strerror", &code))
6745 return NULL;
6746 message = strerror(code);
6747 if (message == NULL) {
6748 PyErr_SetString(PyExc_ValueError,
6749 "strerror() argument out of range");
6750 return NULL;
6752 return PyString_FromString(message);
6756 #ifdef HAVE_SYS_WAIT_H
6758 #ifdef WCOREDUMP
6759 PyDoc_STRVAR(posix_WCOREDUMP__doc__,
6760 "WCOREDUMP(status) -> bool\n\n\
6761 Return True if the process returning 'status' was dumped to a core file.");
6763 static PyObject *
6764 posix_WCOREDUMP(PyObject *self, PyObject *args)
6766 WAIT_TYPE status;
6767 WAIT_STATUS_INT(status) = 0;
6769 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
6770 return NULL;
6772 return PyBool_FromLong(WCOREDUMP(status));
6774 #endif /* WCOREDUMP */
6776 #ifdef WIFCONTINUED
6777 PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
6778 "WIFCONTINUED(status) -> bool\n\n\
6779 Return True if the process returning 'status' was continued from a\n\
6780 job control stop.");
6782 static PyObject *
6783 posix_WIFCONTINUED(PyObject *self, PyObject *args)
6785 WAIT_TYPE status;
6786 WAIT_STATUS_INT(status) = 0;
6788 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
6789 return NULL;
6791 return PyBool_FromLong(WIFCONTINUED(status));
6793 #endif /* WIFCONTINUED */
6795 #ifdef WIFSTOPPED
6796 PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
6797 "WIFSTOPPED(status) -> bool\n\n\
6798 Return True if the process returning 'status' was stopped.");
6800 static PyObject *
6801 posix_WIFSTOPPED(PyObject *self, PyObject *args)
6803 WAIT_TYPE status;
6804 WAIT_STATUS_INT(status) = 0;
6806 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
6807 return NULL;
6809 return PyBool_FromLong(WIFSTOPPED(status));
6811 #endif /* WIFSTOPPED */
6813 #ifdef WIFSIGNALED
6814 PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
6815 "WIFSIGNALED(status) -> bool\n\n\
6816 Return True if the process returning 'status' was terminated by a signal.");
6818 static PyObject *
6819 posix_WIFSIGNALED(PyObject *self, PyObject *args)
6821 WAIT_TYPE status;
6822 WAIT_STATUS_INT(status) = 0;
6824 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
6825 return NULL;
6827 return PyBool_FromLong(WIFSIGNALED(status));
6829 #endif /* WIFSIGNALED */
6831 #ifdef WIFEXITED
6832 PyDoc_STRVAR(posix_WIFEXITED__doc__,
6833 "WIFEXITED(status) -> bool\n\n\
6834 Return true if the process returning 'status' exited using the exit()\n\
6835 system call.");
6837 static PyObject *
6838 posix_WIFEXITED(PyObject *self, PyObject *args)
6840 WAIT_TYPE status;
6841 WAIT_STATUS_INT(status) = 0;
6843 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
6844 return NULL;
6846 return PyBool_FromLong(WIFEXITED(status));
6848 #endif /* WIFEXITED */
6850 #ifdef WEXITSTATUS
6851 PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
6852 "WEXITSTATUS(status) -> integer\n\n\
6853 Return the process return code from 'status'.");
6855 static PyObject *
6856 posix_WEXITSTATUS(PyObject *self, PyObject *args)
6858 WAIT_TYPE status;
6859 WAIT_STATUS_INT(status) = 0;
6861 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
6862 return NULL;
6864 return Py_BuildValue("i", WEXITSTATUS(status));
6866 #endif /* WEXITSTATUS */
6868 #ifdef WTERMSIG
6869 PyDoc_STRVAR(posix_WTERMSIG__doc__,
6870 "WTERMSIG(status) -> integer\n\n\
6871 Return the signal that terminated the process that provided the 'status'\n\
6872 value.");
6874 static PyObject *
6875 posix_WTERMSIG(PyObject *self, PyObject *args)
6877 WAIT_TYPE status;
6878 WAIT_STATUS_INT(status) = 0;
6880 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
6881 return NULL;
6883 return Py_BuildValue("i", WTERMSIG(status));
6885 #endif /* WTERMSIG */
6887 #ifdef WSTOPSIG
6888 PyDoc_STRVAR(posix_WSTOPSIG__doc__,
6889 "WSTOPSIG(status) -> integer\n\n\
6890 Return the signal that stopped the process that provided\n\
6891 the 'status' value.");
6893 static PyObject *
6894 posix_WSTOPSIG(PyObject *self, PyObject *args)
6896 WAIT_TYPE status;
6897 WAIT_STATUS_INT(status) = 0;
6899 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
6900 return NULL;
6902 return Py_BuildValue("i", WSTOPSIG(status));
6904 #endif /* WSTOPSIG */
6906 #endif /* HAVE_SYS_WAIT_H */
6909 #if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
6910 #ifdef _SCO_DS
6911 /* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
6912 needed definitions in sys/statvfs.h */
6913 #define _SVID3
6914 #endif
6915 #include <sys/statvfs.h>
6917 static PyObject*
6918 _pystatvfs_fromstructstatvfs(struct statvfs st) {
6919 PyObject *v = PyStructSequence_New(&StatVFSResultType);
6920 if (v == NULL)
6921 return NULL;
6923 #if !defined(HAVE_LARGEFILE_SUPPORT)
6924 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6925 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
6926 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
6927 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
6928 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
6929 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
6930 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
6931 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
6932 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6933 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6934 #else
6935 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6936 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
6937 PyStructSequence_SET_ITEM(v, 2,
6938 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
6939 PyStructSequence_SET_ITEM(v, 3,
6940 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
6941 PyStructSequence_SET_ITEM(v, 4,
6942 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
6943 PyStructSequence_SET_ITEM(v, 5,
6944 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
6945 PyStructSequence_SET_ITEM(v, 6,
6946 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
6947 PyStructSequence_SET_ITEM(v, 7,
6948 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
6949 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6950 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6951 #endif
6953 return v;
6956 PyDoc_STRVAR(posix_fstatvfs__doc__,
6957 "fstatvfs(fd) -> statvfs result\n\n\
6958 Perform an fstatvfs system call on the given fd.");
6960 static PyObject *
6961 posix_fstatvfs(PyObject *self, PyObject *args)
6963 int fd, res;
6964 struct statvfs st;
6966 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
6967 return NULL;
6968 Py_BEGIN_ALLOW_THREADS
6969 res = fstatvfs(fd, &st);
6970 Py_END_ALLOW_THREADS
6971 if (res != 0)
6972 return posix_error();
6974 return _pystatvfs_fromstructstatvfs(st);
6976 #endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
6979 #if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
6980 #include <sys/statvfs.h>
6982 PyDoc_STRVAR(posix_statvfs__doc__,
6983 "statvfs(path) -> statvfs result\n\n\
6984 Perform a statvfs system call on the given path.");
6986 static PyObject *
6987 posix_statvfs(PyObject *self, PyObject *args)
6989 char *path;
6990 int res;
6991 struct statvfs st;
6992 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
6993 return NULL;
6994 Py_BEGIN_ALLOW_THREADS
6995 res = statvfs(path, &st);
6996 Py_END_ALLOW_THREADS
6997 if (res != 0)
6998 return posix_error_with_filename(path);
7000 return _pystatvfs_fromstructstatvfs(st);
7002 #endif /* HAVE_STATVFS */
7005 #ifdef HAVE_TEMPNAM
7006 PyDoc_STRVAR(posix_tempnam__doc__,
7007 "tempnam([dir[, prefix]]) -> string\n\n\
7008 Return a unique name for a temporary file.\n\
7009 The directory and a prefix may be specified as strings; they may be omitted\n\
7010 or None if not needed.");
7012 static PyObject *
7013 posix_tempnam(PyObject *self, PyObject *args)
7015 PyObject *result = NULL;
7016 char *dir = NULL;
7017 char *pfx = NULL;
7018 char *name;
7020 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
7021 return NULL;
7023 if (PyErr_Warn(PyExc_RuntimeWarning,
7024 "tempnam is a potential security risk to your program") < 0)
7025 return NULL;
7027 #ifdef MS_WINDOWS
7028 name = _tempnam(dir, pfx);
7029 #else
7030 name = tempnam(dir, pfx);
7031 #endif
7032 if (name == NULL)
7033 return PyErr_NoMemory();
7034 result = PyString_FromString(name);
7035 free(name);
7036 return result;
7038 #endif
7041 #ifdef HAVE_TMPFILE
7042 PyDoc_STRVAR(posix_tmpfile__doc__,
7043 "tmpfile() -> file object\n\n\
7044 Create a temporary file with no directory entries.");
7046 static PyObject *
7047 posix_tmpfile(PyObject *self, PyObject *noargs)
7049 FILE *fp;
7051 fp = tmpfile();
7052 if (fp == NULL)
7053 return posix_error();
7054 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
7056 #endif
7059 #ifdef HAVE_TMPNAM
7060 PyDoc_STRVAR(posix_tmpnam__doc__,
7061 "tmpnam() -> string\n\n\
7062 Return a unique name for a temporary file.");
7064 static PyObject *
7065 posix_tmpnam(PyObject *self, PyObject *noargs)
7067 char buffer[L_tmpnam];
7068 char *name;
7070 if (PyErr_Warn(PyExc_RuntimeWarning,
7071 "tmpnam is a potential security risk to your program") < 0)
7072 return NULL;
7074 #ifdef USE_TMPNAM_R
7075 name = tmpnam_r(buffer);
7076 #else
7077 name = tmpnam(buffer);
7078 #endif
7079 if (name == NULL) {
7080 PyObject *err = Py_BuildValue("is", 0,
7081 #ifdef USE_TMPNAM_R
7082 "unexpected NULL from tmpnam_r"
7083 #else
7084 "unexpected NULL from tmpnam"
7085 #endif
7087 PyErr_SetObject(PyExc_OSError, err);
7088 Py_XDECREF(err);
7089 return NULL;
7091 return PyString_FromString(buffer);
7093 #endif
7096 /* This is used for fpathconf(), pathconf(), confstr() and sysconf().
7097 * It maps strings representing configuration variable names to
7098 * integer values, allowing those functions to be called with the
7099 * magic names instead of polluting the module's namespace with tons of
7100 * rarely-used constants. There are three separate tables that use
7101 * these definitions.
7103 * This code is always included, even if none of the interfaces that
7104 * need it are included. The #if hackery needed to avoid it would be
7105 * sufficiently pervasive that it's not worth the loss of readability.
7107 struct constdef {
7108 char *name;
7109 long value;
7112 static int
7113 conv_confname(PyObject *arg, int *valuep, struct constdef *table,
7114 size_t tablesize)
7116 if (PyInt_Check(arg)) {
7117 *valuep = PyInt_AS_LONG(arg);
7118 return 1;
7120 if (PyString_Check(arg)) {
7121 /* look up the value in the table using a binary search */
7122 size_t lo = 0;
7123 size_t mid;
7124 size_t hi = tablesize;
7125 int cmp;
7126 char *confname = PyString_AS_STRING(arg);
7127 while (lo < hi) {
7128 mid = (lo + hi) / 2;
7129 cmp = strcmp(confname, table[mid].name);
7130 if (cmp < 0)
7131 hi = mid;
7132 else if (cmp > 0)
7133 lo = mid + 1;
7134 else {
7135 *valuep = table[mid].value;
7136 return 1;
7139 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
7141 else
7142 PyErr_SetString(PyExc_TypeError,
7143 "configuration names must be strings or integers");
7144 return 0;
7148 #if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
7149 static struct constdef posix_constants_pathconf[] = {
7150 #ifdef _PC_ABI_AIO_XFER_MAX
7151 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
7152 #endif
7153 #ifdef _PC_ABI_ASYNC_IO
7154 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
7155 #endif
7156 #ifdef _PC_ASYNC_IO
7157 {"PC_ASYNC_IO", _PC_ASYNC_IO},
7158 #endif
7159 #ifdef _PC_CHOWN_RESTRICTED
7160 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
7161 #endif
7162 #ifdef _PC_FILESIZEBITS
7163 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
7164 #endif
7165 #ifdef _PC_LAST
7166 {"PC_LAST", _PC_LAST},
7167 #endif
7168 #ifdef _PC_LINK_MAX
7169 {"PC_LINK_MAX", _PC_LINK_MAX},
7170 #endif
7171 #ifdef _PC_MAX_CANON
7172 {"PC_MAX_CANON", _PC_MAX_CANON},
7173 #endif
7174 #ifdef _PC_MAX_INPUT
7175 {"PC_MAX_INPUT", _PC_MAX_INPUT},
7176 #endif
7177 #ifdef _PC_NAME_MAX
7178 {"PC_NAME_MAX", _PC_NAME_MAX},
7179 #endif
7180 #ifdef _PC_NO_TRUNC
7181 {"PC_NO_TRUNC", _PC_NO_TRUNC},
7182 #endif
7183 #ifdef _PC_PATH_MAX
7184 {"PC_PATH_MAX", _PC_PATH_MAX},
7185 #endif
7186 #ifdef _PC_PIPE_BUF
7187 {"PC_PIPE_BUF", _PC_PIPE_BUF},
7188 #endif
7189 #ifdef _PC_PRIO_IO
7190 {"PC_PRIO_IO", _PC_PRIO_IO},
7191 #endif
7192 #ifdef _PC_SOCK_MAXBUF
7193 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
7194 #endif
7195 #ifdef _PC_SYNC_IO
7196 {"PC_SYNC_IO", _PC_SYNC_IO},
7197 #endif
7198 #ifdef _PC_VDISABLE
7199 {"PC_VDISABLE", _PC_VDISABLE},
7200 #endif
7203 static int
7204 conv_path_confname(PyObject *arg, int *valuep)
7206 return conv_confname(arg, valuep, posix_constants_pathconf,
7207 sizeof(posix_constants_pathconf)
7208 / sizeof(struct constdef));
7210 #endif
7212 #ifdef HAVE_FPATHCONF
7213 PyDoc_STRVAR(posix_fpathconf__doc__,
7214 "fpathconf(fd, name) -> integer\n\n\
7215 Return the configuration limit name for the file descriptor fd.\n\
7216 If there is no limit, return -1.");
7218 static PyObject *
7219 posix_fpathconf(PyObject *self, PyObject *args)
7221 PyObject *result = NULL;
7222 int name, fd;
7224 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
7225 conv_path_confname, &name)) {
7226 long limit;
7228 errno = 0;
7229 limit = fpathconf(fd, name);
7230 if (limit == -1 && errno != 0)
7231 posix_error();
7232 else
7233 result = PyInt_FromLong(limit);
7235 return result;
7237 #endif
7240 #ifdef HAVE_PATHCONF
7241 PyDoc_STRVAR(posix_pathconf__doc__,
7242 "pathconf(path, name) -> integer\n\n\
7243 Return the configuration limit name for the file or directory path.\n\
7244 If there is no limit, return -1.");
7246 static PyObject *
7247 posix_pathconf(PyObject *self, PyObject *args)
7249 PyObject *result = NULL;
7250 int name;
7251 char *path;
7253 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
7254 conv_path_confname, &name)) {
7255 long limit;
7257 errno = 0;
7258 limit = pathconf(path, name);
7259 if (limit == -1 && errno != 0) {
7260 if (errno == EINVAL)
7261 /* could be a path or name problem */
7262 posix_error();
7263 else
7264 posix_error_with_filename(path);
7266 else
7267 result = PyInt_FromLong(limit);
7269 return result;
7271 #endif
7273 #ifdef HAVE_CONFSTR
7274 static struct constdef posix_constants_confstr[] = {
7275 #ifdef _CS_ARCHITECTURE
7276 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
7277 #endif
7278 #ifdef _CS_HOSTNAME
7279 {"CS_HOSTNAME", _CS_HOSTNAME},
7280 #endif
7281 #ifdef _CS_HW_PROVIDER
7282 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
7283 #endif
7284 #ifdef _CS_HW_SERIAL
7285 {"CS_HW_SERIAL", _CS_HW_SERIAL},
7286 #endif
7287 #ifdef _CS_INITTAB_NAME
7288 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
7289 #endif
7290 #ifdef _CS_LFS64_CFLAGS
7291 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
7292 #endif
7293 #ifdef _CS_LFS64_LDFLAGS
7294 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
7295 #endif
7296 #ifdef _CS_LFS64_LIBS
7297 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
7298 #endif
7299 #ifdef _CS_LFS64_LINTFLAGS
7300 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
7301 #endif
7302 #ifdef _CS_LFS_CFLAGS
7303 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
7304 #endif
7305 #ifdef _CS_LFS_LDFLAGS
7306 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
7307 #endif
7308 #ifdef _CS_LFS_LIBS
7309 {"CS_LFS_LIBS", _CS_LFS_LIBS},
7310 #endif
7311 #ifdef _CS_LFS_LINTFLAGS
7312 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
7313 #endif
7314 #ifdef _CS_MACHINE
7315 {"CS_MACHINE", _CS_MACHINE},
7316 #endif
7317 #ifdef _CS_PATH
7318 {"CS_PATH", _CS_PATH},
7319 #endif
7320 #ifdef _CS_RELEASE
7321 {"CS_RELEASE", _CS_RELEASE},
7322 #endif
7323 #ifdef _CS_SRPC_DOMAIN
7324 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
7325 #endif
7326 #ifdef _CS_SYSNAME
7327 {"CS_SYSNAME", _CS_SYSNAME},
7328 #endif
7329 #ifdef _CS_VERSION
7330 {"CS_VERSION", _CS_VERSION},
7331 #endif
7332 #ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
7333 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
7334 #endif
7335 #ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
7336 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
7337 #endif
7338 #ifdef _CS_XBS5_ILP32_OFF32_LIBS
7339 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
7340 #endif
7341 #ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
7342 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
7343 #endif
7344 #ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
7345 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
7346 #endif
7347 #ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
7348 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
7349 #endif
7350 #ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
7351 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
7352 #endif
7353 #ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
7354 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
7355 #endif
7356 #ifdef _CS_XBS5_LP64_OFF64_CFLAGS
7357 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
7358 #endif
7359 #ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
7360 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
7361 #endif
7362 #ifdef _CS_XBS5_LP64_OFF64_LIBS
7363 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
7364 #endif
7365 #ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
7366 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
7367 #endif
7368 #ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
7369 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
7370 #endif
7371 #ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
7372 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
7373 #endif
7374 #ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
7375 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
7376 #endif
7377 #ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
7378 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
7379 #endif
7380 #ifdef _MIPS_CS_AVAIL_PROCESSORS
7381 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
7382 #endif
7383 #ifdef _MIPS_CS_BASE
7384 {"MIPS_CS_BASE", _MIPS_CS_BASE},
7385 #endif
7386 #ifdef _MIPS_CS_HOSTID
7387 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
7388 #endif
7389 #ifdef _MIPS_CS_HW_NAME
7390 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
7391 #endif
7392 #ifdef _MIPS_CS_NUM_PROCESSORS
7393 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
7394 #endif
7395 #ifdef _MIPS_CS_OSREL_MAJ
7396 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
7397 #endif
7398 #ifdef _MIPS_CS_OSREL_MIN
7399 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
7400 #endif
7401 #ifdef _MIPS_CS_OSREL_PATCH
7402 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
7403 #endif
7404 #ifdef _MIPS_CS_OS_NAME
7405 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
7406 #endif
7407 #ifdef _MIPS_CS_OS_PROVIDER
7408 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
7409 #endif
7410 #ifdef _MIPS_CS_PROCESSORS
7411 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
7412 #endif
7413 #ifdef _MIPS_CS_SERIAL
7414 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
7415 #endif
7416 #ifdef _MIPS_CS_VENDOR
7417 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
7418 #endif
7421 static int
7422 conv_confstr_confname(PyObject *arg, int *valuep)
7424 return conv_confname(arg, valuep, posix_constants_confstr,
7425 sizeof(posix_constants_confstr)
7426 / sizeof(struct constdef));
7429 PyDoc_STRVAR(posix_confstr__doc__,
7430 "confstr(name) -> string\n\n\
7431 Return a string-valued system configuration variable.");
7433 static PyObject *
7434 posix_confstr(PyObject *self, PyObject *args)
7436 PyObject *result = NULL;
7437 int name;
7438 char buffer[256];
7440 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
7441 int len;
7443 errno = 0;
7444 len = confstr(name, buffer, sizeof(buffer));
7445 if (len == 0) {
7446 if (errno) {
7447 posix_error();
7449 else {
7450 result = Py_None;
7451 Py_INCREF(Py_None);
7454 else {
7455 if ((unsigned int)len >= sizeof(buffer)) {
7456 result = PyString_FromStringAndSize(NULL, len-1);
7457 if (result != NULL)
7458 confstr(name, PyString_AS_STRING(result), len);
7460 else
7461 result = PyString_FromStringAndSize(buffer, len-1);
7464 return result;
7466 #endif
7469 #ifdef HAVE_SYSCONF
7470 static struct constdef posix_constants_sysconf[] = {
7471 #ifdef _SC_2_CHAR_TERM
7472 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
7473 #endif
7474 #ifdef _SC_2_C_BIND
7475 {"SC_2_C_BIND", _SC_2_C_BIND},
7476 #endif
7477 #ifdef _SC_2_C_DEV
7478 {"SC_2_C_DEV", _SC_2_C_DEV},
7479 #endif
7480 #ifdef _SC_2_C_VERSION
7481 {"SC_2_C_VERSION", _SC_2_C_VERSION},
7482 #endif
7483 #ifdef _SC_2_FORT_DEV
7484 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
7485 #endif
7486 #ifdef _SC_2_FORT_RUN
7487 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
7488 #endif
7489 #ifdef _SC_2_LOCALEDEF
7490 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
7491 #endif
7492 #ifdef _SC_2_SW_DEV
7493 {"SC_2_SW_DEV", _SC_2_SW_DEV},
7494 #endif
7495 #ifdef _SC_2_UPE
7496 {"SC_2_UPE", _SC_2_UPE},
7497 #endif
7498 #ifdef _SC_2_VERSION
7499 {"SC_2_VERSION", _SC_2_VERSION},
7500 #endif
7501 #ifdef _SC_ABI_ASYNCHRONOUS_IO
7502 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
7503 #endif
7504 #ifdef _SC_ACL
7505 {"SC_ACL", _SC_ACL},
7506 #endif
7507 #ifdef _SC_AIO_LISTIO_MAX
7508 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
7509 #endif
7510 #ifdef _SC_AIO_MAX
7511 {"SC_AIO_MAX", _SC_AIO_MAX},
7512 #endif
7513 #ifdef _SC_AIO_PRIO_DELTA_MAX
7514 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
7515 #endif
7516 #ifdef _SC_ARG_MAX
7517 {"SC_ARG_MAX", _SC_ARG_MAX},
7518 #endif
7519 #ifdef _SC_ASYNCHRONOUS_IO
7520 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
7521 #endif
7522 #ifdef _SC_ATEXIT_MAX
7523 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
7524 #endif
7525 #ifdef _SC_AUDIT
7526 {"SC_AUDIT", _SC_AUDIT},
7527 #endif
7528 #ifdef _SC_AVPHYS_PAGES
7529 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
7530 #endif
7531 #ifdef _SC_BC_BASE_MAX
7532 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
7533 #endif
7534 #ifdef _SC_BC_DIM_MAX
7535 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
7536 #endif
7537 #ifdef _SC_BC_SCALE_MAX
7538 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
7539 #endif
7540 #ifdef _SC_BC_STRING_MAX
7541 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
7542 #endif
7543 #ifdef _SC_CAP
7544 {"SC_CAP", _SC_CAP},
7545 #endif
7546 #ifdef _SC_CHARCLASS_NAME_MAX
7547 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
7548 #endif
7549 #ifdef _SC_CHAR_BIT
7550 {"SC_CHAR_BIT", _SC_CHAR_BIT},
7551 #endif
7552 #ifdef _SC_CHAR_MAX
7553 {"SC_CHAR_MAX", _SC_CHAR_MAX},
7554 #endif
7555 #ifdef _SC_CHAR_MIN
7556 {"SC_CHAR_MIN", _SC_CHAR_MIN},
7557 #endif
7558 #ifdef _SC_CHILD_MAX
7559 {"SC_CHILD_MAX", _SC_CHILD_MAX},
7560 #endif
7561 #ifdef _SC_CLK_TCK
7562 {"SC_CLK_TCK", _SC_CLK_TCK},
7563 #endif
7564 #ifdef _SC_COHER_BLKSZ
7565 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
7566 #endif
7567 #ifdef _SC_COLL_WEIGHTS_MAX
7568 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
7569 #endif
7570 #ifdef _SC_DCACHE_ASSOC
7571 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
7572 #endif
7573 #ifdef _SC_DCACHE_BLKSZ
7574 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
7575 #endif
7576 #ifdef _SC_DCACHE_LINESZ
7577 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
7578 #endif
7579 #ifdef _SC_DCACHE_SZ
7580 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
7581 #endif
7582 #ifdef _SC_DCACHE_TBLKSZ
7583 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
7584 #endif
7585 #ifdef _SC_DELAYTIMER_MAX
7586 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
7587 #endif
7588 #ifdef _SC_EQUIV_CLASS_MAX
7589 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
7590 #endif
7591 #ifdef _SC_EXPR_NEST_MAX
7592 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
7593 #endif
7594 #ifdef _SC_FSYNC
7595 {"SC_FSYNC", _SC_FSYNC},
7596 #endif
7597 #ifdef _SC_GETGR_R_SIZE_MAX
7598 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
7599 #endif
7600 #ifdef _SC_GETPW_R_SIZE_MAX
7601 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
7602 #endif
7603 #ifdef _SC_ICACHE_ASSOC
7604 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
7605 #endif
7606 #ifdef _SC_ICACHE_BLKSZ
7607 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
7608 #endif
7609 #ifdef _SC_ICACHE_LINESZ
7610 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
7611 #endif
7612 #ifdef _SC_ICACHE_SZ
7613 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
7614 #endif
7615 #ifdef _SC_INF
7616 {"SC_INF", _SC_INF},
7617 #endif
7618 #ifdef _SC_INT_MAX
7619 {"SC_INT_MAX", _SC_INT_MAX},
7620 #endif
7621 #ifdef _SC_INT_MIN
7622 {"SC_INT_MIN", _SC_INT_MIN},
7623 #endif
7624 #ifdef _SC_IOV_MAX
7625 {"SC_IOV_MAX", _SC_IOV_MAX},
7626 #endif
7627 #ifdef _SC_IP_SECOPTS
7628 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
7629 #endif
7630 #ifdef _SC_JOB_CONTROL
7631 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
7632 #endif
7633 #ifdef _SC_KERN_POINTERS
7634 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
7635 #endif
7636 #ifdef _SC_KERN_SIM
7637 {"SC_KERN_SIM", _SC_KERN_SIM},
7638 #endif
7639 #ifdef _SC_LINE_MAX
7640 {"SC_LINE_MAX", _SC_LINE_MAX},
7641 #endif
7642 #ifdef _SC_LOGIN_NAME_MAX
7643 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
7644 #endif
7645 #ifdef _SC_LOGNAME_MAX
7646 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
7647 #endif
7648 #ifdef _SC_LONG_BIT
7649 {"SC_LONG_BIT", _SC_LONG_BIT},
7650 #endif
7651 #ifdef _SC_MAC
7652 {"SC_MAC", _SC_MAC},
7653 #endif
7654 #ifdef _SC_MAPPED_FILES
7655 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
7656 #endif
7657 #ifdef _SC_MAXPID
7658 {"SC_MAXPID", _SC_MAXPID},
7659 #endif
7660 #ifdef _SC_MB_LEN_MAX
7661 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
7662 #endif
7663 #ifdef _SC_MEMLOCK
7664 {"SC_MEMLOCK", _SC_MEMLOCK},
7665 #endif
7666 #ifdef _SC_MEMLOCK_RANGE
7667 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
7668 #endif
7669 #ifdef _SC_MEMORY_PROTECTION
7670 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
7671 #endif
7672 #ifdef _SC_MESSAGE_PASSING
7673 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
7674 #endif
7675 #ifdef _SC_MMAP_FIXED_ALIGNMENT
7676 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
7677 #endif
7678 #ifdef _SC_MQ_OPEN_MAX
7679 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
7680 #endif
7681 #ifdef _SC_MQ_PRIO_MAX
7682 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
7683 #endif
7684 #ifdef _SC_NACLS_MAX
7685 {"SC_NACLS_MAX", _SC_NACLS_MAX},
7686 #endif
7687 #ifdef _SC_NGROUPS_MAX
7688 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
7689 #endif
7690 #ifdef _SC_NL_ARGMAX
7691 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
7692 #endif
7693 #ifdef _SC_NL_LANGMAX
7694 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
7695 #endif
7696 #ifdef _SC_NL_MSGMAX
7697 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
7698 #endif
7699 #ifdef _SC_NL_NMAX
7700 {"SC_NL_NMAX", _SC_NL_NMAX},
7701 #endif
7702 #ifdef _SC_NL_SETMAX
7703 {"SC_NL_SETMAX", _SC_NL_SETMAX},
7704 #endif
7705 #ifdef _SC_NL_TEXTMAX
7706 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
7707 #endif
7708 #ifdef _SC_NPROCESSORS_CONF
7709 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
7710 #endif
7711 #ifdef _SC_NPROCESSORS_ONLN
7712 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
7713 #endif
7714 #ifdef _SC_NPROC_CONF
7715 {"SC_NPROC_CONF", _SC_NPROC_CONF},
7716 #endif
7717 #ifdef _SC_NPROC_ONLN
7718 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
7719 #endif
7720 #ifdef _SC_NZERO
7721 {"SC_NZERO", _SC_NZERO},
7722 #endif
7723 #ifdef _SC_OPEN_MAX
7724 {"SC_OPEN_MAX", _SC_OPEN_MAX},
7725 #endif
7726 #ifdef _SC_PAGESIZE
7727 {"SC_PAGESIZE", _SC_PAGESIZE},
7728 #endif
7729 #ifdef _SC_PAGE_SIZE
7730 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
7731 #endif
7732 #ifdef _SC_PASS_MAX
7733 {"SC_PASS_MAX", _SC_PASS_MAX},
7734 #endif
7735 #ifdef _SC_PHYS_PAGES
7736 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
7737 #endif
7738 #ifdef _SC_PII
7739 {"SC_PII", _SC_PII},
7740 #endif
7741 #ifdef _SC_PII_INTERNET
7742 {"SC_PII_INTERNET", _SC_PII_INTERNET},
7743 #endif
7744 #ifdef _SC_PII_INTERNET_DGRAM
7745 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
7746 #endif
7747 #ifdef _SC_PII_INTERNET_STREAM
7748 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
7749 #endif
7750 #ifdef _SC_PII_OSI
7751 {"SC_PII_OSI", _SC_PII_OSI},
7752 #endif
7753 #ifdef _SC_PII_OSI_CLTS
7754 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
7755 #endif
7756 #ifdef _SC_PII_OSI_COTS
7757 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
7758 #endif
7759 #ifdef _SC_PII_OSI_M
7760 {"SC_PII_OSI_M", _SC_PII_OSI_M},
7761 #endif
7762 #ifdef _SC_PII_SOCKET
7763 {"SC_PII_SOCKET", _SC_PII_SOCKET},
7764 #endif
7765 #ifdef _SC_PII_XTI
7766 {"SC_PII_XTI", _SC_PII_XTI},
7767 #endif
7768 #ifdef _SC_POLL
7769 {"SC_POLL", _SC_POLL},
7770 #endif
7771 #ifdef _SC_PRIORITIZED_IO
7772 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
7773 #endif
7774 #ifdef _SC_PRIORITY_SCHEDULING
7775 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
7776 #endif
7777 #ifdef _SC_REALTIME_SIGNALS
7778 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
7779 #endif
7780 #ifdef _SC_RE_DUP_MAX
7781 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
7782 #endif
7783 #ifdef _SC_RTSIG_MAX
7784 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
7785 #endif
7786 #ifdef _SC_SAVED_IDS
7787 {"SC_SAVED_IDS", _SC_SAVED_IDS},
7788 #endif
7789 #ifdef _SC_SCHAR_MAX
7790 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
7791 #endif
7792 #ifdef _SC_SCHAR_MIN
7793 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
7794 #endif
7795 #ifdef _SC_SELECT
7796 {"SC_SELECT", _SC_SELECT},
7797 #endif
7798 #ifdef _SC_SEMAPHORES
7799 {"SC_SEMAPHORES", _SC_SEMAPHORES},
7800 #endif
7801 #ifdef _SC_SEM_NSEMS_MAX
7802 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
7803 #endif
7804 #ifdef _SC_SEM_VALUE_MAX
7805 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
7806 #endif
7807 #ifdef _SC_SHARED_MEMORY_OBJECTS
7808 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
7809 #endif
7810 #ifdef _SC_SHRT_MAX
7811 {"SC_SHRT_MAX", _SC_SHRT_MAX},
7812 #endif
7813 #ifdef _SC_SHRT_MIN
7814 {"SC_SHRT_MIN", _SC_SHRT_MIN},
7815 #endif
7816 #ifdef _SC_SIGQUEUE_MAX
7817 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
7818 #endif
7819 #ifdef _SC_SIGRT_MAX
7820 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
7821 #endif
7822 #ifdef _SC_SIGRT_MIN
7823 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
7824 #endif
7825 #ifdef _SC_SOFTPOWER
7826 {"SC_SOFTPOWER", _SC_SOFTPOWER},
7827 #endif
7828 #ifdef _SC_SPLIT_CACHE
7829 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
7830 #endif
7831 #ifdef _SC_SSIZE_MAX
7832 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
7833 #endif
7834 #ifdef _SC_STACK_PROT
7835 {"SC_STACK_PROT", _SC_STACK_PROT},
7836 #endif
7837 #ifdef _SC_STREAM_MAX
7838 {"SC_STREAM_MAX", _SC_STREAM_MAX},
7839 #endif
7840 #ifdef _SC_SYNCHRONIZED_IO
7841 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
7842 #endif
7843 #ifdef _SC_THREADS
7844 {"SC_THREADS", _SC_THREADS},
7845 #endif
7846 #ifdef _SC_THREAD_ATTR_STACKADDR
7847 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
7848 #endif
7849 #ifdef _SC_THREAD_ATTR_STACKSIZE
7850 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
7851 #endif
7852 #ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
7853 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
7854 #endif
7855 #ifdef _SC_THREAD_KEYS_MAX
7856 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
7857 #endif
7858 #ifdef _SC_THREAD_PRIORITY_SCHEDULING
7859 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
7860 #endif
7861 #ifdef _SC_THREAD_PRIO_INHERIT
7862 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
7863 #endif
7864 #ifdef _SC_THREAD_PRIO_PROTECT
7865 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
7866 #endif
7867 #ifdef _SC_THREAD_PROCESS_SHARED
7868 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
7869 #endif
7870 #ifdef _SC_THREAD_SAFE_FUNCTIONS
7871 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
7872 #endif
7873 #ifdef _SC_THREAD_STACK_MIN
7874 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
7875 #endif
7876 #ifdef _SC_THREAD_THREADS_MAX
7877 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
7878 #endif
7879 #ifdef _SC_TIMERS
7880 {"SC_TIMERS", _SC_TIMERS},
7881 #endif
7882 #ifdef _SC_TIMER_MAX
7883 {"SC_TIMER_MAX", _SC_TIMER_MAX},
7884 #endif
7885 #ifdef _SC_TTY_NAME_MAX
7886 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
7887 #endif
7888 #ifdef _SC_TZNAME_MAX
7889 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
7890 #endif
7891 #ifdef _SC_T_IOV_MAX
7892 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
7893 #endif
7894 #ifdef _SC_UCHAR_MAX
7895 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
7896 #endif
7897 #ifdef _SC_UINT_MAX
7898 {"SC_UINT_MAX", _SC_UINT_MAX},
7899 #endif
7900 #ifdef _SC_UIO_MAXIOV
7901 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
7902 #endif
7903 #ifdef _SC_ULONG_MAX
7904 {"SC_ULONG_MAX", _SC_ULONG_MAX},
7905 #endif
7906 #ifdef _SC_USHRT_MAX
7907 {"SC_USHRT_MAX", _SC_USHRT_MAX},
7908 #endif
7909 #ifdef _SC_VERSION
7910 {"SC_VERSION", _SC_VERSION},
7911 #endif
7912 #ifdef _SC_WORD_BIT
7913 {"SC_WORD_BIT", _SC_WORD_BIT},
7914 #endif
7915 #ifdef _SC_XBS5_ILP32_OFF32
7916 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
7917 #endif
7918 #ifdef _SC_XBS5_ILP32_OFFBIG
7919 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
7920 #endif
7921 #ifdef _SC_XBS5_LP64_OFF64
7922 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
7923 #endif
7924 #ifdef _SC_XBS5_LPBIG_OFFBIG
7925 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
7926 #endif
7927 #ifdef _SC_XOPEN_CRYPT
7928 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
7929 #endif
7930 #ifdef _SC_XOPEN_ENH_I18N
7931 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
7932 #endif
7933 #ifdef _SC_XOPEN_LEGACY
7934 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
7935 #endif
7936 #ifdef _SC_XOPEN_REALTIME
7937 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
7938 #endif
7939 #ifdef _SC_XOPEN_REALTIME_THREADS
7940 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
7941 #endif
7942 #ifdef _SC_XOPEN_SHM
7943 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
7944 #endif
7945 #ifdef _SC_XOPEN_UNIX
7946 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
7947 #endif
7948 #ifdef _SC_XOPEN_VERSION
7949 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
7950 #endif
7951 #ifdef _SC_XOPEN_XCU_VERSION
7952 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
7953 #endif
7954 #ifdef _SC_XOPEN_XPG2
7955 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
7956 #endif
7957 #ifdef _SC_XOPEN_XPG3
7958 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
7959 #endif
7960 #ifdef _SC_XOPEN_XPG4
7961 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
7962 #endif
7965 static int
7966 conv_sysconf_confname(PyObject *arg, int *valuep)
7968 return conv_confname(arg, valuep, posix_constants_sysconf,
7969 sizeof(posix_constants_sysconf)
7970 / sizeof(struct constdef));
7973 PyDoc_STRVAR(posix_sysconf__doc__,
7974 "sysconf(name) -> integer\n\n\
7975 Return an integer-valued system configuration variable.");
7977 static PyObject *
7978 posix_sysconf(PyObject *self, PyObject *args)
7980 PyObject *result = NULL;
7981 int name;
7983 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
7984 int value;
7986 errno = 0;
7987 value = sysconf(name);
7988 if (value == -1 && errno != 0)
7989 posix_error();
7990 else
7991 result = PyInt_FromLong(value);
7993 return result;
7995 #endif
7998 /* This code is used to ensure that the tables of configuration value names
7999 * are in sorted order as required by conv_confname(), and also to build the
8000 * the exported dictionaries that are used to publish information about the
8001 * names available on the host platform.
8003 * Sorting the table at runtime ensures that the table is properly ordered
8004 * when used, even for platforms we're not able to test on. It also makes
8005 * it easier to add additional entries to the tables.
8008 static int
8009 cmp_constdefs(const void *v1, const void *v2)
8011 const struct constdef *c1 =
8012 (const struct constdef *) v1;
8013 const struct constdef *c2 =
8014 (const struct constdef *) v2;
8016 return strcmp(c1->name, c2->name);
8019 static int
8020 setup_confname_table(struct constdef *table, size_t tablesize,
8021 char *tablename, PyObject *module)
8023 PyObject *d = NULL;
8024 size_t i;
8026 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
8027 d = PyDict_New();
8028 if (d == NULL)
8029 return -1;
8031 for (i=0; i < tablesize; ++i) {
8032 PyObject *o = PyInt_FromLong(table[i].value);
8033 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
8034 Py_XDECREF(o);
8035 Py_DECREF(d);
8036 return -1;
8038 Py_DECREF(o);
8040 return PyModule_AddObject(module, tablename, d);
8043 /* Return -1 on failure, 0 on success. */
8044 static int
8045 setup_confname_tables(PyObject *module)
8047 #if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
8048 if (setup_confname_table(posix_constants_pathconf,
8049 sizeof(posix_constants_pathconf)
8050 / sizeof(struct constdef),
8051 "pathconf_names", module))
8052 return -1;
8053 #endif
8054 #ifdef HAVE_CONFSTR
8055 if (setup_confname_table(posix_constants_confstr,
8056 sizeof(posix_constants_confstr)
8057 / sizeof(struct constdef),
8058 "confstr_names", module))
8059 return -1;
8060 #endif
8061 #ifdef HAVE_SYSCONF
8062 if (setup_confname_table(posix_constants_sysconf,
8063 sizeof(posix_constants_sysconf)
8064 / sizeof(struct constdef),
8065 "sysconf_names", module))
8066 return -1;
8067 #endif
8068 return 0;
8072 PyDoc_STRVAR(posix_abort__doc__,
8073 "abort() -> does not return!\n\n\
8074 Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
8075 in the hardest way possible on the hosting operating system.");
8077 static PyObject *
8078 posix_abort(PyObject *self, PyObject *noargs)
8080 abort();
8081 /*NOTREACHED*/
8082 Py_FatalError("abort() called from Python code didn't abort!");
8083 return NULL;
8086 #ifdef MS_WINDOWS
8087 PyDoc_STRVAR(win32_startfile__doc__,
8088 "startfile(filepath [, operation]) - Start a file with its associated\n\
8089 application.\n\
8091 When \"operation\" is not specified or \"open\", this acts like\n\
8092 double-clicking the file in Explorer, or giving the file name as an\n\
8093 argument to the DOS \"start\" command: the file is opened with whatever\n\
8094 application (if any) its extension is associated.\n\
8095 When another \"operation\" is given, it specifies what should be done with\n\
8096 the file. A typical operation is \"print\".\n\
8098 startfile returns as soon as the associated application is launched.\n\
8099 There is no option to wait for the application to close, and no way\n\
8100 to retrieve the application's exit status.\n\
8102 The filepath is relative to the current directory. If you want to use\n\
8103 an absolute path, make sure the first character is not a slash (\"/\");\n\
8104 the underlying Win32 ShellExecute function doesn't work if it is.");
8106 static PyObject *
8107 win32_startfile(PyObject *self, PyObject *args)
8109 char *filepath;
8110 char *operation = NULL;
8111 HINSTANCE rc;
8112 #ifdef Py_WIN_WIDE_FILENAMES
8113 if (unicode_file_names()) {
8114 PyObject *unipath, *woperation = NULL;
8115 if (!PyArg_ParseTuple(args, "U|s:startfile",
8116 &unipath, &operation)) {
8117 PyErr_Clear();
8118 goto normal;
8122 if (operation) {
8123 woperation = PyUnicode_DecodeASCII(operation,
8124 strlen(operation), NULL);
8125 if (!woperation) {
8126 PyErr_Clear();
8127 operation = NULL;
8128 goto normal;
8132 Py_BEGIN_ALLOW_THREADS
8133 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
8134 PyUnicode_AS_UNICODE(unipath),
8135 NULL, NULL, SW_SHOWNORMAL);
8136 Py_END_ALLOW_THREADS
8138 Py_XDECREF(woperation);
8139 if (rc <= (HINSTANCE)32) {
8140 PyObject *errval = win32_error_unicode("startfile",
8141 PyUnicode_AS_UNICODE(unipath));
8142 return errval;
8144 Py_INCREF(Py_None);
8145 return Py_None;
8147 #endif
8149 normal:
8150 if (!PyArg_ParseTuple(args, "et|s:startfile",
8151 Py_FileSystemDefaultEncoding, &filepath,
8152 &operation))
8153 return NULL;
8154 Py_BEGIN_ALLOW_THREADS
8155 rc = ShellExecute((HWND)0, operation, filepath,
8156 NULL, NULL, SW_SHOWNORMAL);
8157 Py_END_ALLOW_THREADS
8158 if (rc <= (HINSTANCE)32) {
8159 PyObject *errval = win32_error("startfile", filepath);
8160 PyMem_Free(filepath);
8161 return errval;
8163 PyMem_Free(filepath);
8164 Py_INCREF(Py_None);
8165 return Py_None;
8167 #endif
8169 #ifdef HAVE_GETLOADAVG
8170 PyDoc_STRVAR(posix_getloadavg__doc__,
8171 "getloadavg() -> (float, float, float)\n\n\
8172 Return the number of processes in the system run queue averaged over\n\
8173 the last 1, 5, and 15 minutes or raises OSError if the load average\n\
8174 was unobtainable");
8176 static PyObject *
8177 posix_getloadavg(PyObject *self, PyObject *noargs)
8179 double loadavg[3];
8180 if (getloadavg(loadavg, 3)!=3) {
8181 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
8182 return NULL;
8183 } else
8184 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
8186 #endif
8188 #ifdef MS_WINDOWS
8190 PyDoc_STRVAR(win32_urandom__doc__,
8191 "urandom(n) -> str\n\n\
8192 Return a string of n random bytes suitable for cryptographic use.");
8194 typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
8195 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
8196 DWORD dwFlags );
8197 typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
8198 BYTE *pbBuffer );
8200 static CRYPTGENRANDOM pCryptGenRandom = NULL;
8201 /* This handle is never explicitly released. Instead, the operating
8202 system will release it when the process terminates. */
8203 static HCRYPTPROV hCryptProv = 0;
8205 static PyObject*
8206 win32_urandom(PyObject *self, PyObject *args)
8208 int howMany;
8209 PyObject* result;
8211 /* Read arguments */
8212 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
8213 return NULL;
8214 if (howMany < 0)
8215 return PyErr_Format(PyExc_ValueError,
8216 "negative argument not allowed");
8218 if (hCryptProv == 0) {
8219 HINSTANCE hAdvAPI32 = NULL;
8220 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
8222 /* Obtain handle to the DLL containing CryptoAPI
8223 This should not fail */
8224 hAdvAPI32 = GetModuleHandle("advapi32.dll");
8225 if(hAdvAPI32 == NULL)
8226 return win32_error("GetModuleHandle", NULL);
8228 /* Obtain pointers to the CryptoAPI functions
8229 This will fail on some early versions of Win95 */
8230 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
8231 hAdvAPI32,
8232 "CryptAcquireContextA");
8233 if (pCryptAcquireContext == NULL)
8234 return PyErr_Format(PyExc_NotImplementedError,
8235 "CryptAcquireContextA not found");
8237 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
8238 hAdvAPI32, "CryptGenRandom");
8239 if (pCryptGenRandom == NULL)
8240 return PyErr_Format(PyExc_NotImplementedError,
8241 "CryptGenRandom not found");
8243 /* Acquire context */
8244 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
8245 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
8246 return win32_error("CryptAcquireContext", NULL);
8249 /* Allocate bytes */
8250 result = PyString_FromStringAndSize(NULL, howMany);
8251 if (result != NULL) {
8252 /* Get random data */
8253 memset(PyString_AS_STRING(result), 0, howMany); /* zero seed */
8254 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
8255 PyString_AS_STRING(result))) {
8256 Py_DECREF(result);
8257 return win32_error("CryptGenRandom", NULL);
8260 return result;
8262 #endif
8264 #ifdef __VMS
8265 /* Use openssl random routine */
8266 #include <openssl/rand.h>
8267 PyDoc_STRVAR(vms_urandom__doc__,
8268 "urandom(n) -> str\n\n\
8269 Return a string of n random bytes suitable for cryptographic use.");
8271 static PyObject*
8272 vms_urandom(PyObject *self, PyObject *args)
8274 int howMany;
8275 PyObject* result;
8277 /* Read arguments */
8278 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
8279 return NULL;
8280 if (howMany < 0)
8281 return PyErr_Format(PyExc_ValueError,
8282 "negative argument not allowed");
8284 /* Allocate bytes */
8285 result = PyString_FromStringAndSize(NULL, howMany);
8286 if (result != NULL) {
8287 /* Get random data */
8288 if (RAND_pseudo_bytes((unsigned char*)
8289 PyString_AS_STRING(result),
8290 howMany) < 0) {
8291 Py_DECREF(result);
8292 return PyErr_Format(PyExc_ValueError,
8293 "RAND_pseudo_bytes");
8296 return result;
8298 #endif
8300 static PyMethodDef posix_methods[] = {
8301 {"access", posix_access, METH_VARARGS, posix_access__doc__},
8302 #ifdef HAVE_TTYNAME
8303 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
8304 #endif
8305 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
8306 #ifdef HAVE_CHFLAGS
8307 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
8308 #endif /* HAVE_CHFLAGS */
8309 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
8310 #ifdef HAVE_FCHMOD
8311 {"fchmod", posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
8312 #endif /* HAVE_FCHMOD */
8313 #ifdef HAVE_CHOWN
8314 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
8315 #endif /* HAVE_CHOWN */
8316 #ifdef HAVE_LCHMOD
8317 {"lchmod", posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
8318 #endif /* HAVE_LCHMOD */
8319 #ifdef HAVE_FCHOWN
8320 {"fchown", posix_fchown, METH_VARARGS, posix_fchown__doc__},
8321 #endif /* HAVE_FCHOWN */
8322 #ifdef HAVE_LCHFLAGS
8323 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
8324 #endif /* HAVE_LCHFLAGS */
8325 #ifdef HAVE_LCHOWN
8326 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
8327 #endif /* HAVE_LCHOWN */
8328 #ifdef HAVE_CHROOT
8329 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
8330 #endif
8331 #ifdef HAVE_CTERMID
8332 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
8333 #endif
8334 #ifdef HAVE_GETCWD
8335 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
8336 #ifdef Py_USING_UNICODE
8337 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
8338 #endif
8339 #endif
8340 #ifdef HAVE_LINK
8341 {"link", posix_link, METH_VARARGS, posix_link__doc__},
8342 #endif /* HAVE_LINK */
8343 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
8344 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
8345 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
8346 #ifdef HAVE_NICE
8347 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
8348 #endif /* HAVE_NICE */
8349 #ifdef HAVE_READLINK
8350 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
8351 #endif /* HAVE_READLINK */
8352 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
8353 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
8354 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
8355 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
8356 #ifdef HAVE_SYMLINK
8357 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
8358 #endif /* HAVE_SYMLINK */
8359 #ifdef HAVE_SYSTEM
8360 {"system", posix_system, METH_VARARGS, posix_system__doc__},
8361 #endif
8362 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
8363 #ifdef HAVE_UNAME
8364 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
8365 #endif /* HAVE_UNAME */
8366 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
8367 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
8368 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
8369 #ifdef HAVE_TIMES
8370 {"times", posix_times, METH_NOARGS, posix_times__doc__},
8371 #endif /* HAVE_TIMES */
8372 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
8373 #ifdef HAVE_EXECV
8374 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
8375 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
8376 #endif /* HAVE_EXECV */
8377 #ifdef HAVE_SPAWNV
8378 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
8379 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
8380 #if defined(PYOS_OS2)
8381 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
8382 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
8383 #endif /* PYOS_OS2 */
8384 #endif /* HAVE_SPAWNV */
8385 #ifdef HAVE_FORK1
8386 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
8387 #endif /* HAVE_FORK1 */
8388 #ifdef HAVE_FORK
8389 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
8390 #endif /* HAVE_FORK */
8391 #if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
8392 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
8393 #endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
8394 #ifdef HAVE_FORKPTY
8395 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
8396 #endif /* HAVE_FORKPTY */
8397 #ifdef HAVE_GETEGID
8398 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
8399 #endif /* HAVE_GETEGID */
8400 #ifdef HAVE_GETEUID
8401 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
8402 #endif /* HAVE_GETEUID */
8403 #ifdef HAVE_GETGID
8404 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
8405 #endif /* HAVE_GETGID */
8406 #ifdef HAVE_GETGROUPS
8407 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
8408 #endif
8409 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
8410 #ifdef HAVE_GETPGRP
8411 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
8412 #endif /* HAVE_GETPGRP */
8413 #ifdef HAVE_GETPPID
8414 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
8415 #endif /* HAVE_GETPPID */
8416 #ifdef HAVE_GETUID
8417 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
8418 #endif /* HAVE_GETUID */
8419 #ifdef HAVE_GETLOGIN
8420 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
8421 #endif
8422 #ifdef HAVE_KILL
8423 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
8424 #endif /* HAVE_KILL */
8425 #ifdef HAVE_KILLPG
8426 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
8427 #endif /* HAVE_KILLPG */
8428 #ifdef HAVE_PLOCK
8429 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
8430 #endif /* HAVE_PLOCK */
8431 #ifdef HAVE_POPEN
8432 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
8433 #ifdef MS_WINDOWS
8434 {"popen2", win32_popen2, METH_VARARGS},
8435 {"popen3", win32_popen3, METH_VARARGS},
8436 {"popen4", win32_popen4, METH_VARARGS},
8437 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
8438 #else
8439 #if defined(PYOS_OS2) && defined(PYCC_GCC)
8440 {"popen2", os2emx_popen2, METH_VARARGS},
8441 {"popen3", os2emx_popen3, METH_VARARGS},
8442 {"popen4", os2emx_popen4, METH_VARARGS},
8443 #endif
8444 #endif
8445 #endif /* HAVE_POPEN */
8446 #ifdef HAVE_SETUID
8447 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
8448 #endif /* HAVE_SETUID */
8449 #ifdef HAVE_SETEUID
8450 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
8451 #endif /* HAVE_SETEUID */
8452 #ifdef HAVE_SETEGID
8453 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
8454 #endif /* HAVE_SETEGID */
8455 #ifdef HAVE_SETREUID
8456 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
8457 #endif /* HAVE_SETREUID */
8458 #ifdef HAVE_SETREGID
8459 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
8460 #endif /* HAVE_SETREGID */
8461 #ifdef HAVE_SETGID
8462 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
8463 #endif /* HAVE_SETGID */
8464 #ifdef HAVE_SETGROUPS
8465 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
8466 #endif /* HAVE_SETGROUPS */
8467 #ifdef HAVE_GETPGID
8468 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
8469 #endif /* HAVE_GETPGID */
8470 #ifdef HAVE_SETPGRP
8471 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
8472 #endif /* HAVE_SETPGRP */
8473 #ifdef HAVE_WAIT
8474 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
8475 #endif /* HAVE_WAIT */
8476 #ifdef HAVE_WAIT3
8477 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
8478 #endif /* HAVE_WAIT3 */
8479 #ifdef HAVE_WAIT4
8480 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
8481 #endif /* HAVE_WAIT4 */
8482 #if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
8483 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
8484 #endif /* HAVE_WAITPID */
8485 #ifdef HAVE_GETSID
8486 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
8487 #endif /* HAVE_GETSID */
8488 #ifdef HAVE_SETSID
8489 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
8490 #endif /* HAVE_SETSID */
8491 #ifdef HAVE_SETPGID
8492 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
8493 #endif /* HAVE_SETPGID */
8494 #ifdef HAVE_TCGETPGRP
8495 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
8496 #endif /* HAVE_TCGETPGRP */
8497 #ifdef HAVE_TCSETPGRP
8498 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
8499 #endif /* HAVE_TCSETPGRP */
8500 {"open", posix_open, METH_VARARGS, posix_open__doc__},
8501 {"close", posix_close, METH_VARARGS, posix_close__doc__},
8502 {"closerange", posix_closerange, METH_VARARGS, posix_closerange__doc__},
8503 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
8504 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
8505 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
8506 {"read", posix_read, METH_VARARGS, posix_read__doc__},
8507 {"write", posix_write, METH_VARARGS, posix_write__doc__},
8508 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
8509 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
8510 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
8511 #ifdef HAVE_PIPE
8512 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
8513 #endif
8514 #ifdef HAVE_MKFIFO
8515 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
8516 #endif
8517 #if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
8518 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
8519 #endif
8520 #ifdef HAVE_DEVICE_MACROS
8521 {"major", posix_major, METH_VARARGS, posix_major__doc__},
8522 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
8523 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
8524 #endif
8525 #ifdef HAVE_FTRUNCATE
8526 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
8527 #endif
8528 #ifdef HAVE_PUTENV
8529 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
8530 #endif
8531 #ifdef HAVE_UNSETENV
8532 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
8533 #endif
8534 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
8535 #ifdef HAVE_FCHDIR
8536 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
8537 #endif
8538 #ifdef HAVE_FSYNC
8539 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
8540 #endif
8541 #ifdef HAVE_FDATASYNC
8542 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
8543 #endif
8544 #ifdef HAVE_SYS_WAIT_H
8545 #ifdef WCOREDUMP
8546 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
8547 #endif /* WCOREDUMP */
8548 #ifdef WIFCONTINUED
8549 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
8550 #endif /* WIFCONTINUED */
8551 #ifdef WIFSTOPPED
8552 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
8553 #endif /* WIFSTOPPED */
8554 #ifdef WIFSIGNALED
8555 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
8556 #endif /* WIFSIGNALED */
8557 #ifdef WIFEXITED
8558 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
8559 #endif /* WIFEXITED */
8560 #ifdef WEXITSTATUS
8561 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
8562 #endif /* WEXITSTATUS */
8563 #ifdef WTERMSIG
8564 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
8565 #endif /* WTERMSIG */
8566 #ifdef WSTOPSIG
8567 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
8568 #endif /* WSTOPSIG */
8569 #endif /* HAVE_SYS_WAIT_H */
8570 #if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
8571 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
8572 #endif
8573 #if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
8574 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
8575 #endif
8576 #ifdef HAVE_TMPFILE
8577 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
8578 #endif
8579 #ifdef HAVE_TEMPNAM
8580 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
8581 #endif
8582 #ifdef HAVE_TMPNAM
8583 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
8584 #endif
8585 #ifdef HAVE_CONFSTR
8586 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
8587 #endif
8588 #ifdef HAVE_SYSCONF
8589 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
8590 #endif
8591 #ifdef HAVE_FPATHCONF
8592 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
8593 #endif
8594 #ifdef HAVE_PATHCONF
8595 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
8596 #endif
8597 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
8598 #ifdef MS_WINDOWS
8599 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
8600 #endif
8601 #ifdef HAVE_GETLOADAVG
8602 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
8603 #endif
8604 #ifdef MS_WINDOWS
8605 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
8606 #endif
8607 #ifdef __VMS
8608 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
8609 #endif
8610 {NULL, NULL} /* Sentinel */
8614 static int
8615 ins(PyObject *module, char *symbol, long value)
8617 return PyModule_AddIntConstant(module, symbol, value);
8620 #if defined(PYOS_OS2)
8621 /* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
8622 static int insertvalues(PyObject *module)
8624 APIRET rc;
8625 ULONG values[QSV_MAX+1];
8626 PyObject *v;
8627 char *ver, tmp[50];
8629 Py_BEGIN_ALLOW_THREADS
8630 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
8631 Py_END_ALLOW_THREADS
8633 if (rc != NO_ERROR) {
8634 os2_error(rc);
8635 return -1;
8638 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
8639 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
8640 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
8641 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
8642 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
8643 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
8644 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
8646 switch (values[QSV_VERSION_MINOR]) {
8647 case 0: ver = "2.00"; break;
8648 case 10: ver = "2.10"; break;
8649 case 11: ver = "2.11"; break;
8650 case 30: ver = "3.00"; break;
8651 case 40: ver = "4.00"; break;
8652 case 50: ver = "5.00"; break;
8653 default:
8654 PyOS_snprintf(tmp, sizeof(tmp),
8655 "%d-%d", values[QSV_VERSION_MAJOR],
8656 values[QSV_VERSION_MINOR]);
8657 ver = &tmp[0];
8660 /* Add Indicator of the Version of the Operating System */
8661 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
8662 return -1;
8664 /* Add Indicator of Which Drive was Used to Boot the System */
8665 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
8666 tmp[1] = ':';
8667 tmp[2] = '\0';
8669 return PyModule_AddStringConstant(module, "bootdrive", tmp);
8671 #endif
8673 static int
8674 all_ins(PyObject *d)
8676 #ifdef F_OK
8677 if (ins(d, "F_OK", (long)F_OK)) return -1;
8678 #endif
8679 #ifdef R_OK
8680 if (ins(d, "R_OK", (long)R_OK)) return -1;
8681 #endif
8682 #ifdef W_OK
8683 if (ins(d, "W_OK", (long)W_OK)) return -1;
8684 #endif
8685 #ifdef X_OK
8686 if (ins(d, "X_OK", (long)X_OK)) return -1;
8687 #endif
8688 #ifdef NGROUPS_MAX
8689 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
8690 #endif
8691 #ifdef TMP_MAX
8692 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
8693 #endif
8694 #ifdef WCONTINUED
8695 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
8696 #endif
8697 #ifdef WNOHANG
8698 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
8699 #endif
8700 #ifdef WUNTRACED
8701 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
8702 #endif
8703 #ifdef O_RDONLY
8704 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
8705 #endif
8706 #ifdef O_WRONLY
8707 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
8708 #endif
8709 #ifdef O_RDWR
8710 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
8711 #endif
8712 #ifdef O_NDELAY
8713 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
8714 #endif
8715 #ifdef O_NONBLOCK
8716 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
8717 #endif
8718 #ifdef O_APPEND
8719 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
8720 #endif
8721 #ifdef O_DSYNC
8722 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
8723 #endif
8724 #ifdef O_RSYNC
8725 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
8726 #endif
8727 #ifdef O_SYNC
8728 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
8729 #endif
8730 #ifdef O_NOCTTY
8731 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
8732 #endif
8733 #ifdef O_CREAT
8734 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
8735 #endif
8736 #ifdef O_EXCL
8737 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
8738 #endif
8739 #ifdef O_TRUNC
8740 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
8741 #endif
8742 #ifdef O_BINARY
8743 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
8744 #endif
8745 #ifdef O_TEXT
8746 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
8747 #endif
8748 #ifdef O_LARGEFILE
8749 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
8750 #endif
8751 #ifdef O_SHLOCK
8752 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
8753 #endif
8754 #ifdef O_EXLOCK
8755 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
8756 #endif
8758 /* MS Windows */
8759 #ifdef O_NOINHERIT
8760 /* Don't inherit in child processes. */
8761 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
8762 #endif
8763 #ifdef _O_SHORT_LIVED
8764 /* Optimize for short life (keep in memory). */
8765 /* MS forgot to define this one with a non-underscore form too. */
8766 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
8767 #endif
8768 #ifdef O_TEMPORARY
8769 /* Automatically delete when last handle is closed. */
8770 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
8771 #endif
8772 #ifdef O_RANDOM
8773 /* Optimize for random access. */
8774 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
8775 #endif
8776 #ifdef O_SEQUENTIAL
8777 /* Optimize for sequential access. */
8778 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
8779 #endif
8781 /* GNU extensions. */
8782 #ifdef O_ASYNC
8783 /* Send a SIGIO signal whenever input or output
8784 becomes available on file descriptor */
8785 if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
8786 #endif
8787 #ifdef O_DIRECT
8788 /* Direct disk access. */
8789 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
8790 #endif
8791 #ifdef O_DIRECTORY
8792 /* Must be a directory. */
8793 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
8794 #endif
8795 #ifdef O_NOFOLLOW
8796 /* Do not follow links. */
8797 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
8798 #endif
8799 #ifdef O_NOATIME
8800 /* Do not update the access time. */
8801 if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
8802 #endif
8804 /* These come from sysexits.h */
8805 #ifdef EX_OK
8806 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
8807 #endif /* EX_OK */
8808 #ifdef EX_USAGE
8809 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
8810 #endif /* EX_USAGE */
8811 #ifdef EX_DATAERR
8812 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
8813 #endif /* EX_DATAERR */
8814 #ifdef EX_NOINPUT
8815 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
8816 #endif /* EX_NOINPUT */
8817 #ifdef EX_NOUSER
8818 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
8819 #endif /* EX_NOUSER */
8820 #ifdef EX_NOHOST
8821 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
8822 #endif /* EX_NOHOST */
8823 #ifdef EX_UNAVAILABLE
8824 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
8825 #endif /* EX_UNAVAILABLE */
8826 #ifdef EX_SOFTWARE
8827 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
8828 #endif /* EX_SOFTWARE */
8829 #ifdef EX_OSERR
8830 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
8831 #endif /* EX_OSERR */
8832 #ifdef EX_OSFILE
8833 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
8834 #endif /* EX_OSFILE */
8835 #ifdef EX_CANTCREAT
8836 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
8837 #endif /* EX_CANTCREAT */
8838 #ifdef EX_IOERR
8839 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
8840 #endif /* EX_IOERR */
8841 #ifdef EX_TEMPFAIL
8842 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
8843 #endif /* EX_TEMPFAIL */
8844 #ifdef EX_PROTOCOL
8845 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
8846 #endif /* EX_PROTOCOL */
8847 #ifdef EX_NOPERM
8848 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
8849 #endif /* EX_NOPERM */
8850 #ifdef EX_CONFIG
8851 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
8852 #endif /* EX_CONFIG */
8853 #ifdef EX_NOTFOUND
8854 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
8855 #endif /* EX_NOTFOUND */
8857 #ifdef HAVE_SPAWNV
8858 #if defined(PYOS_OS2) && defined(PYCC_GCC)
8859 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
8860 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
8861 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
8862 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
8863 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
8864 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
8865 if (ins(d, "P_PM", (long)P_PM)) return -1;
8866 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
8867 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
8868 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
8869 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
8870 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
8871 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
8872 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
8873 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
8874 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
8875 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
8876 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
8877 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
8878 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
8879 #else
8880 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
8881 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
8882 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
8883 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
8884 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
8885 #endif
8886 #endif
8888 #if defined(PYOS_OS2)
8889 if (insertvalues(d)) return -1;
8890 #endif
8891 return 0;
8895 #if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
8896 #define INITFUNC initnt
8897 #define MODNAME "nt"
8899 #elif defined(PYOS_OS2)
8900 #define INITFUNC initos2
8901 #define MODNAME "os2"
8903 #else
8904 #define INITFUNC initposix
8905 #define MODNAME "posix"
8906 #endif
8908 PyMODINIT_FUNC
8909 INITFUNC(void)
8911 PyObject *m, *v;
8913 m = Py_InitModule3(MODNAME,
8914 posix_methods,
8915 posix__doc__);
8916 if (m == NULL)
8917 return;
8919 /* Initialize environ dictionary */
8920 v = convertenviron();
8921 Py_XINCREF(v);
8922 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
8923 return;
8924 Py_DECREF(v);
8926 if (all_ins(m))
8927 return;
8929 if (setup_confname_tables(m))
8930 return;
8932 Py_INCREF(PyExc_OSError);
8933 PyModule_AddObject(m, "error", PyExc_OSError);
8935 #ifdef HAVE_PUTENV
8936 if (posix_putenv_garbage == NULL)
8937 posix_putenv_garbage = PyDict_New();
8938 #endif
8940 if (!initialized) {
8941 stat_result_desc.name = MODNAME ".stat_result";
8942 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
8943 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
8944 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
8945 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
8946 structseq_new = StatResultType.tp_new;
8947 StatResultType.tp_new = statresult_new;
8949 statvfs_result_desc.name = MODNAME ".statvfs_result";
8950 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
8952 Py_INCREF((PyObject*) &StatResultType);
8953 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
8954 Py_INCREF((PyObject*) &StatVFSResultType);
8955 PyModule_AddObject(m, "statvfs_result",
8956 (PyObject*) &StatVFSResultType);
8957 initialized = 1;
8959 #ifdef __APPLE__
8961 * Step 2 of weak-linking support on Mac OS X.
8963 * The code below removes functions that are not available on the
8964 * currently active platform.
8966 * This block allow one to use a python binary that was build on
8967 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
8968 * OSX 10.4.
8970 #ifdef HAVE_FSTATVFS
8971 if (fstatvfs == NULL) {
8972 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
8973 return;
8976 #endif /* HAVE_FSTATVFS */
8978 #ifdef HAVE_STATVFS
8979 if (statvfs == NULL) {
8980 if (PyObject_DelAttrString(m, "statvfs") == -1) {
8981 return;
8984 #endif /* HAVE_STATVFS */
8986 # ifdef HAVE_LCHOWN
8987 if (lchown == NULL) {
8988 if (PyObject_DelAttrString(m, "lchown") == -1) {
8989 return;
8992 #endif /* HAVE_LCHOWN */
8995 #endif /* __APPLE__ */
8999 #ifdef __cplusplus
9001 #endif