Its time to stop listing (Unix, Windows) when we really mean "everything but Mac...
[python.git] / Modules / posixmodule.c
blobb9572cfa01e29ef133672e2bdda8ba404d317653
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 extern int chown(const char *, uid_t, gid_t);
195 extern char *getcwd(char *, int);
196 extern char *strerror(int);
197 extern int link(const char *, const char *);
198 extern int rename(const char *, const char *);
199 extern int stat(const char *, struct stat *);
200 extern int unlink(const char *);
201 extern int pclose(FILE *);
202 #ifdef HAVE_SYMLINK
203 extern int symlink(const char *, const char *);
204 #endif /* HAVE_SYMLINK */
205 #ifdef HAVE_LSTAT
206 extern int lstat(const char *, struct stat *);
207 #endif /* HAVE_LSTAT */
208 #endif /* !HAVE_UNISTD_H */
210 #endif /* !_MSC_VER */
212 #ifdef HAVE_UTIME_H
213 #include <utime.h>
214 #endif /* HAVE_UTIME_H */
216 #ifdef HAVE_SYS_UTIME_H
217 #include <sys/utime.h>
218 #define HAVE_UTIME_H /* pretend we do for the rest of this file */
219 #endif /* HAVE_SYS_UTIME_H */
221 #ifdef HAVE_SYS_TIMES_H
222 #include <sys/times.h>
223 #endif /* HAVE_SYS_TIMES_H */
225 #ifdef HAVE_SYS_PARAM_H
226 #include <sys/param.h>
227 #endif /* HAVE_SYS_PARAM_H */
229 #ifdef HAVE_SYS_UTSNAME_H
230 #include <sys/utsname.h>
231 #endif /* HAVE_SYS_UTSNAME_H */
233 #ifdef HAVE_DIRENT_H
234 #include <dirent.h>
235 #define NAMLEN(dirent) strlen((dirent)->d_name)
236 #else
237 #if defined(__WATCOMC__) && !defined(__QNX__)
238 #include <direct.h>
239 #define NAMLEN(dirent) strlen((dirent)->d_name)
240 #else
241 #define dirent direct
242 #define NAMLEN(dirent) (dirent)->d_namlen
243 #endif
244 #ifdef HAVE_SYS_NDIR_H
245 #include <sys/ndir.h>
246 #endif
247 #ifdef HAVE_SYS_DIR_H
248 #include <sys/dir.h>
249 #endif
250 #ifdef HAVE_NDIR_H
251 #include <ndir.h>
252 #endif
253 #endif
255 #ifdef _MSC_VER
256 #ifdef HAVE_DIRECT_H
257 #include <direct.h>
258 #endif
259 #ifdef HAVE_IO_H
260 #include <io.h>
261 #endif
262 #ifdef HAVE_PROCESS_H
263 #include <process.h>
264 #endif
265 #include "osdefs.h"
266 #define _WIN32_WINNT 0x0400 /* Needed for CryptoAPI on some systems */
267 #include <windows.h>
268 #include <shellapi.h> /* for ShellExecute() */
269 #define popen _popen
270 #define pclose _pclose
271 #endif /* _MSC_VER */
273 #if defined(PYCC_VACPP) && defined(PYOS_OS2)
274 #include <io.h>
275 #endif /* OS2 */
277 #ifndef MAXPATHLEN
278 #if defined(PATH_MAX) && PATH_MAX > 1024
279 #define MAXPATHLEN PATH_MAX
280 #else
281 #define MAXPATHLEN 1024
282 #endif
283 #endif /* MAXPATHLEN */
285 #ifdef UNION_WAIT
286 /* Emulate some macros on systems that have a union instead of macros */
288 #ifndef WIFEXITED
289 #define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
290 #endif
292 #ifndef WEXITSTATUS
293 #define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
294 #endif
296 #ifndef WTERMSIG
297 #define WTERMSIG(u_wait) ((u_wait).w_termsig)
298 #endif
300 #define WAIT_TYPE union wait
301 #define WAIT_STATUS_INT(s) (s.w_status)
303 #else /* !UNION_WAIT */
304 #define WAIT_TYPE int
305 #define WAIT_STATUS_INT(s) (s)
306 #endif /* UNION_WAIT */
308 /* Don't use the "_r" form if we don't need it (also, won't have a
309 prototype for it, at least on Solaris -- maybe others as well?). */
310 #if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
311 #define USE_CTERMID_R
312 #endif
314 #if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
315 #define USE_TMPNAM_R
316 #endif
318 /* choose the appropriate stat and fstat functions and return structs */
319 #undef STAT
320 #if defined(MS_WIN64) || defined(MS_WINDOWS)
321 # define STAT win32_stat
322 # define FSTAT win32_fstat
323 # define STRUCT_STAT struct win32_stat
324 #else
325 # define STAT stat
326 # define FSTAT fstat
327 # define STRUCT_STAT struct stat
328 #endif
330 #if defined(MAJOR_IN_MKDEV)
331 #include <sys/mkdev.h>
332 #else
333 #if defined(MAJOR_IN_SYSMACROS)
334 #include <sys/sysmacros.h>
335 #endif
336 #if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
337 #include <sys/mkdev.h>
338 #endif
339 #endif
341 /* Return a dictionary corresponding to the POSIX environment table */
342 #ifdef WITH_NEXT_FRAMEWORK
343 /* On Darwin/MacOSX a shared library or framework has no access to
344 ** environ directly, we must obtain it with _NSGetEnviron().
346 #include <crt_externs.h>
347 static char **environ;
348 #elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
349 extern char **environ;
350 #endif /* !_MSC_VER */
352 static PyObject *
353 convertenviron(void)
355 PyObject *d;
356 char **e;
357 d = PyDict_New();
358 if (d == NULL)
359 return NULL;
360 #ifdef WITH_NEXT_FRAMEWORK
361 if (environ == NULL)
362 environ = *_NSGetEnviron();
363 #endif
364 if (environ == NULL)
365 return d;
366 /* This part ignores errors */
367 for (e = environ; *e != NULL; e++) {
368 PyObject *k;
369 PyObject *v;
370 char *p = strchr(*e, '=');
371 if (p == NULL)
372 continue;
373 k = PyString_FromStringAndSize(*e, (int)(p-*e));
374 if (k == NULL) {
375 PyErr_Clear();
376 continue;
378 v = PyString_FromString(p+1);
379 if (v == NULL) {
380 PyErr_Clear();
381 Py_DECREF(k);
382 continue;
384 if (PyDict_GetItem(d, k) == NULL) {
385 if (PyDict_SetItem(d, k, v) != 0)
386 PyErr_Clear();
388 Py_DECREF(k);
389 Py_DECREF(v);
391 #if defined(PYOS_OS2)
393 APIRET rc;
394 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
396 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
397 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
398 PyObject *v = PyString_FromString(buffer);
399 PyDict_SetItemString(d, "BEGINLIBPATH", v);
400 Py_DECREF(v);
402 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
403 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
404 PyObject *v = PyString_FromString(buffer);
405 PyDict_SetItemString(d, "ENDLIBPATH", v);
406 Py_DECREF(v);
409 #endif
410 return d;
414 /* Set a POSIX-specific error from errno, and return NULL */
416 static PyObject *
417 posix_error(void)
419 return PyErr_SetFromErrno(PyExc_OSError);
421 static PyObject *
422 posix_error_with_filename(char* name)
424 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
427 #ifdef Py_WIN_WIDE_FILENAMES
428 static PyObject *
429 posix_error_with_unicode_filename(Py_UNICODE* name)
431 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
433 #endif /* Py_WIN_WIDE_FILENAMES */
436 static PyObject *
437 posix_error_with_allocated_filename(char* name)
439 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
440 PyMem_Free(name);
441 return rc;
444 #ifdef MS_WINDOWS
445 static PyObject *
446 win32_error(char* function, char* filename)
448 /* XXX We should pass the function name along in the future.
449 (_winreg.c also wants to pass the function name.)
450 This would however require an additional param to the
451 Windows error object, which is non-trivial.
453 errno = GetLastError();
454 if (filename)
455 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
456 else
457 return PyErr_SetFromWindowsErr(errno);
460 #ifdef Py_WIN_WIDE_FILENAMES
461 static PyObject *
462 win32_error_unicode(char* function, Py_UNICODE* filename)
464 /* XXX - see win32_error for comments on 'function' */
465 errno = GetLastError();
466 if (filename)
467 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
468 else
469 return PyErr_SetFromWindowsErr(errno);
472 static PyObject *_PyUnicode_FromFileSystemEncodedObject(register PyObject *obj)
476 /* Function suitable for O& conversion */
477 static int
478 convert_to_unicode(PyObject *arg, void* _param)
480 PyObject **param = (PyObject**)_param;
481 if (PyUnicode_CheckExact(arg)) {
482 Py_INCREF(arg);
483 *param = arg;
485 else if (PyUnicode_Check(arg)) {
486 /* For a Unicode subtype that's not a Unicode object,
487 return a true Unicode object with the same data. */
488 *param = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(arg),
489 PyUnicode_GET_SIZE(arg));
490 return *param != NULL;
492 else
493 *param = PyUnicode_FromEncodedObject(arg,
494 Py_FileSystemDefaultEncoding,
495 "strict");
496 return (*param) != NULL;
499 #endif /* Py_WIN_WIDE_FILENAMES */
501 #endif
503 #if defined(PYOS_OS2)
504 /**********************************************************************
505 * Helper Function to Trim and Format OS/2 Messages
506 **********************************************************************/
507 static void
508 os2_formatmsg(char *msgbuf, int msglen, char *reason)
510 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
512 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
513 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
515 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
516 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
519 /* Add Optional Reason Text */
520 if (reason) {
521 strcat(msgbuf, " : ");
522 strcat(msgbuf, reason);
526 /**********************************************************************
527 * Decode an OS/2 Operating System Error Code
529 * A convenience function to lookup an OS/2 error code and return a
530 * text message we can use to raise a Python exception.
532 * Notes:
533 * The messages for errors returned from the OS/2 kernel reside in
534 * the file OSO001.MSG in the \OS2 directory hierarchy.
536 **********************************************************************/
537 static char *
538 os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
540 APIRET rc;
541 ULONG msglen;
543 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
544 Py_BEGIN_ALLOW_THREADS
545 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
546 errorcode, "oso001.msg", &msglen);
547 Py_END_ALLOW_THREADS
549 if (rc == NO_ERROR)
550 os2_formatmsg(msgbuf, msglen, reason);
551 else
552 PyOS_snprintf(msgbuf, msgbuflen,
553 "unknown OS error #%d", errorcode);
555 return msgbuf;
558 /* Set an OS/2-specific error and return NULL. OS/2 kernel
559 errors are not in a global variable e.g. 'errno' nor are
560 they congruent with posix error numbers. */
562 static PyObject * os2_error(int code)
564 char text[1024];
565 PyObject *v;
567 os2_strerror(text, sizeof(text), code, "");
569 v = Py_BuildValue("(is)", code, text);
570 if (v != NULL) {
571 PyErr_SetObject(PyExc_OSError, v);
572 Py_DECREF(v);
574 return NULL; /* Signal to Python that an Exception is Pending */
577 #endif /* OS2 */
579 /* POSIX generic methods */
581 static PyObject *
582 posix_fildes(PyObject *fdobj, int (*func)(int))
584 int fd;
585 int res;
586 fd = PyObject_AsFileDescriptor(fdobj);
587 if (fd < 0)
588 return NULL;
589 Py_BEGIN_ALLOW_THREADS
590 res = (*func)(fd);
591 Py_END_ALLOW_THREADS
592 if (res < 0)
593 return posix_error();
594 Py_INCREF(Py_None);
595 return Py_None;
598 #ifdef Py_WIN_WIDE_FILENAMES
599 static int
600 unicode_file_names(void)
602 static int canusewide = -1;
603 if (canusewide == -1) {
604 /* As per doc for ::GetVersion(), this is the correct test for
605 the Windows NT family. */
606 canusewide = (GetVersion() < 0x80000000) ? 1 : 0;
608 return canusewide;
610 #endif
612 static PyObject *
613 posix_1str(PyObject *args, char *format, int (*func)(const char*))
615 char *path1 = NULL;
616 int res;
617 if (!PyArg_ParseTuple(args, format,
618 Py_FileSystemDefaultEncoding, &path1))
619 return NULL;
620 Py_BEGIN_ALLOW_THREADS
621 res = (*func)(path1);
622 Py_END_ALLOW_THREADS
623 if (res < 0)
624 return posix_error_with_allocated_filename(path1);
625 PyMem_Free(path1);
626 Py_INCREF(Py_None);
627 return Py_None;
630 static PyObject *
631 posix_2str(PyObject *args,
632 char *format,
633 int (*func)(const char *, const char *))
635 char *path1 = NULL, *path2 = NULL;
636 int res;
637 if (!PyArg_ParseTuple(args, format,
638 Py_FileSystemDefaultEncoding, &path1,
639 Py_FileSystemDefaultEncoding, &path2))
640 return NULL;
641 Py_BEGIN_ALLOW_THREADS
642 res = (*func)(path1, path2);
643 Py_END_ALLOW_THREADS
644 PyMem_Free(path1);
645 PyMem_Free(path2);
646 if (res != 0)
647 /* XXX how to report both path1 and path2??? */
648 return posix_error();
649 Py_INCREF(Py_None);
650 return Py_None;
653 #ifdef Py_WIN_WIDE_FILENAMES
654 static PyObject*
655 win32_1str(PyObject* args, char* func,
656 char* format, BOOL (__stdcall *funcA)(LPCSTR),
657 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
659 PyObject *uni;
660 char *ansi;
661 BOOL result;
662 if (unicode_file_names()) {
663 if (!PyArg_ParseTuple(args, wformat, &uni))
664 PyErr_Clear();
665 else {
666 Py_BEGIN_ALLOW_THREADS
667 result = funcW(PyUnicode_AsUnicode(uni));
668 Py_END_ALLOW_THREADS
669 if (!result)
670 return win32_error_unicode(func, PyUnicode_AsUnicode(uni));
671 Py_INCREF(Py_None);
672 return Py_None;
675 if (!PyArg_ParseTuple(args, format, &ansi))
676 return NULL;
677 Py_BEGIN_ALLOW_THREADS
678 result = funcA(ansi);
679 Py_END_ALLOW_THREADS
680 if (!result)
681 return win32_error(func, ansi);
682 Py_INCREF(Py_None);
683 return Py_None;
687 /* This is a reimplementation of the C library's chdir function,
688 but one that produces Win32 errors instead of DOS error codes.
689 chdir is essentially a wrapper around SetCurrentDirectory; however,
690 it also needs to set "magic" environment variables indicating
691 the per-drive current directory, which are of the form =<drive>: */
692 BOOL __stdcall
693 win32_chdir(LPCSTR path)
695 char new_path[MAX_PATH+1];
696 int result;
697 char env[4] = "=x:";
699 if(!SetCurrentDirectoryA(path))
700 return FALSE;
701 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
702 if (!result)
703 return FALSE;
704 /* In the ANSI API, there should not be any paths longer
705 than MAX_PATH. */
706 assert(result <= MAX_PATH+1);
707 if (strncmp(new_path, "\\\\", 2) == 0 ||
708 strncmp(new_path, "//", 2) == 0)
709 /* UNC path, nothing to do. */
710 return TRUE;
711 env[1] = new_path[0];
712 return SetEnvironmentVariableA(env, new_path);
715 /* The Unicode version differs from the ANSI version
716 since the current directory might exceed MAX_PATH characters */
717 BOOL __stdcall
718 win32_wchdir(LPCWSTR path)
720 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
721 int result;
722 wchar_t env[4] = L"=x:";
724 if(!SetCurrentDirectoryW(path))
725 return FALSE;
726 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
727 if (!result)
728 return FALSE;
729 if (result > MAX_PATH+1) {
730 new_path = malloc(result);
731 if (!new_path) {
732 SetLastError(ERROR_OUTOFMEMORY);
733 return FALSE;
736 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
737 wcsncmp(new_path, L"//", 2) == 0)
738 /* UNC path, nothing to do. */
739 return TRUE;
740 env[1] = new_path[0];
741 result = SetEnvironmentVariableW(env, new_path);
742 if (new_path != _new_path)
743 free(new_path);
744 return result;
746 #endif
748 #ifdef MS_WINDOWS
749 /* The CRT of Windows has a number of flaws wrt. its stat() implementation:
750 - time stamps are restricted to second resolution
751 - file modification times suffer from forth-and-back conversions between
752 UTC and local time
753 Therefore, we implement our own stat, based on the Win32 API directly.
755 #define HAVE_STAT_NSEC 1
757 struct win32_stat{
758 int st_dev;
759 __int64 st_ino;
760 unsigned short st_mode;
761 int st_nlink;
762 int st_uid;
763 int st_gid;
764 int st_rdev;
765 __int64 st_size;
766 int st_atime;
767 int st_atime_nsec;
768 int st_mtime;
769 int st_mtime_nsec;
770 int st_ctime;
771 int st_ctime_nsec;
774 static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
776 static void
777 FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, int *time_out, int* nsec_out)
779 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
780 /* Cannot simply cast and dereference in_ptr,
781 since it might not be aligned properly */
782 __int64 in;
783 memcpy(&in, in_ptr, sizeof(in));
784 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
785 /* XXX Win32 supports time stamps past 2038; we currently don't */
786 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, int);
789 static void
790 time_t_to_FILE_TIME(int time_in, int nsec_in, FILETIME *out_ptr)
792 /* XXX endianness */
793 __int64 out;
794 out = time_in + secs_between_epochs;
795 out = out * 10000000 + nsec_in / 100;
796 memcpy(out_ptr, &out, sizeof(out));
799 /* Below, we *know* that ugo+r is 0444 */
800 #if _S_IREAD != 0400
801 #error Unsupported C library
802 #endif
803 static int
804 attributes_to_mode(DWORD attr)
806 int m = 0;
807 if (attr & FILE_ATTRIBUTE_DIRECTORY)
808 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
809 else
810 m |= _S_IFREG;
811 if (attr & FILE_ATTRIBUTE_READONLY)
812 m |= 0444;
813 else
814 m |= 0666;
815 return m;
818 static int
819 attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *result)
821 memset(result, 0, sizeof(*result));
822 result->st_mode = attributes_to_mode(info->dwFileAttributes);
823 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
824 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
825 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
826 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
828 return 0;
831 /* Emulate GetFileAttributesEx[AW] on Windows 95 */
832 static int checked = 0;
833 static BOOL (CALLBACK *gfaxa)(LPCSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
834 static BOOL (CALLBACK *gfaxw)(LPCWSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
835 static void
836 check_gfax()
838 HINSTANCE hKernel32;
839 if (checked)
840 return;
841 checked = 1;
842 hKernel32 = GetModuleHandle("KERNEL32");
843 *(FARPROC*)&gfaxa = GetProcAddress(hKernel32, "GetFileAttributesExA");
844 *(FARPROC*)&gfaxw = GetProcAddress(hKernel32, "GetFileAttributesExW");
847 static BOOL WINAPI
848 Py_GetFileAttributesExA(LPCSTR pszFile,
849 GET_FILEEX_INFO_LEVELS level,
850 LPVOID pv)
852 BOOL result;
853 HANDLE hFindFile;
854 WIN32_FIND_DATAA FileData;
855 LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
856 /* First try to use the system's implementation, if that is
857 available and either succeeds to gives an error other than
858 that it isn't implemented. */
859 check_gfax();
860 if (gfaxa) {
861 result = gfaxa(pszFile, level, pv);
862 if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
863 return result;
865 /* It's either not present, or not implemented.
866 Emulate using FindFirstFile. */
867 if (level != GetFileExInfoStandard) {
868 SetLastError(ERROR_INVALID_PARAMETER);
869 return FALSE;
871 /* Use GetFileAttributes to validate that the file name
872 does not contain wildcards (which FindFirstFile would
873 accept). */
874 if (GetFileAttributesA(pszFile) == 0xFFFFFFFF)
875 return FALSE;
876 hFindFile = FindFirstFileA(pszFile, &FileData);
877 if (hFindFile == INVALID_HANDLE_VALUE)
878 return FALSE;
879 FindClose(hFindFile);
880 pfad->dwFileAttributes = FileData.dwFileAttributes;
881 pfad->ftCreationTime = FileData.ftCreationTime;
882 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
883 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
884 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
885 pfad->nFileSizeLow = FileData.nFileSizeLow;
886 return TRUE;
889 static BOOL WINAPI
890 Py_GetFileAttributesExW(LPCWSTR pszFile,
891 GET_FILEEX_INFO_LEVELS level,
892 LPVOID pv)
894 BOOL result;
895 HANDLE hFindFile;
896 WIN32_FIND_DATAW FileData;
897 LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
898 /* First try to use the system's implementation, if that is
899 available and either succeeds to gives an error other than
900 that it isn't implemented. */
901 check_gfax();
902 if (gfaxa) {
903 result = gfaxw(pszFile, level, pv);
904 if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
905 return result;
907 /* It's either not present, or not implemented.
908 Emulate using FindFirstFile. */
909 if (level != GetFileExInfoStandard) {
910 SetLastError(ERROR_INVALID_PARAMETER);
911 return FALSE;
913 /* Use GetFileAttributes to validate that the file name
914 does not contain wildcards (which FindFirstFile would
915 accept). */
916 if (GetFileAttributesW(pszFile) == 0xFFFFFFFF)
917 return FALSE;
918 hFindFile = FindFirstFileW(pszFile, &FileData);
919 if (hFindFile == INVALID_HANDLE_VALUE)
920 return FALSE;
921 FindClose(hFindFile);
922 pfad->dwFileAttributes = FileData.dwFileAttributes;
923 pfad->ftCreationTime = FileData.ftCreationTime;
924 pfad->ftLastAccessTime = FileData.ftLastAccessTime;
925 pfad->ftLastWriteTime = FileData.ftLastWriteTime;
926 pfad->nFileSizeHigh = FileData.nFileSizeHigh;
927 pfad->nFileSizeLow = FileData.nFileSizeLow;
928 return TRUE;
931 static int
932 win32_stat(const char* path, struct win32_stat *result)
934 WIN32_FILE_ATTRIBUTE_DATA info;
935 int code;
936 char *dot;
937 /* XXX not supported on Win95 and NT 3.x */
938 if (!Py_GetFileAttributesExA(path, GetFileExInfoStandard, &info)) {
939 /* Protocol violation: we explicitly clear errno, instead of
940 setting it to a POSIX error. Callers should use GetLastError. */
941 errno = 0;
942 return -1;
944 code = attribute_data_to_stat(&info, result);
945 if (code != 0)
946 return code;
947 /* Set S_IFEXEC if it is an .exe, .bat, ... */
948 dot = strrchr(path, '.');
949 if (dot) {
950 if (stricmp(dot, ".bat") == 0 ||
951 stricmp(dot, ".cmd") == 0 ||
952 stricmp(dot, ".exe") == 0 ||
953 stricmp(dot, ".com") == 0)
954 result->st_mode |= 0111;
956 return code;
959 static int
960 win32_wstat(const wchar_t* path, struct win32_stat *result)
962 int code;
963 const wchar_t *dot;
964 WIN32_FILE_ATTRIBUTE_DATA info;
965 /* XXX not supported on Win95 and NT 3.x */
966 if (!Py_GetFileAttributesExW(path, GetFileExInfoStandard, &info)) {
967 /* Protocol violation: we explicitly clear errno, instead of
968 setting it to a POSIX error. Callers should use GetLastError. */
969 errno = 0;
970 return -1;
972 code = attribute_data_to_stat(&info, result);
973 if (code < 0)
974 return code;
975 /* Set IFEXEC if it is an .exe, .bat, ... */
976 dot = wcsrchr(path, '.');
977 if (dot) {
978 if (_wcsicmp(dot, L".bat") == 0 ||
979 _wcsicmp(dot, L".cmd") == 0 ||
980 _wcsicmp(dot, L".exe") == 0 ||
981 _wcsicmp(dot, L".com") == 0)
982 result->st_mode |= 0111;
984 return code;
987 static int
988 win32_fstat(int file_number, struct win32_stat *result)
990 BY_HANDLE_FILE_INFORMATION info;
991 HANDLE h;
992 int type;
994 h = (HANDLE)_get_osfhandle(file_number);
996 /* Protocol violation: we explicitly clear errno, instead of
997 setting it to a POSIX error. Callers should use GetLastError. */
998 errno = 0;
1000 if (h == INVALID_HANDLE_VALUE) {
1001 /* This is really a C library error (invalid file handle).
1002 We set the Win32 error to the closes one matching. */
1003 SetLastError(ERROR_INVALID_HANDLE);
1004 return -1;
1006 memset(result, 0, sizeof(*result));
1008 type = GetFileType(h);
1009 if (type == FILE_TYPE_UNKNOWN) {
1010 DWORD error = GetLastError();
1011 if (error != 0) {
1012 return -1;
1014 /* else: valid but unknown file */
1017 if (type != FILE_TYPE_DISK) {
1018 if (type == FILE_TYPE_CHAR)
1019 result->st_mode = _S_IFCHR;
1020 else if (type == FILE_TYPE_PIPE)
1021 result->st_mode = _S_IFIFO;
1022 return 0;
1025 if (!GetFileInformationByHandle(h, &info)) {
1026 return -1;
1029 /* similar to stat() */
1030 result->st_mode = attributes_to_mode(info.dwFileAttributes);
1031 result->st_size = (((__int64)info.nFileSizeHigh)<<32) + info.nFileSizeLow;
1032 FILE_TIME_to_time_t_nsec(&info.ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
1033 FILE_TIME_to_time_t_nsec(&info.ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
1034 FILE_TIME_to_time_t_nsec(&info.ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
1035 /* specific to fstat() */
1036 result->st_nlink = info.nNumberOfLinks;
1037 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
1038 return 0;
1041 #endif /* MS_WINDOWS */
1043 PyDoc_STRVAR(stat_result__doc__,
1044 "stat_result: Result from stat or lstat.\n\n\
1045 This object may be accessed either as a tuple of\n\
1046 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
1047 or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1049 Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1050 or st_flags, they are available as attributes only.\n\
1052 See os.stat for more information.");
1054 static PyStructSequence_Field stat_result_fields[] = {
1055 {"st_mode", "protection bits"},
1056 {"st_ino", "inode"},
1057 {"st_dev", "device"},
1058 {"st_nlink", "number of hard links"},
1059 {"st_uid", "user ID of owner"},
1060 {"st_gid", "group ID of owner"},
1061 {"st_size", "total size, in bytes"},
1062 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1063 {NULL, "integer time of last access"},
1064 {NULL, "integer time of last modification"},
1065 {NULL, "integer time of last change"},
1066 {"st_atime", "time of last access"},
1067 {"st_mtime", "time of last modification"},
1068 {"st_ctime", "time of last change"},
1069 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
1070 {"st_blksize", "blocksize for filesystem I/O"},
1071 #endif
1072 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
1073 {"st_blocks", "number of blocks allocated"},
1074 #endif
1075 #ifdef HAVE_STRUCT_STAT_ST_RDEV
1076 {"st_rdev", "device type (if inode device)"},
1077 #endif
1078 #ifdef HAVE_STRUCT_STAT_ST_FLAGS
1079 {"st_flags", "user defined flags for file"},
1080 #endif
1081 #ifdef HAVE_STRUCT_STAT_ST_GEN
1082 {"st_gen", "generation number"},
1083 #endif
1084 #ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1085 {"st_birthtime", "time of creation"},
1086 #endif
1090 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
1091 #define ST_BLKSIZE_IDX 13
1092 #else
1093 #define ST_BLKSIZE_IDX 12
1094 #endif
1096 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
1097 #define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1098 #else
1099 #define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1100 #endif
1102 #ifdef HAVE_STRUCT_STAT_ST_RDEV
1103 #define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1104 #else
1105 #define ST_RDEV_IDX ST_BLOCKS_IDX
1106 #endif
1108 #ifdef HAVE_STRUCT_STAT_ST_FLAGS
1109 #define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1110 #else
1111 #define ST_FLAGS_IDX ST_RDEV_IDX
1112 #endif
1114 #ifdef HAVE_STRUCT_STAT_ST_GEN
1115 #define ST_GEN_IDX (ST_FLAGS_IDX+1)
1116 #else
1117 #define ST_GEN_IDX ST_FLAGS_IDX
1118 #endif
1120 #ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1121 #define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1122 #else
1123 #define ST_BIRTHTIME_IDX ST_GEN_IDX
1124 #endif
1126 static PyStructSequence_Desc stat_result_desc = {
1127 "stat_result", /* name */
1128 stat_result__doc__, /* doc */
1129 stat_result_fields,
1133 PyDoc_STRVAR(statvfs_result__doc__,
1134 "statvfs_result: Result from statvfs or fstatvfs.\n\n\
1135 This object may be accessed either as a tuple of\n\
1136 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
1137 or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
1139 See os.statvfs for more information.");
1141 static PyStructSequence_Field statvfs_result_fields[] = {
1142 {"f_bsize", },
1143 {"f_frsize", },
1144 {"f_blocks", },
1145 {"f_bfree", },
1146 {"f_bavail", },
1147 {"f_files", },
1148 {"f_ffree", },
1149 {"f_favail", },
1150 {"f_flag", },
1151 {"f_namemax",},
1155 static PyStructSequence_Desc statvfs_result_desc = {
1156 "statvfs_result", /* name */
1157 statvfs_result__doc__, /* doc */
1158 statvfs_result_fields,
1162 static int initialized;
1163 static PyTypeObject StatResultType;
1164 static PyTypeObject StatVFSResultType;
1165 static newfunc structseq_new;
1167 static PyObject *
1168 statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1170 PyStructSequence *result;
1171 int i;
1173 result = (PyStructSequence*)structseq_new(type, args, kwds);
1174 if (!result)
1175 return NULL;
1176 /* If we have been initialized from a tuple,
1177 st_?time might be set to None. Initialize it
1178 from the int slots. */
1179 for (i = 7; i <= 9; i++) {
1180 if (result->ob_item[i+3] == Py_None) {
1181 Py_DECREF(Py_None);
1182 Py_INCREF(result->ob_item[i]);
1183 result->ob_item[i+3] = result->ob_item[i];
1186 return (PyObject*)result;
1191 /* If true, st_?time is float. */
1192 static int _stat_float_times = 1;
1194 PyDoc_STRVAR(stat_float_times__doc__,
1195 "stat_float_times([newval]) -> oldval\n\n\
1196 Determine whether os.[lf]stat represents time stamps as float objects.\n\
1197 If newval is True, future calls to stat() return floats, if it is False,\n\
1198 future calls return ints. \n\
1199 If newval is omitted, return the current setting.\n");
1201 static PyObject*
1202 stat_float_times(PyObject* self, PyObject *args)
1204 int newval = -1;
1205 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1206 return NULL;
1207 if (newval == -1)
1208 /* Return old value */
1209 return PyBool_FromLong(_stat_float_times);
1210 _stat_float_times = newval;
1211 Py_INCREF(Py_None);
1212 return Py_None;
1215 static void
1216 fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1218 PyObject *fval,*ival;
1219 #if SIZEOF_TIME_T > SIZEOF_LONG
1220 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
1221 #else
1222 ival = PyInt_FromLong((long)sec);
1223 #endif
1224 if (!ival)
1225 return;
1226 if (_stat_float_times) {
1227 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1228 } else {
1229 fval = ival;
1230 Py_INCREF(fval);
1232 PyStructSequence_SET_ITEM(v, index, ival);
1233 PyStructSequence_SET_ITEM(v, index+3, fval);
1236 /* pack a system stat C structure into the Python stat tuple
1237 (used by posix_stat() and posix_fstat()) */
1238 static PyObject*
1239 _pystat_fromstructstat(STRUCT_STAT *st)
1241 unsigned long ansec, mnsec, cnsec;
1242 PyObject *v = PyStructSequence_New(&StatResultType);
1243 if (v == NULL)
1244 return NULL;
1246 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st->st_mode));
1247 #ifdef HAVE_LARGEFILE_SUPPORT
1248 PyStructSequence_SET_ITEM(v, 1,
1249 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
1250 #else
1251 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st->st_ino));
1252 #endif
1253 #if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
1254 PyStructSequence_SET_ITEM(v, 2,
1255 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
1256 #else
1257 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st->st_dev));
1258 #endif
1259 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st->st_nlink));
1260 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st->st_uid));
1261 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st->st_gid));
1262 #ifdef HAVE_LARGEFILE_SUPPORT
1263 PyStructSequence_SET_ITEM(v, 6,
1264 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
1265 #else
1266 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st->st_size));
1267 #endif
1269 #if defined(HAVE_STAT_TV_NSEC)
1270 ansec = st->st_atim.tv_nsec;
1271 mnsec = st->st_mtim.tv_nsec;
1272 cnsec = st->st_ctim.tv_nsec;
1273 #elif defined(HAVE_STAT_TV_NSEC2)
1274 ansec = st->st_atimespec.tv_nsec;
1275 mnsec = st->st_mtimespec.tv_nsec;
1276 cnsec = st->st_ctimespec.tv_nsec;
1277 #elif defined(HAVE_STAT_NSEC)
1278 ansec = st->st_atime_nsec;
1279 mnsec = st->st_mtime_nsec;
1280 cnsec = st->st_ctime_nsec;
1281 #else
1282 ansec = mnsec = cnsec = 0;
1283 #endif
1284 fill_time(v, 7, st->st_atime, ansec);
1285 fill_time(v, 8, st->st_mtime, mnsec);
1286 fill_time(v, 9, st->st_ctime, cnsec);
1288 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
1289 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
1290 PyInt_FromLong((long)st->st_blksize));
1291 #endif
1292 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
1293 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
1294 PyInt_FromLong((long)st->st_blocks));
1295 #endif
1296 #ifdef HAVE_STRUCT_STAT_ST_RDEV
1297 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
1298 PyInt_FromLong((long)st->st_rdev));
1299 #endif
1300 #ifdef HAVE_STRUCT_STAT_ST_GEN
1301 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
1302 PyInt_FromLong((long)st->st_gen));
1303 #endif
1304 #ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1306 PyObject *val;
1307 unsigned long bsec,bnsec;
1308 bsec = (long)st->st_birthtime;
1309 #ifdef HAVE_STAT_TV_NSEC2
1310 bnsec = st->st_birthtimespec.tv_nsec;
1311 #else
1312 bnsec = 0;
1313 #endif
1314 if (_stat_float_times) {
1315 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1316 } else {
1317 val = PyInt_FromLong((long)bsec);
1319 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1320 val);
1322 #endif
1323 #ifdef HAVE_STRUCT_STAT_ST_FLAGS
1324 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
1325 PyInt_FromLong((long)st->st_flags));
1326 #endif
1328 if (PyErr_Occurred()) {
1329 Py_DECREF(v);
1330 return NULL;
1333 return v;
1336 #ifdef MS_WINDOWS
1338 /* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
1339 where / can be used in place of \ and the trailing slash is optional.
1340 Both SERVER and SHARE must have at least one character.
1343 #define ISSLASHA(c) ((c) == '\\' || (c) == '/')
1344 #define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
1345 #ifndef ARRAYSIZE
1346 #define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
1347 #endif
1349 static BOOL
1350 IsUNCRootA(char *path, int pathlen)
1352 #define ISSLASH ISSLASHA
1354 int i, share;
1356 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1357 /* minimum UNCRoot is \\x\y */
1358 return FALSE;
1359 for (i = 2; i < pathlen ; i++)
1360 if (ISSLASH(path[i])) break;
1361 if (i == 2 || i == pathlen)
1362 /* do not allow \\\SHARE or \\SERVER */
1363 return FALSE;
1364 share = i+1;
1365 for (i = share; i < pathlen; i++)
1366 if (ISSLASH(path[i])) break;
1367 return (i != share && (i == pathlen || i == pathlen-1));
1369 #undef ISSLASH
1372 #ifdef Py_WIN_WIDE_FILENAMES
1373 static BOOL
1374 IsUNCRootW(Py_UNICODE *path, int pathlen)
1376 #define ISSLASH ISSLASHW
1378 int i, share;
1380 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1381 /* minimum UNCRoot is \\x\y */
1382 return FALSE;
1383 for (i = 2; i < pathlen ; i++)
1384 if (ISSLASH(path[i])) break;
1385 if (i == 2 || i == pathlen)
1386 /* do not allow \\\SHARE or \\SERVER */
1387 return FALSE;
1388 share = i+1;
1389 for (i = share; i < pathlen; i++)
1390 if (ISSLASH(path[i])) break;
1391 return (i != share && (i == pathlen || i == pathlen-1));
1393 #undef ISSLASH
1395 #endif /* Py_WIN_WIDE_FILENAMES */
1396 #endif /* MS_WINDOWS */
1398 static PyObject *
1399 posix_do_stat(PyObject *self, PyObject *args,
1400 char *format,
1401 #ifdef __VMS
1402 int (*statfunc)(const char *, STRUCT_STAT *, ...),
1403 #else
1404 int (*statfunc)(const char *, STRUCT_STAT *),
1405 #endif
1406 char *wformat,
1407 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
1409 STRUCT_STAT st;
1410 char *path = NULL; /* pass this to stat; do not free() it */
1411 char *pathfree = NULL; /* this memory must be free'd */
1412 int res;
1413 PyObject *result;
1415 #ifdef Py_WIN_WIDE_FILENAMES
1416 /* If on wide-character-capable OS see if argument
1417 is Unicode and if so use wide API. */
1418 if (unicode_file_names()) {
1419 PyUnicodeObject *po;
1420 if (PyArg_ParseTuple(args, wformat, &po)) {
1421 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
1423 Py_BEGIN_ALLOW_THREADS
1424 /* PyUnicode_AS_UNICODE result OK without
1425 thread lock as it is a simple dereference. */
1426 res = wstatfunc(wpath, &st);
1427 Py_END_ALLOW_THREADS
1429 if (res != 0)
1430 return win32_error_unicode("stat", wpath);
1431 return _pystat_fromstructstat(&st);
1433 /* Drop the argument parsing error as narrow strings
1434 are also valid. */
1435 PyErr_Clear();
1437 #endif
1439 if (!PyArg_ParseTuple(args, format,
1440 Py_FileSystemDefaultEncoding, &path))
1441 return NULL;
1442 pathfree = path;
1444 Py_BEGIN_ALLOW_THREADS
1445 res = (*statfunc)(path, &st);
1446 Py_END_ALLOW_THREADS
1448 if (res != 0) {
1449 #ifdef MS_WINDOWS
1450 result = win32_error("stat", pathfree);
1451 #else
1452 result = posix_error_with_filename(pathfree);
1453 #endif
1455 else
1456 result = _pystat_fromstructstat(&st);
1458 PyMem_Free(pathfree);
1459 return result;
1462 /* POSIX methods */
1464 PyDoc_STRVAR(posix_access__doc__,
1465 "access(path, mode) -> True if granted, False otherwise\n\n\
1466 Use the real uid/gid to test for access to a path. Note that most\n\
1467 operations will use the effective uid/gid, therefore this routine can\n\
1468 be used in a suid/sgid environment to test if the invoking user has the\n\
1469 specified access to the path. The mode argument can be F_OK to test\n\
1470 existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
1472 static PyObject *
1473 posix_access(PyObject *self, PyObject *args)
1475 char *path;
1476 int mode;
1478 #ifdef Py_WIN_WIDE_FILENAMES
1479 DWORD attr;
1480 if (unicode_file_names()) {
1481 PyUnicodeObject *po;
1482 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1483 Py_BEGIN_ALLOW_THREADS
1484 /* PyUnicode_AS_UNICODE OK without thread lock as
1485 it is a simple dereference. */
1486 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1487 Py_END_ALLOW_THREADS
1488 goto finish;
1490 /* Drop the argument parsing error as narrow strings
1491 are also valid. */
1492 PyErr_Clear();
1494 if (!PyArg_ParseTuple(args, "eti:access",
1495 Py_FileSystemDefaultEncoding, &path, &mode))
1496 return 0;
1497 Py_BEGIN_ALLOW_THREADS
1498 attr = GetFileAttributesA(path);
1499 Py_END_ALLOW_THREADS
1500 PyMem_Free(path);
1501 finish:
1502 if (attr == 0xFFFFFFFF)
1503 /* File does not exist, or cannot read attributes */
1504 return PyBool_FromLong(0);
1505 /* Access is possible if either write access wasn't requested, or
1506 the file isn't read-only. */
1507 return PyBool_FromLong(!(mode & 2) || !(attr & FILE_ATTRIBUTE_READONLY));
1508 #else
1509 int res;
1510 if (!PyArg_ParseTuple(args, "eti:access",
1511 Py_FileSystemDefaultEncoding, &path, &mode))
1512 return NULL;
1513 Py_BEGIN_ALLOW_THREADS
1514 res = access(path, mode);
1515 Py_END_ALLOW_THREADS
1516 PyMem_Free(path);
1517 return PyBool_FromLong(res == 0);
1518 #endif
1521 #ifndef F_OK
1522 #define F_OK 0
1523 #endif
1524 #ifndef R_OK
1525 #define R_OK 4
1526 #endif
1527 #ifndef W_OK
1528 #define W_OK 2
1529 #endif
1530 #ifndef X_OK
1531 #define X_OK 1
1532 #endif
1534 #ifdef HAVE_TTYNAME
1535 PyDoc_STRVAR(posix_ttyname__doc__,
1536 "ttyname(fd) -> string\n\n\
1537 Return the name of the terminal device connected to 'fd'.");
1539 static PyObject *
1540 posix_ttyname(PyObject *self, PyObject *args)
1542 int id;
1543 char *ret;
1545 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
1546 return NULL;
1548 #if defined(__VMS)
1549 /* file descriptor 0 only, the default input device (stdin) */
1550 if (id == 0) {
1551 ret = ttyname();
1553 else {
1554 ret = NULL;
1556 #else
1557 ret = ttyname(id);
1558 #endif
1559 if (ret == NULL)
1560 return posix_error();
1561 return PyString_FromString(ret);
1563 #endif
1565 #ifdef HAVE_CTERMID
1566 PyDoc_STRVAR(posix_ctermid__doc__,
1567 "ctermid() -> string\n\n\
1568 Return the name of the controlling terminal for this process.");
1570 static PyObject *
1571 posix_ctermid(PyObject *self, PyObject *noargs)
1573 char *ret;
1574 char buffer[L_ctermid];
1576 #ifdef USE_CTERMID_R
1577 ret = ctermid_r(buffer);
1578 #else
1579 ret = ctermid(buffer);
1580 #endif
1581 if (ret == NULL)
1582 return posix_error();
1583 return PyString_FromString(buffer);
1585 #endif
1587 PyDoc_STRVAR(posix_chdir__doc__,
1588 "chdir(path)\n\n\
1589 Change the current working directory to the specified path.");
1591 static PyObject *
1592 posix_chdir(PyObject *self, PyObject *args)
1594 #ifdef MS_WINDOWS
1595 return win32_1str(args, "chdir", "s:chdir", win32_chdir, "U:chdir", win32_wchdir);
1596 #elif defined(PYOS_OS2) && defined(PYCC_GCC)
1597 return posix_1str(args, "et:chdir", _chdir2);
1598 #elif defined(__VMS)
1599 return posix_1str(args, "et:chdir", (int (*)(const char *))chdir);
1600 #else
1601 return posix_1str(args, "et:chdir", chdir);
1602 #endif
1605 #ifdef HAVE_FCHDIR
1606 PyDoc_STRVAR(posix_fchdir__doc__,
1607 "fchdir(fildes)\n\n\
1608 Change to the directory of the given file descriptor. fildes must be\n\
1609 opened on a directory, not a file.");
1611 static PyObject *
1612 posix_fchdir(PyObject *self, PyObject *fdobj)
1614 return posix_fildes(fdobj, fchdir);
1616 #endif /* HAVE_FCHDIR */
1619 PyDoc_STRVAR(posix_chmod__doc__,
1620 "chmod(path, mode)\n\n\
1621 Change the access permissions of a file.");
1623 static PyObject *
1624 posix_chmod(PyObject *self, PyObject *args)
1626 char *path = NULL;
1627 int i;
1628 int res;
1629 #ifdef Py_WIN_WIDE_FILENAMES
1630 DWORD attr;
1631 if (unicode_file_names()) {
1632 PyUnicodeObject *po;
1633 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1634 Py_BEGIN_ALLOW_THREADS
1635 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1636 if (attr != 0xFFFFFFFF) {
1637 if (i & _S_IWRITE)
1638 attr &= ~FILE_ATTRIBUTE_READONLY;
1639 else
1640 attr |= FILE_ATTRIBUTE_READONLY;
1641 res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
1643 else
1644 res = 0;
1645 Py_END_ALLOW_THREADS
1646 if (!res)
1647 return win32_error_unicode("chmod",
1648 PyUnicode_AS_UNICODE(po));
1649 Py_INCREF(Py_None);
1650 return Py_None;
1652 /* Drop the argument parsing error as narrow strings
1653 are also valid. */
1654 PyErr_Clear();
1656 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
1657 &path, &i))
1658 return NULL;
1659 Py_BEGIN_ALLOW_THREADS
1660 attr = GetFileAttributesA(path);
1661 if (attr != 0xFFFFFFFF) {
1662 if (i & _S_IWRITE)
1663 attr &= ~FILE_ATTRIBUTE_READONLY;
1664 else
1665 attr |= FILE_ATTRIBUTE_READONLY;
1666 res = SetFileAttributesA(path, attr);
1668 else
1669 res = 0;
1670 Py_END_ALLOW_THREADS
1671 if (!res) {
1672 win32_error("chmod", path);
1673 PyMem_Free(path);
1674 return NULL;
1676 PyMem_Free(path);
1677 Py_INCREF(Py_None);
1678 return Py_None;
1679 #else /* Py_WIN_WIDE_FILENAMES */
1680 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
1681 &path, &i))
1682 return NULL;
1683 Py_BEGIN_ALLOW_THREADS
1684 res = chmod(path, i);
1685 Py_END_ALLOW_THREADS
1686 if (res < 0)
1687 return posix_error_with_allocated_filename(path);
1688 PyMem_Free(path);
1689 Py_INCREF(Py_None);
1690 return Py_None;
1691 #endif
1695 #ifdef HAVE_CHFLAGS
1696 PyDoc_STRVAR(posix_chflags__doc__,
1697 "chflags(path, flags)\n\n\
1698 Set file flags.");
1700 static PyObject *
1701 posix_chflags(PyObject *self, PyObject *args)
1703 char *path;
1704 unsigned long flags;
1705 int res;
1706 if (!PyArg_ParseTuple(args, "etk:chflags",
1707 Py_FileSystemDefaultEncoding, &path, &flags))
1708 return NULL;
1709 Py_BEGIN_ALLOW_THREADS
1710 res = chflags(path, flags);
1711 Py_END_ALLOW_THREADS
1712 if (res < 0)
1713 return posix_error_with_allocated_filename(path);
1714 PyMem_Free(path);
1715 Py_INCREF(Py_None);
1716 return Py_None;
1718 #endif /* HAVE_CHFLAGS */
1720 #ifdef HAVE_LCHFLAGS
1721 PyDoc_STRVAR(posix_lchflags__doc__,
1722 "lchflags(path, flags)\n\n\
1723 Set file flags.\n\
1724 This function will not follow symbolic links.");
1726 static PyObject *
1727 posix_lchflags(PyObject *self, PyObject *args)
1729 char *path;
1730 unsigned long flags;
1731 int res;
1732 if (!PyArg_ParseTuple(args, "etk:lchflags",
1733 Py_FileSystemDefaultEncoding, &path, &flags))
1734 return NULL;
1735 Py_BEGIN_ALLOW_THREADS
1736 res = lchflags(path, flags);
1737 Py_END_ALLOW_THREADS
1738 if (res < 0)
1739 return posix_error_with_allocated_filename(path);
1740 PyMem_Free(path);
1741 Py_INCREF(Py_None);
1742 return Py_None;
1744 #endif /* HAVE_LCHFLAGS */
1746 #ifdef HAVE_CHROOT
1747 PyDoc_STRVAR(posix_chroot__doc__,
1748 "chroot(path)\n\n\
1749 Change root directory to path.");
1751 static PyObject *
1752 posix_chroot(PyObject *self, PyObject *args)
1754 return posix_1str(args, "et:chroot", chroot);
1756 #endif
1758 #ifdef HAVE_FSYNC
1759 PyDoc_STRVAR(posix_fsync__doc__,
1760 "fsync(fildes)\n\n\
1761 force write of file with filedescriptor to disk.");
1763 static PyObject *
1764 posix_fsync(PyObject *self, PyObject *fdobj)
1766 return posix_fildes(fdobj, fsync);
1768 #endif /* HAVE_FSYNC */
1770 #ifdef HAVE_FDATASYNC
1772 #ifdef __hpux
1773 extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1774 #endif
1776 PyDoc_STRVAR(posix_fdatasync__doc__,
1777 "fdatasync(fildes)\n\n\
1778 force write of file with filedescriptor to disk.\n\
1779 does not force update of metadata.");
1781 static PyObject *
1782 posix_fdatasync(PyObject *self, PyObject *fdobj)
1784 return posix_fildes(fdobj, fdatasync);
1786 #endif /* HAVE_FDATASYNC */
1789 #ifdef HAVE_CHOWN
1790 PyDoc_STRVAR(posix_chown__doc__,
1791 "chown(path, uid, gid)\n\n\
1792 Change the owner and group id of path to the numeric uid and gid.");
1794 static PyObject *
1795 posix_chown(PyObject *self, PyObject *args)
1797 char *path = NULL;
1798 int uid, gid;
1799 int res;
1800 if (!PyArg_ParseTuple(args, "etii:chown",
1801 Py_FileSystemDefaultEncoding, &path,
1802 &uid, &gid))
1803 return NULL;
1804 Py_BEGIN_ALLOW_THREADS
1805 res = chown(path, (uid_t) uid, (gid_t) gid);
1806 Py_END_ALLOW_THREADS
1807 if (res < 0)
1808 return posix_error_with_allocated_filename(path);
1809 PyMem_Free(path);
1810 Py_INCREF(Py_None);
1811 return Py_None;
1813 #endif /* HAVE_CHOWN */
1815 #ifdef HAVE_LCHOWN
1816 PyDoc_STRVAR(posix_lchown__doc__,
1817 "lchown(path, uid, gid)\n\n\
1818 Change the owner and group id of path to the numeric uid and gid.\n\
1819 This function will not follow symbolic links.");
1821 static PyObject *
1822 posix_lchown(PyObject *self, PyObject *args)
1824 char *path = NULL;
1825 int uid, gid;
1826 int res;
1827 if (!PyArg_ParseTuple(args, "etii:lchown",
1828 Py_FileSystemDefaultEncoding, &path,
1829 &uid, &gid))
1830 return NULL;
1831 Py_BEGIN_ALLOW_THREADS
1832 res = lchown(path, (uid_t) uid, (gid_t) gid);
1833 Py_END_ALLOW_THREADS
1834 if (res < 0)
1835 return posix_error_with_allocated_filename(path);
1836 PyMem_Free(path);
1837 Py_INCREF(Py_None);
1838 return Py_None;
1840 #endif /* HAVE_LCHOWN */
1843 #ifdef HAVE_GETCWD
1844 PyDoc_STRVAR(posix_getcwd__doc__,
1845 "getcwd() -> path\n\n\
1846 Return a string representing the current working directory.");
1848 static PyObject *
1849 posix_getcwd(PyObject *self, PyObject *noargs)
1851 char buf[1026];
1852 char *res;
1854 Py_BEGIN_ALLOW_THREADS
1855 #if defined(PYOS_OS2) && defined(PYCC_GCC)
1856 res = _getcwd2(buf, sizeof buf);
1857 #else
1858 res = getcwd(buf, sizeof buf);
1859 #endif
1860 Py_END_ALLOW_THREADS
1861 if (res == NULL)
1862 return posix_error();
1863 return PyString_FromString(buf);
1866 #ifdef Py_USING_UNICODE
1867 PyDoc_STRVAR(posix_getcwdu__doc__,
1868 "getcwdu() -> path\n\n\
1869 Return a unicode string representing the current working directory.");
1871 static PyObject *
1872 posix_getcwdu(PyObject *self, PyObject *noargs)
1874 char buf[1026];
1875 char *res;
1877 #ifdef Py_WIN_WIDE_FILENAMES
1878 DWORD len;
1879 if (unicode_file_names()) {
1880 wchar_t wbuf[1026];
1881 wchar_t *wbuf2 = wbuf;
1882 PyObject *resobj;
1883 Py_BEGIN_ALLOW_THREADS
1884 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
1885 /* If the buffer is large enough, len does not include the
1886 terminating \0. If the buffer is too small, len includes
1887 the space needed for the terminator. */
1888 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
1889 wbuf2 = malloc(len * sizeof(wchar_t));
1890 if (wbuf2)
1891 len = GetCurrentDirectoryW(len, wbuf2);
1893 Py_END_ALLOW_THREADS
1894 if (!wbuf2) {
1895 PyErr_NoMemory();
1896 return NULL;
1898 if (!len) {
1899 if (wbuf2 != wbuf) free(wbuf2);
1900 return win32_error("getcwdu", NULL);
1902 resobj = PyUnicode_FromWideChar(wbuf2, len);
1903 if (wbuf2 != wbuf) free(wbuf2);
1904 return resobj;
1906 #endif
1908 Py_BEGIN_ALLOW_THREADS
1909 #if defined(PYOS_OS2) && defined(PYCC_GCC)
1910 res = _getcwd2(buf, sizeof buf);
1911 #else
1912 res = getcwd(buf, sizeof buf);
1913 #endif
1914 Py_END_ALLOW_THREADS
1915 if (res == NULL)
1916 return posix_error();
1917 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
1919 #endif
1920 #endif
1923 #ifdef HAVE_LINK
1924 PyDoc_STRVAR(posix_link__doc__,
1925 "link(src, dst)\n\n\
1926 Create a hard link to a file.");
1928 static PyObject *
1929 posix_link(PyObject *self, PyObject *args)
1931 return posix_2str(args, "etet:link", link);
1933 #endif /* HAVE_LINK */
1936 PyDoc_STRVAR(posix_listdir__doc__,
1937 "listdir(path) -> list_of_strings\n\n\
1938 Return a list containing the names of the entries in the directory.\n\
1940 path: path of directory to list\n\
1942 The list is in arbitrary order. It does not include the special\n\
1943 entries '.' and '..' even if they are present in the directory.");
1945 static PyObject *
1946 posix_listdir(PyObject *self, PyObject *args)
1948 /* XXX Should redo this putting the (now four) versions of opendir
1949 in separate files instead of having them all here... */
1950 #if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
1952 PyObject *d, *v;
1953 HANDLE hFindFile;
1954 BOOL result;
1955 WIN32_FIND_DATA FileData;
1956 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
1957 char *bufptr = namebuf;
1958 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
1960 #ifdef Py_WIN_WIDE_FILENAMES
1961 /* If on wide-character-capable OS see if argument
1962 is Unicode and if so use wide API. */
1963 if (unicode_file_names()) {
1964 PyObject *po;
1965 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
1966 WIN32_FIND_DATAW wFileData;
1967 Py_UNICODE *wnamebuf;
1968 Py_UNICODE wch;
1969 /* Overallocate for \\*.*\0 */
1970 len = PyUnicode_GET_SIZE(po);
1971 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
1972 if (!wnamebuf) {
1973 PyErr_NoMemory();
1974 return NULL;
1976 wcscpy(wnamebuf, PyUnicode_AS_UNICODE(po));
1977 wch = len > 0 ? wnamebuf[len-1] : '\0';
1978 if (wch != L'/' && wch != L'\\' && wch != L':')
1979 wnamebuf[len++] = L'\\';
1980 wcscpy(wnamebuf + len, L"*.*");
1981 if ((d = PyList_New(0)) == NULL) {
1982 free(wnamebuf);
1983 return NULL;
1985 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
1986 if (hFindFile == INVALID_HANDLE_VALUE) {
1987 int error = GetLastError();
1988 if (error == ERROR_FILE_NOT_FOUND) {
1989 free(wnamebuf);
1990 return d;
1992 Py_DECREF(d);
1993 win32_error_unicode("FindFirstFileW", wnamebuf);
1994 free(wnamebuf);
1995 return NULL;
1997 do {
1998 /* Skip over . and .. */
1999 if (wcscmp(wFileData.cFileName, L".") != 0 &&
2000 wcscmp(wFileData.cFileName, L"..") != 0) {
2001 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
2002 if (v == NULL) {
2003 Py_DECREF(d);
2004 d = NULL;
2005 break;
2007 if (PyList_Append(d, v) != 0) {
2008 Py_DECREF(v);
2009 Py_DECREF(d);
2010 d = NULL;
2011 break;
2013 Py_DECREF(v);
2015 Py_BEGIN_ALLOW_THREADS
2016 result = FindNextFileW(hFindFile, &wFileData);
2017 Py_END_ALLOW_THREADS
2018 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2019 it got to the end of the directory. */
2020 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2021 Py_DECREF(d);
2022 win32_error_unicode("FindNextFileW", wnamebuf);
2023 FindClose(hFindFile);
2024 free(wnamebuf);
2025 return NULL;
2027 } while (result == TRUE);
2029 if (FindClose(hFindFile) == FALSE) {
2030 Py_DECREF(d);
2031 win32_error_unicode("FindClose", wnamebuf);
2032 free(wnamebuf);
2033 return NULL;
2035 free(wnamebuf);
2036 return d;
2038 /* Drop the argument parsing error as narrow strings
2039 are also valid. */
2040 PyErr_Clear();
2042 #endif
2044 if (!PyArg_ParseTuple(args, "et#:listdir",
2045 Py_FileSystemDefaultEncoding, &bufptr, &len))
2046 return NULL;
2047 if (len > 0) {
2048 char ch = namebuf[len-1];
2049 if (ch != SEP && ch != ALTSEP && ch != ':')
2050 namebuf[len++] = '/';
2052 strcpy(namebuf + len, "*.*");
2054 if ((d = PyList_New(0)) == NULL)
2055 return NULL;
2057 hFindFile = FindFirstFile(namebuf, &FileData);
2058 if (hFindFile == INVALID_HANDLE_VALUE) {
2059 int error = GetLastError();
2060 if (error == ERROR_FILE_NOT_FOUND)
2061 return d;
2062 Py_DECREF(d);
2063 return win32_error("FindFirstFile", namebuf);
2065 do {
2066 /* Skip over . and .. */
2067 if (strcmp(FileData.cFileName, ".") != 0 &&
2068 strcmp(FileData.cFileName, "..") != 0) {
2069 v = PyString_FromString(FileData.cFileName);
2070 if (v == NULL) {
2071 Py_DECREF(d);
2072 d = NULL;
2073 break;
2075 if (PyList_Append(d, v) != 0) {
2076 Py_DECREF(v);
2077 Py_DECREF(d);
2078 d = NULL;
2079 break;
2081 Py_DECREF(v);
2083 Py_BEGIN_ALLOW_THREADS
2084 result = FindNextFile(hFindFile, &FileData);
2085 Py_END_ALLOW_THREADS
2086 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2087 it got to the end of the directory. */
2088 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
2089 Py_DECREF(d);
2090 win32_error("FindNextFile", namebuf);
2091 FindClose(hFindFile);
2092 return NULL;
2094 } while (result == TRUE);
2096 if (FindClose(hFindFile) == FALSE) {
2097 Py_DECREF(d);
2098 return win32_error("FindClose", namebuf);
2101 return d;
2103 #elif defined(PYOS_OS2)
2105 #ifndef MAX_PATH
2106 #define MAX_PATH CCHMAXPATH
2107 #endif
2108 char *name, *pt;
2109 Py_ssize_t len;
2110 PyObject *d, *v;
2111 char namebuf[MAX_PATH+5];
2112 HDIR hdir = 1;
2113 ULONG srchcnt = 1;
2114 FILEFINDBUF3 ep;
2115 APIRET rc;
2117 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
2118 return NULL;
2119 if (len >= MAX_PATH) {
2120 PyErr_SetString(PyExc_ValueError, "path too long");
2121 return NULL;
2123 strcpy(namebuf, name);
2124 for (pt = namebuf; *pt; pt++)
2125 if (*pt == ALTSEP)
2126 *pt = SEP;
2127 if (namebuf[len-1] != SEP)
2128 namebuf[len++] = SEP;
2129 strcpy(namebuf + len, "*.*");
2131 if ((d = PyList_New(0)) == NULL)
2132 return NULL;
2134 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
2135 &hdir, /* Handle to Use While Search Directory */
2136 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
2137 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
2138 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
2139 FIL_STANDARD); /* Format of Entry (EAs or Not) */
2141 if (rc != NO_ERROR) {
2142 errno = ENOENT;
2143 return posix_error_with_filename(name);
2146 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
2147 do {
2148 if (ep.achName[0] == '.'
2149 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
2150 continue; /* Skip Over "." and ".." Names */
2152 strcpy(namebuf, ep.achName);
2154 /* Leave Case of Name Alone -- In Native Form */
2155 /* (Removed Forced Lowercasing Code) */
2157 v = PyString_FromString(namebuf);
2158 if (v == NULL) {
2159 Py_DECREF(d);
2160 d = NULL;
2161 break;
2163 if (PyList_Append(d, v) != 0) {
2164 Py_DECREF(v);
2165 Py_DECREF(d);
2166 d = NULL;
2167 break;
2169 Py_DECREF(v);
2170 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2173 return d;
2174 #else
2176 char *name = NULL;
2177 PyObject *d, *v;
2178 DIR *dirp;
2179 struct dirent *ep;
2180 int arg_is_unicode = 1;
2182 errno = 0;
2183 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
2184 arg_is_unicode = 0;
2185 PyErr_Clear();
2187 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
2188 return NULL;
2189 if ((dirp = opendir(name)) == NULL) {
2190 return posix_error_with_allocated_filename(name);
2192 if ((d = PyList_New(0)) == NULL) {
2193 closedir(dirp);
2194 PyMem_Free(name);
2195 return NULL;
2197 for (;;) {
2198 Py_BEGIN_ALLOW_THREADS
2199 ep = readdir(dirp);
2200 Py_END_ALLOW_THREADS
2201 if (ep == NULL)
2202 break;
2203 if (ep->d_name[0] == '.' &&
2204 (NAMLEN(ep) == 1 ||
2205 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
2206 continue;
2207 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
2208 if (v == NULL) {
2209 Py_DECREF(d);
2210 d = NULL;
2211 break;
2213 #ifdef Py_USING_UNICODE
2214 if (arg_is_unicode) {
2215 PyObject *w;
2217 w = PyUnicode_FromEncodedObject(v,
2218 Py_FileSystemDefaultEncoding,
2219 "strict");
2220 if (w != NULL) {
2221 Py_DECREF(v);
2222 v = w;
2224 else {
2225 /* fall back to the original byte string, as
2226 discussed in patch #683592 */
2227 PyErr_Clear();
2230 #endif
2231 if (PyList_Append(d, v) != 0) {
2232 Py_DECREF(v);
2233 Py_DECREF(d);
2234 d = NULL;
2235 break;
2237 Py_DECREF(v);
2239 if (errno != 0 && d != NULL) {
2240 /* readdir() returned NULL and set errno */
2241 closedir(dirp);
2242 Py_DECREF(d);
2243 return posix_error_with_allocated_filename(name);
2245 closedir(dirp);
2246 PyMem_Free(name);
2248 return d;
2250 #endif /* which OS */
2251 } /* end of posix_listdir */
2253 #ifdef MS_WINDOWS
2254 /* A helper function for abspath on win32 */
2255 static PyObject *
2256 posix__getfullpathname(PyObject *self, PyObject *args)
2258 /* assume encoded strings wont more than double no of chars */
2259 char inbuf[MAX_PATH*2];
2260 char *inbufp = inbuf;
2261 Py_ssize_t insize = sizeof(inbuf);
2262 char outbuf[MAX_PATH*2];
2263 char *temp;
2264 #ifdef Py_WIN_WIDE_FILENAMES
2265 if (unicode_file_names()) {
2266 PyUnicodeObject *po;
2267 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
2268 Py_UNICODE woutbuf[MAX_PATH*2];
2269 Py_UNICODE *wtemp;
2270 if (!GetFullPathNameW(PyUnicode_AS_UNICODE(po),
2271 sizeof(woutbuf)/sizeof(woutbuf[0]),
2272 woutbuf, &wtemp))
2273 return win32_error("GetFullPathName", "");
2274 return PyUnicode_FromUnicode(woutbuf, wcslen(woutbuf));
2276 /* Drop the argument parsing error as narrow strings
2277 are also valid. */
2278 PyErr_Clear();
2280 #endif
2281 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
2282 Py_FileSystemDefaultEncoding, &inbufp,
2283 &insize))
2284 return NULL;
2285 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
2286 outbuf, &temp))
2287 return win32_error("GetFullPathName", inbuf);
2288 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2289 return PyUnicode_Decode(outbuf, strlen(outbuf),
2290 Py_FileSystemDefaultEncoding, NULL);
2292 return PyString_FromString(outbuf);
2293 } /* end of posix__getfullpathname */
2294 #endif /* MS_WINDOWS */
2296 PyDoc_STRVAR(posix_mkdir__doc__,
2297 "mkdir(path [, mode=0777])\n\n\
2298 Create a directory.");
2300 static PyObject *
2301 posix_mkdir(PyObject *self, PyObject *args)
2303 int res;
2304 char *path = NULL;
2305 int mode = 0777;
2307 #ifdef Py_WIN_WIDE_FILENAMES
2308 if (unicode_file_names()) {
2309 PyUnicodeObject *po;
2310 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
2311 Py_BEGIN_ALLOW_THREADS
2312 /* PyUnicode_AS_UNICODE OK without thread lock as
2313 it is a simple dereference. */
2314 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
2315 Py_END_ALLOW_THREADS
2316 if (!res)
2317 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
2318 Py_INCREF(Py_None);
2319 return Py_None;
2321 /* Drop the argument parsing error as narrow strings
2322 are also valid. */
2323 PyErr_Clear();
2325 if (!PyArg_ParseTuple(args, "et|i:mkdir",
2326 Py_FileSystemDefaultEncoding, &path, &mode))
2327 return NULL;
2328 Py_BEGIN_ALLOW_THREADS
2329 /* PyUnicode_AS_UNICODE OK without thread lock as
2330 it is a simple dereference. */
2331 res = CreateDirectoryA(path, NULL);
2332 Py_END_ALLOW_THREADS
2333 if (!res) {
2334 win32_error("mkdir", path);
2335 PyMem_Free(path);
2336 return NULL;
2338 PyMem_Free(path);
2339 Py_INCREF(Py_None);
2340 return Py_None;
2341 #else
2343 if (!PyArg_ParseTuple(args, "et|i:mkdir",
2344 Py_FileSystemDefaultEncoding, &path, &mode))
2345 return NULL;
2346 Py_BEGIN_ALLOW_THREADS
2347 #if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
2348 res = mkdir(path);
2349 #else
2350 res = mkdir(path, mode);
2351 #endif
2352 Py_END_ALLOW_THREADS
2353 if (res < 0)
2354 return posix_error_with_allocated_filename(path);
2355 PyMem_Free(path);
2356 Py_INCREF(Py_None);
2357 return Py_None;
2358 #endif
2362 /* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2363 #if defined(HAVE_SYS_RESOURCE_H)
2364 #include <sys/resource.h>
2365 #endif
2368 #ifdef HAVE_NICE
2369 PyDoc_STRVAR(posix_nice__doc__,
2370 "nice(inc) -> new_priority\n\n\
2371 Decrease the priority of process by inc and return the new priority.");
2373 static PyObject *
2374 posix_nice(PyObject *self, PyObject *args)
2376 int increment, value;
2378 if (!PyArg_ParseTuple(args, "i:nice", &increment))
2379 return NULL;
2381 /* There are two flavours of 'nice': one that returns the new
2382 priority (as required by almost all standards out there) and the
2383 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2384 the use of getpriority() to get the new priority.
2386 If we are of the nice family that returns the new priority, we
2387 need to clear errno before the call, and check if errno is filled
2388 before calling posix_error() on a returnvalue of -1, because the
2389 -1 may be the actual new priority! */
2391 errno = 0;
2392 value = nice(increment);
2393 #if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
2394 if (value == 0)
2395 value = getpriority(PRIO_PROCESS, 0);
2396 #endif
2397 if (value == -1 && errno != 0)
2398 /* either nice() or getpriority() returned an error */
2399 return posix_error();
2400 return PyInt_FromLong((long) value);
2402 #endif /* HAVE_NICE */
2404 PyDoc_STRVAR(posix_rename__doc__,
2405 "rename(old, new)\n\n\
2406 Rename a file or directory.");
2408 static PyObject *
2409 posix_rename(PyObject *self, PyObject *args)
2411 #ifdef MS_WINDOWS
2412 PyObject *o1, *o2;
2413 char *p1, *p2;
2414 BOOL result;
2415 if (unicode_file_names()) {
2416 if (!PyArg_ParseTuple(args, "O&O&:rename",
2417 convert_to_unicode, &o1,
2418 convert_to_unicode, &o2))
2419 PyErr_Clear();
2420 else {
2421 Py_BEGIN_ALLOW_THREADS
2422 result = MoveFileW(PyUnicode_AsUnicode(o1),
2423 PyUnicode_AsUnicode(o2));
2424 Py_END_ALLOW_THREADS
2425 Py_DECREF(o1);
2426 Py_DECREF(o2);
2427 if (!result)
2428 return win32_error("rename", NULL);
2429 Py_INCREF(Py_None);
2430 return Py_None;
2433 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
2434 return NULL;
2435 Py_BEGIN_ALLOW_THREADS
2436 result = MoveFileA(p1, p2);
2437 Py_END_ALLOW_THREADS
2438 if (!result)
2439 return win32_error("rename", NULL);
2440 Py_INCREF(Py_None);
2441 return Py_None;
2442 #else
2443 return posix_2str(args, "etet:rename", rename);
2444 #endif
2448 PyDoc_STRVAR(posix_rmdir__doc__,
2449 "rmdir(path)\n\n\
2450 Remove a directory.");
2452 static PyObject *
2453 posix_rmdir(PyObject *self, PyObject *args)
2455 #ifdef MS_WINDOWS
2456 return win32_1str(args, "rmdir", "s:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
2457 #else
2458 return posix_1str(args, "et:rmdir", rmdir);
2459 #endif
2463 PyDoc_STRVAR(posix_stat__doc__,
2464 "stat(path) -> stat result\n\n\
2465 Perform a stat system call on the given path.");
2467 static PyObject *
2468 posix_stat(PyObject *self, PyObject *args)
2470 #ifdef MS_WINDOWS
2471 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", win32_wstat);
2472 #else
2473 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
2474 #endif
2478 #ifdef HAVE_SYSTEM
2479 PyDoc_STRVAR(posix_system__doc__,
2480 "system(command) -> exit_status\n\n\
2481 Execute the command (a string) in a subshell.");
2483 static PyObject *
2484 posix_system(PyObject *self, PyObject *args)
2486 char *command;
2487 long sts;
2488 if (!PyArg_ParseTuple(args, "s:system", &command))
2489 return NULL;
2490 Py_BEGIN_ALLOW_THREADS
2491 sts = system(command);
2492 Py_END_ALLOW_THREADS
2493 return PyInt_FromLong(sts);
2495 #endif
2498 PyDoc_STRVAR(posix_umask__doc__,
2499 "umask(new_mask) -> old_mask\n\n\
2500 Set the current numeric umask and return the previous umask.");
2502 static PyObject *
2503 posix_umask(PyObject *self, PyObject *args)
2505 int i;
2506 if (!PyArg_ParseTuple(args, "i:umask", &i))
2507 return NULL;
2508 i = (int)umask(i);
2509 if (i < 0)
2510 return posix_error();
2511 return PyInt_FromLong((long)i);
2515 PyDoc_STRVAR(posix_unlink__doc__,
2516 "unlink(path)\n\n\
2517 Remove a file (same as remove(path)).");
2519 PyDoc_STRVAR(posix_remove__doc__,
2520 "remove(path)\n\n\
2521 Remove a file (same as unlink(path)).");
2523 static PyObject *
2524 posix_unlink(PyObject *self, PyObject *args)
2526 #ifdef MS_WINDOWS
2527 return win32_1str(args, "remove", "s:remove", DeleteFileA, "U:remove", DeleteFileW);
2528 #else
2529 return posix_1str(args, "et:remove", unlink);
2530 #endif
2534 #ifdef HAVE_UNAME
2535 PyDoc_STRVAR(posix_uname__doc__,
2536 "uname() -> (sysname, nodename, release, version, machine)\n\n\
2537 Return a tuple identifying the current operating system.");
2539 static PyObject *
2540 posix_uname(PyObject *self, PyObject *noargs)
2542 struct utsname u;
2543 int res;
2545 Py_BEGIN_ALLOW_THREADS
2546 res = uname(&u);
2547 Py_END_ALLOW_THREADS
2548 if (res < 0)
2549 return posix_error();
2550 return Py_BuildValue("(sssss)",
2551 u.sysname,
2552 u.nodename,
2553 u.release,
2554 u.version,
2555 u.machine);
2557 #endif /* HAVE_UNAME */
2559 static int
2560 extract_time(PyObject *t, long* sec, long* usec)
2562 long intval;
2563 if (PyFloat_Check(t)) {
2564 double tval = PyFloat_AsDouble(t);
2565 PyObject *intobj = t->ob_type->tp_as_number->nb_int(t);
2566 if (!intobj)
2567 return -1;
2568 intval = PyInt_AsLong(intobj);
2569 Py_DECREF(intobj);
2570 if (intval == -1 && PyErr_Occurred())
2571 return -1;
2572 *sec = intval;
2573 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
2574 if (*usec < 0)
2575 /* If rounding gave us a negative number,
2576 truncate. */
2577 *usec = 0;
2578 return 0;
2580 intval = PyInt_AsLong(t);
2581 if (intval == -1 && PyErr_Occurred())
2582 return -1;
2583 *sec = intval;
2584 *usec = 0;
2585 return 0;
2588 PyDoc_STRVAR(posix_utime__doc__,
2589 "utime(path, (atime, mtime))\n\
2590 utime(path, None)\n\n\
2591 Set the access and modified time of the file to the given values. If the\n\
2592 second form is used, set the access and modified times to the current time.");
2594 static PyObject *
2595 posix_utime(PyObject *self, PyObject *args)
2597 #ifdef Py_WIN_WIDE_FILENAMES
2598 PyObject *arg;
2599 PyUnicodeObject *obwpath;
2600 wchar_t *wpath = NULL;
2601 char *apath = NULL;
2602 HANDLE hFile;
2603 long atimesec, mtimesec, ausec, musec;
2604 FILETIME atime, mtime;
2605 PyObject *result = NULL;
2607 if (unicode_file_names()) {
2608 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
2609 wpath = PyUnicode_AS_UNICODE(obwpath);
2610 Py_BEGIN_ALLOW_THREADS
2611 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
2612 NULL, OPEN_EXISTING,
2613 FILE_FLAG_BACKUP_SEMANTICS, NULL);
2614 Py_END_ALLOW_THREADS
2615 if (hFile == INVALID_HANDLE_VALUE)
2616 return win32_error_unicode("utime", wpath);
2617 } else
2618 /* Drop the argument parsing error as narrow strings
2619 are also valid. */
2620 PyErr_Clear();
2622 if (!wpath) {
2623 if (!PyArg_ParseTuple(args, "etO:utime",
2624 Py_FileSystemDefaultEncoding, &apath, &arg))
2625 return NULL;
2626 Py_BEGIN_ALLOW_THREADS
2627 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
2628 NULL, OPEN_EXISTING,
2629 FILE_FLAG_BACKUP_SEMANTICS, NULL);
2630 Py_END_ALLOW_THREADS
2631 if (hFile == INVALID_HANDLE_VALUE) {
2632 win32_error("utime", apath);
2633 PyMem_Free(apath);
2634 return NULL;
2636 PyMem_Free(apath);
2639 if (arg == Py_None) {
2640 SYSTEMTIME now;
2641 GetSystemTime(&now);
2642 if (!SystemTimeToFileTime(&now, &mtime) ||
2643 !SystemTimeToFileTime(&now, &atime)) {
2644 win32_error("utime", NULL);
2645 goto done;
2648 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
2649 PyErr_SetString(PyExc_TypeError,
2650 "utime() arg 2 must be a tuple (atime, mtime)");
2651 goto done;
2653 else {
2654 if (extract_time(PyTuple_GET_ITEM(arg, 0),
2655 &atimesec, &ausec) == -1)
2656 goto done;
2657 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
2658 if (extract_time(PyTuple_GET_ITEM(arg, 1),
2659 &mtimesec, &musec) == -1)
2660 goto done;
2661 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
2663 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
2664 /* Avoid putting the file name into the error here,
2665 as that may confuse the user into believing that
2666 something is wrong with the file, when it also
2667 could be the time stamp that gives a problem. */
2668 win32_error("utime", NULL);
2670 Py_INCREF(Py_None);
2671 result = Py_None;
2672 done:
2673 CloseHandle(hFile);
2674 return result;
2675 #else /* Py_WIN_WIDE_FILENAMES */
2677 char *path = NULL;
2678 long atime, mtime, ausec, musec;
2679 int res;
2680 PyObject* arg;
2682 #if defined(HAVE_UTIMES)
2683 struct timeval buf[2];
2684 #define ATIME buf[0].tv_sec
2685 #define MTIME buf[1].tv_sec
2686 #elif defined(HAVE_UTIME_H)
2687 /* XXX should define struct utimbuf instead, above */
2688 struct utimbuf buf;
2689 #define ATIME buf.actime
2690 #define MTIME buf.modtime
2691 #define UTIME_ARG &buf
2692 #else /* HAVE_UTIMES */
2693 time_t buf[2];
2694 #define ATIME buf[0]
2695 #define MTIME buf[1]
2696 #define UTIME_ARG buf
2697 #endif /* HAVE_UTIMES */
2700 if (!PyArg_ParseTuple(args, "etO:utime",
2701 Py_FileSystemDefaultEncoding, &path, &arg))
2702 return NULL;
2703 if (arg == Py_None) {
2704 /* optional time values not given */
2705 Py_BEGIN_ALLOW_THREADS
2706 res = utime(path, NULL);
2707 Py_END_ALLOW_THREADS
2709 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
2710 PyErr_SetString(PyExc_TypeError,
2711 "utime() arg 2 must be a tuple (atime, mtime)");
2712 PyMem_Free(path);
2713 return NULL;
2715 else {
2716 if (extract_time(PyTuple_GET_ITEM(arg, 0),
2717 &atime, &ausec) == -1) {
2718 PyMem_Free(path);
2719 return NULL;
2721 if (extract_time(PyTuple_GET_ITEM(arg, 1),
2722 &mtime, &musec) == -1) {
2723 PyMem_Free(path);
2724 return NULL;
2726 ATIME = atime;
2727 MTIME = mtime;
2728 #ifdef HAVE_UTIMES
2729 buf[0].tv_usec = ausec;
2730 buf[1].tv_usec = musec;
2731 Py_BEGIN_ALLOW_THREADS
2732 res = utimes(path, buf);
2733 Py_END_ALLOW_THREADS
2734 #else
2735 Py_BEGIN_ALLOW_THREADS
2736 res = utime(path, UTIME_ARG);
2737 Py_END_ALLOW_THREADS
2738 #endif /* HAVE_UTIMES */
2740 if (res < 0) {
2741 return posix_error_with_allocated_filename(path);
2743 PyMem_Free(path);
2744 Py_INCREF(Py_None);
2745 return Py_None;
2746 #undef UTIME_ARG
2747 #undef ATIME
2748 #undef MTIME
2749 #endif /* Py_WIN_WIDE_FILENAMES */
2753 /* Process operations */
2755 PyDoc_STRVAR(posix__exit__doc__,
2756 "_exit(status)\n\n\
2757 Exit to the system with specified status, without normal exit processing.");
2759 static PyObject *
2760 posix__exit(PyObject *self, PyObject *args)
2762 int sts;
2763 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
2764 return NULL;
2765 _exit(sts);
2766 return NULL; /* Make gcc -Wall happy */
2769 #if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
2770 static void
2771 free_string_array(char **array, Py_ssize_t count)
2773 Py_ssize_t i;
2774 for (i = 0; i < count; i++)
2775 PyMem_Free(array[i]);
2776 PyMem_DEL(array);
2778 #endif
2781 #ifdef HAVE_EXECV
2782 PyDoc_STRVAR(posix_execv__doc__,
2783 "execv(path, args)\n\n\
2784 Execute an executable path with arguments, replacing current process.\n\
2786 path: path of executable file\n\
2787 args: tuple or list of strings");
2789 static PyObject *
2790 posix_execv(PyObject *self, PyObject *args)
2792 char *path;
2793 PyObject *argv;
2794 char **argvlist;
2795 Py_ssize_t i, argc;
2796 PyObject *(*getitem)(PyObject *, Py_ssize_t);
2798 /* execv has two arguments: (path, argv), where
2799 argv is a list or tuple of strings. */
2801 if (!PyArg_ParseTuple(args, "etO:execv",
2802 Py_FileSystemDefaultEncoding,
2803 &path, &argv))
2804 return NULL;
2805 if (PyList_Check(argv)) {
2806 argc = PyList_Size(argv);
2807 getitem = PyList_GetItem;
2809 else if (PyTuple_Check(argv)) {
2810 argc = PyTuple_Size(argv);
2811 getitem = PyTuple_GetItem;
2813 else {
2814 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
2815 PyMem_Free(path);
2816 return NULL;
2819 argvlist = PyMem_NEW(char *, argc+1);
2820 if (argvlist == NULL) {
2821 PyMem_Free(path);
2822 return PyErr_NoMemory();
2824 for (i = 0; i < argc; i++) {
2825 if (!PyArg_Parse((*getitem)(argv, i), "et",
2826 Py_FileSystemDefaultEncoding,
2827 &argvlist[i])) {
2828 free_string_array(argvlist, i);
2829 PyErr_SetString(PyExc_TypeError,
2830 "execv() arg 2 must contain only strings");
2831 PyMem_Free(path);
2832 return NULL;
2836 argvlist[argc] = NULL;
2838 execv(path, argvlist);
2840 /* If we get here it's definitely an error */
2842 free_string_array(argvlist, argc);
2843 PyMem_Free(path);
2844 return posix_error();
2848 PyDoc_STRVAR(posix_execve__doc__,
2849 "execve(path, args, env)\n\n\
2850 Execute a path with arguments and environment, replacing current process.\n\
2852 path: path of executable file\n\
2853 args: tuple or list of arguments\n\
2854 env: dictionary of strings mapping to strings");
2856 static PyObject *
2857 posix_execve(PyObject *self, PyObject *args)
2859 char *path;
2860 PyObject *argv, *env;
2861 char **argvlist;
2862 char **envlist;
2863 PyObject *key, *val, *keys=NULL, *vals=NULL;
2864 Py_ssize_t i, pos, argc, envc;
2865 PyObject *(*getitem)(PyObject *, Py_ssize_t);
2866 Py_ssize_t lastarg = 0;
2868 /* execve has three arguments: (path, argv, env), where
2869 argv is a list or tuple of strings and env is a dictionary
2870 like posix.environ. */
2872 if (!PyArg_ParseTuple(args, "etOO:execve",
2873 Py_FileSystemDefaultEncoding,
2874 &path, &argv, &env))
2875 return NULL;
2876 if (PyList_Check(argv)) {
2877 argc = PyList_Size(argv);
2878 getitem = PyList_GetItem;
2880 else if (PyTuple_Check(argv)) {
2881 argc = PyTuple_Size(argv);
2882 getitem = PyTuple_GetItem;
2884 else {
2885 PyErr_SetString(PyExc_TypeError,
2886 "execve() arg 2 must be a tuple or list");
2887 goto fail_0;
2889 if (!PyMapping_Check(env)) {
2890 PyErr_SetString(PyExc_TypeError,
2891 "execve() arg 3 must be a mapping object");
2892 goto fail_0;
2895 argvlist = PyMem_NEW(char *, argc+1);
2896 if (argvlist == NULL) {
2897 PyErr_NoMemory();
2898 goto fail_0;
2900 for (i = 0; i < argc; i++) {
2901 if (!PyArg_Parse((*getitem)(argv, i),
2902 "et;execve() arg 2 must contain only strings",
2903 Py_FileSystemDefaultEncoding,
2904 &argvlist[i]))
2906 lastarg = i;
2907 goto fail_1;
2910 lastarg = argc;
2911 argvlist[argc] = NULL;
2913 i = PyMapping_Size(env);
2914 if (i < 0)
2915 goto fail_1;
2916 envlist = PyMem_NEW(char *, i + 1);
2917 if (envlist == NULL) {
2918 PyErr_NoMemory();
2919 goto fail_1;
2921 envc = 0;
2922 keys = PyMapping_Keys(env);
2923 vals = PyMapping_Values(env);
2924 if (!keys || !vals)
2925 goto fail_2;
2926 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2927 PyErr_SetString(PyExc_TypeError,
2928 "execve(): env.keys() or env.values() is not a list");
2929 goto fail_2;
2932 for (pos = 0; pos < i; pos++) {
2933 char *p, *k, *v;
2934 size_t len;
2936 key = PyList_GetItem(keys, pos);
2937 val = PyList_GetItem(vals, pos);
2938 if (!key || !val)
2939 goto fail_2;
2941 if (!PyArg_Parse(
2942 key,
2943 "s;execve() arg 3 contains a non-string key",
2944 &k) ||
2945 !PyArg_Parse(
2946 val,
2947 "s;execve() arg 3 contains a non-string value",
2948 &v))
2950 goto fail_2;
2953 #if defined(PYOS_OS2)
2954 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
2955 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
2956 #endif
2957 len = PyString_Size(key) + PyString_Size(val) + 2;
2958 p = PyMem_NEW(char, len);
2959 if (p == NULL) {
2960 PyErr_NoMemory();
2961 goto fail_2;
2963 PyOS_snprintf(p, len, "%s=%s", k, v);
2964 envlist[envc++] = p;
2965 #if defined(PYOS_OS2)
2967 #endif
2969 envlist[envc] = 0;
2971 execve(path, argvlist, envlist);
2973 /* If we get here it's definitely an error */
2975 (void) posix_error();
2977 fail_2:
2978 while (--envc >= 0)
2979 PyMem_DEL(envlist[envc]);
2980 PyMem_DEL(envlist);
2981 fail_1:
2982 free_string_array(argvlist, lastarg);
2983 Py_XDECREF(vals);
2984 Py_XDECREF(keys);
2985 fail_0:
2986 PyMem_Free(path);
2987 return NULL;
2989 #endif /* HAVE_EXECV */
2992 #ifdef HAVE_SPAWNV
2993 PyDoc_STRVAR(posix_spawnv__doc__,
2994 "spawnv(mode, path, args)\n\n\
2995 Execute the program 'path' in a new process.\n\
2997 mode: mode of process creation\n\
2998 path: path of executable file\n\
2999 args: tuple or list of strings");
3001 static PyObject *
3002 posix_spawnv(PyObject *self, PyObject *args)
3004 char *path;
3005 PyObject *argv;
3006 char **argvlist;
3007 int mode, i;
3008 Py_ssize_t argc;
3009 Py_intptr_t spawnval;
3010 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3012 /* spawnv has three arguments: (mode, path, argv), where
3013 argv is a list or tuple of strings. */
3015 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
3016 Py_FileSystemDefaultEncoding,
3017 &path, &argv))
3018 return NULL;
3019 if (PyList_Check(argv)) {
3020 argc = PyList_Size(argv);
3021 getitem = PyList_GetItem;
3023 else if (PyTuple_Check(argv)) {
3024 argc = PyTuple_Size(argv);
3025 getitem = PyTuple_GetItem;
3027 else {
3028 PyErr_SetString(PyExc_TypeError,
3029 "spawnv() arg 2 must be a tuple or list");
3030 PyMem_Free(path);
3031 return NULL;
3034 argvlist = PyMem_NEW(char *, argc+1);
3035 if (argvlist == NULL) {
3036 PyMem_Free(path);
3037 return PyErr_NoMemory();
3039 for (i = 0; i < argc; i++) {
3040 if (!PyArg_Parse((*getitem)(argv, i), "et",
3041 Py_FileSystemDefaultEncoding,
3042 &argvlist[i])) {
3043 free_string_array(argvlist, i);
3044 PyErr_SetString(
3045 PyExc_TypeError,
3046 "spawnv() arg 2 must contain only strings");
3047 PyMem_Free(path);
3048 return NULL;
3051 argvlist[argc] = NULL;
3053 #if defined(PYOS_OS2) && defined(PYCC_GCC)
3054 Py_BEGIN_ALLOW_THREADS
3055 spawnval = spawnv(mode, path, argvlist);
3056 Py_END_ALLOW_THREADS
3057 #else
3058 if (mode == _OLD_P_OVERLAY)
3059 mode = _P_OVERLAY;
3061 Py_BEGIN_ALLOW_THREADS
3062 spawnval = _spawnv(mode, path, argvlist);
3063 Py_END_ALLOW_THREADS
3064 #endif
3066 free_string_array(argvlist, argc);
3067 PyMem_Free(path);
3069 if (spawnval == -1)
3070 return posix_error();
3071 else
3072 #if SIZEOF_LONG == SIZEOF_VOID_P
3073 return Py_BuildValue("l", (long) spawnval);
3074 #else
3075 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
3076 #endif
3080 PyDoc_STRVAR(posix_spawnve__doc__,
3081 "spawnve(mode, path, args, env)\n\n\
3082 Execute the program 'path' in a new process.\n\
3084 mode: mode of process creation\n\
3085 path: path of executable file\n\
3086 args: tuple or list of arguments\n\
3087 env: dictionary of strings mapping to strings");
3089 static PyObject *
3090 posix_spawnve(PyObject *self, PyObject *args)
3092 char *path;
3093 PyObject *argv, *env;
3094 char **argvlist;
3095 char **envlist;
3096 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3097 int mode, pos, envc;
3098 Py_ssize_t argc, i;
3099 Py_intptr_t spawnval;
3100 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3101 Py_ssize_t lastarg = 0;
3103 /* spawnve has four arguments: (mode, path, argv, env), where
3104 argv is a list or tuple of strings and env is a dictionary
3105 like posix.environ. */
3107 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
3108 Py_FileSystemDefaultEncoding,
3109 &path, &argv, &env))
3110 return NULL;
3111 if (PyList_Check(argv)) {
3112 argc = PyList_Size(argv);
3113 getitem = PyList_GetItem;
3115 else if (PyTuple_Check(argv)) {
3116 argc = PyTuple_Size(argv);
3117 getitem = PyTuple_GetItem;
3119 else {
3120 PyErr_SetString(PyExc_TypeError,
3121 "spawnve() arg 2 must be a tuple or list");
3122 goto fail_0;
3124 if (!PyMapping_Check(env)) {
3125 PyErr_SetString(PyExc_TypeError,
3126 "spawnve() arg 3 must be a mapping object");
3127 goto fail_0;
3130 argvlist = PyMem_NEW(char *, argc+1);
3131 if (argvlist == NULL) {
3132 PyErr_NoMemory();
3133 goto fail_0;
3135 for (i = 0; i < argc; i++) {
3136 if (!PyArg_Parse((*getitem)(argv, i),
3137 "et;spawnve() arg 2 must contain only strings",
3138 Py_FileSystemDefaultEncoding,
3139 &argvlist[i]))
3141 lastarg = i;
3142 goto fail_1;
3145 lastarg = argc;
3146 argvlist[argc] = NULL;
3148 i = PyMapping_Size(env);
3149 if (i < 0)
3150 goto fail_1;
3151 envlist = PyMem_NEW(char *, i + 1);
3152 if (envlist == NULL) {
3153 PyErr_NoMemory();
3154 goto fail_1;
3156 envc = 0;
3157 keys = PyMapping_Keys(env);
3158 vals = PyMapping_Values(env);
3159 if (!keys || !vals)
3160 goto fail_2;
3161 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3162 PyErr_SetString(PyExc_TypeError,
3163 "spawnve(): env.keys() or env.values() is not a list");
3164 goto fail_2;
3167 for (pos = 0; pos < i; pos++) {
3168 char *p, *k, *v;
3169 size_t len;
3171 key = PyList_GetItem(keys, pos);
3172 val = PyList_GetItem(vals, pos);
3173 if (!key || !val)
3174 goto fail_2;
3176 if (!PyArg_Parse(
3177 key,
3178 "s;spawnve() arg 3 contains a non-string key",
3179 &k) ||
3180 !PyArg_Parse(
3181 val,
3182 "s;spawnve() arg 3 contains a non-string value",
3183 &v))
3185 goto fail_2;
3187 len = PyString_Size(key) + PyString_Size(val) + 2;
3188 p = PyMem_NEW(char, len);
3189 if (p == NULL) {
3190 PyErr_NoMemory();
3191 goto fail_2;
3193 PyOS_snprintf(p, len, "%s=%s", k, v);
3194 envlist[envc++] = p;
3196 envlist[envc] = 0;
3198 #if defined(PYOS_OS2) && defined(PYCC_GCC)
3199 Py_BEGIN_ALLOW_THREADS
3200 spawnval = spawnve(mode, path, argvlist, envlist);
3201 Py_END_ALLOW_THREADS
3202 #else
3203 if (mode == _OLD_P_OVERLAY)
3204 mode = _P_OVERLAY;
3206 Py_BEGIN_ALLOW_THREADS
3207 spawnval = _spawnve(mode, path, argvlist, envlist);
3208 Py_END_ALLOW_THREADS
3209 #endif
3211 if (spawnval == -1)
3212 (void) posix_error();
3213 else
3214 #if SIZEOF_LONG == SIZEOF_VOID_P
3215 res = Py_BuildValue("l", (long) spawnval);
3216 #else
3217 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
3218 #endif
3220 fail_2:
3221 while (--envc >= 0)
3222 PyMem_DEL(envlist[envc]);
3223 PyMem_DEL(envlist);
3224 fail_1:
3225 free_string_array(argvlist, lastarg);
3226 Py_XDECREF(vals);
3227 Py_XDECREF(keys);
3228 fail_0:
3229 PyMem_Free(path);
3230 return res;
3233 /* OS/2 supports spawnvp & spawnvpe natively */
3234 #if defined(PYOS_OS2)
3235 PyDoc_STRVAR(posix_spawnvp__doc__,
3236 "spawnvp(mode, file, args)\n\n\
3237 Execute the program 'file' in a new process, using the environment\n\
3238 search path to find the file.\n\
3240 mode: mode of process creation\n\
3241 file: executable file name\n\
3242 args: tuple or list of strings");
3244 static PyObject *
3245 posix_spawnvp(PyObject *self, PyObject *args)
3247 char *path;
3248 PyObject *argv;
3249 char **argvlist;
3250 int mode, i, argc;
3251 Py_intptr_t spawnval;
3252 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3254 /* spawnvp has three arguments: (mode, path, argv), where
3255 argv is a list or tuple of strings. */
3257 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
3258 Py_FileSystemDefaultEncoding,
3259 &path, &argv))
3260 return NULL;
3261 if (PyList_Check(argv)) {
3262 argc = PyList_Size(argv);
3263 getitem = PyList_GetItem;
3265 else if (PyTuple_Check(argv)) {
3266 argc = PyTuple_Size(argv);
3267 getitem = PyTuple_GetItem;
3269 else {
3270 PyErr_SetString(PyExc_TypeError,
3271 "spawnvp() arg 2 must be a tuple or list");
3272 PyMem_Free(path);
3273 return NULL;
3276 argvlist = PyMem_NEW(char *, argc+1);
3277 if (argvlist == NULL) {
3278 PyMem_Free(path);
3279 return PyErr_NoMemory();
3281 for (i = 0; i < argc; i++) {
3282 if (!PyArg_Parse((*getitem)(argv, i), "et",
3283 Py_FileSystemDefaultEncoding,
3284 &argvlist[i])) {
3285 free_string_array(argvlist, i);
3286 PyErr_SetString(
3287 PyExc_TypeError,
3288 "spawnvp() arg 2 must contain only strings");
3289 PyMem_Free(path);
3290 return NULL;
3293 argvlist[argc] = NULL;
3295 Py_BEGIN_ALLOW_THREADS
3296 #if defined(PYCC_GCC)
3297 spawnval = spawnvp(mode, path, argvlist);
3298 #else
3299 spawnval = _spawnvp(mode, path, argvlist);
3300 #endif
3301 Py_END_ALLOW_THREADS
3303 free_string_array(argvlist, argc);
3304 PyMem_Free(path);
3306 if (spawnval == -1)
3307 return posix_error();
3308 else
3309 return Py_BuildValue("l", (long) spawnval);
3313 PyDoc_STRVAR(posix_spawnvpe__doc__,
3314 "spawnvpe(mode, file, args, env)\n\n\
3315 Execute the program 'file' in a new process, using the environment\n\
3316 search path to find the file.\n\
3318 mode: mode of process creation\n\
3319 file: executable file name\n\
3320 args: tuple or list of arguments\n\
3321 env: dictionary of strings mapping to strings");
3323 static PyObject *
3324 posix_spawnvpe(PyObject *self, PyObject *args)
3326 char *path;
3327 PyObject *argv, *env;
3328 char **argvlist;
3329 char **envlist;
3330 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3331 int mode, i, pos, argc, envc;
3332 Py_intptr_t spawnval;
3333 PyObject *(*getitem)(PyObject *, Py_ssize_t);
3334 int lastarg = 0;
3336 /* spawnvpe has four arguments: (mode, path, argv, env), where
3337 argv is a list or tuple of strings and env is a dictionary
3338 like posix.environ. */
3340 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
3341 Py_FileSystemDefaultEncoding,
3342 &path, &argv, &env))
3343 return NULL;
3344 if (PyList_Check(argv)) {
3345 argc = PyList_Size(argv);
3346 getitem = PyList_GetItem;
3348 else if (PyTuple_Check(argv)) {
3349 argc = PyTuple_Size(argv);
3350 getitem = PyTuple_GetItem;
3352 else {
3353 PyErr_SetString(PyExc_TypeError,
3354 "spawnvpe() arg 2 must be a tuple or list");
3355 goto fail_0;
3357 if (!PyMapping_Check(env)) {
3358 PyErr_SetString(PyExc_TypeError,
3359 "spawnvpe() arg 3 must be a mapping object");
3360 goto fail_0;
3363 argvlist = PyMem_NEW(char *, argc+1);
3364 if (argvlist == NULL) {
3365 PyErr_NoMemory();
3366 goto fail_0;
3368 for (i = 0; i < argc; i++) {
3369 if (!PyArg_Parse((*getitem)(argv, i),
3370 "et;spawnvpe() arg 2 must contain only strings",
3371 Py_FileSystemDefaultEncoding,
3372 &argvlist[i]))
3374 lastarg = i;
3375 goto fail_1;
3378 lastarg = argc;
3379 argvlist[argc] = NULL;
3381 i = PyMapping_Size(env);
3382 if (i < 0)
3383 goto fail_1;
3384 envlist = PyMem_NEW(char *, i + 1);
3385 if (envlist == NULL) {
3386 PyErr_NoMemory();
3387 goto fail_1;
3389 envc = 0;
3390 keys = PyMapping_Keys(env);
3391 vals = PyMapping_Values(env);
3392 if (!keys || !vals)
3393 goto fail_2;
3394 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3395 PyErr_SetString(PyExc_TypeError,
3396 "spawnvpe(): env.keys() or env.values() is not a list");
3397 goto fail_2;
3400 for (pos = 0; pos < i; pos++) {
3401 char *p, *k, *v;
3402 size_t len;
3404 key = PyList_GetItem(keys, pos);
3405 val = PyList_GetItem(vals, pos);
3406 if (!key || !val)
3407 goto fail_2;
3409 if (!PyArg_Parse(
3410 key,
3411 "s;spawnvpe() arg 3 contains a non-string key",
3412 &k) ||
3413 !PyArg_Parse(
3414 val,
3415 "s;spawnvpe() arg 3 contains a non-string value",
3416 &v))
3418 goto fail_2;
3420 len = PyString_Size(key) + PyString_Size(val) + 2;
3421 p = PyMem_NEW(char, len);
3422 if (p == NULL) {
3423 PyErr_NoMemory();
3424 goto fail_2;
3426 PyOS_snprintf(p, len, "%s=%s", k, v);
3427 envlist[envc++] = p;
3429 envlist[envc] = 0;
3431 Py_BEGIN_ALLOW_THREADS
3432 #if defined(PYCC_GCC)
3433 spawnval = spawnve(mode, path, argvlist, envlist);
3434 #else
3435 spawnval = _spawnve(mode, path, argvlist, envlist);
3436 #endif
3437 Py_END_ALLOW_THREADS
3439 if (spawnval == -1)
3440 (void) posix_error();
3441 else
3442 res = Py_BuildValue("l", (long) spawnval);
3444 fail_2:
3445 while (--envc >= 0)
3446 PyMem_DEL(envlist[envc]);
3447 PyMem_DEL(envlist);
3448 fail_1:
3449 free_string_array(argvlist, lastarg);
3450 Py_XDECREF(vals);
3451 Py_XDECREF(keys);
3452 fail_0:
3453 PyMem_Free(path);
3454 return res;
3456 #endif /* PYOS_OS2 */
3457 #endif /* HAVE_SPAWNV */
3460 #ifdef HAVE_FORK1
3461 PyDoc_STRVAR(posix_fork1__doc__,
3462 "fork1() -> pid\n\n\
3463 Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3465 Return 0 to child process and PID of child to parent process.");
3467 static PyObject *
3468 posix_fork1(PyObject *self, PyObject *noargs)
3470 int pid = fork1();
3471 if (pid == -1)
3472 return posix_error();
3473 PyOS_AfterFork();
3474 return PyInt_FromLong((long)pid);
3476 #endif
3479 #ifdef HAVE_FORK
3480 PyDoc_STRVAR(posix_fork__doc__,
3481 "fork() -> pid\n\n\
3482 Fork a child process.\n\
3483 Return 0 to child process and PID of child to parent process.");
3485 static PyObject *
3486 posix_fork(PyObject *self, PyObject *noargs)
3488 int pid = fork();
3489 if (pid == -1)
3490 return posix_error();
3491 if (pid == 0)
3492 PyOS_AfterFork();
3493 return PyInt_FromLong((long)pid);
3495 #endif
3497 /* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
3498 /* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3499 #if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
3500 #define DEV_PTY_FILE "/dev/ptc"
3501 #define HAVE_DEV_PTMX
3502 #else
3503 #define DEV_PTY_FILE "/dev/ptmx"
3504 #endif
3506 #if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
3507 #ifdef HAVE_PTY_H
3508 #include <pty.h>
3509 #else
3510 #ifdef HAVE_LIBUTIL_H
3511 #include <libutil.h>
3512 #endif /* HAVE_LIBUTIL_H */
3513 #endif /* HAVE_PTY_H */
3514 #ifdef HAVE_STROPTS_H
3515 #include <stropts.h>
3516 #endif
3517 #endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
3519 #if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
3520 PyDoc_STRVAR(posix_openpty__doc__,
3521 "openpty() -> (master_fd, slave_fd)\n\n\
3522 Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
3524 static PyObject *
3525 posix_openpty(PyObject *self, PyObject *noargs)
3527 int master_fd, slave_fd;
3528 #ifndef HAVE_OPENPTY
3529 char * slave_name;
3530 #endif
3531 #if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
3532 PyOS_sighandler_t sig_saved;
3533 #ifdef sun
3534 extern char *ptsname(int fildes);
3535 #endif
3536 #endif
3538 #ifdef HAVE_OPENPTY
3539 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
3540 return posix_error();
3541 #elif defined(HAVE__GETPTY)
3542 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
3543 if (slave_name == NULL)
3544 return posix_error();
3546 slave_fd = open(slave_name, O_RDWR);
3547 if (slave_fd < 0)
3548 return posix_error();
3549 #else
3550 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
3551 if (master_fd < 0)
3552 return posix_error();
3553 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
3554 /* change permission of slave */
3555 if (grantpt(master_fd) < 0) {
3556 PyOS_setsig(SIGCHLD, sig_saved);
3557 return posix_error();
3559 /* unlock slave */
3560 if (unlockpt(master_fd) < 0) {
3561 PyOS_setsig(SIGCHLD, sig_saved);
3562 return posix_error();
3564 PyOS_setsig(SIGCHLD, sig_saved);
3565 slave_name = ptsname(master_fd); /* get name of slave */
3566 if (slave_name == NULL)
3567 return posix_error();
3568 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
3569 if (slave_fd < 0)
3570 return posix_error();
3571 #if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
3572 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
3573 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
3574 #ifndef __hpux
3575 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
3576 #endif /* __hpux */
3577 #endif /* HAVE_CYGWIN */
3578 #endif /* HAVE_OPENPTY */
3580 return Py_BuildValue("(ii)", master_fd, slave_fd);
3583 #endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
3585 #ifdef HAVE_FORKPTY
3586 PyDoc_STRVAR(posix_forkpty__doc__,
3587 "forkpty() -> (pid, master_fd)\n\n\
3588 Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
3589 Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
3590 To both, return fd of newly opened pseudo-terminal.\n");
3592 static PyObject *
3593 posix_forkpty(PyObject *self, PyObject *noargs)
3595 int master_fd = -1, pid;
3597 pid = forkpty(&master_fd, NULL, NULL, NULL);
3598 if (pid == -1)
3599 return posix_error();
3600 if (pid == 0)
3601 PyOS_AfterFork();
3602 return Py_BuildValue("(ii)", pid, master_fd);
3604 #endif
3606 #ifdef HAVE_GETEGID
3607 PyDoc_STRVAR(posix_getegid__doc__,
3608 "getegid() -> egid\n\n\
3609 Return the current process's effective group id.");
3611 static PyObject *
3612 posix_getegid(PyObject *self, PyObject *noargs)
3614 return PyInt_FromLong((long)getegid());
3616 #endif
3619 #ifdef HAVE_GETEUID
3620 PyDoc_STRVAR(posix_geteuid__doc__,
3621 "geteuid() -> euid\n\n\
3622 Return the current process's effective user id.");
3624 static PyObject *
3625 posix_geteuid(PyObject *self, PyObject *noargs)
3627 return PyInt_FromLong((long)geteuid());
3629 #endif
3632 #ifdef HAVE_GETGID
3633 PyDoc_STRVAR(posix_getgid__doc__,
3634 "getgid() -> gid\n\n\
3635 Return the current process's group id.");
3637 static PyObject *
3638 posix_getgid(PyObject *self, PyObject *noargs)
3640 return PyInt_FromLong((long)getgid());
3642 #endif
3645 PyDoc_STRVAR(posix_getpid__doc__,
3646 "getpid() -> pid\n\n\
3647 Return the current process id");
3649 static PyObject *
3650 posix_getpid(PyObject *self, PyObject *noargs)
3652 return PyInt_FromLong((long)getpid());
3656 #ifdef HAVE_GETGROUPS
3657 PyDoc_STRVAR(posix_getgroups__doc__,
3658 "getgroups() -> list of group IDs\n\n\
3659 Return list of supplemental group IDs for the process.");
3661 static PyObject *
3662 posix_getgroups(PyObject *self, PyObject *noargs)
3664 PyObject *result = NULL;
3666 #ifdef NGROUPS_MAX
3667 #define MAX_GROUPS NGROUPS_MAX
3668 #else
3669 /* defined to be 16 on Solaris7, so this should be a small number */
3670 #define MAX_GROUPS 64
3671 #endif
3672 gid_t grouplist[MAX_GROUPS];
3673 int n;
3675 n = getgroups(MAX_GROUPS, grouplist);
3676 if (n < 0)
3677 posix_error();
3678 else {
3679 result = PyList_New(n);
3680 if (result != NULL) {
3681 int i;
3682 for (i = 0; i < n; ++i) {
3683 PyObject *o = PyInt_FromLong((long)grouplist[i]);
3684 if (o == NULL) {
3685 Py_DECREF(result);
3686 result = NULL;
3687 break;
3689 PyList_SET_ITEM(result, i, o);
3694 return result;
3696 #endif
3698 #ifdef HAVE_GETPGID
3699 PyDoc_STRVAR(posix_getpgid__doc__,
3700 "getpgid(pid) -> pgid\n\n\
3701 Call the system call getpgid().");
3703 static PyObject *
3704 posix_getpgid(PyObject *self, PyObject *args)
3706 int pid, pgid;
3707 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
3708 return NULL;
3709 pgid = getpgid(pid);
3710 if (pgid < 0)
3711 return posix_error();
3712 return PyInt_FromLong((long)pgid);
3714 #endif /* HAVE_GETPGID */
3717 #ifdef HAVE_GETPGRP
3718 PyDoc_STRVAR(posix_getpgrp__doc__,
3719 "getpgrp() -> pgrp\n\n\
3720 Return the current process group id.");
3722 static PyObject *
3723 posix_getpgrp(PyObject *self, PyObject *noargs)
3725 #ifdef GETPGRP_HAVE_ARG
3726 return PyInt_FromLong((long)getpgrp(0));
3727 #else /* GETPGRP_HAVE_ARG */
3728 return PyInt_FromLong((long)getpgrp());
3729 #endif /* GETPGRP_HAVE_ARG */
3731 #endif /* HAVE_GETPGRP */
3734 #ifdef HAVE_SETPGRP
3735 PyDoc_STRVAR(posix_setpgrp__doc__,
3736 "setpgrp()\n\n\
3737 Make this process a session leader.");
3739 static PyObject *
3740 posix_setpgrp(PyObject *self, PyObject *noargs)
3742 #ifdef SETPGRP_HAVE_ARG
3743 if (setpgrp(0, 0) < 0)
3744 #else /* SETPGRP_HAVE_ARG */
3745 if (setpgrp() < 0)
3746 #endif /* SETPGRP_HAVE_ARG */
3747 return posix_error();
3748 Py_INCREF(Py_None);
3749 return Py_None;
3752 #endif /* HAVE_SETPGRP */
3754 #ifdef HAVE_GETPPID
3755 PyDoc_STRVAR(posix_getppid__doc__,
3756 "getppid() -> ppid\n\n\
3757 Return the parent's process id.");
3759 static PyObject *
3760 posix_getppid(PyObject *self, PyObject *noargs)
3762 return PyInt_FromLong((long)getppid());
3764 #endif
3767 #ifdef HAVE_GETLOGIN
3768 PyDoc_STRVAR(posix_getlogin__doc__,
3769 "getlogin() -> string\n\n\
3770 Return the actual login name.");
3772 static PyObject *
3773 posix_getlogin(PyObject *self, PyObject *noargs)
3775 PyObject *result = NULL;
3776 char *name;
3777 int old_errno = errno;
3779 errno = 0;
3780 name = getlogin();
3781 if (name == NULL) {
3782 if (errno)
3783 posix_error();
3784 else
3785 PyErr_SetString(PyExc_OSError,
3786 "unable to determine login name");
3788 else
3789 result = PyString_FromString(name);
3790 errno = old_errno;
3792 return result;
3794 #endif
3796 #ifdef HAVE_GETUID
3797 PyDoc_STRVAR(posix_getuid__doc__,
3798 "getuid() -> uid\n\n\
3799 Return the current process's user id.");
3801 static PyObject *
3802 posix_getuid(PyObject *self, PyObject *noargs)
3804 return PyInt_FromLong((long)getuid());
3806 #endif
3809 #ifdef HAVE_KILL
3810 PyDoc_STRVAR(posix_kill__doc__,
3811 "kill(pid, sig)\n\n\
3812 Kill a process with a signal.");
3814 static PyObject *
3815 posix_kill(PyObject *self, PyObject *args)
3817 int pid, sig;
3818 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
3819 return NULL;
3820 #if defined(PYOS_OS2) && !defined(PYCC_GCC)
3821 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
3822 APIRET rc;
3823 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
3824 return os2_error(rc);
3826 } else if (sig == XCPT_SIGNAL_KILLPROC) {
3827 APIRET rc;
3828 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
3829 return os2_error(rc);
3831 } else
3832 return NULL; /* Unrecognized Signal Requested */
3833 #else
3834 if (kill(pid, sig) == -1)
3835 return posix_error();
3836 #endif
3837 Py_INCREF(Py_None);
3838 return Py_None;
3840 #endif
3842 #ifdef HAVE_KILLPG
3843 PyDoc_STRVAR(posix_killpg__doc__,
3844 "killpg(pgid, sig)\n\n\
3845 Kill a process group with a signal.");
3847 static PyObject *
3848 posix_killpg(PyObject *self, PyObject *args)
3850 int pgid, sig;
3851 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
3852 return NULL;
3853 if (killpg(pgid, sig) == -1)
3854 return posix_error();
3855 Py_INCREF(Py_None);
3856 return Py_None;
3858 #endif
3860 #ifdef HAVE_PLOCK
3862 #ifdef HAVE_SYS_LOCK_H
3863 #include <sys/lock.h>
3864 #endif
3866 PyDoc_STRVAR(posix_plock__doc__,
3867 "plock(op)\n\n\
3868 Lock program segments into memory.");
3870 static PyObject *
3871 posix_plock(PyObject *self, PyObject *args)
3873 int op;
3874 if (!PyArg_ParseTuple(args, "i:plock", &op))
3875 return NULL;
3876 if (plock(op) == -1)
3877 return posix_error();
3878 Py_INCREF(Py_None);
3879 return Py_None;
3881 #endif
3884 #ifdef HAVE_POPEN
3885 PyDoc_STRVAR(posix_popen__doc__,
3886 "popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
3887 Open a pipe to/from a command returning a file object.");
3889 #if defined(PYOS_OS2)
3890 #if defined(PYCC_VACPP)
3891 static int
3892 async_system(const char *command)
3894 char errormsg[256], args[1024];
3895 RESULTCODES rcodes;
3896 APIRET rc;
3898 char *shell = getenv("COMSPEC");
3899 if (!shell)
3900 shell = "cmd";
3902 /* avoid overflowing the argument buffer */
3903 if (strlen(shell) + 3 + strlen(command) >= 1024)
3904 return ERROR_NOT_ENOUGH_MEMORY
3906 args[0] = '\0';
3907 strcat(args, shell);
3908 strcat(args, "/c ");
3909 strcat(args, command);
3911 /* execute asynchronously, inheriting the environment */
3912 rc = DosExecPgm(errormsg,
3913 sizeof(errormsg),
3914 EXEC_ASYNC,
3915 args,
3916 NULL,
3917 &rcodes,
3918 shell);
3919 return rc;
3922 static FILE *
3923 popen(const char *command, const char *mode, int pipesize, int *err)
3925 int oldfd, tgtfd;
3926 HFILE pipeh[2];
3927 APIRET rc;
3929 /* mode determines which of stdin or stdout is reconnected to
3930 * the pipe to the child
3932 if (strchr(mode, 'r') != NULL) {
3933 tgt_fd = 1; /* stdout */
3934 } else if (strchr(mode, 'w')) {
3935 tgt_fd = 0; /* stdin */
3936 } else {
3937 *err = ERROR_INVALID_ACCESS;
3938 return NULL;
3941 /* setup the pipe */
3942 if ((rc = DosCreatePipe(&pipeh[0], &pipeh[1], pipesize)) != NO_ERROR) {
3943 *err = rc;
3944 return NULL;
3947 /* prevent other threads accessing stdio */
3948 DosEnterCritSec();
3950 /* reconnect stdio and execute child */
3951 oldfd = dup(tgtfd);
3952 close(tgtfd);
3953 if (dup2(pipeh[tgtfd], tgtfd) == 0) {
3954 DosClose(pipeh[tgtfd]);
3955 rc = async_system(command);
3958 /* restore stdio */
3959 dup2(oldfd, tgtfd);
3960 close(oldfd);
3962 /* allow other threads access to stdio */
3963 DosExitCritSec();
3965 /* if execution of child was successful return file stream */
3966 if (rc == NO_ERROR)
3967 return fdopen(pipeh[1 - tgtfd], mode);
3968 else {
3969 DosClose(pipeh[1 - tgtfd]);
3970 *err = rc;
3971 return NULL;
3975 static PyObject *
3976 posix_popen(PyObject *self, PyObject *args)
3978 char *name;
3979 char *mode = "r";
3980 int err, bufsize = -1;
3981 FILE *fp;
3982 PyObject *f;
3983 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
3984 return NULL;
3985 Py_BEGIN_ALLOW_THREADS
3986 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
3987 Py_END_ALLOW_THREADS
3988 if (fp == NULL)
3989 return os2_error(err);
3991 f = PyFile_FromFile(fp, name, mode, fclose);
3992 if (f != NULL)
3993 PyFile_SetBufSize(f, bufsize);
3994 return f;
3997 #elif defined(PYCC_GCC)
3999 /* standard posix version of popen() support */
4000 static PyObject *
4001 posix_popen(PyObject *self, PyObject *args)
4003 char *name;
4004 char *mode = "r";
4005 int bufsize = -1;
4006 FILE *fp;
4007 PyObject *f;
4008 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
4009 return NULL;
4010 Py_BEGIN_ALLOW_THREADS
4011 fp = popen(name, mode);
4012 Py_END_ALLOW_THREADS
4013 if (fp == NULL)
4014 return posix_error();
4015 f = PyFile_FromFile(fp, name, mode, pclose);
4016 if (f != NULL)
4017 PyFile_SetBufSize(f, bufsize);
4018 return f;
4021 /* fork() under OS/2 has lots'o'warts
4022 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
4023 * most of this code is a ripoff of the win32 code, but using the
4024 * capabilities of EMX's C library routines
4027 /* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
4028 #define POPEN_1 1
4029 #define POPEN_2 2
4030 #define POPEN_3 3
4031 #define POPEN_4 4
4033 static PyObject *_PyPopen(char *, int, int, int);
4034 static int _PyPclose(FILE *file);
4037 * Internal dictionary mapping popen* file pointers to process handles,
4038 * for use when retrieving the process exit code. See _PyPclose() below
4039 * for more information on this dictionary's use.
4041 static PyObject *_PyPopenProcs = NULL;
4043 /* os2emx version of popen2()
4045 * The result of this function is a pipe (file) connected to the
4046 * process's stdin, and a pipe connected to the process's stdout.
4049 static PyObject *
4050 os2emx_popen2(PyObject *self, PyObject *args)
4052 PyObject *f;
4053 int tm=0;
4055 char *cmdstring;
4056 char *mode = "t";
4057 int bufsize = -1;
4058 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
4059 return NULL;
4061 if (*mode == 't')
4062 tm = O_TEXT;
4063 else if (*mode != 'b') {
4064 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4065 return NULL;
4066 } else
4067 tm = O_BINARY;
4069 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
4071 return f;
4075 * Variation on os2emx.popen2
4077 * The result of this function is 3 pipes - the process's stdin,
4078 * stdout and stderr
4081 static PyObject *
4082 os2emx_popen3(PyObject *self, PyObject *args)
4084 PyObject *f;
4085 int tm = 0;
4087 char *cmdstring;
4088 char *mode = "t";
4089 int bufsize = -1;
4090 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
4091 return NULL;
4093 if (*mode == 't')
4094 tm = O_TEXT;
4095 else if (*mode != 'b') {
4096 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4097 return NULL;
4098 } else
4099 tm = O_BINARY;
4101 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
4103 return f;
4107 * Variation on os2emx.popen2
4109 * The result of this function is 2 pipes - the processes stdin,
4110 * and stdout+stderr combined as a single pipe.
4113 static PyObject *
4114 os2emx_popen4(PyObject *self, PyObject *args)
4116 PyObject *f;
4117 int tm = 0;
4119 char *cmdstring;
4120 char *mode = "t";
4121 int bufsize = -1;
4122 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
4123 return NULL;
4125 if (*mode == 't')
4126 tm = O_TEXT;
4127 else if (*mode != 'b') {
4128 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
4129 return NULL;
4130 } else
4131 tm = O_BINARY;
4133 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
4135 return f;
4138 /* a couple of structures for convenient handling of multiple
4139 * file handles and pipes
4141 struct file_ref
4143 int handle;
4144 int flags;
4147 struct pipe_ref
4149 int rd;
4150 int wr;
4153 /* The following code is derived from the win32 code */
4155 static PyObject *
4156 _PyPopen(char *cmdstring, int mode, int n, int bufsize)
4158 struct file_ref stdio[3];
4159 struct pipe_ref p_fd[3];
4160 FILE *p_s[3];
4161 int file_count, i, pipe_err, pipe_pid;
4162 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
4163 PyObject *f, *p_f[3];
4165 /* file modes for subsequent fdopen's on pipe handles */
4166 if (mode == O_TEXT)
4168 rd_mode = "rt";
4169 wr_mode = "wt";
4171 else
4173 rd_mode = "rb";
4174 wr_mode = "wb";
4177 /* prepare shell references */
4178 if ((shell = getenv("EMXSHELL")) == NULL)
4179 if ((shell = getenv("COMSPEC")) == NULL)
4181 errno = ENOENT;
4182 return posix_error();
4185 sh_name = _getname(shell);
4186 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
4187 opt = "/c";
4188 else
4189 opt = "-c";
4191 /* save current stdio fds + their flags, and set not inheritable */
4192 i = pipe_err = 0;
4193 while (pipe_err >= 0 && i < 3)
4195 pipe_err = stdio[i].handle = dup(i);
4196 stdio[i].flags = fcntl(i, F_GETFD, 0);
4197 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
4198 i++;
4200 if (pipe_err < 0)
4202 /* didn't get them all saved - clean up and bail out */
4203 int saved_err = errno;
4204 while (i-- > 0)
4206 close(stdio[i].handle);
4208 errno = saved_err;
4209 return posix_error();
4212 /* create pipe ends */
4213 file_count = 2;
4214 if (n == POPEN_3)
4215 file_count = 3;
4216 i = pipe_err = 0;
4217 while ((pipe_err == 0) && (i < file_count))
4218 pipe_err = pipe((int *)&p_fd[i++]);
4219 if (pipe_err < 0)
4221 /* didn't get them all made - clean up and bail out */
4222 while (i-- > 0)
4224 close(p_fd[i].wr);
4225 close(p_fd[i].rd);
4227 errno = EPIPE;
4228 return posix_error();
4231 /* change the actual standard IO streams over temporarily,
4232 * making the retained pipe ends non-inheritable
4234 pipe_err = 0;
4236 /* - stdin */
4237 if (dup2(p_fd[0].rd, 0) == 0)
4239 close(p_fd[0].rd);
4240 i = fcntl(p_fd[0].wr, F_GETFD, 0);
4241 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
4242 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
4244 close(p_fd[0].wr);
4245 pipe_err = -1;
4248 else
4250 pipe_err = -1;
4253 /* - stdout */
4254 if (pipe_err == 0)
4256 if (dup2(p_fd[1].wr, 1) == 1)
4258 close(p_fd[1].wr);
4259 i = fcntl(p_fd[1].rd, F_GETFD, 0);
4260 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
4261 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
4263 close(p_fd[1].rd);
4264 pipe_err = -1;
4267 else
4269 pipe_err = -1;
4273 /* - stderr, as required */
4274 if (pipe_err == 0)
4275 switch (n)
4277 case POPEN_3:
4279 if (dup2(p_fd[2].wr, 2) == 2)
4281 close(p_fd[2].wr);
4282 i = fcntl(p_fd[2].rd, F_GETFD, 0);
4283 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
4284 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
4286 close(p_fd[2].rd);
4287 pipe_err = -1;
4290 else
4292 pipe_err = -1;
4294 break;
4297 case POPEN_4:
4299 if (dup2(1, 2) != 2)
4301 pipe_err = -1;
4303 break;
4307 /* spawn the child process */
4308 if (pipe_err == 0)
4310 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
4311 if (pipe_pid == -1)
4313 pipe_err = -1;
4315 else
4317 /* save the PID into the FILE structure
4318 * NOTE: this implementation doesn't actually
4319 * take advantage of this, but do it for
4320 * completeness - AIM Apr01
4322 for (i = 0; i < file_count; i++)
4323 p_s[i]->_pid = pipe_pid;
4327 /* reset standard IO to normal */
4328 for (i = 0; i < 3; i++)
4330 dup2(stdio[i].handle, i);
4331 fcntl(i, F_SETFD, stdio[i].flags);
4332 close(stdio[i].handle);
4335 /* if any remnant problems, clean up and bail out */
4336 if (pipe_err < 0)
4338 for (i = 0; i < 3; i++)
4340 close(p_fd[i].rd);
4341 close(p_fd[i].wr);
4343 errno = EPIPE;
4344 return posix_error_with_filename(cmdstring);
4347 /* build tuple of file objects to return */
4348 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
4349 PyFile_SetBufSize(p_f[0], bufsize);
4350 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
4351 PyFile_SetBufSize(p_f[1], bufsize);
4352 if (n == POPEN_3)
4354 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
4355 PyFile_SetBufSize(p_f[0], bufsize);
4356 f = PyTuple_Pack(3, p_f[0], p_f[1], p_f[2]);
4358 else
4359 f = PyTuple_Pack(2, p_f[0], p_f[1]);
4362 * Insert the files we've created into the process dictionary
4363 * all referencing the list with the process handle and the
4364 * initial number of files (see description below in _PyPclose).
4365 * Since if _PyPclose later tried to wait on a process when all
4366 * handles weren't closed, it could create a deadlock with the
4367 * child, we spend some energy here to try to ensure that we
4368 * either insert all file handles into the dictionary or none
4369 * at all. It's a little clumsy with the various popen modes
4370 * and variable number of files involved.
4372 if (!_PyPopenProcs)
4374 _PyPopenProcs = PyDict_New();
4377 if (_PyPopenProcs)
4379 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
4380 int ins_rc[3];
4382 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4383 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4385 procObj = PyList_New(2);
4386 pidObj = PyInt_FromLong((long) pipe_pid);
4387 intObj = PyInt_FromLong((long) file_count);
4389 if (procObj && pidObj && intObj)
4391 PyList_SetItem(procObj, 0, pidObj);
4392 PyList_SetItem(procObj, 1, intObj);
4394 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
4395 if (fileObj[0])
4397 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4398 fileObj[0],
4399 procObj);
4401 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
4402 if (fileObj[1])
4404 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4405 fileObj[1],
4406 procObj);
4408 if (file_count >= 3)
4410 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
4411 if (fileObj[2])
4413 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4414 fileObj[2],
4415 procObj);
4419 if (ins_rc[0] < 0 || !fileObj[0] ||
4420 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4421 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
4423 /* Something failed - remove any dictionary
4424 * entries that did make it.
4426 if (!ins_rc[0] && fileObj[0])
4428 PyDict_DelItem(_PyPopenProcs,
4429 fileObj[0]);
4431 if (!ins_rc[1] && fileObj[1])
4433 PyDict_DelItem(_PyPopenProcs,
4434 fileObj[1]);
4436 if (!ins_rc[2] && fileObj[2])
4438 PyDict_DelItem(_PyPopenProcs,
4439 fileObj[2]);
4445 * Clean up our localized references for the dictionary keys
4446 * and value since PyDict_SetItem will Py_INCREF any copies
4447 * that got placed in the dictionary.
4449 Py_XDECREF(procObj);
4450 Py_XDECREF(fileObj[0]);
4451 Py_XDECREF(fileObj[1]);
4452 Py_XDECREF(fileObj[2]);
4455 /* Child is launched. */
4456 return f;
4460 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4461 * exit code for the child process and return as a result of the close.
4463 * This function uses the _PyPopenProcs dictionary in order to map the
4464 * input file pointer to information about the process that was
4465 * originally created by the popen* call that created the file pointer.
4466 * The dictionary uses the file pointer as a key (with one entry
4467 * inserted for each file returned by the original popen* call) and a
4468 * single list object as the value for all files from a single call.
4469 * The list object contains the Win32 process handle at [0], and a file
4470 * count at [1], which is initialized to the total number of file
4471 * handles using that list.
4473 * This function closes whichever handle it is passed, and decrements
4474 * the file count in the dictionary for the process handle pointed to
4475 * by this file. On the last close (when the file count reaches zero),
4476 * this function will wait for the child process and then return its
4477 * exit code as the result of the close() operation. This permits the
4478 * files to be closed in any order - it is always the close() of the
4479 * final handle that will return the exit code.
4481 * NOTE: This function is currently called with the GIL released.
4482 * hence we use the GILState API to manage our state.
4485 static int _PyPclose(FILE *file)
4487 int result;
4488 int exit_code;
4489 int pipe_pid;
4490 PyObject *procObj, *pidObj, *intObj, *fileObj;
4491 int file_count;
4492 #ifdef WITH_THREAD
4493 PyGILState_STATE state;
4494 #endif
4496 /* Close the file handle first, to ensure it can't block the
4497 * child from exiting if it's the last handle.
4499 result = fclose(file);
4501 #ifdef WITH_THREAD
4502 state = PyGILState_Ensure();
4503 #endif
4504 if (_PyPopenProcs)
4506 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4507 (procObj = PyDict_GetItem(_PyPopenProcs,
4508 fileObj)) != NULL &&
4509 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
4510 (intObj = PyList_GetItem(procObj,1)) != NULL)
4512 pipe_pid = (int) PyInt_AsLong(pidObj);
4513 file_count = (int) PyInt_AsLong(intObj);
4515 if (file_count > 1)
4517 /* Still other files referencing process */
4518 file_count--;
4519 PyList_SetItem(procObj,1,
4520 PyInt_FromLong((long) file_count));
4522 else
4524 /* Last file for this process */
4525 if (result != EOF &&
4526 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
4528 /* extract exit status */
4529 if (WIFEXITED(exit_code))
4531 result = WEXITSTATUS(exit_code);
4533 else
4535 errno = EPIPE;
4536 result = -1;
4539 else
4541 /* Indicate failure - this will cause the file object
4542 * to raise an I/O error and translate the last
4543 * error code from errno. We do have a problem with
4544 * last errors that overlap the normal errno table,
4545 * but that's a consistent problem with the file object.
4547 result = -1;
4551 /* Remove this file pointer from dictionary */
4552 PyDict_DelItem(_PyPopenProcs, fileObj);
4554 if (PyDict_Size(_PyPopenProcs) == 0)
4556 Py_DECREF(_PyPopenProcs);
4557 _PyPopenProcs = NULL;
4560 } /* if object retrieval ok */
4562 Py_XDECREF(fileObj);
4563 } /* if _PyPopenProcs */
4565 #ifdef WITH_THREAD
4566 PyGILState_Release(state);
4567 #endif
4568 return result;
4571 #endif /* PYCC_??? */
4573 #elif defined(MS_WINDOWS)
4576 * Portable 'popen' replacement for Win32.
4578 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
4579 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
4580 * Return code handling by David Bolen <db3l@fitlinxx.com>.
4583 #include <malloc.h>
4584 #include <io.h>
4585 #include <fcntl.h>
4587 /* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
4588 #define POPEN_1 1
4589 #define POPEN_2 2
4590 #define POPEN_3 3
4591 #define POPEN_4 4
4593 static PyObject *_PyPopen(char *, int, int);
4594 static int _PyPclose(FILE *file);
4597 * Internal dictionary mapping popen* file pointers to process handles,
4598 * for use when retrieving the process exit code. See _PyPclose() below
4599 * for more information on this dictionary's use.
4601 static PyObject *_PyPopenProcs = NULL;
4604 /* popen that works from a GUI.
4606 * The result of this function is a pipe (file) connected to the
4607 * processes stdin or stdout, depending on the requested mode.
4610 static PyObject *
4611 posix_popen(PyObject *self, PyObject *args)
4613 PyObject *f;
4614 int tm = 0;
4616 char *cmdstring;
4617 char *mode = "r";
4618 int bufsize = -1;
4619 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
4620 return NULL;
4622 if (*mode == 'r')
4623 tm = _O_RDONLY;
4624 else if (*mode != 'w') {
4625 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
4626 return NULL;
4627 } else
4628 tm = _O_WRONLY;
4630 if (bufsize != -1) {
4631 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
4632 return NULL;
4635 if (*(mode+1) == 't')
4636 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
4637 else if (*(mode+1) == 'b')
4638 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
4639 else
4640 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
4642 return f;
4645 /* Variation on win32pipe.popen
4647 * The result of this function is a pipe (file) connected to the
4648 * process's stdin, and a pipe connected to the process's stdout.
4651 static PyObject *
4652 win32_popen2(PyObject *self, PyObject *args)
4654 PyObject *f;
4655 int tm=0;
4657 char *cmdstring;
4658 char *mode = "t";
4659 int bufsize = -1;
4660 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
4661 return NULL;
4663 if (*mode == 't')
4664 tm = _O_TEXT;
4665 else if (*mode != 'b') {
4666 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
4667 return NULL;
4668 } else
4669 tm = _O_BINARY;
4671 if (bufsize != -1) {
4672 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
4673 return NULL;
4676 f = _PyPopen(cmdstring, tm, POPEN_2);
4678 return f;
4682 * Variation on <om win32pipe.popen>
4684 * The result of this function is 3 pipes - the process's stdin,
4685 * stdout and stderr
4688 static PyObject *
4689 win32_popen3(PyObject *self, PyObject *args)
4691 PyObject *f;
4692 int tm = 0;
4694 char *cmdstring;
4695 char *mode = "t";
4696 int bufsize = -1;
4697 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
4698 return NULL;
4700 if (*mode == 't')
4701 tm = _O_TEXT;
4702 else if (*mode != 'b') {
4703 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
4704 return NULL;
4705 } else
4706 tm = _O_BINARY;
4708 if (bufsize != -1) {
4709 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
4710 return NULL;
4713 f = _PyPopen(cmdstring, tm, POPEN_3);
4715 return f;
4719 * Variation on win32pipe.popen
4721 * The result of this function is 2 pipes - the processes stdin,
4722 * and stdout+stderr combined as a single pipe.
4725 static PyObject *
4726 win32_popen4(PyObject *self, PyObject *args)
4728 PyObject *f;
4729 int tm = 0;
4731 char *cmdstring;
4732 char *mode = "t";
4733 int bufsize = -1;
4734 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
4735 return NULL;
4737 if (*mode == 't')
4738 tm = _O_TEXT;
4739 else if (*mode != 'b') {
4740 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
4741 return NULL;
4742 } else
4743 tm = _O_BINARY;
4745 if (bufsize != -1) {
4746 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
4747 return NULL;
4750 f = _PyPopen(cmdstring, tm, POPEN_4);
4752 return f;
4755 static BOOL
4756 _PyPopenCreateProcess(char *cmdstring,
4757 HANDLE hStdin,
4758 HANDLE hStdout,
4759 HANDLE hStderr,
4760 HANDLE *hProcess)
4762 PROCESS_INFORMATION piProcInfo;
4763 STARTUPINFO siStartInfo;
4764 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
4765 char *s1,*s2, *s3 = " /c ";
4766 const char *szConsoleSpawn = "w9xpopen.exe";
4767 int i;
4768 Py_ssize_t x;
4770 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
4771 char *comshell;
4773 s1 = (char *)alloca(i);
4774 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
4775 /* x < i, so x fits into an integer */
4776 return (int)x;
4778 /* Explicitly check if we are using COMMAND.COM. If we are
4779 * then use the w9xpopen hack.
4781 comshell = s1 + x;
4782 while (comshell >= s1 && *comshell != '\\')
4783 --comshell;
4784 ++comshell;
4786 if (GetVersion() < 0x80000000 &&
4787 _stricmp(comshell, "command.com") != 0) {
4788 /* NT/2000 and not using command.com. */
4789 x = i + strlen(s3) + strlen(cmdstring) + 1;
4790 s2 = (char *)alloca(x);
4791 ZeroMemory(s2, x);
4792 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
4794 else {
4796 * Oh gag, we're on Win9x or using COMMAND.COM. Use
4797 * the workaround listed in KB: Q150956
4799 char modulepath[_MAX_PATH];
4800 struct stat statinfo;
4801 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
4802 for (x = i = 0; modulepath[i]; i++)
4803 if (modulepath[i] == SEP)
4804 x = i+1;
4805 modulepath[x] = '\0';
4806 /* Create the full-name to w9xpopen, so we can test it exists */
4807 strncat(modulepath,
4808 szConsoleSpawn,
4809 (sizeof(modulepath)/sizeof(modulepath[0]))
4810 -strlen(modulepath));
4811 if (stat(modulepath, &statinfo) != 0) {
4812 /* Eeek - file-not-found - possibly an embedding
4813 situation - see if we can locate it in sys.prefix
4815 strncpy(modulepath,
4816 Py_GetExecPrefix(),
4817 sizeof(modulepath)/sizeof(modulepath[0]));
4818 if (modulepath[strlen(modulepath)-1] != '\\')
4819 strcat(modulepath, "\\");
4820 strncat(modulepath,
4821 szConsoleSpawn,
4822 (sizeof(modulepath)/sizeof(modulepath[0]))
4823 -strlen(modulepath));
4824 /* No where else to look - raise an easily identifiable
4825 error, rather than leaving Windows to report
4826 "file not found" - as the user is probably blissfully
4827 unaware this shim EXE is used, and it will confuse them.
4828 (well, it confused me for a while ;-)
4830 if (stat(modulepath, &statinfo) != 0) {
4831 PyErr_Format(PyExc_RuntimeError,
4832 "Can not locate '%s' which is needed "
4833 "for popen to work with your shell "
4834 "or platform.",
4835 szConsoleSpawn);
4836 return FALSE;
4839 x = i + strlen(s3) + strlen(cmdstring) + 1 +
4840 strlen(modulepath) +
4841 strlen(szConsoleSpawn) + 1;
4843 s2 = (char *)alloca(x);
4844 ZeroMemory(s2, x);
4845 /* To maintain correct argument passing semantics,
4846 we pass the command-line as it stands, and allow
4847 quoting to be applied. w9xpopen.exe will then
4848 use its argv vector, and re-quote the necessary
4849 args for the ultimate child process.
4851 PyOS_snprintf(
4852 s2, x,
4853 "\"%s\" %s%s%s",
4854 modulepath,
4857 cmdstring);
4858 /* Not passing CREATE_NEW_CONSOLE has been known to
4859 cause random failures on win9x. Specifically a
4860 dialog:
4861 "Your program accessed mem currently in use at xxx"
4862 and a hopeful warning about the stability of your
4863 system.
4864 Cost is Ctrl+C wont kill children, but anyone
4865 who cares can have a go!
4867 dwProcessFlags |= CREATE_NEW_CONSOLE;
4871 /* Could be an else here to try cmd.exe / command.com in the path
4872 Now we'll just error out.. */
4873 else {
4874 PyErr_SetString(PyExc_RuntimeError,
4875 "Cannot locate a COMSPEC environment variable to "
4876 "use as the shell");
4877 return FALSE;
4880 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
4881 siStartInfo.cb = sizeof(STARTUPINFO);
4882 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
4883 siStartInfo.hStdInput = hStdin;
4884 siStartInfo.hStdOutput = hStdout;
4885 siStartInfo.hStdError = hStderr;
4886 siStartInfo.wShowWindow = SW_HIDE;
4888 if (CreateProcess(NULL,
4890 NULL,
4891 NULL,
4892 TRUE,
4893 dwProcessFlags,
4894 NULL,
4895 NULL,
4896 &siStartInfo,
4897 &piProcInfo) ) {
4898 /* Close the handles now so anyone waiting is woken. */
4899 CloseHandle(piProcInfo.hThread);
4901 /* Return process handle */
4902 *hProcess = piProcInfo.hProcess;
4903 return TRUE;
4905 win32_error("CreateProcess", s2);
4906 return FALSE;
4909 /* The following code is based off of KB: Q190351 */
4911 static PyObject *
4912 _PyPopen(char *cmdstring, int mode, int n)
4914 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
4915 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
4916 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
4918 SECURITY_ATTRIBUTES saAttr;
4919 BOOL fSuccess;
4920 int fd1, fd2, fd3;
4921 FILE *f1, *f2, *f3;
4922 long file_count;
4923 PyObject *f;
4925 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
4926 saAttr.bInheritHandle = TRUE;
4927 saAttr.lpSecurityDescriptor = NULL;
4929 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
4930 return win32_error("CreatePipe", NULL);
4932 /* Create new output read handle and the input write handle. Set
4933 * the inheritance properties to FALSE. Otherwise, the child inherits
4934 * these handles; resulting in non-closeable handles to the pipes
4935 * being created. */
4936 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
4937 GetCurrentProcess(), &hChildStdinWrDup, 0,
4938 FALSE,
4939 DUPLICATE_SAME_ACCESS);
4940 if (!fSuccess)
4941 return win32_error("DuplicateHandle", NULL);
4943 /* Close the inheritable version of ChildStdin
4944 that we're using. */
4945 CloseHandle(hChildStdinWr);
4947 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
4948 return win32_error("CreatePipe", NULL);
4950 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
4951 GetCurrentProcess(), &hChildStdoutRdDup, 0,
4952 FALSE, DUPLICATE_SAME_ACCESS);
4953 if (!fSuccess)
4954 return win32_error("DuplicateHandle", NULL);
4956 /* Close the inheritable version of ChildStdout
4957 that we're using. */
4958 CloseHandle(hChildStdoutRd);
4960 if (n != POPEN_4) {
4961 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
4962 return win32_error("CreatePipe", NULL);
4963 fSuccess = DuplicateHandle(GetCurrentProcess(),
4964 hChildStderrRd,
4965 GetCurrentProcess(),
4966 &hChildStderrRdDup, 0,
4967 FALSE, DUPLICATE_SAME_ACCESS);
4968 if (!fSuccess)
4969 return win32_error("DuplicateHandle", NULL);
4970 /* Close the inheritable version of ChildStdErr that we're using. */
4971 CloseHandle(hChildStderrRd);
4974 switch (n) {
4975 case POPEN_1:
4976 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
4977 case _O_WRONLY | _O_TEXT:
4978 /* Case for writing to child Stdin in text mode. */
4979 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
4980 f1 = _fdopen(fd1, "w");
4981 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
4982 PyFile_SetBufSize(f, 0);
4983 /* We don't care about these pipes anymore, so close them. */
4984 CloseHandle(hChildStdoutRdDup);
4985 CloseHandle(hChildStderrRdDup);
4986 break;
4988 case _O_RDONLY | _O_TEXT:
4989 /* Case for reading from child Stdout in text mode. */
4990 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
4991 f1 = _fdopen(fd1, "r");
4992 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
4993 PyFile_SetBufSize(f, 0);
4994 /* We don't care about these pipes anymore, so close them. */
4995 CloseHandle(hChildStdinWrDup);
4996 CloseHandle(hChildStderrRdDup);
4997 break;
4999 case _O_RDONLY | _O_BINARY:
5000 /* Case for readinig from child Stdout in binary mode. */
5001 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5002 f1 = _fdopen(fd1, "rb");
5003 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
5004 PyFile_SetBufSize(f, 0);
5005 /* We don't care about these pipes anymore, so close them. */
5006 CloseHandle(hChildStdinWrDup);
5007 CloseHandle(hChildStderrRdDup);
5008 break;
5010 case _O_WRONLY | _O_BINARY:
5011 /* Case for writing to child Stdin in binary mode. */
5012 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5013 f1 = _fdopen(fd1, "wb");
5014 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
5015 PyFile_SetBufSize(f, 0);
5016 /* We don't care about these pipes anymore, so close them. */
5017 CloseHandle(hChildStdoutRdDup);
5018 CloseHandle(hChildStderrRdDup);
5019 break;
5021 file_count = 1;
5022 break;
5024 case POPEN_2:
5025 case POPEN_4:
5027 char *m1, *m2;
5028 PyObject *p1, *p2;
5030 if (mode & _O_TEXT) {
5031 m1 = "r";
5032 m2 = "w";
5033 } else {
5034 m1 = "rb";
5035 m2 = "wb";
5038 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5039 f1 = _fdopen(fd1, m2);
5040 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5041 f2 = _fdopen(fd2, m1);
5042 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
5043 PyFile_SetBufSize(p1, 0);
5044 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
5045 PyFile_SetBufSize(p2, 0);
5047 if (n != 4)
5048 CloseHandle(hChildStderrRdDup);
5050 f = PyTuple_Pack(2,p1,p2);
5051 Py_XDECREF(p1);
5052 Py_XDECREF(p2);
5053 file_count = 2;
5054 break;
5057 case POPEN_3:
5059 char *m1, *m2;
5060 PyObject *p1, *p2, *p3;
5062 if (mode & _O_TEXT) {
5063 m1 = "r";
5064 m2 = "w";
5065 } else {
5066 m1 = "rb";
5067 m2 = "wb";
5070 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
5071 f1 = _fdopen(fd1, m2);
5072 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
5073 f2 = _fdopen(fd2, m1);
5074 fd3 = _open_osfhandle((Py_intptr_t)hChildStderrRdDup, mode);
5075 f3 = _fdopen(fd3, m1);
5076 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
5077 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
5078 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
5079 PyFile_SetBufSize(p1, 0);
5080 PyFile_SetBufSize(p2, 0);
5081 PyFile_SetBufSize(p3, 0);
5082 f = PyTuple_Pack(3,p1,p2,p3);
5083 Py_XDECREF(p1);
5084 Py_XDECREF(p2);
5085 Py_XDECREF(p3);
5086 file_count = 3;
5087 break;
5091 if (n == POPEN_4) {
5092 if (!_PyPopenCreateProcess(cmdstring,
5093 hChildStdinRd,
5094 hChildStdoutWr,
5095 hChildStdoutWr,
5096 &hProcess))
5097 return NULL;
5099 else {
5100 if (!_PyPopenCreateProcess(cmdstring,
5101 hChildStdinRd,
5102 hChildStdoutWr,
5103 hChildStderrWr,
5104 &hProcess))
5105 return NULL;
5109 * Insert the files we've created into the process dictionary
5110 * all referencing the list with the process handle and the
5111 * initial number of files (see description below in _PyPclose).
5112 * Since if _PyPclose later tried to wait on a process when all
5113 * handles weren't closed, it could create a deadlock with the
5114 * child, we spend some energy here to try to ensure that we
5115 * either insert all file handles into the dictionary or none
5116 * at all. It's a little clumsy with the various popen modes
5117 * and variable number of files involved.
5119 if (!_PyPopenProcs) {
5120 _PyPopenProcs = PyDict_New();
5123 if (_PyPopenProcs) {
5124 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
5125 int ins_rc[3];
5127 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
5128 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
5130 procObj = PyList_New(2);
5131 hProcessObj = PyLong_FromVoidPtr(hProcess);
5132 intObj = PyInt_FromLong(file_count);
5134 if (procObj && hProcessObj && intObj) {
5135 PyList_SetItem(procObj,0,hProcessObj);
5136 PyList_SetItem(procObj,1,intObj);
5138 fileObj[0] = PyLong_FromVoidPtr(f1);
5139 if (fileObj[0]) {
5140 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
5141 fileObj[0],
5142 procObj);
5144 if (file_count >= 2) {
5145 fileObj[1] = PyLong_FromVoidPtr(f2);
5146 if (fileObj[1]) {
5147 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
5148 fileObj[1],
5149 procObj);
5152 if (file_count >= 3) {
5153 fileObj[2] = PyLong_FromVoidPtr(f3);
5154 if (fileObj[2]) {
5155 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
5156 fileObj[2],
5157 procObj);
5161 if (ins_rc[0] < 0 || !fileObj[0] ||
5162 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
5163 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
5164 /* Something failed - remove any dictionary
5165 * entries that did make it.
5167 if (!ins_rc[0] && fileObj[0]) {
5168 PyDict_DelItem(_PyPopenProcs,
5169 fileObj[0]);
5171 if (!ins_rc[1] && fileObj[1]) {
5172 PyDict_DelItem(_PyPopenProcs,
5173 fileObj[1]);
5175 if (!ins_rc[2] && fileObj[2]) {
5176 PyDict_DelItem(_PyPopenProcs,
5177 fileObj[2]);
5183 * Clean up our localized references for the dictionary keys
5184 * and value since PyDict_SetItem will Py_INCREF any copies
5185 * that got placed in the dictionary.
5187 Py_XDECREF(procObj);
5188 Py_XDECREF(fileObj[0]);
5189 Py_XDECREF(fileObj[1]);
5190 Py_XDECREF(fileObj[2]);
5193 /* Child is launched. Close the parents copy of those pipe
5194 * handles that only the child should have open. You need to
5195 * make sure that no handles to the write end of the output pipe
5196 * are maintained in this process or else the pipe will not close
5197 * when the child process exits and the ReadFile will hang. */
5199 if (!CloseHandle(hChildStdinRd))
5200 return win32_error("CloseHandle", NULL);
5202 if (!CloseHandle(hChildStdoutWr))
5203 return win32_error("CloseHandle", NULL);
5205 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
5206 return win32_error("CloseHandle", NULL);
5208 return f;
5212 * Wrapper for fclose() to use for popen* files, so we can retrieve the
5213 * exit code for the child process and return as a result of the close.
5215 * This function uses the _PyPopenProcs dictionary in order to map the
5216 * input file pointer to information about the process that was
5217 * originally created by the popen* call that created the file pointer.
5218 * The dictionary uses the file pointer as a key (with one entry
5219 * inserted for each file returned by the original popen* call) and a
5220 * single list object as the value for all files from a single call.
5221 * The list object contains the Win32 process handle at [0], and a file
5222 * count at [1], which is initialized to the total number of file
5223 * handles using that list.
5225 * This function closes whichever handle it is passed, and decrements
5226 * the file count in the dictionary for the process handle pointed to
5227 * by this file. On the last close (when the file count reaches zero),
5228 * this function will wait for the child process and then return its
5229 * exit code as the result of the close() operation. This permits the
5230 * files to be closed in any order - it is always the close() of the
5231 * final handle that will return the exit code.
5233 * NOTE: This function is currently called with the GIL released.
5234 * hence we use the GILState API to manage our state.
5237 static int _PyPclose(FILE *file)
5239 int result;
5240 DWORD exit_code;
5241 HANDLE hProcess;
5242 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
5243 long file_count;
5244 #ifdef WITH_THREAD
5245 PyGILState_STATE state;
5246 #endif
5248 /* Close the file handle first, to ensure it can't block the
5249 * child from exiting if it's the last handle.
5251 result = fclose(file);
5252 #ifdef WITH_THREAD
5253 state = PyGILState_Ensure();
5254 #endif
5255 if (_PyPopenProcs) {
5256 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
5257 (procObj = PyDict_GetItem(_PyPopenProcs,
5258 fileObj)) != NULL &&
5259 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
5260 (intObj = PyList_GetItem(procObj,1)) != NULL) {
5262 hProcess = PyLong_AsVoidPtr(hProcessObj);
5263 file_count = PyInt_AsLong(intObj);
5265 if (file_count > 1) {
5266 /* Still other files referencing process */
5267 file_count--;
5268 PyList_SetItem(procObj,1,
5269 PyInt_FromLong(file_count));
5270 } else {
5271 /* Last file for this process */
5272 if (result != EOF &&
5273 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
5274 GetExitCodeProcess(hProcess, &exit_code)) {
5275 /* Possible truncation here in 16-bit environments, but
5276 * real exit codes are just the lower byte in any event.
5278 result = exit_code;
5279 } else {
5280 /* Indicate failure - this will cause the file object
5281 * to raise an I/O error and translate the last Win32
5282 * error code from errno. We do have a problem with
5283 * last errors that overlap the normal errno table,
5284 * but that's a consistent problem with the file object.
5286 if (result != EOF) {
5287 /* If the error wasn't from the fclose(), then
5288 * set errno for the file object error handling.
5290 errno = GetLastError();
5292 result = -1;
5295 /* Free up the native handle at this point */
5296 CloseHandle(hProcess);
5299 /* Remove this file pointer from dictionary */
5300 PyDict_DelItem(_PyPopenProcs, fileObj);
5302 if (PyDict_Size(_PyPopenProcs) == 0) {
5303 Py_DECREF(_PyPopenProcs);
5304 _PyPopenProcs = NULL;
5307 } /* if object retrieval ok */
5309 Py_XDECREF(fileObj);
5310 } /* if _PyPopenProcs */
5312 #ifdef WITH_THREAD
5313 PyGILState_Release(state);
5314 #endif
5315 return result;
5318 #else /* which OS? */
5319 static PyObject *
5320 posix_popen(PyObject *self, PyObject *args)
5322 char *name;
5323 char *mode = "r";
5324 int bufsize = -1;
5325 FILE *fp;
5326 PyObject *f;
5327 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
5328 return NULL;
5329 /* Strip mode of binary or text modifiers */
5330 if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
5331 mode = "r";
5332 else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
5333 mode = "w";
5334 Py_BEGIN_ALLOW_THREADS
5335 fp = popen(name, mode);
5336 Py_END_ALLOW_THREADS
5337 if (fp == NULL)
5338 return posix_error();
5339 f = PyFile_FromFile(fp, name, mode, pclose);
5340 if (f != NULL)
5341 PyFile_SetBufSize(f, bufsize);
5342 return f;
5345 #endif /* PYOS_??? */
5346 #endif /* HAVE_POPEN */
5349 #ifdef HAVE_SETUID
5350 PyDoc_STRVAR(posix_setuid__doc__,
5351 "setuid(uid)\n\n\
5352 Set the current process's user id.");
5354 static PyObject *
5355 posix_setuid(PyObject *self, PyObject *args)
5357 int uid;
5358 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
5359 return NULL;
5360 if (setuid(uid) < 0)
5361 return posix_error();
5362 Py_INCREF(Py_None);
5363 return Py_None;
5365 #endif /* HAVE_SETUID */
5368 #ifdef HAVE_SETEUID
5369 PyDoc_STRVAR(posix_seteuid__doc__,
5370 "seteuid(uid)\n\n\
5371 Set the current process's effective user id.");
5373 static PyObject *
5374 posix_seteuid (PyObject *self, PyObject *args)
5376 int euid;
5377 if (!PyArg_ParseTuple(args, "i", &euid)) {
5378 return NULL;
5379 } else if (seteuid(euid) < 0) {
5380 return posix_error();
5381 } else {
5382 Py_INCREF(Py_None);
5383 return Py_None;
5386 #endif /* HAVE_SETEUID */
5388 #ifdef HAVE_SETEGID
5389 PyDoc_STRVAR(posix_setegid__doc__,
5390 "setegid(gid)\n\n\
5391 Set the current process's effective group id.");
5393 static PyObject *
5394 posix_setegid (PyObject *self, PyObject *args)
5396 int egid;
5397 if (!PyArg_ParseTuple(args, "i", &egid)) {
5398 return NULL;
5399 } else if (setegid(egid) < 0) {
5400 return posix_error();
5401 } else {
5402 Py_INCREF(Py_None);
5403 return Py_None;
5406 #endif /* HAVE_SETEGID */
5408 #ifdef HAVE_SETREUID
5409 PyDoc_STRVAR(posix_setreuid__doc__,
5410 "setreuid(ruid, euid)\n\n\
5411 Set the current process's real and effective user ids.");
5413 static PyObject *
5414 posix_setreuid (PyObject *self, PyObject *args)
5416 int ruid, euid;
5417 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
5418 return NULL;
5419 } else if (setreuid(ruid, euid) < 0) {
5420 return posix_error();
5421 } else {
5422 Py_INCREF(Py_None);
5423 return Py_None;
5426 #endif /* HAVE_SETREUID */
5428 #ifdef HAVE_SETREGID
5429 PyDoc_STRVAR(posix_setregid__doc__,
5430 "setregid(rgid, egid)\n\n\
5431 Set the current process's real and effective group ids.");
5433 static PyObject *
5434 posix_setregid (PyObject *self, PyObject *args)
5436 int rgid, egid;
5437 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
5438 return NULL;
5439 } else if (setregid(rgid, egid) < 0) {
5440 return posix_error();
5441 } else {
5442 Py_INCREF(Py_None);
5443 return Py_None;
5446 #endif /* HAVE_SETREGID */
5448 #ifdef HAVE_SETGID
5449 PyDoc_STRVAR(posix_setgid__doc__,
5450 "setgid(gid)\n\n\
5451 Set the current process's group id.");
5453 static PyObject *
5454 posix_setgid(PyObject *self, PyObject *args)
5456 int gid;
5457 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
5458 return NULL;
5459 if (setgid(gid) < 0)
5460 return posix_error();
5461 Py_INCREF(Py_None);
5462 return Py_None;
5464 #endif /* HAVE_SETGID */
5466 #ifdef HAVE_SETGROUPS
5467 PyDoc_STRVAR(posix_setgroups__doc__,
5468 "setgroups(list)\n\n\
5469 Set the groups of the current process to list.");
5471 static PyObject *
5472 posix_setgroups(PyObject *self, PyObject *groups)
5474 int i, len;
5475 gid_t grouplist[MAX_GROUPS];
5477 if (!PySequence_Check(groups)) {
5478 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
5479 return NULL;
5481 len = PySequence_Size(groups);
5482 if (len > MAX_GROUPS) {
5483 PyErr_SetString(PyExc_ValueError, "too many groups");
5484 return NULL;
5486 for(i = 0; i < len; i++) {
5487 PyObject *elem;
5488 elem = PySequence_GetItem(groups, i);
5489 if (!elem)
5490 return NULL;
5491 if (!PyInt_Check(elem)) {
5492 if (!PyLong_Check(elem)) {
5493 PyErr_SetString(PyExc_TypeError,
5494 "groups must be integers");
5495 Py_DECREF(elem);
5496 return NULL;
5497 } else {
5498 unsigned long x = PyLong_AsUnsignedLong(elem);
5499 if (PyErr_Occurred()) {
5500 PyErr_SetString(PyExc_TypeError,
5501 "group id too big");
5502 Py_DECREF(elem);
5503 return NULL;
5505 grouplist[i] = x;
5506 /* read back the value to see if it fitted in gid_t */
5507 if (grouplist[i] != x) {
5508 PyErr_SetString(PyExc_TypeError,
5509 "group id too big");
5510 Py_DECREF(elem);
5511 return NULL;
5514 } else {
5515 long x = PyInt_AsLong(elem);
5516 grouplist[i] = x;
5517 if (grouplist[i] != x) {
5518 PyErr_SetString(PyExc_TypeError,
5519 "group id too big");
5520 Py_DECREF(elem);
5521 return NULL;
5524 Py_DECREF(elem);
5527 if (setgroups(len, grouplist) < 0)
5528 return posix_error();
5529 Py_INCREF(Py_None);
5530 return Py_None;
5532 #endif /* HAVE_SETGROUPS */
5534 #if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
5535 static PyObject *
5536 wait_helper(int pid, int status, struct rusage *ru)
5538 PyObject *result;
5539 static PyObject *struct_rusage;
5541 if (pid == -1)
5542 return posix_error();
5544 if (struct_rusage == NULL) {
5545 PyObject *m = PyImport_ImportModule("resource");
5546 if (m == NULL)
5547 return NULL;
5548 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
5549 Py_DECREF(m);
5550 if (struct_rusage == NULL)
5551 return NULL;
5554 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
5555 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
5556 if (!result)
5557 return NULL;
5559 #ifndef doubletime
5560 #define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
5561 #endif
5563 PyStructSequence_SET_ITEM(result, 0,
5564 PyFloat_FromDouble(doubletime(ru->ru_utime)));
5565 PyStructSequence_SET_ITEM(result, 1,
5566 PyFloat_FromDouble(doubletime(ru->ru_stime)));
5567 #define SET_INT(result, index, value)\
5568 PyStructSequence_SET_ITEM(result, index, PyInt_FromLong(value))
5569 SET_INT(result, 2, ru->ru_maxrss);
5570 SET_INT(result, 3, ru->ru_ixrss);
5571 SET_INT(result, 4, ru->ru_idrss);
5572 SET_INT(result, 5, ru->ru_isrss);
5573 SET_INT(result, 6, ru->ru_minflt);
5574 SET_INT(result, 7, ru->ru_majflt);
5575 SET_INT(result, 8, ru->ru_nswap);
5576 SET_INT(result, 9, ru->ru_inblock);
5577 SET_INT(result, 10, ru->ru_oublock);
5578 SET_INT(result, 11, ru->ru_msgsnd);
5579 SET_INT(result, 12, ru->ru_msgrcv);
5580 SET_INT(result, 13, ru->ru_nsignals);
5581 SET_INT(result, 14, ru->ru_nvcsw);
5582 SET_INT(result, 15, ru->ru_nivcsw);
5583 #undef SET_INT
5585 if (PyErr_Occurred()) {
5586 Py_DECREF(result);
5587 return NULL;
5590 return Py_BuildValue("iiN", pid, status, result);
5592 #endif /* HAVE_WAIT3 || HAVE_WAIT4 */
5594 #ifdef HAVE_WAIT3
5595 PyDoc_STRVAR(posix_wait3__doc__,
5596 "wait3(options) -> (pid, status, rusage)\n\n\
5597 Wait for completion of a child process.");
5599 static PyObject *
5600 posix_wait3(PyObject *self, PyObject *args)
5602 int pid, options;
5603 struct rusage ru;
5604 WAIT_TYPE status;
5605 WAIT_STATUS_INT(status) = 0;
5607 if (!PyArg_ParseTuple(args, "i:wait3", &options))
5608 return NULL;
5610 Py_BEGIN_ALLOW_THREADS
5611 pid = wait3(&status, options, &ru);
5612 Py_END_ALLOW_THREADS
5614 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
5616 #endif /* HAVE_WAIT3 */
5618 #ifdef HAVE_WAIT4
5619 PyDoc_STRVAR(posix_wait4__doc__,
5620 "wait4(pid, options) -> (pid, status, rusage)\n\n\
5621 Wait for completion of a given child process.");
5623 static PyObject *
5624 posix_wait4(PyObject *self, PyObject *args)
5626 int pid, options;
5627 struct rusage ru;
5628 WAIT_TYPE status;
5629 WAIT_STATUS_INT(status) = 0;
5631 if (!PyArg_ParseTuple(args, "ii:wait4", &pid, &options))
5632 return NULL;
5634 Py_BEGIN_ALLOW_THREADS
5635 pid = wait4(pid, &status, options, &ru);
5636 Py_END_ALLOW_THREADS
5638 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
5640 #endif /* HAVE_WAIT4 */
5642 #ifdef HAVE_WAITPID
5643 PyDoc_STRVAR(posix_waitpid__doc__,
5644 "waitpid(pid, options) -> (pid, status)\n\n\
5645 Wait for completion of a given child process.");
5647 static PyObject *
5648 posix_waitpid(PyObject *self, PyObject *args)
5650 int pid, options;
5651 WAIT_TYPE status;
5652 WAIT_STATUS_INT(status) = 0;
5654 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
5655 return NULL;
5656 Py_BEGIN_ALLOW_THREADS
5657 pid = waitpid(pid, &status, options);
5658 Py_END_ALLOW_THREADS
5659 if (pid == -1)
5660 return posix_error();
5662 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
5665 #elif defined(HAVE_CWAIT)
5667 /* MS C has a variant of waitpid() that's usable for most purposes. */
5668 PyDoc_STRVAR(posix_waitpid__doc__,
5669 "waitpid(pid, options) -> (pid, status << 8)\n\n"
5670 "Wait for completion of a given process. options is ignored on Windows.");
5672 static PyObject *
5673 posix_waitpid(PyObject *self, PyObject *args)
5675 Py_intptr_t pid;
5676 int status, options;
5678 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
5679 return NULL;
5680 Py_BEGIN_ALLOW_THREADS
5681 pid = _cwait(&status, pid, options);
5682 Py_END_ALLOW_THREADS
5683 if (pid == -1)
5684 return posix_error();
5686 /* shift the status left a byte so this is more like the POSIX waitpid */
5687 return Py_BuildValue("ii", pid, status << 8);
5689 #endif /* HAVE_WAITPID || HAVE_CWAIT */
5691 #ifdef HAVE_WAIT
5692 PyDoc_STRVAR(posix_wait__doc__,
5693 "wait() -> (pid, status)\n\n\
5694 Wait for completion of a child process.");
5696 static PyObject *
5697 posix_wait(PyObject *self, PyObject *noargs)
5699 int pid;
5700 WAIT_TYPE status;
5701 WAIT_STATUS_INT(status) = 0;
5703 Py_BEGIN_ALLOW_THREADS
5704 pid = wait(&status);
5705 Py_END_ALLOW_THREADS
5706 if (pid == -1)
5707 return posix_error();
5709 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
5711 #endif
5714 PyDoc_STRVAR(posix_lstat__doc__,
5715 "lstat(path) -> stat result\n\n\
5716 Like stat(path), but do not follow symbolic links.");
5718 static PyObject *
5719 posix_lstat(PyObject *self, PyObject *args)
5721 #ifdef HAVE_LSTAT
5722 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
5723 #else /* !HAVE_LSTAT */
5724 #ifdef MS_WINDOWS
5725 return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", win32_wstat);
5726 #else
5727 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
5728 #endif
5729 #endif /* !HAVE_LSTAT */
5733 #ifdef HAVE_READLINK
5734 PyDoc_STRVAR(posix_readlink__doc__,
5735 "readlink(path) -> path\n\n\
5736 Return a string representing the path to which the symbolic link points.");
5738 static PyObject *
5739 posix_readlink(PyObject *self, PyObject *args)
5741 PyObject* v;
5742 char buf[MAXPATHLEN];
5743 char *path;
5744 int n;
5745 #ifdef Py_USING_UNICODE
5746 int arg_is_unicode = 0;
5747 #endif
5749 if (!PyArg_ParseTuple(args, "et:readlink",
5750 Py_FileSystemDefaultEncoding, &path))
5751 return NULL;
5752 #ifdef Py_USING_UNICODE
5753 v = PySequence_GetItem(args, 0);
5754 if (v == NULL) return NULL;
5756 if (PyUnicode_Check(v)) {
5757 arg_is_unicode = 1;
5759 Py_DECREF(v);
5760 #endif
5762 Py_BEGIN_ALLOW_THREADS
5763 n = readlink(path, buf, (int) sizeof buf);
5764 Py_END_ALLOW_THREADS
5765 if (n < 0)
5766 return posix_error_with_filename(path);
5768 v = PyString_FromStringAndSize(buf, n);
5769 #ifdef Py_USING_UNICODE
5770 if (arg_is_unicode) {
5771 PyObject *w;
5773 w = PyUnicode_FromEncodedObject(v,
5774 Py_FileSystemDefaultEncoding,
5775 "strict");
5776 if (w != NULL) {
5777 Py_DECREF(v);
5778 v = w;
5780 else {
5781 /* fall back to the original byte string, as
5782 discussed in patch #683592 */
5783 PyErr_Clear();
5786 #endif
5787 return v;
5789 #endif /* HAVE_READLINK */
5792 #ifdef HAVE_SYMLINK
5793 PyDoc_STRVAR(posix_symlink__doc__,
5794 "symlink(src, dst)\n\n\
5795 Create a symbolic link pointing to src named dst.");
5797 static PyObject *
5798 posix_symlink(PyObject *self, PyObject *args)
5800 return posix_2str(args, "etet:symlink", symlink);
5802 #endif /* HAVE_SYMLINK */
5805 #ifdef HAVE_TIMES
5806 #ifndef HZ
5807 #define HZ 60 /* Universal constant :-) */
5808 #endif /* HZ */
5810 #if defined(PYCC_VACPP) && defined(PYOS_OS2)
5811 static long
5812 system_uptime(void)
5814 ULONG value = 0;
5816 Py_BEGIN_ALLOW_THREADS
5817 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
5818 Py_END_ALLOW_THREADS
5820 return value;
5823 static PyObject *
5824 posix_times(PyObject *self, PyObject *noargs)
5826 /* Currently Only Uptime is Provided -- Others Later */
5827 return Py_BuildValue("ddddd",
5828 (double)0 /* t.tms_utime / HZ */,
5829 (double)0 /* t.tms_stime / HZ */,
5830 (double)0 /* t.tms_cutime / HZ */,
5831 (double)0 /* t.tms_cstime / HZ */,
5832 (double)system_uptime() / 1000);
5834 #else /* not OS2 */
5835 static PyObject *
5836 posix_times(PyObject *self, PyObject *noargs)
5838 struct tms t;
5839 clock_t c;
5840 errno = 0;
5841 c = times(&t);
5842 if (c == (clock_t) -1)
5843 return posix_error();
5844 return Py_BuildValue("ddddd",
5845 (double)t.tms_utime / HZ,
5846 (double)t.tms_stime / HZ,
5847 (double)t.tms_cutime / HZ,
5848 (double)t.tms_cstime / HZ,
5849 (double)c / HZ);
5851 #endif /* not OS2 */
5852 #endif /* HAVE_TIMES */
5855 #ifdef MS_WINDOWS
5856 #define HAVE_TIMES /* so the method table will pick it up */
5857 static PyObject *
5858 posix_times(PyObject *self, PyObject *noargs)
5860 FILETIME create, exit, kernel, user;
5861 HANDLE hProc;
5862 hProc = GetCurrentProcess();
5863 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
5864 /* The fields of a FILETIME structure are the hi and lo part
5865 of a 64-bit value expressed in 100 nanosecond units.
5866 1e7 is one second in such units; 1e-7 the inverse.
5867 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
5869 return Py_BuildValue(
5870 "ddddd",
5871 (double)(kernel.dwHighDateTime*429.4967296 +
5872 kernel.dwLowDateTime*1e-7),
5873 (double)(user.dwHighDateTime*429.4967296 +
5874 user.dwLowDateTime*1e-7),
5875 (double)0,
5876 (double)0,
5877 (double)0);
5879 #endif /* MS_WINDOWS */
5881 #ifdef HAVE_TIMES
5882 PyDoc_STRVAR(posix_times__doc__,
5883 "times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
5884 Return a tuple of floating point numbers indicating process times.");
5885 #endif
5888 #ifdef HAVE_GETSID
5889 PyDoc_STRVAR(posix_getsid__doc__,
5890 "getsid(pid) -> sid\n\n\
5891 Call the system call getsid().");
5893 static PyObject *
5894 posix_getsid(PyObject *self, PyObject *args)
5896 int pid, sid;
5897 if (!PyArg_ParseTuple(args, "i:getsid", &pid))
5898 return NULL;
5899 sid = getsid(pid);
5900 if (sid < 0)
5901 return posix_error();
5902 return PyInt_FromLong((long)sid);
5904 #endif /* HAVE_GETSID */
5907 #ifdef HAVE_SETSID
5908 PyDoc_STRVAR(posix_setsid__doc__,
5909 "setsid()\n\n\
5910 Call the system call setsid().");
5912 static PyObject *
5913 posix_setsid(PyObject *self, PyObject *noargs)
5915 if (setsid() < 0)
5916 return posix_error();
5917 Py_INCREF(Py_None);
5918 return Py_None;
5920 #endif /* HAVE_SETSID */
5922 #ifdef HAVE_SETPGID
5923 PyDoc_STRVAR(posix_setpgid__doc__,
5924 "setpgid(pid, pgrp)\n\n\
5925 Call the system call setpgid().");
5927 static PyObject *
5928 posix_setpgid(PyObject *self, PyObject *args)
5930 int pid, pgrp;
5931 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
5932 return NULL;
5933 if (setpgid(pid, pgrp) < 0)
5934 return posix_error();
5935 Py_INCREF(Py_None);
5936 return Py_None;
5938 #endif /* HAVE_SETPGID */
5941 #ifdef HAVE_TCGETPGRP
5942 PyDoc_STRVAR(posix_tcgetpgrp__doc__,
5943 "tcgetpgrp(fd) -> pgid\n\n\
5944 Return the process group associated with the terminal given by a fd.");
5946 static PyObject *
5947 posix_tcgetpgrp(PyObject *self, PyObject *args)
5949 int fd, pgid;
5950 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
5951 return NULL;
5952 pgid = tcgetpgrp(fd);
5953 if (pgid < 0)
5954 return posix_error();
5955 return PyInt_FromLong((long)pgid);
5957 #endif /* HAVE_TCGETPGRP */
5960 #ifdef HAVE_TCSETPGRP
5961 PyDoc_STRVAR(posix_tcsetpgrp__doc__,
5962 "tcsetpgrp(fd, pgid)\n\n\
5963 Set the process group associated with the terminal given by a fd.");
5965 static PyObject *
5966 posix_tcsetpgrp(PyObject *self, PyObject *args)
5968 int fd, pgid;
5969 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
5970 return NULL;
5971 if (tcsetpgrp(fd, pgid) < 0)
5972 return posix_error();
5973 Py_INCREF(Py_None);
5974 return Py_None;
5976 #endif /* HAVE_TCSETPGRP */
5978 /* Functions acting on file descriptors */
5980 PyDoc_STRVAR(posix_open__doc__,
5981 "open(filename, flag [, mode=0777]) -> fd\n\n\
5982 Open a file (for low level IO).");
5984 static PyObject *
5985 posix_open(PyObject *self, PyObject *args)
5987 char *file = NULL;
5988 int flag;
5989 int mode = 0777;
5990 int fd;
5992 #ifdef MS_WINDOWS
5993 if (unicode_file_names()) {
5994 PyUnicodeObject *po;
5995 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
5996 Py_BEGIN_ALLOW_THREADS
5997 /* PyUnicode_AS_UNICODE OK without thread
5998 lock as it is a simple dereference. */
5999 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
6000 Py_END_ALLOW_THREADS
6001 if (fd < 0)
6002 return posix_error();
6003 return PyInt_FromLong((long)fd);
6005 /* Drop the argument parsing error as narrow strings
6006 are also valid. */
6007 PyErr_Clear();
6009 #endif
6011 if (!PyArg_ParseTuple(args, "eti|i",
6012 Py_FileSystemDefaultEncoding, &file,
6013 &flag, &mode))
6014 return NULL;
6016 Py_BEGIN_ALLOW_THREADS
6017 fd = open(file, flag, mode);
6018 Py_END_ALLOW_THREADS
6019 if (fd < 0)
6020 return posix_error_with_allocated_filename(file);
6021 PyMem_Free(file);
6022 return PyInt_FromLong((long)fd);
6026 PyDoc_STRVAR(posix_close__doc__,
6027 "close(fd)\n\n\
6028 Close a file descriptor (for low level IO).");
6030 static PyObject *
6031 posix_close(PyObject *self, PyObject *args)
6033 int fd, res;
6034 if (!PyArg_ParseTuple(args, "i:close", &fd))
6035 return NULL;
6036 Py_BEGIN_ALLOW_THREADS
6037 res = close(fd);
6038 Py_END_ALLOW_THREADS
6039 if (res < 0)
6040 return posix_error();
6041 Py_INCREF(Py_None);
6042 return Py_None;
6046 PyDoc_STRVAR(posix_dup__doc__,
6047 "dup(fd) -> fd2\n\n\
6048 Return a duplicate of a file descriptor.");
6050 static PyObject *
6051 posix_dup(PyObject *self, PyObject *args)
6053 int fd;
6054 if (!PyArg_ParseTuple(args, "i:dup", &fd))
6055 return NULL;
6056 Py_BEGIN_ALLOW_THREADS
6057 fd = dup(fd);
6058 Py_END_ALLOW_THREADS
6059 if (fd < 0)
6060 return posix_error();
6061 return PyInt_FromLong((long)fd);
6065 PyDoc_STRVAR(posix_dup2__doc__,
6066 "dup2(old_fd, new_fd)\n\n\
6067 Duplicate file descriptor.");
6069 static PyObject *
6070 posix_dup2(PyObject *self, PyObject *args)
6072 int fd, fd2, res;
6073 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
6074 return NULL;
6075 Py_BEGIN_ALLOW_THREADS
6076 res = dup2(fd, fd2);
6077 Py_END_ALLOW_THREADS
6078 if (res < 0)
6079 return posix_error();
6080 Py_INCREF(Py_None);
6081 return Py_None;
6085 PyDoc_STRVAR(posix_lseek__doc__,
6086 "lseek(fd, pos, how) -> newpos\n\n\
6087 Set the current position of a file descriptor.");
6089 static PyObject *
6090 posix_lseek(PyObject *self, PyObject *args)
6092 int fd, how;
6093 #if defined(MS_WIN64) || defined(MS_WINDOWS)
6094 PY_LONG_LONG pos, res;
6095 #else
6096 off_t pos, res;
6097 #endif
6098 PyObject *posobj;
6099 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
6100 return NULL;
6101 #ifdef SEEK_SET
6102 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
6103 switch (how) {
6104 case 0: how = SEEK_SET; break;
6105 case 1: how = SEEK_CUR; break;
6106 case 2: how = SEEK_END; break;
6108 #endif /* SEEK_END */
6110 #if !defined(HAVE_LARGEFILE_SUPPORT)
6111 pos = PyInt_AsLong(posobj);
6112 #else
6113 pos = PyLong_Check(posobj) ?
6114 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
6115 #endif
6116 if (PyErr_Occurred())
6117 return NULL;
6119 Py_BEGIN_ALLOW_THREADS
6120 #if defined(MS_WIN64) || defined(MS_WINDOWS)
6121 res = _lseeki64(fd, pos, how);
6122 #else
6123 res = lseek(fd, pos, how);
6124 #endif
6125 Py_END_ALLOW_THREADS
6126 if (res < 0)
6127 return posix_error();
6129 #if !defined(HAVE_LARGEFILE_SUPPORT)
6130 return PyInt_FromLong(res);
6131 #else
6132 return PyLong_FromLongLong(res);
6133 #endif
6137 PyDoc_STRVAR(posix_read__doc__,
6138 "read(fd, buffersize) -> string\n\n\
6139 Read a file descriptor.");
6141 static PyObject *
6142 posix_read(PyObject *self, PyObject *args)
6144 int fd, size, n;
6145 PyObject *buffer;
6146 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
6147 return NULL;
6148 if (size < 0) {
6149 errno = EINVAL;
6150 return posix_error();
6152 buffer = PyString_FromStringAndSize((char *)NULL, size);
6153 if (buffer == NULL)
6154 return NULL;
6155 Py_BEGIN_ALLOW_THREADS
6156 n = read(fd, PyString_AsString(buffer), size);
6157 Py_END_ALLOW_THREADS
6158 if (n < 0) {
6159 Py_DECREF(buffer);
6160 return posix_error();
6162 if (n != size)
6163 _PyString_Resize(&buffer, n);
6164 return buffer;
6168 PyDoc_STRVAR(posix_write__doc__,
6169 "write(fd, string) -> byteswritten\n\n\
6170 Write a string to a file descriptor.");
6172 static PyObject *
6173 posix_write(PyObject *self, PyObject *args)
6175 int fd;
6176 Py_ssize_t size;
6177 char *buffer;
6179 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
6180 return NULL;
6181 Py_BEGIN_ALLOW_THREADS
6182 size = write(fd, buffer, (size_t)size);
6183 Py_END_ALLOW_THREADS
6184 if (size < 0)
6185 return posix_error();
6186 return PyInt_FromSsize_t(size);
6190 PyDoc_STRVAR(posix_fstat__doc__,
6191 "fstat(fd) -> stat result\n\n\
6192 Like stat(), but for an open file descriptor.");
6194 static PyObject *
6195 posix_fstat(PyObject *self, PyObject *args)
6197 int fd;
6198 STRUCT_STAT st;
6199 int res;
6200 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
6201 return NULL;
6202 #ifdef __VMS
6203 /* on OpenVMS we must ensure that all bytes are written to the file */
6204 fsync(fd);
6205 #endif
6206 Py_BEGIN_ALLOW_THREADS
6207 res = FSTAT(fd, &st);
6208 Py_END_ALLOW_THREADS
6209 if (res != 0) {
6210 #ifdef MS_WINDOWS
6211 return win32_error("fstat", NULL);
6212 #else
6213 return posix_error();
6214 #endif
6217 return _pystat_fromstructstat(&st);
6221 PyDoc_STRVAR(posix_fdopen__doc__,
6222 "fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
6223 Return an open file object connected to a file descriptor.");
6225 static PyObject *
6226 posix_fdopen(PyObject *self, PyObject *args)
6228 int fd;
6229 char *mode = "r";
6230 int bufsize = -1;
6231 FILE *fp;
6232 PyObject *f;
6233 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
6234 return NULL;
6236 if (mode[0] != 'r' && mode[0] != 'w' && mode[0] != 'a') {
6237 PyErr_Format(PyExc_ValueError,
6238 "invalid file mode '%s'", mode);
6239 return NULL;
6241 Py_BEGIN_ALLOW_THREADS
6242 #if !defined(MS_WINDOWS) && defined(HAVE_FCNTL_H)
6243 if (mode[0] == 'a') {
6244 /* try to make sure the O_APPEND flag is set */
6245 int flags;
6246 flags = fcntl(fd, F_GETFL);
6247 if (flags != -1)
6248 fcntl(fd, F_SETFL, flags | O_APPEND);
6249 fp = fdopen(fd, mode);
6250 if (fp == NULL && flags != -1)
6251 /* restore old mode if fdopen failed */
6252 fcntl(fd, F_SETFL, flags);
6253 } else {
6254 fp = fdopen(fd, mode);
6256 #else
6257 fp = fdopen(fd, mode);
6258 #endif
6259 Py_END_ALLOW_THREADS
6260 if (fp == NULL)
6261 return posix_error();
6262 f = PyFile_FromFile(fp, "<fdopen>", mode, fclose);
6263 if (f != NULL)
6264 PyFile_SetBufSize(f, bufsize);
6265 return f;
6268 PyDoc_STRVAR(posix_isatty__doc__,
6269 "isatty(fd) -> bool\n\n\
6270 Return True if the file descriptor 'fd' is an open file descriptor\n\
6271 connected to the slave end of a terminal.");
6273 static PyObject *
6274 posix_isatty(PyObject *self, PyObject *args)
6276 int fd;
6277 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
6278 return NULL;
6279 return PyBool_FromLong(isatty(fd));
6282 #ifdef HAVE_PIPE
6283 PyDoc_STRVAR(posix_pipe__doc__,
6284 "pipe() -> (read_end, write_end)\n\n\
6285 Create a pipe.");
6287 static PyObject *
6288 posix_pipe(PyObject *self, PyObject *noargs)
6290 #if defined(PYOS_OS2)
6291 HFILE read, write;
6292 APIRET rc;
6294 Py_BEGIN_ALLOW_THREADS
6295 rc = DosCreatePipe( &read, &write, 4096);
6296 Py_END_ALLOW_THREADS
6297 if (rc != NO_ERROR)
6298 return os2_error(rc);
6300 return Py_BuildValue("(ii)", read, write);
6301 #else
6302 #if !defined(MS_WINDOWS)
6303 int fds[2];
6304 int res;
6305 Py_BEGIN_ALLOW_THREADS
6306 res = pipe(fds);
6307 Py_END_ALLOW_THREADS
6308 if (res != 0)
6309 return posix_error();
6310 return Py_BuildValue("(ii)", fds[0], fds[1]);
6311 #else /* MS_WINDOWS */
6312 HANDLE read, write;
6313 int read_fd, write_fd;
6314 BOOL ok;
6315 Py_BEGIN_ALLOW_THREADS
6316 ok = CreatePipe(&read, &write, NULL, 0);
6317 Py_END_ALLOW_THREADS
6318 if (!ok)
6319 return win32_error("CreatePipe", NULL);
6320 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
6321 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
6322 return Py_BuildValue("(ii)", read_fd, write_fd);
6323 #endif /* MS_WINDOWS */
6324 #endif
6326 #endif /* HAVE_PIPE */
6329 #ifdef HAVE_MKFIFO
6330 PyDoc_STRVAR(posix_mkfifo__doc__,
6331 "mkfifo(filename [, mode=0666])\n\n\
6332 Create a FIFO (a POSIX named pipe).");
6334 static PyObject *
6335 posix_mkfifo(PyObject *self, PyObject *args)
6337 char *filename;
6338 int mode = 0666;
6339 int res;
6340 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
6341 return NULL;
6342 Py_BEGIN_ALLOW_THREADS
6343 res = mkfifo(filename, mode);
6344 Py_END_ALLOW_THREADS
6345 if (res < 0)
6346 return posix_error();
6347 Py_INCREF(Py_None);
6348 return Py_None;
6350 #endif
6353 #if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
6354 PyDoc_STRVAR(posix_mknod__doc__,
6355 "mknod(filename [, mode=0600, device])\n\n\
6356 Create a filesystem node (file, device special file or named pipe)\n\
6357 named filename. mode specifies both the permissions to use and the\n\
6358 type of node to be created, being combined (bitwise OR) with one of\n\
6359 S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
6360 device defines the newly created device special file (probably using\n\
6361 os.makedev()), otherwise it is ignored.");
6364 static PyObject *
6365 posix_mknod(PyObject *self, PyObject *args)
6367 char *filename;
6368 int mode = 0600;
6369 int device = 0;
6370 int res;
6371 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
6372 return NULL;
6373 Py_BEGIN_ALLOW_THREADS
6374 res = mknod(filename, mode, device);
6375 Py_END_ALLOW_THREADS
6376 if (res < 0)
6377 return posix_error();
6378 Py_INCREF(Py_None);
6379 return Py_None;
6381 #endif
6383 #ifdef HAVE_DEVICE_MACROS
6384 PyDoc_STRVAR(posix_major__doc__,
6385 "major(device) -> major number\n\
6386 Extracts a device major number from a raw device number.");
6388 static PyObject *
6389 posix_major(PyObject *self, PyObject *args)
6391 int device;
6392 if (!PyArg_ParseTuple(args, "i:major", &device))
6393 return NULL;
6394 return PyInt_FromLong((long)major(device));
6397 PyDoc_STRVAR(posix_minor__doc__,
6398 "minor(device) -> minor number\n\
6399 Extracts a device minor number from a raw device number.");
6401 static PyObject *
6402 posix_minor(PyObject *self, PyObject *args)
6404 int device;
6405 if (!PyArg_ParseTuple(args, "i:minor", &device))
6406 return NULL;
6407 return PyInt_FromLong((long)minor(device));
6410 PyDoc_STRVAR(posix_makedev__doc__,
6411 "makedev(major, minor) -> device number\n\
6412 Composes a raw device number from the major and minor device numbers.");
6414 static PyObject *
6415 posix_makedev(PyObject *self, PyObject *args)
6417 int major, minor;
6418 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
6419 return NULL;
6420 return PyInt_FromLong((long)makedev(major, minor));
6422 #endif /* device macros */
6425 #ifdef HAVE_FTRUNCATE
6426 PyDoc_STRVAR(posix_ftruncate__doc__,
6427 "ftruncate(fd, length)\n\n\
6428 Truncate a file to a specified length.");
6430 static PyObject *
6431 posix_ftruncate(PyObject *self, PyObject *args)
6433 int fd;
6434 off_t length;
6435 int res;
6436 PyObject *lenobj;
6438 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
6439 return NULL;
6441 #if !defined(HAVE_LARGEFILE_SUPPORT)
6442 length = PyInt_AsLong(lenobj);
6443 #else
6444 length = PyLong_Check(lenobj) ?
6445 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
6446 #endif
6447 if (PyErr_Occurred())
6448 return NULL;
6450 Py_BEGIN_ALLOW_THREADS
6451 res = ftruncate(fd, length);
6452 Py_END_ALLOW_THREADS
6453 if (res < 0) {
6454 PyErr_SetFromErrno(PyExc_IOError);
6455 return NULL;
6457 Py_INCREF(Py_None);
6458 return Py_None;
6460 #endif
6462 #ifdef HAVE_PUTENV
6463 PyDoc_STRVAR(posix_putenv__doc__,
6464 "putenv(key, value)\n\n\
6465 Change or add an environment variable.");
6467 /* Save putenv() parameters as values here, so we can collect them when they
6468 * get re-set with another call for the same key. */
6469 static PyObject *posix_putenv_garbage;
6471 static PyObject *
6472 posix_putenv(PyObject *self, PyObject *args)
6474 char *s1, *s2;
6475 char *newenv;
6476 PyObject *newstr;
6477 size_t len;
6479 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
6480 return NULL;
6482 #if defined(PYOS_OS2)
6483 if (stricmp(s1, "BEGINLIBPATH") == 0) {
6484 APIRET rc;
6486 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
6487 if (rc != NO_ERROR)
6488 return os2_error(rc);
6490 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
6491 APIRET rc;
6493 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
6494 if (rc != NO_ERROR)
6495 return os2_error(rc);
6496 } else {
6497 #endif
6499 /* XXX This can leak memory -- not easy to fix :-( */
6500 len = strlen(s1) + strlen(s2) + 2;
6501 /* len includes space for a trailing \0; the size arg to
6502 PyString_FromStringAndSize does not count that */
6503 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
6504 if (newstr == NULL)
6505 return PyErr_NoMemory();
6506 newenv = PyString_AS_STRING(newstr);
6507 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
6508 if (putenv(newenv)) {
6509 Py_DECREF(newstr);
6510 posix_error();
6511 return NULL;
6513 /* Install the first arg and newstr in posix_putenv_garbage;
6514 * this will cause previous value to be collected. This has to
6515 * happen after the real putenv() call because the old value
6516 * was still accessible until then. */
6517 if (PyDict_SetItem(posix_putenv_garbage,
6518 PyTuple_GET_ITEM(args, 0), newstr)) {
6519 /* really not much we can do; just leak */
6520 PyErr_Clear();
6522 else {
6523 Py_DECREF(newstr);
6526 #if defined(PYOS_OS2)
6528 #endif
6529 Py_INCREF(Py_None);
6530 return Py_None;
6532 #endif /* putenv */
6534 #ifdef HAVE_UNSETENV
6535 PyDoc_STRVAR(posix_unsetenv__doc__,
6536 "unsetenv(key)\n\n\
6537 Delete an environment variable.");
6539 static PyObject *
6540 posix_unsetenv(PyObject *self, PyObject *args)
6542 char *s1;
6544 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
6545 return NULL;
6547 unsetenv(s1);
6549 /* Remove the key from posix_putenv_garbage;
6550 * this will cause it to be collected. This has to
6551 * happen after the real unsetenv() call because the
6552 * old value was still accessible until then.
6554 if (PyDict_DelItem(posix_putenv_garbage,
6555 PyTuple_GET_ITEM(args, 0))) {
6556 /* really not much we can do; just leak */
6557 PyErr_Clear();
6560 Py_INCREF(Py_None);
6561 return Py_None;
6563 #endif /* unsetenv */
6565 #ifdef HAVE_STRERROR
6566 PyDoc_STRVAR(posix_strerror__doc__,
6567 "strerror(code) -> string\n\n\
6568 Translate an error code to a message string.");
6570 static PyObject *
6571 posix_strerror(PyObject *self, PyObject *args)
6573 int code;
6574 char *message;
6575 if (!PyArg_ParseTuple(args, "i:strerror", &code))
6576 return NULL;
6577 message = strerror(code);
6578 if (message == NULL) {
6579 PyErr_SetString(PyExc_ValueError,
6580 "strerror() argument out of range");
6581 return NULL;
6583 return PyString_FromString(message);
6585 #endif /* strerror */
6588 #ifdef HAVE_SYS_WAIT_H
6590 #ifdef WCOREDUMP
6591 PyDoc_STRVAR(posix_WCOREDUMP__doc__,
6592 "WCOREDUMP(status) -> bool\n\n\
6593 Return True if the process returning 'status' was dumped to a core file.");
6595 static PyObject *
6596 posix_WCOREDUMP(PyObject *self, PyObject *args)
6598 WAIT_TYPE status;
6599 WAIT_STATUS_INT(status) = 0;
6601 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
6602 return NULL;
6604 return PyBool_FromLong(WCOREDUMP(status));
6606 #endif /* WCOREDUMP */
6608 #ifdef WIFCONTINUED
6609 PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
6610 "WIFCONTINUED(status) -> bool\n\n\
6611 Return True if the process returning 'status' was continued from a\n\
6612 job control stop.");
6614 static PyObject *
6615 posix_WIFCONTINUED(PyObject *self, PyObject *args)
6617 WAIT_TYPE status;
6618 WAIT_STATUS_INT(status) = 0;
6620 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
6621 return NULL;
6623 return PyBool_FromLong(WIFCONTINUED(status));
6625 #endif /* WIFCONTINUED */
6627 #ifdef WIFSTOPPED
6628 PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
6629 "WIFSTOPPED(status) -> bool\n\n\
6630 Return True if the process returning 'status' was stopped.");
6632 static PyObject *
6633 posix_WIFSTOPPED(PyObject *self, PyObject *args)
6635 WAIT_TYPE status;
6636 WAIT_STATUS_INT(status) = 0;
6638 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
6639 return NULL;
6641 return PyBool_FromLong(WIFSTOPPED(status));
6643 #endif /* WIFSTOPPED */
6645 #ifdef WIFSIGNALED
6646 PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
6647 "WIFSIGNALED(status) -> bool\n\n\
6648 Return True if the process returning 'status' was terminated by a signal.");
6650 static PyObject *
6651 posix_WIFSIGNALED(PyObject *self, PyObject *args)
6653 WAIT_TYPE status;
6654 WAIT_STATUS_INT(status) = 0;
6656 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
6657 return NULL;
6659 return PyBool_FromLong(WIFSIGNALED(status));
6661 #endif /* WIFSIGNALED */
6663 #ifdef WIFEXITED
6664 PyDoc_STRVAR(posix_WIFEXITED__doc__,
6665 "WIFEXITED(status) -> bool\n\n\
6666 Return true if the process returning 'status' exited using the exit()\n\
6667 system call.");
6669 static PyObject *
6670 posix_WIFEXITED(PyObject *self, PyObject *args)
6672 WAIT_TYPE status;
6673 WAIT_STATUS_INT(status) = 0;
6675 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
6676 return NULL;
6678 return PyBool_FromLong(WIFEXITED(status));
6680 #endif /* WIFEXITED */
6682 #ifdef WEXITSTATUS
6683 PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
6684 "WEXITSTATUS(status) -> integer\n\n\
6685 Return the process return code from 'status'.");
6687 static PyObject *
6688 posix_WEXITSTATUS(PyObject *self, PyObject *args)
6690 WAIT_TYPE status;
6691 WAIT_STATUS_INT(status) = 0;
6693 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
6694 return NULL;
6696 return Py_BuildValue("i", WEXITSTATUS(status));
6698 #endif /* WEXITSTATUS */
6700 #ifdef WTERMSIG
6701 PyDoc_STRVAR(posix_WTERMSIG__doc__,
6702 "WTERMSIG(status) -> integer\n\n\
6703 Return the signal that terminated the process that provided the 'status'\n\
6704 value.");
6706 static PyObject *
6707 posix_WTERMSIG(PyObject *self, PyObject *args)
6709 WAIT_TYPE status;
6710 WAIT_STATUS_INT(status) = 0;
6712 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
6713 return NULL;
6715 return Py_BuildValue("i", WTERMSIG(status));
6717 #endif /* WTERMSIG */
6719 #ifdef WSTOPSIG
6720 PyDoc_STRVAR(posix_WSTOPSIG__doc__,
6721 "WSTOPSIG(status) -> integer\n\n\
6722 Return the signal that stopped the process that provided\n\
6723 the 'status' value.");
6725 static PyObject *
6726 posix_WSTOPSIG(PyObject *self, PyObject *args)
6728 WAIT_TYPE status;
6729 WAIT_STATUS_INT(status) = 0;
6731 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
6732 return NULL;
6734 return Py_BuildValue("i", WSTOPSIG(status));
6736 #endif /* WSTOPSIG */
6738 #endif /* HAVE_SYS_WAIT_H */
6741 #if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
6742 #ifdef _SCO_DS
6743 /* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
6744 needed definitions in sys/statvfs.h */
6745 #define _SVID3
6746 #endif
6747 #include <sys/statvfs.h>
6749 static PyObject*
6750 _pystatvfs_fromstructstatvfs(struct statvfs st) {
6751 PyObject *v = PyStructSequence_New(&StatVFSResultType);
6752 if (v == NULL)
6753 return NULL;
6755 #if !defined(HAVE_LARGEFILE_SUPPORT)
6756 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6757 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
6758 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
6759 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
6760 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
6761 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
6762 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
6763 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
6764 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6765 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6766 #else
6767 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6768 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
6769 PyStructSequence_SET_ITEM(v, 2,
6770 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
6771 PyStructSequence_SET_ITEM(v, 3,
6772 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
6773 PyStructSequence_SET_ITEM(v, 4,
6774 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
6775 PyStructSequence_SET_ITEM(v, 5,
6776 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
6777 PyStructSequence_SET_ITEM(v, 6,
6778 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
6779 PyStructSequence_SET_ITEM(v, 7,
6780 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
6781 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6782 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6783 #endif
6785 return v;
6788 PyDoc_STRVAR(posix_fstatvfs__doc__,
6789 "fstatvfs(fd) -> statvfs result\n\n\
6790 Perform an fstatvfs system call on the given fd.");
6792 static PyObject *
6793 posix_fstatvfs(PyObject *self, PyObject *args)
6795 int fd, res;
6796 struct statvfs st;
6798 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
6799 return NULL;
6800 Py_BEGIN_ALLOW_THREADS
6801 res = fstatvfs(fd, &st);
6802 Py_END_ALLOW_THREADS
6803 if (res != 0)
6804 return posix_error();
6806 return _pystatvfs_fromstructstatvfs(st);
6808 #endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
6811 #if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
6812 #include <sys/statvfs.h>
6814 PyDoc_STRVAR(posix_statvfs__doc__,
6815 "statvfs(path) -> statvfs result\n\n\
6816 Perform a statvfs system call on the given path.");
6818 static PyObject *
6819 posix_statvfs(PyObject *self, PyObject *args)
6821 char *path;
6822 int res;
6823 struct statvfs st;
6824 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
6825 return NULL;
6826 Py_BEGIN_ALLOW_THREADS
6827 res = statvfs(path, &st);
6828 Py_END_ALLOW_THREADS
6829 if (res != 0)
6830 return posix_error_with_filename(path);
6832 return _pystatvfs_fromstructstatvfs(st);
6834 #endif /* HAVE_STATVFS */
6837 #ifdef HAVE_TEMPNAM
6838 PyDoc_STRVAR(posix_tempnam__doc__,
6839 "tempnam([dir[, prefix]]) -> string\n\n\
6840 Return a unique name for a temporary file.\n\
6841 The directory and a prefix may be specified as strings; they may be omitted\n\
6842 or None if not needed.");
6844 static PyObject *
6845 posix_tempnam(PyObject *self, PyObject *args)
6847 PyObject *result = NULL;
6848 char *dir = NULL;
6849 char *pfx = NULL;
6850 char *name;
6852 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
6853 return NULL;
6855 if (PyErr_Warn(PyExc_RuntimeWarning,
6856 "tempnam is a potential security risk to your program") < 0)
6857 return NULL;
6859 #ifdef MS_WINDOWS
6860 name = _tempnam(dir, pfx);
6861 #else
6862 name = tempnam(dir, pfx);
6863 #endif
6864 if (name == NULL)
6865 return PyErr_NoMemory();
6866 result = PyString_FromString(name);
6867 free(name);
6868 return result;
6870 #endif
6873 #ifdef HAVE_TMPFILE
6874 PyDoc_STRVAR(posix_tmpfile__doc__,
6875 "tmpfile() -> file object\n\n\
6876 Create a temporary file with no directory entries.");
6878 static PyObject *
6879 posix_tmpfile(PyObject *self, PyObject *noargs)
6881 FILE *fp;
6883 fp = tmpfile();
6884 if (fp == NULL)
6885 return posix_error();
6886 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
6888 #endif
6891 #ifdef HAVE_TMPNAM
6892 PyDoc_STRVAR(posix_tmpnam__doc__,
6893 "tmpnam() -> string\n\n\
6894 Return a unique name for a temporary file.");
6896 static PyObject *
6897 posix_tmpnam(PyObject *self, PyObject *noargs)
6899 char buffer[L_tmpnam];
6900 char *name;
6902 if (PyErr_Warn(PyExc_RuntimeWarning,
6903 "tmpnam is a potential security risk to your program") < 0)
6904 return NULL;
6906 #ifdef USE_TMPNAM_R
6907 name = tmpnam_r(buffer);
6908 #else
6909 name = tmpnam(buffer);
6910 #endif
6911 if (name == NULL) {
6912 PyObject *err = Py_BuildValue("is", 0,
6913 #ifdef USE_TMPNAM_R
6914 "unexpected NULL from tmpnam_r"
6915 #else
6916 "unexpected NULL from tmpnam"
6917 #endif
6919 PyErr_SetObject(PyExc_OSError, err);
6920 Py_XDECREF(err);
6921 return NULL;
6923 return PyString_FromString(buffer);
6925 #endif
6928 /* This is used for fpathconf(), pathconf(), confstr() and sysconf().
6929 * It maps strings representing configuration variable names to
6930 * integer values, allowing those functions to be called with the
6931 * magic names instead of polluting the module's namespace with tons of
6932 * rarely-used constants. There are three separate tables that use
6933 * these definitions.
6935 * This code is always included, even if none of the interfaces that
6936 * need it are included. The #if hackery needed to avoid it would be
6937 * sufficiently pervasive that it's not worth the loss of readability.
6939 struct constdef {
6940 char *name;
6941 long value;
6944 static int
6945 conv_confname(PyObject *arg, int *valuep, struct constdef *table,
6946 size_t tablesize)
6948 if (PyInt_Check(arg)) {
6949 *valuep = PyInt_AS_LONG(arg);
6950 return 1;
6952 if (PyString_Check(arg)) {
6953 /* look up the value in the table using a binary search */
6954 size_t lo = 0;
6955 size_t mid;
6956 size_t hi = tablesize;
6957 int cmp;
6958 char *confname = PyString_AS_STRING(arg);
6959 while (lo < hi) {
6960 mid = (lo + hi) / 2;
6961 cmp = strcmp(confname, table[mid].name);
6962 if (cmp < 0)
6963 hi = mid;
6964 else if (cmp > 0)
6965 lo = mid + 1;
6966 else {
6967 *valuep = table[mid].value;
6968 return 1;
6971 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
6973 else
6974 PyErr_SetString(PyExc_TypeError,
6975 "configuration names must be strings or integers");
6976 return 0;
6980 #if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
6981 static struct constdef posix_constants_pathconf[] = {
6982 #ifdef _PC_ABI_AIO_XFER_MAX
6983 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
6984 #endif
6985 #ifdef _PC_ABI_ASYNC_IO
6986 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
6987 #endif
6988 #ifdef _PC_ASYNC_IO
6989 {"PC_ASYNC_IO", _PC_ASYNC_IO},
6990 #endif
6991 #ifdef _PC_CHOWN_RESTRICTED
6992 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
6993 #endif
6994 #ifdef _PC_FILESIZEBITS
6995 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
6996 #endif
6997 #ifdef _PC_LAST
6998 {"PC_LAST", _PC_LAST},
6999 #endif
7000 #ifdef _PC_LINK_MAX
7001 {"PC_LINK_MAX", _PC_LINK_MAX},
7002 #endif
7003 #ifdef _PC_MAX_CANON
7004 {"PC_MAX_CANON", _PC_MAX_CANON},
7005 #endif
7006 #ifdef _PC_MAX_INPUT
7007 {"PC_MAX_INPUT", _PC_MAX_INPUT},
7008 #endif
7009 #ifdef _PC_NAME_MAX
7010 {"PC_NAME_MAX", _PC_NAME_MAX},
7011 #endif
7012 #ifdef _PC_NO_TRUNC
7013 {"PC_NO_TRUNC", _PC_NO_TRUNC},
7014 #endif
7015 #ifdef _PC_PATH_MAX
7016 {"PC_PATH_MAX", _PC_PATH_MAX},
7017 #endif
7018 #ifdef _PC_PIPE_BUF
7019 {"PC_PIPE_BUF", _PC_PIPE_BUF},
7020 #endif
7021 #ifdef _PC_PRIO_IO
7022 {"PC_PRIO_IO", _PC_PRIO_IO},
7023 #endif
7024 #ifdef _PC_SOCK_MAXBUF
7025 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
7026 #endif
7027 #ifdef _PC_SYNC_IO
7028 {"PC_SYNC_IO", _PC_SYNC_IO},
7029 #endif
7030 #ifdef _PC_VDISABLE
7031 {"PC_VDISABLE", _PC_VDISABLE},
7032 #endif
7035 static int
7036 conv_path_confname(PyObject *arg, int *valuep)
7038 return conv_confname(arg, valuep, posix_constants_pathconf,
7039 sizeof(posix_constants_pathconf)
7040 / sizeof(struct constdef));
7042 #endif
7044 #ifdef HAVE_FPATHCONF
7045 PyDoc_STRVAR(posix_fpathconf__doc__,
7046 "fpathconf(fd, name) -> integer\n\n\
7047 Return the configuration limit name for the file descriptor fd.\n\
7048 If there is no limit, return -1.");
7050 static PyObject *
7051 posix_fpathconf(PyObject *self, PyObject *args)
7053 PyObject *result = NULL;
7054 int name, fd;
7056 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
7057 conv_path_confname, &name)) {
7058 long limit;
7060 errno = 0;
7061 limit = fpathconf(fd, name);
7062 if (limit == -1 && errno != 0)
7063 posix_error();
7064 else
7065 result = PyInt_FromLong(limit);
7067 return result;
7069 #endif
7072 #ifdef HAVE_PATHCONF
7073 PyDoc_STRVAR(posix_pathconf__doc__,
7074 "pathconf(path, name) -> integer\n\n\
7075 Return the configuration limit name for the file or directory path.\n\
7076 If there is no limit, return -1.");
7078 static PyObject *
7079 posix_pathconf(PyObject *self, PyObject *args)
7081 PyObject *result = NULL;
7082 int name;
7083 char *path;
7085 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
7086 conv_path_confname, &name)) {
7087 long limit;
7089 errno = 0;
7090 limit = pathconf(path, name);
7091 if (limit == -1 && errno != 0) {
7092 if (errno == EINVAL)
7093 /* could be a path or name problem */
7094 posix_error();
7095 else
7096 posix_error_with_filename(path);
7098 else
7099 result = PyInt_FromLong(limit);
7101 return result;
7103 #endif
7105 #ifdef HAVE_CONFSTR
7106 static struct constdef posix_constants_confstr[] = {
7107 #ifdef _CS_ARCHITECTURE
7108 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
7109 #endif
7110 #ifdef _CS_HOSTNAME
7111 {"CS_HOSTNAME", _CS_HOSTNAME},
7112 #endif
7113 #ifdef _CS_HW_PROVIDER
7114 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
7115 #endif
7116 #ifdef _CS_HW_SERIAL
7117 {"CS_HW_SERIAL", _CS_HW_SERIAL},
7118 #endif
7119 #ifdef _CS_INITTAB_NAME
7120 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
7121 #endif
7122 #ifdef _CS_LFS64_CFLAGS
7123 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
7124 #endif
7125 #ifdef _CS_LFS64_LDFLAGS
7126 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
7127 #endif
7128 #ifdef _CS_LFS64_LIBS
7129 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
7130 #endif
7131 #ifdef _CS_LFS64_LINTFLAGS
7132 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
7133 #endif
7134 #ifdef _CS_LFS_CFLAGS
7135 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
7136 #endif
7137 #ifdef _CS_LFS_LDFLAGS
7138 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
7139 #endif
7140 #ifdef _CS_LFS_LIBS
7141 {"CS_LFS_LIBS", _CS_LFS_LIBS},
7142 #endif
7143 #ifdef _CS_LFS_LINTFLAGS
7144 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
7145 #endif
7146 #ifdef _CS_MACHINE
7147 {"CS_MACHINE", _CS_MACHINE},
7148 #endif
7149 #ifdef _CS_PATH
7150 {"CS_PATH", _CS_PATH},
7151 #endif
7152 #ifdef _CS_RELEASE
7153 {"CS_RELEASE", _CS_RELEASE},
7154 #endif
7155 #ifdef _CS_SRPC_DOMAIN
7156 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
7157 #endif
7158 #ifdef _CS_SYSNAME
7159 {"CS_SYSNAME", _CS_SYSNAME},
7160 #endif
7161 #ifdef _CS_VERSION
7162 {"CS_VERSION", _CS_VERSION},
7163 #endif
7164 #ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
7165 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
7166 #endif
7167 #ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
7168 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
7169 #endif
7170 #ifdef _CS_XBS5_ILP32_OFF32_LIBS
7171 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
7172 #endif
7173 #ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
7174 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
7175 #endif
7176 #ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
7177 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
7178 #endif
7179 #ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
7180 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
7181 #endif
7182 #ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
7183 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
7184 #endif
7185 #ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
7186 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
7187 #endif
7188 #ifdef _CS_XBS5_LP64_OFF64_CFLAGS
7189 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
7190 #endif
7191 #ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
7192 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
7193 #endif
7194 #ifdef _CS_XBS5_LP64_OFF64_LIBS
7195 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
7196 #endif
7197 #ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
7198 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
7199 #endif
7200 #ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
7201 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
7202 #endif
7203 #ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
7204 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
7205 #endif
7206 #ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
7207 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
7208 #endif
7209 #ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
7210 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
7211 #endif
7212 #ifdef _MIPS_CS_AVAIL_PROCESSORS
7213 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
7214 #endif
7215 #ifdef _MIPS_CS_BASE
7216 {"MIPS_CS_BASE", _MIPS_CS_BASE},
7217 #endif
7218 #ifdef _MIPS_CS_HOSTID
7219 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
7220 #endif
7221 #ifdef _MIPS_CS_HW_NAME
7222 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
7223 #endif
7224 #ifdef _MIPS_CS_NUM_PROCESSORS
7225 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
7226 #endif
7227 #ifdef _MIPS_CS_OSREL_MAJ
7228 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
7229 #endif
7230 #ifdef _MIPS_CS_OSREL_MIN
7231 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
7232 #endif
7233 #ifdef _MIPS_CS_OSREL_PATCH
7234 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
7235 #endif
7236 #ifdef _MIPS_CS_OS_NAME
7237 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
7238 #endif
7239 #ifdef _MIPS_CS_OS_PROVIDER
7240 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
7241 #endif
7242 #ifdef _MIPS_CS_PROCESSORS
7243 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
7244 #endif
7245 #ifdef _MIPS_CS_SERIAL
7246 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
7247 #endif
7248 #ifdef _MIPS_CS_VENDOR
7249 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
7250 #endif
7253 static int
7254 conv_confstr_confname(PyObject *arg, int *valuep)
7256 return conv_confname(arg, valuep, posix_constants_confstr,
7257 sizeof(posix_constants_confstr)
7258 / sizeof(struct constdef));
7261 PyDoc_STRVAR(posix_confstr__doc__,
7262 "confstr(name) -> string\n\n\
7263 Return a string-valued system configuration variable.");
7265 static PyObject *
7266 posix_confstr(PyObject *self, PyObject *args)
7268 PyObject *result = NULL;
7269 int name;
7270 char buffer[256];
7272 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
7273 int len;
7275 errno = 0;
7276 len = confstr(name, buffer, sizeof(buffer));
7277 if (len == 0) {
7278 if (errno) {
7279 posix_error();
7281 else {
7282 result = Py_None;
7283 Py_INCREF(Py_None);
7286 else {
7287 if ((unsigned int)len >= sizeof(buffer)) {
7288 result = PyString_FromStringAndSize(NULL, len-1);
7289 if (result != NULL)
7290 confstr(name, PyString_AS_STRING(result), len);
7292 else
7293 result = PyString_FromStringAndSize(buffer, len-1);
7296 return result;
7298 #endif
7301 #ifdef HAVE_SYSCONF
7302 static struct constdef posix_constants_sysconf[] = {
7303 #ifdef _SC_2_CHAR_TERM
7304 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
7305 #endif
7306 #ifdef _SC_2_C_BIND
7307 {"SC_2_C_BIND", _SC_2_C_BIND},
7308 #endif
7309 #ifdef _SC_2_C_DEV
7310 {"SC_2_C_DEV", _SC_2_C_DEV},
7311 #endif
7312 #ifdef _SC_2_C_VERSION
7313 {"SC_2_C_VERSION", _SC_2_C_VERSION},
7314 #endif
7315 #ifdef _SC_2_FORT_DEV
7316 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
7317 #endif
7318 #ifdef _SC_2_FORT_RUN
7319 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
7320 #endif
7321 #ifdef _SC_2_LOCALEDEF
7322 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
7323 #endif
7324 #ifdef _SC_2_SW_DEV
7325 {"SC_2_SW_DEV", _SC_2_SW_DEV},
7326 #endif
7327 #ifdef _SC_2_UPE
7328 {"SC_2_UPE", _SC_2_UPE},
7329 #endif
7330 #ifdef _SC_2_VERSION
7331 {"SC_2_VERSION", _SC_2_VERSION},
7332 #endif
7333 #ifdef _SC_ABI_ASYNCHRONOUS_IO
7334 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
7335 #endif
7336 #ifdef _SC_ACL
7337 {"SC_ACL", _SC_ACL},
7338 #endif
7339 #ifdef _SC_AIO_LISTIO_MAX
7340 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
7341 #endif
7342 #ifdef _SC_AIO_MAX
7343 {"SC_AIO_MAX", _SC_AIO_MAX},
7344 #endif
7345 #ifdef _SC_AIO_PRIO_DELTA_MAX
7346 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
7347 #endif
7348 #ifdef _SC_ARG_MAX
7349 {"SC_ARG_MAX", _SC_ARG_MAX},
7350 #endif
7351 #ifdef _SC_ASYNCHRONOUS_IO
7352 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
7353 #endif
7354 #ifdef _SC_ATEXIT_MAX
7355 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
7356 #endif
7357 #ifdef _SC_AUDIT
7358 {"SC_AUDIT", _SC_AUDIT},
7359 #endif
7360 #ifdef _SC_AVPHYS_PAGES
7361 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
7362 #endif
7363 #ifdef _SC_BC_BASE_MAX
7364 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
7365 #endif
7366 #ifdef _SC_BC_DIM_MAX
7367 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
7368 #endif
7369 #ifdef _SC_BC_SCALE_MAX
7370 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
7371 #endif
7372 #ifdef _SC_BC_STRING_MAX
7373 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
7374 #endif
7375 #ifdef _SC_CAP
7376 {"SC_CAP", _SC_CAP},
7377 #endif
7378 #ifdef _SC_CHARCLASS_NAME_MAX
7379 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
7380 #endif
7381 #ifdef _SC_CHAR_BIT
7382 {"SC_CHAR_BIT", _SC_CHAR_BIT},
7383 #endif
7384 #ifdef _SC_CHAR_MAX
7385 {"SC_CHAR_MAX", _SC_CHAR_MAX},
7386 #endif
7387 #ifdef _SC_CHAR_MIN
7388 {"SC_CHAR_MIN", _SC_CHAR_MIN},
7389 #endif
7390 #ifdef _SC_CHILD_MAX
7391 {"SC_CHILD_MAX", _SC_CHILD_MAX},
7392 #endif
7393 #ifdef _SC_CLK_TCK
7394 {"SC_CLK_TCK", _SC_CLK_TCK},
7395 #endif
7396 #ifdef _SC_COHER_BLKSZ
7397 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
7398 #endif
7399 #ifdef _SC_COLL_WEIGHTS_MAX
7400 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
7401 #endif
7402 #ifdef _SC_DCACHE_ASSOC
7403 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
7404 #endif
7405 #ifdef _SC_DCACHE_BLKSZ
7406 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
7407 #endif
7408 #ifdef _SC_DCACHE_LINESZ
7409 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
7410 #endif
7411 #ifdef _SC_DCACHE_SZ
7412 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
7413 #endif
7414 #ifdef _SC_DCACHE_TBLKSZ
7415 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
7416 #endif
7417 #ifdef _SC_DELAYTIMER_MAX
7418 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
7419 #endif
7420 #ifdef _SC_EQUIV_CLASS_MAX
7421 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
7422 #endif
7423 #ifdef _SC_EXPR_NEST_MAX
7424 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
7425 #endif
7426 #ifdef _SC_FSYNC
7427 {"SC_FSYNC", _SC_FSYNC},
7428 #endif
7429 #ifdef _SC_GETGR_R_SIZE_MAX
7430 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
7431 #endif
7432 #ifdef _SC_GETPW_R_SIZE_MAX
7433 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
7434 #endif
7435 #ifdef _SC_ICACHE_ASSOC
7436 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
7437 #endif
7438 #ifdef _SC_ICACHE_BLKSZ
7439 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
7440 #endif
7441 #ifdef _SC_ICACHE_LINESZ
7442 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
7443 #endif
7444 #ifdef _SC_ICACHE_SZ
7445 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
7446 #endif
7447 #ifdef _SC_INF
7448 {"SC_INF", _SC_INF},
7449 #endif
7450 #ifdef _SC_INT_MAX
7451 {"SC_INT_MAX", _SC_INT_MAX},
7452 #endif
7453 #ifdef _SC_INT_MIN
7454 {"SC_INT_MIN", _SC_INT_MIN},
7455 #endif
7456 #ifdef _SC_IOV_MAX
7457 {"SC_IOV_MAX", _SC_IOV_MAX},
7458 #endif
7459 #ifdef _SC_IP_SECOPTS
7460 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
7461 #endif
7462 #ifdef _SC_JOB_CONTROL
7463 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
7464 #endif
7465 #ifdef _SC_KERN_POINTERS
7466 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
7467 #endif
7468 #ifdef _SC_KERN_SIM
7469 {"SC_KERN_SIM", _SC_KERN_SIM},
7470 #endif
7471 #ifdef _SC_LINE_MAX
7472 {"SC_LINE_MAX", _SC_LINE_MAX},
7473 #endif
7474 #ifdef _SC_LOGIN_NAME_MAX
7475 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
7476 #endif
7477 #ifdef _SC_LOGNAME_MAX
7478 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
7479 #endif
7480 #ifdef _SC_LONG_BIT
7481 {"SC_LONG_BIT", _SC_LONG_BIT},
7482 #endif
7483 #ifdef _SC_MAC
7484 {"SC_MAC", _SC_MAC},
7485 #endif
7486 #ifdef _SC_MAPPED_FILES
7487 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
7488 #endif
7489 #ifdef _SC_MAXPID
7490 {"SC_MAXPID", _SC_MAXPID},
7491 #endif
7492 #ifdef _SC_MB_LEN_MAX
7493 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
7494 #endif
7495 #ifdef _SC_MEMLOCK
7496 {"SC_MEMLOCK", _SC_MEMLOCK},
7497 #endif
7498 #ifdef _SC_MEMLOCK_RANGE
7499 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
7500 #endif
7501 #ifdef _SC_MEMORY_PROTECTION
7502 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
7503 #endif
7504 #ifdef _SC_MESSAGE_PASSING
7505 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
7506 #endif
7507 #ifdef _SC_MMAP_FIXED_ALIGNMENT
7508 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
7509 #endif
7510 #ifdef _SC_MQ_OPEN_MAX
7511 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
7512 #endif
7513 #ifdef _SC_MQ_PRIO_MAX
7514 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
7515 #endif
7516 #ifdef _SC_NACLS_MAX
7517 {"SC_NACLS_MAX", _SC_NACLS_MAX},
7518 #endif
7519 #ifdef _SC_NGROUPS_MAX
7520 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
7521 #endif
7522 #ifdef _SC_NL_ARGMAX
7523 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
7524 #endif
7525 #ifdef _SC_NL_LANGMAX
7526 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
7527 #endif
7528 #ifdef _SC_NL_MSGMAX
7529 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
7530 #endif
7531 #ifdef _SC_NL_NMAX
7532 {"SC_NL_NMAX", _SC_NL_NMAX},
7533 #endif
7534 #ifdef _SC_NL_SETMAX
7535 {"SC_NL_SETMAX", _SC_NL_SETMAX},
7536 #endif
7537 #ifdef _SC_NL_TEXTMAX
7538 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
7539 #endif
7540 #ifdef _SC_NPROCESSORS_CONF
7541 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
7542 #endif
7543 #ifdef _SC_NPROCESSORS_ONLN
7544 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
7545 #endif
7546 #ifdef _SC_NPROC_CONF
7547 {"SC_NPROC_CONF", _SC_NPROC_CONF},
7548 #endif
7549 #ifdef _SC_NPROC_ONLN
7550 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
7551 #endif
7552 #ifdef _SC_NZERO
7553 {"SC_NZERO", _SC_NZERO},
7554 #endif
7555 #ifdef _SC_OPEN_MAX
7556 {"SC_OPEN_MAX", _SC_OPEN_MAX},
7557 #endif
7558 #ifdef _SC_PAGESIZE
7559 {"SC_PAGESIZE", _SC_PAGESIZE},
7560 #endif
7561 #ifdef _SC_PAGE_SIZE
7562 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
7563 #endif
7564 #ifdef _SC_PASS_MAX
7565 {"SC_PASS_MAX", _SC_PASS_MAX},
7566 #endif
7567 #ifdef _SC_PHYS_PAGES
7568 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
7569 #endif
7570 #ifdef _SC_PII
7571 {"SC_PII", _SC_PII},
7572 #endif
7573 #ifdef _SC_PII_INTERNET
7574 {"SC_PII_INTERNET", _SC_PII_INTERNET},
7575 #endif
7576 #ifdef _SC_PII_INTERNET_DGRAM
7577 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
7578 #endif
7579 #ifdef _SC_PII_INTERNET_STREAM
7580 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
7581 #endif
7582 #ifdef _SC_PII_OSI
7583 {"SC_PII_OSI", _SC_PII_OSI},
7584 #endif
7585 #ifdef _SC_PII_OSI_CLTS
7586 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
7587 #endif
7588 #ifdef _SC_PII_OSI_COTS
7589 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
7590 #endif
7591 #ifdef _SC_PII_OSI_M
7592 {"SC_PII_OSI_M", _SC_PII_OSI_M},
7593 #endif
7594 #ifdef _SC_PII_SOCKET
7595 {"SC_PII_SOCKET", _SC_PII_SOCKET},
7596 #endif
7597 #ifdef _SC_PII_XTI
7598 {"SC_PII_XTI", _SC_PII_XTI},
7599 #endif
7600 #ifdef _SC_POLL
7601 {"SC_POLL", _SC_POLL},
7602 #endif
7603 #ifdef _SC_PRIORITIZED_IO
7604 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
7605 #endif
7606 #ifdef _SC_PRIORITY_SCHEDULING
7607 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
7608 #endif
7609 #ifdef _SC_REALTIME_SIGNALS
7610 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
7611 #endif
7612 #ifdef _SC_RE_DUP_MAX
7613 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
7614 #endif
7615 #ifdef _SC_RTSIG_MAX
7616 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
7617 #endif
7618 #ifdef _SC_SAVED_IDS
7619 {"SC_SAVED_IDS", _SC_SAVED_IDS},
7620 #endif
7621 #ifdef _SC_SCHAR_MAX
7622 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
7623 #endif
7624 #ifdef _SC_SCHAR_MIN
7625 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
7626 #endif
7627 #ifdef _SC_SELECT
7628 {"SC_SELECT", _SC_SELECT},
7629 #endif
7630 #ifdef _SC_SEMAPHORES
7631 {"SC_SEMAPHORES", _SC_SEMAPHORES},
7632 #endif
7633 #ifdef _SC_SEM_NSEMS_MAX
7634 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
7635 #endif
7636 #ifdef _SC_SEM_VALUE_MAX
7637 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
7638 #endif
7639 #ifdef _SC_SHARED_MEMORY_OBJECTS
7640 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
7641 #endif
7642 #ifdef _SC_SHRT_MAX
7643 {"SC_SHRT_MAX", _SC_SHRT_MAX},
7644 #endif
7645 #ifdef _SC_SHRT_MIN
7646 {"SC_SHRT_MIN", _SC_SHRT_MIN},
7647 #endif
7648 #ifdef _SC_SIGQUEUE_MAX
7649 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
7650 #endif
7651 #ifdef _SC_SIGRT_MAX
7652 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
7653 #endif
7654 #ifdef _SC_SIGRT_MIN
7655 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
7656 #endif
7657 #ifdef _SC_SOFTPOWER
7658 {"SC_SOFTPOWER", _SC_SOFTPOWER},
7659 #endif
7660 #ifdef _SC_SPLIT_CACHE
7661 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
7662 #endif
7663 #ifdef _SC_SSIZE_MAX
7664 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
7665 #endif
7666 #ifdef _SC_STACK_PROT
7667 {"SC_STACK_PROT", _SC_STACK_PROT},
7668 #endif
7669 #ifdef _SC_STREAM_MAX
7670 {"SC_STREAM_MAX", _SC_STREAM_MAX},
7671 #endif
7672 #ifdef _SC_SYNCHRONIZED_IO
7673 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
7674 #endif
7675 #ifdef _SC_THREADS
7676 {"SC_THREADS", _SC_THREADS},
7677 #endif
7678 #ifdef _SC_THREAD_ATTR_STACKADDR
7679 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
7680 #endif
7681 #ifdef _SC_THREAD_ATTR_STACKSIZE
7682 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
7683 #endif
7684 #ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
7685 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
7686 #endif
7687 #ifdef _SC_THREAD_KEYS_MAX
7688 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
7689 #endif
7690 #ifdef _SC_THREAD_PRIORITY_SCHEDULING
7691 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
7692 #endif
7693 #ifdef _SC_THREAD_PRIO_INHERIT
7694 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
7695 #endif
7696 #ifdef _SC_THREAD_PRIO_PROTECT
7697 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
7698 #endif
7699 #ifdef _SC_THREAD_PROCESS_SHARED
7700 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
7701 #endif
7702 #ifdef _SC_THREAD_SAFE_FUNCTIONS
7703 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
7704 #endif
7705 #ifdef _SC_THREAD_STACK_MIN
7706 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
7707 #endif
7708 #ifdef _SC_THREAD_THREADS_MAX
7709 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
7710 #endif
7711 #ifdef _SC_TIMERS
7712 {"SC_TIMERS", _SC_TIMERS},
7713 #endif
7714 #ifdef _SC_TIMER_MAX
7715 {"SC_TIMER_MAX", _SC_TIMER_MAX},
7716 #endif
7717 #ifdef _SC_TTY_NAME_MAX
7718 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
7719 #endif
7720 #ifdef _SC_TZNAME_MAX
7721 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
7722 #endif
7723 #ifdef _SC_T_IOV_MAX
7724 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
7725 #endif
7726 #ifdef _SC_UCHAR_MAX
7727 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
7728 #endif
7729 #ifdef _SC_UINT_MAX
7730 {"SC_UINT_MAX", _SC_UINT_MAX},
7731 #endif
7732 #ifdef _SC_UIO_MAXIOV
7733 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
7734 #endif
7735 #ifdef _SC_ULONG_MAX
7736 {"SC_ULONG_MAX", _SC_ULONG_MAX},
7737 #endif
7738 #ifdef _SC_USHRT_MAX
7739 {"SC_USHRT_MAX", _SC_USHRT_MAX},
7740 #endif
7741 #ifdef _SC_VERSION
7742 {"SC_VERSION", _SC_VERSION},
7743 #endif
7744 #ifdef _SC_WORD_BIT
7745 {"SC_WORD_BIT", _SC_WORD_BIT},
7746 #endif
7747 #ifdef _SC_XBS5_ILP32_OFF32
7748 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
7749 #endif
7750 #ifdef _SC_XBS5_ILP32_OFFBIG
7751 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
7752 #endif
7753 #ifdef _SC_XBS5_LP64_OFF64
7754 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
7755 #endif
7756 #ifdef _SC_XBS5_LPBIG_OFFBIG
7757 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
7758 #endif
7759 #ifdef _SC_XOPEN_CRYPT
7760 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
7761 #endif
7762 #ifdef _SC_XOPEN_ENH_I18N
7763 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
7764 #endif
7765 #ifdef _SC_XOPEN_LEGACY
7766 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
7767 #endif
7768 #ifdef _SC_XOPEN_REALTIME
7769 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
7770 #endif
7771 #ifdef _SC_XOPEN_REALTIME_THREADS
7772 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
7773 #endif
7774 #ifdef _SC_XOPEN_SHM
7775 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
7776 #endif
7777 #ifdef _SC_XOPEN_UNIX
7778 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
7779 #endif
7780 #ifdef _SC_XOPEN_VERSION
7781 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
7782 #endif
7783 #ifdef _SC_XOPEN_XCU_VERSION
7784 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
7785 #endif
7786 #ifdef _SC_XOPEN_XPG2
7787 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
7788 #endif
7789 #ifdef _SC_XOPEN_XPG3
7790 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
7791 #endif
7792 #ifdef _SC_XOPEN_XPG4
7793 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
7794 #endif
7797 static int
7798 conv_sysconf_confname(PyObject *arg, int *valuep)
7800 return conv_confname(arg, valuep, posix_constants_sysconf,
7801 sizeof(posix_constants_sysconf)
7802 / sizeof(struct constdef));
7805 PyDoc_STRVAR(posix_sysconf__doc__,
7806 "sysconf(name) -> integer\n\n\
7807 Return an integer-valued system configuration variable.");
7809 static PyObject *
7810 posix_sysconf(PyObject *self, PyObject *args)
7812 PyObject *result = NULL;
7813 int name;
7815 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
7816 int value;
7818 errno = 0;
7819 value = sysconf(name);
7820 if (value == -1 && errno != 0)
7821 posix_error();
7822 else
7823 result = PyInt_FromLong(value);
7825 return result;
7827 #endif
7830 /* This code is used to ensure that the tables of configuration value names
7831 * are in sorted order as required by conv_confname(), and also to build the
7832 * the exported dictionaries that are used to publish information about the
7833 * names available on the host platform.
7835 * Sorting the table at runtime ensures that the table is properly ordered
7836 * when used, even for platforms we're not able to test on. It also makes
7837 * it easier to add additional entries to the tables.
7840 static int
7841 cmp_constdefs(const void *v1, const void *v2)
7843 const struct constdef *c1 =
7844 (const struct constdef *) v1;
7845 const struct constdef *c2 =
7846 (const struct constdef *) v2;
7848 return strcmp(c1->name, c2->name);
7851 static int
7852 setup_confname_table(struct constdef *table, size_t tablesize,
7853 char *tablename, PyObject *module)
7855 PyObject *d = NULL;
7856 size_t i;
7858 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
7859 d = PyDict_New();
7860 if (d == NULL)
7861 return -1;
7863 for (i=0; i < tablesize; ++i) {
7864 PyObject *o = PyInt_FromLong(table[i].value);
7865 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
7866 Py_XDECREF(o);
7867 Py_DECREF(d);
7868 return -1;
7870 Py_DECREF(o);
7872 return PyModule_AddObject(module, tablename, d);
7875 /* Return -1 on failure, 0 on success. */
7876 static int
7877 setup_confname_tables(PyObject *module)
7879 #if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
7880 if (setup_confname_table(posix_constants_pathconf,
7881 sizeof(posix_constants_pathconf)
7882 / sizeof(struct constdef),
7883 "pathconf_names", module))
7884 return -1;
7885 #endif
7886 #ifdef HAVE_CONFSTR
7887 if (setup_confname_table(posix_constants_confstr,
7888 sizeof(posix_constants_confstr)
7889 / sizeof(struct constdef),
7890 "confstr_names", module))
7891 return -1;
7892 #endif
7893 #ifdef HAVE_SYSCONF
7894 if (setup_confname_table(posix_constants_sysconf,
7895 sizeof(posix_constants_sysconf)
7896 / sizeof(struct constdef),
7897 "sysconf_names", module))
7898 return -1;
7899 #endif
7900 return 0;
7904 PyDoc_STRVAR(posix_abort__doc__,
7905 "abort() -> does not return!\n\n\
7906 Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
7907 in the hardest way possible on the hosting operating system.");
7909 static PyObject *
7910 posix_abort(PyObject *self, PyObject *noargs)
7912 abort();
7913 /*NOTREACHED*/
7914 Py_FatalError("abort() called from Python code didn't abort!");
7915 return NULL;
7918 #ifdef MS_WINDOWS
7919 PyDoc_STRVAR(win32_startfile__doc__,
7920 "startfile(filepath [, operation]) - Start a file with its associated\n\
7921 application.\n\
7923 When \"operation\" is not specified or \"open\", this acts like\n\
7924 double-clicking the file in Explorer, or giving the file name as an\n\
7925 argument to the DOS \"start\" command: the file is opened with whatever\n\
7926 application (if any) its extension is associated.\n\
7927 When another \"operation\" is given, it specifies what should be done with\n\
7928 the file. A typical operation is \"print\".\n\
7930 startfile returns as soon as the associated application is launched.\n\
7931 There is no option to wait for the application to close, and no way\n\
7932 to retrieve the application's exit status.\n\
7934 The filepath is relative to the current directory. If you want to use\n\
7935 an absolute path, make sure the first character is not a slash (\"/\");\n\
7936 the underlying Win32 ShellExecute function doesn't work if it is.");
7938 static PyObject *
7939 win32_startfile(PyObject *self, PyObject *args)
7941 char *filepath;
7942 char *operation = NULL;
7943 HINSTANCE rc;
7944 #ifdef Py_WIN_WIDE_FILENAMES
7945 if (unicode_file_names()) {
7946 PyObject *unipath, *woperation = NULL;
7947 if (!PyArg_ParseTuple(args, "U|s:startfile",
7948 &unipath, &operation)) {
7949 PyErr_Clear();
7950 goto normal;
7954 if (operation) {
7955 woperation = PyUnicode_DecodeASCII(operation,
7956 strlen(operation), NULL);
7957 if (!woperation) {
7958 PyErr_Clear();
7959 operation = NULL;
7960 goto normal;
7964 Py_BEGIN_ALLOW_THREADS
7965 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
7966 PyUnicode_AS_UNICODE(unipath),
7967 NULL, NULL, SW_SHOWNORMAL);
7968 Py_END_ALLOW_THREADS
7970 Py_XDECREF(woperation);
7971 if (rc <= (HINSTANCE)32) {
7972 PyObject *errval = win32_error_unicode("startfile",
7973 PyUnicode_AS_UNICODE(unipath));
7974 return errval;
7976 Py_INCREF(Py_None);
7977 return Py_None;
7979 #endif
7981 normal:
7982 if (!PyArg_ParseTuple(args, "et|s:startfile",
7983 Py_FileSystemDefaultEncoding, &filepath,
7984 &operation))
7985 return NULL;
7986 Py_BEGIN_ALLOW_THREADS
7987 rc = ShellExecute((HWND)0, operation, filepath,
7988 NULL, NULL, SW_SHOWNORMAL);
7989 Py_END_ALLOW_THREADS
7990 if (rc <= (HINSTANCE)32) {
7991 PyObject *errval = win32_error("startfile", filepath);
7992 PyMem_Free(filepath);
7993 return errval;
7995 PyMem_Free(filepath);
7996 Py_INCREF(Py_None);
7997 return Py_None;
7999 #endif
8001 #ifdef HAVE_GETLOADAVG
8002 PyDoc_STRVAR(posix_getloadavg__doc__,
8003 "getloadavg() -> (float, float, float)\n\n\
8004 Return the number of processes in the system run queue averaged over\n\
8005 the last 1, 5, and 15 minutes or raises OSError if the load average\n\
8006 was unobtainable");
8008 static PyObject *
8009 posix_getloadavg(PyObject *self, PyObject *noargs)
8011 double loadavg[3];
8012 if (getloadavg(loadavg, 3)!=3) {
8013 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
8014 return NULL;
8015 } else
8016 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
8018 #endif
8020 #ifdef MS_WINDOWS
8022 PyDoc_STRVAR(win32_urandom__doc__,
8023 "urandom(n) -> str\n\n\
8024 Return a string of n random bytes suitable for cryptographic use.");
8026 typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
8027 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
8028 DWORD dwFlags );
8029 typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
8030 BYTE *pbBuffer );
8032 static CRYPTGENRANDOM pCryptGenRandom = NULL;
8033 static HCRYPTPROV hCryptProv = 0;
8035 static PyObject*
8036 win32_urandom(PyObject *self, PyObject *args)
8038 int howMany;
8039 PyObject* result;
8041 /* Read arguments */
8042 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
8043 return NULL;
8044 if (howMany < 0)
8045 return PyErr_Format(PyExc_ValueError,
8046 "negative argument not allowed");
8048 if (hCryptProv == 0) {
8049 HINSTANCE hAdvAPI32 = NULL;
8050 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
8052 /* Obtain handle to the DLL containing CryptoAPI
8053 This should not fail */
8054 hAdvAPI32 = GetModuleHandle("advapi32.dll");
8055 if(hAdvAPI32 == NULL)
8056 return win32_error("GetModuleHandle", NULL);
8058 /* Obtain pointers to the CryptoAPI functions
8059 This will fail on some early versions of Win95 */
8060 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
8061 hAdvAPI32,
8062 "CryptAcquireContextA");
8063 if (pCryptAcquireContext == NULL)
8064 return PyErr_Format(PyExc_NotImplementedError,
8065 "CryptAcquireContextA not found");
8067 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
8068 hAdvAPI32, "CryptGenRandom");
8069 if (pCryptGenRandom == NULL)
8070 return PyErr_Format(PyExc_NotImplementedError,
8071 "CryptGenRandom not found");
8073 /* Acquire context */
8074 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
8075 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
8076 return win32_error("CryptAcquireContext", NULL);
8079 /* Allocate bytes */
8080 result = PyString_FromStringAndSize(NULL, howMany);
8081 if (result != NULL) {
8082 /* Get random data */
8083 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
8084 PyString_AS_STRING(result))) {
8085 Py_DECREF(result);
8086 return win32_error("CryptGenRandom", NULL);
8089 return result;
8091 #endif
8093 #ifdef __VMS
8094 /* Use openssl random routine */
8095 #include <openssl/rand.h>
8096 PyDoc_STRVAR(vms_urandom__doc__,
8097 "urandom(n) -> str\n\n\
8098 Return a string of n random bytes suitable for cryptographic use.");
8100 static PyObject*
8101 vms_urandom(PyObject *self, PyObject *args)
8103 int howMany;
8104 PyObject* result;
8106 /* Read arguments */
8107 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
8108 return NULL;
8109 if (howMany < 0)
8110 return PyErr_Format(PyExc_ValueError,
8111 "negative argument not allowed");
8113 /* Allocate bytes */
8114 result = PyString_FromStringAndSize(NULL, howMany);
8115 if (result != NULL) {
8116 /* Get random data */
8117 if (RAND_pseudo_bytes((unsigned char*)
8118 PyString_AS_STRING(result),
8119 howMany) < 0) {
8120 Py_DECREF(result);
8121 return PyErr_Format(PyExc_ValueError,
8122 "RAND_pseudo_bytes");
8125 return result;
8127 #endif
8129 static PyMethodDef posix_methods[] = {
8130 {"access", posix_access, METH_VARARGS, posix_access__doc__},
8131 #ifdef HAVE_TTYNAME
8132 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
8133 #endif
8134 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
8135 #ifdef HAVE_CHFLAGS
8136 {"chflags", posix_chflags, METH_VARARGS, posix_chflags__doc__},
8137 #endif /* HAVE_CHFLAGS */
8138 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
8139 #ifdef HAVE_CHOWN
8140 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
8141 #endif /* HAVE_CHOWN */
8142 #ifdef HAVE_LCHFLAGS
8143 {"lchflags", posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
8144 #endif /* HAVE_LCHFLAGS */
8145 #ifdef HAVE_LCHOWN
8146 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
8147 #endif /* HAVE_LCHOWN */
8148 #ifdef HAVE_CHROOT
8149 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
8150 #endif
8151 #ifdef HAVE_CTERMID
8152 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
8153 #endif
8154 #ifdef HAVE_GETCWD
8155 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
8156 #ifdef Py_USING_UNICODE
8157 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
8158 #endif
8159 #endif
8160 #ifdef HAVE_LINK
8161 {"link", posix_link, METH_VARARGS, posix_link__doc__},
8162 #endif /* HAVE_LINK */
8163 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
8164 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
8165 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
8166 #ifdef HAVE_NICE
8167 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
8168 #endif /* HAVE_NICE */
8169 #ifdef HAVE_READLINK
8170 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
8171 #endif /* HAVE_READLINK */
8172 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
8173 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
8174 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
8175 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
8176 #ifdef HAVE_SYMLINK
8177 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
8178 #endif /* HAVE_SYMLINK */
8179 #ifdef HAVE_SYSTEM
8180 {"system", posix_system, METH_VARARGS, posix_system__doc__},
8181 #endif
8182 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
8183 #ifdef HAVE_UNAME
8184 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
8185 #endif /* HAVE_UNAME */
8186 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
8187 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
8188 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
8189 #ifdef HAVE_TIMES
8190 {"times", posix_times, METH_NOARGS, posix_times__doc__},
8191 #endif /* HAVE_TIMES */
8192 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
8193 #ifdef HAVE_EXECV
8194 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
8195 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
8196 #endif /* HAVE_EXECV */
8197 #ifdef HAVE_SPAWNV
8198 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
8199 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
8200 #if defined(PYOS_OS2)
8201 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
8202 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
8203 #endif /* PYOS_OS2 */
8204 #endif /* HAVE_SPAWNV */
8205 #ifdef HAVE_FORK1
8206 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
8207 #endif /* HAVE_FORK1 */
8208 #ifdef HAVE_FORK
8209 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
8210 #endif /* HAVE_FORK */
8211 #if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
8212 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
8213 #endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
8214 #ifdef HAVE_FORKPTY
8215 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
8216 #endif /* HAVE_FORKPTY */
8217 #ifdef HAVE_GETEGID
8218 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
8219 #endif /* HAVE_GETEGID */
8220 #ifdef HAVE_GETEUID
8221 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
8222 #endif /* HAVE_GETEUID */
8223 #ifdef HAVE_GETGID
8224 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
8225 #endif /* HAVE_GETGID */
8226 #ifdef HAVE_GETGROUPS
8227 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
8228 #endif
8229 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
8230 #ifdef HAVE_GETPGRP
8231 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
8232 #endif /* HAVE_GETPGRP */
8233 #ifdef HAVE_GETPPID
8234 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
8235 #endif /* HAVE_GETPPID */
8236 #ifdef HAVE_GETUID
8237 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
8238 #endif /* HAVE_GETUID */
8239 #ifdef HAVE_GETLOGIN
8240 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
8241 #endif
8242 #ifdef HAVE_KILL
8243 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
8244 #endif /* HAVE_KILL */
8245 #ifdef HAVE_KILLPG
8246 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
8247 #endif /* HAVE_KILLPG */
8248 #ifdef HAVE_PLOCK
8249 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
8250 #endif /* HAVE_PLOCK */
8251 #ifdef HAVE_POPEN
8252 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
8253 #ifdef MS_WINDOWS
8254 {"popen2", win32_popen2, METH_VARARGS},
8255 {"popen3", win32_popen3, METH_VARARGS},
8256 {"popen4", win32_popen4, METH_VARARGS},
8257 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
8258 #else
8259 #if defined(PYOS_OS2) && defined(PYCC_GCC)
8260 {"popen2", os2emx_popen2, METH_VARARGS},
8261 {"popen3", os2emx_popen3, METH_VARARGS},
8262 {"popen4", os2emx_popen4, METH_VARARGS},
8263 #endif
8264 #endif
8265 #endif /* HAVE_POPEN */
8266 #ifdef HAVE_SETUID
8267 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
8268 #endif /* HAVE_SETUID */
8269 #ifdef HAVE_SETEUID
8270 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
8271 #endif /* HAVE_SETEUID */
8272 #ifdef HAVE_SETEGID
8273 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
8274 #endif /* HAVE_SETEGID */
8275 #ifdef HAVE_SETREUID
8276 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
8277 #endif /* HAVE_SETREUID */
8278 #ifdef HAVE_SETREGID
8279 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
8280 #endif /* HAVE_SETREGID */
8281 #ifdef HAVE_SETGID
8282 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
8283 #endif /* HAVE_SETGID */
8284 #ifdef HAVE_SETGROUPS
8285 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
8286 #endif /* HAVE_SETGROUPS */
8287 #ifdef HAVE_GETPGID
8288 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
8289 #endif /* HAVE_GETPGID */
8290 #ifdef HAVE_SETPGRP
8291 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
8292 #endif /* HAVE_SETPGRP */
8293 #ifdef HAVE_WAIT
8294 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
8295 #endif /* HAVE_WAIT */
8296 #ifdef HAVE_WAIT3
8297 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
8298 #endif /* HAVE_WAIT3 */
8299 #ifdef HAVE_WAIT4
8300 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
8301 #endif /* HAVE_WAIT4 */
8302 #if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
8303 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
8304 #endif /* HAVE_WAITPID */
8305 #ifdef HAVE_GETSID
8306 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
8307 #endif /* HAVE_GETSID */
8308 #ifdef HAVE_SETSID
8309 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
8310 #endif /* HAVE_SETSID */
8311 #ifdef HAVE_SETPGID
8312 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
8313 #endif /* HAVE_SETPGID */
8314 #ifdef HAVE_TCGETPGRP
8315 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
8316 #endif /* HAVE_TCGETPGRP */
8317 #ifdef HAVE_TCSETPGRP
8318 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
8319 #endif /* HAVE_TCSETPGRP */
8320 {"open", posix_open, METH_VARARGS, posix_open__doc__},
8321 {"close", posix_close, METH_VARARGS, posix_close__doc__},
8322 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
8323 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
8324 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
8325 {"read", posix_read, METH_VARARGS, posix_read__doc__},
8326 {"write", posix_write, METH_VARARGS, posix_write__doc__},
8327 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
8328 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
8329 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
8330 #ifdef HAVE_PIPE
8331 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
8332 #endif
8333 #ifdef HAVE_MKFIFO
8334 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
8335 #endif
8336 #if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
8337 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
8338 #endif
8339 #ifdef HAVE_DEVICE_MACROS
8340 {"major", posix_major, METH_VARARGS, posix_major__doc__},
8341 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
8342 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
8343 #endif
8344 #ifdef HAVE_FTRUNCATE
8345 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
8346 #endif
8347 #ifdef HAVE_PUTENV
8348 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
8349 #endif
8350 #ifdef HAVE_UNSETENV
8351 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
8352 #endif
8353 #ifdef HAVE_STRERROR
8354 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
8355 #endif
8356 #ifdef HAVE_FCHDIR
8357 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
8358 #endif
8359 #ifdef HAVE_FSYNC
8360 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
8361 #endif
8362 #ifdef HAVE_FDATASYNC
8363 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
8364 #endif
8365 #ifdef HAVE_SYS_WAIT_H
8366 #ifdef WCOREDUMP
8367 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
8368 #endif /* WCOREDUMP */
8369 #ifdef WIFCONTINUED
8370 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
8371 #endif /* WIFCONTINUED */
8372 #ifdef WIFSTOPPED
8373 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
8374 #endif /* WIFSTOPPED */
8375 #ifdef WIFSIGNALED
8376 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
8377 #endif /* WIFSIGNALED */
8378 #ifdef WIFEXITED
8379 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
8380 #endif /* WIFEXITED */
8381 #ifdef WEXITSTATUS
8382 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
8383 #endif /* WEXITSTATUS */
8384 #ifdef WTERMSIG
8385 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
8386 #endif /* WTERMSIG */
8387 #ifdef WSTOPSIG
8388 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
8389 #endif /* WSTOPSIG */
8390 #endif /* HAVE_SYS_WAIT_H */
8391 #if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
8392 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
8393 #endif
8394 #if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
8395 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
8396 #endif
8397 #ifdef HAVE_TMPFILE
8398 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
8399 #endif
8400 #ifdef HAVE_TEMPNAM
8401 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
8402 #endif
8403 #ifdef HAVE_TMPNAM
8404 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
8405 #endif
8406 #ifdef HAVE_CONFSTR
8407 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
8408 #endif
8409 #ifdef HAVE_SYSCONF
8410 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
8411 #endif
8412 #ifdef HAVE_FPATHCONF
8413 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
8414 #endif
8415 #ifdef HAVE_PATHCONF
8416 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
8417 #endif
8418 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
8419 #ifdef MS_WINDOWS
8420 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
8421 #endif
8422 #ifdef HAVE_GETLOADAVG
8423 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
8424 #endif
8425 #ifdef MS_WINDOWS
8426 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
8427 #endif
8428 #ifdef __VMS
8429 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
8430 #endif
8431 {NULL, NULL} /* Sentinel */
8435 static int
8436 ins(PyObject *module, char *symbol, long value)
8438 return PyModule_AddIntConstant(module, symbol, value);
8441 #if defined(PYOS_OS2)
8442 /* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
8443 static int insertvalues(PyObject *module)
8445 APIRET rc;
8446 ULONG values[QSV_MAX+1];
8447 PyObject *v;
8448 char *ver, tmp[50];
8450 Py_BEGIN_ALLOW_THREADS
8451 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
8452 Py_END_ALLOW_THREADS
8454 if (rc != NO_ERROR) {
8455 os2_error(rc);
8456 return -1;
8459 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
8460 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
8461 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
8462 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
8463 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
8464 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
8465 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
8467 switch (values[QSV_VERSION_MINOR]) {
8468 case 0: ver = "2.00"; break;
8469 case 10: ver = "2.10"; break;
8470 case 11: ver = "2.11"; break;
8471 case 30: ver = "3.00"; break;
8472 case 40: ver = "4.00"; break;
8473 case 50: ver = "5.00"; break;
8474 default:
8475 PyOS_snprintf(tmp, sizeof(tmp),
8476 "%d-%d", values[QSV_VERSION_MAJOR],
8477 values[QSV_VERSION_MINOR]);
8478 ver = &tmp[0];
8481 /* Add Indicator of the Version of the Operating System */
8482 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
8483 return -1;
8485 /* Add Indicator of Which Drive was Used to Boot the System */
8486 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
8487 tmp[1] = ':';
8488 tmp[2] = '\0';
8490 return PyModule_AddStringConstant(module, "bootdrive", tmp);
8492 #endif
8494 static int
8495 all_ins(PyObject *d)
8497 #ifdef F_OK
8498 if (ins(d, "F_OK", (long)F_OK)) return -1;
8499 #endif
8500 #ifdef R_OK
8501 if (ins(d, "R_OK", (long)R_OK)) return -1;
8502 #endif
8503 #ifdef W_OK
8504 if (ins(d, "W_OK", (long)W_OK)) return -1;
8505 #endif
8506 #ifdef X_OK
8507 if (ins(d, "X_OK", (long)X_OK)) return -1;
8508 #endif
8509 #ifdef NGROUPS_MAX
8510 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
8511 #endif
8512 #ifdef TMP_MAX
8513 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
8514 #endif
8515 #ifdef WCONTINUED
8516 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
8517 #endif
8518 #ifdef WNOHANG
8519 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
8520 #endif
8521 #ifdef WUNTRACED
8522 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
8523 #endif
8524 #ifdef O_RDONLY
8525 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
8526 #endif
8527 #ifdef O_WRONLY
8528 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
8529 #endif
8530 #ifdef O_RDWR
8531 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
8532 #endif
8533 #ifdef O_NDELAY
8534 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
8535 #endif
8536 #ifdef O_NONBLOCK
8537 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
8538 #endif
8539 #ifdef O_APPEND
8540 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
8541 #endif
8542 #ifdef O_DSYNC
8543 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
8544 #endif
8545 #ifdef O_RSYNC
8546 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
8547 #endif
8548 #ifdef O_SYNC
8549 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
8550 #endif
8551 #ifdef O_NOCTTY
8552 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
8553 #endif
8554 #ifdef O_CREAT
8555 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
8556 #endif
8557 #ifdef O_EXCL
8558 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
8559 #endif
8560 #ifdef O_TRUNC
8561 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
8562 #endif
8563 #ifdef O_BINARY
8564 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
8565 #endif
8566 #ifdef O_TEXT
8567 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
8568 #endif
8569 #ifdef O_LARGEFILE
8570 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
8571 #endif
8572 #ifdef O_SHLOCK
8573 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
8574 #endif
8575 #ifdef O_EXLOCK
8576 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
8577 #endif
8579 /* MS Windows */
8580 #ifdef O_NOINHERIT
8581 /* Don't inherit in child processes. */
8582 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
8583 #endif
8584 #ifdef _O_SHORT_LIVED
8585 /* Optimize for short life (keep in memory). */
8586 /* MS forgot to define this one with a non-underscore form too. */
8587 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
8588 #endif
8589 #ifdef O_TEMPORARY
8590 /* Automatically delete when last handle is closed. */
8591 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
8592 #endif
8593 #ifdef O_RANDOM
8594 /* Optimize for random access. */
8595 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
8596 #endif
8597 #ifdef O_SEQUENTIAL
8598 /* Optimize for sequential access. */
8599 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
8600 #endif
8602 /* GNU extensions. */
8603 #ifdef O_DIRECT
8604 /* Direct disk access. */
8605 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
8606 #endif
8607 #ifdef O_DIRECTORY
8608 /* Must be a directory. */
8609 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
8610 #endif
8611 #ifdef O_NOFOLLOW
8612 /* Do not follow links. */
8613 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
8614 #endif
8616 /* These come from sysexits.h */
8617 #ifdef EX_OK
8618 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
8619 #endif /* EX_OK */
8620 #ifdef EX_USAGE
8621 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
8622 #endif /* EX_USAGE */
8623 #ifdef EX_DATAERR
8624 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
8625 #endif /* EX_DATAERR */
8626 #ifdef EX_NOINPUT
8627 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
8628 #endif /* EX_NOINPUT */
8629 #ifdef EX_NOUSER
8630 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
8631 #endif /* EX_NOUSER */
8632 #ifdef EX_NOHOST
8633 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
8634 #endif /* EX_NOHOST */
8635 #ifdef EX_UNAVAILABLE
8636 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
8637 #endif /* EX_UNAVAILABLE */
8638 #ifdef EX_SOFTWARE
8639 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
8640 #endif /* EX_SOFTWARE */
8641 #ifdef EX_OSERR
8642 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
8643 #endif /* EX_OSERR */
8644 #ifdef EX_OSFILE
8645 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
8646 #endif /* EX_OSFILE */
8647 #ifdef EX_CANTCREAT
8648 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
8649 #endif /* EX_CANTCREAT */
8650 #ifdef EX_IOERR
8651 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
8652 #endif /* EX_IOERR */
8653 #ifdef EX_TEMPFAIL
8654 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
8655 #endif /* EX_TEMPFAIL */
8656 #ifdef EX_PROTOCOL
8657 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
8658 #endif /* EX_PROTOCOL */
8659 #ifdef EX_NOPERM
8660 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
8661 #endif /* EX_NOPERM */
8662 #ifdef EX_CONFIG
8663 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
8664 #endif /* EX_CONFIG */
8665 #ifdef EX_NOTFOUND
8666 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
8667 #endif /* EX_NOTFOUND */
8669 #ifdef HAVE_SPAWNV
8670 #if defined(PYOS_OS2) && defined(PYCC_GCC)
8671 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
8672 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
8673 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
8674 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
8675 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
8676 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
8677 if (ins(d, "P_PM", (long)P_PM)) return -1;
8678 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
8679 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
8680 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
8681 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
8682 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
8683 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
8684 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
8685 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
8686 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
8687 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
8688 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
8689 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
8690 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
8691 #else
8692 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
8693 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
8694 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
8695 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
8696 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
8697 #endif
8698 #endif
8700 #if defined(PYOS_OS2)
8701 if (insertvalues(d)) return -1;
8702 #endif
8703 return 0;
8707 #if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
8708 #define INITFUNC initnt
8709 #define MODNAME "nt"
8711 #elif defined(PYOS_OS2)
8712 #define INITFUNC initos2
8713 #define MODNAME "os2"
8715 #else
8716 #define INITFUNC initposix
8717 #define MODNAME "posix"
8718 #endif
8720 PyMODINIT_FUNC
8721 INITFUNC(void)
8723 PyObject *m, *v;
8725 m = Py_InitModule3(MODNAME,
8726 posix_methods,
8727 posix__doc__);
8728 if (m == NULL)
8729 return;
8731 /* Initialize environ dictionary */
8732 v = convertenviron();
8733 Py_XINCREF(v);
8734 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
8735 return;
8736 Py_DECREF(v);
8738 if (all_ins(m))
8739 return;
8741 if (setup_confname_tables(m))
8742 return;
8744 Py_INCREF(PyExc_OSError);
8745 PyModule_AddObject(m, "error", PyExc_OSError);
8747 #ifdef HAVE_PUTENV
8748 if (posix_putenv_garbage == NULL)
8749 posix_putenv_garbage = PyDict_New();
8750 #endif
8752 if (!initialized) {
8753 stat_result_desc.name = MODNAME ".stat_result";
8754 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
8755 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
8756 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
8757 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
8758 structseq_new = StatResultType.tp_new;
8759 StatResultType.tp_new = statresult_new;
8761 statvfs_result_desc.name = MODNAME ".statvfs_result";
8762 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
8764 Py_INCREF((PyObject*) &StatResultType);
8765 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
8766 Py_INCREF((PyObject*) &StatVFSResultType);
8767 PyModule_AddObject(m, "statvfs_result",
8768 (PyObject*) &StatVFSResultType);
8769 initialized = 1;
8771 #ifdef __APPLE__
8773 * Step 2 of weak-linking support on Mac OS X.
8775 * The code below removes functions that are not available on the
8776 * currently active platform.
8778 * This block allow one to use a python binary that was build on
8779 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
8780 * OSX 10.4.
8782 #ifdef HAVE_FSTATVFS
8783 if (fstatvfs == NULL) {
8784 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
8785 return;
8788 #endif /* HAVE_FSTATVFS */
8790 #ifdef HAVE_STATVFS
8791 if (statvfs == NULL) {
8792 if (PyObject_DelAttrString(m, "statvfs") == -1) {
8793 return;
8796 #endif /* HAVE_STATVFS */
8798 # ifdef HAVE_LCHOWN
8799 if (lchown == NULL) {
8800 if (PyObject_DelAttrString(m, "lchown") == -1) {
8801 return;
8804 #endif /* HAVE_LCHOWN */
8807 #endif /* __APPLE__ */
8811 #ifdef __cplusplus
8813 #endif