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 */
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.
24 # pragma weak fstatvfs
26 #endif /* __APPLE__ */
28 #define PY_SSIZE_T_CLEAN
31 #include "structseq.h"
35 #endif /* defined(__VMS) */
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
54 #define INCL_DOSERRORS
55 #define INCL_DOSPROCESS
67 #ifdef HAVE_SYS_TYPES_H
68 #include <sys/types.h>
69 #endif /* HAVE_SYS_TYPES_H */
71 #ifdef HAVE_SYS_STAT_H
73 #endif /* HAVE_SYS_STAT_H */
75 #ifdef HAVE_SYS_WAIT_H
76 #include <sys/wait.h> /* For WNOHANG */
85 #endif /* HAVE_FCNTL_H */
91 #ifdef HAVE_SYSEXITS_H
93 #endif /* HAVE_SYSEXITS_H */
95 #ifdef HAVE_SYS_LOADAVG_H
96 #include <sys/loadavg.h>
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)
104 #if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
105 #define HAVE_GETCWD 1
106 #define HAVE_OPENDIR 1
107 #define HAVE_SYSTEM 1
114 #ifdef __BORLANDC__ /* Borland compiler */
116 #define HAVE_GETCWD 1
117 #define HAVE_OPENDIR 1
120 #define HAVE_SYSTEM 1
123 #ifdef _MSC_VER /* Microsoft compiler */
124 #define HAVE_GETCWD 1
125 #define HAVE_SPAWNV 1
129 #define HAVE_SYSTEM 1
132 #define fsync _commit
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 */
140 #if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
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
150 #define HAVE_OPENDIR 1
155 #define HAVE_SYSTEM 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__ */
166 #if defined(__sgi)&&_COMPILER_VERSION>=700
167 /* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
169 extern char *ctermid_r(char *);
172 #ifndef HAVE_UNISTD_H
173 #if defined(PYCC_VACPP)
174 extern int mkdir(char *);
176 #if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
177 extern int mkdir(const char *);
179 extern int mkdir(const char *, mode_t
);
182 #if defined(__IBMC__) || defined(__IBMCPP__)
183 extern int chdir(char *);
184 extern int rmdir(char *);
186 extern int chdir(const char *);
187 extern int rmdir(const char *);
190 extern int chmod(const char *, int);
192 extern int chmod(const char *, mode_t
);
195 extern int fchmod(int, mode_t);
198 extern int lchmod(const char *, mode_t);
200 extern int chown(const char *, uid_t
, gid_t
);
201 extern char *getcwd(char *, int);
202 extern char *strerror(int);
203 extern int link(const char *, const char *);
204 extern int rename(const char *, const char *);
205 extern int stat(const char *, struct stat
*);
206 extern int unlink(const char *);
207 extern int pclose(FILE *);
209 extern int symlink(const char *, const char *);
210 #endif /* HAVE_SYMLINK */
212 extern int lstat(const char *, struct stat
*);
213 #endif /* HAVE_LSTAT */
214 #endif /* !HAVE_UNISTD_H */
216 #endif /* !_MSC_VER */
220 #endif /* HAVE_UTIME_H */
222 #ifdef HAVE_SYS_UTIME_H
223 #include <sys/utime.h>
224 #define HAVE_UTIME_H /* pretend we do for the rest of this file */
225 #endif /* HAVE_SYS_UTIME_H */
227 #ifdef HAVE_SYS_TIMES_H
228 #include <sys/times.h>
229 #endif /* HAVE_SYS_TIMES_H */
231 #ifdef HAVE_SYS_PARAM_H
232 #include <sys/param.h>
233 #endif /* HAVE_SYS_PARAM_H */
235 #ifdef HAVE_SYS_UTSNAME_H
236 #include <sys/utsname.h>
237 #endif /* HAVE_SYS_UTSNAME_H */
241 #define NAMLEN(dirent) strlen((dirent)->d_name)
243 #if defined(__WATCOMC__) && !defined(__QNX__)
245 #define NAMLEN(dirent) strlen((dirent)->d_name)
247 #define dirent direct
248 #define NAMLEN(dirent) (dirent)->d_namlen
250 #ifdef HAVE_SYS_NDIR_H
251 #include <sys/ndir.h>
253 #ifdef HAVE_SYS_DIR_H
268 #ifdef HAVE_PROCESS_H
273 #include <shellapi.h> /* for ShellExecute() */
275 #define pclose _pclose
276 #endif /* _MSC_VER */
278 #if defined(PYCC_VACPP) && defined(PYOS_OS2)
283 #if defined(PATH_MAX) && PATH_MAX > 1024
284 #define MAXPATHLEN PATH_MAX
286 #define MAXPATHLEN 1024
288 #endif /* MAXPATHLEN */
291 /* Emulate some macros on systems that have a union instead of macros */
294 #define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
298 #define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
302 #define WTERMSIG(u_wait) ((u_wait).w_termsig)
305 #define WAIT_TYPE union wait
306 #define WAIT_STATUS_INT(s) (s.w_status)
308 #else /* !UNION_WAIT */
309 #define WAIT_TYPE int
310 #define WAIT_STATUS_INT(s) (s)
311 #endif /* UNION_WAIT */
313 /* Don't use the "_r" form if we don't need it (also, won't have a
314 prototype for it, at least on Solaris -- maybe others as well?). */
315 #if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
316 #define USE_CTERMID_R
319 #if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
323 /* choose the appropriate stat and fstat functions and return structs */
325 #if defined(MS_WIN64) || defined(MS_WINDOWS)
326 # define STAT win32_stat
327 # define FSTAT win32_fstat
328 # define STRUCT_STAT struct win32_stat
332 # define STRUCT_STAT struct stat
335 #if defined(MAJOR_IN_MKDEV)
336 #include <sys/mkdev.h>
338 #if defined(MAJOR_IN_SYSMACROS)
339 #include <sys/sysmacros.h>
341 #if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
342 #include <sys/mkdev.h>
346 /* Return a dictionary corresponding to the POSIX environment table */
347 #ifdef WITH_NEXT_FRAMEWORK
348 /* On Darwin/MacOSX a shared library or framework has no access to
349 ** environ directly, we must obtain it with _NSGetEnviron().
351 #include <crt_externs.h>
352 static char **environ
;
353 #elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
354 extern char **environ
;
355 #endif /* !_MSC_VER */
365 #ifdef WITH_NEXT_FRAMEWORK
367 environ
= *_NSGetEnviron();
371 /* This part ignores errors */
372 for (e
= environ
; *e
!= NULL
; e
++) {
375 char *p
= strchr(*e
, '=');
378 k
= PyString_FromStringAndSize(*e
, (int)(p
-*e
));
383 v
= PyString_FromString(p
+1);
389 if (PyDict_GetItem(d
, k
) == NULL
) {
390 if (PyDict_SetItem(d
, k
, v
) != 0)
396 #if defined(PYOS_OS2)
399 char buffer
[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
401 rc
= DosQueryExtLIBPATH(buffer
, BEGIN_LIBPATH
);
402 if (rc
== NO_ERROR
) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
403 PyObject
*v
= PyString_FromString(buffer
);
404 PyDict_SetItemString(d
, "BEGINLIBPATH", v
);
407 rc
= DosQueryExtLIBPATH(buffer
, END_LIBPATH
);
408 if (rc
== NO_ERROR
) { /* (not a typo, envname is NOT 'END_LIBPATH') */
409 PyObject
*v
= PyString_FromString(buffer
);
410 PyDict_SetItemString(d
, "ENDLIBPATH", v
);
419 /* Set a POSIX-specific error from errno, and return NULL */
424 return PyErr_SetFromErrno(PyExc_OSError
);
427 posix_error_with_filename(char* name
)
429 return PyErr_SetFromErrnoWithFilename(PyExc_OSError
, name
);
432 #ifdef Py_WIN_WIDE_FILENAMES
434 posix_error_with_unicode_filename(Py_UNICODE
* name
)
436 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError
, name
);
438 #endif /* Py_WIN_WIDE_FILENAMES */
442 posix_error_with_allocated_filename(char* name
)
444 PyObject
*rc
= PyErr_SetFromErrnoWithFilename(PyExc_OSError
, name
);
451 win32_error(char* function
, char* filename
)
453 /* XXX We should pass the function name along in the future.
454 (_winreg.c also wants to pass the function name.)
455 This would however require an additional param to the
456 Windows error object, which is non-trivial.
458 errno
= GetLastError();
460 return PyErr_SetFromWindowsErrWithFilename(errno
, filename
);
462 return PyErr_SetFromWindowsErr(errno
);
465 #ifdef Py_WIN_WIDE_FILENAMES
467 win32_error_unicode(char* function
, Py_UNICODE
* filename
)
469 /* XXX - see win32_error for comments on 'function' */
470 errno
= GetLastError();
472 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno
, filename
);
474 return PyErr_SetFromWindowsErr(errno
);
477 static PyObject
*_PyUnicode_FromFileSystemEncodedObject(register PyObject
*obj
)
481 /* Function suitable for O& conversion */
483 convert_to_unicode(PyObject
*arg
, void* _param
)
485 PyObject
**param
= (PyObject
**)_param
;
486 if (PyUnicode_CheckExact(arg
)) {
490 else if (PyUnicode_Check(arg
)) {
491 /* For a Unicode subtype that's not a Unicode object,
492 return a true Unicode object with the same data. */
493 *param
= PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(arg
),
494 PyUnicode_GET_SIZE(arg
));
495 return *param
!= NULL
;
498 *param
= PyUnicode_FromEncodedObject(arg
,
499 Py_FileSystemDefaultEncoding
,
501 return (*param
) != NULL
;
504 #endif /* Py_WIN_WIDE_FILENAMES */
508 #if defined(PYOS_OS2)
509 /**********************************************************************
510 * Helper Function to Trim and Format OS/2 Messages
511 **********************************************************************/
513 os2_formatmsg(char *msgbuf
, int msglen
, char *reason
)
515 msgbuf
[msglen
] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
517 if (strlen(msgbuf
) > 0) { /* If Non-Empty Msg, Trim CRLF */
518 char *lastc
= &msgbuf
[ strlen(msgbuf
)-1 ];
520 while (lastc
> msgbuf
&& isspace(Py_CHARMASK(*lastc
)))
521 *lastc
-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
524 /* Add Optional Reason Text */
526 strcat(msgbuf
, " : ");
527 strcat(msgbuf
, reason
);
531 /**********************************************************************
532 * Decode an OS/2 Operating System Error Code
534 * A convenience function to lookup an OS/2 error code and return a
535 * text message we can use to raise a Python exception.
538 * The messages for errors returned from the OS/2 kernel reside in
539 * the file OSO001.MSG in the \OS2 directory hierarchy.
541 **********************************************************************/
543 os2_strerror(char *msgbuf
, int msgbuflen
, int errorcode
, char *reason
)
548 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
549 Py_BEGIN_ALLOW_THREADS
550 rc
= DosGetMessage(NULL
, 0, msgbuf
, msgbuflen
,
551 errorcode
, "oso001.msg", &msglen
);
555 os2_formatmsg(msgbuf
, msglen
, reason
);
557 PyOS_snprintf(msgbuf
, msgbuflen
,
558 "unknown OS error #%d", errorcode
);
563 /* Set an OS/2-specific error and return NULL. OS/2 kernel
564 errors are not in a global variable e.g. 'errno' nor are
565 they congruent with posix error numbers. */
567 static PyObject
* os2_error(int code
)
572 os2_strerror(text
, sizeof(text
), code
, "");
574 v
= Py_BuildValue("(is)", code
, text
);
576 PyErr_SetObject(PyExc_OSError
, v
);
579 return NULL
; /* Signal to Python that an Exception is Pending */
584 /* POSIX generic methods */
587 posix_fildes(PyObject
*fdobj
, int (*func
)(int))
591 fd
= PyObject_AsFileDescriptor(fdobj
);
594 Py_BEGIN_ALLOW_THREADS
598 return posix_error();
603 #ifdef Py_WIN_WIDE_FILENAMES
605 unicode_file_names(void)
607 static int canusewide
= -1;
608 if (canusewide
== -1) {
609 /* As per doc for ::GetVersion(), this is the correct test for
610 the Windows NT family. */
611 canusewide
= (GetVersion() < 0x80000000) ? 1 : 0;
618 posix_1str(PyObject
*args
, char *format
, int (*func
)(const char*))
622 if (!PyArg_ParseTuple(args
, format
,
623 Py_FileSystemDefaultEncoding
, &path1
))
625 Py_BEGIN_ALLOW_THREADS
626 res
= (*func
)(path1
);
629 return posix_error_with_allocated_filename(path1
);
636 posix_2str(PyObject
*args
,
638 int (*func
)(const char *, const char *))
640 char *path1
= NULL
, *path2
= NULL
;
642 if (!PyArg_ParseTuple(args
, format
,
643 Py_FileSystemDefaultEncoding
, &path1
,
644 Py_FileSystemDefaultEncoding
, &path2
))
646 Py_BEGIN_ALLOW_THREADS
647 res
= (*func
)(path1
, path2
);
652 /* XXX how to report both path1 and path2??? */
653 return posix_error();
658 #ifdef Py_WIN_WIDE_FILENAMES
660 win32_1str(PyObject
* args
, char* func
,
661 char* format
, BOOL (__stdcall
*funcA
)(LPCSTR
),
662 char* wformat
, BOOL (__stdcall
*funcW
)(LPWSTR
))
667 if (unicode_file_names()) {
668 if (!PyArg_ParseTuple(args
, wformat
, &uni
))
671 Py_BEGIN_ALLOW_THREADS
672 result
= funcW(PyUnicode_AsUnicode(uni
));
675 return win32_error_unicode(func
, PyUnicode_AsUnicode(uni
));
680 if (!PyArg_ParseTuple(args
, format
, &ansi
))
682 Py_BEGIN_ALLOW_THREADS
683 result
= funcA(ansi
);
686 return win32_error(func
, ansi
);
692 /* This is a reimplementation of the C library's chdir function,
693 but one that produces Win32 errors instead of DOS error codes.
694 chdir is essentially a wrapper around SetCurrentDirectory; however,
695 it also needs to set "magic" environment variables indicating
696 the per-drive current directory, which are of the form =<drive>: */
698 win32_chdir(LPCSTR path
)
700 char new_path
[MAX_PATH
+1];
704 if(!SetCurrentDirectoryA(path
))
706 result
= GetCurrentDirectoryA(MAX_PATH
+1, new_path
);
709 /* In the ANSI API, there should not be any paths longer
711 assert(result
<= MAX_PATH
+1);
712 if (strncmp(new_path
, "\\\\", 2) == 0 ||
713 strncmp(new_path
, "//", 2) == 0)
714 /* UNC path, nothing to do. */
716 env
[1] = new_path
[0];
717 return SetEnvironmentVariableA(env
, new_path
);
720 /* The Unicode version differs from the ANSI version
721 since the current directory might exceed MAX_PATH characters */
723 win32_wchdir(LPCWSTR path
)
725 wchar_t _new_path
[MAX_PATH
+1], *new_path
= _new_path
;
727 wchar_t env
[4] = L
"=x:";
729 if(!SetCurrentDirectoryW(path
))
731 result
= GetCurrentDirectoryW(MAX_PATH
+1, new_path
);
734 if (result
> MAX_PATH
+1) {
735 new_path
= malloc(result
);
737 SetLastError(ERROR_OUTOFMEMORY
);
741 if (wcsncmp(new_path
, L
"\\\\", 2) == 0 ||
742 wcsncmp(new_path
, L
"//", 2) == 0)
743 /* UNC path, nothing to do. */
745 env
[1] = new_path
[0];
746 result
= SetEnvironmentVariableW(env
, new_path
);
747 if (new_path
!= _new_path
)
754 /* The CRT of Windows has a number of flaws wrt. its stat() implementation:
755 - time stamps are restricted to second resolution
756 - file modification times suffer from forth-and-back conversions between
758 Therefore, we implement our own stat, based on the Win32 API directly.
760 #define HAVE_STAT_NSEC 1
765 unsigned short st_mode
;
779 static __int64 secs_between_epochs
= 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
782 FILE_TIME_to_time_t_nsec(FILETIME
*in_ptr
, int *time_out
, int* nsec_out
)
784 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
785 /* Cannot simply cast and dereference in_ptr,
786 since it might not be aligned properly */
788 memcpy(&in
, in_ptr
, sizeof(in
));
789 *nsec_out
= (int)(in
% 10000000) * 100; /* FILETIME is in units of 100 nsec. */
790 /* XXX Win32 supports time stamps past 2038; we currently don't */
791 *time_out
= Py_SAFE_DOWNCAST((in
/ 10000000) - secs_between_epochs
, __int64
, int);
795 time_t_to_FILE_TIME(int time_in
, int nsec_in
, FILETIME
*out_ptr
)
799 out
= time_in
+ secs_between_epochs
;
800 out
= out
* 10000000 + nsec_in
/ 100;
801 memcpy(out_ptr
, &out
, sizeof(out
));
804 /* Below, we *know* that ugo+r is 0444 */
806 #error Unsupported C library
809 attributes_to_mode(DWORD attr
)
812 if (attr
& FILE_ATTRIBUTE_DIRECTORY
)
813 m
|= _S_IFDIR
| 0111; /* IFEXEC for user,group,other */
816 if (attr
& FILE_ATTRIBUTE_READONLY
)
824 attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA
*info
, struct win32_stat
*result
)
826 memset(result
, 0, sizeof(*result
));
827 result
->st_mode
= attributes_to_mode(info
->dwFileAttributes
);
828 result
->st_size
= (((__int64
)info
->nFileSizeHigh
)<<32) + info
->nFileSizeLow
;
829 FILE_TIME_to_time_t_nsec(&info
->ftCreationTime
, &result
->st_ctime
, &result
->st_ctime_nsec
);
830 FILE_TIME_to_time_t_nsec(&info
->ftLastWriteTime
, &result
->st_mtime
, &result
->st_mtime_nsec
);
831 FILE_TIME_to_time_t_nsec(&info
->ftLastAccessTime
, &result
->st_atime
, &result
->st_atime_nsec
);
836 /* Emulate GetFileAttributesEx[AW] on Windows 95 */
837 static int checked
= 0;
838 static BOOL (CALLBACK
*gfaxa
)(LPCSTR
, GET_FILEEX_INFO_LEVELS
, LPVOID
);
839 static BOOL (CALLBACK
*gfaxw
)(LPCWSTR
, GET_FILEEX_INFO_LEVELS
, LPVOID
);
847 hKernel32
= GetModuleHandle("KERNEL32");
848 *(FARPROC
*)&gfaxa
= GetProcAddress(hKernel32
, "GetFileAttributesExA");
849 *(FARPROC
*)&gfaxw
= GetProcAddress(hKernel32
, "GetFileAttributesExW");
853 attributes_from_dir(LPCSTR pszFile
, LPWIN32_FILE_ATTRIBUTE_DATA pfad
)
856 WIN32_FIND_DATAA FileData
;
857 hFindFile
= FindFirstFileA(pszFile
, &FileData
);
858 if (hFindFile
== INVALID_HANDLE_VALUE
)
860 FindClose(hFindFile
);
861 pfad
->dwFileAttributes
= FileData
.dwFileAttributes
;
862 pfad
->ftCreationTime
= FileData
.ftCreationTime
;
863 pfad
->ftLastAccessTime
= FileData
.ftLastAccessTime
;
864 pfad
->ftLastWriteTime
= FileData
.ftLastWriteTime
;
865 pfad
->nFileSizeHigh
= FileData
.nFileSizeHigh
;
866 pfad
->nFileSizeLow
= FileData
.nFileSizeLow
;
871 attributes_from_dir_w(LPCWSTR pszFile
, LPWIN32_FILE_ATTRIBUTE_DATA pfad
)
874 WIN32_FIND_DATAW FileData
;
875 hFindFile
= FindFirstFileW(pszFile
, &FileData
);
876 if (hFindFile
== INVALID_HANDLE_VALUE
)
878 FindClose(hFindFile
);
879 pfad
->dwFileAttributes
= FileData
.dwFileAttributes
;
880 pfad
->ftCreationTime
= FileData
.ftCreationTime
;
881 pfad
->ftLastAccessTime
= FileData
.ftLastAccessTime
;
882 pfad
->ftLastWriteTime
= FileData
.ftLastWriteTime
;
883 pfad
->nFileSizeHigh
= FileData
.nFileSizeHigh
;
884 pfad
->nFileSizeLow
= FileData
.nFileSizeLow
;
889 Py_GetFileAttributesExA(LPCSTR pszFile
,
890 GET_FILEEX_INFO_LEVELS level
,
894 LPWIN32_FILE_ATTRIBUTE_DATA pfad
= pv
;
895 /* First try to use the system's implementation, if that is
896 available and either succeeds to gives an error other than
897 that it isn't implemented. */
900 result
= gfaxa(pszFile
, level
, pv
);
901 if (result
|| GetLastError() != ERROR_CALL_NOT_IMPLEMENTED
)
904 /* It's either not present, or not implemented.
905 Emulate using FindFirstFile. */
906 if (level
!= GetFileExInfoStandard
) {
907 SetLastError(ERROR_INVALID_PARAMETER
);
910 /* Use GetFileAttributes to validate that the file name
911 does not contain wildcards (which FindFirstFile would
913 if (GetFileAttributesA(pszFile
) == 0xFFFFFFFF)
915 return attributes_from_dir(pszFile
, pfad
);
919 Py_GetFileAttributesExW(LPCWSTR pszFile
,
920 GET_FILEEX_INFO_LEVELS level
,
924 LPWIN32_FILE_ATTRIBUTE_DATA pfad
= pv
;
925 /* First try to use the system's implementation, if that is
926 available and either succeeds to gives an error other than
927 that it isn't implemented. */
930 result
= gfaxw(pszFile
, level
, pv
);
931 if (result
|| GetLastError() != ERROR_CALL_NOT_IMPLEMENTED
)
934 /* It's either not present, or not implemented.
935 Emulate using FindFirstFile. */
936 if (level
!= GetFileExInfoStandard
) {
937 SetLastError(ERROR_INVALID_PARAMETER
);
940 /* Use GetFileAttributes to validate that the file name
941 does not contain wildcards (which FindFirstFile would
943 if (GetFileAttributesW(pszFile
) == 0xFFFFFFFF)
945 return attributes_from_dir_w(pszFile
, pfad
);
949 win32_stat(const char* path
, struct win32_stat
*result
)
951 WIN32_FILE_ATTRIBUTE_DATA info
;
954 /* XXX not supported on Win95 and NT 3.x */
955 if (!Py_GetFileAttributesExA(path
, GetFileExInfoStandard
, &info
)) {
956 if (GetLastError() != ERROR_SHARING_VIOLATION
) {
957 /* Protocol violation: we explicitly clear errno, instead of
958 setting it to a POSIX error. Callers should use GetLastError. */
962 /* Could not get attributes on open file. Fall back to
963 reading the directory. */
964 if (!attributes_from_dir(path
, &info
)) {
965 /* Very strange. This should not fail now */
971 code
= attribute_data_to_stat(&info
, result
);
974 /* Set S_IFEXEC if it is an .exe, .bat, ... */
975 dot
= strrchr(path
, '.');
977 if (stricmp(dot
, ".bat") == 0 ||
978 stricmp(dot
, ".cmd") == 0 ||
979 stricmp(dot
, ".exe") == 0 ||
980 stricmp(dot
, ".com") == 0)
981 result
->st_mode
|= 0111;
987 win32_wstat(const wchar_t* path
, struct win32_stat
*result
)
991 WIN32_FILE_ATTRIBUTE_DATA info
;
992 /* XXX not supported on Win95 and NT 3.x */
993 if (!Py_GetFileAttributesExW(path
, GetFileExInfoStandard
, &info
)) {
994 if (GetLastError() != ERROR_SHARING_VIOLATION
) {
995 /* Protocol violation: we explicitly clear errno, instead of
996 setting it to a POSIX error. Callers should use GetLastError. */
1000 /* Could not get attributes on open file. Fall back to
1001 reading the directory. */
1002 if (!attributes_from_dir_w(path
, &info
)) {
1003 /* Very strange. This should not fail now */
1009 code
= attribute_data_to_stat(&info
, result
);
1012 /* Set IFEXEC if it is an .exe, .bat, ... */
1013 dot
= wcsrchr(path
, '.');
1015 if (_wcsicmp(dot
, L
".bat") == 0 ||
1016 _wcsicmp(dot
, L
".cmd") == 0 ||
1017 _wcsicmp(dot
, L
".exe") == 0 ||
1018 _wcsicmp(dot
, L
".com") == 0)
1019 result
->st_mode
|= 0111;
1025 win32_fstat(int file_number
, struct win32_stat
*result
)
1027 BY_HANDLE_FILE_INFORMATION info
;
1031 h
= (HANDLE
)_get_osfhandle(file_number
);
1033 /* Protocol violation: we explicitly clear errno, instead of
1034 setting it to a POSIX error. Callers should use GetLastError. */
1037 if (h
== INVALID_HANDLE_VALUE
) {
1038 /* This is really a C library error (invalid file handle).
1039 We set the Win32 error to the closes one matching. */
1040 SetLastError(ERROR_INVALID_HANDLE
);
1043 memset(result
, 0, sizeof(*result
));
1045 type
= GetFileType(h
);
1046 if (type
== FILE_TYPE_UNKNOWN
) {
1047 DWORD error
= GetLastError();
1051 /* else: valid but unknown file */
1054 if (type
!= FILE_TYPE_DISK
) {
1055 if (type
== FILE_TYPE_CHAR
)
1056 result
->st_mode
= _S_IFCHR
;
1057 else if (type
== FILE_TYPE_PIPE
)
1058 result
->st_mode
= _S_IFIFO
;
1062 if (!GetFileInformationByHandle(h
, &info
)) {
1066 /* similar to stat() */
1067 result
->st_mode
= attributes_to_mode(info
.dwFileAttributes
);
1068 result
->st_size
= (((__int64
)info
.nFileSizeHigh
)<<32) + info
.nFileSizeLow
;
1069 FILE_TIME_to_time_t_nsec(&info
.ftCreationTime
, &result
->st_ctime
, &result
->st_ctime_nsec
);
1070 FILE_TIME_to_time_t_nsec(&info
.ftLastWriteTime
, &result
->st_mtime
, &result
->st_mtime_nsec
);
1071 FILE_TIME_to_time_t_nsec(&info
.ftLastAccessTime
, &result
->st_atime
, &result
->st_atime_nsec
);
1072 /* specific to fstat() */
1073 result
->st_nlink
= info
.nNumberOfLinks
;
1074 result
->st_ino
= (((__int64
)info
.nFileIndexHigh
)<<32) + info
.nFileIndexLow
;
1078 #endif /* MS_WINDOWS */
1080 PyDoc_STRVAR(stat_result__doc__
,
1081 "stat_result: Result from stat or lstat.\n\n\
1082 This object may be accessed either as a tuple of\n\
1083 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
1084 or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1086 Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1087 or st_flags, they are available as attributes only.\n\
1089 See os.stat for more information.");
1091 static PyStructSequence_Field stat_result_fields
[] = {
1092 {"st_mode", "protection bits"},
1093 {"st_ino", "inode"},
1094 {"st_dev", "device"},
1095 {"st_nlink", "number of hard links"},
1096 {"st_uid", "user ID of owner"},
1097 {"st_gid", "group ID of owner"},
1098 {"st_size", "total size, in bytes"},
1099 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1100 {NULL
, "integer time of last access"},
1101 {NULL
, "integer time of last modification"},
1102 {NULL
, "integer time of last change"},
1103 {"st_atime", "time of last access"},
1104 {"st_mtime", "time of last modification"},
1105 {"st_ctime", "time of last change"},
1106 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
1107 {"st_blksize", "blocksize for filesystem I/O"},
1109 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
1110 {"st_blocks", "number of blocks allocated"},
1112 #ifdef HAVE_STRUCT_STAT_ST_RDEV
1113 {"st_rdev", "device type (if inode device)"},
1115 #ifdef HAVE_STRUCT_STAT_ST_FLAGS
1116 {"st_flags", "user defined flags for file"},
1118 #ifdef HAVE_STRUCT_STAT_ST_GEN
1119 {"st_gen", "generation number"},
1121 #ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1122 {"st_birthtime", "time of creation"},
1127 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
1128 #define ST_BLKSIZE_IDX 13
1130 #define ST_BLKSIZE_IDX 12
1133 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
1134 #define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1136 #define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1139 #ifdef HAVE_STRUCT_STAT_ST_RDEV
1140 #define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1142 #define ST_RDEV_IDX ST_BLOCKS_IDX
1145 #ifdef HAVE_STRUCT_STAT_ST_FLAGS
1146 #define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1148 #define ST_FLAGS_IDX ST_RDEV_IDX
1151 #ifdef HAVE_STRUCT_STAT_ST_GEN
1152 #define ST_GEN_IDX (ST_FLAGS_IDX+1)
1154 #define ST_GEN_IDX ST_FLAGS_IDX
1157 #ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1158 #define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1160 #define ST_BIRTHTIME_IDX ST_GEN_IDX
1163 static PyStructSequence_Desc stat_result_desc
= {
1164 "stat_result", /* name */
1165 stat_result__doc__
, /* doc */
1170 PyDoc_STRVAR(statvfs_result__doc__
,
1171 "statvfs_result: Result from statvfs or fstatvfs.\n\n\
1172 This object may be accessed either as a tuple of\n\
1173 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
1174 or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
1176 See os.statvfs for more information.");
1178 static PyStructSequence_Field statvfs_result_fields
[] = {
1192 static PyStructSequence_Desc statvfs_result_desc
= {
1193 "statvfs_result", /* name */
1194 statvfs_result__doc__
, /* doc */
1195 statvfs_result_fields
,
1199 static int initialized
;
1200 static PyTypeObject StatResultType
;
1201 static PyTypeObject StatVFSResultType
;
1202 static newfunc structseq_new
;
1205 statresult_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwds
)
1207 PyStructSequence
*result
;
1210 result
= (PyStructSequence
*)structseq_new(type
, args
, kwds
);
1213 /* If we have been initialized from a tuple,
1214 st_?time might be set to None. Initialize it
1215 from the int slots. */
1216 for (i
= 7; i
<= 9; i
++) {
1217 if (result
->ob_item
[i
+3] == Py_None
) {
1219 Py_INCREF(result
->ob_item
[i
]);
1220 result
->ob_item
[i
+3] = result
->ob_item
[i
];
1223 return (PyObject
*)result
;
1228 /* If true, st_?time is float. */
1229 static int _stat_float_times
= 1;
1231 PyDoc_STRVAR(stat_float_times__doc__
,
1232 "stat_float_times([newval]) -> oldval\n\n\
1233 Determine whether os.[lf]stat represents time stamps as float objects.\n\
1234 If newval is True, future calls to stat() return floats, if it is False,\n\
1235 future calls return ints. \n\
1236 If newval is omitted, return the current setting.\n");
1239 stat_float_times(PyObject
* self
, PyObject
*args
)
1242 if (!PyArg_ParseTuple(args
, "|i:stat_float_times", &newval
))
1245 /* Return old value */
1246 return PyBool_FromLong(_stat_float_times
);
1247 _stat_float_times
= newval
;
1253 fill_time(PyObject
*v
, int index
, time_t sec
, unsigned long nsec
)
1255 PyObject
*fval
,*ival
;
1256 #if SIZEOF_TIME_T > SIZEOF_LONG
1257 ival
= PyLong_FromLongLong((PY_LONG_LONG
)sec
);
1259 ival
= PyInt_FromLong((long)sec
);
1263 if (_stat_float_times
) {
1264 fval
= PyFloat_FromDouble(sec
+ 1e-9*nsec
);
1269 PyStructSequence_SET_ITEM(v
, index
, ival
);
1270 PyStructSequence_SET_ITEM(v
, index
+3, fval
);
1273 /* pack a system stat C structure into the Python stat tuple
1274 (used by posix_stat() and posix_fstat()) */
1276 _pystat_fromstructstat(STRUCT_STAT
*st
)
1278 unsigned long ansec
, mnsec
, cnsec
;
1279 PyObject
*v
= PyStructSequence_New(&StatResultType
);
1283 PyStructSequence_SET_ITEM(v
, 0, PyInt_FromLong((long)st
->st_mode
));
1284 #ifdef HAVE_LARGEFILE_SUPPORT
1285 PyStructSequence_SET_ITEM(v
, 1,
1286 PyLong_FromLongLong((PY_LONG_LONG
)st
->st_ino
));
1288 PyStructSequence_SET_ITEM(v
, 1, PyInt_FromLong((long)st
->st_ino
));
1290 #if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
1291 PyStructSequence_SET_ITEM(v
, 2,
1292 PyLong_FromLongLong((PY_LONG_LONG
)st
->st_dev
));
1294 PyStructSequence_SET_ITEM(v
, 2, PyInt_FromLong((long)st
->st_dev
));
1296 PyStructSequence_SET_ITEM(v
, 3, PyInt_FromLong((long)st
->st_nlink
));
1297 PyStructSequence_SET_ITEM(v
, 4, PyInt_FromLong((long)st
->st_uid
));
1298 PyStructSequence_SET_ITEM(v
, 5, PyInt_FromLong((long)st
->st_gid
));
1299 #ifdef HAVE_LARGEFILE_SUPPORT
1300 PyStructSequence_SET_ITEM(v
, 6,
1301 PyLong_FromLongLong((PY_LONG_LONG
)st
->st_size
));
1303 PyStructSequence_SET_ITEM(v
, 6, PyInt_FromLong(st
->st_size
));
1306 #if defined(HAVE_STAT_TV_NSEC)
1307 ansec
= st
->st_atim
.tv_nsec
;
1308 mnsec
= st
->st_mtim
.tv_nsec
;
1309 cnsec
= st
->st_ctim
.tv_nsec
;
1310 #elif defined(HAVE_STAT_TV_NSEC2)
1311 ansec
= st
->st_atimespec
.tv_nsec
;
1312 mnsec
= st
->st_mtimespec
.tv_nsec
;
1313 cnsec
= st
->st_ctimespec
.tv_nsec
;
1314 #elif defined(HAVE_STAT_NSEC)
1315 ansec
= st
->st_atime_nsec
;
1316 mnsec
= st
->st_mtime_nsec
;
1317 cnsec
= st
->st_ctime_nsec
;
1319 ansec
= mnsec
= cnsec
= 0;
1321 fill_time(v
, 7, st
->st_atime
, ansec
);
1322 fill_time(v
, 8, st
->st_mtime
, mnsec
);
1323 fill_time(v
, 9, st
->st_ctime
, cnsec
);
1325 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
1326 PyStructSequence_SET_ITEM(v
, ST_BLKSIZE_IDX
,
1327 PyInt_FromLong((long)st
->st_blksize
));
1329 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
1330 PyStructSequence_SET_ITEM(v
, ST_BLOCKS_IDX
,
1331 PyInt_FromLong((long)st
->st_blocks
));
1333 #ifdef HAVE_STRUCT_STAT_ST_RDEV
1334 PyStructSequence_SET_ITEM(v
, ST_RDEV_IDX
,
1335 PyInt_FromLong((long)st
->st_rdev
));
1337 #ifdef HAVE_STRUCT_STAT_ST_GEN
1338 PyStructSequence_SET_ITEM(v
, ST_GEN_IDX
,
1339 PyInt_FromLong((long)st
->st_gen
));
1341 #ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1344 unsigned long bsec
,bnsec
;
1345 bsec
= (long)st
->st_birthtime
;
1346 #ifdef HAVE_STAT_TV_NSEC2
1347 bnsec
= st
->st_birthtimespec
.tv_nsec
;
1351 if (_stat_float_times
) {
1352 val
= PyFloat_FromDouble(bsec
+ 1e-9*bnsec
);
1354 val
= PyInt_FromLong((long)bsec
);
1356 PyStructSequence_SET_ITEM(v
, ST_BIRTHTIME_IDX
,
1360 #ifdef HAVE_STRUCT_STAT_ST_FLAGS
1361 PyStructSequence_SET_ITEM(v
, ST_FLAGS_IDX
,
1362 PyInt_FromLong((long)st
->st_flags
));
1365 if (PyErr_Occurred()) {
1375 /* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
1376 where / can be used in place of \ and the trailing slash is optional.
1377 Both SERVER and SHARE must have at least one character.
1380 #define ISSLASHA(c) ((c) == '\\' || (c) == '/')
1381 #define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
1383 #define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
1387 IsUNCRootA(char *path
, int pathlen
)
1389 #define ISSLASH ISSLASHA
1393 if (pathlen
< 5 || !ISSLASH(path
[0]) || !ISSLASH(path
[1]))
1394 /* minimum UNCRoot is \\x\y */
1396 for (i
= 2; i
< pathlen
; i
++)
1397 if (ISSLASH(path
[i
])) break;
1398 if (i
== 2 || i
== pathlen
)
1399 /* do not allow \\\SHARE or \\SERVER */
1402 for (i
= share
; i
< pathlen
; i
++)
1403 if (ISSLASH(path
[i
])) break;
1404 return (i
!= share
&& (i
== pathlen
|| i
== pathlen
-1));
1409 #ifdef Py_WIN_WIDE_FILENAMES
1411 IsUNCRootW(Py_UNICODE
*path
, int pathlen
)
1413 #define ISSLASH ISSLASHW
1417 if (pathlen
< 5 || !ISSLASH(path
[0]) || !ISSLASH(path
[1]))
1418 /* minimum UNCRoot is \\x\y */
1420 for (i
= 2; i
< pathlen
; i
++)
1421 if (ISSLASH(path
[i
])) break;
1422 if (i
== 2 || i
== pathlen
)
1423 /* do not allow \\\SHARE or \\SERVER */
1426 for (i
= share
; i
< pathlen
; i
++)
1427 if (ISSLASH(path
[i
])) break;
1428 return (i
!= share
&& (i
== pathlen
|| i
== pathlen
-1));
1432 #endif /* Py_WIN_WIDE_FILENAMES */
1433 #endif /* MS_WINDOWS */
1436 posix_do_stat(PyObject
*self
, PyObject
*args
,
1439 int (*statfunc
)(const char *, STRUCT_STAT
*, ...),
1441 int (*statfunc
)(const char *, STRUCT_STAT
*),
1444 int (*wstatfunc
)(const Py_UNICODE
*, STRUCT_STAT
*))
1447 char *path
= NULL
; /* pass this to stat; do not free() it */
1448 char *pathfree
= NULL
; /* this memory must be free'd */
1452 #ifdef Py_WIN_WIDE_FILENAMES
1453 /* If on wide-character-capable OS see if argument
1454 is Unicode and if so use wide API. */
1455 if (unicode_file_names()) {
1456 PyUnicodeObject
*po
;
1457 if (PyArg_ParseTuple(args
, wformat
, &po
)) {
1458 Py_UNICODE
*wpath
= PyUnicode_AS_UNICODE(po
);
1460 Py_BEGIN_ALLOW_THREADS
1461 /* PyUnicode_AS_UNICODE result OK without
1462 thread lock as it is a simple dereference. */
1463 res
= wstatfunc(wpath
, &st
);
1464 Py_END_ALLOW_THREADS
1467 return win32_error_unicode("stat", wpath
);
1468 return _pystat_fromstructstat(&st
);
1470 /* Drop the argument parsing error as narrow strings
1476 if (!PyArg_ParseTuple(args
, format
,
1477 Py_FileSystemDefaultEncoding
, &path
))
1481 Py_BEGIN_ALLOW_THREADS
1482 res
= (*statfunc
)(path
, &st
);
1483 Py_END_ALLOW_THREADS
1487 result
= win32_error("stat", pathfree
);
1489 result
= posix_error_with_filename(pathfree
);
1493 result
= _pystat_fromstructstat(&st
);
1495 PyMem_Free(pathfree
);
1501 PyDoc_STRVAR(posix_access__doc__
,
1502 "access(path, mode) -> True if granted, False otherwise\n\n\
1503 Use the real uid/gid to test for access to a path. Note that most\n\
1504 operations will use the effective uid/gid, therefore this routine can\n\
1505 be used in a suid/sgid environment to test if the invoking user has the\n\
1506 specified access to the path. The mode argument can be F_OK to test\n\
1507 existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
1510 posix_access(PyObject
*self
, PyObject
*args
)
1515 #ifdef Py_WIN_WIDE_FILENAMES
1517 if (unicode_file_names()) {
1518 PyUnicodeObject
*po
;
1519 if (PyArg_ParseTuple(args
, "Ui:access", &po
, &mode
)) {
1520 Py_BEGIN_ALLOW_THREADS
1521 /* PyUnicode_AS_UNICODE OK without thread lock as
1522 it is a simple dereference. */
1523 attr
= GetFileAttributesW(PyUnicode_AS_UNICODE(po
));
1524 Py_END_ALLOW_THREADS
1527 /* Drop the argument parsing error as narrow strings
1531 if (!PyArg_ParseTuple(args
, "eti:access",
1532 Py_FileSystemDefaultEncoding
, &path
, &mode
))
1534 Py_BEGIN_ALLOW_THREADS
1535 attr
= GetFileAttributesA(path
);
1536 Py_END_ALLOW_THREADS
1539 if (attr
== 0xFFFFFFFF)
1540 /* File does not exist, or cannot read attributes */
1541 return PyBool_FromLong(0);
1542 /* Access is possible if either write access wasn't requested, or
1543 the file isn't read-only, or if it's a directory, as there are
1544 no read-only directories on Windows. */
1545 return PyBool_FromLong(!(mode
& 2)
1546 || !(attr
& FILE_ATTRIBUTE_READONLY
)
1547 || (attr
& FILE_ATTRIBUTE_DIRECTORY
));
1550 if (!PyArg_ParseTuple(args
, "eti:access",
1551 Py_FileSystemDefaultEncoding
, &path
, &mode
))
1553 Py_BEGIN_ALLOW_THREADS
1554 res
= access(path
, mode
);
1555 Py_END_ALLOW_THREADS
1557 return PyBool_FromLong(res
== 0);
1575 PyDoc_STRVAR(posix_ttyname__doc__
,
1576 "ttyname(fd) -> string\n\n\
1577 Return the name of the terminal device connected to 'fd'.");
1580 posix_ttyname(PyObject
*self
, PyObject
*args
)
1585 if (!PyArg_ParseTuple(args
, "i:ttyname", &id
))
1589 /* file descriptor 0 only, the default input device (stdin) */
1600 return posix_error();
1601 return PyString_FromString(ret
);
1606 PyDoc_STRVAR(posix_ctermid__doc__
,
1607 "ctermid() -> string\n\n\
1608 Return the name of the controlling terminal for this process.");
1611 posix_ctermid(PyObject
*self
, PyObject
*noargs
)
1614 char buffer
[L_ctermid
];
1616 #ifdef USE_CTERMID_R
1617 ret
= ctermid_r(buffer
);
1619 ret
= ctermid(buffer
);
1622 return posix_error();
1623 return PyString_FromString(buffer
);
1627 PyDoc_STRVAR(posix_chdir__doc__
,
1629 Change the current working directory to the specified path.");
1632 posix_chdir(PyObject
*self
, PyObject
*args
)
1635 return win32_1str(args
, "chdir", "s:chdir", win32_chdir
, "U:chdir", win32_wchdir
);
1636 #elif defined(PYOS_OS2) && defined(PYCC_GCC)
1637 return posix_1str(args
, "et:chdir", _chdir2
);
1638 #elif defined(__VMS)
1639 return posix_1str(args
, "et:chdir", (int (*)(const char *))chdir
);
1641 return posix_1str(args
, "et:chdir", chdir
);
1646 PyDoc_STRVAR(posix_fchdir__doc__
,
1647 "fchdir(fildes)\n\n\
1648 Change to the directory of the given file descriptor. fildes must be\n\
1649 opened on a directory, not a file.");
1652 posix_fchdir(PyObject
*self
, PyObject
*fdobj
)
1654 return posix_fildes(fdobj
, fchdir
);
1656 #endif /* HAVE_FCHDIR */
1659 PyDoc_STRVAR(posix_chmod__doc__
,
1660 "chmod(path, mode)\n\n\
1661 Change the access permissions of a file.");
1664 posix_chmod(PyObject
*self
, PyObject
*args
)
1669 #ifdef Py_WIN_WIDE_FILENAMES
1671 if (unicode_file_names()) {
1672 PyUnicodeObject
*po
;
1673 if (PyArg_ParseTuple(args
, "Ui|:chmod", &po
, &i
)) {
1674 Py_BEGIN_ALLOW_THREADS
1675 attr
= GetFileAttributesW(PyUnicode_AS_UNICODE(po
));
1676 if (attr
!= 0xFFFFFFFF) {
1678 attr
&= ~FILE_ATTRIBUTE_READONLY
;
1680 attr
|= FILE_ATTRIBUTE_READONLY
;
1681 res
= SetFileAttributesW(PyUnicode_AS_UNICODE(po
), attr
);
1685 Py_END_ALLOW_THREADS
1687 return win32_error_unicode("chmod",
1688 PyUnicode_AS_UNICODE(po
));
1692 /* Drop the argument parsing error as narrow strings
1696 if (!PyArg_ParseTuple(args
, "eti:chmod", Py_FileSystemDefaultEncoding
,
1699 Py_BEGIN_ALLOW_THREADS
1700 attr
= GetFileAttributesA(path
);
1701 if (attr
!= 0xFFFFFFFF) {
1703 attr
&= ~FILE_ATTRIBUTE_READONLY
;
1705 attr
|= FILE_ATTRIBUTE_READONLY
;
1706 res
= SetFileAttributesA(path
, attr
);
1710 Py_END_ALLOW_THREADS
1712 win32_error("chmod", path
);
1719 #else /* Py_WIN_WIDE_FILENAMES */
1720 if (!PyArg_ParseTuple(args
, "eti:chmod", Py_FileSystemDefaultEncoding
,
1723 Py_BEGIN_ALLOW_THREADS
1724 res
= chmod(path
, i
);
1725 Py_END_ALLOW_THREADS
1727 return posix_error_with_allocated_filename(path
);
1735 PyDoc_STRVAR(posix_fchmod__doc__
,
1736 "fchmod(fd, mode)\n\n\
1737 Change the access permissions of the file given by file\n\
1741 posix_fchmod(PyObject
*self
, PyObject
*args
)
1744 if (!PyArg_ParseTuple(args
, "ii:fchmod", &fd
, &mode
))
1746 Py_BEGIN_ALLOW_THREADS
1747 res
= fchmod(fd
, mode
);
1748 Py_END_ALLOW_THREADS
1750 return posix_error();
1753 #endif /* HAVE_FCHMOD */
1756 PyDoc_STRVAR(posix_lchmod__doc__
,
1757 "lchmod(path, mode)\n\n\
1758 Change the access permissions of a file. If path is a symlink, this\n\
1759 affects the link itself rather than the target.");
1762 posix_lchmod(PyObject
*self
, PyObject
*args
)
1767 if (!PyArg_ParseTuple(args
, "eti:lchmod", Py_FileSystemDefaultEncoding
,
1770 Py_BEGIN_ALLOW_THREADS
1771 res
= lchmod(path
, i
);
1772 Py_END_ALLOW_THREADS
1774 return posix_error_with_allocated_filename(path
);
1778 #endif /* HAVE_LCHMOD */
1782 PyDoc_STRVAR(posix_chflags__doc__
,
1783 "chflags(path, flags)\n\n\
1787 posix_chflags(PyObject
*self
, PyObject
*args
)
1790 unsigned long flags
;
1792 if (!PyArg_ParseTuple(args
, "etk:chflags",
1793 Py_FileSystemDefaultEncoding
, &path
, &flags
))
1795 Py_BEGIN_ALLOW_THREADS
1796 res
= chflags(path
, flags
);
1797 Py_END_ALLOW_THREADS
1799 return posix_error_with_allocated_filename(path
);
1804 #endif /* HAVE_CHFLAGS */
1806 #ifdef HAVE_LCHFLAGS
1807 PyDoc_STRVAR(posix_lchflags__doc__
,
1808 "lchflags(path, flags)\n\n\
1810 This function will not follow symbolic links.");
1813 posix_lchflags(PyObject
*self
, PyObject
*args
)
1816 unsigned long flags
;
1818 if (!PyArg_ParseTuple(args
, "etk:lchflags",
1819 Py_FileSystemDefaultEncoding
, &path
, &flags
))
1821 Py_BEGIN_ALLOW_THREADS
1822 res
= lchflags(path
, flags
);
1823 Py_END_ALLOW_THREADS
1825 return posix_error_with_allocated_filename(path
);
1830 #endif /* HAVE_LCHFLAGS */
1833 PyDoc_STRVAR(posix_chroot__doc__
,
1835 Change root directory to path.");
1838 posix_chroot(PyObject
*self
, PyObject
*args
)
1840 return posix_1str(args
, "et:chroot", chroot
);
1845 PyDoc_STRVAR(posix_fsync__doc__
,
1847 force write of file with filedescriptor to disk.");
1850 posix_fsync(PyObject
*self
, PyObject
*fdobj
)
1852 return posix_fildes(fdobj
, fsync
);
1854 #endif /* HAVE_FSYNC */
1856 #ifdef HAVE_FDATASYNC
1859 extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1862 PyDoc_STRVAR(posix_fdatasync__doc__
,
1863 "fdatasync(fildes)\n\n\
1864 force write of file with filedescriptor to disk.\n\
1865 does not force update of metadata.");
1868 posix_fdatasync(PyObject
*self
, PyObject
*fdobj
)
1870 return posix_fildes(fdobj
, fdatasync
);
1872 #endif /* HAVE_FDATASYNC */
1876 PyDoc_STRVAR(posix_chown__doc__
,
1877 "chown(path, uid, gid)\n\n\
1878 Change the owner and group id of path to the numeric uid and gid.");
1881 posix_chown(PyObject
*self
, PyObject
*args
)
1886 if (!PyArg_ParseTuple(args
, "etll:chown",
1887 Py_FileSystemDefaultEncoding
, &path
,
1890 Py_BEGIN_ALLOW_THREADS
1891 res
= chown(path
, (uid_t
) uid
, (gid_t
) gid
);
1892 Py_END_ALLOW_THREADS
1894 return posix_error_with_allocated_filename(path
);
1899 #endif /* HAVE_CHOWN */
1902 PyDoc_STRVAR(posix_fchown__doc__
,
1903 "fchown(fd, uid, gid)\n\n\
1904 Change the owner and group id of the file given by file descriptor\n\
1905 fd to the numeric uid and gid.");
1908 posix_fchown(PyObject
*self
, PyObject
*args
)
1912 if (!PyArg_ParseTuple(args
, "iii:chown", &fd
, &uid
, &gid
))
1914 Py_BEGIN_ALLOW_THREADS
1915 res
= fchown(fd
, (uid_t
) uid
, (gid_t
) gid
);
1916 Py_END_ALLOW_THREADS
1918 return posix_error();
1921 #endif /* HAVE_FCHOWN */
1924 PyDoc_STRVAR(posix_lchown__doc__
,
1925 "lchown(path, uid, gid)\n\n\
1926 Change the owner and group id of path to the numeric uid and gid.\n\
1927 This function will not follow symbolic links.");
1930 posix_lchown(PyObject
*self
, PyObject
*args
)
1935 if (!PyArg_ParseTuple(args
, "etii:lchown",
1936 Py_FileSystemDefaultEncoding
, &path
,
1939 Py_BEGIN_ALLOW_THREADS
1940 res
= lchown(path
, (uid_t
) uid
, (gid_t
) gid
);
1941 Py_END_ALLOW_THREADS
1943 return posix_error_with_allocated_filename(path
);
1948 #endif /* HAVE_LCHOWN */
1952 PyDoc_STRVAR(posix_getcwd__doc__
,
1953 "getcwd() -> path\n\n\
1954 Return a string representing the current working directory.");
1957 posix_getcwd(PyObject
*self
, PyObject
*noargs
)
1959 int bufsize_incr
= 1024;
1961 char *tmpbuf
= NULL
;
1963 PyObject
*dynamic_return
;
1965 Py_BEGIN_ALLOW_THREADS
1967 bufsize
= bufsize
+ bufsize_incr
;
1968 tmpbuf
= malloc(bufsize
);
1969 if (tmpbuf
== NULL
) {
1972 #if defined(PYOS_OS2) && defined(PYCC_GCC)
1973 res
= _getcwd2(tmpbuf
, bufsize
);
1975 res
= getcwd(tmpbuf
, bufsize
);
1981 } while ((res
== NULL
) && (errno
== ERANGE
));
1982 Py_END_ALLOW_THREADS
1985 return posix_error();
1987 dynamic_return
= PyString_FromString(tmpbuf
);
1990 return dynamic_return
;
1993 #ifdef Py_USING_UNICODE
1994 PyDoc_STRVAR(posix_getcwdu__doc__
,
1995 "getcwdu() -> path\n\n\
1996 Return a unicode string representing the current working directory.");
1999 posix_getcwdu(PyObject
*self
, PyObject
*noargs
)
2004 #ifdef Py_WIN_WIDE_FILENAMES
2006 if (unicode_file_names()) {
2008 wchar_t *wbuf2
= wbuf
;
2010 Py_BEGIN_ALLOW_THREADS
2011 len
= GetCurrentDirectoryW(sizeof wbuf
/ sizeof wbuf
[0], wbuf
);
2012 /* If the buffer is large enough, len does not include the
2013 terminating \0. If the buffer is too small, len includes
2014 the space needed for the terminator. */
2015 if (len
>= sizeof wbuf
/ sizeof wbuf
[0]) {
2016 wbuf2
= malloc(len
* sizeof(wchar_t));
2018 len
= GetCurrentDirectoryW(len
, wbuf2
);
2020 Py_END_ALLOW_THREADS
2026 if (wbuf2
!= wbuf
) free(wbuf2
);
2027 return win32_error("getcwdu", NULL
);
2029 resobj
= PyUnicode_FromWideChar(wbuf2
, len
);
2030 if (wbuf2
!= wbuf
) free(wbuf2
);
2035 Py_BEGIN_ALLOW_THREADS
2036 #if defined(PYOS_OS2) && defined(PYCC_GCC)
2037 res
= _getcwd2(buf
, sizeof buf
);
2039 res
= getcwd(buf
, sizeof buf
);
2041 Py_END_ALLOW_THREADS
2043 return posix_error();
2044 return PyUnicode_Decode(buf
, strlen(buf
), Py_FileSystemDefaultEncoding
,"strict");
2051 PyDoc_STRVAR(posix_link__doc__
,
2052 "link(src, dst)\n\n\
2053 Create a hard link to a file.");
2056 posix_link(PyObject
*self
, PyObject
*args
)
2058 return posix_2str(args
, "etet:link", link
);
2060 #endif /* HAVE_LINK */
2063 PyDoc_STRVAR(posix_listdir__doc__
,
2064 "listdir(path) -> list_of_strings\n\n\
2065 Return a list containing the names of the entries in the directory.\n\
2067 path: path of directory to list\n\
2069 The list is in arbitrary order. It does not include the special\n\
2070 entries '.' and '..' even if they are present in the directory.");
2073 posix_listdir(PyObject
*self
, PyObject
*args
)
2075 /* XXX Should redo this putting the (now four) versions of opendir
2076 in separate files instead of having them all here... */
2077 #if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
2082 WIN32_FIND_DATA FileData
;
2083 char namebuf
[MAX_PATH
+5]; /* Overallocate for \\*.*\0 */
2084 char *bufptr
= namebuf
;
2085 Py_ssize_t len
= sizeof(namebuf
)-5; /* only claim to have space for MAX_PATH */
2087 #ifdef Py_WIN_WIDE_FILENAMES
2088 /* If on wide-character-capable OS see if argument
2089 is Unicode and if so use wide API. */
2090 if (unicode_file_names()) {
2092 if (PyArg_ParseTuple(args
, "U:listdir", &po
)) {
2093 WIN32_FIND_DATAW wFileData
;
2094 Py_UNICODE
*wnamebuf
;
2096 /* Overallocate for \\*.*\0 */
2097 len
= PyUnicode_GET_SIZE(po
);
2098 wnamebuf
= malloc((len
+ 5) * sizeof(wchar_t));
2103 wcscpy(wnamebuf
, PyUnicode_AS_UNICODE(po
));
2104 wch
= len
> 0 ? wnamebuf
[len
-1] : '\0';
2105 if (wch
!= L
'/' && wch
!= L
'\\' && wch
!= L
':')
2106 wnamebuf
[len
++] = L
'\\';
2107 wcscpy(wnamebuf
+ len
, L
"*.*");
2108 if ((d
= PyList_New(0)) == NULL
) {
2112 hFindFile
= FindFirstFileW(wnamebuf
, &wFileData
);
2113 if (hFindFile
== INVALID_HANDLE_VALUE
) {
2114 int error
= GetLastError();
2115 if (error
== ERROR_FILE_NOT_FOUND
) {
2120 win32_error_unicode("FindFirstFileW", wnamebuf
);
2125 /* Skip over . and .. */
2126 if (wcscmp(wFileData
.cFileName
, L
".") != 0 &&
2127 wcscmp(wFileData
.cFileName
, L
"..") != 0) {
2128 v
= PyUnicode_FromUnicode(wFileData
.cFileName
, wcslen(wFileData
.cFileName
));
2134 if (PyList_Append(d
, v
) != 0) {
2142 Py_BEGIN_ALLOW_THREADS
2143 result
= FindNextFileW(hFindFile
, &wFileData
);
2144 Py_END_ALLOW_THREADS
2145 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2146 it got to the end of the directory. */
2147 if (!result
&& GetLastError() != ERROR_NO_MORE_FILES
) {
2149 win32_error_unicode("FindNextFileW", wnamebuf
);
2150 FindClose(hFindFile
);
2154 } while (result
== TRUE
);
2156 if (FindClose(hFindFile
) == FALSE
) {
2158 win32_error_unicode("FindClose", wnamebuf
);
2165 /* Drop the argument parsing error as narrow strings
2171 if (!PyArg_ParseTuple(args
, "et#:listdir",
2172 Py_FileSystemDefaultEncoding
, &bufptr
, &len
))
2175 char ch
= namebuf
[len
-1];
2176 if (ch
!= SEP
&& ch
!= ALTSEP
&& ch
!= ':')
2177 namebuf
[len
++] = '/';
2179 strcpy(namebuf
+ len
, "*.*");
2181 if ((d
= PyList_New(0)) == NULL
)
2184 hFindFile
= FindFirstFile(namebuf
, &FileData
);
2185 if (hFindFile
== INVALID_HANDLE_VALUE
) {
2186 int error
= GetLastError();
2187 if (error
== ERROR_FILE_NOT_FOUND
)
2190 return win32_error("FindFirstFile", namebuf
);
2193 /* Skip over . and .. */
2194 if (strcmp(FileData
.cFileName
, ".") != 0 &&
2195 strcmp(FileData
.cFileName
, "..") != 0) {
2196 v
= PyString_FromString(FileData
.cFileName
);
2202 if (PyList_Append(d
, v
) != 0) {
2210 Py_BEGIN_ALLOW_THREADS
2211 result
= FindNextFile(hFindFile
, &FileData
);
2212 Py_END_ALLOW_THREADS
2213 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2214 it got to the end of the directory. */
2215 if (!result
&& GetLastError() != ERROR_NO_MORE_FILES
) {
2217 win32_error("FindNextFile", namebuf
);
2218 FindClose(hFindFile
);
2221 } while (result
== TRUE
);
2223 if (FindClose(hFindFile
) == FALSE
) {
2225 return win32_error("FindClose", namebuf
);
2230 #elif defined(PYOS_OS2)
2233 #define MAX_PATH CCHMAXPATH
2238 char namebuf
[MAX_PATH
+5];
2244 if (!PyArg_ParseTuple(args
, "t#:listdir", &name
, &len
))
2246 if (len
>= MAX_PATH
) {
2247 PyErr_SetString(PyExc_ValueError
, "path too long");
2250 strcpy(namebuf
, name
);
2251 for (pt
= namebuf
; *pt
; pt
++)
2254 if (namebuf
[len
-1] != SEP
)
2255 namebuf
[len
++] = SEP
;
2256 strcpy(namebuf
+ len
, "*.*");
2258 if ((d
= PyList_New(0)) == NULL
)
2261 rc
= DosFindFirst(namebuf
, /* Wildcard Pattern to Match */
2262 &hdir
, /* Handle to Use While Search Directory */
2263 FILE_READONLY
| FILE_HIDDEN
| FILE_SYSTEM
| FILE_DIRECTORY
,
2264 &ep
, sizeof(ep
), /* Structure to Receive Directory Entry */
2265 &srchcnt
, /* Max and Actual Count of Entries Per Iteration */
2266 FIL_STANDARD
); /* Format of Entry (EAs or Not) */
2268 if (rc
!= NO_ERROR
) {
2270 return posix_error_with_filename(name
);
2273 if (srchcnt
> 0) { /* If Directory is NOT Totally Empty, */
2275 if (ep
.achName
[0] == '.'
2276 && (ep
.achName
[1] == '\0' || (ep
.achName
[1] == '.' && ep
.achName
[2] == '\0')))
2277 continue; /* Skip Over "." and ".." Names */
2279 strcpy(namebuf
, ep
.achName
);
2281 /* Leave Case of Name Alone -- In Native Form */
2282 /* (Removed Forced Lowercasing Code) */
2284 v
= PyString_FromString(namebuf
);
2290 if (PyList_Append(d
, v
) != 0) {
2297 } while (DosFindNext(hdir
, &ep
, sizeof(ep
), &srchcnt
) == NO_ERROR
&& srchcnt
> 0);
2307 int arg_is_unicode
= 1;
2310 if (!PyArg_ParseTuple(args
, "U:listdir", &v
)) {
2314 if (!PyArg_ParseTuple(args
, "et:listdir", Py_FileSystemDefaultEncoding
, &name
))
2316 if ((dirp
= opendir(name
)) == NULL
) {
2317 return posix_error_with_allocated_filename(name
);
2319 if ((d
= PyList_New(0)) == NULL
) {
2326 Py_BEGIN_ALLOW_THREADS
2328 Py_END_ALLOW_THREADS
2335 return posix_error_with_allocated_filename(name
);
2338 if (ep
->d_name
[0] == '.' &&
2340 (ep
->d_name
[1] == '.' && NAMLEN(ep
) == 2)))
2342 v
= PyString_FromStringAndSize(ep
->d_name
, NAMLEN(ep
));
2348 #ifdef Py_USING_UNICODE
2349 if (arg_is_unicode
) {
2352 w
= PyUnicode_FromEncodedObject(v
,
2353 Py_FileSystemDefaultEncoding
,
2360 /* fall back to the original byte string, as
2361 discussed in patch #683592 */
2366 if (PyList_Append(d
, v
) != 0) {
2379 #endif /* which OS */
2380 } /* end of posix_listdir */
2383 /* A helper function for abspath on win32 */
2385 posix__getfullpathname(PyObject
*self
, PyObject
*args
)
2387 /* assume encoded strings wont more than double no of chars */
2388 char inbuf
[MAX_PATH
*2];
2389 char *inbufp
= inbuf
;
2390 Py_ssize_t insize
= sizeof(inbuf
);
2391 char outbuf
[MAX_PATH
*2];
2393 #ifdef Py_WIN_WIDE_FILENAMES
2394 if (unicode_file_names()) {
2395 PyUnicodeObject
*po
;
2396 if (PyArg_ParseTuple(args
, "U|:_getfullpathname", &po
)) {
2397 Py_UNICODE woutbuf
[MAX_PATH
*2];
2399 if (!GetFullPathNameW(PyUnicode_AS_UNICODE(po
),
2400 sizeof(woutbuf
)/sizeof(woutbuf
[0]),
2402 return win32_error("GetFullPathName", "");
2403 return PyUnicode_FromUnicode(woutbuf
, wcslen(woutbuf
));
2405 /* Drop the argument parsing error as narrow strings
2410 if (!PyArg_ParseTuple (args
, "et#:_getfullpathname",
2411 Py_FileSystemDefaultEncoding
, &inbufp
,
2414 if (!GetFullPathName(inbuf
, sizeof(outbuf
)/sizeof(outbuf
[0]),
2416 return win32_error("GetFullPathName", inbuf
);
2417 if (PyUnicode_Check(PyTuple_GetItem(args
, 0))) {
2418 return PyUnicode_Decode(outbuf
, strlen(outbuf
),
2419 Py_FileSystemDefaultEncoding
, NULL
);
2421 return PyString_FromString(outbuf
);
2422 } /* end of posix__getfullpathname */
2423 #endif /* MS_WINDOWS */
2425 PyDoc_STRVAR(posix_mkdir__doc__
,
2426 "mkdir(path [, mode=0777])\n\n\
2427 Create a directory.");
2430 posix_mkdir(PyObject
*self
, PyObject
*args
)
2436 #ifdef Py_WIN_WIDE_FILENAMES
2437 if (unicode_file_names()) {
2438 PyUnicodeObject
*po
;
2439 if (PyArg_ParseTuple(args
, "U|i:mkdir", &po
, &mode
)) {
2440 Py_BEGIN_ALLOW_THREADS
2441 /* PyUnicode_AS_UNICODE OK without thread lock as
2442 it is a simple dereference. */
2443 res
= CreateDirectoryW(PyUnicode_AS_UNICODE(po
), NULL
);
2444 Py_END_ALLOW_THREADS
2446 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po
));
2450 /* Drop the argument parsing error as narrow strings
2454 if (!PyArg_ParseTuple(args
, "et|i:mkdir",
2455 Py_FileSystemDefaultEncoding
, &path
, &mode
))
2457 Py_BEGIN_ALLOW_THREADS
2458 /* PyUnicode_AS_UNICODE OK without thread lock as
2459 it is a simple dereference. */
2460 res
= CreateDirectoryA(path
, NULL
);
2461 Py_END_ALLOW_THREADS
2463 win32_error("mkdir", path
);
2472 if (!PyArg_ParseTuple(args
, "et|i:mkdir",
2473 Py_FileSystemDefaultEncoding
, &path
, &mode
))
2475 Py_BEGIN_ALLOW_THREADS
2476 #if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
2479 res
= mkdir(path
, mode
);
2481 Py_END_ALLOW_THREADS
2483 return posix_error_with_allocated_filename(path
);
2491 /* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2492 #if defined(HAVE_SYS_RESOURCE_H)
2493 #include <sys/resource.h>
2498 PyDoc_STRVAR(posix_nice__doc__
,
2499 "nice(inc) -> new_priority\n\n\
2500 Decrease the priority of process by inc and return the new priority.");
2503 posix_nice(PyObject
*self
, PyObject
*args
)
2505 int increment
, value
;
2507 if (!PyArg_ParseTuple(args
, "i:nice", &increment
))
2510 /* There are two flavours of 'nice': one that returns the new
2511 priority (as required by almost all standards out there) and the
2512 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2513 the use of getpriority() to get the new priority.
2515 If we are of the nice family that returns the new priority, we
2516 need to clear errno before the call, and check if errno is filled
2517 before calling posix_error() on a returnvalue of -1, because the
2518 -1 may be the actual new priority! */
2521 value
= nice(increment
);
2522 #if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
2524 value
= getpriority(PRIO_PROCESS
, 0);
2526 if (value
== -1 && errno
!= 0)
2527 /* either nice() or getpriority() returned an error */
2528 return posix_error();
2529 return PyInt_FromLong((long) value
);
2531 #endif /* HAVE_NICE */
2533 PyDoc_STRVAR(posix_rename__doc__
,
2534 "rename(old, new)\n\n\
2535 Rename a file or directory.");
2538 posix_rename(PyObject
*self
, PyObject
*args
)
2544 if (unicode_file_names()) {
2545 if (!PyArg_ParseTuple(args
, "O&O&:rename",
2546 convert_to_unicode
, &o1
,
2547 convert_to_unicode
, &o2
))
2550 Py_BEGIN_ALLOW_THREADS
2551 result
= MoveFileW(PyUnicode_AsUnicode(o1
),
2552 PyUnicode_AsUnicode(o2
));
2553 Py_END_ALLOW_THREADS
2557 return win32_error("rename", NULL
);
2562 if (!PyArg_ParseTuple(args
, "ss:rename", &p1
, &p2
))
2564 Py_BEGIN_ALLOW_THREADS
2565 result
= MoveFileA(p1
, p2
);
2566 Py_END_ALLOW_THREADS
2568 return win32_error("rename", NULL
);
2572 return posix_2str(args
, "etet:rename", rename
);
2577 PyDoc_STRVAR(posix_rmdir__doc__
,
2579 Remove a directory.");
2582 posix_rmdir(PyObject
*self
, PyObject
*args
)
2585 return win32_1str(args
, "rmdir", "s:rmdir", RemoveDirectoryA
, "U:rmdir", RemoveDirectoryW
);
2587 return posix_1str(args
, "et:rmdir", rmdir
);
2592 PyDoc_STRVAR(posix_stat__doc__
,
2593 "stat(path) -> stat result\n\n\
2594 Perform a stat system call on the given path.");
2597 posix_stat(PyObject
*self
, PyObject
*args
)
2600 return posix_do_stat(self
, args
, "et:stat", STAT
, "U:stat", win32_wstat
);
2602 return posix_do_stat(self
, args
, "et:stat", STAT
, NULL
, NULL
);
2608 PyDoc_STRVAR(posix_system__doc__
,
2609 "system(command) -> exit_status\n\n\
2610 Execute the command (a string) in a subshell.");
2613 posix_system(PyObject
*self
, PyObject
*args
)
2617 if (!PyArg_ParseTuple(args
, "s:system", &command
))
2619 Py_BEGIN_ALLOW_THREADS
2620 sts
= system(command
);
2621 Py_END_ALLOW_THREADS
2622 return PyInt_FromLong(sts
);
2627 PyDoc_STRVAR(posix_umask__doc__
,
2628 "umask(new_mask) -> old_mask\n\n\
2629 Set the current numeric umask and return the previous umask.");
2632 posix_umask(PyObject
*self
, PyObject
*args
)
2635 if (!PyArg_ParseTuple(args
, "i:umask", &i
))
2639 return posix_error();
2640 return PyInt_FromLong((long)i
);
2644 PyDoc_STRVAR(posix_unlink__doc__
,
2646 Remove a file (same as remove(path)).");
2648 PyDoc_STRVAR(posix_remove__doc__
,
2650 Remove a file (same as unlink(path)).");
2653 posix_unlink(PyObject
*self
, PyObject
*args
)
2656 return win32_1str(args
, "remove", "s:remove", DeleteFileA
, "U:remove", DeleteFileW
);
2658 return posix_1str(args
, "et:remove", unlink
);
2664 PyDoc_STRVAR(posix_uname__doc__
,
2665 "uname() -> (sysname, nodename, release, version, machine)\n\n\
2666 Return a tuple identifying the current operating system.");
2669 posix_uname(PyObject
*self
, PyObject
*noargs
)
2674 Py_BEGIN_ALLOW_THREADS
2676 Py_END_ALLOW_THREADS
2678 return posix_error();
2679 return Py_BuildValue("(sssss)",
2686 #endif /* HAVE_UNAME */
2689 extract_time(PyObject
*t
, long* sec
, long* usec
)
2692 if (PyFloat_Check(t
)) {
2693 double tval
= PyFloat_AsDouble(t
);
2694 PyObject
*intobj
= Py_TYPE(t
)->tp_as_number
->nb_int(t
);
2697 intval
= PyInt_AsLong(intobj
);
2699 if (intval
== -1 && PyErr_Occurred())
2702 *usec
= (long)((tval
- intval
) * 1e6
); /* can't exceed 1000000 */
2704 /* If rounding gave us a negative number,
2709 intval
= PyInt_AsLong(t
);
2710 if (intval
== -1 && PyErr_Occurred())
2717 PyDoc_STRVAR(posix_utime__doc__
,
2718 "utime(path, (atime, mtime))\n\
2719 utime(path, None)\n\n\
2720 Set the access and modified time of the file to the given values. If the\n\
2721 second form is used, set the access and modified times to the current time.");
2724 posix_utime(PyObject
*self
, PyObject
*args
)
2726 #ifdef Py_WIN_WIDE_FILENAMES
2728 PyUnicodeObject
*obwpath
;
2729 wchar_t *wpath
= NULL
;
2732 long atimesec
, mtimesec
, ausec
, musec
;
2733 FILETIME atime
, mtime
;
2734 PyObject
*result
= NULL
;
2736 if (unicode_file_names()) {
2737 if (PyArg_ParseTuple(args
, "UO|:utime", &obwpath
, &arg
)) {
2738 wpath
= PyUnicode_AS_UNICODE(obwpath
);
2739 Py_BEGIN_ALLOW_THREADS
2740 hFile
= CreateFileW(wpath
, FILE_WRITE_ATTRIBUTES
, 0,
2741 NULL
, OPEN_EXISTING
,
2742 FILE_FLAG_BACKUP_SEMANTICS
, NULL
);
2743 Py_END_ALLOW_THREADS
2744 if (hFile
== INVALID_HANDLE_VALUE
)
2745 return win32_error_unicode("utime", wpath
);
2747 /* Drop the argument parsing error as narrow strings
2752 if (!PyArg_ParseTuple(args
, "etO:utime",
2753 Py_FileSystemDefaultEncoding
, &apath
, &arg
))
2755 Py_BEGIN_ALLOW_THREADS
2756 hFile
= CreateFileA(apath
, FILE_WRITE_ATTRIBUTES
, 0,
2757 NULL
, OPEN_EXISTING
,
2758 FILE_FLAG_BACKUP_SEMANTICS
, NULL
);
2759 Py_END_ALLOW_THREADS
2760 if (hFile
== INVALID_HANDLE_VALUE
) {
2761 win32_error("utime", apath
);
2768 if (arg
== Py_None
) {
2770 GetSystemTime(&now
);
2771 if (!SystemTimeToFileTime(&now
, &mtime
) ||
2772 !SystemTimeToFileTime(&now
, &atime
)) {
2773 win32_error("utime", NULL
);
2777 else if (!PyTuple_Check(arg
) || PyTuple_Size(arg
) != 2) {
2778 PyErr_SetString(PyExc_TypeError
,
2779 "utime() arg 2 must be a tuple (atime, mtime)");
2783 if (extract_time(PyTuple_GET_ITEM(arg
, 0),
2784 &atimesec
, &ausec
) == -1)
2786 time_t_to_FILE_TIME(atimesec
, 1000*ausec
, &atime
);
2787 if (extract_time(PyTuple_GET_ITEM(arg
, 1),
2788 &mtimesec
, &musec
) == -1)
2790 time_t_to_FILE_TIME(mtimesec
, 1000*musec
, &mtime
);
2792 if (!SetFileTime(hFile
, NULL
, &atime
, &mtime
)) {
2793 /* Avoid putting the file name into the error here,
2794 as that may confuse the user into believing that
2795 something is wrong with the file, when it also
2796 could be the time stamp that gives a problem. */
2797 win32_error("utime", NULL
);
2804 #else /* Py_WIN_WIDE_FILENAMES */
2807 long atime
, mtime
, ausec
, musec
;
2811 #if defined(HAVE_UTIMES)
2812 struct timeval buf
[2];
2813 #define ATIME buf[0].tv_sec
2814 #define MTIME buf[1].tv_sec
2815 #elif defined(HAVE_UTIME_H)
2816 /* XXX should define struct utimbuf instead, above */
2818 #define ATIME buf.actime
2819 #define MTIME buf.modtime
2820 #define UTIME_ARG &buf
2821 #else /* HAVE_UTIMES */
2823 #define ATIME buf[0]
2824 #define MTIME buf[1]
2825 #define UTIME_ARG buf
2826 #endif /* HAVE_UTIMES */
2829 if (!PyArg_ParseTuple(args
, "etO:utime",
2830 Py_FileSystemDefaultEncoding
, &path
, &arg
))
2832 if (arg
== Py_None
) {
2833 /* optional time values not given */
2834 Py_BEGIN_ALLOW_THREADS
2835 res
= utime(path
, NULL
);
2836 Py_END_ALLOW_THREADS
2838 else if (!PyTuple_Check(arg
) || PyTuple_Size(arg
) != 2) {
2839 PyErr_SetString(PyExc_TypeError
,
2840 "utime() arg 2 must be a tuple (atime, mtime)");
2845 if (extract_time(PyTuple_GET_ITEM(arg
, 0),
2846 &atime
, &ausec
) == -1) {
2850 if (extract_time(PyTuple_GET_ITEM(arg
, 1),
2851 &mtime
, &musec
) == -1) {
2858 buf
[0].tv_usec
= ausec
;
2859 buf
[1].tv_usec
= musec
;
2860 Py_BEGIN_ALLOW_THREADS
2861 res
= utimes(path
, buf
);
2862 Py_END_ALLOW_THREADS
2864 Py_BEGIN_ALLOW_THREADS
2865 res
= utime(path
, UTIME_ARG
);
2866 Py_END_ALLOW_THREADS
2867 #endif /* HAVE_UTIMES */
2870 return posix_error_with_allocated_filename(path
);
2878 #endif /* Py_WIN_WIDE_FILENAMES */
2882 /* Process operations */
2884 PyDoc_STRVAR(posix__exit__doc__
,
2886 Exit to the system with specified status, without normal exit processing.");
2889 posix__exit(PyObject
*self
, PyObject
*args
)
2892 if (!PyArg_ParseTuple(args
, "i:_exit", &sts
))
2895 return NULL
; /* Make gcc -Wall happy */
2898 #if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
2900 free_string_array(char **array
, Py_ssize_t count
)
2903 for (i
= 0; i
< count
; i
++)
2904 PyMem_Free(array
[i
]);
2911 PyDoc_STRVAR(posix_execv__doc__
,
2912 "execv(path, args)\n\n\
2913 Execute an executable path with arguments, replacing current process.\n\
2915 path: path of executable file\n\
2916 args: tuple or list of strings");
2919 posix_execv(PyObject
*self
, PyObject
*args
)
2925 PyObject
*(*getitem
)(PyObject
*, Py_ssize_t
);
2927 /* execv has two arguments: (path, argv), where
2928 argv is a list or tuple of strings. */
2930 if (!PyArg_ParseTuple(args
, "etO:execv",
2931 Py_FileSystemDefaultEncoding
,
2934 if (PyList_Check(argv
)) {
2935 argc
= PyList_Size(argv
);
2936 getitem
= PyList_GetItem
;
2938 else if (PyTuple_Check(argv
)) {
2939 argc
= PyTuple_Size(argv
);
2940 getitem
= PyTuple_GetItem
;
2943 PyErr_SetString(PyExc_TypeError
, "execv() arg 2 must be a tuple or list");
2948 argvlist
= PyMem_NEW(char *, argc
+1);
2949 if (argvlist
== NULL
) {
2951 return PyErr_NoMemory();
2953 for (i
= 0; i
< argc
; i
++) {
2954 if (!PyArg_Parse((*getitem
)(argv
, i
), "et",
2955 Py_FileSystemDefaultEncoding
,
2957 free_string_array(argvlist
, i
);
2958 PyErr_SetString(PyExc_TypeError
,
2959 "execv() arg 2 must contain only strings");
2965 argvlist
[argc
] = NULL
;
2967 execv(path
, argvlist
);
2969 /* If we get here it's definitely an error */
2971 free_string_array(argvlist
, argc
);
2973 return posix_error();
2977 PyDoc_STRVAR(posix_execve__doc__
,
2978 "execve(path, args, env)\n\n\
2979 Execute a path with arguments and environment, replacing current process.\n\
2981 path: path of executable file\n\
2982 args: tuple or list of arguments\n\
2983 env: dictionary of strings mapping to strings");
2986 posix_execve(PyObject
*self
, PyObject
*args
)
2989 PyObject
*argv
, *env
;
2992 PyObject
*key
, *val
, *keys
=NULL
, *vals
=NULL
;
2993 Py_ssize_t i
, pos
, argc
, envc
;
2994 PyObject
*(*getitem
)(PyObject
*, Py_ssize_t
);
2995 Py_ssize_t lastarg
= 0;
2997 /* execve has three arguments: (path, argv, env), where
2998 argv is a list or tuple of strings and env is a dictionary
2999 like posix.environ. */
3001 if (!PyArg_ParseTuple(args
, "etOO:execve",
3002 Py_FileSystemDefaultEncoding
,
3003 &path
, &argv
, &env
))
3005 if (PyList_Check(argv
)) {
3006 argc
= PyList_Size(argv
);
3007 getitem
= PyList_GetItem
;
3009 else if (PyTuple_Check(argv
)) {
3010 argc
= PyTuple_Size(argv
);
3011 getitem
= PyTuple_GetItem
;
3014 PyErr_SetString(PyExc_TypeError
,
3015 "execve() arg 2 must be a tuple or list");
3018 if (!PyMapping_Check(env
)) {
3019 PyErr_SetString(PyExc_TypeError
,
3020 "execve() arg 3 must be a mapping object");
3024 argvlist
= PyMem_NEW(char *, argc
+1);
3025 if (argvlist
== NULL
) {
3029 for (i
= 0; i
< argc
; i
++) {
3030 if (!PyArg_Parse((*getitem
)(argv
, i
),
3031 "et;execve() arg 2 must contain only strings",
3032 Py_FileSystemDefaultEncoding
,
3040 argvlist
[argc
] = NULL
;
3042 i
= PyMapping_Size(env
);
3045 envlist
= PyMem_NEW(char *, i
+ 1);
3046 if (envlist
== NULL
) {
3051 keys
= PyMapping_Keys(env
);
3052 vals
= PyMapping_Values(env
);
3055 if (!PyList_Check(keys
) || !PyList_Check(vals
)) {
3056 PyErr_SetString(PyExc_TypeError
,
3057 "execve(): env.keys() or env.values() is not a list");
3061 for (pos
= 0; pos
< i
; pos
++) {
3065 key
= PyList_GetItem(keys
, pos
);
3066 val
= PyList_GetItem(vals
, pos
);
3072 "s;execve() arg 3 contains a non-string key",
3076 "s;execve() arg 3 contains a non-string value",
3082 #if defined(PYOS_OS2)
3083 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
3084 if (stricmp(k
, "BEGINLIBPATH") != 0 && stricmp(k
, "ENDLIBPATH") != 0) {
3086 len
= PyString_Size(key
) + PyString_Size(val
) + 2;
3087 p
= PyMem_NEW(char, len
);
3092 PyOS_snprintf(p
, len
, "%s=%s", k
, v
);
3093 envlist
[envc
++] = p
;
3094 #if defined(PYOS_OS2)
3100 execve(path
, argvlist
, envlist
);
3102 /* If we get here it's definitely an error */
3104 (void) posix_error();
3108 PyMem_DEL(envlist
[envc
]);
3111 free_string_array(argvlist
, lastarg
);
3118 #endif /* HAVE_EXECV */
3122 PyDoc_STRVAR(posix_spawnv__doc__
,
3123 "spawnv(mode, path, args)\n\n\
3124 Execute the program 'path' in a new process.\n\
3126 mode: mode of process creation\n\
3127 path: path of executable file\n\
3128 args: tuple or list of strings");
3131 posix_spawnv(PyObject
*self
, PyObject
*args
)
3138 Py_intptr_t spawnval
;
3139 PyObject
*(*getitem
)(PyObject
*, Py_ssize_t
);
3141 /* spawnv has three arguments: (mode, path, argv), where
3142 argv is a list or tuple of strings. */
3144 if (!PyArg_ParseTuple(args
, "ietO:spawnv", &mode
,
3145 Py_FileSystemDefaultEncoding
,
3148 if (PyList_Check(argv
)) {
3149 argc
= PyList_Size(argv
);
3150 getitem
= PyList_GetItem
;
3152 else if (PyTuple_Check(argv
)) {
3153 argc
= PyTuple_Size(argv
);
3154 getitem
= PyTuple_GetItem
;
3157 PyErr_SetString(PyExc_TypeError
,
3158 "spawnv() arg 2 must be a tuple or list");
3163 argvlist
= PyMem_NEW(char *, argc
+1);
3164 if (argvlist
== NULL
) {
3166 return PyErr_NoMemory();
3168 for (i
= 0; i
< argc
; i
++) {
3169 if (!PyArg_Parse((*getitem
)(argv
, i
), "et",
3170 Py_FileSystemDefaultEncoding
,
3172 free_string_array(argvlist
, i
);
3175 "spawnv() arg 2 must contain only strings");
3180 argvlist
[argc
] = NULL
;
3182 #if defined(PYOS_OS2) && defined(PYCC_GCC)
3183 Py_BEGIN_ALLOW_THREADS
3184 spawnval
= spawnv(mode
, path
, argvlist
);
3185 Py_END_ALLOW_THREADS
3187 if (mode
== _OLD_P_OVERLAY
)
3190 Py_BEGIN_ALLOW_THREADS
3191 spawnval
= _spawnv(mode
, path
, argvlist
);
3192 Py_END_ALLOW_THREADS
3195 free_string_array(argvlist
, argc
);
3199 return posix_error();
3201 #if SIZEOF_LONG == SIZEOF_VOID_P
3202 return Py_BuildValue("l", (long) spawnval
);
3204 return Py_BuildValue("L", (PY_LONG_LONG
) spawnval
);
3209 PyDoc_STRVAR(posix_spawnve__doc__
,
3210 "spawnve(mode, path, args, env)\n\n\
3211 Execute the program 'path' in a new process.\n\
3213 mode: mode of process creation\n\
3214 path: path of executable file\n\
3215 args: tuple or list of arguments\n\
3216 env: dictionary of strings mapping to strings");
3219 posix_spawnve(PyObject
*self
, PyObject
*args
)
3222 PyObject
*argv
, *env
;
3225 PyObject
*key
, *val
, *keys
=NULL
, *vals
=NULL
, *res
=NULL
;
3226 int mode
, pos
, envc
;
3228 Py_intptr_t spawnval
;
3229 PyObject
*(*getitem
)(PyObject
*, Py_ssize_t
);
3230 Py_ssize_t lastarg
= 0;
3232 /* spawnve has four arguments: (mode, path, argv, env), where
3233 argv is a list or tuple of strings and env is a dictionary
3234 like posix.environ. */
3236 if (!PyArg_ParseTuple(args
, "ietOO:spawnve", &mode
,
3237 Py_FileSystemDefaultEncoding
,
3238 &path
, &argv
, &env
))
3240 if (PyList_Check(argv
)) {
3241 argc
= PyList_Size(argv
);
3242 getitem
= PyList_GetItem
;
3244 else if (PyTuple_Check(argv
)) {
3245 argc
= PyTuple_Size(argv
);
3246 getitem
= PyTuple_GetItem
;
3249 PyErr_SetString(PyExc_TypeError
,
3250 "spawnve() arg 2 must be a tuple or list");
3253 if (!PyMapping_Check(env
)) {
3254 PyErr_SetString(PyExc_TypeError
,
3255 "spawnve() arg 3 must be a mapping object");
3259 argvlist
= PyMem_NEW(char *, argc
+1);
3260 if (argvlist
== NULL
) {
3264 for (i
= 0; i
< argc
; i
++) {
3265 if (!PyArg_Parse((*getitem
)(argv
, i
),
3266 "et;spawnve() arg 2 must contain only strings",
3267 Py_FileSystemDefaultEncoding
,
3275 argvlist
[argc
] = NULL
;
3277 i
= PyMapping_Size(env
);
3280 envlist
= PyMem_NEW(char *, i
+ 1);
3281 if (envlist
== NULL
) {
3286 keys
= PyMapping_Keys(env
);
3287 vals
= PyMapping_Values(env
);
3290 if (!PyList_Check(keys
) || !PyList_Check(vals
)) {
3291 PyErr_SetString(PyExc_TypeError
,
3292 "spawnve(): env.keys() or env.values() is not a list");
3296 for (pos
= 0; pos
< i
; pos
++) {
3300 key
= PyList_GetItem(keys
, pos
);
3301 val
= PyList_GetItem(vals
, pos
);
3307 "s;spawnve() arg 3 contains a non-string key",
3311 "s;spawnve() arg 3 contains a non-string value",
3316 len
= PyString_Size(key
) + PyString_Size(val
) + 2;
3317 p
= PyMem_NEW(char, len
);
3322 PyOS_snprintf(p
, len
, "%s=%s", k
, v
);
3323 envlist
[envc
++] = p
;
3327 #if defined(PYOS_OS2) && defined(PYCC_GCC)
3328 Py_BEGIN_ALLOW_THREADS
3329 spawnval
= spawnve(mode
, path
, argvlist
, envlist
);
3330 Py_END_ALLOW_THREADS
3332 if (mode
== _OLD_P_OVERLAY
)
3335 Py_BEGIN_ALLOW_THREADS
3336 spawnval
= _spawnve(mode
, path
, argvlist
, envlist
);
3337 Py_END_ALLOW_THREADS
3341 (void) posix_error();
3343 #if SIZEOF_LONG == SIZEOF_VOID_P
3344 res
= Py_BuildValue("l", (long) spawnval
);
3346 res
= Py_BuildValue("L", (PY_LONG_LONG
) spawnval
);
3351 PyMem_DEL(envlist
[envc
]);
3354 free_string_array(argvlist
, lastarg
);
3362 /* OS/2 supports spawnvp & spawnvpe natively */
3363 #if defined(PYOS_OS2)
3364 PyDoc_STRVAR(posix_spawnvp__doc__
,
3365 "spawnvp(mode, file, args)\n\n\
3366 Execute the program 'file' in a new process, using the environment\n\
3367 search path to find the file.\n\
3369 mode: mode of process creation\n\
3370 file: executable file name\n\
3371 args: tuple or list of strings");
3374 posix_spawnvp(PyObject
*self
, PyObject
*args
)
3380 Py_intptr_t spawnval
;
3381 PyObject
*(*getitem
)(PyObject
*, Py_ssize_t
);
3383 /* spawnvp has three arguments: (mode, path, argv), where
3384 argv is a list or tuple of strings. */
3386 if (!PyArg_ParseTuple(args
, "ietO:spawnvp", &mode
,
3387 Py_FileSystemDefaultEncoding
,
3390 if (PyList_Check(argv
)) {
3391 argc
= PyList_Size(argv
);
3392 getitem
= PyList_GetItem
;
3394 else if (PyTuple_Check(argv
)) {
3395 argc
= PyTuple_Size(argv
);
3396 getitem
= PyTuple_GetItem
;
3399 PyErr_SetString(PyExc_TypeError
,
3400 "spawnvp() arg 2 must be a tuple or list");
3405 argvlist
= PyMem_NEW(char *, argc
+1);
3406 if (argvlist
== NULL
) {
3408 return PyErr_NoMemory();
3410 for (i
= 0; i
< argc
; i
++) {
3411 if (!PyArg_Parse((*getitem
)(argv
, i
), "et",
3412 Py_FileSystemDefaultEncoding
,
3414 free_string_array(argvlist
, i
);
3417 "spawnvp() arg 2 must contain only strings");
3422 argvlist
[argc
] = NULL
;
3424 Py_BEGIN_ALLOW_THREADS
3425 #if defined(PYCC_GCC)
3426 spawnval
= spawnvp(mode
, path
, argvlist
);
3428 spawnval
= _spawnvp(mode
, path
, argvlist
);
3430 Py_END_ALLOW_THREADS
3432 free_string_array(argvlist
, argc
);
3436 return posix_error();
3438 return Py_BuildValue("l", (long) spawnval
);
3442 PyDoc_STRVAR(posix_spawnvpe__doc__
,
3443 "spawnvpe(mode, file, args, env)\n\n\
3444 Execute the program 'file' in a new process, using the environment\n\
3445 search path to find the file.\n\
3447 mode: mode of process creation\n\
3448 file: executable file name\n\
3449 args: tuple or list of arguments\n\
3450 env: dictionary of strings mapping to strings");
3453 posix_spawnvpe(PyObject
*self
, PyObject
*args
)
3456 PyObject
*argv
, *env
;
3459 PyObject
*key
, *val
, *keys
=NULL
, *vals
=NULL
, *res
=NULL
;
3460 int mode
, i
, pos
, argc
, envc
;
3461 Py_intptr_t spawnval
;
3462 PyObject
*(*getitem
)(PyObject
*, Py_ssize_t
);
3465 /* spawnvpe has four arguments: (mode, path, argv, env), where
3466 argv is a list or tuple of strings and env is a dictionary
3467 like posix.environ. */
3469 if (!PyArg_ParseTuple(args
, "ietOO:spawnvpe", &mode
,
3470 Py_FileSystemDefaultEncoding
,
3471 &path
, &argv
, &env
))
3473 if (PyList_Check(argv
)) {
3474 argc
= PyList_Size(argv
);
3475 getitem
= PyList_GetItem
;
3477 else if (PyTuple_Check(argv
)) {
3478 argc
= PyTuple_Size(argv
);
3479 getitem
= PyTuple_GetItem
;
3482 PyErr_SetString(PyExc_TypeError
,
3483 "spawnvpe() arg 2 must be a tuple or list");
3486 if (!PyMapping_Check(env
)) {
3487 PyErr_SetString(PyExc_TypeError
,
3488 "spawnvpe() arg 3 must be a mapping object");
3492 argvlist
= PyMem_NEW(char *, argc
+1);
3493 if (argvlist
== NULL
) {
3497 for (i
= 0; i
< argc
; i
++) {
3498 if (!PyArg_Parse((*getitem
)(argv
, i
),
3499 "et;spawnvpe() arg 2 must contain only strings",
3500 Py_FileSystemDefaultEncoding
,
3508 argvlist
[argc
] = NULL
;
3510 i
= PyMapping_Size(env
);
3513 envlist
= PyMem_NEW(char *, i
+ 1);
3514 if (envlist
== NULL
) {
3519 keys
= PyMapping_Keys(env
);
3520 vals
= PyMapping_Values(env
);
3523 if (!PyList_Check(keys
) || !PyList_Check(vals
)) {
3524 PyErr_SetString(PyExc_TypeError
,
3525 "spawnvpe(): env.keys() or env.values() is not a list");
3529 for (pos
= 0; pos
< i
; pos
++) {
3533 key
= PyList_GetItem(keys
, pos
);
3534 val
= PyList_GetItem(vals
, pos
);
3540 "s;spawnvpe() arg 3 contains a non-string key",
3544 "s;spawnvpe() arg 3 contains a non-string value",
3549 len
= PyString_Size(key
) + PyString_Size(val
) + 2;
3550 p
= PyMem_NEW(char, len
);
3555 PyOS_snprintf(p
, len
, "%s=%s", k
, v
);
3556 envlist
[envc
++] = p
;
3560 Py_BEGIN_ALLOW_THREADS
3561 #if defined(PYCC_GCC)
3562 spawnval
= spawnvpe(mode
, path
, argvlist
, envlist
);
3564 spawnval
= _spawnvpe(mode
, path
, argvlist
, envlist
);
3566 Py_END_ALLOW_THREADS
3569 (void) posix_error();
3571 res
= Py_BuildValue("l", (long) spawnval
);
3575 PyMem_DEL(envlist
[envc
]);
3578 free_string_array(argvlist
, lastarg
);
3585 #endif /* PYOS_OS2 */
3586 #endif /* HAVE_SPAWNV */
3590 PyDoc_STRVAR(posix_fork1__doc__
,
3591 "fork1() -> pid\n\n\
3592 Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3594 Return 0 to child process and PID of child to parent process.");
3597 posix_fork1(PyObject
*self
, PyObject
*noargs
)
3599 pid_t pid
= fork1();
3601 return posix_error();
3604 return PyInt_FromLong(pid
);
3610 PyDoc_STRVAR(posix_fork__doc__
,
3612 Fork a child process.\n\
3613 Return 0 to child process and PID of child to parent process.");
3616 posix_fork(PyObject
*self
, PyObject
*noargs
)
3620 return posix_error();
3623 return PyInt_FromLong(pid
);
3627 /* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
3628 /* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3629 #if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
3630 #define DEV_PTY_FILE "/dev/ptc"
3631 #define HAVE_DEV_PTMX
3633 #define DEV_PTY_FILE "/dev/ptmx"
3636 #if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
3640 #ifdef HAVE_LIBUTIL_H
3641 #include <libutil.h>
3642 #endif /* HAVE_LIBUTIL_H */
3643 #endif /* HAVE_PTY_H */
3644 #ifdef HAVE_STROPTS_H
3645 #include <stropts.h>
3647 #endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
3649 #if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
3650 PyDoc_STRVAR(posix_openpty__doc__
,
3651 "openpty() -> (master_fd, slave_fd)\n\n\
3652 Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
3655 posix_openpty(PyObject
*self
, PyObject
*noargs
)
3657 int master_fd
, slave_fd
;
3658 #ifndef HAVE_OPENPTY
3661 #if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
3662 PyOS_sighandler_t sig_saved
;
3664 extern char *ptsname(int fildes
);
3669 if (openpty(&master_fd
, &slave_fd
, NULL
, NULL
, NULL
) != 0)
3670 return posix_error();
3671 #elif defined(HAVE__GETPTY)
3672 slave_name
= _getpty(&master_fd
, O_RDWR
, 0666, 0);
3673 if (slave_name
== NULL
)
3674 return posix_error();
3676 slave_fd
= open(slave_name
, O_RDWR
);
3678 return posix_error();
3680 master_fd
= open(DEV_PTY_FILE
, O_RDWR
| O_NOCTTY
); /* open master */
3682 return posix_error();
3683 sig_saved
= PyOS_setsig(SIGCHLD
, SIG_DFL
);
3684 /* change permission of slave */
3685 if (grantpt(master_fd
) < 0) {
3686 PyOS_setsig(SIGCHLD
, sig_saved
);
3687 return posix_error();
3690 if (unlockpt(master_fd
) < 0) {
3691 PyOS_setsig(SIGCHLD
, sig_saved
);
3692 return posix_error();
3694 PyOS_setsig(SIGCHLD
, sig_saved
);
3695 slave_name
= ptsname(master_fd
); /* get name of slave */
3696 if (slave_name
== NULL
)
3697 return posix_error();
3698 slave_fd
= open(slave_name
, O_RDWR
| O_NOCTTY
); /* open slave */
3700 return posix_error();
3701 #if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
3702 ioctl(slave_fd
, I_PUSH
, "ptem"); /* push ptem */
3703 ioctl(slave_fd
, I_PUSH
, "ldterm"); /* push ldterm */
3705 ioctl(slave_fd
, I_PUSH
, "ttcompat"); /* push ttcompat */
3707 #endif /* HAVE_CYGWIN */
3708 #endif /* HAVE_OPENPTY */
3710 return Py_BuildValue("(ii)", master_fd
, slave_fd
);
3713 #endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
3716 PyDoc_STRVAR(posix_forkpty__doc__
,
3717 "forkpty() -> (pid, master_fd)\n\n\
3718 Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
3719 Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
3720 To both, return fd of newly opened pseudo-terminal.\n");
3723 posix_forkpty(PyObject
*self
, PyObject
*noargs
)
3728 pid
= forkpty(&master_fd
, NULL
, NULL
, NULL
);
3730 return posix_error();
3733 return Py_BuildValue("(li)", pid
, master_fd
);
3738 PyDoc_STRVAR(posix_getegid__doc__
,
3739 "getegid() -> egid\n\n\
3740 Return the current process's effective group id.");
3743 posix_getegid(PyObject
*self
, PyObject
*noargs
)
3745 return PyInt_FromLong((long)getegid());
3751 PyDoc_STRVAR(posix_geteuid__doc__
,
3752 "geteuid() -> euid\n\n\
3753 Return the current process's effective user id.");
3756 posix_geteuid(PyObject
*self
, PyObject
*noargs
)
3758 return PyInt_FromLong((long)geteuid());
3764 PyDoc_STRVAR(posix_getgid__doc__
,
3765 "getgid() -> gid\n\n\
3766 Return the current process's group id.");
3769 posix_getgid(PyObject
*self
, PyObject
*noargs
)
3771 return PyInt_FromLong((long)getgid());
3776 PyDoc_STRVAR(posix_getpid__doc__
,
3777 "getpid() -> pid\n\n\
3778 Return the current process id");
3781 posix_getpid(PyObject
*self
, PyObject
*noargs
)
3783 return PyInt_FromLong((long)getpid());
3787 #ifdef HAVE_GETGROUPS
3788 PyDoc_STRVAR(posix_getgroups__doc__
,
3789 "getgroups() -> list of group IDs\n\n\
3790 Return list of supplemental group IDs for the process.");
3793 posix_getgroups(PyObject
*self
, PyObject
*noargs
)
3795 PyObject
*result
= NULL
;
3798 #define MAX_GROUPS NGROUPS_MAX
3800 /* defined to be 16 on Solaris7, so this should be a small number */
3801 #define MAX_GROUPS 64
3803 gid_t grouplist
[MAX_GROUPS
];
3806 n
= getgroups(MAX_GROUPS
, grouplist
);
3810 result
= PyList_New(n
);
3811 if (result
!= NULL
) {
3813 for (i
= 0; i
< n
; ++i
) {
3814 PyObject
*o
= PyInt_FromLong((long)grouplist
[i
]);
3820 PyList_SET_ITEM(result
, i
, o
);
3830 PyDoc_STRVAR(posix_getpgid__doc__
,
3831 "getpgid(pid) -> pgid\n\n\
3832 Call the system call getpgid().");
3835 posix_getpgid(PyObject
*self
, PyObject
*args
)
3838 if (!PyArg_ParseTuple(args
, "i:getpgid", &pid
))
3840 pgid
= getpgid(pid
);
3842 return posix_error();
3843 return PyInt_FromLong((long)pgid
);
3845 #endif /* HAVE_GETPGID */
3849 PyDoc_STRVAR(posix_getpgrp__doc__
,
3850 "getpgrp() -> pgrp\n\n\
3851 Return the current process group id.");
3854 posix_getpgrp(PyObject
*self
, PyObject
*noargs
)
3856 #ifdef GETPGRP_HAVE_ARG
3857 return PyInt_FromLong((long)getpgrp(0));
3858 #else /* GETPGRP_HAVE_ARG */
3859 return PyInt_FromLong((long)getpgrp());
3860 #endif /* GETPGRP_HAVE_ARG */
3862 #endif /* HAVE_GETPGRP */
3866 PyDoc_STRVAR(posix_setpgrp__doc__
,
3868 Make this process a session leader.");
3871 posix_setpgrp(PyObject
*self
, PyObject
*noargs
)
3873 #ifdef SETPGRP_HAVE_ARG
3874 if (setpgrp(0, 0) < 0)
3875 #else /* SETPGRP_HAVE_ARG */
3877 #endif /* SETPGRP_HAVE_ARG */
3878 return posix_error();
3883 #endif /* HAVE_SETPGRP */
3886 PyDoc_STRVAR(posix_getppid__doc__
,
3887 "getppid() -> ppid\n\n\
3888 Return the parent's process id.");
3891 posix_getppid(PyObject
*self
, PyObject
*noargs
)
3893 return PyInt_FromLong(getppid());
3898 #ifdef HAVE_GETLOGIN
3899 PyDoc_STRVAR(posix_getlogin__doc__
,
3900 "getlogin() -> string\n\n\
3901 Return the actual login name.");
3904 posix_getlogin(PyObject
*self
, PyObject
*noargs
)
3906 PyObject
*result
= NULL
;
3908 int old_errno
= errno
;
3916 PyErr_SetString(PyExc_OSError
,
3917 "unable to determine login name");
3920 result
= PyString_FromString(name
);
3928 PyDoc_STRVAR(posix_getuid__doc__
,
3929 "getuid() -> uid\n\n\
3930 Return the current process's user id.");
3933 posix_getuid(PyObject
*self
, PyObject
*noargs
)
3935 return PyInt_FromLong((long)getuid());
3941 PyDoc_STRVAR(posix_kill__doc__
,
3942 "kill(pid, sig)\n\n\
3943 Kill a process with a signal.");
3946 posix_kill(PyObject
*self
, PyObject
*args
)
3950 if (!PyArg_ParseTuple(args
, "ii:kill", &pid
, &sig
))
3952 #if defined(PYOS_OS2) && !defined(PYCC_GCC)
3953 if (sig
== XCPT_SIGNAL_INTR
|| sig
== XCPT_SIGNAL_BREAK
) {
3955 if ((rc
= DosSendSignalException(pid
, sig
)) != NO_ERROR
)
3956 return os2_error(rc
);
3958 } else if (sig
== XCPT_SIGNAL_KILLPROC
) {
3960 if ((rc
= DosKillProcess(DKP_PROCESS
, pid
)) != NO_ERROR
)
3961 return os2_error(rc
);
3964 return NULL
; /* Unrecognized Signal Requested */
3966 if (kill(pid
, sig
) == -1)
3967 return posix_error();
3975 PyDoc_STRVAR(posix_killpg__doc__
,
3976 "killpg(pgid, sig)\n\n\
3977 Kill a process group with a signal.");
3980 posix_killpg(PyObject
*self
, PyObject
*args
)
3983 if (!PyArg_ParseTuple(args
, "ii:killpg", &pgid
, &sig
))
3985 if (killpg(pgid
, sig
) == -1)
3986 return posix_error();
3994 #ifdef HAVE_SYS_LOCK_H
3995 #include <sys/lock.h>
3998 PyDoc_STRVAR(posix_plock__doc__
,
4000 Lock program segments into memory.");
4003 posix_plock(PyObject
*self
, PyObject
*args
)
4006 if (!PyArg_ParseTuple(args
, "i:plock", &op
))
4008 if (plock(op
) == -1)
4009 return posix_error();
4017 PyDoc_STRVAR(posix_popen__doc__
,
4018 "popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
4019 Open a pipe to/from a command returning a file object.");
4021 #if defined(PYOS_OS2)
4022 #if defined(PYCC_VACPP)
4024 async_system(const char *command
)
4026 char errormsg
[256], args
[1024];
4030 char *shell
= getenv("COMSPEC");
4034 /* avoid overflowing the argument buffer */
4035 if (strlen(shell
) + 3 + strlen(command
) >= 1024)
4036 return ERROR_NOT_ENOUGH_MEMORY
4039 strcat(args
, shell
);
4040 strcat(args
, "/c ");
4041 strcat(args
, command
);
4043 /* execute asynchronously, inheriting the environment */
4044 rc
= DosExecPgm(errormsg
,
4055 popen(const char *command
, const char *mode
, int pipesize
, int *err
)
4061 /* mode determines which of stdin or stdout is reconnected to
4062 * the pipe to the child
4064 if (strchr(mode
, 'r') != NULL
) {
4065 tgt_fd
= 1; /* stdout */
4066 } else if (strchr(mode
, 'w')) {
4067 tgt_fd
= 0; /* stdin */
4069 *err
= ERROR_INVALID_ACCESS
;
4073 /* setup the pipe */
4074 if ((rc
= DosCreatePipe(&pipeh
[0], &pipeh
[1], pipesize
)) != NO_ERROR
) {
4079 /* prevent other threads accessing stdio */
4082 /* reconnect stdio and execute child */
4085 if (dup2(pipeh
[tgtfd
], tgtfd
) == 0) {
4086 DosClose(pipeh
[tgtfd
]);
4087 rc
= async_system(command
);
4094 /* allow other threads access to stdio */
4097 /* if execution of child was successful return file stream */
4099 return fdopen(pipeh
[1 - tgtfd
], mode
);
4101 DosClose(pipeh
[1 - tgtfd
]);
4108 posix_popen(PyObject
*self
, PyObject
*args
)
4112 int err
, bufsize
= -1;
4115 if (!PyArg_ParseTuple(args
, "s|si:popen", &name
, &mode
, &bufsize
))
4117 Py_BEGIN_ALLOW_THREADS
4118 fp
= popen(name
, mode
, (bufsize
> 0) ? bufsize
: 4096, &err
);
4119 Py_END_ALLOW_THREADS
4121 return os2_error(err
);
4123 f
= PyFile_FromFile(fp
, name
, mode
, fclose
);
4125 PyFile_SetBufSize(f
, bufsize
);
4129 #elif defined(PYCC_GCC)
4131 /* standard posix version of popen() support */
4133 posix_popen(PyObject
*self
, PyObject
*args
)
4140 if (!PyArg_ParseTuple(args
, "s|si:popen", &name
, &mode
, &bufsize
))
4142 Py_BEGIN_ALLOW_THREADS
4143 fp
= popen(name
, mode
);
4144 Py_END_ALLOW_THREADS
4146 return posix_error();
4147 f
= PyFile_FromFile(fp
, name
, mode
, pclose
);
4149 PyFile_SetBufSize(f
, bufsize
);
4153 /* fork() under OS/2 has lots'o'warts
4154 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
4155 * most of this code is a ripoff of the win32 code, but using the
4156 * capabilities of EMX's C library routines
4159 /* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
4165 static PyObject
*_PyPopen(char *, int, int, int);
4166 static int _PyPclose(FILE *file
);
4169 * Internal dictionary mapping popen* file pointers to process handles,
4170 * for use when retrieving the process exit code. See _PyPclose() below
4171 * for more information on this dictionary's use.
4173 static PyObject
*_PyPopenProcs
= NULL
;
4175 /* os2emx version of popen2()
4177 * The result of this function is a pipe (file) connected to the
4178 * process's stdin, and a pipe connected to the process's stdout.
4182 os2emx_popen2(PyObject
*self
, PyObject
*args
)
4190 if (!PyArg_ParseTuple(args
, "s|si:popen2", &cmdstring
, &mode
, &bufsize
))
4195 else if (*mode
!= 'b') {
4196 PyErr_SetString(PyExc_ValueError
, "mode must be 't' or 'b'");
4201 f
= _PyPopen(cmdstring
, tm
, POPEN_2
, bufsize
);
4207 * Variation on os2emx.popen2
4209 * The result of this function is 3 pipes - the process's stdin,
4214 os2emx_popen3(PyObject
*self
, PyObject
*args
)
4222 if (!PyArg_ParseTuple(args
, "s|si:popen3", &cmdstring
, &mode
, &bufsize
))
4227 else if (*mode
!= 'b') {
4228 PyErr_SetString(PyExc_ValueError
, "mode must be 't' or 'b'");
4233 f
= _PyPopen(cmdstring
, tm
, POPEN_3
, bufsize
);
4239 * Variation on os2emx.popen2
4241 * The result of this function is 2 pipes - the processes stdin,
4242 * and stdout+stderr combined as a single pipe.
4246 os2emx_popen4(PyObject
*self
, PyObject
*args
)
4254 if (!PyArg_ParseTuple(args
, "s|si:popen4", &cmdstring
, &mode
, &bufsize
))
4259 else if (*mode
!= 'b') {
4260 PyErr_SetString(PyExc_ValueError
, "mode must be 't' or 'b'");
4265 f
= _PyPopen(cmdstring
, tm
, POPEN_4
, bufsize
);
4270 /* a couple of structures for convenient handling of multiple
4271 * file handles and pipes
4285 /* The following code is derived from the win32 code */
4288 _PyPopen(char *cmdstring
, int mode
, int n
, int bufsize
)
4290 struct file_ref stdio
[3];
4291 struct pipe_ref p_fd
[3];
4293 int file_count
, i
, pipe_err
;
4295 char *shell
, *sh_name
, *opt
, *rd_mode
, *wr_mode
;
4296 PyObject
*f
, *p_f
[3];
4298 /* file modes for subsequent fdopen's on pipe handles */
4310 /* prepare shell references */
4311 if ((shell
= getenv("EMXSHELL")) == NULL
)
4312 if ((shell
= getenv("COMSPEC")) == NULL
)
4315 return posix_error();
4318 sh_name
= _getname(shell
);
4319 if (stricmp(sh_name
, "cmd.exe") == 0 || stricmp(sh_name
, "4os2.exe") == 0)
4324 /* save current stdio fds + their flags, and set not inheritable */
4326 while (pipe_err
>= 0 && i
< 3)
4328 pipe_err
= stdio
[i
].handle
= dup(i
);
4329 stdio
[i
].flags
= fcntl(i
, F_GETFD
, 0);
4330 fcntl(stdio
[i
].handle
, F_SETFD
, stdio
[i
].flags
| FD_CLOEXEC
);
4335 /* didn't get them all saved - clean up and bail out */
4336 int saved_err
= errno
;
4339 close(stdio
[i
].handle
);
4342 return posix_error();
4345 /* create pipe ends */
4350 while ((pipe_err
== 0) && (i
< file_count
))
4351 pipe_err
= pipe((int *)&p_fd
[i
++]);
4354 /* didn't get them all made - clean up and bail out */
4361 return posix_error();
4364 /* change the actual standard IO streams over temporarily,
4365 * making the retained pipe ends non-inheritable
4370 if (dup2(p_fd
[0].rd
, 0) == 0)
4373 i
= fcntl(p_fd
[0].wr
, F_GETFD
, 0);
4374 fcntl(p_fd
[0].wr
, F_SETFD
, i
| FD_CLOEXEC
);
4375 if ((p_s
[0] = fdopen(p_fd
[0].wr
, wr_mode
)) == NULL
)
4389 if (dup2(p_fd
[1].wr
, 1) == 1)
4392 i
= fcntl(p_fd
[1].rd
, F_GETFD
, 0);
4393 fcntl(p_fd
[1].rd
, F_SETFD
, i
| FD_CLOEXEC
);
4394 if ((p_s
[1] = fdopen(p_fd
[1].rd
, rd_mode
)) == NULL
)
4406 /* - stderr, as required */
4412 if (dup2(p_fd
[2].wr
, 2) == 2)
4415 i
= fcntl(p_fd
[2].rd
, F_GETFD
, 0);
4416 fcntl(p_fd
[2].rd
, F_SETFD
, i
| FD_CLOEXEC
);
4417 if ((p_s
[2] = fdopen(p_fd
[2].rd
, rd_mode
)) == NULL
)
4432 if (dup2(1, 2) != 2)
4440 /* spawn the child process */
4443 pipe_pid
= spawnlp(P_NOWAIT
, shell
, shell
, opt
, cmdstring
, (char *)0);
4450 /* save the PID into the FILE structure
4451 * NOTE: this implementation doesn't actually
4452 * take advantage of this, but do it for
4453 * completeness - AIM Apr01
4455 for (i
= 0; i
< file_count
; i
++)
4456 p_s
[i
]->_pid
= pipe_pid
;
4460 /* reset standard IO to normal */
4461 for (i
= 0; i
< 3; i
++)
4463 dup2(stdio
[i
].handle
, i
);
4464 fcntl(i
, F_SETFD
, stdio
[i
].flags
);
4465 close(stdio
[i
].handle
);
4468 /* if any remnant problems, clean up and bail out */
4471 for (i
= 0; i
< 3; i
++)
4477 return posix_error_with_filename(cmdstring
);
4480 /* build tuple of file objects to return */
4481 if ((p_f
[0] = PyFile_FromFile(p_s
[0], cmdstring
, wr_mode
, _PyPclose
)) != NULL
)
4482 PyFile_SetBufSize(p_f
[0], bufsize
);
4483 if ((p_f
[1] = PyFile_FromFile(p_s
[1], cmdstring
, rd_mode
, _PyPclose
)) != NULL
)
4484 PyFile_SetBufSize(p_f
[1], bufsize
);
4487 if ((p_f
[2] = PyFile_FromFile(p_s
[2], cmdstring
, rd_mode
, _PyPclose
)) != NULL
)
4488 PyFile_SetBufSize(p_f
[0], bufsize
);
4489 f
= PyTuple_Pack(3, p_f
[0], p_f
[1], p_f
[2]);
4492 f
= PyTuple_Pack(2, p_f
[0], p_f
[1]);
4495 * Insert the files we've created into the process dictionary
4496 * all referencing the list with the process handle and the
4497 * initial number of files (see description below in _PyPclose).
4498 * Since if _PyPclose later tried to wait on a process when all
4499 * handles weren't closed, it could create a deadlock with the
4500 * child, we spend some energy here to try to ensure that we
4501 * either insert all file handles into the dictionary or none
4502 * at all. It's a little clumsy with the various popen modes
4503 * and variable number of files involved.
4507 _PyPopenProcs
= PyDict_New();
4512 PyObject
*procObj
, *pidObj
, *intObj
, *fileObj
[3];
4515 fileObj
[0] = fileObj
[1] = fileObj
[2] = NULL
;
4516 ins_rc
[0] = ins_rc
[1] = ins_rc
[2] = 0;
4518 procObj
= PyList_New(2);
4519 pidObj
= PyInt_FromLong((long) pipe_pid
);
4520 intObj
= PyInt_FromLong((long) file_count
);
4522 if (procObj
&& pidObj
&& intObj
)
4524 PyList_SetItem(procObj
, 0, pidObj
);
4525 PyList_SetItem(procObj
, 1, intObj
);
4527 fileObj
[0] = PyLong_FromVoidPtr(p_s
[0]);
4530 ins_rc
[0] = PyDict_SetItem(_PyPopenProcs
,
4534 fileObj
[1] = PyLong_FromVoidPtr(p_s
[1]);
4537 ins_rc
[1] = PyDict_SetItem(_PyPopenProcs
,
4541 if (file_count
>= 3)
4543 fileObj
[2] = PyLong_FromVoidPtr(p_s
[2]);
4546 ins_rc
[2] = PyDict_SetItem(_PyPopenProcs
,
4552 if (ins_rc
[0] < 0 || !fileObj
[0] ||
4553 ins_rc
[1] < 0 || (file_count
> 1 && !fileObj
[1]) ||
4554 ins_rc
[2] < 0 || (file_count
> 2 && !fileObj
[2]))
4556 /* Something failed - remove any dictionary
4557 * entries that did make it.
4559 if (!ins_rc
[0] && fileObj
[0])
4561 PyDict_DelItem(_PyPopenProcs
,
4564 if (!ins_rc
[1] && fileObj
[1])
4566 PyDict_DelItem(_PyPopenProcs
,
4569 if (!ins_rc
[2] && fileObj
[2])
4571 PyDict_DelItem(_PyPopenProcs
,
4578 * Clean up our localized references for the dictionary keys
4579 * and value since PyDict_SetItem will Py_INCREF any copies
4580 * that got placed in the dictionary.
4582 Py_XDECREF(procObj
);
4583 Py_XDECREF(fileObj
[0]);
4584 Py_XDECREF(fileObj
[1]);
4585 Py_XDECREF(fileObj
[2]);
4588 /* Child is launched. */
4593 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4594 * exit code for the child process and return as a result of the close.
4596 * This function uses the _PyPopenProcs dictionary in order to map the
4597 * input file pointer to information about the process that was
4598 * originally created by the popen* call that created the file pointer.
4599 * The dictionary uses the file pointer as a key (with one entry
4600 * inserted for each file returned by the original popen* call) and a
4601 * single list object as the value for all files from a single call.
4602 * The list object contains the Win32 process handle at [0], and a file
4603 * count at [1], which is initialized to the total number of file
4604 * handles using that list.
4606 * This function closes whichever handle it is passed, and decrements
4607 * the file count in the dictionary for the process handle pointed to
4608 * by this file. On the last close (when the file count reaches zero),
4609 * this function will wait for the child process and then return its
4610 * exit code as the result of the close() operation. This permits the
4611 * files to be closed in any order - it is always the close() of the
4612 * final handle that will return the exit code.
4614 * NOTE: This function is currently called with the GIL released.
4615 * hence we use the GILState API to manage our state.
4618 static int _PyPclose(FILE *file
)
4623 PyObject
*procObj
, *pidObj
, *intObj
, *fileObj
;
4626 PyGILState_STATE state
;
4629 /* Close the file handle first, to ensure it can't block the
4630 * child from exiting if it's the last handle.
4632 result
= fclose(file
);
4635 state
= PyGILState_Ensure();
4639 if ((fileObj
= PyLong_FromVoidPtr(file
)) != NULL
&&
4640 (procObj
= PyDict_GetItem(_PyPopenProcs
,
4641 fileObj
)) != NULL
&&
4642 (pidObj
= PyList_GetItem(procObj
,0)) != NULL
&&
4643 (intObj
= PyList_GetItem(procObj
,1)) != NULL
)
4645 pipe_pid
= (int) PyInt_AsLong(pidObj
);
4646 file_count
= (int) PyInt_AsLong(intObj
);
4650 /* Still other files referencing process */
4652 PyList_SetItem(procObj
,1,
4653 PyInt_FromLong((long) file_count
));
4657 /* Last file for this process */
4658 if (result
!= EOF
&&
4659 waitpid(pipe_pid
, &exit_code
, 0) == pipe_pid
)
4661 /* extract exit status */
4662 if (WIFEXITED(exit_code
))
4664 result
= WEXITSTATUS(exit_code
);
4674 /* Indicate failure - this will cause the file object
4675 * to raise an I/O error and translate the last
4676 * error code from errno. We do have a problem with
4677 * last errors that overlap the normal errno table,
4678 * but that's a consistent problem with the file object.
4684 /* Remove this file pointer from dictionary */
4685 PyDict_DelItem(_PyPopenProcs
, fileObj
);
4687 if (PyDict_Size(_PyPopenProcs
) == 0)
4689 Py_DECREF(_PyPopenProcs
);
4690 _PyPopenProcs
= NULL
;
4693 } /* if object retrieval ok */
4695 Py_XDECREF(fileObj
);
4696 } /* if _PyPopenProcs */
4699 PyGILState_Release(state
);
4704 #endif /* PYCC_??? */
4706 #elif defined(MS_WINDOWS)
4709 * Portable 'popen' replacement for Win32.
4711 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
4712 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
4713 * Return code handling by David Bolen <db3l@fitlinxx.com>.
4720 /* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
4726 static PyObject
*_PyPopen(char *, int, int);
4727 static int _PyPclose(FILE *file
);
4730 * Internal dictionary mapping popen* file pointers to process handles,
4731 * for use when retrieving the process exit code. See _PyPclose() below
4732 * for more information on this dictionary's use.
4734 static PyObject
*_PyPopenProcs
= NULL
;
4737 /* popen that works from a GUI.
4739 * The result of this function is a pipe (file) connected to the
4740 * processes stdin or stdout, depending on the requested mode.
4744 posix_popen(PyObject
*self
, PyObject
*args
)
4752 if (!PyArg_ParseTuple(args
, "s|si:popen", &cmdstring
, &mode
, &bufsize
))
4757 else if (*mode
!= 'w') {
4758 PyErr_SetString(PyExc_ValueError
, "popen() arg 2 must be 'r' or 'w'");
4763 if (bufsize
!= -1) {
4764 PyErr_SetString(PyExc_ValueError
, "popen() arg 3 must be -1");
4768 if (*(mode
+1) == 't')
4769 f
= _PyPopen(cmdstring
, tm
| _O_TEXT
, POPEN_1
);
4770 else if (*(mode
+1) == 'b')
4771 f
= _PyPopen(cmdstring
, tm
| _O_BINARY
, POPEN_1
);
4773 f
= _PyPopen(cmdstring
, tm
| _O_TEXT
, POPEN_1
);
4778 /* Variation on win32pipe.popen
4780 * The result of this function is a pipe (file) connected to the
4781 * process's stdin, and a pipe connected to the process's stdout.
4785 win32_popen2(PyObject
*self
, PyObject
*args
)
4793 if (!PyArg_ParseTuple(args
, "s|si:popen2", &cmdstring
, &mode
, &bufsize
))
4798 else if (*mode
!= 'b') {
4799 PyErr_SetString(PyExc_ValueError
, "popen2() arg 2 must be 't' or 'b'");
4804 if (bufsize
!= -1) {
4805 PyErr_SetString(PyExc_ValueError
, "popen2() arg 3 must be -1");
4809 f
= _PyPopen(cmdstring
, tm
, POPEN_2
);
4815 * Variation on <om win32pipe.popen>
4817 * The result of this function is 3 pipes - the process's stdin,
4822 win32_popen3(PyObject
*self
, PyObject
*args
)
4830 if (!PyArg_ParseTuple(args
, "s|si:popen3", &cmdstring
, &mode
, &bufsize
))
4835 else if (*mode
!= 'b') {
4836 PyErr_SetString(PyExc_ValueError
, "popen3() arg 2 must be 't' or 'b'");
4841 if (bufsize
!= -1) {
4842 PyErr_SetString(PyExc_ValueError
, "popen3() arg 3 must be -1");
4846 f
= _PyPopen(cmdstring
, tm
, POPEN_3
);
4852 * Variation on win32pipe.popen
4854 * The result of this function is 2 pipes - the processes stdin,
4855 * and stdout+stderr combined as a single pipe.
4859 win32_popen4(PyObject
*self
, PyObject
*args
)
4867 if (!PyArg_ParseTuple(args
, "s|si:popen4", &cmdstring
, &mode
, &bufsize
))
4872 else if (*mode
!= 'b') {
4873 PyErr_SetString(PyExc_ValueError
, "popen4() arg 2 must be 't' or 'b'");
4878 if (bufsize
!= -1) {
4879 PyErr_SetString(PyExc_ValueError
, "popen4() arg 3 must be -1");
4883 f
= _PyPopen(cmdstring
, tm
, POPEN_4
);
4889 _PyPopenCreateProcess(char *cmdstring
,
4895 PROCESS_INFORMATION piProcInfo
;
4896 STARTUPINFO siStartInfo
;
4897 DWORD dwProcessFlags
= 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
4898 char *s1
,*s2
, *s3
= " /c ";
4899 const char *szConsoleSpawn
= "w9xpopen.exe";
4903 if (i
= GetEnvironmentVariable("COMSPEC",NULL
,0)) {
4906 s1
= (char *)alloca(i
);
4907 if (!(x
= GetEnvironmentVariable("COMSPEC", s1
, i
)))
4908 /* x < i, so x fits into an integer */
4911 /* Explicitly check if we are using COMMAND.COM. If we are
4912 * then use the w9xpopen hack.
4915 while (comshell
>= s1
&& *comshell
!= '\\')
4919 if (GetVersion() < 0x80000000 &&
4920 _stricmp(comshell
, "command.com") != 0) {
4921 /* NT/2000 and not using command.com. */
4922 x
= i
+ strlen(s3
) + strlen(cmdstring
) + 1;
4923 s2
= (char *)alloca(x
);
4925 PyOS_snprintf(s2
, x
, "%s%s%s", s1
, s3
, cmdstring
);
4929 * Oh gag, we're on Win9x or using COMMAND.COM. Use
4930 * the workaround listed in KB: Q150956
4932 char modulepath
[_MAX_PATH
];
4933 struct stat statinfo
;
4934 GetModuleFileName(NULL
, modulepath
, sizeof(modulepath
));
4935 for (x
= i
= 0; modulepath
[i
]; i
++)
4936 if (modulepath
[i
] == SEP
)
4938 modulepath
[x
] = '\0';
4939 /* Create the full-name to w9xpopen, so we can test it exists */
4942 (sizeof(modulepath
)/sizeof(modulepath
[0]))
4943 -strlen(modulepath
));
4944 if (stat(modulepath
, &statinfo
) != 0) {
4945 size_t mplen
= sizeof(modulepath
)/sizeof(modulepath
[0]);
4946 /* Eeek - file-not-found - possibly an embedding
4947 situation - see if we can locate it in sys.prefix
4952 modulepath
[mplen
-1] = '\0';
4953 if (modulepath
[strlen(modulepath
)-1] != '\\')
4954 strcat(modulepath
, "\\");
4957 mplen
-strlen(modulepath
));
4958 /* No where else to look - raise an easily identifiable
4959 error, rather than leaving Windows to report
4960 "file not found" - as the user is probably blissfully
4961 unaware this shim EXE is used, and it will confuse them.
4962 (well, it confused me for a while ;-)
4964 if (stat(modulepath
, &statinfo
) != 0) {
4965 PyErr_Format(PyExc_RuntimeError
,
4966 "Can not locate '%s' which is needed "
4967 "for popen to work with your shell "
4973 x
= i
+ strlen(s3
) + strlen(cmdstring
) + 1 +
4974 strlen(modulepath
) +
4975 strlen(szConsoleSpawn
) + 1;
4977 s2
= (char *)alloca(x
);
4979 /* To maintain correct argument passing semantics,
4980 we pass the command-line as it stands, and allow
4981 quoting to be applied. w9xpopen.exe will then
4982 use its argv vector, and re-quote the necessary
4983 args for the ultimate child process.
4992 /* Not passing CREATE_NEW_CONSOLE has been known to
4993 cause random failures on win9x. Specifically a
4995 "Your program accessed mem currently in use at xxx"
4996 and a hopeful warning about the stability of your
4998 Cost is Ctrl+C wont kill children, but anyone
4999 who cares can have a go!
5001 dwProcessFlags
|= CREATE_NEW_CONSOLE
;
5005 /* Could be an else here to try cmd.exe / command.com in the path
5006 Now we'll just error out.. */
5008 PyErr_SetString(PyExc_RuntimeError
,
5009 "Cannot locate a COMSPEC environment variable to "
5010 "use as the shell");
5014 ZeroMemory(&siStartInfo
, sizeof(STARTUPINFO
));
5015 siStartInfo
.cb
= sizeof(STARTUPINFO
);
5016 siStartInfo
.dwFlags
= STARTF_USESTDHANDLES
| STARTF_USESHOWWINDOW
;
5017 siStartInfo
.hStdInput
= hStdin
;
5018 siStartInfo
.hStdOutput
= hStdout
;
5019 siStartInfo
.hStdError
= hStderr
;
5020 siStartInfo
.wShowWindow
= SW_HIDE
;
5022 if (CreateProcess(NULL
,
5032 /* Close the handles now so anyone waiting is woken. */
5033 CloseHandle(piProcInfo
.hThread
);
5035 /* Return process handle */
5036 *hProcess
= piProcInfo
.hProcess
;
5039 win32_error("CreateProcess", s2
);
5043 /* The following code is based off of KB: Q190351 */
5046 _PyPopen(char *cmdstring
, int mode
, int n
)
5048 HANDLE hChildStdinRd
, hChildStdinWr
, hChildStdoutRd
, hChildStdoutWr
,
5049 hChildStderrRd
, hChildStderrWr
, hChildStdinWrDup
, hChildStdoutRdDup
,
5050 hChildStderrRdDup
, hProcess
; /* hChildStdoutWrDup; */
5052 SECURITY_ATTRIBUTES saAttr
;
5059 saAttr
.nLength
= sizeof(SECURITY_ATTRIBUTES
);
5060 saAttr
.bInheritHandle
= TRUE
;
5061 saAttr
.lpSecurityDescriptor
= NULL
;
5063 if (!CreatePipe(&hChildStdinRd
, &hChildStdinWr
, &saAttr
, 0))
5064 return win32_error("CreatePipe", NULL
);
5066 /* Create new output read handle and the input write handle. Set
5067 * the inheritance properties to FALSE. Otherwise, the child inherits
5068 * these handles; resulting in non-closeable handles to the pipes
5070 fSuccess
= DuplicateHandle(GetCurrentProcess(), hChildStdinWr
,
5071 GetCurrentProcess(), &hChildStdinWrDup
, 0,
5073 DUPLICATE_SAME_ACCESS
);
5075 return win32_error("DuplicateHandle", NULL
);
5077 /* Close the inheritable version of ChildStdin
5078 that we're using. */
5079 CloseHandle(hChildStdinWr
);
5081 if (!CreatePipe(&hChildStdoutRd
, &hChildStdoutWr
, &saAttr
, 0))
5082 return win32_error("CreatePipe", NULL
);
5084 fSuccess
= DuplicateHandle(GetCurrentProcess(), hChildStdoutRd
,
5085 GetCurrentProcess(), &hChildStdoutRdDup
, 0,
5086 FALSE
, DUPLICATE_SAME_ACCESS
);
5088 return win32_error("DuplicateHandle", NULL
);
5090 /* Close the inheritable version of ChildStdout
5091 that we're using. */
5092 CloseHandle(hChildStdoutRd
);
5095 if (!CreatePipe(&hChildStderrRd
, &hChildStderrWr
, &saAttr
, 0))
5096 return win32_error("CreatePipe", NULL
);
5097 fSuccess
= DuplicateHandle(GetCurrentProcess(),
5099 GetCurrentProcess(),
5100 &hChildStderrRdDup
, 0,
5101 FALSE
, DUPLICATE_SAME_ACCESS
);
5103 return win32_error("DuplicateHandle", NULL
);
5104 /* Close the inheritable version of ChildStdErr that we're using. */
5105 CloseHandle(hChildStderrRd
);
5110 switch (mode
& (_O_RDONLY
| _O_TEXT
| _O_BINARY
| _O_WRONLY
)) {
5111 case _O_WRONLY
| _O_TEXT
:
5112 /* Case for writing to child Stdin in text mode. */
5113 fd1
= _open_osfhandle((Py_intptr_t
)hChildStdinWrDup
, mode
);
5114 f1
= _fdopen(fd1
, "w");
5115 f
= PyFile_FromFile(f1
, cmdstring
, "w", _PyPclose
);
5116 PyFile_SetBufSize(f
, 0);
5117 /* We don't care about these pipes anymore, so close them. */
5118 CloseHandle(hChildStdoutRdDup
);
5119 CloseHandle(hChildStderrRdDup
);
5122 case _O_RDONLY
| _O_TEXT
:
5123 /* Case for reading from child Stdout in text mode. */
5124 fd1
= _open_osfhandle((Py_intptr_t
)hChildStdoutRdDup
, mode
);
5125 f1
= _fdopen(fd1
, "r");
5126 f
= PyFile_FromFile(f1
, cmdstring
, "r", _PyPclose
);
5127 PyFile_SetBufSize(f
, 0);
5128 /* We don't care about these pipes anymore, so close them. */
5129 CloseHandle(hChildStdinWrDup
);
5130 CloseHandle(hChildStderrRdDup
);
5133 case _O_RDONLY
| _O_BINARY
:
5134 /* Case for readinig from child Stdout in binary mode. */
5135 fd1
= _open_osfhandle((Py_intptr_t
)hChildStdoutRdDup
, mode
);
5136 f1
= _fdopen(fd1
, "rb");
5137 f
= PyFile_FromFile(f1
, cmdstring
, "rb", _PyPclose
);
5138 PyFile_SetBufSize(f
, 0);
5139 /* We don't care about these pipes anymore, so close them. */
5140 CloseHandle(hChildStdinWrDup
);
5141 CloseHandle(hChildStderrRdDup
);
5144 case _O_WRONLY
| _O_BINARY
:
5145 /* Case for writing to child Stdin in binary mode. */
5146 fd1
= _open_osfhandle((Py_intptr_t
)hChildStdinWrDup
, mode
);
5147 f1
= _fdopen(fd1
, "wb");
5148 f
= PyFile_FromFile(f1
, cmdstring
, "wb", _PyPclose
);
5149 PyFile_SetBufSize(f
, 0);
5150 /* We don't care about these pipes anymore, so close them. */
5151 CloseHandle(hChildStdoutRdDup
);
5152 CloseHandle(hChildStderrRdDup
);
5164 if (mode
& _O_TEXT
) {
5172 fd1
= _open_osfhandle((Py_intptr_t
)hChildStdinWrDup
, mode
);
5173 f1
= _fdopen(fd1
, m2
);
5174 fd2
= _open_osfhandle((Py_intptr_t
)hChildStdoutRdDup
, mode
);
5175 f2
= _fdopen(fd2
, m1
);
5176 p1
= PyFile_FromFile(f1
, cmdstring
, m2
, _PyPclose
);
5177 PyFile_SetBufSize(p1
, 0);
5178 p2
= PyFile_FromFile(f2
, cmdstring
, m1
, _PyPclose
);
5179 PyFile_SetBufSize(p2
, 0);
5182 CloseHandle(hChildStderrRdDup
);
5184 f
= PyTuple_Pack(2,p1
,p2
);
5194 PyObject
*p1
, *p2
, *p3
;
5196 if (mode
& _O_TEXT
) {
5204 fd1
= _open_osfhandle((Py_intptr_t
)hChildStdinWrDup
, mode
);
5205 f1
= _fdopen(fd1
, m2
);
5206 fd2
= _open_osfhandle((Py_intptr_t
)hChildStdoutRdDup
, mode
);
5207 f2
= _fdopen(fd2
, m1
);
5208 fd3
= _open_osfhandle((Py_intptr_t
)hChildStderrRdDup
, mode
);
5209 f3
= _fdopen(fd3
, m1
);
5210 p1
= PyFile_FromFile(f1
, cmdstring
, m2
, _PyPclose
);
5211 p2
= PyFile_FromFile(f2
, cmdstring
, m1
, _PyPclose
);
5212 p3
= PyFile_FromFile(f3
, cmdstring
, m1
, _PyPclose
);
5213 PyFile_SetBufSize(p1
, 0);
5214 PyFile_SetBufSize(p2
, 0);
5215 PyFile_SetBufSize(p3
, 0);
5216 f
= PyTuple_Pack(3,p1
,p2
,p3
);
5226 if (!_PyPopenCreateProcess(cmdstring
,
5234 if (!_PyPopenCreateProcess(cmdstring
,
5243 * Insert the files we've created into the process dictionary
5244 * all referencing the list with the process handle and the
5245 * initial number of files (see description below in _PyPclose).
5246 * Since if _PyPclose later tried to wait on a process when all
5247 * handles weren't closed, it could create a deadlock with the
5248 * child, we spend some energy here to try to ensure that we
5249 * either insert all file handles into the dictionary or none
5250 * at all. It's a little clumsy with the various popen modes
5251 * and variable number of files involved.
5253 if (!_PyPopenProcs
) {
5254 _PyPopenProcs
= PyDict_New();
5257 if (_PyPopenProcs
) {
5258 PyObject
*procObj
, *hProcessObj
, *intObj
, *fileObj
[3];
5261 fileObj
[0] = fileObj
[1] = fileObj
[2] = NULL
;
5262 ins_rc
[0] = ins_rc
[1] = ins_rc
[2] = 0;
5264 procObj
= PyList_New(2);
5265 hProcessObj
= PyLong_FromVoidPtr(hProcess
);
5266 intObj
= PyInt_FromLong(file_count
);
5268 if (procObj
&& hProcessObj
&& intObj
) {
5269 PyList_SetItem(procObj
,0,hProcessObj
);
5270 PyList_SetItem(procObj
,1,intObj
);
5272 fileObj
[0] = PyLong_FromVoidPtr(f1
);
5274 ins_rc
[0] = PyDict_SetItem(_PyPopenProcs
,
5278 if (file_count
>= 2) {
5279 fileObj
[1] = PyLong_FromVoidPtr(f2
);
5281 ins_rc
[1] = PyDict_SetItem(_PyPopenProcs
,
5286 if (file_count
>= 3) {
5287 fileObj
[2] = PyLong_FromVoidPtr(f3
);
5289 ins_rc
[2] = PyDict_SetItem(_PyPopenProcs
,
5295 if (ins_rc
[0] < 0 || !fileObj
[0] ||
5296 ins_rc
[1] < 0 || (file_count
> 1 && !fileObj
[1]) ||
5297 ins_rc
[2] < 0 || (file_count
> 2 && !fileObj
[2])) {
5298 /* Something failed - remove any dictionary
5299 * entries that did make it.
5301 if (!ins_rc
[0] && fileObj
[0]) {
5302 PyDict_DelItem(_PyPopenProcs
,
5305 if (!ins_rc
[1] && fileObj
[1]) {
5306 PyDict_DelItem(_PyPopenProcs
,
5309 if (!ins_rc
[2] && fileObj
[2]) {
5310 PyDict_DelItem(_PyPopenProcs
,
5317 * Clean up our localized references for the dictionary keys
5318 * and value since PyDict_SetItem will Py_INCREF any copies
5319 * that got placed in the dictionary.
5321 Py_XDECREF(procObj
);
5322 Py_XDECREF(fileObj
[0]);
5323 Py_XDECREF(fileObj
[1]);
5324 Py_XDECREF(fileObj
[2]);
5327 /* Child is launched. Close the parents copy of those pipe
5328 * handles that only the child should have open. You need to
5329 * make sure that no handles to the write end of the output pipe
5330 * are maintained in this process or else the pipe will not close
5331 * when the child process exits and the ReadFile will hang. */
5333 if (!CloseHandle(hChildStdinRd
))
5334 return win32_error("CloseHandle", NULL
);
5336 if (!CloseHandle(hChildStdoutWr
))
5337 return win32_error("CloseHandle", NULL
);
5339 if ((n
!= 4) && (!CloseHandle(hChildStderrWr
)))
5340 return win32_error("CloseHandle", NULL
);
5346 * Wrapper for fclose() to use for popen* files, so we can retrieve the
5347 * exit code for the child process and return as a result of the close.
5349 * This function uses the _PyPopenProcs dictionary in order to map the
5350 * input file pointer to information about the process that was
5351 * originally created by the popen* call that created the file pointer.
5352 * The dictionary uses the file pointer as a key (with one entry
5353 * inserted for each file returned by the original popen* call) and a
5354 * single list object as the value for all files from a single call.
5355 * The list object contains the Win32 process handle at [0], and a file
5356 * count at [1], which is initialized to the total number of file
5357 * handles using that list.
5359 * This function closes whichever handle it is passed, and decrements
5360 * the file count in the dictionary for the process handle pointed to
5361 * by this file. On the last close (when the file count reaches zero),
5362 * this function will wait for the child process and then return its
5363 * exit code as the result of the close() operation. This permits the
5364 * files to be closed in any order - it is always the close() of the
5365 * final handle that will return the exit code.
5367 * NOTE: This function is currently called with the GIL released.
5368 * hence we use the GILState API to manage our state.
5371 static int _PyPclose(FILE *file
)
5376 PyObject
*procObj
, *hProcessObj
, *intObj
, *fileObj
;
5379 PyGILState_STATE state
;
5382 /* Close the file handle first, to ensure it can't block the
5383 * child from exiting if it's the last handle.
5385 result
= fclose(file
);
5387 state
= PyGILState_Ensure();
5389 if (_PyPopenProcs
) {
5390 if ((fileObj
= PyLong_FromVoidPtr(file
)) != NULL
&&
5391 (procObj
= PyDict_GetItem(_PyPopenProcs
,
5392 fileObj
)) != NULL
&&
5393 (hProcessObj
= PyList_GetItem(procObj
,0)) != NULL
&&
5394 (intObj
= PyList_GetItem(procObj
,1)) != NULL
) {
5396 hProcess
= PyLong_AsVoidPtr(hProcessObj
);
5397 file_count
= PyInt_AsLong(intObj
);
5399 if (file_count
> 1) {
5400 /* Still other files referencing process */
5402 PyList_SetItem(procObj
,1,
5403 PyInt_FromLong(file_count
));
5405 /* Last file for this process */
5406 if (result
!= EOF
&&
5407 WaitForSingleObject(hProcess
, INFINITE
) != WAIT_FAILED
&&
5408 GetExitCodeProcess(hProcess
, &exit_code
)) {
5409 /* Possible truncation here in 16-bit environments, but
5410 * real exit codes are just the lower byte in any event.
5414 /* Indicate failure - this will cause the file object
5415 * to raise an I/O error and translate the last Win32
5416 * error code from errno. We do have a problem with
5417 * last errors that overlap the normal errno table,
5418 * but that's a consistent problem with the file object.
5420 if (result
!= EOF
) {
5421 /* If the error wasn't from the fclose(), then
5422 * set errno for the file object error handling.
5424 errno
= GetLastError();
5429 /* Free up the native handle at this point */
5430 CloseHandle(hProcess
);
5433 /* Remove this file pointer from dictionary */
5434 PyDict_DelItem(_PyPopenProcs
, fileObj
);
5436 if (PyDict_Size(_PyPopenProcs
) == 0) {
5437 Py_DECREF(_PyPopenProcs
);
5438 _PyPopenProcs
= NULL
;
5441 } /* if object retrieval ok */
5443 Py_XDECREF(fileObj
);
5444 } /* if _PyPopenProcs */
5447 PyGILState_Release(state
);
5452 #else /* which OS? */
5454 posix_popen(PyObject
*self
, PyObject
*args
)
5461 if (!PyArg_ParseTuple(args
, "s|si:popen", &name
, &mode
, &bufsize
))
5463 /* Strip mode of binary or text modifiers */
5464 if (strcmp(mode
, "rb") == 0 || strcmp(mode
, "rt") == 0)
5466 else if (strcmp(mode
, "wb") == 0 || strcmp(mode
, "wt") == 0)
5468 Py_BEGIN_ALLOW_THREADS
5469 fp
= popen(name
, mode
);
5470 Py_END_ALLOW_THREADS
5472 return posix_error();
5473 f
= PyFile_FromFile(fp
, name
, mode
, pclose
);
5475 PyFile_SetBufSize(f
, bufsize
);
5479 #endif /* PYOS_??? */
5480 #endif /* HAVE_POPEN */
5484 PyDoc_STRVAR(posix_setuid__doc__
,
5486 Set the current process's user id.");
5489 posix_setuid(PyObject
*self
, PyObject
*args
)
5492 if (!PyArg_ParseTuple(args
, "i:setuid", &uid
))
5494 if (setuid(uid
) < 0)
5495 return posix_error();
5499 #endif /* HAVE_SETUID */
5503 PyDoc_STRVAR(posix_seteuid__doc__
,
5505 Set the current process's effective user id.");
5508 posix_seteuid (PyObject
*self
, PyObject
*args
)
5511 if (!PyArg_ParseTuple(args
, "i", &euid
)) {
5513 } else if (seteuid(euid
) < 0) {
5514 return posix_error();
5520 #endif /* HAVE_SETEUID */
5523 PyDoc_STRVAR(posix_setegid__doc__
,
5525 Set the current process's effective group id.");
5528 posix_setegid (PyObject
*self
, PyObject
*args
)
5531 if (!PyArg_ParseTuple(args
, "i", &egid
)) {
5533 } else if (setegid(egid
) < 0) {
5534 return posix_error();
5540 #endif /* HAVE_SETEGID */
5542 #ifdef HAVE_SETREUID
5543 PyDoc_STRVAR(posix_setreuid__doc__
,
5544 "setreuid(ruid, euid)\n\n\
5545 Set the current process's real and effective user ids.");
5548 posix_setreuid (PyObject
*self
, PyObject
*args
)
5551 if (!PyArg_ParseTuple(args
, "ii", &ruid
, &euid
)) {
5553 } else if (setreuid(ruid
, euid
) < 0) {
5554 return posix_error();
5560 #endif /* HAVE_SETREUID */
5562 #ifdef HAVE_SETREGID
5563 PyDoc_STRVAR(posix_setregid__doc__
,
5564 "setregid(rgid, egid)\n\n\
5565 Set the current process's real and effective group ids.");
5568 posix_setregid (PyObject
*self
, PyObject
*args
)
5571 if (!PyArg_ParseTuple(args
, "ii", &rgid
, &egid
)) {
5573 } else if (setregid(rgid
, egid
) < 0) {
5574 return posix_error();
5580 #endif /* HAVE_SETREGID */
5583 PyDoc_STRVAR(posix_setgid__doc__
,
5585 Set the current process's group id.");
5588 posix_setgid(PyObject
*self
, PyObject
*args
)
5591 if (!PyArg_ParseTuple(args
, "i:setgid", &gid
))
5593 if (setgid(gid
) < 0)
5594 return posix_error();
5598 #endif /* HAVE_SETGID */
5600 #ifdef HAVE_SETGROUPS
5601 PyDoc_STRVAR(posix_setgroups__doc__
,
5602 "setgroups(list)\n\n\
5603 Set the groups of the current process to list.");
5606 posix_setgroups(PyObject
*self
, PyObject
*groups
)
5609 gid_t grouplist
[MAX_GROUPS
];
5611 if (!PySequence_Check(groups
)) {
5612 PyErr_SetString(PyExc_TypeError
, "setgroups argument must be a sequence");
5615 len
= PySequence_Size(groups
);
5616 if (len
> MAX_GROUPS
) {
5617 PyErr_SetString(PyExc_ValueError
, "too many groups");
5620 for(i
= 0; i
< len
; i
++) {
5622 elem
= PySequence_GetItem(groups
, i
);
5625 if (!PyInt_Check(elem
)) {
5626 if (!PyLong_Check(elem
)) {
5627 PyErr_SetString(PyExc_TypeError
,
5628 "groups must be integers");
5632 unsigned long x
= PyLong_AsUnsignedLong(elem
);
5633 if (PyErr_Occurred()) {
5634 PyErr_SetString(PyExc_TypeError
,
5635 "group id too big");
5640 /* read back the value to see if it fitted in gid_t */
5641 if (grouplist
[i
] != x
) {
5642 PyErr_SetString(PyExc_TypeError
,
5643 "group id too big");
5649 long x
= PyInt_AsLong(elem
);
5651 if (grouplist
[i
] != x
) {
5652 PyErr_SetString(PyExc_TypeError
,
5653 "group id too big");
5661 if (setgroups(len
, grouplist
) < 0)
5662 return posix_error();
5666 #endif /* HAVE_SETGROUPS */
5668 #if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
5670 wait_helper(pid_t pid
, int status
, struct rusage
*ru
)
5673 static PyObject
*struct_rusage
;
5676 return posix_error();
5678 if (struct_rusage
== NULL
) {
5679 PyObject
*m
= PyImport_ImportModuleNoBlock("resource");
5682 struct_rusage
= PyObject_GetAttrString(m
, "struct_rusage");
5684 if (struct_rusage
== NULL
)
5688 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
5689 result
= PyStructSequence_New((PyTypeObject
*) struct_rusage
);
5694 #define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
5697 PyStructSequence_SET_ITEM(result
, 0,
5698 PyFloat_FromDouble(doubletime(ru
->ru_utime
)));
5699 PyStructSequence_SET_ITEM(result
, 1,
5700 PyFloat_FromDouble(doubletime(ru
->ru_stime
)));
5701 #define SET_INT(result, index, value)\
5702 PyStructSequence_SET_ITEM(result, index, PyInt_FromLong(value))
5703 SET_INT(result
, 2, ru
->ru_maxrss
);
5704 SET_INT(result
, 3, ru
->ru_ixrss
);
5705 SET_INT(result
, 4, ru
->ru_idrss
);
5706 SET_INT(result
, 5, ru
->ru_isrss
);
5707 SET_INT(result
, 6, ru
->ru_minflt
);
5708 SET_INT(result
, 7, ru
->ru_majflt
);
5709 SET_INT(result
, 8, ru
->ru_nswap
);
5710 SET_INT(result
, 9, ru
->ru_inblock
);
5711 SET_INT(result
, 10, ru
->ru_oublock
);
5712 SET_INT(result
, 11, ru
->ru_msgsnd
);
5713 SET_INT(result
, 12, ru
->ru_msgrcv
);
5714 SET_INT(result
, 13, ru
->ru_nsignals
);
5715 SET_INT(result
, 14, ru
->ru_nvcsw
);
5716 SET_INT(result
, 15, ru
->ru_nivcsw
);
5719 if (PyErr_Occurred()) {
5724 return Py_BuildValue("iiN", pid
, status
, result
);
5726 #endif /* HAVE_WAIT3 || HAVE_WAIT4 */
5729 PyDoc_STRVAR(posix_wait3__doc__
,
5730 "wait3(options) -> (pid, status, rusage)\n\n\
5731 Wait for completion of a child process.");
5734 posix_wait3(PyObject
*self
, PyObject
*args
)
5740 WAIT_STATUS_INT(status
) = 0;
5742 if (!PyArg_ParseTuple(args
, "i:wait3", &options
))
5745 Py_BEGIN_ALLOW_THREADS
5746 pid
= wait3(&status
, options
, &ru
);
5747 Py_END_ALLOW_THREADS
5749 return wait_helper(pid
, WAIT_STATUS_INT(status
), &ru
);
5751 #endif /* HAVE_WAIT3 */
5754 PyDoc_STRVAR(posix_wait4__doc__
,
5755 "wait4(pid, options) -> (pid, status, rusage)\n\n\
5756 Wait for completion of a given child process.");
5759 posix_wait4(PyObject
*self
, PyObject
*args
)
5765 WAIT_STATUS_INT(status
) = 0;
5767 if (!PyArg_ParseTuple(args
, "ii:wait4", &pid
, &options
))
5770 Py_BEGIN_ALLOW_THREADS
5771 pid
= wait4(pid
, &status
, options
, &ru
);
5772 Py_END_ALLOW_THREADS
5774 return wait_helper(pid
, WAIT_STATUS_INT(status
), &ru
);
5776 #endif /* HAVE_WAIT4 */
5779 PyDoc_STRVAR(posix_waitpid__doc__
,
5780 "waitpid(pid, options) -> (pid, status)\n\n\
5781 Wait for completion of a given child process.");
5784 posix_waitpid(PyObject
*self
, PyObject
*args
)
5789 WAIT_STATUS_INT(status
) = 0;
5791 if (!PyArg_ParseTuple(args
, "ii:waitpid", &pid
, &options
))
5793 Py_BEGIN_ALLOW_THREADS
5794 pid
= waitpid(pid
, &status
, options
);
5795 Py_END_ALLOW_THREADS
5797 return posix_error();
5799 return Py_BuildValue("ii", pid
, WAIT_STATUS_INT(status
));
5802 #elif defined(HAVE_CWAIT)
5804 /* MS C has a variant of waitpid() that's usable for most purposes. */
5805 PyDoc_STRVAR(posix_waitpid__doc__
,
5806 "waitpid(pid, options) -> (pid, status << 8)\n\n"
5807 "Wait for completion of a given process. options is ignored on Windows.");
5810 posix_waitpid(PyObject
*self
, PyObject
*args
)
5813 int status
, options
;
5815 if (!PyArg_ParseTuple(args
, "ii:waitpid", &pid
, &options
))
5817 Py_BEGIN_ALLOW_THREADS
5818 pid
= _cwait(&status
, pid
, options
);
5819 Py_END_ALLOW_THREADS
5821 return posix_error();
5823 /* shift the status left a byte so this is more like the POSIX waitpid */
5824 return Py_BuildValue("ii", pid
, status
<< 8);
5826 #endif /* HAVE_WAITPID || HAVE_CWAIT */
5829 PyDoc_STRVAR(posix_wait__doc__
,
5830 "wait() -> (pid, status)\n\n\
5831 Wait for completion of a child process.");
5834 posix_wait(PyObject
*self
, PyObject
*noargs
)
5838 WAIT_STATUS_INT(status
) = 0;
5840 Py_BEGIN_ALLOW_THREADS
5841 pid
= wait(&status
);
5842 Py_END_ALLOW_THREADS
5844 return posix_error();
5846 return Py_BuildValue("ii", pid
, WAIT_STATUS_INT(status
));
5851 PyDoc_STRVAR(posix_lstat__doc__
,
5852 "lstat(path) -> stat result\n\n\
5853 Like stat(path), but do not follow symbolic links.");
5856 posix_lstat(PyObject
*self
, PyObject
*args
)
5859 return posix_do_stat(self
, args
, "et:lstat", lstat
, NULL
, NULL
);
5860 #else /* !HAVE_LSTAT */
5862 return posix_do_stat(self
, args
, "et:lstat", STAT
, "U:lstat", win32_wstat
);
5864 return posix_do_stat(self
, args
, "et:lstat", STAT
, NULL
, NULL
);
5866 #endif /* !HAVE_LSTAT */
5870 #ifdef HAVE_READLINK
5871 PyDoc_STRVAR(posix_readlink__doc__
,
5872 "readlink(path) -> path\n\n\
5873 Return a string representing the path to which the symbolic link points.");
5876 posix_readlink(PyObject
*self
, PyObject
*args
)
5879 char buf
[MAXPATHLEN
];
5882 #ifdef Py_USING_UNICODE
5883 int arg_is_unicode
= 0;
5886 if (!PyArg_ParseTuple(args
, "et:readlink",
5887 Py_FileSystemDefaultEncoding
, &path
))
5889 #ifdef Py_USING_UNICODE
5890 v
= PySequence_GetItem(args
, 0);
5896 if (PyUnicode_Check(v
)) {
5902 Py_BEGIN_ALLOW_THREADS
5903 n
= readlink(path
, buf
, (int) sizeof buf
);
5904 Py_END_ALLOW_THREADS
5906 return posix_error_with_allocated_filename(path
);
5909 v
= PyString_FromStringAndSize(buf
, n
);
5910 #ifdef Py_USING_UNICODE
5911 if (arg_is_unicode
) {
5914 w
= PyUnicode_FromEncodedObject(v
,
5915 Py_FileSystemDefaultEncoding
,
5922 /* fall back to the original byte string, as
5923 discussed in patch #683592 */
5930 #endif /* HAVE_READLINK */
5934 PyDoc_STRVAR(posix_symlink__doc__
,
5935 "symlink(src, dst)\n\n\
5936 Create a symbolic link pointing to src named dst.");
5939 posix_symlink(PyObject
*self
, PyObject
*args
)
5941 return posix_2str(args
, "etet:symlink", symlink
);
5943 #endif /* HAVE_SYMLINK */
5948 #define HZ 60 /* Universal constant :-) */
5951 #if defined(PYCC_VACPP) && defined(PYOS_OS2)
5957 Py_BEGIN_ALLOW_THREADS
5958 DosQuerySysInfo(QSV_MS_COUNT
, QSV_MS_COUNT
, &value
, sizeof(value
));
5959 Py_END_ALLOW_THREADS
5965 posix_times(PyObject
*self
, PyObject
*noargs
)
5967 /* Currently Only Uptime is Provided -- Others Later */
5968 return Py_BuildValue("ddddd",
5969 (double)0 /* t.tms_utime / HZ */,
5970 (double)0 /* t.tms_stime / HZ */,
5971 (double)0 /* t.tms_cutime / HZ */,
5972 (double)0 /* t.tms_cstime / HZ */,
5973 (double)system_uptime() / 1000);
5977 posix_times(PyObject
*self
, PyObject
*noargs
)
5983 if (c
== (clock_t) -1)
5984 return posix_error();
5985 return Py_BuildValue("ddddd",
5986 (double)t
.tms_utime
/ HZ
,
5987 (double)t
.tms_stime
/ HZ
,
5988 (double)t
.tms_cutime
/ HZ
,
5989 (double)t
.tms_cstime
/ HZ
,
5992 #endif /* not OS2 */
5993 #endif /* HAVE_TIMES */
5997 #define HAVE_TIMES /* so the method table will pick it up */
5999 posix_times(PyObject
*self
, PyObject
*noargs
)
6001 FILETIME create
, exit
, kernel
, user
;
6003 hProc
= GetCurrentProcess();
6004 GetProcessTimes(hProc
, &create
, &exit
, &kernel
, &user
);
6005 /* The fields of a FILETIME structure are the hi and lo part
6006 of a 64-bit value expressed in 100 nanosecond units.
6007 1e7 is one second in such units; 1e-7 the inverse.
6008 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
6010 return Py_BuildValue(
6012 (double)(user
.dwHighDateTime
*429.4967296 +
6013 user
.dwLowDateTime
*1e-7),
6014 (double)(kernel
.dwHighDateTime
*429.4967296 +
6015 kernel
.dwLowDateTime
*1e-7),
6020 #endif /* MS_WINDOWS */
6023 PyDoc_STRVAR(posix_times__doc__
,
6024 "times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
6025 Return a tuple of floating point numbers indicating process times.");
6030 PyDoc_STRVAR(posix_getsid__doc__
,
6031 "getsid(pid) -> sid\n\n\
6032 Call the system call getsid().");
6035 posix_getsid(PyObject
*self
, PyObject
*args
)
6039 if (!PyArg_ParseTuple(args
, "i:getsid", &pid
))
6043 return posix_error();
6044 return PyInt_FromLong((long)sid
);
6046 #endif /* HAVE_GETSID */
6050 PyDoc_STRVAR(posix_setsid__doc__
,
6052 Call the system call setsid().");
6055 posix_setsid(PyObject
*self
, PyObject
*noargs
)
6058 return posix_error();
6062 #endif /* HAVE_SETSID */
6065 PyDoc_STRVAR(posix_setpgid__doc__
,
6066 "setpgid(pid, pgrp)\n\n\
6067 Call the system call setpgid().");
6070 posix_setpgid(PyObject
*self
, PyObject
*args
)
6074 if (!PyArg_ParseTuple(args
, "ii:setpgid", &pid
, &pgrp
))
6076 if (setpgid(pid
, pgrp
) < 0)
6077 return posix_error();
6081 #endif /* HAVE_SETPGID */
6084 #ifdef HAVE_TCGETPGRP
6085 PyDoc_STRVAR(posix_tcgetpgrp__doc__
,
6086 "tcgetpgrp(fd) -> pgid\n\n\
6087 Return the process group associated with the terminal given by a fd.");
6090 posix_tcgetpgrp(PyObject
*self
, PyObject
*args
)
6094 if (!PyArg_ParseTuple(args
, "i:tcgetpgrp", &fd
))
6096 pgid
= tcgetpgrp(fd
);
6098 return posix_error();
6099 return PyInt_FromLong((long)pgid
);
6101 #endif /* HAVE_TCGETPGRP */
6104 #ifdef HAVE_TCSETPGRP
6105 PyDoc_STRVAR(posix_tcsetpgrp__doc__
,
6106 "tcsetpgrp(fd, pgid)\n\n\
6107 Set the process group associated with the terminal given by a fd.");
6110 posix_tcsetpgrp(PyObject
*self
, PyObject
*args
)
6113 if (!PyArg_ParseTuple(args
, "ii:tcsetpgrp", &fd
, &pgid
))
6115 if (tcsetpgrp(fd
, pgid
) < 0)
6116 return posix_error();
6120 #endif /* HAVE_TCSETPGRP */
6122 /* Functions acting on file descriptors */
6124 PyDoc_STRVAR(posix_open__doc__
,
6125 "open(filename, flag [, mode=0777]) -> fd\n\n\
6126 Open a file (for low level IO).");
6129 posix_open(PyObject
*self
, PyObject
*args
)
6137 if (unicode_file_names()) {
6138 PyUnicodeObject
*po
;
6139 if (PyArg_ParseTuple(args
, "Ui|i:mkdir", &po
, &flag
, &mode
)) {
6140 Py_BEGIN_ALLOW_THREADS
6141 /* PyUnicode_AS_UNICODE OK without thread
6142 lock as it is a simple dereference. */
6143 fd
= _wopen(PyUnicode_AS_UNICODE(po
), flag
, mode
);
6144 Py_END_ALLOW_THREADS
6146 return posix_error();
6147 return PyInt_FromLong((long)fd
);
6149 /* Drop the argument parsing error as narrow strings
6155 if (!PyArg_ParseTuple(args
, "eti|i",
6156 Py_FileSystemDefaultEncoding
, &file
,
6160 Py_BEGIN_ALLOW_THREADS
6161 fd
= open(file
, flag
, mode
);
6162 Py_END_ALLOW_THREADS
6164 return posix_error_with_allocated_filename(file
);
6166 return PyInt_FromLong((long)fd
);
6170 PyDoc_STRVAR(posix_close__doc__
,
6172 Close a file descriptor (for low level IO).");
6175 posix_close(PyObject
*self
, PyObject
*args
)
6178 if (!PyArg_ParseTuple(args
, "i:close", &fd
))
6180 Py_BEGIN_ALLOW_THREADS
6182 Py_END_ALLOW_THREADS
6184 return posix_error();
6190 PyDoc_STRVAR(posix_closerange__doc__
,
6191 "closerange(fd_low, fd_high)\n\n\
6192 Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
6195 posix_closerange(PyObject
*self
, PyObject
*args
)
6197 int fd_from
, fd_to
, i
;
6198 if (!PyArg_ParseTuple(args
, "ii:closerange", &fd_from
, &fd_to
))
6200 Py_BEGIN_ALLOW_THREADS
6201 for (i
= fd_from
; i
< fd_to
; i
++)
6203 Py_END_ALLOW_THREADS
6208 PyDoc_STRVAR(posix_dup__doc__
,
6209 "dup(fd) -> fd2\n\n\
6210 Return a duplicate of a file descriptor.");
6213 posix_dup(PyObject
*self
, PyObject
*args
)
6216 if (!PyArg_ParseTuple(args
, "i:dup", &fd
))
6218 Py_BEGIN_ALLOW_THREADS
6220 Py_END_ALLOW_THREADS
6222 return posix_error();
6223 return PyInt_FromLong((long)fd
);
6227 PyDoc_STRVAR(posix_dup2__doc__
,
6228 "dup2(old_fd, new_fd)\n\n\
6229 Duplicate file descriptor.");
6232 posix_dup2(PyObject
*self
, PyObject
*args
)
6235 if (!PyArg_ParseTuple(args
, "ii:dup2", &fd
, &fd2
))
6237 Py_BEGIN_ALLOW_THREADS
6238 res
= dup2(fd
, fd2
);
6239 Py_END_ALLOW_THREADS
6241 return posix_error();
6247 PyDoc_STRVAR(posix_lseek__doc__
,
6248 "lseek(fd, pos, how) -> newpos\n\n\
6249 Set the current position of a file descriptor.");
6252 posix_lseek(PyObject
*self
, PyObject
*args
)
6255 #if defined(MS_WIN64) || defined(MS_WINDOWS)
6256 PY_LONG_LONG pos
, res
;
6261 if (!PyArg_ParseTuple(args
, "iOi:lseek", &fd
, &posobj
, &how
))
6264 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
6266 case 0: how
= SEEK_SET
; break;
6267 case 1: how
= SEEK_CUR
; break;
6268 case 2: how
= SEEK_END
; break;
6270 #endif /* SEEK_END */
6272 #if !defined(HAVE_LARGEFILE_SUPPORT)
6273 pos
= PyInt_AsLong(posobj
);
6275 pos
= PyLong_Check(posobj
) ?
6276 PyLong_AsLongLong(posobj
) : PyInt_AsLong(posobj
);
6278 if (PyErr_Occurred())
6281 Py_BEGIN_ALLOW_THREADS
6282 #if defined(MS_WIN64) || defined(MS_WINDOWS)
6283 res
= _lseeki64(fd
, pos
, how
);
6285 res
= lseek(fd
, pos
, how
);
6287 Py_END_ALLOW_THREADS
6289 return posix_error();
6291 #if !defined(HAVE_LARGEFILE_SUPPORT)
6292 return PyInt_FromLong(res
);
6294 return PyLong_FromLongLong(res
);
6299 PyDoc_STRVAR(posix_read__doc__
,
6300 "read(fd, buffersize) -> string\n\n\
6301 Read a file descriptor.");
6304 posix_read(PyObject
*self
, PyObject
*args
)
6308 if (!PyArg_ParseTuple(args
, "ii:read", &fd
, &size
))
6312 return posix_error();
6314 buffer
= PyString_FromStringAndSize((char *)NULL
, size
);
6317 Py_BEGIN_ALLOW_THREADS
6318 n
= read(fd
, PyString_AsString(buffer
), size
);
6319 Py_END_ALLOW_THREADS
6322 return posix_error();
6325 _PyString_Resize(&buffer
, n
);
6330 PyDoc_STRVAR(posix_write__doc__
,
6331 "write(fd, string) -> byteswritten\n\n\
6332 Write a string to a file descriptor.");
6335 posix_write(PyObject
*self
, PyObject
*args
)
6341 if (!PyArg_ParseTuple(args
, "is#:write", &fd
, &buffer
, &size
))
6343 Py_BEGIN_ALLOW_THREADS
6344 size
= write(fd
, buffer
, (size_t)size
);
6345 Py_END_ALLOW_THREADS
6347 return posix_error();
6348 return PyInt_FromSsize_t(size
);
6352 PyDoc_STRVAR(posix_fstat__doc__
,
6353 "fstat(fd) -> stat result\n\n\
6354 Like stat(), but for an open file descriptor.");
6357 posix_fstat(PyObject
*self
, PyObject
*args
)
6362 if (!PyArg_ParseTuple(args
, "i:fstat", &fd
))
6365 /* on OpenVMS we must ensure that all bytes are written to the file */
6368 Py_BEGIN_ALLOW_THREADS
6369 res
= FSTAT(fd
, &st
);
6370 Py_END_ALLOW_THREADS
6373 return win32_error("fstat", NULL
);
6375 return posix_error();
6379 return _pystat_fromstructstat(&st
);
6383 PyDoc_STRVAR(posix_fdopen__doc__
,
6384 "fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
6385 Return an open file object connected to a file descriptor.");
6388 posix_fdopen(PyObject
*self
, PyObject
*args
)
6391 char *orgmode
= "r";
6396 if (!PyArg_ParseTuple(args
, "i|si", &fd
, &orgmode
, &bufsize
))
6399 /* Sanitize mode. See fileobject.c */
6400 mode
= PyMem_MALLOC(strlen(orgmode
)+3);
6405 strcpy(mode
, orgmode
);
6406 if (_PyFile_SanitizeMode(mode
)) {
6410 Py_BEGIN_ALLOW_THREADS
6411 #if !defined(MS_WINDOWS) && defined(HAVE_FCNTL_H)
6412 if (mode
[0] == 'a') {
6413 /* try to make sure the O_APPEND flag is set */
6415 flags
= fcntl(fd
, F_GETFL
);
6417 fcntl(fd
, F_SETFL
, flags
| O_APPEND
);
6418 fp
= fdopen(fd
, mode
);
6419 if (fp
== NULL
&& flags
!= -1)
6420 /* restore old mode if fdopen failed */
6421 fcntl(fd
, F_SETFL
, flags
);
6423 fp
= fdopen(fd
, mode
);
6426 fp
= fdopen(fd
, mode
);
6428 Py_END_ALLOW_THREADS
6431 return posix_error();
6432 f
= PyFile_FromFile(fp
, "<fdopen>", orgmode
, fclose
);
6434 PyFile_SetBufSize(f
, bufsize
);
6438 PyDoc_STRVAR(posix_isatty__doc__
,
6439 "isatty(fd) -> bool\n\n\
6440 Return True if the file descriptor 'fd' is an open file descriptor\n\
6441 connected to the slave end of a terminal.");
6444 posix_isatty(PyObject
*self
, PyObject
*args
)
6447 if (!PyArg_ParseTuple(args
, "i:isatty", &fd
))
6449 return PyBool_FromLong(isatty(fd
));
6453 PyDoc_STRVAR(posix_pipe__doc__
,
6454 "pipe() -> (read_end, write_end)\n\n\
6458 posix_pipe(PyObject
*self
, PyObject
*noargs
)
6460 #if defined(PYOS_OS2)
6464 Py_BEGIN_ALLOW_THREADS
6465 rc
= DosCreatePipe( &read
, &write
, 4096);
6466 Py_END_ALLOW_THREADS
6468 return os2_error(rc
);
6470 return Py_BuildValue("(ii)", read
, write
);
6472 #if !defined(MS_WINDOWS)
6475 Py_BEGIN_ALLOW_THREADS
6477 Py_END_ALLOW_THREADS
6479 return posix_error();
6480 return Py_BuildValue("(ii)", fds
[0], fds
[1]);
6481 #else /* MS_WINDOWS */
6483 int read_fd
, write_fd
;
6485 Py_BEGIN_ALLOW_THREADS
6486 ok
= CreatePipe(&read
, &write
, NULL
, 0);
6487 Py_END_ALLOW_THREADS
6489 return win32_error("CreatePipe", NULL
);
6490 read_fd
= _open_osfhandle((Py_intptr_t
)read
, 0);
6491 write_fd
= _open_osfhandle((Py_intptr_t
)write
, 1);
6492 return Py_BuildValue("(ii)", read_fd
, write_fd
);
6493 #endif /* MS_WINDOWS */
6496 #endif /* HAVE_PIPE */
6500 PyDoc_STRVAR(posix_mkfifo__doc__
,
6501 "mkfifo(filename [, mode=0666])\n\n\
6502 Create a FIFO (a POSIX named pipe).");
6505 posix_mkfifo(PyObject
*self
, PyObject
*args
)
6510 if (!PyArg_ParseTuple(args
, "s|i:mkfifo", &filename
, &mode
))
6512 Py_BEGIN_ALLOW_THREADS
6513 res
= mkfifo(filename
, mode
);
6514 Py_END_ALLOW_THREADS
6516 return posix_error();
6523 #if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
6524 PyDoc_STRVAR(posix_mknod__doc__
,
6525 "mknod(filename [, mode=0600, device])\n\n\
6526 Create a filesystem node (file, device special file or named pipe)\n\
6527 named filename. mode specifies both the permissions to use and the\n\
6528 type of node to be created, being combined (bitwise OR) with one of\n\
6529 S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
6530 device defines the newly created device special file (probably using\n\
6531 os.makedev()), otherwise it is ignored.");
6535 posix_mknod(PyObject
*self
, PyObject
*args
)
6541 if (!PyArg_ParseTuple(args
, "s|ii:mknod", &filename
, &mode
, &device
))
6543 Py_BEGIN_ALLOW_THREADS
6544 res
= mknod(filename
, mode
, device
);
6545 Py_END_ALLOW_THREADS
6547 return posix_error();
6553 #ifdef HAVE_DEVICE_MACROS
6554 PyDoc_STRVAR(posix_major__doc__
,
6555 "major(device) -> major number\n\
6556 Extracts a device major number from a raw device number.");
6559 posix_major(PyObject
*self
, PyObject
*args
)
6562 if (!PyArg_ParseTuple(args
, "i:major", &device
))
6564 return PyInt_FromLong((long)major(device
));
6567 PyDoc_STRVAR(posix_minor__doc__
,
6568 "minor(device) -> minor number\n\
6569 Extracts a device minor number from a raw device number.");
6572 posix_minor(PyObject
*self
, PyObject
*args
)
6575 if (!PyArg_ParseTuple(args
, "i:minor", &device
))
6577 return PyInt_FromLong((long)minor(device
));
6580 PyDoc_STRVAR(posix_makedev__doc__
,
6581 "makedev(major, minor) -> device number\n\
6582 Composes a raw device number from the major and minor device numbers.");
6585 posix_makedev(PyObject
*self
, PyObject
*args
)
6588 if (!PyArg_ParseTuple(args
, "ii:makedev", &major
, &minor
))
6590 return PyInt_FromLong((long)makedev(major
, minor
));
6592 #endif /* device macros */
6595 #ifdef HAVE_FTRUNCATE
6596 PyDoc_STRVAR(posix_ftruncate__doc__
,
6597 "ftruncate(fd, length)\n\n\
6598 Truncate a file to a specified length.");
6601 posix_ftruncate(PyObject
*self
, PyObject
*args
)
6608 if (!PyArg_ParseTuple(args
, "iO:ftruncate", &fd
, &lenobj
))
6611 #if !defined(HAVE_LARGEFILE_SUPPORT)
6612 length
= PyInt_AsLong(lenobj
);
6614 length
= PyLong_Check(lenobj
) ?
6615 PyLong_AsLongLong(lenobj
) : PyInt_AsLong(lenobj
);
6617 if (PyErr_Occurred())
6620 Py_BEGIN_ALLOW_THREADS
6621 res
= ftruncate(fd
, length
);
6622 Py_END_ALLOW_THREADS
6624 PyErr_SetFromErrno(PyExc_IOError
);
6633 PyDoc_STRVAR(posix_putenv__doc__
,
6634 "putenv(key, value)\n\n\
6635 Change or add an environment variable.");
6637 /* Save putenv() parameters as values here, so we can collect them when they
6638 * get re-set with another call for the same key. */
6639 static PyObject
*posix_putenv_garbage
;
6642 posix_putenv(PyObject
*self
, PyObject
*args
)
6649 if (!PyArg_ParseTuple(args
, "ss:putenv", &s1
, &s2
))
6652 #if defined(PYOS_OS2)
6653 if (stricmp(s1
, "BEGINLIBPATH") == 0) {
6656 rc
= DosSetExtLIBPATH(s2
, BEGIN_LIBPATH
);
6658 return os2_error(rc
);
6660 } else if (stricmp(s1
, "ENDLIBPATH") == 0) {
6663 rc
= DosSetExtLIBPATH(s2
, END_LIBPATH
);
6665 return os2_error(rc
);
6669 /* XXX This can leak memory -- not easy to fix :-( */
6670 len
= strlen(s1
) + strlen(s2
) + 2;
6671 /* len includes space for a trailing \0; the size arg to
6672 PyString_FromStringAndSize does not count that */
6673 newstr
= PyString_FromStringAndSize(NULL
, (int)len
- 1);
6675 return PyErr_NoMemory();
6676 newenv
= PyString_AS_STRING(newstr
);
6677 PyOS_snprintf(newenv
, len
, "%s=%s", s1
, s2
);
6678 if (putenv(newenv
)) {
6683 /* Install the first arg and newstr in posix_putenv_garbage;
6684 * this will cause previous value to be collected. This has to
6685 * happen after the real putenv() call because the old value
6686 * was still accessible until then. */
6687 if (PyDict_SetItem(posix_putenv_garbage
,
6688 PyTuple_GET_ITEM(args
, 0), newstr
)) {
6689 /* really not much we can do; just leak */
6696 #if defined(PYOS_OS2)
6704 #ifdef HAVE_UNSETENV
6705 PyDoc_STRVAR(posix_unsetenv__doc__
,
6707 Delete an environment variable.");
6710 posix_unsetenv(PyObject
*self
, PyObject
*args
)
6714 if (!PyArg_ParseTuple(args
, "s:unsetenv", &s1
))
6719 /* Remove the key from posix_putenv_garbage;
6720 * this will cause it to be collected. This has to
6721 * happen after the real unsetenv() call because the
6722 * old value was still accessible until then.
6724 if (PyDict_DelItem(posix_putenv_garbage
,
6725 PyTuple_GET_ITEM(args
, 0))) {
6726 /* really not much we can do; just leak */
6733 #endif /* unsetenv */
6735 PyDoc_STRVAR(posix_strerror__doc__
,
6736 "strerror(code) -> string\n\n\
6737 Translate an error code to a message string.");
6740 posix_strerror(PyObject
*self
, PyObject
*args
)
6744 if (!PyArg_ParseTuple(args
, "i:strerror", &code
))
6746 message
= strerror(code
);
6747 if (message
== NULL
) {
6748 PyErr_SetString(PyExc_ValueError
,
6749 "strerror() argument out of range");
6752 return PyString_FromString(message
);
6756 #ifdef HAVE_SYS_WAIT_H
6759 PyDoc_STRVAR(posix_WCOREDUMP__doc__
,
6760 "WCOREDUMP(status) -> bool\n\n\
6761 Return True if the process returning 'status' was dumped to a core file.");
6764 posix_WCOREDUMP(PyObject
*self
, PyObject
*args
)
6767 WAIT_STATUS_INT(status
) = 0;
6769 if (!PyArg_ParseTuple(args
, "i:WCOREDUMP", &WAIT_STATUS_INT(status
)))
6772 return PyBool_FromLong(WCOREDUMP(status
));
6774 #endif /* WCOREDUMP */
6777 PyDoc_STRVAR(posix_WIFCONTINUED__doc__
,
6778 "WIFCONTINUED(status) -> bool\n\n\
6779 Return True if the process returning 'status' was continued from a\n\
6780 job control stop.");
6783 posix_WIFCONTINUED(PyObject
*self
, PyObject
*args
)
6786 WAIT_STATUS_INT(status
) = 0;
6788 if (!PyArg_ParseTuple(args
, "i:WCONTINUED", &WAIT_STATUS_INT(status
)))
6791 return PyBool_FromLong(WIFCONTINUED(status
));
6793 #endif /* WIFCONTINUED */
6796 PyDoc_STRVAR(posix_WIFSTOPPED__doc__
,
6797 "WIFSTOPPED(status) -> bool\n\n\
6798 Return True if the process returning 'status' was stopped.");
6801 posix_WIFSTOPPED(PyObject
*self
, PyObject
*args
)
6804 WAIT_STATUS_INT(status
) = 0;
6806 if (!PyArg_ParseTuple(args
, "i:WIFSTOPPED", &WAIT_STATUS_INT(status
)))
6809 return PyBool_FromLong(WIFSTOPPED(status
));
6811 #endif /* WIFSTOPPED */
6814 PyDoc_STRVAR(posix_WIFSIGNALED__doc__
,
6815 "WIFSIGNALED(status) -> bool\n\n\
6816 Return True if the process returning 'status' was terminated by a signal.");
6819 posix_WIFSIGNALED(PyObject
*self
, PyObject
*args
)
6822 WAIT_STATUS_INT(status
) = 0;
6824 if (!PyArg_ParseTuple(args
, "i:WIFSIGNALED", &WAIT_STATUS_INT(status
)))
6827 return PyBool_FromLong(WIFSIGNALED(status
));
6829 #endif /* WIFSIGNALED */
6832 PyDoc_STRVAR(posix_WIFEXITED__doc__
,
6833 "WIFEXITED(status) -> bool\n\n\
6834 Return true if the process returning 'status' exited using the exit()\n\
6838 posix_WIFEXITED(PyObject
*self
, PyObject
*args
)
6841 WAIT_STATUS_INT(status
) = 0;
6843 if (!PyArg_ParseTuple(args
, "i:WIFEXITED", &WAIT_STATUS_INT(status
)))
6846 return PyBool_FromLong(WIFEXITED(status
));
6848 #endif /* WIFEXITED */
6851 PyDoc_STRVAR(posix_WEXITSTATUS__doc__
,
6852 "WEXITSTATUS(status) -> integer\n\n\
6853 Return the process return code from 'status'.");
6856 posix_WEXITSTATUS(PyObject
*self
, PyObject
*args
)
6859 WAIT_STATUS_INT(status
) = 0;
6861 if (!PyArg_ParseTuple(args
, "i:WEXITSTATUS", &WAIT_STATUS_INT(status
)))
6864 return Py_BuildValue("i", WEXITSTATUS(status
));
6866 #endif /* WEXITSTATUS */
6869 PyDoc_STRVAR(posix_WTERMSIG__doc__
,
6870 "WTERMSIG(status) -> integer\n\n\
6871 Return the signal that terminated the process that provided the 'status'\n\
6875 posix_WTERMSIG(PyObject
*self
, PyObject
*args
)
6878 WAIT_STATUS_INT(status
) = 0;
6880 if (!PyArg_ParseTuple(args
, "i:WTERMSIG", &WAIT_STATUS_INT(status
)))
6883 return Py_BuildValue("i", WTERMSIG(status
));
6885 #endif /* WTERMSIG */
6888 PyDoc_STRVAR(posix_WSTOPSIG__doc__
,
6889 "WSTOPSIG(status) -> integer\n\n\
6890 Return the signal that stopped the process that provided\n\
6891 the 'status' value.");
6894 posix_WSTOPSIG(PyObject
*self
, PyObject
*args
)
6897 WAIT_STATUS_INT(status
) = 0;
6899 if (!PyArg_ParseTuple(args
, "i:WSTOPSIG", &WAIT_STATUS_INT(status
)))
6902 return Py_BuildValue("i", WSTOPSIG(status
));
6904 #endif /* WSTOPSIG */
6906 #endif /* HAVE_SYS_WAIT_H */
6909 #if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
6911 /* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
6912 needed definitions in sys/statvfs.h */
6915 #include <sys/statvfs.h>
6918 _pystatvfs_fromstructstatvfs(struct statvfs st
) {
6919 PyObject
*v
= PyStructSequence_New(&StatVFSResultType
);
6923 #if !defined(HAVE_LARGEFILE_SUPPORT)
6924 PyStructSequence_SET_ITEM(v
, 0, PyInt_FromLong((long) st
.f_bsize
));
6925 PyStructSequence_SET_ITEM(v
, 1, PyInt_FromLong((long) st
.f_frsize
));
6926 PyStructSequence_SET_ITEM(v
, 2, PyInt_FromLong((long) st
.f_blocks
));
6927 PyStructSequence_SET_ITEM(v
, 3, PyInt_FromLong((long) st
.f_bfree
));
6928 PyStructSequence_SET_ITEM(v
, 4, PyInt_FromLong((long) st
.f_bavail
));
6929 PyStructSequence_SET_ITEM(v
, 5, PyInt_FromLong((long) st
.f_files
));
6930 PyStructSequence_SET_ITEM(v
, 6, PyInt_FromLong((long) st
.f_ffree
));
6931 PyStructSequence_SET_ITEM(v
, 7, PyInt_FromLong((long) st
.f_favail
));
6932 PyStructSequence_SET_ITEM(v
, 8, PyInt_FromLong((long) st
.f_flag
));
6933 PyStructSequence_SET_ITEM(v
, 9, PyInt_FromLong((long) st
.f_namemax
));
6935 PyStructSequence_SET_ITEM(v
, 0, PyInt_FromLong((long) st
.f_bsize
));
6936 PyStructSequence_SET_ITEM(v
, 1, PyInt_FromLong((long) st
.f_frsize
));
6937 PyStructSequence_SET_ITEM(v
, 2,
6938 PyLong_FromLongLong((PY_LONG_LONG
) st
.f_blocks
));
6939 PyStructSequence_SET_ITEM(v
, 3,
6940 PyLong_FromLongLong((PY_LONG_LONG
) st
.f_bfree
));
6941 PyStructSequence_SET_ITEM(v
, 4,
6942 PyLong_FromLongLong((PY_LONG_LONG
) st
.f_bavail
));
6943 PyStructSequence_SET_ITEM(v
, 5,
6944 PyLong_FromLongLong((PY_LONG_LONG
) st
.f_files
));
6945 PyStructSequence_SET_ITEM(v
, 6,
6946 PyLong_FromLongLong((PY_LONG_LONG
) st
.f_ffree
));
6947 PyStructSequence_SET_ITEM(v
, 7,
6948 PyLong_FromLongLong((PY_LONG_LONG
) st
.f_favail
));
6949 PyStructSequence_SET_ITEM(v
, 8, PyInt_FromLong((long) st
.f_flag
));
6950 PyStructSequence_SET_ITEM(v
, 9, PyInt_FromLong((long) st
.f_namemax
));
6956 PyDoc_STRVAR(posix_fstatvfs__doc__
,
6957 "fstatvfs(fd) -> statvfs result\n\n\
6958 Perform an fstatvfs system call on the given fd.");
6961 posix_fstatvfs(PyObject
*self
, PyObject
*args
)
6966 if (!PyArg_ParseTuple(args
, "i:fstatvfs", &fd
))
6968 Py_BEGIN_ALLOW_THREADS
6969 res
= fstatvfs(fd
, &st
);
6970 Py_END_ALLOW_THREADS
6972 return posix_error();
6974 return _pystatvfs_fromstructstatvfs(st
);
6976 #endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
6979 #if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
6980 #include <sys/statvfs.h>
6982 PyDoc_STRVAR(posix_statvfs__doc__
,
6983 "statvfs(path) -> statvfs result\n\n\
6984 Perform a statvfs system call on the given path.");
6987 posix_statvfs(PyObject
*self
, PyObject
*args
)
6992 if (!PyArg_ParseTuple(args
, "s:statvfs", &path
))
6994 Py_BEGIN_ALLOW_THREADS
6995 res
= statvfs(path
, &st
);
6996 Py_END_ALLOW_THREADS
6998 return posix_error_with_filename(path
);
7000 return _pystatvfs_fromstructstatvfs(st
);
7002 #endif /* HAVE_STATVFS */
7006 PyDoc_STRVAR(posix_tempnam__doc__
,
7007 "tempnam([dir[, prefix]]) -> string\n\n\
7008 Return a unique name for a temporary file.\n\
7009 The directory and a prefix may be specified as strings; they may be omitted\n\
7010 or None if not needed.");
7013 posix_tempnam(PyObject
*self
, PyObject
*args
)
7015 PyObject
*result
= NULL
;
7020 if (!PyArg_ParseTuple(args
, "|zz:tempnam", &dir
, &pfx
))
7023 if (PyErr_Warn(PyExc_RuntimeWarning
,
7024 "tempnam is a potential security risk to your program") < 0)
7028 name
= _tempnam(dir
, pfx
);
7030 name
= tempnam(dir
, pfx
);
7033 return PyErr_NoMemory();
7034 result
= PyString_FromString(name
);
7042 PyDoc_STRVAR(posix_tmpfile__doc__
,
7043 "tmpfile() -> file object\n\n\
7044 Create a temporary file with no directory entries.");
7047 posix_tmpfile(PyObject
*self
, PyObject
*noargs
)
7053 return posix_error();
7054 return PyFile_FromFile(fp
, "<tmpfile>", "w+b", fclose
);
7060 PyDoc_STRVAR(posix_tmpnam__doc__
,
7061 "tmpnam() -> string\n\n\
7062 Return a unique name for a temporary file.");
7065 posix_tmpnam(PyObject
*self
, PyObject
*noargs
)
7067 char buffer
[L_tmpnam
];
7070 if (PyErr_Warn(PyExc_RuntimeWarning
,
7071 "tmpnam is a potential security risk to your program") < 0)
7075 name
= tmpnam_r(buffer
);
7077 name
= tmpnam(buffer
);
7080 PyObject
*err
= Py_BuildValue("is", 0,
7082 "unexpected NULL from tmpnam_r"
7084 "unexpected NULL from tmpnam"
7087 PyErr_SetObject(PyExc_OSError
, err
);
7091 return PyString_FromString(buffer
);
7096 /* This is used for fpathconf(), pathconf(), confstr() and sysconf().
7097 * It maps strings representing configuration variable names to
7098 * integer values, allowing those functions to be called with the
7099 * magic names instead of polluting the module's namespace with tons of
7100 * rarely-used constants. There are three separate tables that use
7101 * these definitions.
7103 * This code is always included, even if none of the interfaces that
7104 * need it are included. The #if hackery needed to avoid it would be
7105 * sufficiently pervasive that it's not worth the loss of readability.
7113 conv_confname(PyObject
*arg
, int *valuep
, struct constdef
*table
,
7116 if (PyInt_Check(arg
)) {
7117 *valuep
= PyInt_AS_LONG(arg
);
7120 if (PyString_Check(arg
)) {
7121 /* look up the value in the table using a binary search */
7124 size_t hi
= tablesize
;
7126 char *confname
= PyString_AS_STRING(arg
);
7128 mid
= (lo
+ hi
) / 2;
7129 cmp
= strcmp(confname
, table
[mid
].name
);
7135 *valuep
= table
[mid
].value
;
7139 PyErr_SetString(PyExc_ValueError
, "unrecognized configuration name");
7142 PyErr_SetString(PyExc_TypeError
,
7143 "configuration names must be strings or integers");
7148 #if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
7149 static struct constdef posix_constants_pathconf
[] = {
7150 #ifdef _PC_ABI_AIO_XFER_MAX
7151 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX
},
7153 #ifdef _PC_ABI_ASYNC_IO
7154 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO
},
7157 {"PC_ASYNC_IO", _PC_ASYNC_IO
},
7159 #ifdef _PC_CHOWN_RESTRICTED
7160 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED
},
7162 #ifdef _PC_FILESIZEBITS
7163 {"PC_FILESIZEBITS", _PC_FILESIZEBITS
},
7166 {"PC_LAST", _PC_LAST
},
7169 {"PC_LINK_MAX", _PC_LINK_MAX
},
7171 #ifdef _PC_MAX_CANON
7172 {"PC_MAX_CANON", _PC_MAX_CANON
},
7174 #ifdef _PC_MAX_INPUT
7175 {"PC_MAX_INPUT", _PC_MAX_INPUT
},
7178 {"PC_NAME_MAX", _PC_NAME_MAX
},
7181 {"PC_NO_TRUNC", _PC_NO_TRUNC
},
7184 {"PC_PATH_MAX", _PC_PATH_MAX
},
7187 {"PC_PIPE_BUF", _PC_PIPE_BUF
},
7190 {"PC_PRIO_IO", _PC_PRIO_IO
},
7192 #ifdef _PC_SOCK_MAXBUF
7193 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF
},
7196 {"PC_SYNC_IO", _PC_SYNC_IO
},
7199 {"PC_VDISABLE", _PC_VDISABLE
},
7204 conv_path_confname(PyObject
*arg
, int *valuep
)
7206 return conv_confname(arg
, valuep
, posix_constants_pathconf
,
7207 sizeof(posix_constants_pathconf
)
7208 / sizeof(struct constdef
));
7212 #ifdef HAVE_FPATHCONF
7213 PyDoc_STRVAR(posix_fpathconf__doc__
,
7214 "fpathconf(fd, name) -> integer\n\n\
7215 Return the configuration limit name for the file descriptor fd.\n\
7216 If there is no limit, return -1.");
7219 posix_fpathconf(PyObject
*self
, PyObject
*args
)
7221 PyObject
*result
= NULL
;
7224 if (PyArg_ParseTuple(args
, "iO&:fpathconf", &fd
,
7225 conv_path_confname
, &name
)) {
7229 limit
= fpathconf(fd
, name
);
7230 if (limit
== -1 && errno
!= 0)
7233 result
= PyInt_FromLong(limit
);
7240 #ifdef HAVE_PATHCONF
7241 PyDoc_STRVAR(posix_pathconf__doc__
,
7242 "pathconf(path, name) -> integer\n\n\
7243 Return the configuration limit name for the file or directory path.\n\
7244 If there is no limit, return -1.");
7247 posix_pathconf(PyObject
*self
, PyObject
*args
)
7249 PyObject
*result
= NULL
;
7253 if (PyArg_ParseTuple(args
, "sO&:pathconf", &path
,
7254 conv_path_confname
, &name
)) {
7258 limit
= pathconf(path
, name
);
7259 if (limit
== -1 && errno
!= 0) {
7260 if (errno
== EINVAL
)
7261 /* could be a path or name problem */
7264 posix_error_with_filename(path
);
7267 result
= PyInt_FromLong(limit
);
7274 static struct constdef posix_constants_confstr
[] = {
7275 #ifdef _CS_ARCHITECTURE
7276 {"CS_ARCHITECTURE", _CS_ARCHITECTURE
},
7279 {"CS_HOSTNAME", _CS_HOSTNAME
},
7281 #ifdef _CS_HW_PROVIDER
7282 {"CS_HW_PROVIDER", _CS_HW_PROVIDER
},
7284 #ifdef _CS_HW_SERIAL
7285 {"CS_HW_SERIAL", _CS_HW_SERIAL
},
7287 #ifdef _CS_INITTAB_NAME
7288 {"CS_INITTAB_NAME", _CS_INITTAB_NAME
},
7290 #ifdef _CS_LFS64_CFLAGS
7291 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS
},
7293 #ifdef _CS_LFS64_LDFLAGS
7294 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS
},
7296 #ifdef _CS_LFS64_LIBS
7297 {"CS_LFS64_LIBS", _CS_LFS64_LIBS
},
7299 #ifdef _CS_LFS64_LINTFLAGS
7300 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS
},
7302 #ifdef _CS_LFS_CFLAGS
7303 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS
},
7305 #ifdef _CS_LFS_LDFLAGS
7306 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS
},
7309 {"CS_LFS_LIBS", _CS_LFS_LIBS
},
7311 #ifdef _CS_LFS_LINTFLAGS
7312 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS
},
7315 {"CS_MACHINE", _CS_MACHINE
},
7318 {"CS_PATH", _CS_PATH
},
7321 {"CS_RELEASE", _CS_RELEASE
},
7323 #ifdef _CS_SRPC_DOMAIN
7324 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN
},
7327 {"CS_SYSNAME", _CS_SYSNAME
},
7330 {"CS_VERSION", _CS_VERSION
},
7332 #ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
7333 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS
},
7335 #ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
7336 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS
},
7338 #ifdef _CS_XBS5_ILP32_OFF32_LIBS
7339 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS
},
7341 #ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
7342 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS
},
7344 #ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
7345 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS
},
7347 #ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
7348 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS
},
7350 #ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
7351 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS
},
7353 #ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
7354 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
},
7356 #ifdef _CS_XBS5_LP64_OFF64_CFLAGS
7357 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS
},
7359 #ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
7360 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS
},
7362 #ifdef _CS_XBS5_LP64_OFF64_LIBS
7363 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS
},
7365 #ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
7366 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS
},
7368 #ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
7369 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS
},
7371 #ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
7372 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
},
7374 #ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
7375 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS
},
7377 #ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
7378 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
},
7380 #ifdef _MIPS_CS_AVAIL_PROCESSORS
7381 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS
},
7383 #ifdef _MIPS_CS_BASE
7384 {"MIPS_CS_BASE", _MIPS_CS_BASE
},
7386 #ifdef _MIPS_CS_HOSTID
7387 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID
},
7389 #ifdef _MIPS_CS_HW_NAME
7390 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME
},
7392 #ifdef _MIPS_CS_NUM_PROCESSORS
7393 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS
},
7395 #ifdef _MIPS_CS_OSREL_MAJ
7396 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ
},
7398 #ifdef _MIPS_CS_OSREL_MIN
7399 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN
},
7401 #ifdef _MIPS_CS_OSREL_PATCH
7402 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH
},
7404 #ifdef _MIPS_CS_OS_NAME
7405 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME
},
7407 #ifdef _MIPS_CS_OS_PROVIDER
7408 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER
},
7410 #ifdef _MIPS_CS_PROCESSORS
7411 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS
},
7413 #ifdef _MIPS_CS_SERIAL
7414 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL
},
7416 #ifdef _MIPS_CS_VENDOR
7417 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR
},
7422 conv_confstr_confname(PyObject
*arg
, int *valuep
)
7424 return conv_confname(arg
, valuep
, posix_constants_confstr
,
7425 sizeof(posix_constants_confstr
)
7426 / sizeof(struct constdef
));
7429 PyDoc_STRVAR(posix_confstr__doc__
,
7430 "confstr(name) -> string\n\n\
7431 Return a string-valued system configuration variable.");
7434 posix_confstr(PyObject
*self
, PyObject
*args
)
7436 PyObject
*result
= NULL
;
7440 if (PyArg_ParseTuple(args
, "O&:confstr", conv_confstr_confname
, &name
)) {
7444 len
= confstr(name
, buffer
, sizeof(buffer
));
7455 if ((unsigned int)len
>= sizeof(buffer
)) {
7456 result
= PyString_FromStringAndSize(NULL
, len
-1);
7458 confstr(name
, PyString_AS_STRING(result
), len
);
7461 result
= PyString_FromStringAndSize(buffer
, len
-1);
7470 static struct constdef posix_constants_sysconf
[] = {
7471 #ifdef _SC_2_CHAR_TERM
7472 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM
},
7475 {"SC_2_C_BIND", _SC_2_C_BIND
},
7478 {"SC_2_C_DEV", _SC_2_C_DEV
},
7480 #ifdef _SC_2_C_VERSION
7481 {"SC_2_C_VERSION", _SC_2_C_VERSION
},
7483 #ifdef _SC_2_FORT_DEV
7484 {"SC_2_FORT_DEV", _SC_2_FORT_DEV
},
7486 #ifdef _SC_2_FORT_RUN
7487 {"SC_2_FORT_RUN", _SC_2_FORT_RUN
},
7489 #ifdef _SC_2_LOCALEDEF
7490 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF
},
7493 {"SC_2_SW_DEV", _SC_2_SW_DEV
},
7496 {"SC_2_UPE", _SC_2_UPE
},
7498 #ifdef _SC_2_VERSION
7499 {"SC_2_VERSION", _SC_2_VERSION
},
7501 #ifdef _SC_ABI_ASYNCHRONOUS_IO
7502 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO
},
7505 {"SC_ACL", _SC_ACL
},
7507 #ifdef _SC_AIO_LISTIO_MAX
7508 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX
},
7511 {"SC_AIO_MAX", _SC_AIO_MAX
},
7513 #ifdef _SC_AIO_PRIO_DELTA_MAX
7514 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX
},
7517 {"SC_ARG_MAX", _SC_ARG_MAX
},
7519 #ifdef _SC_ASYNCHRONOUS_IO
7520 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO
},
7522 #ifdef _SC_ATEXIT_MAX
7523 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX
},
7526 {"SC_AUDIT", _SC_AUDIT
},
7528 #ifdef _SC_AVPHYS_PAGES
7529 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES
},
7531 #ifdef _SC_BC_BASE_MAX
7532 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX
},
7534 #ifdef _SC_BC_DIM_MAX
7535 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX
},
7537 #ifdef _SC_BC_SCALE_MAX
7538 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX
},
7540 #ifdef _SC_BC_STRING_MAX
7541 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX
},
7544 {"SC_CAP", _SC_CAP
},
7546 #ifdef _SC_CHARCLASS_NAME_MAX
7547 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX
},
7550 {"SC_CHAR_BIT", _SC_CHAR_BIT
},
7553 {"SC_CHAR_MAX", _SC_CHAR_MAX
},
7556 {"SC_CHAR_MIN", _SC_CHAR_MIN
},
7558 #ifdef _SC_CHILD_MAX
7559 {"SC_CHILD_MAX", _SC_CHILD_MAX
},
7562 {"SC_CLK_TCK", _SC_CLK_TCK
},
7564 #ifdef _SC_COHER_BLKSZ
7565 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ
},
7567 #ifdef _SC_COLL_WEIGHTS_MAX
7568 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX
},
7570 #ifdef _SC_DCACHE_ASSOC
7571 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC
},
7573 #ifdef _SC_DCACHE_BLKSZ
7574 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ
},
7576 #ifdef _SC_DCACHE_LINESZ
7577 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ
},
7579 #ifdef _SC_DCACHE_SZ
7580 {"SC_DCACHE_SZ", _SC_DCACHE_SZ
},
7582 #ifdef _SC_DCACHE_TBLKSZ
7583 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ
},
7585 #ifdef _SC_DELAYTIMER_MAX
7586 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX
},
7588 #ifdef _SC_EQUIV_CLASS_MAX
7589 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX
},
7591 #ifdef _SC_EXPR_NEST_MAX
7592 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX
},
7595 {"SC_FSYNC", _SC_FSYNC
},
7597 #ifdef _SC_GETGR_R_SIZE_MAX
7598 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX
},
7600 #ifdef _SC_GETPW_R_SIZE_MAX
7601 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX
},
7603 #ifdef _SC_ICACHE_ASSOC
7604 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC
},
7606 #ifdef _SC_ICACHE_BLKSZ
7607 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ
},
7609 #ifdef _SC_ICACHE_LINESZ
7610 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ
},
7612 #ifdef _SC_ICACHE_SZ
7613 {"SC_ICACHE_SZ", _SC_ICACHE_SZ
},
7616 {"SC_INF", _SC_INF
},
7619 {"SC_INT_MAX", _SC_INT_MAX
},
7622 {"SC_INT_MIN", _SC_INT_MIN
},
7625 {"SC_IOV_MAX", _SC_IOV_MAX
},
7627 #ifdef _SC_IP_SECOPTS
7628 {"SC_IP_SECOPTS", _SC_IP_SECOPTS
},
7630 #ifdef _SC_JOB_CONTROL
7631 {"SC_JOB_CONTROL", _SC_JOB_CONTROL
},
7633 #ifdef _SC_KERN_POINTERS
7634 {"SC_KERN_POINTERS", _SC_KERN_POINTERS
},
7637 {"SC_KERN_SIM", _SC_KERN_SIM
},
7640 {"SC_LINE_MAX", _SC_LINE_MAX
},
7642 #ifdef _SC_LOGIN_NAME_MAX
7643 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX
},
7645 #ifdef _SC_LOGNAME_MAX
7646 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX
},
7649 {"SC_LONG_BIT", _SC_LONG_BIT
},
7652 {"SC_MAC", _SC_MAC
},
7654 #ifdef _SC_MAPPED_FILES
7655 {"SC_MAPPED_FILES", _SC_MAPPED_FILES
},
7658 {"SC_MAXPID", _SC_MAXPID
},
7660 #ifdef _SC_MB_LEN_MAX
7661 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX
},
7664 {"SC_MEMLOCK", _SC_MEMLOCK
},
7666 #ifdef _SC_MEMLOCK_RANGE
7667 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE
},
7669 #ifdef _SC_MEMORY_PROTECTION
7670 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION
},
7672 #ifdef _SC_MESSAGE_PASSING
7673 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING
},
7675 #ifdef _SC_MMAP_FIXED_ALIGNMENT
7676 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT
},
7678 #ifdef _SC_MQ_OPEN_MAX
7679 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX
},
7681 #ifdef _SC_MQ_PRIO_MAX
7682 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX
},
7684 #ifdef _SC_NACLS_MAX
7685 {"SC_NACLS_MAX", _SC_NACLS_MAX
},
7687 #ifdef _SC_NGROUPS_MAX
7688 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX
},
7690 #ifdef _SC_NL_ARGMAX
7691 {"SC_NL_ARGMAX", _SC_NL_ARGMAX
},
7693 #ifdef _SC_NL_LANGMAX
7694 {"SC_NL_LANGMAX", _SC_NL_LANGMAX
},
7696 #ifdef _SC_NL_MSGMAX
7697 {"SC_NL_MSGMAX", _SC_NL_MSGMAX
},
7700 {"SC_NL_NMAX", _SC_NL_NMAX
},
7702 #ifdef _SC_NL_SETMAX
7703 {"SC_NL_SETMAX", _SC_NL_SETMAX
},
7705 #ifdef _SC_NL_TEXTMAX
7706 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX
},
7708 #ifdef _SC_NPROCESSORS_CONF
7709 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF
},
7711 #ifdef _SC_NPROCESSORS_ONLN
7712 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN
},
7714 #ifdef _SC_NPROC_CONF
7715 {"SC_NPROC_CONF", _SC_NPROC_CONF
},
7717 #ifdef _SC_NPROC_ONLN
7718 {"SC_NPROC_ONLN", _SC_NPROC_ONLN
},
7721 {"SC_NZERO", _SC_NZERO
},
7724 {"SC_OPEN_MAX", _SC_OPEN_MAX
},
7727 {"SC_PAGESIZE", _SC_PAGESIZE
},
7729 #ifdef _SC_PAGE_SIZE
7730 {"SC_PAGE_SIZE", _SC_PAGE_SIZE
},
7733 {"SC_PASS_MAX", _SC_PASS_MAX
},
7735 #ifdef _SC_PHYS_PAGES
7736 {"SC_PHYS_PAGES", _SC_PHYS_PAGES
},
7739 {"SC_PII", _SC_PII
},
7741 #ifdef _SC_PII_INTERNET
7742 {"SC_PII_INTERNET", _SC_PII_INTERNET
},
7744 #ifdef _SC_PII_INTERNET_DGRAM
7745 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM
},
7747 #ifdef _SC_PII_INTERNET_STREAM
7748 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM
},
7751 {"SC_PII_OSI", _SC_PII_OSI
},
7753 #ifdef _SC_PII_OSI_CLTS
7754 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS
},
7756 #ifdef _SC_PII_OSI_COTS
7757 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS
},
7759 #ifdef _SC_PII_OSI_M
7760 {"SC_PII_OSI_M", _SC_PII_OSI_M
},
7762 #ifdef _SC_PII_SOCKET
7763 {"SC_PII_SOCKET", _SC_PII_SOCKET
},
7766 {"SC_PII_XTI", _SC_PII_XTI
},
7769 {"SC_POLL", _SC_POLL
},
7771 #ifdef _SC_PRIORITIZED_IO
7772 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO
},
7774 #ifdef _SC_PRIORITY_SCHEDULING
7775 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING
},
7777 #ifdef _SC_REALTIME_SIGNALS
7778 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS
},
7780 #ifdef _SC_RE_DUP_MAX
7781 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX
},
7783 #ifdef _SC_RTSIG_MAX
7784 {"SC_RTSIG_MAX", _SC_RTSIG_MAX
},
7786 #ifdef _SC_SAVED_IDS
7787 {"SC_SAVED_IDS", _SC_SAVED_IDS
},
7789 #ifdef _SC_SCHAR_MAX
7790 {"SC_SCHAR_MAX", _SC_SCHAR_MAX
},
7792 #ifdef _SC_SCHAR_MIN
7793 {"SC_SCHAR_MIN", _SC_SCHAR_MIN
},
7796 {"SC_SELECT", _SC_SELECT
},
7798 #ifdef _SC_SEMAPHORES
7799 {"SC_SEMAPHORES", _SC_SEMAPHORES
},
7801 #ifdef _SC_SEM_NSEMS_MAX
7802 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX
},
7804 #ifdef _SC_SEM_VALUE_MAX
7805 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX
},
7807 #ifdef _SC_SHARED_MEMORY_OBJECTS
7808 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS
},
7811 {"SC_SHRT_MAX", _SC_SHRT_MAX
},
7814 {"SC_SHRT_MIN", _SC_SHRT_MIN
},
7816 #ifdef _SC_SIGQUEUE_MAX
7817 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX
},
7819 #ifdef _SC_SIGRT_MAX
7820 {"SC_SIGRT_MAX", _SC_SIGRT_MAX
},
7822 #ifdef _SC_SIGRT_MIN
7823 {"SC_SIGRT_MIN", _SC_SIGRT_MIN
},
7825 #ifdef _SC_SOFTPOWER
7826 {"SC_SOFTPOWER", _SC_SOFTPOWER
},
7828 #ifdef _SC_SPLIT_CACHE
7829 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE
},
7831 #ifdef _SC_SSIZE_MAX
7832 {"SC_SSIZE_MAX", _SC_SSIZE_MAX
},
7834 #ifdef _SC_STACK_PROT
7835 {"SC_STACK_PROT", _SC_STACK_PROT
},
7837 #ifdef _SC_STREAM_MAX
7838 {"SC_STREAM_MAX", _SC_STREAM_MAX
},
7840 #ifdef _SC_SYNCHRONIZED_IO
7841 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO
},
7844 {"SC_THREADS", _SC_THREADS
},
7846 #ifdef _SC_THREAD_ATTR_STACKADDR
7847 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR
},
7849 #ifdef _SC_THREAD_ATTR_STACKSIZE
7850 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE
},
7852 #ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
7853 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS
},
7855 #ifdef _SC_THREAD_KEYS_MAX
7856 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX
},
7858 #ifdef _SC_THREAD_PRIORITY_SCHEDULING
7859 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING
},
7861 #ifdef _SC_THREAD_PRIO_INHERIT
7862 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT
},
7864 #ifdef _SC_THREAD_PRIO_PROTECT
7865 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT
},
7867 #ifdef _SC_THREAD_PROCESS_SHARED
7868 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED
},
7870 #ifdef _SC_THREAD_SAFE_FUNCTIONS
7871 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS
},
7873 #ifdef _SC_THREAD_STACK_MIN
7874 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN
},
7876 #ifdef _SC_THREAD_THREADS_MAX
7877 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX
},
7880 {"SC_TIMERS", _SC_TIMERS
},
7882 #ifdef _SC_TIMER_MAX
7883 {"SC_TIMER_MAX", _SC_TIMER_MAX
},
7885 #ifdef _SC_TTY_NAME_MAX
7886 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX
},
7888 #ifdef _SC_TZNAME_MAX
7889 {"SC_TZNAME_MAX", _SC_TZNAME_MAX
},
7891 #ifdef _SC_T_IOV_MAX
7892 {"SC_T_IOV_MAX", _SC_T_IOV_MAX
},
7894 #ifdef _SC_UCHAR_MAX
7895 {"SC_UCHAR_MAX", _SC_UCHAR_MAX
},
7898 {"SC_UINT_MAX", _SC_UINT_MAX
},
7900 #ifdef _SC_UIO_MAXIOV
7901 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV
},
7903 #ifdef _SC_ULONG_MAX
7904 {"SC_ULONG_MAX", _SC_ULONG_MAX
},
7906 #ifdef _SC_USHRT_MAX
7907 {"SC_USHRT_MAX", _SC_USHRT_MAX
},
7910 {"SC_VERSION", _SC_VERSION
},
7913 {"SC_WORD_BIT", _SC_WORD_BIT
},
7915 #ifdef _SC_XBS5_ILP32_OFF32
7916 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32
},
7918 #ifdef _SC_XBS5_ILP32_OFFBIG
7919 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG
},
7921 #ifdef _SC_XBS5_LP64_OFF64
7922 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64
},
7924 #ifdef _SC_XBS5_LPBIG_OFFBIG
7925 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG
},
7927 #ifdef _SC_XOPEN_CRYPT
7928 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT
},
7930 #ifdef _SC_XOPEN_ENH_I18N
7931 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N
},
7933 #ifdef _SC_XOPEN_LEGACY
7934 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY
},
7936 #ifdef _SC_XOPEN_REALTIME
7937 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME
},
7939 #ifdef _SC_XOPEN_REALTIME_THREADS
7940 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS
},
7942 #ifdef _SC_XOPEN_SHM
7943 {"SC_XOPEN_SHM", _SC_XOPEN_SHM
},
7945 #ifdef _SC_XOPEN_UNIX
7946 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX
},
7948 #ifdef _SC_XOPEN_VERSION
7949 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION
},
7951 #ifdef _SC_XOPEN_XCU_VERSION
7952 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION
},
7954 #ifdef _SC_XOPEN_XPG2
7955 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2
},
7957 #ifdef _SC_XOPEN_XPG3
7958 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3
},
7960 #ifdef _SC_XOPEN_XPG4
7961 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4
},
7966 conv_sysconf_confname(PyObject
*arg
, int *valuep
)
7968 return conv_confname(arg
, valuep
, posix_constants_sysconf
,
7969 sizeof(posix_constants_sysconf
)
7970 / sizeof(struct constdef
));
7973 PyDoc_STRVAR(posix_sysconf__doc__
,
7974 "sysconf(name) -> integer\n\n\
7975 Return an integer-valued system configuration variable.");
7978 posix_sysconf(PyObject
*self
, PyObject
*args
)
7980 PyObject
*result
= NULL
;
7983 if (PyArg_ParseTuple(args
, "O&:sysconf", conv_sysconf_confname
, &name
)) {
7987 value
= sysconf(name
);
7988 if (value
== -1 && errno
!= 0)
7991 result
= PyInt_FromLong(value
);
7998 /* This code is used to ensure that the tables of configuration value names
7999 * are in sorted order as required by conv_confname(), and also to build the
8000 * the exported dictionaries that are used to publish information about the
8001 * names available on the host platform.
8003 * Sorting the table at runtime ensures that the table is properly ordered
8004 * when used, even for platforms we're not able to test on. It also makes
8005 * it easier to add additional entries to the tables.
8009 cmp_constdefs(const void *v1
, const void *v2
)
8011 const struct constdef
*c1
=
8012 (const struct constdef
*) v1
;
8013 const struct constdef
*c2
=
8014 (const struct constdef
*) v2
;
8016 return strcmp(c1
->name
, c2
->name
);
8020 setup_confname_table(struct constdef
*table
, size_t tablesize
,
8021 char *tablename
, PyObject
*module
)
8026 qsort(table
, tablesize
, sizeof(struct constdef
), cmp_constdefs
);
8031 for (i
=0; i
< tablesize
; ++i
) {
8032 PyObject
*o
= PyInt_FromLong(table
[i
].value
);
8033 if (o
== NULL
|| PyDict_SetItemString(d
, table
[i
].name
, o
) == -1) {
8040 return PyModule_AddObject(module
, tablename
, d
);
8043 /* Return -1 on failure, 0 on success. */
8045 setup_confname_tables(PyObject
*module
)
8047 #if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
8048 if (setup_confname_table(posix_constants_pathconf
,
8049 sizeof(posix_constants_pathconf
)
8050 / sizeof(struct constdef
),
8051 "pathconf_names", module
))
8055 if (setup_confname_table(posix_constants_confstr
,
8056 sizeof(posix_constants_confstr
)
8057 / sizeof(struct constdef
),
8058 "confstr_names", module
))
8062 if (setup_confname_table(posix_constants_sysconf
,
8063 sizeof(posix_constants_sysconf
)
8064 / sizeof(struct constdef
),
8065 "sysconf_names", module
))
8072 PyDoc_STRVAR(posix_abort__doc__
,
8073 "abort() -> does not return!\n\n\
8074 Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
8075 in the hardest way possible on the hosting operating system.");
8078 posix_abort(PyObject
*self
, PyObject
*noargs
)
8082 Py_FatalError("abort() called from Python code didn't abort!");
8087 PyDoc_STRVAR(win32_startfile__doc__
,
8088 "startfile(filepath [, operation]) - Start a file with its associated\n\
8091 When \"operation\" is not specified or \"open\", this acts like\n\
8092 double-clicking the file in Explorer, or giving the file name as an\n\
8093 argument to the DOS \"start\" command: the file is opened with whatever\n\
8094 application (if any) its extension is associated.\n\
8095 When another \"operation\" is given, it specifies what should be done with\n\
8096 the file. A typical operation is \"print\".\n\
8098 startfile returns as soon as the associated application is launched.\n\
8099 There is no option to wait for the application to close, and no way\n\
8100 to retrieve the application's exit status.\n\
8102 The filepath is relative to the current directory. If you want to use\n\
8103 an absolute path, make sure the first character is not a slash (\"/\");\n\
8104 the underlying Win32 ShellExecute function doesn't work if it is.");
8107 win32_startfile(PyObject
*self
, PyObject
*args
)
8110 char *operation
= NULL
;
8112 #ifdef Py_WIN_WIDE_FILENAMES
8113 if (unicode_file_names()) {
8114 PyObject
*unipath
, *woperation
= NULL
;
8115 if (!PyArg_ParseTuple(args
, "U|s:startfile",
8116 &unipath
, &operation
)) {
8123 woperation
= PyUnicode_DecodeASCII(operation
,
8124 strlen(operation
), NULL
);
8132 Py_BEGIN_ALLOW_THREADS
8133 rc
= ShellExecuteW((HWND
)0, woperation
? PyUnicode_AS_UNICODE(woperation
) : 0,
8134 PyUnicode_AS_UNICODE(unipath
),
8135 NULL
, NULL
, SW_SHOWNORMAL
);
8136 Py_END_ALLOW_THREADS
8138 Py_XDECREF(woperation
);
8139 if (rc
<= (HINSTANCE
)32) {
8140 PyObject
*errval
= win32_error_unicode("startfile",
8141 PyUnicode_AS_UNICODE(unipath
));
8150 if (!PyArg_ParseTuple(args
, "et|s:startfile",
8151 Py_FileSystemDefaultEncoding
, &filepath
,
8154 Py_BEGIN_ALLOW_THREADS
8155 rc
= ShellExecute((HWND
)0, operation
, filepath
,
8156 NULL
, NULL
, SW_SHOWNORMAL
);
8157 Py_END_ALLOW_THREADS
8158 if (rc
<= (HINSTANCE
)32) {
8159 PyObject
*errval
= win32_error("startfile", filepath
);
8160 PyMem_Free(filepath
);
8163 PyMem_Free(filepath
);
8169 #ifdef HAVE_GETLOADAVG
8170 PyDoc_STRVAR(posix_getloadavg__doc__
,
8171 "getloadavg() -> (float, float, float)\n\n\
8172 Return the number of processes in the system run queue averaged over\n\
8173 the last 1, 5, and 15 minutes or raises OSError if the load average\n\
8177 posix_getloadavg(PyObject
*self
, PyObject
*noargs
)
8180 if (getloadavg(loadavg
, 3)!=3) {
8181 PyErr_SetString(PyExc_OSError
, "Load averages are unobtainable");
8184 return Py_BuildValue("ddd", loadavg
[0], loadavg
[1], loadavg
[2]);
8190 PyDoc_STRVAR(win32_urandom__doc__
,
8191 "urandom(n) -> str\n\n\
8192 Return a string of n random bytes suitable for cryptographic use.");
8194 typedef BOOL (WINAPI
*CRYPTACQUIRECONTEXTA
)(HCRYPTPROV
*phProv
,\
8195 LPCSTR pszContainer
, LPCSTR pszProvider
, DWORD dwProvType
,\
8197 typedef BOOL (WINAPI
*CRYPTGENRANDOM
)(HCRYPTPROV hProv
, DWORD dwLen
,\
8200 static CRYPTGENRANDOM pCryptGenRandom
= NULL
;
8201 /* This handle is never explicitly released. Instead, the operating
8202 system will release it when the process terminates. */
8203 static HCRYPTPROV hCryptProv
= 0;
8206 win32_urandom(PyObject
*self
, PyObject
*args
)
8211 /* Read arguments */
8212 if (! PyArg_ParseTuple(args
, "i:urandom", &howMany
))
8215 return PyErr_Format(PyExc_ValueError
,
8216 "negative argument not allowed");
8218 if (hCryptProv
== 0) {
8219 HINSTANCE hAdvAPI32
= NULL
;
8220 CRYPTACQUIRECONTEXTA pCryptAcquireContext
= NULL
;
8222 /* Obtain handle to the DLL containing CryptoAPI
8223 This should not fail */
8224 hAdvAPI32
= GetModuleHandle("advapi32.dll");
8225 if(hAdvAPI32
== NULL
)
8226 return win32_error("GetModuleHandle", NULL
);
8228 /* Obtain pointers to the CryptoAPI functions
8229 This will fail on some early versions of Win95 */
8230 pCryptAcquireContext
= (CRYPTACQUIRECONTEXTA
)GetProcAddress(
8232 "CryptAcquireContextA");
8233 if (pCryptAcquireContext
== NULL
)
8234 return PyErr_Format(PyExc_NotImplementedError
,
8235 "CryptAcquireContextA not found");
8237 pCryptGenRandom
= (CRYPTGENRANDOM
)GetProcAddress(
8238 hAdvAPI32
, "CryptGenRandom");
8239 if (pCryptGenRandom
== NULL
)
8240 return PyErr_Format(PyExc_NotImplementedError
,
8241 "CryptGenRandom not found");
8243 /* Acquire context */
8244 if (! pCryptAcquireContext(&hCryptProv
, NULL
, NULL
,
8245 PROV_RSA_FULL
, CRYPT_VERIFYCONTEXT
))
8246 return win32_error("CryptAcquireContext", NULL
);
8249 /* Allocate bytes */
8250 result
= PyString_FromStringAndSize(NULL
, howMany
);
8251 if (result
!= NULL
) {
8252 /* Get random data */
8253 memset(PyString_AS_STRING(result
), 0, howMany
); /* zero seed */
8254 if (! pCryptGenRandom(hCryptProv
, howMany
, (unsigned char*)
8255 PyString_AS_STRING(result
))) {
8257 return win32_error("CryptGenRandom", NULL
);
8265 /* Use openssl random routine */
8266 #include <openssl/rand.h>
8267 PyDoc_STRVAR(vms_urandom__doc__
,
8268 "urandom(n) -> str\n\n\
8269 Return a string of n random bytes suitable for cryptographic use.");
8272 vms_urandom(PyObject
*self
, PyObject
*args
)
8277 /* Read arguments */
8278 if (! PyArg_ParseTuple(args
, "i:urandom", &howMany
))
8281 return PyErr_Format(PyExc_ValueError
,
8282 "negative argument not allowed");
8284 /* Allocate bytes */
8285 result
= PyString_FromStringAndSize(NULL
, howMany
);
8286 if (result
!= NULL
) {
8287 /* Get random data */
8288 if (RAND_pseudo_bytes((unsigned char*)
8289 PyString_AS_STRING(result
),
8292 return PyErr_Format(PyExc_ValueError
,
8293 "RAND_pseudo_bytes");
8300 static PyMethodDef posix_methods
[] = {
8301 {"access", posix_access
, METH_VARARGS
, posix_access__doc__
},
8303 {"ttyname", posix_ttyname
, METH_VARARGS
, posix_ttyname__doc__
},
8305 {"chdir", posix_chdir
, METH_VARARGS
, posix_chdir__doc__
},
8307 {"chflags", posix_chflags
, METH_VARARGS
, posix_chflags__doc__
},
8308 #endif /* HAVE_CHFLAGS */
8309 {"chmod", posix_chmod
, METH_VARARGS
, posix_chmod__doc__
},
8311 {"fchmod", posix_fchmod
, METH_VARARGS
, posix_fchmod__doc__
},
8312 #endif /* HAVE_FCHMOD */
8314 {"chown", posix_chown
, METH_VARARGS
, posix_chown__doc__
},
8315 #endif /* HAVE_CHOWN */
8317 {"lchmod", posix_lchmod
, METH_VARARGS
, posix_lchmod__doc__
},
8318 #endif /* HAVE_LCHMOD */
8320 {"fchown", posix_fchown
, METH_VARARGS
, posix_fchown__doc__
},
8321 #endif /* HAVE_FCHOWN */
8322 #ifdef HAVE_LCHFLAGS
8323 {"lchflags", posix_lchflags
, METH_VARARGS
, posix_lchflags__doc__
},
8324 #endif /* HAVE_LCHFLAGS */
8326 {"lchown", posix_lchown
, METH_VARARGS
, posix_lchown__doc__
},
8327 #endif /* HAVE_LCHOWN */
8329 {"chroot", posix_chroot
, METH_VARARGS
, posix_chroot__doc__
},
8332 {"ctermid", posix_ctermid
, METH_NOARGS
, posix_ctermid__doc__
},
8335 {"getcwd", posix_getcwd
, METH_NOARGS
, posix_getcwd__doc__
},
8336 #ifdef Py_USING_UNICODE
8337 {"getcwdu", posix_getcwdu
, METH_NOARGS
, posix_getcwdu__doc__
},
8341 {"link", posix_link
, METH_VARARGS
, posix_link__doc__
},
8342 #endif /* HAVE_LINK */
8343 {"listdir", posix_listdir
, METH_VARARGS
, posix_listdir__doc__
},
8344 {"lstat", posix_lstat
, METH_VARARGS
, posix_lstat__doc__
},
8345 {"mkdir", posix_mkdir
, METH_VARARGS
, posix_mkdir__doc__
},
8347 {"nice", posix_nice
, METH_VARARGS
, posix_nice__doc__
},
8348 #endif /* HAVE_NICE */
8349 #ifdef HAVE_READLINK
8350 {"readlink", posix_readlink
, METH_VARARGS
, posix_readlink__doc__
},
8351 #endif /* HAVE_READLINK */
8352 {"rename", posix_rename
, METH_VARARGS
, posix_rename__doc__
},
8353 {"rmdir", posix_rmdir
, METH_VARARGS
, posix_rmdir__doc__
},
8354 {"stat", posix_stat
, METH_VARARGS
, posix_stat__doc__
},
8355 {"stat_float_times", stat_float_times
, METH_VARARGS
, stat_float_times__doc__
},
8357 {"symlink", posix_symlink
, METH_VARARGS
, posix_symlink__doc__
},
8358 #endif /* HAVE_SYMLINK */
8360 {"system", posix_system
, METH_VARARGS
, posix_system__doc__
},
8362 {"umask", posix_umask
, METH_VARARGS
, posix_umask__doc__
},
8364 {"uname", posix_uname
, METH_NOARGS
, posix_uname__doc__
},
8365 #endif /* HAVE_UNAME */
8366 {"unlink", posix_unlink
, METH_VARARGS
, posix_unlink__doc__
},
8367 {"remove", posix_unlink
, METH_VARARGS
, posix_remove__doc__
},
8368 {"utime", posix_utime
, METH_VARARGS
, posix_utime__doc__
},
8370 {"times", posix_times
, METH_NOARGS
, posix_times__doc__
},
8371 #endif /* HAVE_TIMES */
8372 {"_exit", posix__exit
, METH_VARARGS
, posix__exit__doc__
},
8374 {"execv", posix_execv
, METH_VARARGS
, posix_execv__doc__
},
8375 {"execve", posix_execve
, METH_VARARGS
, posix_execve__doc__
},
8376 #endif /* HAVE_EXECV */
8378 {"spawnv", posix_spawnv
, METH_VARARGS
, posix_spawnv__doc__
},
8379 {"spawnve", posix_spawnve
, METH_VARARGS
, posix_spawnve__doc__
},
8380 #if defined(PYOS_OS2)
8381 {"spawnvp", posix_spawnvp
, METH_VARARGS
, posix_spawnvp__doc__
},
8382 {"spawnvpe", posix_spawnvpe
, METH_VARARGS
, posix_spawnvpe__doc__
},
8383 #endif /* PYOS_OS2 */
8384 #endif /* HAVE_SPAWNV */
8386 {"fork1", posix_fork1
, METH_NOARGS
, posix_fork1__doc__
},
8387 #endif /* HAVE_FORK1 */
8389 {"fork", posix_fork
, METH_NOARGS
, posix_fork__doc__
},
8390 #endif /* HAVE_FORK */
8391 #if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
8392 {"openpty", posix_openpty
, METH_NOARGS
, posix_openpty__doc__
},
8393 #endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
8395 {"forkpty", posix_forkpty
, METH_NOARGS
, posix_forkpty__doc__
},
8396 #endif /* HAVE_FORKPTY */
8398 {"getegid", posix_getegid
, METH_NOARGS
, posix_getegid__doc__
},
8399 #endif /* HAVE_GETEGID */
8401 {"geteuid", posix_geteuid
, METH_NOARGS
, posix_geteuid__doc__
},
8402 #endif /* HAVE_GETEUID */
8404 {"getgid", posix_getgid
, METH_NOARGS
, posix_getgid__doc__
},
8405 #endif /* HAVE_GETGID */
8406 #ifdef HAVE_GETGROUPS
8407 {"getgroups", posix_getgroups
, METH_NOARGS
, posix_getgroups__doc__
},
8409 {"getpid", posix_getpid
, METH_NOARGS
, posix_getpid__doc__
},
8411 {"getpgrp", posix_getpgrp
, METH_NOARGS
, posix_getpgrp__doc__
},
8412 #endif /* HAVE_GETPGRP */
8414 {"getppid", posix_getppid
, METH_NOARGS
, posix_getppid__doc__
},
8415 #endif /* HAVE_GETPPID */
8417 {"getuid", posix_getuid
, METH_NOARGS
, posix_getuid__doc__
},
8418 #endif /* HAVE_GETUID */
8419 #ifdef HAVE_GETLOGIN
8420 {"getlogin", posix_getlogin
, METH_NOARGS
, posix_getlogin__doc__
},
8423 {"kill", posix_kill
, METH_VARARGS
, posix_kill__doc__
},
8424 #endif /* HAVE_KILL */
8426 {"killpg", posix_killpg
, METH_VARARGS
, posix_killpg__doc__
},
8427 #endif /* HAVE_KILLPG */
8429 {"plock", posix_plock
, METH_VARARGS
, posix_plock__doc__
},
8430 #endif /* HAVE_PLOCK */
8432 {"popen", posix_popen
, METH_VARARGS
, posix_popen__doc__
},
8434 {"popen2", win32_popen2
, METH_VARARGS
},
8435 {"popen3", win32_popen3
, METH_VARARGS
},
8436 {"popen4", win32_popen4
, METH_VARARGS
},
8437 {"startfile", win32_startfile
, METH_VARARGS
, win32_startfile__doc__
},
8439 #if defined(PYOS_OS2) && defined(PYCC_GCC)
8440 {"popen2", os2emx_popen2
, METH_VARARGS
},
8441 {"popen3", os2emx_popen3
, METH_VARARGS
},
8442 {"popen4", os2emx_popen4
, METH_VARARGS
},
8445 #endif /* HAVE_POPEN */
8447 {"setuid", posix_setuid
, METH_VARARGS
, posix_setuid__doc__
},
8448 #endif /* HAVE_SETUID */
8450 {"seteuid", posix_seteuid
, METH_VARARGS
, posix_seteuid__doc__
},
8451 #endif /* HAVE_SETEUID */
8453 {"setegid", posix_setegid
, METH_VARARGS
, posix_setegid__doc__
},
8454 #endif /* HAVE_SETEGID */
8455 #ifdef HAVE_SETREUID
8456 {"setreuid", posix_setreuid
, METH_VARARGS
, posix_setreuid__doc__
},
8457 #endif /* HAVE_SETREUID */
8458 #ifdef HAVE_SETREGID
8459 {"setregid", posix_setregid
, METH_VARARGS
, posix_setregid__doc__
},
8460 #endif /* HAVE_SETREGID */
8462 {"setgid", posix_setgid
, METH_VARARGS
, posix_setgid__doc__
},
8463 #endif /* HAVE_SETGID */
8464 #ifdef HAVE_SETGROUPS
8465 {"setgroups", posix_setgroups
, METH_O
, posix_setgroups__doc__
},
8466 #endif /* HAVE_SETGROUPS */
8468 {"getpgid", posix_getpgid
, METH_VARARGS
, posix_getpgid__doc__
},
8469 #endif /* HAVE_GETPGID */
8471 {"setpgrp", posix_setpgrp
, METH_NOARGS
, posix_setpgrp__doc__
},
8472 #endif /* HAVE_SETPGRP */
8474 {"wait", posix_wait
, METH_NOARGS
, posix_wait__doc__
},
8475 #endif /* HAVE_WAIT */
8477 {"wait3", posix_wait3
, METH_VARARGS
, posix_wait3__doc__
},
8478 #endif /* HAVE_WAIT3 */
8480 {"wait4", posix_wait4
, METH_VARARGS
, posix_wait4__doc__
},
8481 #endif /* HAVE_WAIT4 */
8482 #if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
8483 {"waitpid", posix_waitpid
, METH_VARARGS
, posix_waitpid__doc__
},
8484 #endif /* HAVE_WAITPID */
8486 {"getsid", posix_getsid
, METH_VARARGS
, posix_getsid__doc__
},
8487 #endif /* HAVE_GETSID */
8489 {"setsid", posix_setsid
, METH_NOARGS
, posix_setsid__doc__
},
8490 #endif /* HAVE_SETSID */
8492 {"setpgid", posix_setpgid
, METH_VARARGS
, posix_setpgid__doc__
},
8493 #endif /* HAVE_SETPGID */
8494 #ifdef HAVE_TCGETPGRP
8495 {"tcgetpgrp", posix_tcgetpgrp
, METH_VARARGS
, posix_tcgetpgrp__doc__
},
8496 #endif /* HAVE_TCGETPGRP */
8497 #ifdef HAVE_TCSETPGRP
8498 {"tcsetpgrp", posix_tcsetpgrp
, METH_VARARGS
, posix_tcsetpgrp__doc__
},
8499 #endif /* HAVE_TCSETPGRP */
8500 {"open", posix_open
, METH_VARARGS
, posix_open__doc__
},
8501 {"close", posix_close
, METH_VARARGS
, posix_close__doc__
},
8502 {"closerange", posix_closerange
, METH_VARARGS
, posix_closerange__doc__
},
8503 {"dup", posix_dup
, METH_VARARGS
, posix_dup__doc__
},
8504 {"dup2", posix_dup2
, METH_VARARGS
, posix_dup2__doc__
},
8505 {"lseek", posix_lseek
, METH_VARARGS
, posix_lseek__doc__
},
8506 {"read", posix_read
, METH_VARARGS
, posix_read__doc__
},
8507 {"write", posix_write
, METH_VARARGS
, posix_write__doc__
},
8508 {"fstat", posix_fstat
, METH_VARARGS
, posix_fstat__doc__
},
8509 {"fdopen", posix_fdopen
, METH_VARARGS
, posix_fdopen__doc__
},
8510 {"isatty", posix_isatty
, METH_VARARGS
, posix_isatty__doc__
},
8512 {"pipe", posix_pipe
, METH_NOARGS
, posix_pipe__doc__
},
8515 {"mkfifo", posix_mkfifo
, METH_VARARGS
, posix_mkfifo__doc__
},
8517 #if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
8518 {"mknod", posix_mknod
, METH_VARARGS
, posix_mknod__doc__
},
8520 #ifdef HAVE_DEVICE_MACROS
8521 {"major", posix_major
, METH_VARARGS
, posix_major__doc__
},
8522 {"minor", posix_minor
, METH_VARARGS
, posix_minor__doc__
},
8523 {"makedev", posix_makedev
, METH_VARARGS
, posix_makedev__doc__
},
8525 #ifdef HAVE_FTRUNCATE
8526 {"ftruncate", posix_ftruncate
, METH_VARARGS
, posix_ftruncate__doc__
},
8529 {"putenv", posix_putenv
, METH_VARARGS
, posix_putenv__doc__
},
8531 #ifdef HAVE_UNSETENV
8532 {"unsetenv", posix_unsetenv
, METH_VARARGS
, posix_unsetenv__doc__
},
8534 {"strerror", posix_strerror
, METH_VARARGS
, posix_strerror__doc__
},
8536 {"fchdir", posix_fchdir
, METH_O
, posix_fchdir__doc__
},
8539 {"fsync", posix_fsync
, METH_O
, posix_fsync__doc__
},
8541 #ifdef HAVE_FDATASYNC
8542 {"fdatasync", posix_fdatasync
, METH_O
, posix_fdatasync__doc__
},
8544 #ifdef HAVE_SYS_WAIT_H
8546 {"WCOREDUMP", posix_WCOREDUMP
, METH_VARARGS
, posix_WCOREDUMP__doc__
},
8547 #endif /* WCOREDUMP */
8549 {"WIFCONTINUED",posix_WIFCONTINUED
, METH_VARARGS
, posix_WIFCONTINUED__doc__
},
8550 #endif /* WIFCONTINUED */
8552 {"WIFSTOPPED", posix_WIFSTOPPED
, METH_VARARGS
, posix_WIFSTOPPED__doc__
},
8553 #endif /* WIFSTOPPED */
8555 {"WIFSIGNALED", posix_WIFSIGNALED
, METH_VARARGS
, posix_WIFSIGNALED__doc__
},
8556 #endif /* WIFSIGNALED */
8558 {"WIFEXITED", posix_WIFEXITED
, METH_VARARGS
, posix_WIFEXITED__doc__
},
8559 #endif /* WIFEXITED */
8561 {"WEXITSTATUS", posix_WEXITSTATUS
, METH_VARARGS
, posix_WEXITSTATUS__doc__
},
8562 #endif /* WEXITSTATUS */
8564 {"WTERMSIG", posix_WTERMSIG
, METH_VARARGS
, posix_WTERMSIG__doc__
},
8565 #endif /* WTERMSIG */
8567 {"WSTOPSIG", posix_WSTOPSIG
, METH_VARARGS
, posix_WSTOPSIG__doc__
},
8568 #endif /* WSTOPSIG */
8569 #endif /* HAVE_SYS_WAIT_H */
8570 #if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
8571 {"fstatvfs", posix_fstatvfs
, METH_VARARGS
, posix_fstatvfs__doc__
},
8573 #if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
8574 {"statvfs", posix_statvfs
, METH_VARARGS
, posix_statvfs__doc__
},
8577 {"tmpfile", posix_tmpfile
, METH_NOARGS
, posix_tmpfile__doc__
},
8580 {"tempnam", posix_tempnam
, METH_VARARGS
, posix_tempnam__doc__
},
8583 {"tmpnam", posix_tmpnam
, METH_NOARGS
, posix_tmpnam__doc__
},
8586 {"confstr", posix_confstr
, METH_VARARGS
, posix_confstr__doc__
},
8589 {"sysconf", posix_sysconf
, METH_VARARGS
, posix_sysconf__doc__
},
8591 #ifdef HAVE_FPATHCONF
8592 {"fpathconf", posix_fpathconf
, METH_VARARGS
, posix_fpathconf__doc__
},
8594 #ifdef HAVE_PATHCONF
8595 {"pathconf", posix_pathconf
, METH_VARARGS
, posix_pathconf__doc__
},
8597 {"abort", posix_abort
, METH_NOARGS
, posix_abort__doc__
},
8599 {"_getfullpathname", posix__getfullpathname
, METH_VARARGS
, NULL
},
8601 #ifdef HAVE_GETLOADAVG
8602 {"getloadavg", posix_getloadavg
, METH_NOARGS
, posix_getloadavg__doc__
},
8605 {"urandom", win32_urandom
, METH_VARARGS
, win32_urandom__doc__
},
8608 {"urandom", vms_urandom
, METH_VARARGS
, vms_urandom__doc__
},
8610 {NULL
, NULL
} /* Sentinel */
8615 ins(PyObject
*module
, char *symbol
, long value
)
8617 return PyModule_AddIntConstant(module
, symbol
, value
);
8620 #if defined(PYOS_OS2)
8621 /* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
8622 static int insertvalues(PyObject
*module
)
8625 ULONG values
[QSV_MAX
+1];
8629 Py_BEGIN_ALLOW_THREADS
8630 rc
= DosQuerySysInfo(1L, QSV_MAX
, &values
[1], sizeof(ULONG
) * QSV_MAX
);
8631 Py_END_ALLOW_THREADS
8633 if (rc
!= NO_ERROR
) {
8638 if (ins(module
, "meminstalled", values
[QSV_TOTPHYSMEM
])) return -1;
8639 if (ins(module
, "memkernel", values
[QSV_TOTRESMEM
])) return -1;
8640 if (ins(module
, "memvirtual", values
[QSV_TOTAVAILMEM
])) return -1;
8641 if (ins(module
, "maxpathlen", values
[QSV_MAX_PATH_LENGTH
])) return -1;
8642 if (ins(module
, "maxnamelen", values
[QSV_MAX_COMP_LENGTH
])) return -1;
8643 if (ins(module
, "revision", values
[QSV_VERSION_REVISION
])) return -1;
8644 if (ins(module
, "timeslice", values
[QSV_MIN_SLICE
])) return -1;
8646 switch (values
[QSV_VERSION_MINOR
]) {
8647 case 0: ver
= "2.00"; break;
8648 case 10: ver
= "2.10"; break;
8649 case 11: ver
= "2.11"; break;
8650 case 30: ver
= "3.00"; break;
8651 case 40: ver
= "4.00"; break;
8652 case 50: ver
= "5.00"; break;
8654 PyOS_snprintf(tmp
, sizeof(tmp
),
8655 "%d-%d", values
[QSV_VERSION_MAJOR
],
8656 values
[QSV_VERSION_MINOR
]);
8660 /* Add Indicator of the Version of the Operating System */
8661 if (PyModule_AddStringConstant(module
, "version", tmp
) < 0)
8664 /* Add Indicator of Which Drive was Used to Boot the System */
8665 tmp
[0] = 'A' + values
[QSV_BOOT_DRIVE
] - 1;
8669 return PyModule_AddStringConstant(module
, "bootdrive", tmp
);
8674 all_ins(PyObject
*d
)
8677 if (ins(d
, "F_OK", (long)F_OK
)) return -1;
8680 if (ins(d
, "R_OK", (long)R_OK
)) return -1;
8683 if (ins(d
, "W_OK", (long)W_OK
)) return -1;
8686 if (ins(d
, "X_OK", (long)X_OK
)) return -1;
8689 if (ins(d
, "NGROUPS_MAX", (long)NGROUPS_MAX
)) return -1;
8692 if (ins(d
, "TMP_MAX", (long)TMP_MAX
)) return -1;
8695 if (ins(d
, "WCONTINUED", (long)WCONTINUED
)) return -1;
8698 if (ins(d
, "WNOHANG", (long)WNOHANG
)) return -1;
8701 if (ins(d
, "WUNTRACED", (long)WUNTRACED
)) return -1;
8704 if (ins(d
, "O_RDONLY", (long)O_RDONLY
)) return -1;
8707 if (ins(d
, "O_WRONLY", (long)O_WRONLY
)) return -1;
8710 if (ins(d
, "O_RDWR", (long)O_RDWR
)) return -1;
8713 if (ins(d
, "O_NDELAY", (long)O_NDELAY
)) return -1;
8716 if (ins(d
, "O_NONBLOCK", (long)O_NONBLOCK
)) return -1;
8719 if (ins(d
, "O_APPEND", (long)O_APPEND
)) return -1;
8722 if (ins(d
, "O_DSYNC", (long)O_DSYNC
)) return -1;
8725 if (ins(d
, "O_RSYNC", (long)O_RSYNC
)) return -1;
8728 if (ins(d
, "O_SYNC", (long)O_SYNC
)) return -1;
8731 if (ins(d
, "O_NOCTTY", (long)O_NOCTTY
)) return -1;
8734 if (ins(d
, "O_CREAT", (long)O_CREAT
)) return -1;
8737 if (ins(d
, "O_EXCL", (long)O_EXCL
)) return -1;
8740 if (ins(d
, "O_TRUNC", (long)O_TRUNC
)) return -1;
8743 if (ins(d
, "O_BINARY", (long)O_BINARY
)) return -1;
8746 if (ins(d
, "O_TEXT", (long)O_TEXT
)) return -1;
8749 if (ins(d
, "O_LARGEFILE", (long)O_LARGEFILE
)) return -1;
8752 if (ins(d
, "O_SHLOCK", (long)O_SHLOCK
)) return -1;
8755 if (ins(d
, "O_EXLOCK", (long)O_EXLOCK
)) return -1;
8760 /* Don't inherit in child processes. */
8761 if (ins(d
, "O_NOINHERIT", (long)O_NOINHERIT
)) return -1;
8763 #ifdef _O_SHORT_LIVED
8764 /* Optimize for short life (keep in memory). */
8765 /* MS forgot to define this one with a non-underscore form too. */
8766 if (ins(d
, "O_SHORT_LIVED", (long)_O_SHORT_LIVED
)) return -1;
8769 /* Automatically delete when last handle is closed. */
8770 if (ins(d
, "O_TEMPORARY", (long)O_TEMPORARY
)) return -1;
8773 /* Optimize for random access. */
8774 if (ins(d
, "O_RANDOM", (long)O_RANDOM
)) return -1;
8777 /* Optimize for sequential access. */
8778 if (ins(d
, "O_SEQUENTIAL", (long)O_SEQUENTIAL
)) return -1;
8781 /* GNU extensions. */
8783 /* Send a SIGIO signal whenever input or output
8784 becomes available on file descriptor */
8785 if (ins(d
, "O_ASYNC", (long)O_ASYNC
)) return -1;
8788 /* Direct disk access. */
8789 if (ins(d
, "O_DIRECT", (long)O_DIRECT
)) return -1;
8792 /* Must be a directory. */
8793 if (ins(d
, "O_DIRECTORY", (long)O_DIRECTORY
)) return -1;
8796 /* Do not follow links. */
8797 if (ins(d
, "O_NOFOLLOW", (long)O_NOFOLLOW
)) return -1;
8800 /* Do not update the access time. */
8801 if (ins(d
, "O_NOATIME", (long)O_NOATIME
)) return -1;
8804 /* These come from sysexits.h */
8806 if (ins(d
, "EX_OK", (long)EX_OK
)) return -1;
8809 if (ins(d
, "EX_USAGE", (long)EX_USAGE
)) return -1;
8810 #endif /* EX_USAGE */
8812 if (ins(d
, "EX_DATAERR", (long)EX_DATAERR
)) return -1;
8813 #endif /* EX_DATAERR */
8815 if (ins(d
, "EX_NOINPUT", (long)EX_NOINPUT
)) return -1;
8816 #endif /* EX_NOINPUT */
8818 if (ins(d
, "EX_NOUSER", (long)EX_NOUSER
)) return -1;
8819 #endif /* EX_NOUSER */
8821 if (ins(d
, "EX_NOHOST", (long)EX_NOHOST
)) return -1;
8822 #endif /* EX_NOHOST */
8823 #ifdef EX_UNAVAILABLE
8824 if (ins(d
, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE
)) return -1;
8825 #endif /* EX_UNAVAILABLE */
8827 if (ins(d
, "EX_SOFTWARE", (long)EX_SOFTWARE
)) return -1;
8828 #endif /* EX_SOFTWARE */
8830 if (ins(d
, "EX_OSERR", (long)EX_OSERR
)) return -1;
8831 #endif /* EX_OSERR */
8833 if (ins(d
, "EX_OSFILE", (long)EX_OSFILE
)) return -1;
8834 #endif /* EX_OSFILE */
8836 if (ins(d
, "EX_CANTCREAT", (long)EX_CANTCREAT
)) return -1;
8837 #endif /* EX_CANTCREAT */
8839 if (ins(d
, "EX_IOERR", (long)EX_IOERR
)) return -1;
8840 #endif /* EX_IOERR */
8842 if (ins(d
, "EX_TEMPFAIL", (long)EX_TEMPFAIL
)) return -1;
8843 #endif /* EX_TEMPFAIL */
8845 if (ins(d
, "EX_PROTOCOL", (long)EX_PROTOCOL
)) return -1;
8846 #endif /* EX_PROTOCOL */
8848 if (ins(d
, "EX_NOPERM", (long)EX_NOPERM
)) return -1;
8849 #endif /* EX_NOPERM */
8851 if (ins(d
, "EX_CONFIG", (long)EX_CONFIG
)) return -1;
8852 #endif /* EX_CONFIG */
8854 if (ins(d
, "EX_NOTFOUND", (long)EX_NOTFOUND
)) return -1;
8855 #endif /* EX_NOTFOUND */
8858 #if defined(PYOS_OS2) && defined(PYCC_GCC)
8859 if (ins(d
, "P_WAIT", (long)P_WAIT
)) return -1;
8860 if (ins(d
, "P_NOWAIT", (long)P_NOWAIT
)) return -1;
8861 if (ins(d
, "P_OVERLAY", (long)P_OVERLAY
)) return -1;
8862 if (ins(d
, "P_DEBUG", (long)P_DEBUG
)) return -1;
8863 if (ins(d
, "P_SESSION", (long)P_SESSION
)) return -1;
8864 if (ins(d
, "P_DETACH", (long)P_DETACH
)) return -1;
8865 if (ins(d
, "P_PM", (long)P_PM
)) return -1;
8866 if (ins(d
, "P_DEFAULT", (long)P_DEFAULT
)) return -1;
8867 if (ins(d
, "P_MINIMIZE", (long)P_MINIMIZE
)) return -1;
8868 if (ins(d
, "P_MAXIMIZE", (long)P_MAXIMIZE
)) return -1;
8869 if (ins(d
, "P_FULLSCREEN", (long)P_FULLSCREEN
)) return -1;
8870 if (ins(d
, "P_WINDOWED", (long)P_WINDOWED
)) return -1;
8871 if (ins(d
, "P_FOREGROUND", (long)P_FOREGROUND
)) return -1;
8872 if (ins(d
, "P_BACKGROUND", (long)P_BACKGROUND
)) return -1;
8873 if (ins(d
, "P_NOCLOSE", (long)P_NOCLOSE
)) return -1;
8874 if (ins(d
, "P_NOSESSION", (long)P_NOSESSION
)) return -1;
8875 if (ins(d
, "P_QUOTE", (long)P_QUOTE
)) return -1;
8876 if (ins(d
, "P_TILDE", (long)P_TILDE
)) return -1;
8877 if (ins(d
, "P_UNRELATED", (long)P_UNRELATED
)) return -1;
8878 if (ins(d
, "P_DEBUGDESC", (long)P_DEBUGDESC
)) return -1;
8880 if (ins(d
, "P_WAIT", (long)_P_WAIT
)) return -1;
8881 if (ins(d
, "P_NOWAIT", (long)_P_NOWAIT
)) return -1;
8882 if (ins(d
, "P_OVERLAY", (long)_OLD_P_OVERLAY
)) return -1;
8883 if (ins(d
, "P_NOWAITO", (long)_P_NOWAITO
)) return -1;
8884 if (ins(d
, "P_DETACH", (long)_P_DETACH
)) return -1;
8888 #if defined(PYOS_OS2)
8889 if (insertvalues(d
)) return -1;
8895 #if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
8896 #define INITFUNC initnt
8897 #define MODNAME "nt"
8899 #elif defined(PYOS_OS2)
8900 #define INITFUNC initos2
8901 #define MODNAME "os2"
8904 #define INITFUNC initposix
8905 #define MODNAME "posix"
8913 m
= Py_InitModule3(MODNAME
,
8919 /* Initialize environ dictionary */
8920 v
= convertenviron();
8922 if (v
== NULL
|| PyModule_AddObject(m
, "environ", v
) != 0)
8929 if (setup_confname_tables(m
))
8932 Py_INCREF(PyExc_OSError
);
8933 PyModule_AddObject(m
, "error", PyExc_OSError
);
8936 if (posix_putenv_garbage
== NULL
)
8937 posix_putenv_garbage
= PyDict_New();
8941 stat_result_desc
.name
= MODNAME
".stat_result";
8942 stat_result_desc
.fields
[7].name
= PyStructSequence_UnnamedField
;
8943 stat_result_desc
.fields
[8].name
= PyStructSequence_UnnamedField
;
8944 stat_result_desc
.fields
[9].name
= PyStructSequence_UnnamedField
;
8945 PyStructSequence_InitType(&StatResultType
, &stat_result_desc
);
8946 structseq_new
= StatResultType
.tp_new
;
8947 StatResultType
.tp_new
= statresult_new
;
8949 statvfs_result_desc
.name
= MODNAME
".statvfs_result";
8950 PyStructSequence_InitType(&StatVFSResultType
, &statvfs_result_desc
);
8952 Py_INCREF((PyObject
*) &StatResultType
);
8953 PyModule_AddObject(m
, "stat_result", (PyObject
*) &StatResultType
);
8954 Py_INCREF((PyObject
*) &StatVFSResultType
);
8955 PyModule_AddObject(m
, "statvfs_result",
8956 (PyObject
*) &StatVFSResultType
);
8961 * Step 2 of weak-linking support on Mac OS X.
8963 * The code below removes functions that are not available on the
8964 * currently active platform.
8966 * This block allow one to use a python binary that was build on
8967 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
8970 #ifdef HAVE_FSTATVFS
8971 if (fstatvfs
== NULL
) {
8972 if (PyObject_DelAttrString(m
, "fstatvfs") == -1) {
8976 #endif /* HAVE_FSTATVFS */
8979 if (statvfs
== NULL
) {
8980 if (PyObject_DelAttrString(m
, "statvfs") == -1) {
8984 #endif /* HAVE_STATVFS */
8987 if (lchown
== NULL
) {
8988 if (PyObject_DelAttrString(m
, "lchown") == -1) {
8992 #endif /* HAVE_LCHOWN */
8995 #endif /* __APPLE__ */