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
);
194 extern int chown(const char *, uid_t
, gid_t
);
195 extern char *getcwd(char *, int);
196 extern char *strerror(int);
197 extern int link(const char *, const char *);
198 extern int rename(const char *, const char *);
199 extern int stat(const char *, struct stat
*);
200 extern int unlink(const char *);
201 extern int pclose(FILE *);
203 extern int symlink(const char *, const char *);
204 #endif /* HAVE_SYMLINK */
206 extern int lstat(const char *, struct stat
*);
207 #endif /* HAVE_LSTAT */
208 #endif /* !HAVE_UNISTD_H */
210 #endif /* !_MSC_VER */
214 #endif /* HAVE_UTIME_H */
216 #ifdef HAVE_SYS_UTIME_H
217 #include <sys/utime.h>
218 #define HAVE_UTIME_H /* pretend we do for the rest of this file */
219 #endif /* HAVE_SYS_UTIME_H */
221 #ifdef HAVE_SYS_TIMES_H
222 #include <sys/times.h>
223 #endif /* HAVE_SYS_TIMES_H */
225 #ifdef HAVE_SYS_PARAM_H
226 #include <sys/param.h>
227 #endif /* HAVE_SYS_PARAM_H */
229 #ifdef HAVE_SYS_UTSNAME_H
230 #include <sys/utsname.h>
231 #endif /* HAVE_SYS_UTSNAME_H */
235 #define NAMLEN(dirent) strlen((dirent)->d_name)
237 #if defined(__WATCOMC__) && !defined(__QNX__)
239 #define NAMLEN(dirent) strlen((dirent)->d_name)
241 #define dirent direct
242 #define NAMLEN(dirent) (dirent)->d_namlen
244 #ifdef HAVE_SYS_NDIR_H
245 #include <sys/ndir.h>
247 #ifdef HAVE_SYS_DIR_H
262 #ifdef HAVE_PROCESS_H
266 #define _WIN32_WINNT 0x0400 /* Needed for CryptoAPI on some systems */
268 #include <shellapi.h> /* for ShellExecute() */
270 #define pclose _pclose
271 #endif /* _MSC_VER */
273 #if defined(PYCC_VACPP) && defined(PYOS_OS2)
278 #if defined(PATH_MAX) && PATH_MAX > 1024
279 #define MAXPATHLEN PATH_MAX
281 #define MAXPATHLEN 1024
283 #endif /* MAXPATHLEN */
286 /* Emulate some macros on systems that have a union instead of macros */
289 #define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
293 #define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
297 #define WTERMSIG(u_wait) ((u_wait).w_termsig)
300 #define WAIT_TYPE union wait
301 #define WAIT_STATUS_INT(s) (s.w_status)
303 #else /* !UNION_WAIT */
304 #define WAIT_TYPE int
305 #define WAIT_STATUS_INT(s) (s)
306 #endif /* UNION_WAIT */
308 /* Don't use the "_r" form if we don't need it (also, won't have a
309 prototype for it, at least on Solaris -- maybe others as well?). */
310 #if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
311 #define USE_CTERMID_R
314 #if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
318 /* choose the appropriate stat and fstat functions and return structs */
320 #if defined(MS_WIN64) || defined(MS_WINDOWS)
321 # define STAT win32_stat
322 # define FSTAT win32_fstat
323 # define STRUCT_STAT struct win32_stat
327 # define STRUCT_STAT struct stat
330 #if defined(MAJOR_IN_MKDEV)
331 #include <sys/mkdev.h>
333 #if defined(MAJOR_IN_SYSMACROS)
334 #include <sys/sysmacros.h>
336 #if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
337 #include <sys/mkdev.h>
341 /* Return a dictionary corresponding to the POSIX environment table */
342 #ifdef WITH_NEXT_FRAMEWORK
343 /* On Darwin/MacOSX a shared library or framework has no access to
344 ** environ directly, we must obtain it with _NSGetEnviron().
346 #include <crt_externs.h>
347 static char **environ
;
348 #elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
349 extern char **environ
;
350 #endif /* !_MSC_VER */
360 #ifdef WITH_NEXT_FRAMEWORK
362 environ
= *_NSGetEnviron();
366 /* This part ignores errors */
367 for (e
= environ
; *e
!= NULL
; e
++) {
370 char *p
= strchr(*e
, '=');
373 k
= PyString_FromStringAndSize(*e
, (int)(p
-*e
));
378 v
= PyString_FromString(p
+1);
384 if (PyDict_GetItem(d
, k
) == NULL
) {
385 if (PyDict_SetItem(d
, k
, v
) != 0)
391 #if defined(PYOS_OS2)
394 char buffer
[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
396 rc
= DosQueryExtLIBPATH(buffer
, BEGIN_LIBPATH
);
397 if (rc
== NO_ERROR
) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
398 PyObject
*v
= PyString_FromString(buffer
);
399 PyDict_SetItemString(d
, "BEGINLIBPATH", v
);
402 rc
= DosQueryExtLIBPATH(buffer
, END_LIBPATH
);
403 if (rc
== NO_ERROR
) { /* (not a typo, envname is NOT 'END_LIBPATH') */
404 PyObject
*v
= PyString_FromString(buffer
);
405 PyDict_SetItemString(d
, "ENDLIBPATH", v
);
414 /* Set a POSIX-specific error from errno, and return NULL */
419 return PyErr_SetFromErrno(PyExc_OSError
);
422 posix_error_with_filename(char* name
)
424 return PyErr_SetFromErrnoWithFilename(PyExc_OSError
, name
);
427 #ifdef Py_WIN_WIDE_FILENAMES
429 posix_error_with_unicode_filename(Py_UNICODE
* name
)
431 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError
, name
);
433 #endif /* Py_WIN_WIDE_FILENAMES */
437 posix_error_with_allocated_filename(char* name
)
439 PyObject
*rc
= PyErr_SetFromErrnoWithFilename(PyExc_OSError
, name
);
446 win32_error(char* function
, char* filename
)
448 /* XXX We should pass the function name along in the future.
449 (_winreg.c also wants to pass the function name.)
450 This would however require an additional param to the
451 Windows error object, which is non-trivial.
453 errno
= GetLastError();
455 return PyErr_SetFromWindowsErrWithFilename(errno
, filename
);
457 return PyErr_SetFromWindowsErr(errno
);
460 #ifdef Py_WIN_WIDE_FILENAMES
462 win32_error_unicode(char* function
, Py_UNICODE
* filename
)
464 /* XXX - see win32_error for comments on 'function' */
465 errno
= GetLastError();
467 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno
, filename
);
469 return PyErr_SetFromWindowsErr(errno
);
472 static PyObject
*_PyUnicode_FromFileSystemEncodedObject(register PyObject
*obj
)
476 /* Function suitable for O& conversion */
478 convert_to_unicode(PyObject
*arg
, void* _param
)
480 PyObject
**param
= (PyObject
**)_param
;
481 if (PyUnicode_CheckExact(arg
)) {
485 else if (PyUnicode_Check(arg
)) {
486 /* For a Unicode subtype that's not a Unicode object,
487 return a true Unicode object with the same data. */
488 *param
= PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(arg
),
489 PyUnicode_GET_SIZE(arg
));
490 return *param
!= NULL
;
493 *param
= PyUnicode_FromEncodedObject(arg
,
494 Py_FileSystemDefaultEncoding
,
496 return (*param
) != NULL
;
499 #endif /* Py_WIN_WIDE_FILENAMES */
503 #if defined(PYOS_OS2)
504 /**********************************************************************
505 * Helper Function to Trim and Format OS/2 Messages
506 **********************************************************************/
508 os2_formatmsg(char *msgbuf
, int msglen
, char *reason
)
510 msgbuf
[msglen
] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
512 if (strlen(msgbuf
) > 0) { /* If Non-Empty Msg, Trim CRLF */
513 char *lastc
= &msgbuf
[ strlen(msgbuf
)-1 ];
515 while (lastc
> msgbuf
&& isspace(Py_CHARMASK(*lastc
)))
516 *lastc
-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
519 /* Add Optional Reason Text */
521 strcat(msgbuf
, " : ");
522 strcat(msgbuf
, reason
);
526 /**********************************************************************
527 * Decode an OS/2 Operating System Error Code
529 * A convenience function to lookup an OS/2 error code and return a
530 * text message we can use to raise a Python exception.
533 * The messages for errors returned from the OS/2 kernel reside in
534 * the file OSO001.MSG in the \OS2 directory hierarchy.
536 **********************************************************************/
538 os2_strerror(char *msgbuf
, int msgbuflen
, int errorcode
, char *reason
)
543 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
544 Py_BEGIN_ALLOW_THREADS
545 rc
= DosGetMessage(NULL
, 0, msgbuf
, msgbuflen
,
546 errorcode
, "oso001.msg", &msglen
);
550 os2_formatmsg(msgbuf
, msglen
, reason
);
552 PyOS_snprintf(msgbuf
, msgbuflen
,
553 "unknown OS error #%d", errorcode
);
558 /* Set an OS/2-specific error and return NULL. OS/2 kernel
559 errors are not in a global variable e.g. 'errno' nor are
560 they congruent with posix error numbers. */
562 static PyObject
* os2_error(int code
)
567 os2_strerror(text
, sizeof(text
), code
, "");
569 v
= Py_BuildValue("(is)", code
, text
);
571 PyErr_SetObject(PyExc_OSError
, v
);
574 return NULL
; /* Signal to Python that an Exception is Pending */
579 /* POSIX generic methods */
582 posix_fildes(PyObject
*fdobj
, int (*func
)(int))
586 fd
= PyObject_AsFileDescriptor(fdobj
);
589 Py_BEGIN_ALLOW_THREADS
593 return posix_error();
598 #ifdef Py_WIN_WIDE_FILENAMES
600 unicode_file_names(void)
602 static int canusewide
= -1;
603 if (canusewide
== -1) {
604 /* As per doc for ::GetVersion(), this is the correct test for
605 the Windows NT family. */
606 canusewide
= (GetVersion() < 0x80000000) ? 1 : 0;
613 posix_1str(PyObject
*args
, char *format
, int (*func
)(const char*))
617 if (!PyArg_ParseTuple(args
, format
,
618 Py_FileSystemDefaultEncoding
, &path1
))
620 Py_BEGIN_ALLOW_THREADS
621 res
= (*func
)(path1
);
624 return posix_error_with_allocated_filename(path1
);
631 posix_2str(PyObject
*args
,
633 int (*func
)(const char *, const char *))
635 char *path1
= NULL
, *path2
= NULL
;
637 if (!PyArg_ParseTuple(args
, format
,
638 Py_FileSystemDefaultEncoding
, &path1
,
639 Py_FileSystemDefaultEncoding
, &path2
))
641 Py_BEGIN_ALLOW_THREADS
642 res
= (*func
)(path1
, path2
);
647 /* XXX how to report both path1 and path2??? */
648 return posix_error();
653 #ifdef Py_WIN_WIDE_FILENAMES
655 win32_1str(PyObject
* args
, char* func
,
656 char* format
, BOOL (__stdcall
*funcA
)(LPCSTR
),
657 char* wformat
, BOOL (__stdcall
*funcW
)(LPWSTR
))
662 if (unicode_file_names()) {
663 if (!PyArg_ParseTuple(args
, wformat
, &uni
))
666 Py_BEGIN_ALLOW_THREADS
667 result
= funcW(PyUnicode_AsUnicode(uni
));
670 return win32_error_unicode(func
, PyUnicode_AsUnicode(uni
));
675 if (!PyArg_ParseTuple(args
, format
, &ansi
))
677 Py_BEGIN_ALLOW_THREADS
678 result
= funcA(ansi
);
681 return win32_error(func
, ansi
);
687 /* This is a reimplementation of the C library's chdir function,
688 but one that produces Win32 errors instead of DOS error codes.
689 chdir is essentially a wrapper around SetCurrentDirectory; however,
690 it also needs to set "magic" environment variables indicating
691 the per-drive current directory, which are of the form =<drive>: */
693 win32_chdir(LPCSTR path
)
695 char new_path
[MAX_PATH
+1];
699 if(!SetCurrentDirectoryA(path
))
701 result
= GetCurrentDirectoryA(MAX_PATH
+1, new_path
);
704 /* In the ANSI API, there should not be any paths longer
706 assert(result
<= MAX_PATH
+1);
707 if (strncmp(new_path
, "\\\\", 2) == 0 ||
708 strncmp(new_path
, "//", 2) == 0)
709 /* UNC path, nothing to do. */
711 env
[1] = new_path
[0];
712 return SetEnvironmentVariableA(env
, new_path
);
715 /* The Unicode version differs from the ANSI version
716 since the current directory might exceed MAX_PATH characters */
718 win32_wchdir(LPCWSTR path
)
720 wchar_t _new_path
[MAX_PATH
+1], *new_path
= _new_path
;
722 wchar_t env
[4] = L
"=x:";
724 if(!SetCurrentDirectoryW(path
))
726 result
= GetCurrentDirectoryW(MAX_PATH
+1, new_path
);
729 if (result
> MAX_PATH
+1) {
730 new_path
= malloc(result
);
732 SetLastError(ERROR_OUTOFMEMORY
);
736 if (wcsncmp(new_path
, L
"\\\\", 2) == 0 ||
737 wcsncmp(new_path
, L
"//", 2) == 0)
738 /* UNC path, nothing to do. */
740 env
[1] = new_path
[0];
741 result
= SetEnvironmentVariableW(env
, new_path
);
742 if (new_path
!= _new_path
)
749 /* The CRT of Windows has a number of flaws wrt. its stat() implementation:
750 - time stamps are restricted to second resolution
751 - file modification times suffer from forth-and-back conversions between
753 Therefore, we implement our own stat, based on the Win32 API directly.
755 #define HAVE_STAT_NSEC 1
760 unsigned short st_mode
;
774 static __int64 secs_between_epochs
= 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
777 FILE_TIME_to_time_t_nsec(FILETIME
*in_ptr
, int *time_out
, int* nsec_out
)
779 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
780 /* Cannot simply cast and dereference in_ptr,
781 since it might not be aligned properly */
783 memcpy(&in
, in_ptr
, sizeof(in
));
784 *nsec_out
= (int)(in
% 10000000) * 100; /* FILETIME is in units of 100 nsec. */
785 /* XXX Win32 supports time stamps past 2038; we currently don't */
786 *time_out
= Py_SAFE_DOWNCAST((in
/ 10000000) - secs_between_epochs
, __int64
, int);
790 time_t_to_FILE_TIME(int time_in
, int nsec_in
, FILETIME
*out_ptr
)
794 out
= time_in
+ secs_between_epochs
;
795 out
= out
* 10000000 + nsec_in
/ 100;
796 memcpy(out_ptr
, &out
, sizeof(out
));
799 /* Below, we *know* that ugo+r is 0444 */
801 #error Unsupported C library
804 attributes_to_mode(DWORD attr
)
807 if (attr
& FILE_ATTRIBUTE_DIRECTORY
)
808 m
|= _S_IFDIR
| 0111; /* IFEXEC for user,group,other */
811 if (attr
& FILE_ATTRIBUTE_READONLY
)
819 attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA
*info
, struct win32_stat
*result
)
821 memset(result
, 0, sizeof(*result
));
822 result
->st_mode
= attributes_to_mode(info
->dwFileAttributes
);
823 result
->st_size
= (((__int64
)info
->nFileSizeHigh
)<<32) + info
->nFileSizeLow
;
824 FILE_TIME_to_time_t_nsec(&info
->ftCreationTime
, &result
->st_ctime
, &result
->st_ctime_nsec
);
825 FILE_TIME_to_time_t_nsec(&info
->ftLastWriteTime
, &result
->st_mtime
, &result
->st_mtime_nsec
);
826 FILE_TIME_to_time_t_nsec(&info
->ftLastAccessTime
, &result
->st_atime
, &result
->st_atime_nsec
);
831 /* Emulate GetFileAttributesEx[AW] on Windows 95 */
832 static int checked
= 0;
833 static BOOL (CALLBACK
*gfaxa
)(LPCSTR
, GET_FILEEX_INFO_LEVELS
, LPVOID
);
834 static BOOL (CALLBACK
*gfaxw
)(LPCWSTR
, GET_FILEEX_INFO_LEVELS
, LPVOID
);
842 hKernel32
= GetModuleHandle("KERNEL32");
843 *(FARPROC
*)&gfaxa
= GetProcAddress(hKernel32
, "GetFileAttributesExA");
844 *(FARPROC
*)&gfaxw
= GetProcAddress(hKernel32
, "GetFileAttributesExW");
848 Py_GetFileAttributesExA(LPCSTR pszFile
,
849 GET_FILEEX_INFO_LEVELS level
,
854 WIN32_FIND_DATAA FileData
;
855 LPWIN32_FILE_ATTRIBUTE_DATA pfad
= pv
;
856 /* First try to use the system's implementation, if that is
857 available and either succeeds to gives an error other than
858 that it isn't implemented. */
861 result
= gfaxa(pszFile
, level
, pv
);
862 if (result
|| GetLastError() != ERROR_CALL_NOT_IMPLEMENTED
)
865 /* It's either not present, or not implemented.
866 Emulate using FindFirstFile. */
867 if (level
!= GetFileExInfoStandard
) {
868 SetLastError(ERROR_INVALID_PARAMETER
);
871 /* Use GetFileAttributes to validate that the file name
872 does not contain wildcards (which FindFirstFile would
874 if (GetFileAttributesA(pszFile
) == 0xFFFFFFFF)
876 hFindFile
= FindFirstFileA(pszFile
, &FileData
);
877 if (hFindFile
== INVALID_HANDLE_VALUE
)
879 FindClose(hFindFile
);
880 pfad
->dwFileAttributes
= FileData
.dwFileAttributes
;
881 pfad
->ftCreationTime
= FileData
.ftCreationTime
;
882 pfad
->ftLastAccessTime
= FileData
.ftLastAccessTime
;
883 pfad
->ftLastWriteTime
= FileData
.ftLastWriteTime
;
884 pfad
->nFileSizeHigh
= FileData
.nFileSizeHigh
;
885 pfad
->nFileSizeLow
= FileData
.nFileSizeLow
;
890 Py_GetFileAttributesExW(LPCWSTR pszFile
,
891 GET_FILEEX_INFO_LEVELS level
,
896 WIN32_FIND_DATAW FileData
;
897 LPWIN32_FILE_ATTRIBUTE_DATA pfad
= pv
;
898 /* First try to use the system's implementation, if that is
899 available and either succeeds to gives an error other than
900 that it isn't implemented. */
903 result
= gfaxw(pszFile
, level
, pv
);
904 if (result
|| GetLastError() != ERROR_CALL_NOT_IMPLEMENTED
)
907 /* It's either not present, or not implemented.
908 Emulate using FindFirstFile. */
909 if (level
!= GetFileExInfoStandard
) {
910 SetLastError(ERROR_INVALID_PARAMETER
);
913 /* Use GetFileAttributes to validate that the file name
914 does not contain wildcards (which FindFirstFile would
916 if (GetFileAttributesW(pszFile
) == 0xFFFFFFFF)
918 hFindFile
= FindFirstFileW(pszFile
, &FileData
);
919 if (hFindFile
== INVALID_HANDLE_VALUE
)
921 FindClose(hFindFile
);
922 pfad
->dwFileAttributes
= FileData
.dwFileAttributes
;
923 pfad
->ftCreationTime
= FileData
.ftCreationTime
;
924 pfad
->ftLastAccessTime
= FileData
.ftLastAccessTime
;
925 pfad
->ftLastWriteTime
= FileData
.ftLastWriteTime
;
926 pfad
->nFileSizeHigh
= FileData
.nFileSizeHigh
;
927 pfad
->nFileSizeLow
= FileData
.nFileSizeLow
;
932 win32_stat(const char* path
, struct win32_stat
*result
)
934 WIN32_FILE_ATTRIBUTE_DATA info
;
937 /* XXX not supported on Win95 and NT 3.x */
938 if (!Py_GetFileAttributesExA(path
, GetFileExInfoStandard
, &info
)) {
939 /* Protocol violation: we explicitly clear errno, instead of
940 setting it to a POSIX error. Callers should use GetLastError. */
944 code
= attribute_data_to_stat(&info
, result
);
947 /* Set S_IFEXEC if it is an .exe, .bat, ... */
948 dot
= strrchr(path
, '.');
950 if (stricmp(dot
, ".bat") == 0 ||
951 stricmp(dot
, ".cmd") == 0 ||
952 stricmp(dot
, ".exe") == 0 ||
953 stricmp(dot
, ".com") == 0)
954 result
->st_mode
|= 0111;
960 win32_wstat(const wchar_t* path
, struct win32_stat
*result
)
964 WIN32_FILE_ATTRIBUTE_DATA info
;
965 /* XXX not supported on Win95 and NT 3.x */
966 if (!Py_GetFileAttributesExW(path
, GetFileExInfoStandard
, &info
)) {
967 /* Protocol violation: we explicitly clear errno, instead of
968 setting it to a POSIX error. Callers should use GetLastError. */
972 code
= attribute_data_to_stat(&info
, result
);
975 /* Set IFEXEC if it is an .exe, .bat, ... */
976 dot
= wcsrchr(path
, '.');
978 if (_wcsicmp(dot
, L
".bat") == 0 ||
979 _wcsicmp(dot
, L
".cmd") == 0 ||
980 _wcsicmp(dot
, L
".exe") == 0 ||
981 _wcsicmp(dot
, L
".com") == 0)
982 result
->st_mode
|= 0111;
988 win32_fstat(int file_number
, struct win32_stat
*result
)
990 BY_HANDLE_FILE_INFORMATION info
;
994 h
= (HANDLE
)_get_osfhandle(file_number
);
996 /* Protocol violation: we explicitly clear errno, instead of
997 setting it to a POSIX error. Callers should use GetLastError. */
1000 if (h
== INVALID_HANDLE_VALUE
) {
1001 /* This is really a C library error (invalid file handle).
1002 We set the Win32 error to the closes one matching. */
1003 SetLastError(ERROR_INVALID_HANDLE
);
1006 memset(result
, 0, sizeof(*result
));
1008 type
= GetFileType(h
);
1009 if (type
== FILE_TYPE_UNKNOWN
) {
1010 DWORD error
= GetLastError();
1014 /* else: valid but unknown file */
1017 if (type
!= FILE_TYPE_DISK
) {
1018 if (type
== FILE_TYPE_CHAR
)
1019 result
->st_mode
= _S_IFCHR
;
1020 else if (type
== FILE_TYPE_PIPE
)
1021 result
->st_mode
= _S_IFIFO
;
1025 if (!GetFileInformationByHandle(h
, &info
)) {
1029 /* similar to stat() */
1030 result
->st_mode
= attributes_to_mode(info
.dwFileAttributes
);
1031 result
->st_size
= (((__int64
)info
.nFileSizeHigh
)<<32) + info
.nFileSizeLow
;
1032 FILE_TIME_to_time_t_nsec(&info
.ftCreationTime
, &result
->st_ctime
, &result
->st_ctime_nsec
);
1033 FILE_TIME_to_time_t_nsec(&info
.ftLastWriteTime
, &result
->st_mtime
, &result
->st_mtime_nsec
);
1034 FILE_TIME_to_time_t_nsec(&info
.ftLastAccessTime
, &result
->st_atime
, &result
->st_atime_nsec
);
1035 /* specific to fstat() */
1036 result
->st_nlink
= info
.nNumberOfLinks
;
1037 result
->st_ino
= (((__int64
)info
.nFileIndexHigh
)<<32) + info
.nFileIndexLow
;
1041 #endif /* MS_WINDOWS */
1043 PyDoc_STRVAR(stat_result__doc__
,
1044 "stat_result: Result from stat or lstat.\n\n\
1045 This object may be accessed either as a tuple of\n\
1046 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
1047 or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1049 Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1050 or st_flags, they are available as attributes only.\n\
1052 See os.stat for more information.");
1054 static PyStructSequence_Field stat_result_fields
[] = {
1055 {"st_mode", "protection bits"},
1056 {"st_ino", "inode"},
1057 {"st_dev", "device"},
1058 {"st_nlink", "number of hard links"},
1059 {"st_uid", "user ID of owner"},
1060 {"st_gid", "group ID of owner"},
1061 {"st_size", "total size, in bytes"},
1062 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1063 {NULL
, "integer time of last access"},
1064 {NULL
, "integer time of last modification"},
1065 {NULL
, "integer time of last change"},
1066 {"st_atime", "time of last access"},
1067 {"st_mtime", "time of last modification"},
1068 {"st_ctime", "time of last change"},
1069 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
1070 {"st_blksize", "blocksize for filesystem I/O"},
1072 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
1073 {"st_blocks", "number of blocks allocated"},
1075 #ifdef HAVE_STRUCT_STAT_ST_RDEV
1076 {"st_rdev", "device type (if inode device)"},
1078 #ifdef HAVE_STRUCT_STAT_ST_FLAGS
1079 {"st_flags", "user defined flags for file"},
1081 #ifdef HAVE_STRUCT_STAT_ST_GEN
1082 {"st_gen", "generation number"},
1084 #ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1085 {"st_birthtime", "time of creation"},
1090 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
1091 #define ST_BLKSIZE_IDX 13
1093 #define ST_BLKSIZE_IDX 12
1096 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
1097 #define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1099 #define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1102 #ifdef HAVE_STRUCT_STAT_ST_RDEV
1103 #define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1105 #define ST_RDEV_IDX ST_BLOCKS_IDX
1108 #ifdef HAVE_STRUCT_STAT_ST_FLAGS
1109 #define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1111 #define ST_FLAGS_IDX ST_RDEV_IDX
1114 #ifdef HAVE_STRUCT_STAT_ST_GEN
1115 #define ST_GEN_IDX (ST_FLAGS_IDX+1)
1117 #define ST_GEN_IDX ST_FLAGS_IDX
1120 #ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1121 #define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1123 #define ST_BIRTHTIME_IDX ST_GEN_IDX
1126 static PyStructSequence_Desc stat_result_desc
= {
1127 "stat_result", /* name */
1128 stat_result__doc__
, /* doc */
1133 PyDoc_STRVAR(statvfs_result__doc__
,
1134 "statvfs_result: Result from statvfs or fstatvfs.\n\n\
1135 This object may be accessed either as a tuple of\n\
1136 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
1137 or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
1139 See os.statvfs for more information.");
1141 static PyStructSequence_Field statvfs_result_fields
[] = {
1155 static PyStructSequence_Desc statvfs_result_desc
= {
1156 "statvfs_result", /* name */
1157 statvfs_result__doc__
, /* doc */
1158 statvfs_result_fields
,
1162 static int initialized
;
1163 static PyTypeObject StatResultType
;
1164 static PyTypeObject StatVFSResultType
;
1165 static newfunc structseq_new
;
1168 statresult_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwds
)
1170 PyStructSequence
*result
;
1173 result
= (PyStructSequence
*)structseq_new(type
, args
, kwds
);
1176 /* If we have been initialized from a tuple,
1177 st_?time might be set to None. Initialize it
1178 from the int slots. */
1179 for (i
= 7; i
<= 9; i
++) {
1180 if (result
->ob_item
[i
+3] == Py_None
) {
1182 Py_INCREF(result
->ob_item
[i
]);
1183 result
->ob_item
[i
+3] = result
->ob_item
[i
];
1186 return (PyObject
*)result
;
1191 /* If true, st_?time is float. */
1192 static int _stat_float_times
= 1;
1194 PyDoc_STRVAR(stat_float_times__doc__
,
1195 "stat_float_times([newval]) -> oldval\n\n\
1196 Determine whether os.[lf]stat represents time stamps as float objects.\n\
1197 If newval is True, future calls to stat() return floats, if it is False,\n\
1198 future calls return ints. \n\
1199 If newval is omitted, return the current setting.\n");
1202 stat_float_times(PyObject
* self
, PyObject
*args
)
1205 if (!PyArg_ParseTuple(args
, "|i:stat_float_times", &newval
))
1208 /* Return old value */
1209 return PyBool_FromLong(_stat_float_times
);
1210 _stat_float_times
= newval
;
1216 fill_time(PyObject
*v
, int index
, time_t sec
, unsigned long nsec
)
1218 PyObject
*fval
,*ival
;
1219 #if SIZEOF_TIME_T > SIZEOF_LONG
1220 ival
= PyLong_FromLongLong((PY_LONG_LONG
)sec
);
1222 ival
= PyInt_FromLong((long)sec
);
1226 if (_stat_float_times
) {
1227 fval
= PyFloat_FromDouble(sec
+ 1e-9*nsec
);
1232 PyStructSequence_SET_ITEM(v
, index
, ival
);
1233 PyStructSequence_SET_ITEM(v
, index
+3, fval
);
1236 /* pack a system stat C structure into the Python stat tuple
1237 (used by posix_stat() and posix_fstat()) */
1239 _pystat_fromstructstat(STRUCT_STAT
*st
)
1241 unsigned long ansec
, mnsec
, cnsec
;
1242 PyObject
*v
= PyStructSequence_New(&StatResultType
);
1246 PyStructSequence_SET_ITEM(v
, 0, PyInt_FromLong((long)st
->st_mode
));
1247 #ifdef HAVE_LARGEFILE_SUPPORT
1248 PyStructSequence_SET_ITEM(v
, 1,
1249 PyLong_FromLongLong((PY_LONG_LONG
)st
->st_ino
));
1251 PyStructSequence_SET_ITEM(v
, 1, PyInt_FromLong((long)st
->st_ino
));
1253 #if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
1254 PyStructSequence_SET_ITEM(v
, 2,
1255 PyLong_FromLongLong((PY_LONG_LONG
)st
->st_dev
));
1257 PyStructSequence_SET_ITEM(v
, 2, PyInt_FromLong((long)st
->st_dev
));
1259 PyStructSequence_SET_ITEM(v
, 3, PyInt_FromLong((long)st
->st_nlink
));
1260 PyStructSequence_SET_ITEM(v
, 4, PyInt_FromLong((long)st
->st_uid
));
1261 PyStructSequence_SET_ITEM(v
, 5, PyInt_FromLong((long)st
->st_gid
));
1262 #ifdef HAVE_LARGEFILE_SUPPORT
1263 PyStructSequence_SET_ITEM(v
, 6,
1264 PyLong_FromLongLong((PY_LONG_LONG
)st
->st_size
));
1266 PyStructSequence_SET_ITEM(v
, 6, PyInt_FromLong(st
->st_size
));
1269 #if defined(HAVE_STAT_TV_NSEC)
1270 ansec
= st
->st_atim
.tv_nsec
;
1271 mnsec
= st
->st_mtim
.tv_nsec
;
1272 cnsec
= st
->st_ctim
.tv_nsec
;
1273 #elif defined(HAVE_STAT_TV_NSEC2)
1274 ansec
= st
->st_atimespec
.tv_nsec
;
1275 mnsec
= st
->st_mtimespec
.tv_nsec
;
1276 cnsec
= st
->st_ctimespec
.tv_nsec
;
1277 #elif defined(HAVE_STAT_NSEC)
1278 ansec
= st
->st_atime_nsec
;
1279 mnsec
= st
->st_mtime_nsec
;
1280 cnsec
= st
->st_ctime_nsec
;
1282 ansec
= mnsec
= cnsec
= 0;
1284 fill_time(v
, 7, st
->st_atime
, ansec
);
1285 fill_time(v
, 8, st
->st_mtime
, mnsec
);
1286 fill_time(v
, 9, st
->st_ctime
, cnsec
);
1288 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
1289 PyStructSequence_SET_ITEM(v
, ST_BLKSIZE_IDX
,
1290 PyInt_FromLong((long)st
->st_blksize
));
1292 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
1293 PyStructSequence_SET_ITEM(v
, ST_BLOCKS_IDX
,
1294 PyInt_FromLong((long)st
->st_blocks
));
1296 #ifdef HAVE_STRUCT_STAT_ST_RDEV
1297 PyStructSequence_SET_ITEM(v
, ST_RDEV_IDX
,
1298 PyInt_FromLong((long)st
->st_rdev
));
1300 #ifdef HAVE_STRUCT_STAT_ST_GEN
1301 PyStructSequence_SET_ITEM(v
, ST_GEN_IDX
,
1302 PyInt_FromLong((long)st
->st_gen
));
1304 #ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1307 unsigned long bsec
,bnsec
;
1308 bsec
= (long)st
->st_birthtime
;
1309 #ifdef HAVE_STAT_TV_NSEC2
1310 bnsec
= st
->st_birthtimespec
.tv_nsec
;
1314 if (_stat_float_times
) {
1315 val
= PyFloat_FromDouble(bsec
+ 1e-9*bnsec
);
1317 val
= PyInt_FromLong((long)bsec
);
1319 PyStructSequence_SET_ITEM(v
, ST_BIRTHTIME_IDX
,
1323 #ifdef HAVE_STRUCT_STAT_ST_FLAGS
1324 PyStructSequence_SET_ITEM(v
, ST_FLAGS_IDX
,
1325 PyInt_FromLong((long)st
->st_flags
));
1328 if (PyErr_Occurred()) {
1338 /* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
1339 where / can be used in place of \ and the trailing slash is optional.
1340 Both SERVER and SHARE must have at least one character.
1343 #define ISSLASHA(c) ((c) == '\\' || (c) == '/')
1344 #define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
1346 #define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
1350 IsUNCRootA(char *path
, int pathlen
)
1352 #define ISSLASH ISSLASHA
1356 if (pathlen
< 5 || !ISSLASH(path
[0]) || !ISSLASH(path
[1]))
1357 /* minimum UNCRoot is \\x\y */
1359 for (i
= 2; i
< pathlen
; i
++)
1360 if (ISSLASH(path
[i
])) break;
1361 if (i
== 2 || i
== pathlen
)
1362 /* do not allow \\\SHARE or \\SERVER */
1365 for (i
= share
; i
< pathlen
; i
++)
1366 if (ISSLASH(path
[i
])) break;
1367 return (i
!= share
&& (i
== pathlen
|| i
== pathlen
-1));
1372 #ifdef Py_WIN_WIDE_FILENAMES
1374 IsUNCRootW(Py_UNICODE
*path
, int pathlen
)
1376 #define ISSLASH ISSLASHW
1380 if (pathlen
< 5 || !ISSLASH(path
[0]) || !ISSLASH(path
[1]))
1381 /* minimum UNCRoot is \\x\y */
1383 for (i
= 2; i
< pathlen
; i
++)
1384 if (ISSLASH(path
[i
])) break;
1385 if (i
== 2 || i
== pathlen
)
1386 /* do not allow \\\SHARE or \\SERVER */
1389 for (i
= share
; i
< pathlen
; i
++)
1390 if (ISSLASH(path
[i
])) break;
1391 return (i
!= share
&& (i
== pathlen
|| i
== pathlen
-1));
1395 #endif /* Py_WIN_WIDE_FILENAMES */
1396 #endif /* MS_WINDOWS */
1399 posix_do_stat(PyObject
*self
, PyObject
*args
,
1402 int (*statfunc
)(const char *, STRUCT_STAT
*, ...),
1404 int (*statfunc
)(const char *, STRUCT_STAT
*),
1407 int (*wstatfunc
)(const Py_UNICODE
*, STRUCT_STAT
*))
1410 char *path
= NULL
; /* pass this to stat; do not free() it */
1411 char *pathfree
= NULL
; /* this memory must be free'd */
1415 #ifdef Py_WIN_WIDE_FILENAMES
1416 /* If on wide-character-capable OS see if argument
1417 is Unicode and if so use wide API. */
1418 if (unicode_file_names()) {
1419 PyUnicodeObject
*po
;
1420 if (PyArg_ParseTuple(args
, wformat
, &po
)) {
1421 Py_UNICODE
*wpath
= PyUnicode_AS_UNICODE(po
);
1423 Py_BEGIN_ALLOW_THREADS
1424 /* PyUnicode_AS_UNICODE result OK without
1425 thread lock as it is a simple dereference. */
1426 res
= wstatfunc(wpath
, &st
);
1427 Py_END_ALLOW_THREADS
1430 return win32_error_unicode("stat", wpath
);
1431 return _pystat_fromstructstat(&st
);
1433 /* Drop the argument parsing error as narrow strings
1439 if (!PyArg_ParseTuple(args
, format
,
1440 Py_FileSystemDefaultEncoding
, &path
))
1444 Py_BEGIN_ALLOW_THREADS
1445 res
= (*statfunc
)(path
, &st
);
1446 Py_END_ALLOW_THREADS
1450 result
= win32_error("stat", pathfree
);
1452 result
= posix_error_with_filename(pathfree
);
1456 result
= _pystat_fromstructstat(&st
);
1458 PyMem_Free(pathfree
);
1464 PyDoc_STRVAR(posix_access__doc__
,
1465 "access(path, mode) -> True if granted, False otherwise\n\n\
1466 Use the real uid/gid to test for access to a path. Note that most\n\
1467 operations will use the effective uid/gid, therefore this routine can\n\
1468 be used in a suid/sgid environment to test if the invoking user has the\n\
1469 specified access to the path. The mode argument can be F_OK to test\n\
1470 existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
1473 posix_access(PyObject
*self
, PyObject
*args
)
1478 #ifdef Py_WIN_WIDE_FILENAMES
1480 if (unicode_file_names()) {
1481 PyUnicodeObject
*po
;
1482 if (PyArg_ParseTuple(args
, "Ui:access", &po
, &mode
)) {
1483 Py_BEGIN_ALLOW_THREADS
1484 /* PyUnicode_AS_UNICODE OK without thread lock as
1485 it is a simple dereference. */
1486 attr
= GetFileAttributesW(PyUnicode_AS_UNICODE(po
));
1487 Py_END_ALLOW_THREADS
1490 /* Drop the argument parsing error as narrow strings
1494 if (!PyArg_ParseTuple(args
, "eti:access",
1495 Py_FileSystemDefaultEncoding
, &path
, &mode
))
1497 Py_BEGIN_ALLOW_THREADS
1498 attr
= GetFileAttributesA(path
);
1499 Py_END_ALLOW_THREADS
1502 if (attr
== 0xFFFFFFFF)
1503 /* File does not exist, or cannot read attributes */
1504 return PyBool_FromLong(0);
1505 /* Access is possible if either write access wasn't requested, or
1506 the file isn't read-only. */
1507 return PyBool_FromLong(!(mode
& 2) || !(attr
& FILE_ATTRIBUTE_READONLY
));
1510 if (!PyArg_ParseTuple(args
, "eti:access",
1511 Py_FileSystemDefaultEncoding
, &path
, &mode
))
1513 Py_BEGIN_ALLOW_THREADS
1514 res
= access(path
, mode
);
1515 Py_END_ALLOW_THREADS
1517 return PyBool_FromLong(res
== 0);
1535 PyDoc_STRVAR(posix_ttyname__doc__
,
1536 "ttyname(fd) -> string\n\n\
1537 Return the name of the terminal device connected to 'fd'.");
1540 posix_ttyname(PyObject
*self
, PyObject
*args
)
1545 if (!PyArg_ParseTuple(args
, "i:ttyname", &id
))
1549 /* file descriptor 0 only, the default input device (stdin) */
1560 return posix_error();
1561 return PyString_FromString(ret
);
1566 PyDoc_STRVAR(posix_ctermid__doc__
,
1567 "ctermid() -> string\n\n\
1568 Return the name of the controlling terminal for this process.");
1571 posix_ctermid(PyObject
*self
, PyObject
*noargs
)
1574 char buffer
[L_ctermid
];
1576 #ifdef USE_CTERMID_R
1577 ret
= ctermid_r(buffer
);
1579 ret
= ctermid(buffer
);
1582 return posix_error();
1583 return PyString_FromString(buffer
);
1587 PyDoc_STRVAR(posix_chdir__doc__
,
1589 Change the current working directory to the specified path.");
1592 posix_chdir(PyObject
*self
, PyObject
*args
)
1595 return win32_1str(args
, "chdir", "s:chdir", win32_chdir
, "U:chdir", win32_wchdir
);
1596 #elif defined(PYOS_OS2) && defined(PYCC_GCC)
1597 return posix_1str(args
, "et:chdir", _chdir2
);
1598 #elif defined(__VMS)
1599 return posix_1str(args
, "et:chdir", (int (*)(const char *))chdir
);
1601 return posix_1str(args
, "et:chdir", chdir
);
1606 PyDoc_STRVAR(posix_fchdir__doc__
,
1607 "fchdir(fildes)\n\n\
1608 Change to the directory of the given file descriptor. fildes must be\n\
1609 opened on a directory, not a file.");
1612 posix_fchdir(PyObject
*self
, PyObject
*fdobj
)
1614 return posix_fildes(fdobj
, fchdir
);
1616 #endif /* HAVE_FCHDIR */
1619 PyDoc_STRVAR(posix_chmod__doc__
,
1620 "chmod(path, mode)\n\n\
1621 Change the access permissions of a file.");
1624 posix_chmod(PyObject
*self
, PyObject
*args
)
1629 #ifdef Py_WIN_WIDE_FILENAMES
1631 if (unicode_file_names()) {
1632 PyUnicodeObject
*po
;
1633 if (PyArg_ParseTuple(args
, "Ui|:chmod", &po
, &i
)) {
1634 Py_BEGIN_ALLOW_THREADS
1635 attr
= GetFileAttributesW(PyUnicode_AS_UNICODE(po
));
1636 if (attr
!= 0xFFFFFFFF) {
1638 attr
&= ~FILE_ATTRIBUTE_READONLY
;
1640 attr
|= FILE_ATTRIBUTE_READONLY
;
1641 res
= SetFileAttributesW(PyUnicode_AS_UNICODE(po
), attr
);
1645 Py_END_ALLOW_THREADS
1647 return win32_error_unicode("chmod",
1648 PyUnicode_AS_UNICODE(po
));
1652 /* Drop the argument parsing error as narrow strings
1656 if (!PyArg_ParseTuple(args
, "eti:chmod", Py_FileSystemDefaultEncoding
,
1659 Py_BEGIN_ALLOW_THREADS
1660 attr
= GetFileAttributesA(path
);
1661 if (attr
!= 0xFFFFFFFF) {
1663 attr
&= ~FILE_ATTRIBUTE_READONLY
;
1665 attr
|= FILE_ATTRIBUTE_READONLY
;
1666 res
= SetFileAttributesA(path
, attr
);
1670 Py_END_ALLOW_THREADS
1672 win32_error("chmod", path
);
1679 #else /* Py_WIN_WIDE_FILENAMES */
1680 if (!PyArg_ParseTuple(args
, "eti:chmod", Py_FileSystemDefaultEncoding
,
1683 Py_BEGIN_ALLOW_THREADS
1684 res
= chmod(path
, i
);
1685 Py_END_ALLOW_THREADS
1687 return posix_error_with_allocated_filename(path
);
1696 PyDoc_STRVAR(posix_chflags__doc__
,
1697 "chflags(path, flags)\n\n\
1701 posix_chflags(PyObject
*self
, PyObject
*args
)
1704 unsigned long flags
;
1706 if (!PyArg_ParseTuple(args
, "etk:chflags",
1707 Py_FileSystemDefaultEncoding
, &path
, &flags
))
1709 Py_BEGIN_ALLOW_THREADS
1710 res
= chflags(path
, flags
);
1711 Py_END_ALLOW_THREADS
1713 return posix_error_with_allocated_filename(path
);
1718 #endif /* HAVE_CHFLAGS */
1720 #ifdef HAVE_LCHFLAGS
1721 PyDoc_STRVAR(posix_lchflags__doc__
,
1722 "lchflags(path, flags)\n\n\
1724 This function will not follow symbolic links.");
1727 posix_lchflags(PyObject
*self
, PyObject
*args
)
1730 unsigned long flags
;
1732 if (!PyArg_ParseTuple(args
, "etk:lchflags",
1733 Py_FileSystemDefaultEncoding
, &path
, &flags
))
1735 Py_BEGIN_ALLOW_THREADS
1736 res
= lchflags(path
, flags
);
1737 Py_END_ALLOW_THREADS
1739 return posix_error_with_allocated_filename(path
);
1744 #endif /* HAVE_LCHFLAGS */
1747 PyDoc_STRVAR(posix_chroot__doc__
,
1749 Change root directory to path.");
1752 posix_chroot(PyObject
*self
, PyObject
*args
)
1754 return posix_1str(args
, "et:chroot", chroot
);
1759 PyDoc_STRVAR(posix_fsync__doc__
,
1761 force write of file with filedescriptor to disk.");
1764 posix_fsync(PyObject
*self
, PyObject
*fdobj
)
1766 return posix_fildes(fdobj
, fsync
);
1768 #endif /* HAVE_FSYNC */
1770 #ifdef HAVE_FDATASYNC
1773 extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1776 PyDoc_STRVAR(posix_fdatasync__doc__
,
1777 "fdatasync(fildes)\n\n\
1778 force write of file with filedescriptor to disk.\n\
1779 does not force update of metadata.");
1782 posix_fdatasync(PyObject
*self
, PyObject
*fdobj
)
1784 return posix_fildes(fdobj
, fdatasync
);
1786 #endif /* HAVE_FDATASYNC */
1790 PyDoc_STRVAR(posix_chown__doc__
,
1791 "chown(path, uid, gid)\n\n\
1792 Change the owner and group id of path to the numeric uid and gid.");
1795 posix_chown(PyObject
*self
, PyObject
*args
)
1800 if (!PyArg_ParseTuple(args
, "etii:chown",
1801 Py_FileSystemDefaultEncoding
, &path
,
1804 Py_BEGIN_ALLOW_THREADS
1805 res
= chown(path
, (uid_t
) uid
, (gid_t
) gid
);
1806 Py_END_ALLOW_THREADS
1808 return posix_error_with_allocated_filename(path
);
1813 #endif /* HAVE_CHOWN */
1816 PyDoc_STRVAR(posix_lchown__doc__
,
1817 "lchown(path, uid, gid)\n\n\
1818 Change the owner and group id of path to the numeric uid and gid.\n\
1819 This function will not follow symbolic links.");
1822 posix_lchown(PyObject
*self
, PyObject
*args
)
1827 if (!PyArg_ParseTuple(args
, "etii:lchown",
1828 Py_FileSystemDefaultEncoding
, &path
,
1831 Py_BEGIN_ALLOW_THREADS
1832 res
= lchown(path
, (uid_t
) uid
, (gid_t
) gid
);
1833 Py_END_ALLOW_THREADS
1835 return posix_error_with_allocated_filename(path
);
1840 #endif /* HAVE_LCHOWN */
1844 PyDoc_STRVAR(posix_getcwd__doc__
,
1845 "getcwd() -> path\n\n\
1846 Return a string representing the current working directory.");
1849 posix_getcwd(PyObject
*self
, PyObject
*noargs
)
1854 Py_BEGIN_ALLOW_THREADS
1855 #if defined(PYOS_OS2) && defined(PYCC_GCC)
1856 res
= _getcwd2(buf
, sizeof buf
);
1858 res
= getcwd(buf
, sizeof buf
);
1860 Py_END_ALLOW_THREADS
1862 return posix_error();
1863 return PyString_FromString(buf
);
1866 #ifdef Py_USING_UNICODE
1867 PyDoc_STRVAR(posix_getcwdu__doc__
,
1868 "getcwdu() -> path\n\n\
1869 Return a unicode string representing the current working directory.");
1872 posix_getcwdu(PyObject
*self
, PyObject
*noargs
)
1877 #ifdef Py_WIN_WIDE_FILENAMES
1879 if (unicode_file_names()) {
1881 wchar_t *wbuf2
= wbuf
;
1883 Py_BEGIN_ALLOW_THREADS
1884 len
= GetCurrentDirectoryW(sizeof wbuf
/ sizeof wbuf
[0], wbuf
);
1885 /* If the buffer is large enough, len does not include the
1886 terminating \0. If the buffer is too small, len includes
1887 the space needed for the terminator. */
1888 if (len
>= sizeof wbuf
/ sizeof wbuf
[0]) {
1889 wbuf2
= malloc(len
* sizeof(wchar_t));
1891 len
= GetCurrentDirectoryW(len
, wbuf2
);
1893 Py_END_ALLOW_THREADS
1899 if (wbuf2
!= wbuf
) free(wbuf2
);
1900 return win32_error("getcwdu", NULL
);
1902 resobj
= PyUnicode_FromWideChar(wbuf2
, len
);
1903 if (wbuf2
!= wbuf
) free(wbuf2
);
1908 Py_BEGIN_ALLOW_THREADS
1909 #if defined(PYOS_OS2) && defined(PYCC_GCC)
1910 res
= _getcwd2(buf
, sizeof buf
);
1912 res
= getcwd(buf
, sizeof buf
);
1914 Py_END_ALLOW_THREADS
1916 return posix_error();
1917 return PyUnicode_Decode(buf
, strlen(buf
), Py_FileSystemDefaultEncoding
,"strict");
1924 PyDoc_STRVAR(posix_link__doc__
,
1925 "link(src, dst)\n\n\
1926 Create a hard link to a file.");
1929 posix_link(PyObject
*self
, PyObject
*args
)
1931 return posix_2str(args
, "etet:link", link
);
1933 #endif /* HAVE_LINK */
1936 PyDoc_STRVAR(posix_listdir__doc__
,
1937 "listdir(path) -> list_of_strings\n\n\
1938 Return a list containing the names of the entries in the directory.\n\
1940 path: path of directory to list\n\
1942 The list is in arbitrary order. It does not include the special\n\
1943 entries '.' and '..' even if they are present in the directory.");
1946 posix_listdir(PyObject
*self
, PyObject
*args
)
1948 /* XXX Should redo this putting the (now four) versions of opendir
1949 in separate files instead of having them all here... */
1950 #if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
1955 WIN32_FIND_DATA FileData
;
1956 char namebuf
[MAX_PATH
+5]; /* Overallocate for \\*.*\0 */
1957 char *bufptr
= namebuf
;
1958 Py_ssize_t len
= sizeof(namebuf
)-5; /* only claim to have space for MAX_PATH */
1960 #ifdef Py_WIN_WIDE_FILENAMES
1961 /* If on wide-character-capable OS see if argument
1962 is Unicode and if so use wide API. */
1963 if (unicode_file_names()) {
1965 if (PyArg_ParseTuple(args
, "U:listdir", &po
)) {
1966 WIN32_FIND_DATAW wFileData
;
1967 Py_UNICODE
*wnamebuf
;
1969 /* Overallocate for \\*.*\0 */
1970 len
= PyUnicode_GET_SIZE(po
);
1971 wnamebuf
= malloc((len
+ 5) * sizeof(wchar_t));
1976 wcscpy(wnamebuf
, PyUnicode_AS_UNICODE(po
));
1977 wch
= len
> 0 ? wnamebuf
[len
-1] : '\0';
1978 if (wch
!= L
'/' && wch
!= L
'\\' && wch
!= L
':')
1979 wnamebuf
[len
++] = L
'\\';
1980 wcscpy(wnamebuf
+ len
, L
"*.*");
1981 if ((d
= PyList_New(0)) == NULL
) {
1985 hFindFile
= FindFirstFileW(wnamebuf
, &wFileData
);
1986 if (hFindFile
== INVALID_HANDLE_VALUE
) {
1987 int error
= GetLastError();
1988 if (error
== ERROR_FILE_NOT_FOUND
) {
1993 win32_error_unicode("FindFirstFileW", wnamebuf
);
1998 /* Skip over . and .. */
1999 if (wcscmp(wFileData
.cFileName
, L
".") != 0 &&
2000 wcscmp(wFileData
.cFileName
, L
"..") != 0) {
2001 v
= PyUnicode_FromUnicode(wFileData
.cFileName
, wcslen(wFileData
.cFileName
));
2007 if (PyList_Append(d
, v
) != 0) {
2015 Py_BEGIN_ALLOW_THREADS
2016 result
= FindNextFileW(hFindFile
, &wFileData
);
2017 Py_END_ALLOW_THREADS
2018 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2019 it got to the end of the directory. */
2020 if (!result
&& GetLastError() != ERROR_NO_MORE_FILES
) {
2022 win32_error_unicode("FindNextFileW", wnamebuf
);
2023 FindClose(hFindFile
);
2027 } while (result
== TRUE
);
2029 if (FindClose(hFindFile
) == FALSE
) {
2031 win32_error_unicode("FindClose", wnamebuf
);
2038 /* Drop the argument parsing error as narrow strings
2044 if (!PyArg_ParseTuple(args
, "et#:listdir",
2045 Py_FileSystemDefaultEncoding
, &bufptr
, &len
))
2048 char ch
= namebuf
[len
-1];
2049 if (ch
!= SEP
&& ch
!= ALTSEP
&& ch
!= ':')
2050 namebuf
[len
++] = '/';
2052 strcpy(namebuf
+ len
, "*.*");
2054 if ((d
= PyList_New(0)) == NULL
)
2057 hFindFile
= FindFirstFile(namebuf
, &FileData
);
2058 if (hFindFile
== INVALID_HANDLE_VALUE
) {
2059 int error
= GetLastError();
2060 if (error
== ERROR_FILE_NOT_FOUND
)
2063 return win32_error("FindFirstFile", namebuf
);
2066 /* Skip over . and .. */
2067 if (strcmp(FileData
.cFileName
, ".") != 0 &&
2068 strcmp(FileData
.cFileName
, "..") != 0) {
2069 v
= PyString_FromString(FileData
.cFileName
);
2075 if (PyList_Append(d
, v
) != 0) {
2083 Py_BEGIN_ALLOW_THREADS
2084 result
= FindNextFile(hFindFile
, &FileData
);
2085 Py_END_ALLOW_THREADS
2086 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
2087 it got to the end of the directory. */
2088 if (!result
&& GetLastError() != ERROR_NO_MORE_FILES
) {
2090 win32_error("FindNextFile", namebuf
);
2091 FindClose(hFindFile
);
2094 } while (result
== TRUE
);
2096 if (FindClose(hFindFile
) == FALSE
) {
2098 return win32_error("FindClose", namebuf
);
2103 #elif defined(PYOS_OS2)
2106 #define MAX_PATH CCHMAXPATH
2111 char namebuf
[MAX_PATH
+5];
2117 if (!PyArg_ParseTuple(args
, "t#:listdir", &name
, &len
))
2119 if (len
>= MAX_PATH
) {
2120 PyErr_SetString(PyExc_ValueError
, "path too long");
2123 strcpy(namebuf
, name
);
2124 for (pt
= namebuf
; *pt
; pt
++)
2127 if (namebuf
[len
-1] != SEP
)
2128 namebuf
[len
++] = SEP
;
2129 strcpy(namebuf
+ len
, "*.*");
2131 if ((d
= PyList_New(0)) == NULL
)
2134 rc
= DosFindFirst(namebuf
, /* Wildcard Pattern to Match */
2135 &hdir
, /* Handle to Use While Search Directory */
2136 FILE_READONLY
| FILE_HIDDEN
| FILE_SYSTEM
| FILE_DIRECTORY
,
2137 &ep
, sizeof(ep
), /* Structure to Receive Directory Entry */
2138 &srchcnt
, /* Max and Actual Count of Entries Per Iteration */
2139 FIL_STANDARD
); /* Format of Entry (EAs or Not) */
2141 if (rc
!= NO_ERROR
) {
2143 return posix_error_with_filename(name
);
2146 if (srchcnt
> 0) { /* If Directory is NOT Totally Empty, */
2148 if (ep
.achName
[0] == '.'
2149 && (ep
.achName
[1] == '\0' || (ep
.achName
[1] == '.' && ep
.achName
[2] == '\0')))
2150 continue; /* Skip Over "." and ".." Names */
2152 strcpy(namebuf
, ep
.achName
);
2154 /* Leave Case of Name Alone -- In Native Form */
2155 /* (Removed Forced Lowercasing Code) */
2157 v
= PyString_FromString(namebuf
);
2163 if (PyList_Append(d
, v
) != 0) {
2170 } while (DosFindNext(hdir
, &ep
, sizeof(ep
), &srchcnt
) == NO_ERROR
&& srchcnt
> 0);
2180 int arg_is_unicode
= 1;
2183 if (!PyArg_ParseTuple(args
, "U:listdir", &v
)) {
2187 if (!PyArg_ParseTuple(args
, "et:listdir", Py_FileSystemDefaultEncoding
, &name
))
2189 if ((dirp
= opendir(name
)) == NULL
) {
2190 return posix_error_with_allocated_filename(name
);
2192 if ((d
= PyList_New(0)) == NULL
) {
2198 Py_BEGIN_ALLOW_THREADS
2200 Py_END_ALLOW_THREADS
2203 if (ep
->d_name
[0] == '.' &&
2205 (ep
->d_name
[1] == '.' && NAMLEN(ep
) == 2)))
2207 v
= PyString_FromStringAndSize(ep
->d_name
, NAMLEN(ep
));
2213 #ifdef Py_USING_UNICODE
2214 if (arg_is_unicode
) {
2217 w
= PyUnicode_FromEncodedObject(v
,
2218 Py_FileSystemDefaultEncoding
,
2225 /* fall back to the original byte string, as
2226 discussed in patch #683592 */
2231 if (PyList_Append(d
, v
) != 0) {
2239 if (errno
!= 0 && d
!= NULL
) {
2240 /* readdir() returned NULL and set errno */
2243 return posix_error_with_allocated_filename(name
);
2250 #endif /* which OS */
2251 } /* end of posix_listdir */
2254 /* A helper function for abspath on win32 */
2256 posix__getfullpathname(PyObject
*self
, PyObject
*args
)
2258 /* assume encoded strings wont more than double no of chars */
2259 char inbuf
[MAX_PATH
*2];
2260 char *inbufp
= inbuf
;
2261 Py_ssize_t insize
= sizeof(inbuf
);
2262 char outbuf
[MAX_PATH
*2];
2264 #ifdef Py_WIN_WIDE_FILENAMES
2265 if (unicode_file_names()) {
2266 PyUnicodeObject
*po
;
2267 if (PyArg_ParseTuple(args
, "U|:_getfullpathname", &po
)) {
2268 Py_UNICODE woutbuf
[MAX_PATH
*2];
2270 if (!GetFullPathNameW(PyUnicode_AS_UNICODE(po
),
2271 sizeof(woutbuf
)/sizeof(woutbuf
[0]),
2273 return win32_error("GetFullPathName", "");
2274 return PyUnicode_FromUnicode(woutbuf
, wcslen(woutbuf
));
2276 /* Drop the argument parsing error as narrow strings
2281 if (!PyArg_ParseTuple (args
, "et#:_getfullpathname",
2282 Py_FileSystemDefaultEncoding
, &inbufp
,
2285 if (!GetFullPathName(inbuf
, sizeof(outbuf
)/sizeof(outbuf
[0]),
2287 return win32_error("GetFullPathName", inbuf
);
2288 if (PyUnicode_Check(PyTuple_GetItem(args
, 0))) {
2289 return PyUnicode_Decode(outbuf
, strlen(outbuf
),
2290 Py_FileSystemDefaultEncoding
, NULL
);
2292 return PyString_FromString(outbuf
);
2293 } /* end of posix__getfullpathname */
2294 #endif /* MS_WINDOWS */
2296 PyDoc_STRVAR(posix_mkdir__doc__
,
2297 "mkdir(path [, mode=0777])\n\n\
2298 Create a directory.");
2301 posix_mkdir(PyObject
*self
, PyObject
*args
)
2307 #ifdef Py_WIN_WIDE_FILENAMES
2308 if (unicode_file_names()) {
2309 PyUnicodeObject
*po
;
2310 if (PyArg_ParseTuple(args
, "U|i:mkdir", &po
, &mode
)) {
2311 Py_BEGIN_ALLOW_THREADS
2312 /* PyUnicode_AS_UNICODE OK without thread lock as
2313 it is a simple dereference. */
2314 res
= CreateDirectoryW(PyUnicode_AS_UNICODE(po
), NULL
);
2315 Py_END_ALLOW_THREADS
2317 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po
));
2321 /* Drop the argument parsing error as narrow strings
2325 if (!PyArg_ParseTuple(args
, "et|i:mkdir",
2326 Py_FileSystemDefaultEncoding
, &path
, &mode
))
2328 Py_BEGIN_ALLOW_THREADS
2329 /* PyUnicode_AS_UNICODE OK without thread lock as
2330 it is a simple dereference. */
2331 res
= CreateDirectoryA(path
, NULL
);
2332 Py_END_ALLOW_THREADS
2334 win32_error("mkdir", path
);
2343 if (!PyArg_ParseTuple(args
, "et|i:mkdir",
2344 Py_FileSystemDefaultEncoding
, &path
, &mode
))
2346 Py_BEGIN_ALLOW_THREADS
2347 #if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
2350 res
= mkdir(path
, mode
);
2352 Py_END_ALLOW_THREADS
2354 return posix_error_with_allocated_filename(path
);
2362 /* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2363 #if defined(HAVE_SYS_RESOURCE_H)
2364 #include <sys/resource.h>
2369 PyDoc_STRVAR(posix_nice__doc__
,
2370 "nice(inc) -> new_priority\n\n\
2371 Decrease the priority of process by inc and return the new priority.");
2374 posix_nice(PyObject
*self
, PyObject
*args
)
2376 int increment
, value
;
2378 if (!PyArg_ParseTuple(args
, "i:nice", &increment
))
2381 /* There are two flavours of 'nice': one that returns the new
2382 priority (as required by almost all standards out there) and the
2383 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2384 the use of getpriority() to get the new priority.
2386 If we are of the nice family that returns the new priority, we
2387 need to clear errno before the call, and check if errno is filled
2388 before calling posix_error() on a returnvalue of -1, because the
2389 -1 may be the actual new priority! */
2392 value
= nice(increment
);
2393 #if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
2395 value
= getpriority(PRIO_PROCESS
, 0);
2397 if (value
== -1 && errno
!= 0)
2398 /* either nice() or getpriority() returned an error */
2399 return posix_error();
2400 return PyInt_FromLong((long) value
);
2402 #endif /* HAVE_NICE */
2404 PyDoc_STRVAR(posix_rename__doc__
,
2405 "rename(old, new)\n\n\
2406 Rename a file or directory.");
2409 posix_rename(PyObject
*self
, PyObject
*args
)
2415 if (unicode_file_names()) {
2416 if (!PyArg_ParseTuple(args
, "O&O&:rename",
2417 convert_to_unicode
, &o1
,
2418 convert_to_unicode
, &o2
))
2421 Py_BEGIN_ALLOW_THREADS
2422 result
= MoveFileW(PyUnicode_AsUnicode(o1
),
2423 PyUnicode_AsUnicode(o2
));
2424 Py_END_ALLOW_THREADS
2428 return win32_error("rename", NULL
);
2433 if (!PyArg_ParseTuple(args
, "ss:rename", &p1
, &p2
))
2435 Py_BEGIN_ALLOW_THREADS
2436 result
= MoveFileA(p1
, p2
);
2437 Py_END_ALLOW_THREADS
2439 return win32_error("rename", NULL
);
2443 return posix_2str(args
, "etet:rename", rename
);
2448 PyDoc_STRVAR(posix_rmdir__doc__
,
2450 Remove a directory.");
2453 posix_rmdir(PyObject
*self
, PyObject
*args
)
2456 return win32_1str(args
, "rmdir", "s:rmdir", RemoveDirectoryA
, "U:rmdir", RemoveDirectoryW
);
2458 return posix_1str(args
, "et:rmdir", rmdir
);
2463 PyDoc_STRVAR(posix_stat__doc__
,
2464 "stat(path) -> stat result\n\n\
2465 Perform a stat system call on the given path.");
2468 posix_stat(PyObject
*self
, PyObject
*args
)
2471 return posix_do_stat(self
, args
, "et:stat", STAT
, "U:stat", win32_wstat
);
2473 return posix_do_stat(self
, args
, "et:stat", STAT
, NULL
, NULL
);
2479 PyDoc_STRVAR(posix_system__doc__
,
2480 "system(command) -> exit_status\n\n\
2481 Execute the command (a string) in a subshell.");
2484 posix_system(PyObject
*self
, PyObject
*args
)
2488 if (!PyArg_ParseTuple(args
, "s:system", &command
))
2490 Py_BEGIN_ALLOW_THREADS
2491 sts
= system(command
);
2492 Py_END_ALLOW_THREADS
2493 return PyInt_FromLong(sts
);
2498 PyDoc_STRVAR(posix_umask__doc__
,
2499 "umask(new_mask) -> old_mask\n\n\
2500 Set the current numeric umask and return the previous umask.");
2503 posix_umask(PyObject
*self
, PyObject
*args
)
2506 if (!PyArg_ParseTuple(args
, "i:umask", &i
))
2510 return posix_error();
2511 return PyInt_FromLong((long)i
);
2515 PyDoc_STRVAR(posix_unlink__doc__
,
2517 Remove a file (same as remove(path)).");
2519 PyDoc_STRVAR(posix_remove__doc__
,
2521 Remove a file (same as unlink(path)).");
2524 posix_unlink(PyObject
*self
, PyObject
*args
)
2527 return win32_1str(args
, "remove", "s:remove", DeleteFileA
, "U:remove", DeleteFileW
);
2529 return posix_1str(args
, "et:remove", unlink
);
2535 PyDoc_STRVAR(posix_uname__doc__
,
2536 "uname() -> (sysname, nodename, release, version, machine)\n\n\
2537 Return a tuple identifying the current operating system.");
2540 posix_uname(PyObject
*self
, PyObject
*noargs
)
2545 Py_BEGIN_ALLOW_THREADS
2547 Py_END_ALLOW_THREADS
2549 return posix_error();
2550 return Py_BuildValue("(sssss)",
2557 #endif /* HAVE_UNAME */
2560 extract_time(PyObject
*t
, long* sec
, long* usec
)
2563 if (PyFloat_Check(t
)) {
2564 double tval
= PyFloat_AsDouble(t
);
2565 PyObject
*intobj
= t
->ob_type
->tp_as_number
->nb_int(t
);
2568 intval
= PyInt_AsLong(intobj
);
2570 if (intval
== -1 && PyErr_Occurred())
2573 *usec
= (long)((tval
- intval
) * 1e6
); /* can't exceed 1000000 */
2575 /* If rounding gave us a negative number,
2580 intval
= PyInt_AsLong(t
);
2581 if (intval
== -1 && PyErr_Occurred())
2588 PyDoc_STRVAR(posix_utime__doc__
,
2589 "utime(path, (atime, mtime))\n\
2590 utime(path, None)\n\n\
2591 Set the access and modified time of the file to the given values. If the\n\
2592 second form is used, set the access and modified times to the current time.");
2595 posix_utime(PyObject
*self
, PyObject
*args
)
2597 #ifdef Py_WIN_WIDE_FILENAMES
2599 PyUnicodeObject
*obwpath
;
2600 wchar_t *wpath
= NULL
;
2603 long atimesec
, mtimesec
, ausec
, musec
;
2604 FILETIME atime
, mtime
;
2605 PyObject
*result
= NULL
;
2607 if (unicode_file_names()) {
2608 if (PyArg_ParseTuple(args
, "UO|:utime", &obwpath
, &arg
)) {
2609 wpath
= PyUnicode_AS_UNICODE(obwpath
);
2610 Py_BEGIN_ALLOW_THREADS
2611 hFile
= CreateFileW(wpath
, FILE_WRITE_ATTRIBUTES
, 0,
2612 NULL
, OPEN_EXISTING
,
2613 FILE_FLAG_BACKUP_SEMANTICS
, NULL
);
2614 Py_END_ALLOW_THREADS
2615 if (hFile
== INVALID_HANDLE_VALUE
)
2616 return win32_error_unicode("utime", wpath
);
2618 /* Drop the argument parsing error as narrow strings
2623 if (!PyArg_ParseTuple(args
, "etO:utime",
2624 Py_FileSystemDefaultEncoding
, &apath
, &arg
))
2626 Py_BEGIN_ALLOW_THREADS
2627 hFile
= CreateFileA(apath
, FILE_WRITE_ATTRIBUTES
, 0,
2628 NULL
, OPEN_EXISTING
,
2629 FILE_FLAG_BACKUP_SEMANTICS
, NULL
);
2630 Py_END_ALLOW_THREADS
2631 if (hFile
== INVALID_HANDLE_VALUE
) {
2632 win32_error("utime", apath
);
2639 if (arg
== Py_None
) {
2641 GetSystemTime(&now
);
2642 if (!SystemTimeToFileTime(&now
, &mtime
) ||
2643 !SystemTimeToFileTime(&now
, &atime
)) {
2644 win32_error("utime", NULL
);
2648 else if (!PyTuple_Check(arg
) || PyTuple_Size(arg
) != 2) {
2649 PyErr_SetString(PyExc_TypeError
,
2650 "utime() arg 2 must be a tuple (atime, mtime)");
2654 if (extract_time(PyTuple_GET_ITEM(arg
, 0),
2655 &atimesec
, &ausec
) == -1)
2657 time_t_to_FILE_TIME(atimesec
, 1000*ausec
, &atime
);
2658 if (extract_time(PyTuple_GET_ITEM(arg
, 1),
2659 &mtimesec
, &musec
) == -1)
2661 time_t_to_FILE_TIME(mtimesec
, 1000*musec
, &mtime
);
2663 if (!SetFileTime(hFile
, NULL
, &atime
, &mtime
)) {
2664 /* Avoid putting the file name into the error here,
2665 as that may confuse the user into believing that
2666 something is wrong with the file, when it also
2667 could be the time stamp that gives a problem. */
2668 win32_error("utime", NULL
);
2675 #else /* Py_WIN_WIDE_FILENAMES */
2678 long atime
, mtime
, ausec
, musec
;
2682 #if defined(HAVE_UTIMES)
2683 struct timeval buf
[2];
2684 #define ATIME buf[0].tv_sec
2685 #define MTIME buf[1].tv_sec
2686 #elif defined(HAVE_UTIME_H)
2687 /* XXX should define struct utimbuf instead, above */
2689 #define ATIME buf.actime
2690 #define MTIME buf.modtime
2691 #define UTIME_ARG &buf
2692 #else /* HAVE_UTIMES */
2694 #define ATIME buf[0]
2695 #define MTIME buf[1]
2696 #define UTIME_ARG buf
2697 #endif /* HAVE_UTIMES */
2700 if (!PyArg_ParseTuple(args
, "etO:utime",
2701 Py_FileSystemDefaultEncoding
, &path
, &arg
))
2703 if (arg
== Py_None
) {
2704 /* optional time values not given */
2705 Py_BEGIN_ALLOW_THREADS
2706 res
= utime(path
, NULL
);
2707 Py_END_ALLOW_THREADS
2709 else if (!PyTuple_Check(arg
) || PyTuple_Size(arg
) != 2) {
2710 PyErr_SetString(PyExc_TypeError
,
2711 "utime() arg 2 must be a tuple (atime, mtime)");
2716 if (extract_time(PyTuple_GET_ITEM(arg
, 0),
2717 &atime
, &ausec
) == -1) {
2721 if (extract_time(PyTuple_GET_ITEM(arg
, 1),
2722 &mtime
, &musec
) == -1) {
2729 buf
[0].tv_usec
= ausec
;
2730 buf
[1].tv_usec
= musec
;
2731 Py_BEGIN_ALLOW_THREADS
2732 res
= utimes(path
, buf
);
2733 Py_END_ALLOW_THREADS
2735 Py_BEGIN_ALLOW_THREADS
2736 res
= utime(path
, UTIME_ARG
);
2737 Py_END_ALLOW_THREADS
2738 #endif /* HAVE_UTIMES */
2741 return posix_error_with_allocated_filename(path
);
2749 #endif /* Py_WIN_WIDE_FILENAMES */
2753 /* Process operations */
2755 PyDoc_STRVAR(posix__exit__doc__
,
2757 Exit to the system with specified status, without normal exit processing.");
2760 posix__exit(PyObject
*self
, PyObject
*args
)
2763 if (!PyArg_ParseTuple(args
, "i:_exit", &sts
))
2766 return NULL
; /* Make gcc -Wall happy */
2769 #if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
2771 free_string_array(char **array
, Py_ssize_t count
)
2774 for (i
= 0; i
< count
; i
++)
2775 PyMem_Free(array
[i
]);
2782 PyDoc_STRVAR(posix_execv__doc__
,
2783 "execv(path, args)\n\n\
2784 Execute an executable path with arguments, replacing current process.\n\
2786 path: path of executable file\n\
2787 args: tuple or list of strings");
2790 posix_execv(PyObject
*self
, PyObject
*args
)
2796 PyObject
*(*getitem
)(PyObject
*, Py_ssize_t
);
2798 /* execv has two arguments: (path, argv), where
2799 argv is a list or tuple of strings. */
2801 if (!PyArg_ParseTuple(args
, "etO:execv",
2802 Py_FileSystemDefaultEncoding
,
2805 if (PyList_Check(argv
)) {
2806 argc
= PyList_Size(argv
);
2807 getitem
= PyList_GetItem
;
2809 else if (PyTuple_Check(argv
)) {
2810 argc
= PyTuple_Size(argv
);
2811 getitem
= PyTuple_GetItem
;
2814 PyErr_SetString(PyExc_TypeError
, "execv() arg 2 must be a tuple or list");
2819 argvlist
= PyMem_NEW(char *, argc
+1);
2820 if (argvlist
== NULL
) {
2822 return PyErr_NoMemory();
2824 for (i
= 0; i
< argc
; i
++) {
2825 if (!PyArg_Parse((*getitem
)(argv
, i
), "et",
2826 Py_FileSystemDefaultEncoding
,
2828 free_string_array(argvlist
, i
);
2829 PyErr_SetString(PyExc_TypeError
,
2830 "execv() arg 2 must contain only strings");
2836 argvlist
[argc
] = NULL
;
2838 execv(path
, argvlist
);
2840 /* If we get here it's definitely an error */
2842 free_string_array(argvlist
, argc
);
2844 return posix_error();
2848 PyDoc_STRVAR(posix_execve__doc__
,
2849 "execve(path, args, env)\n\n\
2850 Execute a path with arguments and environment, replacing current process.\n\
2852 path: path of executable file\n\
2853 args: tuple or list of arguments\n\
2854 env: dictionary of strings mapping to strings");
2857 posix_execve(PyObject
*self
, PyObject
*args
)
2860 PyObject
*argv
, *env
;
2863 PyObject
*key
, *val
, *keys
=NULL
, *vals
=NULL
;
2864 Py_ssize_t i
, pos
, argc
, envc
;
2865 PyObject
*(*getitem
)(PyObject
*, Py_ssize_t
);
2866 Py_ssize_t lastarg
= 0;
2868 /* execve has three arguments: (path, argv, env), where
2869 argv is a list or tuple of strings and env is a dictionary
2870 like posix.environ. */
2872 if (!PyArg_ParseTuple(args
, "etOO:execve",
2873 Py_FileSystemDefaultEncoding
,
2874 &path
, &argv
, &env
))
2876 if (PyList_Check(argv
)) {
2877 argc
= PyList_Size(argv
);
2878 getitem
= PyList_GetItem
;
2880 else if (PyTuple_Check(argv
)) {
2881 argc
= PyTuple_Size(argv
);
2882 getitem
= PyTuple_GetItem
;
2885 PyErr_SetString(PyExc_TypeError
,
2886 "execve() arg 2 must be a tuple or list");
2889 if (!PyMapping_Check(env
)) {
2890 PyErr_SetString(PyExc_TypeError
,
2891 "execve() arg 3 must be a mapping object");
2895 argvlist
= PyMem_NEW(char *, argc
+1);
2896 if (argvlist
== NULL
) {
2900 for (i
= 0; i
< argc
; i
++) {
2901 if (!PyArg_Parse((*getitem
)(argv
, i
),
2902 "et;execve() arg 2 must contain only strings",
2903 Py_FileSystemDefaultEncoding
,
2911 argvlist
[argc
] = NULL
;
2913 i
= PyMapping_Size(env
);
2916 envlist
= PyMem_NEW(char *, i
+ 1);
2917 if (envlist
== NULL
) {
2922 keys
= PyMapping_Keys(env
);
2923 vals
= PyMapping_Values(env
);
2926 if (!PyList_Check(keys
) || !PyList_Check(vals
)) {
2927 PyErr_SetString(PyExc_TypeError
,
2928 "execve(): env.keys() or env.values() is not a list");
2932 for (pos
= 0; pos
< i
; pos
++) {
2936 key
= PyList_GetItem(keys
, pos
);
2937 val
= PyList_GetItem(vals
, pos
);
2943 "s;execve() arg 3 contains a non-string key",
2947 "s;execve() arg 3 contains a non-string value",
2953 #if defined(PYOS_OS2)
2954 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
2955 if (stricmp(k
, "BEGINLIBPATH") != 0 && stricmp(k
, "ENDLIBPATH") != 0) {
2957 len
= PyString_Size(key
) + PyString_Size(val
) + 2;
2958 p
= PyMem_NEW(char, len
);
2963 PyOS_snprintf(p
, len
, "%s=%s", k
, v
);
2964 envlist
[envc
++] = p
;
2965 #if defined(PYOS_OS2)
2971 execve(path
, argvlist
, envlist
);
2973 /* If we get here it's definitely an error */
2975 (void) posix_error();
2979 PyMem_DEL(envlist
[envc
]);
2982 free_string_array(argvlist
, lastarg
);
2989 #endif /* HAVE_EXECV */
2993 PyDoc_STRVAR(posix_spawnv__doc__
,
2994 "spawnv(mode, path, args)\n\n\
2995 Execute the program 'path' in a new process.\n\
2997 mode: mode of process creation\n\
2998 path: path of executable file\n\
2999 args: tuple or list of strings");
3002 posix_spawnv(PyObject
*self
, PyObject
*args
)
3009 Py_intptr_t spawnval
;
3010 PyObject
*(*getitem
)(PyObject
*, Py_ssize_t
);
3012 /* spawnv has three arguments: (mode, path, argv), where
3013 argv is a list or tuple of strings. */
3015 if (!PyArg_ParseTuple(args
, "ietO:spawnv", &mode
,
3016 Py_FileSystemDefaultEncoding
,
3019 if (PyList_Check(argv
)) {
3020 argc
= PyList_Size(argv
);
3021 getitem
= PyList_GetItem
;
3023 else if (PyTuple_Check(argv
)) {
3024 argc
= PyTuple_Size(argv
);
3025 getitem
= PyTuple_GetItem
;
3028 PyErr_SetString(PyExc_TypeError
,
3029 "spawnv() arg 2 must be a tuple or list");
3034 argvlist
= PyMem_NEW(char *, argc
+1);
3035 if (argvlist
== NULL
) {
3037 return PyErr_NoMemory();
3039 for (i
= 0; i
< argc
; i
++) {
3040 if (!PyArg_Parse((*getitem
)(argv
, i
), "et",
3041 Py_FileSystemDefaultEncoding
,
3043 free_string_array(argvlist
, i
);
3046 "spawnv() arg 2 must contain only strings");
3051 argvlist
[argc
] = NULL
;
3053 #if defined(PYOS_OS2) && defined(PYCC_GCC)
3054 Py_BEGIN_ALLOW_THREADS
3055 spawnval
= spawnv(mode
, path
, argvlist
);
3056 Py_END_ALLOW_THREADS
3058 if (mode
== _OLD_P_OVERLAY
)
3061 Py_BEGIN_ALLOW_THREADS
3062 spawnval
= _spawnv(mode
, path
, argvlist
);
3063 Py_END_ALLOW_THREADS
3066 free_string_array(argvlist
, argc
);
3070 return posix_error();
3072 #if SIZEOF_LONG == SIZEOF_VOID_P
3073 return Py_BuildValue("l", (long) spawnval
);
3075 return Py_BuildValue("L", (PY_LONG_LONG
) spawnval
);
3080 PyDoc_STRVAR(posix_spawnve__doc__
,
3081 "spawnve(mode, path, args, env)\n\n\
3082 Execute the program 'path' in a new process.\n\
3084 mode: mode of process creation\n\
3085 path: path of executable file\n\
3086 args: tuple or list of arguments\n\
3087 env: dictionary of strings mapping to strings");
3090 posix_spawnve(PyObject
*self
, PyObject
*args
)
3093 PyObject
*argv
, *env
;
3096 PyObject
*key
, *val
, *keys
=NULL
, *vals
=NULL
, *res
=NULL
;
3097 int mode
, pos
, envc
;
3099 Py_intptr_t spawnval
;
3100 PyObject
*(*getitem
)(PyObject
*, Py_ssize_t
);
3101 Py_ssize_t lastarg
= 0;
3103 /* spawnve has four arguments: (mode, path, argv, env), where
3104 argv is a list or tuple of strings and env is a dictionary
3105 like posix.environ. */
3107 if (!PyArg_ParseTuple(args
, "ietOO:spawnve", &mode
,
3108 Py_FileSystemDefaultEncoding
,
3109 &path
, &argv
, &env
))
3111 if (PyList_Check(argv
)) {
3112 argc
= PyList_Size(argv
);
3113 getitem
= PyList_GetItem
;
3115 else if (PyTuple_Check(argv
)) {
3116 argc
= PyTuple_Size(argv
);
3117 getitem
= PyTuple_GetItem
;
3120 PyErr_SetString(PyExc_TypeError
,
3121 "spawnve() arg 2 must be a tuple or list");
3124 if (!PyMapping_Check(env
)) {
3125 PyErr_SetString(PyExc_TypeError
,
3126 "spawnve() arg 3 must be a mapping object");
3130 argvlist
= PyMem_NEW(char *, argc
+1);
3131 if (argvlist
== NULL
) {
3135 for (i
= 0; i
< argc
; i
++) {
3136 if (!PyArg_Parse((*getitem
)(argv
, i
),
3137 "et;spawnve() arg 2 must contain only strings",
3138 Py_FileSystemDefaultEncoding
,
3146 argvlist
[argc
] = NULL
;
3148 i
= PyMapping_Size(env
);
3151 envlist
= PyMem_NEW(char *, i
+ 1);
3152 if (envlist
== NULL
) {
3157 keys
= PyMapping_Keys(env
);
3158 vals
= PyMapping_Values(env
);
3161 if (!PyList_Check(keys
) || !PyList_Check(vals
)) {
3162 PyErr_SetString(PyExc_TypeError
,
3163 "spawnve(): env.keys() or env.values() is not a list");
3167 for (pos
= 0; pos
< i
; pos
++) {
3171 key
= PyList_GetItem(keys
, pos
);
3172 val
= PyList_GetItem(vals
, pos
);
3178 "s;spawnve() arg 3 contains a non-string key",
3182 "s;spawnve() arg 3 contains a non-string value",
3187 len
= PyString_Size(key
) + PyString_Size(val
) + 2;
3188 p
= PyMem_NEW(char, len
);
3193 PyOS_snprintf(p
, len
, "%s=%s", k
, v
);
3194 envlist
[envc
++] = p
;
3198 #if defined(PYOS_OS2) && defined(PYCC_GCC)
3199 Py_BEGIN_ALLOW_THREADS
3200 spawnval
= spawnve(mode
, path
, argvlist
, envlist
);
3201 Py_END_ALLOW_THREADS
3203 if (mode
== _OLD_P_OVERLAY
)
3206 Py_BEGIN_ALLOW_THREADS
3207 spawnval
= _spawnve(mode
, path
, argvlist
, envlist
);
3208 Py_END_ALLOW_THREADS
3212 (void) posix_error();
3214 #if SIZEOF_LONG == SIZEOF_VOID_P
3215 res
= Py_BuildValue("l", (long) spawnval
);
3217 res
= Py_BuildValue("L", (PY_LONG_LONG
) spawnval
);
3222 PyMem_DEL(envlist
[envc
]);
3225 free_string_array(argvlist
, lastarg
);
3233 /* OS/2 supports spawnvp & spawnvpe natively */
3234 #if defined(PYOS_OS2)
3235 PyDoc_STRVAR(posix_spawnvp__doc__
,
3236 "spawnvp(mode, file, args)\n\n\
3237 Execute the program 'file' in a new process, using the environment\n\
3238 search path to find the file.\n\
3240 mode: mode of process creation\n\
3241 file: executable file name\n\
3242 args: tuple or list of strings");
3245 posix_spawnvp(PyObject
*self
, PyObject
*args
)
3251 Py_intptr_t spawnval
;
3252 PyObject
*(*getitem
)(PyObject
*, Py_ssize_t
);
3254 /* spawnvp has three arguments: (mode, path, argv), where
3255 argv is a list or tuple of strings. */
3257 if (!PyArg_ParseTuple(args
, "ietO:spawnvp", &mode
,
3258 Py_FileSystemDefaultEncoding
,
3261 if (PyList_Check(argv
)) {
3262 argc
= PyList_Size(argv
);
3263 getitem
= PyList_GetItem
;
3265 else if (PyTuple_Check(argv
)) {
3266 argc
= PyTuple_Size(argv
);
3267 getitem
= PyTuple_GetItem
;
3270 PyErr_SetString(PyExc_TypeError
,
3271 "spawnvp() arg 2 must be a tuple or list");
3276 argvlist
= PyMem_NEW(char *, argc
+1);
3277 if (argvlist
== NULL
) {
3279 return PyErr_NoMemory();
3281 for (i
= 0; i
< argc
; i
++) {
3282 if (!PyArg_Parse((*getitem
)(argv
, i
), "et",
3283 Py_FileSystemDefaultEncoding
,
3285 free_string_array(argvlist
, i
);
3288 "spawnvp() arg 2 must contain only strings");
3293 argvlist
[argc
] = NULL
;
3295 Py_BEGIN_ALLOW_THREADS
3296 #if defined(PYCC_GCC)
3297 spawnval
= spawnvp(mode
, path
, argvlist
);
3299 spawnval
= _spawnvp(mode
, path
, argvlist
);
3301 Py_END_ALLOW_THREADS
3303 free_string_array(argvlist
, argc
);
3307 return posix_error();
3309 return Py_BuildValue("l", (long) spawnval
);
3313 PyDoc_STRVAR(posix_spawnvpe__doc__
,
3314 "spawnvpe(mode, file, args, env)\n\n\
3315 Execute the program 'file' in a new process, using the environment\n\
3316 search path to find the file.\n\
3318 mode: mode of process creation\n\
3319 file: executable file name\n\
3320 args: tuple or list of arguments\n\
3321 env: dictionary of strings mapping to strings");
3324 posix_spawnvpe(PyObject
*self
, PyObject
*args
)
3327 PyObject
*argv
, *env
;
3330 PyObject
*key
, *val
, *keys
=NULL
, *vals
=NULL
, *res
=NULL
;
3331 int mode
, i
, pos
, argc
, envc
;
3332 Py_intptr_t spawnval
;
3333 PyObject
*(*getitem
)(PyObject
*, Py_ssize_t
);
3336 /* spawnvpe has four arguments: (mode, path, argv, env), where
3337 argv is a list or tuple of strings and env is a dictionary
3338 like posix.environ. */
3340 if (!PyArg_ParseTuple(args
, "ietOO:spawnvpe", &mode
,
3341 Py_FileSystemDefaultEncoding
,
3342 &path
, &argv
, &env
))
3344 if (PyList_Check(argv
)) {
3345 argc
= PyList_Size(argv
);
3346 getitem
= PyList_GetItem
;
3348 else if (PyTuple_Check(argv
)) {
3349 argc
= PyTuple_Size(argv
);
3350 getitem
= PyTuple_GetItem
;
3353 PyErr_SetString(PyExc_TypeError
,
3354 "spawnvpe() arg 2 must be a tuple or list");
3357 if (!PyMapping_Check(env
)) {
3358 PyErr_SetString(PyExc_TypeError
,
3359 "spawnvpe() arg 3 must be a mapping object");
3363 argvlist
= PyMem_NEW(char *, argc
+1);
3364 if (argvlist
== NULL
) {
3368 for (i
= 0; i
< argc
; i
++) {
3369 if (!PyArg_Parse((*getitem
)(argv
, i
),
3370 "et;spawnvpe() arg 2 must contain only strings",
3371 Py_FileSystemDefaultEncoding
,
3379 argvlist
[argc
] = NULL
;
3381 i
= PyMapping_Size(env
);
3384 envlist
= PyMem_NEW(char *, i
+ 1);
3385 if (envlist
== NULL
) {
3390 keys
= PyMapping_Keys(env
);
3391 vals
= PyMapping_Values(env
);
3394 if (!PyList_Check(keys
) || !PyList_Check(vals
)) {
3395 PyErr_SetString(PyExc_TypeError
,
3396 "spawnvpe(): env.keys() or env.values() is not a list");
3400 for (pos
= 0; pos
< i
; pos
++) {
3404 key
= PyList_GetItem(keys
, pos
);
3405 val
= PyList_GetItem(vals
, pos
);
3411 "s;spawnvpe() arg 3 contains a non-string key",
3415 "s;spawnvpe() arg 3 contains a non-string value",
3420 len
= PyString_Size(key
) + PyString_Size(val
) + 2;
3421 p
= PyMem_NEW(char, len
);
3426 PyOS_snprintf(p
, len
, "%s=%s", k
, v
);
3427 envlist
[envc
++] = p
;
3431 Py_BEGIN_ALLOW_THREADS
3432 #if defined(PYCC_GCC)
3433 spawnval
= spawnve(mode
, path
, argvlist
, envlist
);
3435 spawnval
= _spawnve(mode
, path
, argvlist
, envlist
);
3437 Py_END_ALLOW_THREADS
3440 (void) posix_error();
3442 res
= Py_BuildValue("l", (long) spawnval
);
3446 PyMem_DEL(envlist
[envc
]);
3449 free_string_array(argvlist
, lastarg
);
3456 #endif /* PYOS_OS2 */
3457 #endif /* HAVE_SPAWNV */
3461 PyDoc_STRVAR(posix_fork1__doc__
,
3462 "fork1() -> pid\n\n\
3463 Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3465 Return 0 to child process and PID of child to parent process.");
3468 posix_fork1(PyObject
*self
, PyObject
*noargs
)
3472 return posix_error();
3474 return PyInt_FromLong((long)pid
);
3480 PyDoc_STRVAR(posix_fork__doc__
,
3482 Fork a child process.\n\
3483 Return 0 to child process and PID of child to parent process.");
3486 posix_fork(PyObject
*self
, PyObject
*noargs
)
3490 return posix_error();
3493 return PyInt_FromLong((long)pid
);
3497 /* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
3498 /* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3499 #if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
3500 #define DEV_PTY_FILE "/dev/ptc"
3501 #define HAVE_DEV_PTMX
3503 #define DEV_PTY_FILE "/dev/ptmx"
3506 #if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
3510 #ifdef HAVE_LIBUTIL_H
3511 #include <libutil.h>
3512 #endif /* HAVE_LIBUTIL_H */
3513 #endif /* HAVE_PTY_H */
3514 #ifdef HAVE_STROPTS_H
3515 #include <stropts.h>
3517 #endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
3519 #if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
3520 PyDoc_STRVAR(posix_openpty__doc__
,
3521 "openpty() -> (master_fd, slave_fd)\n\n\
3522 Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
3525 posix_openpty(PyObject
*self
, PyObject
*noargs
)
3527 int master_fd
, slave_fd
;
3528 #ifndef HAVE_OPENPTY
3531 #if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
3532 PyOS_sighandler_t sig_saved
;
3534 extern char *ptsname(int fildes
);
3539 if (openpty(&master_fd
, &slave_fd
, NULL
, NULL
, NULL
) != 0)
3540 return posix_error();
3541 #elif defined(HAVE__GETPTY)
3542 slave_name
= _getpty(&master_fd
, O_RDWR
, 0666, 0);
3543 if (slave_name
== NULL
)
3544 return posix_error();
3546 slave_fd
= open(slave_name
, O_RDWR
);
3548 return posix_error();
3550 master_fd
= open(DEV_PTY_FILE
, O_RDWR
| O_NOCTTY
); /* open master */
3552 return posix_error();
3553 sig_saved
= PyOS_setsig(SIGCHLD
, SIG_DFL
);
3554 /* change permission of slave */
3555 if (grantpt(master_fd
) < 0) {
3556 PyOS_setsig(SIGCHLD
, sig_saved
);
3557 return posix_error();
3560 if (unlockpt(master_fd
) < 0) {
3561 PyOS_setsig(SIGCHLD
, sig_saved
);
3562 return posix_error();
3564 PyOS_setsig(SIGCHLD
, sig_saved
);
3565 slave_name
= ptsname(master_fd
); /* get name of slave */
3566 if (slave_name
== NULL
)
3567 return posix_error();
3568 slave_fd
= open(slave_name
, O_RDWR
| O_NOCTTY
); /* open slave */
3570 return posix_error();
3571 #if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
3572 ioctl(slave_fd
, I_PUSH
, "ptem"); /* push ptem */
3573 ioctl(slave_fd
, I_PUSH
, "ldterm"); /* push ldterm */
3575 ioctl(slave_fd
, I_PUSH
, "ttcompat"); /* push ttcompat */
3577 #endif /* HAVE_CYGWIN */
3578 #endif /* HAVE_OPENPTY */
3580 return Py_BuildValue("(ii)", master_fd
, slave_fd
);
3583 #endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
3586 PyDoc_STRVAR(posix_forkpty__doc__
,
3587 "forkpty() -> (pid, master_fd)\n\n\
3588 Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
3589 Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
3590 To both, return fd of newly opened pseudo-terminal.\n");
3593 posix_forkpty(PyObject
*self
, PyObject
*noargs
)
3595 int master_fd
= -1, pid
;
3597 pid
= forkpty(&master_fd
, NULL
, NULL
, NULL
);
3599 return posix_error();
3602 return Py_BuildValue("(ii)", pid
, master_fd
);
3607 PyDoc_STRVAR(posix_getegid__doc__
,
3608 "getegid() -> egid\n\n\
3609 Return the current process's effective group id.");
3612 posix_getegid(PyObject
*self
, PyObject
*noargs
)
3614 return PyInt_FromLong((long)getegid());
3620 PyDoc_STRVAR(posix_geteuid__doc__
,
3621 "geteuid() -> euid\n\n\
3622 Return the current process's effective user id.");
3625 posix_geteuid(PyObject
*self
, PyObject
*noargs
)
3627 return PyInt_FromLong((long)geteuid());
3633 PyDoc_STRVAR(posix_getgid__doc__
,
3634 "getgid() -> gid\n\n\
3635 Return the current process's group id.");
3638 posix_getgid(PyObject
*self
, PyObject
*noargs
)
3640 return PyInt_FromLong((long)getgid());
3645 PyDoc_STRVAR(posix_getpid__doc__
,
3646 "getpid() -> pid\n\n\
3647 Return the current process id");
3650 posix_getpid(PyObject
*self
, PyObject
*noargs
)
3652 return PyInt_FromLong((long)getpid());
3656 #ifdef HAVE_GETGROUPS
3657 PyDoc_STRVAR(posix_getgroups__doc__
,
3658 "getgroups() -> list of group IDs\n\n\
3659 Return list of supplemental group IDs for the process.");
3662 posix_getgroups(PyObject
*self
, PyObject
*noargs
)
3664 PyObject
*result
= NULL
;
3667 #define MAX_GROUPS NGROUPS_MAX
3669 /* defined to be 16 on Solaris7, so this should be a small number */
3670 #define MAX_GROUPS 64
3672 gid_t grouplist
[MAX_GROUPS
];
3675 n
= getgroups(MAX_GROUPS
, grouplist
);
3679 result
= PyList_New(n
);
3680 if (result
!= NULL
) {
3682 for (i
= 0; i
< n
; ++i
) {
3683 PyObject
*o
= PyInt_FromLong((long)grouplist
[i
]);
3689 PyList_SET_ITEM(result
, i
, o
);
3699 PyDoc_STRVAR(posix_getpgid__doc__
,
3700 "getpgid(pid) -> pgid\n\n\
3701 Call the system call getpgid().");
3704 posix_getpgid(PyObject
*self
, PyObject
*args
)
3707 if (!PyArg_ParseTuple(args
, "i:getpgid", &pid
))
3709 pgid
= getpgid(pid
);
3711 return posix_error();
3712 return PyInt_FromLong((long)pgid
);
3714 #endif /* HAVE_GETPGID */
3718 PyDoc_STRVAR(posix_getpgrp__doc__
,
3719 "getpgrp() -> pgrp\n\n\
3720 Return the current process group id.");
3723 posix_getpgrp(PyObject
*self
, PyObject
*noargs
)
3725 #ifdef GETPGRP_HAVE_ARG
3726 return PyInt_FromLong((long)getpgrp(0));
3727 #else /* GETPGRP_HAVE_ARG */
3728 return PyInt_FromLong((long)getpgrp());
3729 #endif /* GETPGRP_HAVE_ARG */
3731 #endif /* HAVE_GETPGRP */
3735 PyDoc_STRVAR(posix_setpgrp__doc__
,
3737 Make this process a session leader.");
3740 posix_setpgrp(PyObject
*self
, PyObject
*noargs
)
3742 #ifdef SETPGRP_HAVE_ARG
3743 if (setpgrp(0, 0) < 0)
3744 #else /* SETPGRP_HAVE_ARG */
3746 #endif /* SETPGRP_HAVE_ARG */
3747 return posix_error();
3752 #endif /* HAVE_SETPGRP */
3755 PyDoc_STRVAR(posix_getppid__doc__
,
3756 "getppid() -> ppid\n\n\
3757 Return the parent's process id.");
3760 posix_getppid(PyObject
*self
, PyObject
*noargs
)
3762 return PyInt_FromLong((long)getppid());
3767 #ifdef HAVE_GETLOGIN
3768 PyDoc_STRVAR(posix_getlogin__doc__
,
3769 "getlogin() -> string\n\n\
3770 Return the actual login name.");
3773 posix_getlogin(PyObject
*self
, PyObject
*noargs
)
3775 PyObject
*result
= NULL
;
3777 int old_errno
= errno
;
3785 PyErr_SetString(PyExc_OSError
,
3786 "unable to determine login name");
3789 result
= PyString_FromString(name
);
3797 PyDoc_STRVAR(posix_getuid__doc__
,
3798 "getuid() -> uid\n\n\
3799 Return the current process's user id.");
3802 posix_getuid(PyObject
*self
, PyObject
*noargs
)
3804 return PyInt_FromLong((long)getuid());
3810 PyDoc_STRVAR(posix_kill__doc__
,
3811 "kill(pid, sig)\n\n\
3812 Kill a process with a signal.");
3815 posix_kill(PyObject
*self
, PyObject
*args
)
3818 if (!PyArg_ParseTuple(args
, "ii:kill", &pid
, &sig
))
3820 #if defined(PYOS_OS2) && !defined(PYCC_GCC)
3821 if (sig
== XCPT_SIGNAL_INTR
|| sig
== XCPT_SIGNAL_BREAK
) {
3823 if ((rc
= DosSendSignalException(pid
, sig
)) != NO_ERROR
)
3824 return os2_error(rc
);
3826 } else if (sig
== XCPT_SIGNAL_KILLPROC
) {
3828 if ((rc
= DosKillProcess(DKP_PROCESS
, pid
)) != NO_ERROR
)
3829 return os2_error(rc
);
3832 return NULL
; /* Unrecognized Signal Requested */
3834 if (kill(pid
, sig
) == -1)
3835 return posix_error();
3843 PyDoc_STRVAR(posix_killpg__doc__
,
3844 "killpg(pgid, sig)\n\n\
3845 Kill a process group with a signal.");
3848 posix_killpg(PyObject
*self
, PyObject
*args
)
3851 if (!PyArg_ParseTuple(args
, "ii:killpg", &pgid
, &sig
))
3853 if (killpg(pgid
, sig
) == -1)
3854 return posix_error();
3862 #ifdef HAVE_SYS_LOCK_H
3863 #include <sys/lock.h>
3866 PyDoc_STRVAR(posix_plock__doc__
,
3868 Lock program segments into memory.");
3871 posix_plock(PyObject
*self
, PyObject
*args
)
3874 if (!PyArg_ParseTuple(args
, "i:plock", &op
))
3876 if (plock(op
) == -1)
3877 return posix_error();
3885 PyDoc_STRVAR(posix_popen__doc__
,
3886 "popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
3887 Open a pipe to/from a command returning a file object.");
3889 #if defined(PYOS_OS2)
3890 #if defined(PYCC_VACPP)
3892 async_system(const char *command
)
3894 char errormsg
[256], args
[1024];
3898 char *shell
= getenv("COMSPEC");
3902 /* avoid overflowing the argument buffer */
3903 if (strlen(shell
) + 3 + strlen(command
) >= 1024)
3904 return ERROR_NOT_ENOUGH_MEMORY
3907 strcat(args
, shell
);
3908 strcat(args
, "/c ");
3909 strcat(args
, command
);
3911 /* execute asynchronously, inheriting the environment */
3912 rc
= DosExecPgm(errormsg
,
3923 popen(const char *command
, const char *mode
, int pipesize
, int *err
)
3929 /* mode determines which of stdin or stdout is reconnected to
3930 * the pipe to the child
3932 if (strchr(mode
, 'r') != NULL
) {
3933 tgt_fd
= 1; /* stdout */
3934 } else if (strchr(mode
, 'w')) {
3935 tgt_fd
= 0; /* stdin */
3937 *err
= ERROR_INVALID_ACCESS
;
3941 /* setup the pipe */
3942 if ((rc
= DosCreatePipe(&pipeh
[0], &pipeh
[1], pipesize
)) != NO_ERROR
) {
3947 /* prevent other threads accessing stdio */
3950 /* reconnect stdio and execute child */
3953 if (dup2(pipeh
[tgtfd
], tgtfd
) == 0) {
3954 DosClose(pipeh
[tgtfd
]);
3955 rc
= async_system(command
);
3962 /* allow other threads access to stdio */
3965 /* if execution of child was successful return file stream */
3967 return fdopen(pipeh
[1 - tgtfd
], mode
);
3969 DosClose(pipeh
[1 - tgtfd
]);
3976 posix_popen(PyObject
*self
, PyObject
*args
)
3980 int err
, bufsize
= -1;
3983 if (!PyArg_ParseTuple(args
, "s|si:popen", &name
, &mode
, &bufsize
))
3985 Py_BEGIN_ALLOW_THREADS
3986 fp
= popen(name
, mode
, (bufsize
> 0) ? bufsize
: 4096, &err
);
3987 Py_END_ALLOW_THREADS
3989 return os2_error(err
);
3991 f
= PyFile_FromFile(fp
, name
, mode
, fclose
);
3993 PyFile_SetBufSize(f
, bufsize
);
3997 #elif defined(PYCC_GCC)
3999 /* standard posix version of popen() support */
4001 posix_popen(PyObject
*self
, PyObject
*args
)
4008 if (!PyArg_ParseTuple(args
, "s|si:popen", &name
, &mode
, &bufsize
))
4010 Py_BEGIN_ALLOW_THREADS
4011 fp
= popen(name
, mode
);
4012 Py_END_ALLOW_THREADS
4014 return posix_error();
4015 f
= PyFile_FromFile(fp
, name
, mode
, pclose
);
4017 PyFile_SetBufSize(f
, bufsize
);
4021 /* fork() under OS/2 has lots'o'warts
4022 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
4023 * most of this code is a ripoff of the win32 code, but using the
4024 * capabilities of EMX's C library routines
4027 /* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
4033 static PyObject
*_PyPopen(char *, int, int, int);
4034 static int _PyPclose(FILE *file
);
4037 * Internal dictionary mapping popen* file pointers to process handles,
4038 * for use when retrieving the process exit code. See _PyPclose() below
4039 * for more information on this dictionary's use.
4041 static PyObject
*_PyPopenProcs
= NULL
;
4043 /* os2emx version of popen2()
4045 * The result of this function is a pipe (file) connected to the
4046 * process's stdin, and a pipe connected to the process's stdout.
4050 os2emx_popen2(PyObject
*self
, PyObject
*args
)
4058 if (!PyArg_ParseTuple(args
, "s|si:popen2", &cmdstring
, &mode
, &bufsize
))
4063 else if (*mode
!= 'b') {
4064 PyErr_SetString(PyExc_ValueError
, "mode must be 't' or 'b'");
4069 f
= _PyPopen(cmdstring
, tm
, POPEN_2
, bufsize
);
4075 * Variation on os2emx.popen2
4077 * The result of this function is 3 pipes - the process's stdin,
4082 os2emx_popen3(PyObject
*self
, PyObject
*args
)
4090 if (!PyArg_ParseTuple(args
, "s|si:popen3", &cmdstring
, &mode
, &bufsize
))
4095 else if (*mode
!= 'b') {
4096 PyErr_SetString(PyExc_ValueError
, "mode must be 't' or 'b'");
4101 f
= _PyPopen(cmdstring
, tm
, POPEN_3
, bufsize
);
4107 * Variation on os2emx.popen2
4109 * The result of this function is 2 pipes - the processes stdin,
4110 * and stdout+stderr combined as a single pipe.
4114 os2emx_popen4(PyObject
*self
, PyObject
*args
)
4122 if (!PyArg_ParseTuple(args
, "s|si:popen4", &cmdstring
, &mode
, &bufsize
))
4127 else if (*mode
!= 'b') {
4128 PyErr_SetString(PyExc_ValueError
, "mode must be 't' or 'b'");
4133 f
= _PyPopen(cmdstring
, tm
, POPEN_4
, bufsize
);
4138 /* a couple of structures for convenient handling of multiple
4139 * file handles and pipes
4153 /* The following code is derived from the win32 code */
4156 _PyPopen(char *cmdstring
, int mode
, int n
, int bufsize
)
4158 struct file_ref stdio
[3];
4159 struct pipe_ref p_fd
[3];
4161 int file_count
, i
, pipe_err
, pipe_pid
;
4162 char *shell
, *sh_name
, *opt
, *rd_mode
, *wr_mode
;
4163 PyObject
*f
, *p_f
[3];
4165 /* file modes for subsequent fdopen's on pipe handles */
4177 /* prepare shell references */
4178 if ((shell
= getenv("EMXSHELL")) == NULL
)
4179 if ((shell
= getenv("COMSPEC")) == NULL
)
4182 return posix_error();
4185 sh_name
= _getname(shell
);
4186 if (stricmp(sh_name
, "cmd.exe") == 0 || stricmp(sh_name
, "4os2.exe") == 0)
4191 /* save current stdio fds + their flags, and set not inheritable */
4193 while (pipe_err
>= 0 && i
< 3)
4195 pipe_err
= stdio
[i
].handle
= dup(i
);
4196 stdio
[i
].flags
= fcntl(i
, F_GETFD
, 0);
4197 fcntl(stdio
[i
].handle
, F_SETFD
, stdio
[i
].flags
| FD_CLOEXEC
);
4202 /* didn't get them all saved - clean up and bail out */
4203 int saved_err
= errno
;
4206 close(stdio
[i
].handle
);
4209 return posix_error();
4212 /* create pipe ends */
4217 while ((pipe_err
== 0) && (i
< file_count
))
4218 pipe_err
= pipe((int *)&p_fd
[i
++]);
4221 /* didn't get them all made - clean up and bail out */
4228 return posix_error();
4231 /* change the actual standard IO streams over temporarily,
4232 * making the retained pipe ends non-inheritable
4237 if (dup2(p_fd
[0].rd
, 0) == 0)
4240 i
= fcntl(p_fd
[0].wr
, F_GETFD
, 0);
4241 fcntl(p_fd
[0].wr
, F_SETFD
, i
| FD_CLOEXEC
);
4242 if ((p_s
[0] = fdopen(p_fd
[0].wr
, wr_mode
)) == NULL
)
4256 if (dup2(p_fd
[1].wr
, 1) == 1)
4259 i
= fcntl(p_fd
[1].rd
, F_GETFD
, 0);
4260 fcntl(p_fd
[1].rd
, F_SETFD
, i
| FD_CLOEXEC
);
4261 if ((p_s
[1] = fdopen(p_fd
[1].rd
, rd_mode
)) == NULL
)
4273 /* - stderr, as required */
4279 if (dup2(p_fd
[2].wr
, 2) == 2)
4282 i
= fcntl(p_fd
[2].rd
, F_GETFD
, 0);
4283 fcntl(p_fd
[2].rd
, F_SETFD
, i
| FD_CLOEXEC
);
4284 if ((p_s
[2] = fdopen(p_fd
[2].rd
, rd_mode
)) == NULL
)
4299 if (dup2(1, 2) != 2)
4307 /* spawn the child process */
4310 pipe_pid
= spawnlp(P_NOWAIT
, shell
, shell
, opt
, cmdstring
, (char *)0);
4317 /* save the PID into the FILE structure
4318 * NOTE: this implementation doesn't actually
4319 * take advantage of this, but do it for
4320 * completeness - AIM Apr01
4322 for (i
= 0; i
< file_count
; i
++)
4323 p_s
[i
]->_pid
= pipe_pid
;
4327 /* reset standard IO to normal */
4328 for (i
= 0; i
< 3; i
++)
4330 dup2(stdio
[i
].handle
, i
);
4331 fcntl(i
, F_SETFD
, stdio
[i
].flags
);
4332 close(stdio
[i
].handle
);
4335 /* if any remnant problems, clean up and bail out */
4338 for (i
= 0; i
< 3; i
++)
4344 return posix_error_with_filename(cmdstring
);
4347 /* build tuple of file objects to return */
4348 if ((p_f
[0] = PyFile_FromFile(p_s
[0], cmdstring
, wr_mode
, _PyPclose
)) != NULL
)
4349 PyFile_SetBufSize(p_f
[0], bufsize
);
4350 if ((p_f
[1] = PyFile_FromFile(p_s
[1], cmdstring
, rd_mode
, _PyPclose
)) != NULL
)
4351 PyFile_SetBufSize(p_f
[1], bufsize
);
4354 if ((p_f
[2] = PyFile_FromFile(p_s
[2], cmdstring
, rd_mode
, _PyPclose
)) != NULL
)
4355 PyFile_SetBufSize(p_f
[0], bufsize
);
4356 f
= PyTuple_Pack(3, p_f
[0], p_f
[1], p_f
[2]);
4359 f
= PyTuple_Pack(2, p_f
[0], p_f
[1]);
4362 * Insert the files we've created into the process dictionary
4363 * all referencing the list with the process handle and the
4364 * initial number of files (see description below in _PyPclose).
4365 * Since if _PyPclose later tried to wait on a process when all
4366 * handles weren't closed, it could create a deadlock with the
4367 * child, we spend some energy here to try to ensure that we
4368 * either insert all file handles into the dictionary or none
4369 * at all. It's a little clumsy with the various popen modes
4370 * and variable number of files involved.
4374 _PyPopenProcs
= PyDict_New();
4379 PyObject
*procObj
, *pidObj
, *intObj
, *fileObj
[3];
4382 fileObj
[0] = fileObj
[1] = fileObj
[2] = NULL
;
4383 ins_rc
[0] = ins_rc
[1] = ins_rc
[2] = 0;
4385 procObj
= PyList_New(2);
4386 pidObj
= PyInt_FromLong((long) pipe_pid
);
4387 intObj
= PyInt_FromLong((long) file_count
);
4389 if (procObj
&& pidObj
&& intObj
)
4391 PyList_SetItem(procObj
, 0, pidObj
);
4392 PyList_SetItem(procObj
, 1, intObj
);
4394 fileObj
[0] = PyLong_FromVoidPtr(p_s
[0]);
4397 ins_rc
[0] = PyDict_SetItem(_PyPopenProcs
,
4401 fileObj
[1] = PyLong_FromVoidPtr(p_s
[1]);
4404 ins_rc
[1] = PyDict_SetItem(_PyPopenProcs
,
4408 if (file_count
>= 3)
4410 fileObj
[2] = PyLong_FromVoidPtr(p_s
[2]);
4413 ins_rc
[2] = PyDict_SetItem(_PyPopenProcs
,
4419 if (ins_rc
[0] < 0 || !fileObj
[0] ||
4420 ins_rc
[1] < 0 || (file_count
> 1 && !fileObj
[1]) ||
4421 ins_rc
[2] < 0 || (file_count
> 2 && !fileObj
[2]))
4423 /* Something failed - remove any dictionary
4424 * entries that did make it.
4426 if (!ins_rc
[0] && fileObj
[0])
4428 PyDict_DelItem(_PyPopenProcs
,
4431 if (!ins_rc
[1] && fileObj
[1])
4433 PyDict_DelItem(_PyPopenProcs
,
4436 if (!ins_rc
[2] && fileObj
[2])
4438 PyDict_DelItem(_PyPopenProcs
,
4445 * Clean up our localized references for the dictionary keys
4446 * and value since PyDict_SetItem will Py_INCREF any copies
4447 * that got placed in the dictionary.
4449 Py_XDECREF(procObj
);
4450 Py_XDECREF(fileObj
[0]);
4451 Py_XDECREF(fileObj
[1]);
4452 Py_XDECREF(fileObj
[2]);
4455 /* Child is launched. */
4460 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4461 * exit code for the child process and return as a result of the close.
4463 * This function uses the _PyPopenProcs dictionary in order to map the
4464 * input file pointer to information about the process that was
4465 * originally created by the popen* call that created the file pointer.
4466 * The dictionary uses the file pointer as a key (with one entry
4467 * inserted for each file returned by the original popen* call) and a
4468 * single list object as the value for all files from a single call.
4469 * The list object contains the Win32 process handle at [0], and a file
4470 * count at [1], which is initialized to the total number of file
4471 * handles using that list.
4473 * This function closes whichever handle it is passed, and decrements
4474 * the file count in the dictionary for the process handle pointed to
4475 * by this file. On the last close (when the file count reaches zero),
4476 * this function will wait for the child process and then return its
4477 * exit code as the result of the close() operation. This permits the
4478 * files to be closed in any order - it is always the close() of the
4479 * final handle that will return the exit code.
4481 * NOTE: This function is currently called with the GIL released.
4482 * hence we use the GILState API to manage our state.
4485 static int _PyPclose(FILE *file
)
4490 PyObject
*procObj
, *pidObj
, *intObj
, *fileObj
;
4493 PyGILState_STATE state
;
4496 /* Close the file handle first, to ensure it can't block the
4497 * child from exiting if it's the last handle.
4499 result
= fclose(file
);
4502 state
= PyGILState_Ensure();
4506 if ((fileObj
= PyLong_FromVoidPtr(file
)) != NULL
&&
4507 (procObj
= PyDict_GetItem(_PyPopenProcs
,
4508 fileObj
)) != NULL
&&
4509 (pidObj
= PyList_GetItem(procObj
,0)) != NULL
&&
4510 (intObj
= PyList_GetItem(procObj
,1)) != NULL
)
4512 pipe_pid
= (int) PyInt_AsLong(pidObj
);
4513 file_count
= (int) PyInt_AsLong(intObj
);
4517 /* Still other files referencing process */
4519 PyList_SetItem(procObj
,1,
4520 PyInt_FromLong((long) file_count
));
4524 /* Last file for this process */
4525 if (result
!= EOF
&&
4526 waitpid(pipe_pid
, &exit_code
, 0) == pipe_pid
)
4528 /* extract exit status */
4529 if (WIFEXITED(exit_code
))
4531 result
= WEXITSTATUS(exit_code
);
4541 /* Indicate failure - this will cause the file object
4542 * to raise an I/O error and translate the last
4543 * error code from errno. We do have a problem with
4544 * last errors that overlap the normal errno table,
4545 * but that's a consistent problem with the file object.
4551 /* Remove this file pointer from dictionary */
4552 PyDict_DelItem(_PyPopenProcs
, fileObj
);
4554 if (PyDict_Size(_PyPopenProcs
) == 0)
4556 Py_DECREF(_PyPopenProcs
);
4557 _PyPopenProcs
= NULL
;
4560 } /* if object retrieval ok */
4562 Py_XDECREF(fileObj
);
4563 } /* if _PyPopenProcs */
4566 PyGILState_Release(state
);
4571 #endif /* PYCC_??? */
4573 #elif defined(MS_WINDOWS)
4576 * Portable 'popen' replacement for Win32.
4578 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
4579 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
4580 * Return code handling by David Bolen <db3l@fitlinxx.com>.
4587 /* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
4593 static PyObject
*_PyPopen(char *, int, int);
4594 static int _PyPclose(FILE *file
);
4597 * Internal dictionary mapping popen* file pointers to process handles,
4598 * for use when retrieving the process exit code. See _PyPclose() below
4599 * for more information on this dictionary's use.
4601 static PyObject
*_PyPopenProcs
= NULL
;
4604 /* popen that works from a GUI.
4606 * The result of this function is a pipe (file) connected to the
4607 * processes stdin or stdout, depending on the requested mode.
4611 posix_popen(PyObject
*self
, PyObject
*args
)
4619 if (!PyArg_ParseTuple(args
, "s|si:popen", &cmdstring
, &mode
, &bufsize
))
4624 else if (*mode
!= 'w') {
4625 PyErr_SetString(PyExc_ValueError
, "popen() arg 2 must be 'r' or 'w'");
4630 if (bufsize
!= -1) {
4631 PyErr_SetString(PyExc_ValueError
, "popen() arg 3 must be -1");
4635 if (*(mode
+1) == 't')
4636 f
= _PyPopen(cmdstring
, tm
| _O_TEXT
, POPEN_1
);
4637 else if (*(mode
+1) == 'b')
4638 f
= _PyPopen(cmdstring
, tm
| _O_BINARY
, POPEN_1
);
4640 f
= _PyPopen(cmdstring
, tm
| _O_TEXT
, POPEN_1
);
4645 /* Variation on win32pipe.popen
4647 * The result of this function is a pipe (file) connected to the
4648 * process's stdin, and a pipe connected to the process's stdout.
4652 win32_popen2(PyObject
*self
, PyObject
*args
)
4660 if (!PyArg_ParseTuple(args
, "s|si:popen2", &cmdstring
, &mode
, &bufsize
))
4665 else if (*mode
!= 'b') {
4666 PyErr_SetString(PyExc_ValueError
, "popen2() arg 2 must be 't' or 'b'");
4671 if (bufsize
!= -1) {
4672 PyErr_SetString(PyExc_ValueError
, "popen2() arg 3 must be -1");
4676 f
= _PyPopen(cmdstring
, tm
, POPEN_2
);
4682 * Variation on <om win32pipe.popen>
4684 * The result of this function is 3 pipes - the process's stdin,
4689 win32_popen3(PyObject
*self
, PyObject
*args
)
4697 if (!PyArg_ParseTuple(args
, "s|si:popen3", &cmdstring
, &mode
, &bufsize
))
4702 else if (*mode
!= 'b') {
4703 PyErr_SetString(PyExc_ValueError
, "popen3() arg 2 must be 't' or 'b'");
4708 if (bufsize
!= -1) {
4709 PyErr_SetString(PyExc_ValueError
, "popen3() arg 3 must be -1");
4713 f
= _PyPopen(cmdstring
, tm
, POPEN_3
);
4719 * Variation on win32pipe.popen
4721 * The result of this function is 2 pipes - the processes stdin,
4722 * and stdout+stderr combined as a single pipe.
4726 win32_popen4(PyObject
*self
, PyObject
*args
)
4734 if (!PyArg_ParseTuple(args
, "s|si:popen4", &cmdstring
, &mode
, &bufsize
))
4739 else if (*mode
!= 'b') {
4740 PyErr_SetString(PyExc_ValueError
, "popen4() arg 2 must be 't' or 'b'");
4745 if (bufsize
!= -1) {
4746 PyErr_SetString(PyExc_ValueError
, "popen4() arg 3 must be -1");
4750 f
= _PyPopen(cmdstring
, tm
, POPEN_4
);
4756 _PyPopenCreateProcess(char *cmdstring
,
4762 PROCESS_INFORMATION piProcInfo
;
4763 STARTUPINFO siStartInfo
;
4764 DWORD dwProcessFlags
= 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
4765 char *s1
,*s2
, *s3
= " /c ";
4766 const char *szConsoleSpawn
= "w9xpopen.exe";
4770 if (i
= GetEnvironmentVariable("COMSPEC",NULL
,0)) {
4773 s1
= (char *)alloca(i
);
4774 if (!(x
= GetEnvironmentVariable("COMSPEC", s1
, i
)))
4775 /* x < i, so x fits into an integer */
4778 /* Explicitly check if we are using COMMAND.COM. If we are
4779 * then use the w9xpopen hack.
4782 while (comshell
>= s1
&& *comshell
!= '\\')
4786 if (GetVersion() < 0x80000000 &&
4787 _stricmp(comshell
, "command.com") != 0) {
4788 /* NT/2000 and not using command.com. */
4789 x
= i
+ strlen(s3
) + strlen(cmdstring
) + 1;
4790 s2
= (char *)alloca(x
);
4792 PyOS_snprintf(s2
, x
, "%s%s%s", s1
, s3
, cmdstring
);
4796 * Oh gag, we're on Win9x or using COMMAND.COM. Use
4797 * the workaround listed in KB: Q150956
4799 char modulepath
[_MAX_PATH
];
4800 struct stat statinfo
;
4801 GetModuleFileName(NULL
, modulepath
, sizeof(modulepath
));
4802 for (x
= i
= 0; modulepath
[i
]; i
++)
4803 if (modulepath
[i
] == SEP
)
4805 modulepath
[x
] = '\0';
4806 /* Create the full-name to w9xpopen, so we can test it exists */
4809 (sizeof(modulepath
)/sizeof(modulepath
[0]))
4810 -strlen(modulepath
));
4811 if (stat(modulepath
, &statinfo
) != 0) {
4812 /* Eeek - file-not-found - possibly an embedding
4813 situation - see if we can locate it in sys.prefix
4817 sizeof(modulepath
)/sizeof(modulepath
[0]));
4818 if (modulepath
[strlen(modulepath
)-1] != '\\')
4819 strcat(modulepath
, "\\");
4822 (sizeof(modulepath
)/sizeof(modulepath
[0]))
4823 -strlen(modulepath
));
4824 /* No where else to look - raise an easily identifiable
4825 error, rather than leaving Windows to report
4826 "file not found" - as the user is probably blissfully
4827 unaware this shim EXE is used, and it will confuse them.
4828 (well, it confused me for a while ;-)
4830 if (stat(modulepath
, &statinfo
) != 0) {
4831 PyErr_Format(PyExc_RuntimeError
,
4832 "Can not locate '%s' which is needed "
4833 "for popen to work with your shell "
4839 x
= i
+ strlen(s3
) + strlen(cmdstring
) + 1 +
4840 strlen(modulepath
) +
4841 strlen(szConsoleSpawn
) + 1;
4843 s2
= (char *)alloca(x
);
4845 /* To maintain correct argument passing semantics,
4846 we pass the command-line as it stands, and allow
4847 quoting to be applied. w9xpopen.exe will then
4848 use its argv vector, and re-quote the necessary
4849 args for the ultimate child process.
4858 /* Not passing CREATE_NEW_CONSOLE has been known to
4859 cause random failures on win9x. Specifically a
4861 "Your program accessed mem currently in use at xxx"
4862 and a hopeful warning about the stability of your
4864 Cost is Ctrl+C wont kill children, but anyone
4865 who cares can have a go!
4867 dwProcessFlags
|= CREATE_NEW_CONSOLE
;
4871 /* Could be an else here to try cmd.exe / command.com in the path
4872 Now we'll just error out.. */
4874 PyErr_SetString(PyExc_RuntimeError
,
4875 "Cannot locate a COMSPEC environment variable to "
4876 "use as the shell");
4880 ZeroMemory(&siStartInfo
, sizeof(STARTUPINFO
));
4881 siStartInfo
.cb
= sizeof(STARTUPINFO
);
4882 siStartInfo
.dwFlags
= STARTF_USESTDHANDLES
| STARTF_USESHOWWINDOW
;
4883 siStartInfo
.hStdInput
= hStdin
;
4884 siStartInfo
.hStdOutput
= hStdout
;
4885 siStartInfo
.hStdError
= hStderr
;
4886 siStartInfo
.wShowWindow
= SW_HIDE
;
4888 if (CreateProcess(NULL
,
4898 /* Close the handles now so anyone waiting is woken. */
4899 CloseHandle(piProcInfo
.hThread
);
4901 /* Return process handle */
4902 *hProcess
= piProcInfo
.hProcess
;
4905 win32_error("CreateProcess", s2
);
4909 /* The following code is based off of KB: Q190351 */
4912 _PyPopen(char *cmdstring
, int mode
, int n
)
4914 HANDLE hChildStdinRd
, hChildStdinWr
, hChildStdoutRd
, hChildStdoutWr
,
4915 hChildStderrRd
, hChildStderrWr
, hChildStdinWrDup
, hChildStdoutRdDup
,
4916 hChildStderrRdDup
, hProcess
; /* hChildStdoutWrDup; */
4918 SECURITY_ATTRIBUTES saAttr
;
4925 saAttr
.nLength
= sizeof(SECURITY_ATTRIBUTES
);
4926 saAttr
.bInheritHandle
= TRUE
;
4927 saAttr
.lpSecurityDescriptor
= NULL
;
4929 if (!CreatePipe(&hChildStdinRd
, &hChildStdinWr
, &saAttr
, 0))
4930 return win32_error("CreatePipe", NULL
);
4932 /* Create new output read handle and the input write handle. Set
4933 * the inheritance properties to FALSE. Otherwise, the child inherits
4934 * these handles; resulting in non-closeable handles to the pipes
4936 fSuccess
= DuplicateHandle(GetCurrentProcess(), hChildStdinWr
,
4937 GetCurrentProcess(), &hChildStdinWrDup
, 0,
4939 DUPLICATE_SAME_ACCESS
);
4941 return win32_error("DuplicateHandle", NULL
);
4943 /* Close the inheritable version of ChildStdin
4944 that we're using. */
4945 CloseHandle(hChildStdinWr
);
4947 if (!CreatePipe(&hChildStdoutRd
, &hChildStdoutWr
, &saAttr
, 0))
4948 return win32_error("CreatePipe", NULL
);
4950 fSuccess
= DuplicateHandle(GetCurrentProcess(), hChildStdoutRd
,
4951 GetCurrentProcess(), &hChildStdoutRdDup
, 0,
4952 FALSE
, DUPLICATE_SAME_ACCESS
);
4954 return win32_error("DuplicateHandle", NULL
);
4956 /* Close the inheritable version of ChildStdout
4957 that we're using. */
4958 CloseHandle(hChildStdoutRd
);
4961 if (!CreatePipe(&hChildStderrRd
, &hChildStderrWr
, &saAttr
, 0))
4962 return win32_error("CreatePipe", NULL
);
4963 fSuccess
= DuplicateHandle(GetCurrentProcess(),
4965 GetCurrentProcess(),
4966 &hChildStderrRdDup
, 0,
4967 FALSE
, DUPLICATE_SAME_ACCESS
);
4969 return win32_error("DuplicateHandle", NULL
);
4970 /* Close the inheritable version of ChildStdErr that we're using. */
4971 CloseHandle(hChildStderrRd
);
4976 switch (mode
& (_O_RDONLY
| _O_TEXT
| _O_BINARY
| _O_WRONLY
)) {
4977 case _O_WRONLY
| _O_TEXT
:
4978 /* Case for writing to child Stdin in text mode. */
4979 fd1
= _open_osfhandle((Py_intptr_t
)hChildStdinWrDup
, mode
);
4980 f1
= _fdopen(fd1
, "w");
4981 f
= PyFile_FromFile(f1
, cmdstring
, "w", _PyPclose
);
4982 PyFile_SetBufSize(f
, 0);
4983 /* We don't care about these pipes anymore, so close them. */
4984 CloseHandle(hChildStdoutRdDup
);
4985 CloseHandle(hChildStderrRdDup
);
4988 case _O_RDONLY
| _O_TEXT
:
4989 /* Case for reading from child Stdout in text mode. */
4990 fd1
= _open_osfhandle((Py_intptr_t
)hChildStdoutRdDup
, mode
);
4991 f1
= _fdopen(fd1
, "r");
4992 f
= PyFile_FromFile(f1
, cmdstring
, "r", _PyPclose
);
4993 PyFile_SetBufSize(f
, 0);
4994 /* We don't care about these pipes anymore, so close them. */
4995 CloseHandle(hChildStdinWrDup
);
4996 CloseHandle(hChildStderrRdDup
);
4999 case _O_RDONLY
| _O_BINARY
:
5000 /* Case for readinig from child Stdout in binary mode. */
5001 fd1
= _open_osfhandle((Py_intptr_t
)hChildStdoutRdDup
, mode
);
5002 f1
= _fdopen(fd1
, "rb");
5003 f
= PyFile_FromFile(f1
, cmdstring
, "rb", _PyPclose
);
5004 PyFile_SetBufSize(f
, 0);
5005 /* We don't care about these pipes anymore, so close them. */
5006 CloseHandle(hChildStdinWrDup
);
5007 CloseHandle(hChildStderrRdDup
);
5010 case _O_WRONLY
| _O_BINARY
:
5011 /* Case for writing to child Stdin in binary mode. */
5012 fd1
= _open_osfhandle((Py_intptr_t
)hChildStdinWrDup
, mode
);
5013 f1
= _fdopen(fd1
, "wb");
5014 f
= PyFile_FromFile(f1
, cmdstring
, "wb", _PyPclose
);
5015 PyFile_SetBufSize(f
, 0);
5016 /* We don't care about these pipes anymore, so close them. */
5017 CloseHandle(hChildStdoutRdDup
);
5018 CloseHandle(hChildStderrRdDup
);
5030 if (mode
& _O_TEXT
) {
5038 fd1
= _open_osfhandle((Py_intptr_t
)hChildStdinWrDup
, mode
);
5039 f1
= _fdopen(fd1
, m2
);
5040 fd2
= _open_osfhandle((Py_intptr_t
)hChildStdoutRdDup
, mode
);
5041 f2
= _fdopen(fd2
, m1
);
5042 p1
= PyFile_FromFile(f1
, cmdstring
, m2
, _PyPclose
);
5043 PyFile_SetBufSize(p1
, 0);
5044 p2
= PyFile_FromFile(f2
, cmdstring
, m1
, _PyPclose
);
5045 PyFile_SetBufSize(p2
, 0);
5048 CloseHandle(hChildStderrRdDup
);
5050 f
= PyTuple_Pack(2,p1
,p2
);
5060 PyObject
*p1
, *p2
, *p3
;
5062 if (mode
& _O_TEXT
) {
5070 fd1
= _open_osfhandle((Py_intptr_t
)hChildStdinWrDup
, mode
);
5071 f1
= _fdopen(fd1
, m2
);
5072 fd2
= _open_osfhandle((Py_intptr_t
)hChildStdoutRdDup
, mode
);
5073 f2
= _fdopen(fd2
, m1
);
5074 fd3
= _open_osfhandle((Py_intptr_t
)hChildStderrRdDup
, mode
);
5075 f3
= _fdopen(fd3
, m1
);
5076 p1
= PyFile_FromFile(f1
, cmdstring
, m2
, _PyPclose
);
5077 p2
= PyFile_FromFile(f2
, cmdstring
, m1
, _PyPclose
);
5078 p3
= PyFile_FromFile(f3
, cmdstring
, m1
, _PyPclose
);
5079 PyFile_SetBufSize(p1
, 0);
5080 PyFile_SetBufSize(p2
, 0);
5081 PyFile_SetBufSize(p3
, 0);
5082 f
= PyTuple_Pack(3,p1
,p2
,p3
);
5092 if (!_PyPopenCreateProcess(cmdstring
,
5100 if (!_PyPopenCreateProcess(cmdstring
,
5109 * Insert the files we've created into the process dictionary
5110 * all referencing the list with the process handle and the
5111 * initial number of files (see description below in _PyPclose).
5112 * Since if _PyPclose later tried to wait on a process when all
5113 * handles weren't closed, it could create a deadlock with the
5114 * child, we spend some energy here to try to ensure that we
5115 * either insert all file handles into the dictionary or none
5116 * at all. It's a little clumsy with the various popen modes
5117 * and variable number of files involved.
5119 if (!_PyPopenProcs
) {
5120 _PyPopenProcs
= PyDict_New();
5123 if (_PyPopenProcs
) {
5124 PyObject
*procObj
, *hProcessObj
, *intObj
, *fileObj
[3];
5127 fileObj
[0] = fileObj
[1] = fileObj
[2] = NULL
;
5128 ins_rc
[0] = ins_rc
[1] = ins_rc
[2] = 0;
5130 procObj
= PyList_New(2);
5131 hProcessObj
= PyLong_FromVoidPtr(hProcess
);
5132 intObj
= PyInt_FromLong(file_count
);
5134 if (procObj
&& hProcessObj
&& intObj
) {
5135 PyList_SetItem(procObj
,0,hProcessObj
);
5136 PyList_SetItem(procObj
,1,intObj
);
5138 fileObj
[0] = PyLong_FromVoidPtr(f1
);
5140 ins_rc
[0] = PyDict_SetItem(_PyPopenProcs
,
5144 if (file_count
>= 2) {
5145 fileObj
[1] = PyLong_FromVoidPtr(f2
);
5147 ins_rc
[1] = PyDict_SetItem(_PyPopenProcs
,
5152 if (file_count
>= 3) {
5153 fileObj
[2] = PyLong_FromVoidPtr(f3
);
5155 ins_rc
[2] = PyDict_SetItem(_PyPopenProcs
,
5161 if (ins_rc
[0] < 0 || !fileObj
[0] ||
5162 ins_rc
[1] < 0 || (file_count
> 1 && !fileObj
[1]) ||
5163 ins_rc
[2] < 0 || (file_count
> 2 && !fileObj
[2])) {
5164 /* Something failed - remove any dictionary
5165 * entries that did make it.
5167 if (!ins_rc
[0] && fileObj
[0]) {
5168 PyDict_DelItem(_PyPopenProcs
,
5171 if (!ins_rc
[1] && fileObj
[1]) {
5172 PyDict_DelItem(_PyPopenProcs
,
5175 if (!ins_rc
[2] && fileObj
[2]) {
5176 PyDict_DelItem(_PyPopenProcs
,
5183 * Clean up our localized references for the dictionary keys
5184 * and value since PyDict_SetItem will Py_INCREF any copies
5185 * that got placed in the dictionary.
5187 Py_XDECREF(procObj
);
5188 Py_XDECREF(fileObj
[0]);
5189 Py_XDECREF(fileObj
[1]);
5190 Py_XDECREF(fileObj
[2]);
5193 /* Child is launched. Close the parents copy of those pipe
5194 * handles that only the child should have open. You need to
5195 * make sure that no handles to the write end of the output pipe
5196 * are maintained in this process or else the pipe will not close
5197 * when the child process exits and the ReadFile will hang. */
5199 if (!CloseHandle(hChildStdinRd
))
5200 return win32_error("CloseHandle", NULL
);
5202 if (!CloseHandle(hChildStdoutWr
))
5203 return win32_error("CloseHandle", NULL
);
5205 if ((n
!= 4) && (!CloseHandle(hChildStderrWr
)))
5206 return win32_error("CloseHandle", NULL
);
5212 * Wrapper for fclose() to use for popen* files, so we can retrieve the
5213 * exit code for the child process and return as a result of the close.
5215 * This function uses the _PyPopenProcs dictionary in order to map the
5216 * input file pointer to information about the process that was
5217 * originally created by the popen* call that created the file pointer.
5218 * The dictionary uses the file pointer as a key (with one entry
5219 * inserted for each file returned by the original popen* call) and a
5220 * single list object as the value for all files from a single call.
5221 * The list object contains the Win32 process handle at [0], and a file
5222 * count at [1], which is initialized to the total number of file
5223 * handles using that list.
5225 * This function closes whichever handle it is passed, and decrements
5226 * the file count in the dictionary for the process handle pointed to
5227 * by this file. On the last close (when the file count reaches zero),
5228 * this function will wait for the child process and then return its
5229 * exit code as the result of the close() operation. This permits the
5230 * files to be closed in any order - it is always the close() of the
5231 * final handle that will return the exit code.
5233 * NOTE: This function is currently called with the GIL released.
5234 * hence we use the GILState API to manage our state.
5237 static int _PyPclose(FILE *file
)
5242 PyObject
*procObj
, *hProcessObj
, *intObj
, *fileObj
;
5245 PyGILState_STATE state
;
5248 /* Close the file handle first, to ensure it can't block the
5249 * child from exiting if it's the last handle.
5251 result
= fclose(file
);
5253 state
= PyGILState_Ensure();
5255 if (_PyPopenProcs
) {
5256 if ((fileObj
= PyLong_FromVoidPtr(file
)) != NULL
&&
5257 (procObj
= PyDict_GetItem(_PyPopenProcs
,
5258 fileObj
)) != NULL
&&
5259 (hProcessObj
= PyList_GetItem(procObj
,0)) != NULL
&&
5260 (intObj
= PyList_GetItem(procObj
,1)) != NULL
) {
5262 hProcess
= PyLong_AsVoidPtr(hProcessObj
);
5263 file_count
= PyInt_AsLong(intObj
);
5265 if (file_count
> 1) {
5266 /* Still other files referencing process */
5268 PyList_SetItem(procObj
,1,
5269 PyInt_FromLong(file_count
));
5271 /* Last file for this process */
5272 if (result
!= EOF
&&
5273 WaitForSingleObject(hProcess
, INFINITE
) != WAIT_FAILED
&&
5274 GetExitCodeProcess(hProcess
, &exit_code
)) {
5275 /* Possible truncation here in 16-bit environments, but
5276 * real exit codes are just the lower byte in any event.
5280 /* Indicate failure - this will cause the file object
5281 * to raise an I/O error and translate the last Win32
5282 * error code from errno. We do have a problem with
5283 * last errors that overlap the normal errno table,
5284 * but that's a consistent problem with the file object.
5286 if (result
!= EOF
) {
5287 /* If the error wasn't from the fclose(), then
5288 * set errno for the file object error handling.
5290 errno
= GetLastError();
5295 /* Free up the native handle at this point */
5296 CloseHandle(hProcess
);
5299 /* Remove this file pointer from dictionary */
5300 PyDict_DelItem(_PyPopenProcs
, fileObj
);
5302 if (PyDict_Size(_PyPopenProcs
) == 0) {
5303 Py_DECREF(_PyPopenProcs
);
5304 _PyPopenProcs
= NULL
;
5307 } /* if object retrieval ok */
5309 Py_XDECREF(fileObj
);
5310 } /* if _PyPopenProcs */
5313 PyGILState_Release(state
);
5318 #else /* which OS? */
5320 posix_popen(PyObject
*self
, PyObject
*args
)
5327 if (!PyArg_ParseTuple(args
, "s|si:popen", &name
, &mode
, &bufsize
))
5329 /* Strip mode of binary or text modifiers */
5330 if (strcmp(mode
, "rb") == 0 || strcmp(mode
, "rt") == 0)
5332 else if (strcmp(mode
, "wb") == 0 || strcmp(mode
, "wt") == 0)
5334 Py_BEGIN_ALLOW_THREADS
5335 fp
= popen(name
, mode
);
5336 Py_END_ALLOW_THREADS
5338 return posix_error();
5339 f
= PyFile_FromFile(fp
, name
, mode
, pclose
);
5341 PyFile_SetBufSize(f
, bufsize
);
5345 #endif /* PYOS_??? */
5346 #endif /* HAVE_POPEN */
5350 PyDoc_STRVAR(posix_setuid__doc__
,
5352 Set the current process's user id.");
5355 posix_setuid(PyObject
*self
, PyObject
*args
)
5358 if (!PyArg_ParseTuple(args
, "i:setuid", &uid
))
5360 if (setuid(uid
) < 0)
5361 return posix_error();
5365 #endif /* HAVE_SETUID */
5369 PyDoc_STRVAR(posix_seteuid__doc__
,
5371 Set the current process's effective user id.");
5374 posix_seteuid (PyObject
*self
, PyObject
*args
)
5377 if (!PyArg_ParseTuple(args
, "i", &euid
)) {
5379 } else if (seteuid(euid
) < 0) {
5380 return posix_error();
5386 #endif /* HAVE_SETEUID */
5389 PyDoc_STRVAR(posix_setegid__doc__
,
5391 Set the current process's effective group id.");
5394 posix_setegid (PyObject
*self
, PyObject
*args
)
5397 if (!PyArg_ParseTuple(args
, "i", &egid
)) {
5399 } else if (setegid(egid
) < 0) {
5400 return posix_error();
5406 #endif /* HAVE_SETEGID */
5408 #ifdef HAVE_SETREUID
5409 PyDoc_STRVAR(posix_setreuid__doc__
,
5410 "setreuid(ruid, euid)\n\n\
5411 Set the current process's real and effective user ids.");
5414 posix_setreuid (PyObject
*self
, PyObject
*args
)
5417 if (!PyArg_ParseTuple(args
, "ii", &ruid
, &euid
)) {
5419 } else if (setreuid(ruid
, euid
) < 0) {
5420 return posix_error();
5426 #endif /* HAVE_SETREUID */
5428 #ifdef HAVE_SETREGID
5429 PyDoc_STRVAR(posix_setregid__doc__
,
5430 "setregid(rgid, egid)\n\n\
5431 Set the current process's real and effective group ids.");
5434 posix_setregid (PyObject
*self
, PyObject
*args
)
5437 if (!PyArg_ParseTuple(args
, "ii", &rgid
, &egid
)) {
5439 } else if (setregid(rgid
, egid
) < 0) {
5440 return posix_error();
5446 #endif /* HAVE_SETREGID */
5449 PyDoc_STRVAR(posix_setgid__doc__
,
5451 Set the current process's group id.");
5454 posix_setgid(PyObject
*self
, PyObject
*args
)
5457 if (!PyArg_ParseTuple(args
, "i:setgid", &gid
))
5459 if (setgid(gid
) < 0)
5460 return posix_error();
5464 #endif /* HAVE_SETGID */
5466 #ifdef HAVE_SETGROUPS
5467 PyDoc_STRVAR(posix_setgroups__doc__
,
5468 "setgroups(list)\n\n\
5469 Set the groups of the current process to list.");
5472 posix_setgroups(PyObject
*self
, PyObject
*groups
)
5475 gid_t grouplist
[MAX_GROUPS
];
5477 if (!PySequence_Check(groups
)) {
5478 PyErr_SetString(PyExc_TypeError
, "setgroups argument must be a sequence");
5481 len
= PySequence_Size(groups
);
5482 if (len
> MAX_GROUPS
) {
5483 PyErr_SetString(PyExc_ValueError
, "too many groups");
5486 for(i
= 0; i
< len
; i
++) {
5488 elem
= PySequence_GetItem(groups
, i
);
5491 if (!PyInt_Check(elem
)) {
5492 if (!PyLong_Check(elem
)) {
5493 PyErr_SetString(PyExc_TypeError
,
5494 "groups must be integers");
5498 unsigned long x
= PyLong_AsUnsignedLong(elem
);
5499 if (PyErr_Occurred()) {
5500 PyErr_SetString(PyExc_TypeError
,
5501 "group id too big");
5506 /* read back the value to see if it fitted in gid_t */
5507 if (grouplist
[i
] != x
) {
5508 PyErr_SetString(PyExc_TypeError
,
5509 "group id too big");
5515 long x
= PyInt_AsLong(elem
);
5517 if (grouplist
[i
] != x
) {
5518 PyErr_SetString(PyExc_TypeError
,
5519 "group id too big");
5527 if (setgroups(len
, grouplist
) < 0)
5528 return posix_error();
5532 #endif /* HAVE_SETGROUPS */
5534 #if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
5536 wait_helper(int pid
, int status
, struct rusage
*ru
)
5539 static PyObject
*struct_rusage
;
5542 return posix_error();
5544 if (struct_rusage
== NULL
) {
5545 PyObject
*m
= PyImport_ImportModule("resource");
5548 struct_rusage
= PyObject_GetAttrString(m
, "struct_rusage");
5550 if (struct_rusage
== NULL
)
5554 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
5555 result
= PyStructSequence_New((PyTypeObject
*) struct_rusage
);
5560 #define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
5563 PyStructSequence_SET_ITEM(result
, 0,
5564 PyFloat_FromDouble(doubletime(ru
->ru_utime
)));
5565 PyStructSequence_SET_ITEM(result
, 1,
5566 PyFloat_FromDouble(doubletime(ru
->ru_stime
)));
5567 #define SET_INT(result, index, value)\
5568 PyStructSequence_SET_ITEM(result, index, PyInt_FromLong(value))
5569 SET_INT(result
, 2, ru
->ru_maxrss
);
5570 SET_INT(result
, 3, ru
->ru_ixrss
);
5571 SET_INT(result
, 4, ru
->ru_idrss
);
5572 SET_INT(result
, 5, ru
->ru_isrss
);
5573 SET_INT(result
, 6, ru
->ru_minflt
);
5574 SET_INT(result
, 7, ru
->ru_majflt
);
5575 SET_INT(result
, 8, ru
->ru_nswap
);
5576 SET_INT(result
, 9, ru
->ru_inblock
);
5577 SET_INT(result
, 10, ru
->ru_oublock
);
5578 SET_INT(result
, 11, ru
->ru_msgsnd
);
5579 SET_INT(result
, 12, ru
->ru_msgrcv
);
5580 SET_INT(result
, 13, ru
->ru_nsignals
);
5581 SET_INT(result
, 14, ru
->ru_nvcsw
);
5582 SET_INT(result
, 15, ru
->ru_nivcsw
);
5585 if (PyErr_Occurred()) {
5590 return Py_BuildValue("iiN", pid
, status
, result
);
5592 #endif /* HAVE_WAIT3 || HAVE_WAIT4 */
5595 PyDoc_STRVAR(posix_wait3__doc__
,
5596 "wait3(options) -> (pid, status, rusage)\n\n\
5597 Wait for completion of a child process.");
5600 posix_wait3(PyObject
*self
, PyObject
*args
)
5605 WAIT_STATUS_INT(status
) = 0;
5607 if (!PyArg_ParseTuple(args
, "i:wait3", &options
))
5610 Py_BEGIN_ALLOW_THREADS
5611 pid
= wait3(&status
, options
, &ru
);
5612 Py_END_ALLOW_THREADS
5614 return wait_helper(pid
, WAIT_STATUS_INT(status
), &ru
);
5616 #endif /* HAVE_WAIT3 */
5619 PyDoc_STRVAR(posix_wait4__doc__
,
5620 "wait4(pid, options) -> (pid, status, rusage)\n\n\
5621 Wait for completion of a given child process.");
5624 posix_wait4(PyObject
*self
, PyObject
*args
)
5629 WAIT_STATUS_INT(status
) = 0;
5631 if (!PyArg_ParseTuple(args
, "ii:wait4", &pid
, &options
))
5634 Py_BEGIN_ALLOW_THREADS
5635 pid
= wait4(pid
, &status
, options
, &ru
);
5636 Py_END_ALLOW_THREADS
5638 return wait_helper(pid
, WAIT_STATUS_INT(status
), &ru
);
5640 #endif /* HAVE_WAIT4 */
5643 PyDoc_STRVAR(posix_waitpid__doc__
,
5644 "waitpid(pid, options) -> (pid, status)\n\n\
5645 Wait for completion of a given child process.");
5648 posix_waitpid(PyObject
*self
, PyObject
*args
)
5652 WAIT_STATUS_INT(status
) = 0;
5654 if (!PyArg_ParseTuple(args
, "ii:waitpid", &pid
, &options
))
5656 Py_BEGIN_ALLOW_THREADS
5657 pid
= waitpid(pid
, &status
, options
);
5658 Py_END_ALLOW_THREADS
5660 return posix_error();
5662 return Py_BuildValue("ii", pid
, WAIT_STATUS_INT(status
));
5665 #elif defined(HAVE_CWAIT)
5667 /* MS C has a variant of waitpid() that's usable for most purposes. */
5668 PyDoc_STRVAR(posix_waitpid__doc__
,
5669 "waitpid(pid, options) -> (pid, status << 8)\n\n"
5670 "Wait for completion of a given process. options is ignored on Windows.");
5673 posix_waitpid(PyObject
*self
, PyObject
*args
)
5676 int status
, options
;
5678 if (!PyArg_ParseTuple(args
, "ii:waitpid", &pid
, &options
))
5680 Py_BEGIN_ALLOW_THREADS
5681 pid
= _cwait(&status
, pid
, options
);
5682 Py_END_ALLOW_THREADS
5684 return posix_error();
5686 /* shift the status left a byte so this is more like the POSIX waitpid */
5687 return Py_BuildValue("ii", pid
, status
<< 8);
5689 #endif /* HAVE_WAITPID || HAVE_CWAIT */
5692 PyDoc_STRVAR(posix_wait__doc__
,
5693 "wait() -> (pid, status)\n\n\
5694 Wait for completion of a child process.");
5697 posix_wait(PyObject
*self
, PyObject
*noargs
)
5701 WAIT_STATUS_INT(status
) = 0;
5703 Py_BEGIN_ALLOW_THREADS
5704 pid
= wait(&status
);
5705 Py_END_ALLOW_THREADS
5707 return posix_error();
5709 return Py_BuildValue("ii", pid
, WAIT_STATUS_INT(status
));
5714 PyDoc_STRVAR(posix_lstat__doc__
,
5715 "lstat(path) -> stat result\n\n\
5716 Like stat(path), but do not follow symbolic links.");
5719 posix_lstat(PyObject
*self
, PyObject
*args
)
5722 return posix_do_stat(self
, args
, "et:lstat", lstat
, NULL
, NULL
);
5723 #else /* !HAVE_LSTAT */
5725 return posix_do_stat(self
, args
, "et:lstat", STAT
, "U:lstat", win32_wstat
);
5727 return posix_do_stat(self
, args
, "et:lstat", STAT
, NULL
, NULL
);
5729 #endif /* !HAVE_LSTAT */
5733 #ifdef HAVE_READLINK
5734 PyDoc_STRVAR(posix_readlink__doc__
,
5735 "readlink(path) -> path\n\n\
5736 Return a string representing the path to which the symbolic link points.");
5739 posix_readlink(PyObject
*self
, PyObject
*args
)
5742 char buf
[MAXPATHLEN
];
5745 #ifdef Py_USING_UNICODE
5746 int arg_is_unicode
= 0;
5749 if (!PyArg_ParseTuple(args
, "et:readlink",
5750 Py_FileSystemDefaultEncoding
, &path
))
5752 #ifdef Py_USING_UNICODE
5753 v
= PySequence_GetItem(args
, 0);
5754 if (v
== NULL
) return NULL
;
5756 if (PyUnicode_Check(v
)) {
5762 Py_BEGIN_ALLOW_THREADS
5763 n
= readlink(path
, buf
, (int) sizeof buf
);
5764 Py_END_ALLOW_THREADS
5766 return posix_error_with_filename(path
);
5768 v
= PyString_FromStringAndSize(buf
, n
);
5769 #ifdef Py_USING_UNICODE
5770 if (arg_is_unicode
) {
5773 w
= PyUnicode_FromEncodedObject(v
,
5774 Py_FileSystemDefaultEncoding
,
5781 /* fall back to the original byte string, as
5782 discussed in patch #683592 */
5789 #endif /* HAVE_READLINK */
5793 PyDoc_STRVAR(posix_symlink__doc__
,
5794 "symlink(src, dst)\n\n\
5795 Create a symbolic link pointing to src named dst.");
5798 posix_symlink(PyObject
*self
, PyObject
*args
)
5800 return posix_2str(args
, "etet:symlink", symlink
);
5802 #endif /* HAVE_SYMLINK */
5807 #define HZ 60 /* Universal constant :-) */
5810 #if defined(PYCC_VACPP) && defined(PYOS_OS2)
5816 Py_BEGIN_ALLOW_THREADS
5817 DosQuerySysInfo(QSV_MS_COUNT
, QSV_MS_COUNT
, &value
, sizeof(value
));
5818 Py_END_ALLOW_THREADS
5824 posix_times(PyObject
*self
, PyObject
*noargs
)
5826 /* Currently Only Uptime is Provided -- Others Later */
5827 return Py_BuildValue("ddddd",
5828 (double)0 /* t.tms_utime / HZ */,
5829 (double)0 /* t.tms_stime / HZ */,
5830 (double)0 /* t.tms_cutime / HZ */,
5831 (double)0 /* t.tms_cstime / HZ */,
5832 (double)system_uptime() / 1000);
5836 posix_times(PyObject
*self
, PyObject
*noargs
)
5842 if (c
== (clock_t) -1)
5843 return posix_error();
5844 return Py_BuildValue("ddddd",
5845 (double)t
.tms_utime
/ HZ
,
5846 (double)t
.tms_stime
/ HZ
,
5847 (double)t
.tms_cutime
/ HZ
,
5848 (double)t
.tms_cstime
/ HZ
,
5851 #endif /* not OS2 */
5852 #endif /* HAVE_TIMES */
5856 #define HAVE_TIMES /* so the method table will pick it up */
5858 posix_times(PyObject
*self
, PyObject
*noargs
)
5860 FILETIME create
, exit
, kernel
, user
;
5862 hProc
= GetCurrentProcess();
5863 GetProcessTimes(hProc
, &create
, &exit
, &kernel
, &user
);
5864 /* The fields of a FILETIME structure are the hi and lo part
5865 of a 64-bit value expressed in 100 nanosecond units.
5866 1e7 is one second in such units; 1e-7 the inverse.
5867 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
5869 return Py_BuildValue(
5871 (double)(kernel
.dwHighDateTime
*429.4967296 +
5872 kernel
.dwLowDateTime
*1e-7),
5873 (double)(user
.dwHighDateTime
*429.4967296 +
5874 user
.dwLowDateTime
*1e-7),
5879 #endif /* MS_WINDOWS */
5882 PyDoc_STRVAR(posix_times__doc__
,
5883 "times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
5884 Return a tuple of floating point numbers indicating process times.");
5889 PyDoc_STRVAR(posix_getsid__doc__
,
5890 "getsid(pid) -> sid\n\n\
5891 Call the system call getsid().");
5894 posix_getsid(PyObject
*self
, PyObject
*args
)
5897 if (!PyArg_ParseTuple(args
, "i:getsid", &pid
))
5901 return posix_error();
5902 return PyInt_FromLong((long)sid
);
5904 #endif /* HAVE_GETSID */
5908 PyDoc_STRVAR(posix_setsid__doc__
,
5910 Call the system call setsid().");
5913 posix_setsid(PyObject
*self
, PyObject
*noargs
)
5916 return posix_error();
5920 #endif /* HAVE_SETSID */
5923 PyDoc_STRVAR(posix_setpgid__doc__
,
5924 "setpgid(pid, pgrp)\n\n\
5925 Call the system call setpgid().");
5928 posix_setpgid(PyObject
*self
, PyObject
*args
)
5931 if (!PyArg_ParseTuple(args
, "ii:setpgid", &pid
, &pgrp
))
5933 if (setpgid(pid
, pgrp
) < 0)
5934 return posix_error();
5938 #endif /* HAVE_SETPGID */
5941 #ifdef HAVE_TCGETPGRP
5942 PyDoc_STRVAR(posix_tcgetpgrp__doc__
,
5943 "tcgetpgrp(fd) -> pgid\n\n\
5944 Return the process group associated with the terminal given by a fd.");
5947 posix_tcgetpgrp(PyObject
*self
, PyObject
*args
)
5950 if (!PyArg_ParseTuple(args
, "i:tcgetpgrp", &fd
))
5952 pgid
= tcgetpgrp(fd
);
5954 return posix_error();
5955 return PyInt_FromLong((long)pgid
);
5957 #endif /* HAVE_TCGETPGRP */
5960 #ifdef HAVE_TCSETPGRP
5961 PyDoc_STRVAR(posix_tcsetpgrp__doc__
,
5962 "tcsetpgrp(fd, pgid)\n\n\
5963 Set the process group associated with the terminal given by a fd.");
5966 posix_tcsetpgrp(PyObject
*self
, PyObject
*args
)
5969 if (!PyArg_ParseTuple(args
, "ii:tcsetpgrp", &fd
, &pgid
))
5971 if (tcsetpgrp(fd
, pgid
) < 0)
5972 return posix_error();
5976 #endif /* HAVE_TCSETPGRP */
5978 /* Functions acting on file descriptors */
5980 PyDoc_STRVAR(posix_open__doc__
,
5981 "open(filename, flag [, mode=0777]) -> fd\n\n\
5982 Open a file (for low level IO).");
5985 posix_open(PyObject
*self
, PyObject
*args
)
5993 if (unicode_file_names()) {
5994 PyUnicodeObject
*po
;
5995 if (PyArg_ParseTuple(args
, "Ui|i:mkdir", &po
, &flag
, &mode
)) {
5996 Py_BEGIN_ALLOW_THREADS
5997 /* PyUnicode_AS_UNICODE OK without thread
5998 lock as it is a simple dereference. */
5999 fd
= _wopen(PyUnicode_AS_UNICODE(po
), flag
, mode
);
6000 Py_END_ALLOW_THREADS
6002 return posix_error();
6003 return PyInt_FromLong((long)fd
);
6005 /* Drop the argument parsing error as narrow strings
6011 if (!PyArg_ParseTuple(args
, "eti|i",
6012 Py_FileSystemDefaultEncoding
, &file
,
6016 Py_BEGIN_ALLOW_THREADS
6017 fd
= open(file
, flag
, mode
);
6018 Py_END_ALLOW_THREADS
6020 return posix_error_with_allocated_filename(file
);
6022 return PyInt_FromLong((long)fd
);
6026 PyDoc_STRVAR(posix_close__doc__
,
6028 Close a file descriptor (for low level IO).");
6031 posix_close(PyObject
*self
, PyObject
*args
)
6034 if (!PyArg_ParseTuple(args
, "i:close", &fd
))
6036 Py_BEGIN_ALLOW_THREADS
6038 Py_END_ALLOW_THREADS
6040 return posix_error();
6046 PyDoc_STRVAR(posix_dup__doc__
,
6047 "dup(fd) -> fd2\n\n\
6048 Return a duplicate of a file descriptor.");
6051 posix_dup(PyObject
*self
, PyObject
*args
)
6054 if (!PyArg_ParseTuple(args
, "i:dup", &fd
))
6056 Py_BEGIN_ALLOW_THREADS
6058 Py_END_ALLOW_THREADS
6060 return posix_error();
6061 return PyInt_FromLong((long)fd
);
6065 PyDoc_STRVAR(posix_dup2__doc__
,
6066 "dup2(old_fd, new_fd)\n\n\
6067 Duplicate file descriptor.");
6070 posix_dup2(PyObject
*self
, PyObject
*args
)
6073 if (!PyArg_ParseTuple(args
, "ii:dup2", &fd
, &fd2
))
6075 Py_BEGIN_ALLOW_THREADS
6076 res
= dup2(fd
, fd2
);
6077 Py_END_ALLOW_THREADS
6079 return posix_error();
6085 PyDoc_STRVAR(posix_lseek__doc__
,
6086 "lseek(fd, pos, how) -> newpos\n\n\
6087 Set the current position of a file descriptor.");
6090 posix_lseek(PyObject
*self
, PyObject
*args
)
6093 #if defined(MS_WIN64) || defined(MS_WINDOWS)
6094 PY_LONG_LONG pos
, res
;
6099 if (!PyArg_ParseTuple(args
, "iOi:lseek", &fd
, &posobj
, &how
))
6102 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
6104 case 0: how
= SEEK_SET
; break;
6105 case 1: how
= SEEK_CUR
; break;
6106 case 2: how
= SEEK_END
; break;
6108 #endif /* SEEK_END */
6110 #if !defined(HAVE_LARGEFILE_SUPPORT)
6111 pos
= PyInt_AsLong(posobj
);
6113 pos
= PyLong_Check(posobj
) ?
6114 PyLong_AsLongLong(posobj
) : PyInt_AsLong(posobj
);
6116 if (PyErr_Occurred())
6119 Py_BEGIN_ALLOW_THREADS
6120 #if defined(MS_WIN64) || defined(MS_WINDOWS)
6121 res
= _lseeki64(fd
, pos
, how
);
6123 res
= lseek(fd
, pos
, how
);
6125 Py_END_ALLOW_THREADS
6127 return posix_error();
6129 #if !defined(HAVE_LARGEFILE_SUPPORT)
6130 return PyInt_FromLong(res
);
6132 return PyLong_FromLongLong(res
);
6137 PyDoc_STRVAR(posix_read__doc__
,
6138 "read(fd, buffersize) -> string\n\n\
6139 Read a file descriptor.");
6142 posix_read(PyObject
*self
, PyObject
*args
)
6146 if (!PyArg_ParseTuple(args
, "ii:read", &fd
, &size
))
6150 return posix_error();
6152 buffer
= PyString_FromStringAndSize((char *)NULL
, size
);
6155 Py_BEGIN_ALLOW_THREADS
6156 n
= read(fd
, PyString_AsString(buffer
), size
);
6157 Py_END_ALLOW_THREADS
6160 return posix_error();
6163 _PyString_Resize(&buffer
, n
);
6168 PyDoc_STRVAR(posix_write__doc__
,
6169 "write(fd, string) -> byteswritten\n\n\
6170 Write a string to a file descriptor.");
6173 posix_write(PyObject
*self
, PyObject
*args
)
6179 if (!PyArg_ParseTuple(args
, "is#:write", &fd
, &buffer
, &size
))
6181 Py_BEGIN_ALLOW_THREADS
6182 size
= write(fd
, buffer
, (size_t)size
);
6183 Py_END_ALLOW_THREADS
6185 return posix_error();
6186 return PyInt_FromSsize_t(size
);
6190 PyDoc_STRVAR(posix_fstat__doc__
,
6191 "fstat(fd) -> stat result\n\n\
6192 Like stat(), but for an open file descriptor.");
6195 posix_fstat(PyObject
*self
, PyObject
*args
)
6200 if (!PyArg_ParseTuple(args
, "i:fstat", &fd
))
6203 /* on OpenVMS we must ensure that all bytes are written to the file */
6206 Py_BEGIN_ALLOW_THREADS
6207 res
= FSTAT(fd
, &st
);
6208 Py_END_ALLOW_THREADS
6211 return win32_error("fstat", NULL
);
6213 return posix_error();
6217 return _pystat_fromstructstat(&st
);
6221 PyDoc_STRVAR(posix_fdopen__doc__
,
6222 "fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
6223 Return an open file object connected to a file descriptor.");
6226 posix_fdopen(PyObject
*self
, PyObject
*args
)
6233 if (!PyArg_ParseTuple(args
, "i|si", &fd
, &mode
, &bufsize
))
6236 if (mode
[0] != 'r' && mode
[0] != 'w' && mode
[0] != 'a') {
6237 PyErr_Format(PyExc_ValueError
,
6238 "invalid file mode '%s'", mode
);
6241 Py_BEGIN_ALLOW_THREADS
6242 #if !defined(MS_WINDOWS) && defined(HAVE_FCNTL_H)
6243 if (mode
[0] == 'a') {
6244 /* try to make sure the O_APPEND flag is set */
6246 flags
= fcntl(fd
, F_GETFL
);
6248 fcntl(fd
, F_SETFL
, flags
| O_APPEND
);
6249 fp
= fdopen(fd
, mode
);
6250 if (fp
== NULL
&& flags
!= -1)
6251 /* restore old mode if fdopen failed */
6252 fcntl(fd
, F_SETFL
, flags
);
6254 fp
= fdopen(fd
, mode
);
6257 fp
= fdopen(fd
, mode
);
6259 Py_END_ALLOW_THREADS
6261 return posix_error();
6262 f
= PyFile_FromFile(fp
, "<fdopen>", mode
, fclose
);
6264 PyFile_SetBufSize(f
, bufsize
);
6268 PyDoc_STRVAR(posix_isatty__doc__
,
6269 "isatty(fd) -> bool\n\n\
6270 Return True if the file descriptor 'fd' is an open file descriptor\n\
6271 connected to the slave end of a terminal.");
6274 posix_isatty(PyObject
*self
, PyObject
*args
)
6277 if (!PyArg_ParseTuple(args
, "i:isatty", &fd
))
6279 return PyBool_FromLong(isatty(fd
));
6283 PyDoc_STRVAR(posix_pipe__doc__
,
6284 "pipe() -> (read_end, write_end)\n\n\
6288 posix_pipe(PyObject
*self
, PyObject
*noargs
)
6290 #if defined(PYOS_OS2)
6294 Py_BEGIN_ALLOW_THREADS
6295 rc
= DosCreatePipe( &read
, &write
, 4096);
6296 Py_END_ALLOW_THREADS
6298 return os2_error(rc
);
6300 return Py_BuildValue("(ii)", read
, write
);
6302 #if !defined(MS_WINDOWS)
6305 Py_BEGIN_ALLOW_THREADS
6307 Py_END_ALLOW_THREADS
6309 return posix_error();
6310 return Py_BuildValue("(ii)", fds
[0], fds
[1]);
6311 #else /* MS_WINDOWS */
6313 int read_fd
, write_fd
;
6315 Py_BEGIN_ALLOW_THREADS
6316 ok
= CreatePipe(&read
, &write
, NULL
, 0);
6317 Py_END_ALLOW_THREADS
6319 return win32_error("CreatePipe", NULL
);
6320 read_fd
= _open_osfhandle((Py_intptr_t
)read
, 0);
6321 write_fd
= _open_osfhandle((Py_intptr_t
)write
, 1);
6322 return Py_BuildValue("(ii)", read_fd
, write_fd
);
6323 #endif /* MS_WINDOWS */
6326 #endif /* HAVE_PIPE */
6330 PyDoc_STRVAR(posix_mkfifo__doc__
,
6331 "mkfifo(filename [, mode=0666])\n\n\
6332 Create a FIFO (a POSIX named pipe).");
6335 posix_mkfifo(PyObject
*self
, PyObject
*args
)
6340 if (!PyArg_ParseTuple(args
, "s|i:mkfifo", &filename
, &mode
))
6342 Py_BEGIN_ALLOW_THREADS
6343 res
= mkfifo(filename
, mode
);
6344 Py_END_ALLOW_THREADS
6346 return posix_error();
6353 #if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
6354 PyDoc_STRVAR(posix_mknod__doc__
,
6355 "mknod(filename [, mode=0600, device])\n\n\
6356 Create a filesystem node (file, device special file or named pipe)\n\
6357 named filename. mode specifies both the permissions to use and the\n\
6358 type of node to be created, being combined (bitwise OR) with one of\n\
6359 S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
6360 device defines the newly created device special file (probably using\n\
6361 os.makedev()), otherwise it is ignored.");
6365 posix_mknod(PyObject
*self
, PyObject
*args
)
6371 if (!PyArg_ParseTuple(args
, "s|ii:mknod", &filename
, &mode
, &device
))
6373 Py_BEGIN_ALLOW_THREADS
6374 res
= mknod(filename
, mode
, device
);
6375 Py_END_ALLOW_THREADS
6377 return posix_error();
6383 #ifdef HAVE_DEVICE_MACROS
6384 PyDoc_STRVAR(posix_major__doc__
,
6385 "major(device) -> major number\n\
6386 Extracts a device major number from a raw device number.");
6389 posix_major(PyObject
*self
, PyObject
*args
)
6392 if (!PyArg_ParseTuple(args
, "i:major", &device
))
6394 return PyInt_FromLong((long)major(device
));
6397 PyDoc_STRVAR(posix_minor__doc__
,
6398 "minor(device) -> minor number\n\
6399 Extracts a device minor number from a raw device number.");
6402 posix_minor(PyObject
*self
, PyObject
*args
)
6405 if (!PyArg_ParseTuple(args
, "i:minor", &device
))
6407 return PyInt_FromLong((long)minor(device
));
6410 PyDoc_STRVAR(posix_makedev__doc__
,
6411 "makedev(major, minor) -> device number\n\
6412 Composes a raw device number from the major and minor device numbers.");
6415 posix_makedev(PyObject
*self
, PyObject
*args
)
6418 if (!PyArg_ParseTuple(args
, "ii:makedev", &major
, &minor
))
6420 return PyInt_FromLong((long)makedev(major
, minor
));
6422 #endif /* device macros */
6425 #ifdef HAVE_FTRUNCATE
6426 PyDoc_STRVAR(posix_ftruncate__doc__
,
6427 "ftruncate(fd, length)\n\n\
6428 Truncate a file to a specified length.");
6431 posix_ftruncate(PyObject
*self
, PyObject
*args
)
6438 if (!PyArg_ParseTuple(args
, "iO:ftruncate", &fd
, &lenobj
))
6441 #if !defined(HAVE_LARGEFILE_SUPPORT)
6442 length
= PyInt_AsLong(lenobj
);
6444 length
= PyLong_Check(lenobj
) ?
6445 PyLong_AsLongLong(lenobj
) : PyInt_AsLong(lenobj
);
6447 if (PyErr_Occurred())
6450 Py_BEGIN_ALLOW_THREADS
6451 res
= ftruncate(fd
, length
);
6452 Py_END_ALLOW_THREADS
6454 PyErr_SetFromErrno(PyExc_IOError
);
6463 PyDoc_STRVAR(posix_putenv__doc__
,
6464 "putenv(key, value)\n\n\
6465 Change or add an environment variable.");
6467 /* Save putenv() parameters as values here, so we can collect them when they
6468 * get re-set with another call for the same key. */
6469 static PyObject
*posix_putenv_garbage
;
6472 posix_putenv(PyObject
*self
, PyObject
*args
)
6479 if (!PyArg_ParseTuple(args
, "ss:putenv", &s1
, &s2
))
6482 #if defined(PYOS_OS2)
6483 if (stricmp(s1
, "BEGINLIBPATH") == 0) {
6486 rc
= DosSetExtLIBPATH(s2
, BEGIN_LIBPATH
);
6488 return os2_error(rc
);
6490 } else if (stricmp(s1
, "ENDLIBPATH") == 0) {
6493 rc
= DosSetExtLIBPATH(s2
, END_LIBPATH
);
6495 return os2_error(rc
);
6499 /* XXX This can leak memory -- not easy to fix :-( */
6500 len
= strlen(s1
) + strlen(s2
) + 2;
6501 /* len includes space for a trailing \0; the size arg to
6502 PyString_FromStringAndSize does not count that */
6503 newstr
= PyString_FromStringAndSize(NULL
, (int)len
- 1);
6505 return PyErr_NoMemory();
6506 newenv
= PyString_AS_STRING(newstr
);
6507 PyOS_snprintf(newenv
, len
, "%s=%s", s1
, s2
);
6508 if (putenv(newenv
)) {
6513 /* Install the first arg and newstr in posix_putenv_garbage;
6514 * this will cause previous value to be collected. This has to
6515 * happen after the real putenv() call because the old value
6516 * was still accessible until then. */
6517 if (PyDict_SetItem(posix_putenv_garbage
,
6518 PyTuple_GET_ITEM(args
, 0), newstr
)) {
6519 /* really not much we can do; just leak */
6526 #if defined(PYOS_OS2)
6534 #ifdef HAVE_UNSETENV
6535 PyDoc_STRVAR(posix_unsetenv__doc__
,
6537 Delete an environment variable.");
6540 posix_unsetenv(PyObject
*self
, PyObject
*args
)
6544 if (!PyArg_ParseTuple(args
, "s:unsetenv", &s1
))
6549 /* Remove the key from posix_putenv_garbage;
6550 * this will cause it to be collected. This has to
6551 * happen after the real unsetenv() call because the
6552 * old value was still accessible until then.
6554 if (PyDict_DelItem(posix_putenv_garbage
,
6555 PyTuple_GET_ITEM(args
, 0))) {
6556 /* really not much we can do; just leak */
6563 #endif /* unsetenv */
6565 #ifdef HAVE_STRERROR
6566 PyDoc_STRVAR(posix_strerror__doc__
,
6567 "strerror(code) -> string\n\n\
6568 Translate an error code to a message string.");
6571 posix_strerror(PyObject
*self
, PyObject
*args
)
6575 if (!PyArg_ParseTuple(args
, "i:strerror", &code
))
6577 message
= strerror(code
);
6578 if (message
== NULL
) {
6579 PyErr_SetString(PyExc_ValueError
,
6580 "strerror() argument out of range");
6583 return PyString_FromString(message
);
6585 #endif /* strerror */
6588 #ifdef HAVE_SYS_WAIT_H
6591 PyDoc_STRVAR(posix_WCOREDUMP__doc__
,
6592 "WCOREDUMP(status) -> bool\n\n\
6593 Return True if the process returning 'status' was dumped to a core file.");
6596 posix_WCOREDUMP(PyObject
*self
, PyObject
*args
)
6599 WAIT_STATUS_INT(status
) = 0;
6601 if (!PyArg_ParseTuple(args
, "i:WCOREDUMP", &WAIT_STATUS_INT(status
)))
6604 return PyBool_FromLong(WCOREDUMP(status
));
6606 #endif /* WCOREDUMP */
6609 PyDoc_STRVAR(posix_WIFCONTINUED__doc__
,
6610 "WIFCONTINUED(status) -> bool\n\n\
6611 Return True if the process returning 'status' was continued from a\n\
6612 job control stop.");
6615 posix_WIFCONTINUED(PyObject
*self
, PyObject
*args
)
6618 WAIT_STATUS_INT(status
) = 0;
6620 if (!PyArg_ParseTuple(args
, "i:WCONTINUED", &WAIT_STATUS_INT(status
)))
6623 return PyBool_FromLong(WIFCONTINUED(status
));
6625 #endif /* WIFCONTINUED */
6628 PyDoc_STRVAR(posix_WIFSTOPPED__doc__
,
6629 "WIFSTOPPED(status) -> bool\n\n\
6630 Return True if the process returning 'status' was stopped.");
6633 posix_WIFSTOPPED(PyObject
*self
, PyObject
*args
)
6636 WAIT_STATUS_INT(status
) = 0;
6638 if (!PyArg_ParseTuple(args
, "i:WIFSTOPPED", &WAIT_STATUS_INT(status
)))
6641 return PyBool_FromLong(WIFSTOPPED(status
));
6643 #endif /* WIFSTOPPED */
6646 PyDoc_STRVAR(posix_WIFSIGNALED__doc__
,
6647 "WIFSIGNALED(status) -> bool\n\n\
6648 Return True if the process returning 'status' was terminated by a signal.");
6651 posix_WIFSIGNALED(PyObject
*self
, PyObject
*args
)
6654 WAIT_STATUS_INT(status
) = 0;
6656 if (!PyArg_ParseTuple(args
, "i:WIFSIGNALED", &WAIT_STATUS_INT(status
)))
6659 return PyBool_FromLong(WIFSIGNALED(status
));
6661 #endif /* WIFSIGNALED */
6664 PyDoc_STRVAR(posix_WIFEXITED__doc__
,
6665 "WIFEXITED(status) -> bool\n\n\
6666 Return true if the process returning 'status' exited using the exit()\n\
6670 posix_WIFEXITED(PyObject
*self
, PyObject
*args
)
6673 WAIT_STATUS_INT(status
) = 0;
6675 if (!PyArg_ParseTuple(args
, "i:WIFEXITED", &WAIT_STATUS_INT(status
)))
6678 return PyBool_FromLong(WIFEXITED(status
));
6680 #endif /* WIFEXITED */
6683 PyDoc_STRVAR(posix_WEXITSTATUS__doc__
,
6684 "WEXITSTATUS(status) -> integer\n\n\
6685 Return the process return code from 'status'.");
6688 posix_WEXITSTATUS(PyObject
*self
, PyObject
*args
)
6691 WAIT_STATUS_INT(status
) = 0;
6693 if (!PyArg_ParseTuple(args
, "i:WEXITSTATUS", &WAIT_STATUS_INT(status
)))
6696 return Py_BuildValue("i", WEXITSTATUS(status
));
6698 #endif /* WEXITSTATUS */
6701 PyDoc_STRVAR(posix_WTERMSIG__doc__
,
6702 "WTERMSIG(status) -> integer\n\n\
6703 Return the signal that terminated the process that provided the 'status'\n\
6707 posix_WTERMSIG(PyObject
*self
, PyObject
*args
)
6710 WAIT_STATUS_INT(status
) = 0;
6712 if (!PyArg_ParseTuple(args
, "i:WTERMSIG", &WAIT_STATUS_INT(status
)))
6715 return Py_BuildValue("i", WTERMSIG(status
));
6717 #endif /* WTERMSIG */
6720 PyDoc_STRVAR(posix_WSTOPSIG__doc__
,
6721 "WSTOPSIG(status) -> integer\n\n\
6722 Return the signal that stopped the process that provided\n\
6723 the 'status' value.");
6726 posix_WSTOPSIG(PyObject
*self
, PyObject
*args
)
6729 WAIT_STATUS_INT(status
) = 0;
6731 if (!PyArg_ParseTuple(args
, "i:WSTOPSIG", &WAIT_STATUS_INT(status
)))
6734 return Py_BuildValue("i", WSTOPSIG(status
));
6736 #endif /* WSTOPSIG */
6738 #endif /* HAVE_SYS_WAIT_H */
6741 #if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
6743 /* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
6744 needed definitions in sys/statvfs.h */
6747 #include <sys/statvfs.h>
6750 _pystatvfs_fromstructstatvfs(struct statvfs st
) {
6751 PyObject
*v
= PyStructSequence_New(&StatVFSResultType
);
6755 #if !defined(HAVE_LARGEFILE_SUPPORT)
6756 PyStructSequence_SET_ITEM(v
, 0, PyInt_FromLong((long) st
.f_bsize
));
6757 PyStructSequence_SET_ITEM(v
, 1, PyInt_FromLong((long) st
.f_frsize
));
6758 PyStructSequence_SET_ITEM(v
, 2, PyInt_FromLong((long) st
.f_blocks
));
6759 PyStructSequence_SET_ITEM(v
, 3, PyInt_FromLong((long) st
.f_bfree
));
6760 PyStructSequence_SET_ITEM(v
, 4, PyInt_FromLong((long) st
.f_bavail
));
6761 PyStructSequence_SET_ITEM(v
, 5, PyInt_FromLong((long) st
.f_files
));
6762 PyStructSequence_SET_ITEM(v
, 6, PyInt_FromLong((long) st
.f_ffree
));
6763 PyStructSequence_SET_ITEM(v
, 7, PyInt_FromLong((long) st
.f_favail
));
6764 PyStructSequence_SET_ITEM(v
, 8, PyInt_FromLong((long) st
.f_flag
));
6765 PyStructSequence_SET_ITEM(v
, 9, PyInt_FromLong((long) st
.f_namemax
));
6767 PyStructSequence_SET_ITEM(v
, 0, PyInt_FromLong((long) st
.f_bsize
));
6768 PyStructSequence_SET_ITEM(v
, 1, PyInt_FromLong((long) st
.f_frsize
));
6769 PyStructSequence_SET_ITEM(v
, 2,
6770 PyLong_FromLongLong((PY_LONG_LONG
) st
.f_blocks
));
6771 PyStructSequence_SET_ITEM(v
, 3,
6772 PyLong_FromLongLong((PY_LONG_LONG
) st
.f_bfree
));
6773 PyStructSequence_SET_ITEM(v
, 4,
6774 PyLong_FromLongLong((PY_LONG_LONG
) st
.f_bavail
));
6775 PyStructSequence_SET_ITEM(v
, 5,
6776 PyLong_FromLongLong((PY_LONG_LONG
) st
.f_files
));
6777 PyStructSequence_SET_ITEM(v
, 6,
6778 PyLong_FromLongLong((PY_LONG_LONG
) st
.f_ffree
));
6779 PyStructSequence_SET_ITEM(v
, 7,
6780 PyLong_FromLongLong((PY_LONG_LONG
) st
.f_favail
));
6781 PyStructSequence_SET_ITEM(v
, 8, PyInt_FromLong((long) st
.f_flag
));
6782 PyStructSequence_SET_ITEM(v
, 9, PyInt_FromLong((long) st
.f_namemax
));
6788 PyDoc_STRVAR(posix_fstatvfs__doc__
,
6789 "fstatvfs(fd) -> statvfs result\n\n\
6790 Perform an fstatvfs system call on the given fd.");
6793 posix_fstatvfs(PyObject
*self
, PyObject
*args
)
6798 if (!PyArg_ParseTuple(args
, "i:fstatvfs", &fd
))
6800 Py_BEGIN_ALLOW_THREADS
6801 res
= fstatvfs(fd
, &st
);
6802 Py_END_ALLOW_THREADS
6804 return posix_error();
6806 return _pystatvfs_fromstructstatvfs(st
);
6808 #endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
6811 #if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
6812 #include <sys/statvfs.h>
6814 PyDoc_STRVAR(posix_statvfs__doc__
,
6815 "statvfs(path) -> statvfs result\n\n\
6816 Perform a statvfs system call on the given path.");
6819 posix_statvfs(PyObject
*self
, PyObject
*args
)
6824 if (!PyArg_ParseTuple(args
, "s:statvfs", &path
))
6826 Py_BEGIN_ALLOW_THREADS
6827 res
= statvfs(path
, &st
);
6828 Py_END_ALLOW_THREADS
6830 return posix_error_with_filename(path
);
6832 return _pystatvfs_fromstructstatvfs(st
);
6834 #endif /* HAVE_STATVFS */
6838 PyDoc_STRVAR(posix_tempnam__doc__
,
6839 "tempnam([dir[, prefix]]) -> string\n\n\
6840 Return a unique name for a temporary file.\n\
6841 The directory and a prefix may be specified as strings; they may be omitted\n\
6842 or None if not needed.");
6845 posix_tempnam(PyObject
*self
, PyObject
*args
)
6847 PyObject
*result
= NULL
;
6852 if (!PyArg_ParseTuple(args
, "|zz:tempnam", &dir
, &pfx
))
6855 if (PyErr_Warn(PyExc_RuntimeWarning
,
6856 "tempnam is a potential security risk to your program") < 0)
6860 name
= _tempnam(dir
, pfx
);
6862 name
= tempnam(dir
, pfx
);
6865 return PyErr_NoMemory();
6866 result
= PyString_FromString(name
);
6874 PyDoc_STRVAR(posix_tmpfile__doc__
,
6875 "tmpfile() -> file object\n\n\
6876 Create a temporary file with no directory entries.");
6879 posix_tmpfile(PyObject
*self
, PyObject
*noargs
)
6885 return posix_error();
6886 return PyFile_FromFile(fp
, "<tmpfile>", "w+b", fclose
);
6892 PyDoc_STRVAR(posix_tmpnam__doc__
,
6893 "tmpnam() -> string\n\n\
6894 Return a unique name for a temporary file.");
6897 posix_tmpnam(PyObject
*self
, PyObject
*noargs
)
6899 char buffer
[L_tmpnam
];
6902 if (PyErr_Warn(PyExc_RuntimeWarning
,
6903 "tmpnam is a potential security risk to your program") < 0)
6907 name
= tmpnam_r(buffer
);
6909 name
= tmpnam(buffer
);
6912 PyObject
*err
= Py_BuildValue("is", 0,
6914 "unexpected NULL from tmpnam_r"
6916 "unexpected NULL from tmpnam"
6919 PyErr_SetObject(PyExc_OSError
, err
);
6923 return PyString_FromString(buffer
);
6928 /* This is used for fpathconf(), pathconf(), confstr() and sysconf().
6929 * It maps strings representing configuration variable names to
6930 * integer values, allowing those functions to be called with the
6931 * magic names instead of polluting the module's namespace with tons of
6932 * rarely-used constants. There are three separate tables that use
6933 * these definitions.
6935 * This code is always included, even if none of the interfaces that
6936 * need it are included. The #if hackery needed to avoid it would be
6937 * sufficiently pervasive that it's not worth the loss of readability.
6945 conv_confname(PyObject
*arg
, int *valuep
, struct constdef
*table
,
6948 if (PyInt_Check(arg
)) {
6949 *valuep
= PyInt_AS_LONG(arg
);
6952 if (PyString_Check(arg
)) {
6953 /* look up the value in the table using a binary search */
6956 size_t hi
= tablesize
;
6958 char *confname
= PyString_AS_STRING(arg
);
6960 mid
= (lo
+ hi
) / 2;
6961 cmp
= strcmp(confname
, table
[mid
].name
);
6967 *valuep
= table
[mid
].value
;
6971 PyErr_SetString(PyExc_ValueError
, "unrecognized configuration name");
6974 PyErr_SetString(PyExc_TypeError
,
6975 "configuration names must be strings or integers");
6980 #if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
6981 static struct constdef posix_constants_pathconf
[] = {
6982 #ifdef _PC_ABI_AIO_XFER_MAX
6983 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX
},
6985 #ifdef _PC_ABI_ASYNC_IO
6986 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO
},
6989 {"PC_ASYNC_IO", _PC_ASYNC_IO
},
6991 #ifdef _PC_CHOWN_RESTRICTED
6992 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED
},
6994 #ifdef _PC_FILESIZEBITS
6995 {"PC_FILESIZEBITS", _PC_FILESIZEBITS
},
6998 {"PC_LAST", _PC_LAST
},
7001 {"PC_LINK_MAX", _PC_LINK_MAX
},
7003 #ifdef _PC_MAX_CANON
7004 {"PC_MAX_CANON", _PC_MAX_CANON
},
7006 #ifdef _PC_MAX_INPUT
7007 {"PC_MAX_INPUT", _PC_MAX_INPUT
},
7010 {"PC_NAME_MAX", _PC_NAME_MAX
},
7013 {"PC_NO_TRUNC", _PC_NO_TRUNC
},
7016 {"PC_PATH_MAX", _PC_PATH_MAX
},
7019 {"PC_PIPE_BUF", _PC_PIPE_BUF
},
7022 {"PC_PRIO_IO", _PC_PRIO_IO
},
7024 #ifdef _PC_SOCK_MAXBUF
7025 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF
},
7028 {"PC_SYNC_IO", _PC_SYNC_IO
},
7031 {"PC_VDISABLE", _PC_VDISABLE
},
7036 conv_path_confname(PyObject
*arg
, int *valuep
)
7038 return conv_confname(arg
, valuep
, posix_constants_pathconf
,
7039 sizeof(posix_constants_pathconf
)
7040 / sizeof(struct constdef
));
7044 #ifdef HAVE_FPATHCONF
7045 PyDoc_STRVAR(posix_fpathconf__doc__
,
7046 "fpathconf(fd, name) -> integer\n\n\
7047 Return the configuration limit name for the file descriptor fd.\n\
7048 If there is no limit, return -1.");
7051 posix_fpathconf(PyObject
*self
, PyObject
*args
)
7053 PyObject
*result
= NULL
;
7056 if (PyArg_ParseTuple(args
, "iO&:fpathconf", &fd
,
7057 conv_path_confname
, &name
)) {
7061 limit
= fpathconf(fd
, name
);
7062 if (limit
== -1 && errno
!= 0)
7065 result
= PyInt_FromLong(limit
);
7072 #ifdef HAVE_PATHCONF
7073 PyDoc_STRVAR(posix_pathconf__doc__
,
7074 "pathconf(path, name) -> integer\n\n\
7075 Return the configuration limit name for the file or directory path.\n\
7076 If there is no limit, return -1.");
7079 posix_pathconf(PyObject
*self
, PyObject
*args
)
7081 PyObject
*result
= NULL
;
7085 if (PyArg_ParseTuple(args
, "sO&:pathconf", &path
,
7086 conv_path_confname
, &name
)) {
7090 limit
= pathconf(path
, name
);
7091 if (limit
== -1 && errno
!= 0) {
7092 if (errno
== EINVAL
)
7093 /* could be a path or name problem */
7096 posix_error_with_filename(path
);
7099 result
= PyInt_FromLong(limit
);
7106 static struct constdef posix_constants_confstr
[] = {
7107 #ifdef _CS_ARCHITECTURE
7108 {"CS_ARCHITECTURE", _CS_ARCHITECTURE
},
7111 {"CS_HOSTNAME", _CS_HOSTNAME
},
7113 #ifdef _CS_HW_PROVIDER
7114 {"CS_HW_PROVIDER", _CS_HW_PROVIDER
},
7116 #ifdef _CS_HW_SERIAL
7117 {"CS_HW_SERIAL", _CS_HW_SERIAL
},
7119 #ifdef _CS_INITTAB_NAME
7120 {"CS_INITTAB_NAME", _CS_INITTAB_NAME
},
7122 #ifdef _CS_LFS64_CFLAGS
7123 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS
},
7125 #ifdef _CS_LFS64_LDFLAGS
7126 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS
},
7128 #ifdef _CS_LFS64_LIBS
7129 {"CS_LFS64_LIBS", _CS_LFS64_LIBS
},
7131 #ifdef _CS_LFS64_LINTFLAGS
7132 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS
},
7134 #ifdef _CS_LFS_CFLAGS
7135 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS
},
7137 #ifdef _CS_LFS_LDFLAGS
7138 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS
},
7141 {"CS_LFS_LIBS", _CS_LFS_LIBS
},
7143 #ifdef _CS_LFS_LINTFLAGS
7144 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS
},
7147 {"CS_MACHINE", _CS_MACHINE
},
7150 {"CS_PATH", _CS_PATH
},
7153 {"CS_RELEASE", _CS_RELEASE
},
7155 #ifdef _CS_SRPC_DOMAIN
7156 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN
},
7159 {"CS_SYSNAME", _CS_SYSNAME
},
7162 {"CS_VERSION", _CS_VERSION
},
7164 #ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
7165 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS
},
7167 #ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
7168 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS
},
7170 #ifdef _CS_XBS5_ILP32_OFF32_LIBS
7171 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS
},
7173 #ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
7174 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS
},
7176 #ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
7177 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS
},
7179 #ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
7180 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS
},
7182 #ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
7183 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS
},
7185 #ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
7186 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
},
7188 #ifdef _CS_XBS5_LP64_OFF64_CFLAGS
7189 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS
},
7191 #ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
7192 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS
},
7194 #ifdef _CS_XBS5_LP64_OFF64_LIBS
7195 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS
},
7197 #ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
7198 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS
},
7200 #ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
7201 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS
},
7203 #ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
7204 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
},
7206 #ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
7207 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS
},
7209 #ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
7210 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
},
7212 #ifdef _MIPS_CS_AVAIL_PROCESSORS
7213 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS
},
7215 #ifdef _MIPS_CS_BASE
7216 {"MIPS_CS_BASE", _MIPS_CS_BASE
},
7218 #ifdef _MIPS_CS_HOSTID
7219 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID
},
7221 #ifdef _MIPS_CS_HW_NAME
7222 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME
},
7224 #ifdef _MIPS_CS_NUM_PROCESSORS
7225 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS
},
7227 #ifdef _MIPS_CS_OSREL_MAJ
7228 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ
},
7230 #ifdef _MIPS_CS_OSREL_MIN
7231 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN
},
7233 #ifdef _MIPS_CS_OSREL_PATCH
7234 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH
},
7236 #ifdef _MIPS_CS_OS_NAME
7237 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME
},
7239 #ifdef _MIPS_CS_OS_PROVIDER
7240 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER
},
7242 #ifdef _MIPS_CS_PROCESSORS
7243 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS
},
7245 #ifdef _MIPS_CS_SERIAL
7246 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL
},
7248 #ifdef _MIPS_CS_VENDOR
7249 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR
},
7254 conv_confstr_confname(PyObject
*arg
, int *valuep
)
7256 return conv_confname(arg
, valuep
, posix_constants_confstr
,
7257 sizeof(posix_constants_confstr
)
7258 / sizeof(struct constdef
));
7261 PyDoc_STRVAR(posix_confstr__doc__
,
7262 "confstr(name) -> string\n\n\
7263 Return a string-valued system configuration variable.");
7266 posix_confstr(PyObject
*self
, PyObject
*args
)
7268 PyObject
*result
= NULL
;
7272 if (PyArg_ParseTuple(args
, "O&:confstr", conv_confstr_confname
, &name
)) {
7276 len
= confstr(name
, buffer
, sizeof(buffer
));
7287 if ((unsigned int)len
>= sizeof(buffer
)) {
7288 result
= PyString_FromStringAndSize(NULL
, len
-1);
7290 confstr(name
, PyString_AS_STRING(result
), len
);
7293 result
= PyString_FromStringAndSize(buffer
, len
-1);
7302 static struct constdef posix_constants_sysconf
[] = {
7303 #ifdef _SC_2_CHAR_TERM
7304 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM
},
7307 {"SC_2_C_BIND", _SC_2_C_BIND
},
7310 {"SC_2_C_DEV", _SC_2_C_DEV
},
7312 #ifdef _SC_2_C_VERSION
7313 {"SC_2_C_VERSION", _SC_2_C_VERSION
},
7315 #ifdef _SC_2_FORT_DEV
7316 {"SC_2_FORT_DEV", _SC_2_FORT_DEV
},
7318 #ifdef _SC_2_FORT_RUN
7319 {"SC_2_FORT_RUN", _SC_2_FORT_RUN
},
7321 #ifdef _SC_2_LOCALEDEF
7322 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF
},
7325 {"SC_2_SW_DEV", _SC_2_SW_DEV
},
7328 {"SC_2_UPE", _SC_2_UPE
},
7330 #ifdef _SC_2_VERSION
7331 {"SC_2_VERSION", _SC_2_VERSION
},
7333 #ifdef _SC_ABI_ASYNCHRONOUS_IO
7334 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO
},
7337 {"SC_ACL", _SC_ACL
},
7339 #ifdef _SC_AIO_LISTIO_MAX
7340 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX
},
7343 {"SC_AIO_MAX", _SC_AIO_MAX
},
7345 #ifdef _SC_AIO_PRIO_DELTA_MAX
7346 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX
},
7349 {"SC_ARG_MAX", _SC_ARG_MAX
},
7351 #ifdef _SC_ASYNCHRONOUS_IO
7352 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO
},
7354 #ifdef _SC_ATEXIT_MAX
7355 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX
},
7358 {"SC_AUDIT", _SC_AUDIT
},
7360 #ifdef _SC_AVPHYS_PAGES
7361 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES
},
7363 #ifdef _SC_BC_BASE_MAX
7364 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX
},
7366 #ifdef _SC_BC_DIM_MAX
7367 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX
},
7369 #ifdef _SC_BC_SCALE_MAX
7370 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX
},
7372 #ifdef _SC_BC_STRING_MAX
7373 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX
},
7376 {"SC_CAP", _SC_CAP
},
7378 #ifdef _SC_CHARCLASS_NAME_MAX
7379 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX
},
7382 {"SC_CHAR_BIT", _SC_CHAR_BIT
},
7385 {"SC_CHAR_MAX", _SC_CHAR_MAX
},
7388 {"SC_CHAR_MIN", _SC_CHAR_MIN
},
7390 #ifdef _SC_CHILD_MAX
7391 {"SC_CHILD_MAX", _SC_CHILD_MAX
},
7394 {"SC_CLK_TCK", _SC_CLK_TCK
},
7396 #ifdef _SC_COHER_BLKSZ
7397 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ
},
7399 #ifdef _SC_COLL_WEIGHTS_MAX
7400 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX
},
7402 #ifdef _SC_DCACHE_ASSOC
7403 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC
},
7405 #ifdef _SC_DCACHE_BLKSZ
7406 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ
},
7408 #ifdef _SC_DCACHE_LINESZ
7409 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ
},
7411 #ifdef _SC_DCACHE_SZ
7412 {"SC_DCACHE_SZ", _SC_DCACHE_SZ
},
7414 #ifdef _SC_DCACHE_TBLKSZ
7415 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ
},
7417 #ifdef _SC_DELAYTIMER_MAX
7418 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX
},
7420 #ifdef _SC_EQUIV_CLASS_MAX
7421 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX
},
7423 #ifdef _SC_EXPR_NEST_MAX
7424 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX
},
7427 {"SC_FSYNC", _SC_FSYNC
},
7429 #ifdef _SC_GETGR_R_SIZE_MAX
7430 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX
},
7432 #ifdef _SC_GETPW_R_SIZE_MAX
7433 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX
},
7435 #ifdef _SC_ICACHE_ASSOC
7436 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC
},
7438 #ifdef _SC_ICACHE_BLKSZ
7439 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ
},
7441 #ifdef _SC_ICACHE_LINESZ
7442 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ
},
7444 #ifdef _SC_ICACHE_SZ
7445 {"SC_ICACHE_SZ", _SC_ICACHE_SZ
},
7448 {"SC_INF", _SC_INF
},
7451 {"SC_INT_MAX", _SC_INT_MAX
},
7454 {"SC_INT_MIN", _SC_INT_MIN
},
7457 {"SC_IOV_MAX", _SC_IOV_MAX
},
7459 #ifdef _SC_IP_SECOPTS
7460 {"SC_IP_SECOPTS", _SC_IP_SECOPTS
},
7462 #ifdef _SC_JOB_CONTROL
7463 {"SC_JOB_CONTROL", _SC_JOB_CONTROL
},
7465 #ifdef _SC_KERN_POINTERS
7466 {"SC_KERN_POINTERS", _SC_KERN_POINTERS
},
7469 {"SC_KERN_SIM", _SC_KERN_SIM
},
7472 {"SC_LINE_MAX", _SC_LINE_MAX
},
7474 #ifdef _SC_LOGIN_NAME_MAX
7475 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX
},
7477 #ifdef _SC_LOGNAME_MAX
7478 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX
},
7481 {"SC_LONG_BIT", _SC_LONG_BIT
},
7484 {"SC_MAC", _SC_MAC
},
7486 #ifdef _SC_MAPPED_FILES
7487 {"SC_MAPPED_FILES", _SC_MAPPED_FILES
},
7490 {"SC_MAXPID", _SC_MAXPID
},
7492 #ifdef _SC_MB_LEN_MAX
7493 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX
},
7496 {"SC_MEMLOCK", _SC_MEMLOCK
},
7498 #ifdef _SC_MEMLOCK_RANGE
7499 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE
},
7501 #ifdef _SC_MEMORY_PROTECTION
7502 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION
},
7504 #ifdef _SC_MESSAGE_PASSING
7505 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING
},
7507 #ifdef _SC_MMAP_FIXED_ALIGNMENT
7508 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT
},
7510 #ifdef _SC_MQ_OPEN_MAX
7511 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX
},
7513 #ifdef _SC_MQ_PRIO_MAX
7514 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX
},
7516 #ifdef _SC_NACLS_MAX
7517 {"SC_NACLS_MAX", _SC_NACLS_MAX
},
7519 #ifdef _SC_NGROUPS_MAX
7520 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX
},
7522 #ifdef _SC_NL_ARGMAX
7523 {"SC_NL_ARGMAX", _SC_NL_ARGMAX
},
7525 #ifdef _SC_NL_LANGMAX
7526 {"SC_NL_LANGMAX", _SC_NL_LANGMAX
},
7528 #ifdef _SC_NL_MSGMAX
7529 {"SC_NL_MSGMAX", _SC_NL_MSGMAX
},
7532 {"SC_NL_NMAX", _SC_NL_NMAX
},
7534 #ifdef _SC_NL_SETMAX
7535 {"SC_NL_SETMAX", _SC_NL_SETMAX
},
7537 #ifdef _SC_NL_TEXTMAX
7538 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX
},
7540 #ifdef _SC_NPROCESSORS_CONF
7541 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF
},
7543 #ifdef _SC_NPROCESSORS_ONLN
7544 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN
},
7546 #ifdef _SC_NPROC_CONF
7547 {"SC_NPROC_CONF", _SC_NPROC_CONF
},
7549 #ifdef _SC_NPROC_ONLN
7550 {"SC_NPROC_ONLN", _SC_NPROC_ONLN
},
7553 {"SC_NZERO", _SC_NZERO
},
7556 {"SC_OPEN_MAX", _SC_OPEN_MAX
},
7559 {"SC_PAGESIZE", _SC_PAGESIZE
},
7561 #ifdef _SC_PAGE_SIZE
7562 {"SC_PAGE_SIZE", _SC_PAGE_SIZE
},
7565 {"SC_PASS_MAX", _SC_PASS_MAX
},
7567 #ifdef _SC_PHYS_PAGES
7568 {"SC_PHYS_PAGES", _SC_PHYS_PAGES
},
7571 {"SC_PII", _SC_PII
},
7573 #ifdef _SC_PII_INTERNET
7574 {"SC_PII_INTERNET", _SC_PII_INTERNET
},
7576 #ifdef _SC_PII_INTERNET_DGRAM
7577 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM
},
7579 #ifdef _SC_PII_INTERNET_STREAM
7580 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM
},
7583 {"SC_PII_OSI", _SC_PII_OSI
},
7585 #ifdef _SC_PII_OSI_CLTS
7586 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS
},
7588 #ifdef _SC_PII_OSI_COTS
7589 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS
},
7591 #ifdef _SC_PII_OSI_M
7592 {"SC_PII_OSI_M", _SC_PII_OSI_M
},
7594 #ifdef _SC_PII_SOCKET
7595 {"SC_PII_SOCKET", _SC_PII_SOCKET
},
7598 {"SC_PII_XTI", _SC_PII_XTI
},
7601 {"SC_POLL", _SC_POLL
},
7603 #ifdef _SC_PRIORITIZED_IO
7604 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO
},
7606 #ifdef _SC_PRIORITY_SCHEDULING
7607 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING
},
7609 #ifdef _SC_REALTIME_SIGNALS
7610 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS
},
7612 #ifdef _SC_RE_DUP_MAX
7613 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX
},
7615 #ifdef _SC_RTSIG_MAX
7616 {"SC_RTSIG_MAX", _SC_RTSIG_MAX
},
7618 #ifdef _SC_SAVED_IDS
7619 {"SC_SAVED_IDS", _SC_SAVED_IDS
},
7621 #ifdef _SC_SCHAR_MAX
7622 {"SC_SCHAR_MAX", _SC_SCHAR_MAX
},
7624 #ifdef _SC_SCHAR_MIN
7625 {"SC_SCHAR_MIN", _SC_SCHAR_MIN
},
7628 {"SC_SELECT", _SC_SELECT
},
7630 #ifdef _SC_SEMAPHORES
7631 {"SC_SEMAPHORES", _SC_SEMAPHORES
},
7633 #ifdef _SC_SEM_NSEMS_MAX
7634 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX
},
7636 #ifdef _SC_SEM_VALUE_MAX
7637 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX
},
7639 #ifdef _SC_SHARED_MEMORY_OBJECTS
7640 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS
},
7643 {"SC_SHRT_MAX", _SC_SHRT_MAX
},
7646 {"SC_SHRT_MIN", _SC_SHRT_MIN
},
7648 #ifdef _SC_SIGQUEUE_MAX
7649 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX
},
7651 #ifdef _SC_SIGRT_MAX
7652 {"SC_SIGRT_MAX", _SC_SIGRT_MAX
},
7654 #ifdef _SC_SIGRT_MIN
7655 {"SC_SIGRT_MIN", _SC_SIGRT_MIN
},
7657 #ifdef _SC_SOFTPOWER
7658 {"SC_SOFTPOWER", _SC_SOFTPOWER
},
7660 #ifdef _SC_SPLIT_CACHE
7661 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE
},
7663 #ifdef _SC_SSIZE_MAX
7664 {"SC_SSIZE_MAX", _SC_SSIZE_MAX
},
7666 #ifdef _SC_STACK_PROT
7667 {"SC_STACK_PROT", _SC_STACK_PROT
},
7669 #ifdef _SC_STREAM_MAX
7670 {"SC_STREAM_MAX", _SC_STREAM_MAX
},
7672 #ifdef _SC_SYNCHRONIZED_IO
7673 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO
},
7676 {"SC_THREADS", _SC_THREADS
},
7678 #ifdef _SC_THREAD_ATTR_STACKADDR
7679 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR
},
7681 #ifdef _SC_THREAD_ATTR_STACKSIZE
7682 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE
},
7684 #ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
7685 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS
},
7687 #ifdef _SC_THREAD_KEYS_MAX
7688 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX
},
7690 #ifdef _SC_THREAD_PRIORITY_SCHEDULING
7691 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING
},
7693 #ifdef _SC_THREAD_PRIO_INHERIT
7694 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT
},
7696 #ifdef _SC_THREAD_PRIO_PROTECT
7697 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT
},
7699 #ifdef _SC_THREAD_PROCESS_SHARED
7700 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED
},
7702 #ifdef _SC_THREAD_SAFE_FUNCTIONS
7703 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS
},
7705 #ifdef _SC_THREAD_STACK_MIN
7706 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN
},
7708 #ifdef _SC_THREAD_THREADS_MAX
7709 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX
},
7712 {"SC_TIMERS", _SC_TIMERS
},
7714 #ifdef _SC_TIMER_MAX
7715 {"SC_TIMER_MAX", _SC_TIMER_MAX
},
7717 #ifdef _SC_TTY_NAME_MAX
7718 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX
},
7720 #ifdef _SC_TZNAME_MAX
7721 {"SC_TZNAME_MAX", _SC_TZNAME_MAX
},
7723 #ifdef _SC_T_IOV_MAX
7724 {"SC_T_IOV_MAX", _SC_T_IOV_MAX
},
7726 #ifdef _SC_UCHAR_MAX
7727 {"SC_UCHAR_MAX", _SC_UCHAR_MAX
},
7730 {"SC_UINT_MAX", _SC_UINT_MAX
},
7732 #ifdef _SC_UIO_MAXIOV
7733 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV
},
7735 #ifdef _SC_ULONG_MAX
7736 {"SC_ULONG_MAX", _SC_ULONG_MAX
},
7738 #ifdef _SC_USHRT_MAX
7739 {"SC_USHRT_MAX", _SC_USHRT_MAX
},
7742 {"SC_VERSION", _SC_VERSION
},
7745 {"SC_WORD_BIT", _SC_WORD_BIT
},
7747 #ifdef _SC_XBS5_ILP32_OFF32
7748 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32
},
7750 #ifdef _SC_XBS5_ILP32_OFFBIG
7751 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG
},
7753 #ifdef _SC_XBS5_LP64_OFF64
7754 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64
},
7756 #ifdef _SC_XBS5_LPBIG_OFFBIG
7757 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG
},
7759 #ifdef _SC_XOPEN_CRYPT
7760 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT
},
7762 #ifdef _SC_XOPEN_ENH_I18N
7763 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N
},
7765 #ifdef _SC_XOPEN_LEGACY
7766 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY
},
7768 #ifdef _SC_XOPEN_REALTIME
7769 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME
},
7771 #ifdef _SC_XOPEN_REALTIME_THREADS
7772 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS
},
7774 #ifdef _SC_XOPEN_SHM
7775 {"SC_XOPEN_SHM", _SC_XOPEN_SHM
},
7777 #ifdef _SC_XOPEN_UNIX
7778 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX
},
7780 #ifdef _SC_XOPEN_VERSION
7781 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION
},
7783 #ifdef _SC_XOPEN_XCU_VERSION
7784 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION
},
7786 #ifdef _SC_XOPEN_XPG2
7787 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2
},
7789 #ifdef _SC_XOPEN_XPG3
7790 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3
},
7792 #ifdef _SC_XOPEN_XPG4
7793 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4
},
7798 conv_sysconf_confname(PyObject
*arg
, int *valuep
)
7800 return conv_confname(arg
, valuep
, posix_constants_sysconf
,
7801 sizeof(posix_constants_sysconf
)
7802 / sizeof(struct constdef
));
7805 PyDoc_STRVAR(posix_sysconf__doc__
,
7806 "sysconf(name) -> integer\n\n\
7807 Return an integer-valued system configuration variable.");
7810 posix_sysconf(PyObject
*self
, PyObject
*args
)
7812 PyObject
*result
= NULL
;
7815 if (PyArg_ParseTuple(args
, "O&:sysconf", conv_sysconf_confname
, &name
)) {
7819 value
= sysconf(name
);
7820 if (value
== -1 && errno
!= 0)
7823 result
= PyInt_FromLong(value
);
7830 /* This code is used to ensure that the tables of configuration value names
7831 * are in sorted order as required by conv_confname(), and also to build the
7832 * the exported dictionaries that are used to publish information about the
7833 * names available on the host platform.
7835 * Sorting the table at runtime ensures that the table is properly ordered
7836 * when used, even for platforms we're not able to test on. It also makes
7837 * it easier to add additional entries to the tables.
7841 cmp_constdefs(const void *v1
, const void *v2
)
7843 const struct constdef
*c1
=
7844 (const struct constdef
*) v1
;
7845 const struct constdef
*c2
=
7846 (const struct constdef
*) v2
;
7848 return strcmp(c1
->name
, c2
->name
);
7852 setup_confname_table(struct constdef
*table
, size_t tablesize
,
7853 char *tablename
, PyObject
*module
)
7858 qsort(table
, tablesize
, sizeof(struct constdef
), cmp_constdefs
);
7863 for (i
=0; i
< tablesize
; ++i
) {
7864 PyObject
*o
= PyInt_FromLong(table
[i
].value
);
7865 if (o
== NULL
|| PyDict_SetItemString(d
, table
[i
].name
, o
) == -1) {
7872 return PyModule_AddObject(module
, tablename
, d
);
7875 /* Return -1 on failure, 0 on success. */
7877 setup_confname_tables(PyObject
*module
)
7879 #if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
7880 if (setup_confname_table(posix_constants_pathconf
,
7881 sizeof(posix_constants_pathconf
)
7882 / sizeof(struct constdef
),
7883 "pathconf_names", module
))
7887 if (setup_confname_table(posix_constants_confstr
,
7888 sizeof(posix_constants_confstr
)
7889 / sizeof(struct constdef
),
7890 "confstr_names", module
))
7894 if (setup_confname_table(posix_constants_sysconf
,
7895 sizeof(posix_constants_sysconf
)
7896 / sizeof(struct constdef
),
7897 "sysconf_names", module
))
7904 PyDoc_STRVAR(posix_abort__doc__
,
7905 "abort() -> does not return!\n\n\
7906 Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
7907 in the hardest way possible on the hosting operating system.");
7910 posix_abort(PyObject
*self
, PyObject
*noargs
)
7914 Py_FatalError("abort() called from Python code didn't abort!");
7919 PyDoc_STRVAR(win32_startfile__doc__
,
7920 "startfile(filepath [, operation]) - Start a file with its associated\n\
7923 When \"operation\" is not specified or \"open\", this acts like\n\
7924 double-clicking the file in Explorer, or giving the file name as an\n\
7925 argument to the DOS \"start\" command: the file is opened with whatever\n\
7926 application (if any) its extension is associated.\n\
7927 When another \"operation\" is given, it specifies what should be done with\n\
7928 the file. A typical operation is \"print\".\n\
7930 startfile returns as soon as the associated application is launched.\n\
7931 There is no option to wait for the application to close, and no way\n\
7932 to retrieve the application's exit status.\n\
7934 The filepath is relative to the current directory. If you want to use\n\
7935 an absolute path, make sure the first character is not a slash (\"/\");\n\
7936 the underlying Win32 ShellExecute function doesn't work if it is.");
7939 win32_startfile(PyObject
*self
, PyObject
*args
)
7942 char *operation
= NULL
;
7944 #ifdef Py_WIN_WIDE_FILENAMES
7945 if (unicode_file_names()) {
7946 PyObject
*unipath
, *woperation
= NULL
;
7947 if (!PyArg_ParseTuple(args
, "U|s:startfile",
7948 &unipath
, &operation
)) {
7955 woperation
= PyUnicode_DecodeASCII(operation
,
7956 strlen(operation
), NULL
);
7964 Py_BEGIN_ALLOW_THREADS
7965 rc
= ShellExecuteW((HWND
)0, woperation
? PyUnicode_AS_UNICODE(woperation
) : 0,
7966 PyUnicode_AS_UNICODE(unipath
),
7967 NULL
, NULL
, SW_SHOWNORMAL
);
7968 Py_END_ALLOW_THREADS
7970 Py_XDECREF(woperation
);
7971 if (rc
<= (HINSTANCE
)32) {
7972 PyObject
*errval
= win32_error_unicode("startfile",
7973 PyUnicode_AS_UNICODE(unipath
));
7982 if (!PyArg_ParseTuple(args
, "et|s:startfile",
7983 Py_FileSystemDefaultEncoding
, &filepath
,
7986 Py_BEGIN_ALLOW_THREADS
7987 rc
= ShellExecute((HWND
)0, operation
, filepath
,
7988 NULL
, NULL
, SW_SHOWNORMAL
);
7989 Py_END_ALLOW_THREADS
7990 if (rc
<= (HINSTANCE
)32) {
7991 PyObject
*errval
= win32_error("startfile", filepath
);
7992 PyMem_Free(filepath
);
7995 PyMem_Free(filepath
);
8001 #ifdef HAVE_GETLOADAVG
8002 PyDoc_STRVAR(posix_getloadavg__doc__
,
8003 "getloadavg() -> (float, float, float)\n\n\
8004 Return the number of processes in the system run queue averaged over\n\
8005 the last 1, 5, and 15 minutes or raises OSError if the load average\n\
8009 posix_getloadavg(PyObject
*self
, PyObject
*noargs
)
8012 if (getloadavg(loadavg
, 3)!=3) {
8013 PyErr_SetString(PyExc_OSError
, "Load averages are unobtainable");
8016 return Py_BuildValue("ddd", loadavg
[0], loadavg
[1], loadavg
[2]);
8022 PyDoc_STRVAR(win32_urandom__doc__
,
8023 "urandom(n) -> str\n\n\
8024 Return a string of n random bytes suitable for cryptographic use.");
8026 typedef BOOL (WINAPI
*CRYPTACQUIRECONTEXTA
)(HCRYPTPROV
*phProv
,\
8027 LPCSTR pszContainer
, LPCSTR pszProvider
, DWORD dwProvType
,\
8029 typedef BOOL (WINAPI
*CRYPTGENRANDOM
)(HCRYPTPROV hProv
, DWORD dwLen
,\
8032 static CRYPTGENRANDOM pCryptGenRandom
= NULL
;
8033 static HCRYPTPROV hCryptProv
= 0;
8036 win32_urandom(PyObject
*self
, PyObject
*args
)
8041 /* Read arguments */
8042 if (! PyArg_ParseTuple(args
, "i:urandom", &howMany
))
8045 return PyErr_Format(PyExc_ValueError
,
8046 "negative argument not allowed");
8048 if (hCryptProv
== 0) {
8049 HINSTANCE hAdvAPI32
= NULL
;
8050 CRYPTACQUIRECONTEXTA pCryptAcquireContext
= NULL
;
8052 /* Obtain handle to the DLL containing CryptoAPI
8053 This should not fail */
8054 hAdvAPI32
= GetModuleHandle("advapi32.dll");
8055 if(hAdvAPI32
== NULL
)
8056 return win32_error("GetModuleHandle", NULL
);
8058 /* Obtain pointers to the CryptoAPI functions
8059 This will fail on some early versions of Win95 */
8060 pCryptAcquireContext
= (CRYPTACQUIRECONTEXTA
)GetProcAddress(
8062 "CryptAcquireContextA");
8063 if (pCryptAcquireContext
== NULL
)
8064 return PyErr_Format(PyExc_NotImplementedError
,
8065 "CryptAcquireContextA not found");
8067 pCryptGenRandom
= (CRYPTGENRANDOM
)GetProcAddress(
8068 hAdvAPI32
, "CryptGenRandom");
8069 if (pCryptGenRandom
== NULL
)
8070 return PyErr_Format(PyExc_NotImplementedError
,
8071 "CryptGenRandom not found");
8073 /* Acquire context */
8074 if (! pCryptAcquireContext(&hCryptProv
, NULL
, NULL
,
8075 PROV_RSA_FULL
, CRYPT_VERIFYCONTEXT
))
8076 return win32_error("CryptAcquireContext", NULL
);
8079 /* Allocate bytes */
8080 result
= PyString_FromStringAndSize(NULL
, howMany
);
8081 if (result
!= NULL
) {
8082 /* Get random data */
8083 if (! pCryptGenRandom(hCryptProv
, howMany
, (unsigned char*)
8084 PyString_AS_STRING(result
))) {
8086 return win32_error("CryptGenRandom", NULL
);
8094 /* Use openssl random routine */
8095 #include <openssl/rand.h>
8096 PyDoc_STRVAR(vms_urandom__doc__
,
8097 "urandom(n) -> str\n\n\
8098 Return a string of n random bytes suitable for cryptographic use.");
8101 vms_urandom(PyObject
*self
, PyObject
*args
)
8106 /* Read arguments */
8107 if (! PyArg_ParseTuple(args
, "i:urandom", &howMany
))
8110 return PyErr_Format(PyExc_ValueError
,
8111 "negative argument not allowed");
8113 /* Allocate bytes */
8114 result
= PyString_FromStringAndSize(NULL
, howMany
);
8115 if (result
!= NULL
) {
8116 /* Get random data */
8117 if (RAND_pseudo_bytes((unsigned char*)
8118 PyString_AS_STRING(result
),
8121 return PyErr_Format(PyExc_ValueError
,
8122 "RAND_pseudo_bytes");
8129 static PyMethodDef posix_methods
[] = {
8130 {"access", posix_access
, METH_VARARGS
, posix_access__doc__
},
8132 {"ttyname", posix_ttyname
, METH_VARARGS
, posix_ttyname__doc__
},
8134 {"chdir", posix_chdir
, METH_VARARGS
, posix_chdir__doc__
},
8136 {"chflags", posix_chflags
, METH_VARARGS
, posix_chflags__doc__
},
8137 #endif /* HAVE_CHFLAGS */
8138 {"chmod", posix_chmod
, METH_VARARGS
, posix_chmod__doc__
},
8140 {"chown", posix_chown
, METH_VARARGS
, posix_chown__doc__
},
8141 #endif /* HAVE_CHOWN */
8142 #ifdef HAVE_LCHFLAGS
8143 {"lchflags", posix_lchflags
, METH_VARARGS
, posix_lchflags__doc__
},
8144 #endif /* HAVE_LCHFLAGS */
8146 {"lchown", posix_lchown
, METH_VARARGS
, posix_lchown__doc__
},
8147 #endif /* HAVE_LCHOWN */
8149 {"chroot", posix_chroot
, METH_VARARGS
, posix_chroot__doc__
},
8152 {"ctermid", posix_ctermid
, METH_NOARGS
, posix_ctermid__doc__
},
8155 {"getcwd", posix_getcwd
, METH_NOARGS
, posix_getcwd__doc__
},
8156 #ifdef Py_USING_UNICODE
8157 {"getcwdu", posix_getcwdu
, METH_NOARGS
, posix_getcwdu__doc__
},
8161 {"link", posix_link
, METH_VARARGS
, posix_link__doc__
},
8162 #endif /* HAVE_LINK */
8163 {"listdir", posix_listdir
, METH_VARARGS
, posix_listdir__doc__
},
8164 {"lstat", posix_lstat
, METH_VARARGS
, posix_lstat__doc__
},
8165 {"mkdir", posix_mkdir
, METH_VARARGS
, posix_mkdir__doc__
},
8167 {"nice", posix_nice
, METH_VARARGS
, posix_nice__doc__
},
8168 #endif /* HAVE_NICE */
8169 #ifdef HAVE_READLINK
8170 {"readlink", posix_readlink
, METH_VARARGS
, posix_readlink__doc__
},
8171 #endif /* HAVE_READLINK */
8172 {"rename", posix_rename
, METH_VARARGS
, posix_rename__doc__
},
8173 {"rmdir", posix_rmdir
, METH_VARARGS
, posix_rmdir__doc__
},
8174 {"stat", posix_stat
, METH_VARARGS
, posix_stat__doc__
},
8175 {"stat_float_times", stat_float_times
, METH_VARARGS
, stat_float_times__doc__
},
8177 {"symlink", posix_symlink
, METH_VARARGS
, posix_symlink__doc__
},
8178 #endif /* HAVE_SYMLINK */
8180 {"system", posix_system
, METH_VARARGS
, posix_system__doc__
},
8182 {"umask", posix_umask
, METH_VARARGS
, posix_umask__doc__
},
8184 {"uname", posix_uname
, METH_NOARGS
, posix_uname__doc__
},
8185 #endif /* HAVE_UNAME */
8186 {"unlink", posix_unlink
, METH_VARARGS
, posix_unlink__doc__
},
8187 {"remove", posix_unlink
, METH_VARARGS
, posix_remove__doc__
},
8188 {"utime", posix_utime
, METH_VARARGS
, posix_utime__doc__
},
8190 {"times", posix_times
, METH_NOARGS
, posix_times__doc__
},
8191 #endif /* HAVE_TIMES */
8192 {"_exit", posix__exit
, METH_VARARGS
, posix__exit__doc__
},
8194 {"execv", posix_execv
, METH_VARARGS
, posix_execv__doc__
},
8195 {"execve", posix_execve
, METH_VARARGS
, posix_execve__doc__
},
8196 #endif /* HAVE_EXECV */
8198 {"spawnv", posix_spawnv
, METH_VARARGS
, posix_spawnv__doc__
},
8199 {"spawnve", posix_spawnve
, METH_VARARGS
, posix_spawnve__doc__
},
8200 #if defined(PYOS_OS2)
8201 {"spawnvp", posix_spawnvp
, METH_VARARGS
, posix_spawnvp__doc__
},
8202 {"spawnvpe", posix_spawnvpe
, METH_VARARGS
, posix_spawnvpe__doc__
},
8203 #endif /* PYOS_OS2 */
8204 #endif /* HAVE_SPAWNV */
8206 {"fork1", posix_fork1
, METH_NOARGS
, posix_fork1__doc__
},
8207 #endif /* HAVE_FORK1 */
8209 {"fork", posix_fork
, METH_NOARGS
, posix_fork__doc__
},
8210 #endif /* HAVE_FORK */
8211 #if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
8212 {"openpty", posix_openpty
, METH_NOARGS
, posix_openpty__doc__
},
8213 #endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
8215 {"forkpty", posix_forkpty
, METH_NOARGS
, posix_forkpty__doc__
},
8216 #endif /* HAVE_FORKPTY */
8218 {"getegid", posix_getegid
, METH_NOARGS
, posix_getegid__doc__
},
8219 #endif /* HAVE_GETEGID */
8221 {"geteuid", posix_geteuid
, METH_NOARGS
, posix_geteuid__doc__
},
8222 #endif /* HAVE_GETEUID */
8224 {"getgid", posix_getgid
, METH_NOARGS
, posix_getgid__doc__
},
8225 #endif /* HAVE_GETGID */
8226 #ifdef HAVE_GETGROUPS
8227 {"getgroups", posix_getgroups
, METH_NOARGS
, posix_getgroups__doc__
},
8229 {"getpid", posix_getpid
, METH_NOARGS
, posix_getpid__doc__
},
8231 {"getpgrp", posix_getpgrp
, METH_NOARGS
, posix_getpgrp__doc__
},
8232 #endif /* HAVE_GETPGRP */
8234 {"getppid", posix_getppid
, METH_NOARGS
, posix_getppid__doc__
},
8235 #endif /* HAVE_GETPPID */
8237 {"getuid", posix_getuid
, METH_NOARGS
, posix_getuid__doc__
},
8238 #endif /* HAVE_GETUID */
8239 #ifdef HAVE_GETLOGIN
8240 {"getlogin", posix_getlogin
, METH_NOARGS
, posix_getlogin__doc__
},
8243 {"kill", posix_kill
, METH_VARARGS
, posix_kill__doc__
},
8244 #endif /* HAVE_KILL */
8246 {"killpg", posix_killpg
, METH_VARARGS
, posix_killpg__doc__
},
8247 #endif /* HAVE_KILLPG */
8249 {"plock", posix_plock
, METH_VARARGS
, posix_plock__doc__
},
8250 #endif /* HAVE_PLOCK */
8252 {"popen", posix_popen
, METH_VARARGS
, posix_popen__doc__
},
8254 {"popen2", win32_popen2
, METH_VARARGS
},
8255 {"popen3", win32_popen3
, METH_VARARGS
},
8256 {"popen4", win32_popen4
, METH_VARARGS
},
8257 {"startfile", win32_startfile
, METH_VARARGS
, win32_startfile__doc__
},
8259 #if defined(PYOS_OS2) && defined(PYCC_GCC)
8260 {"popen2", os2emx_popen2
, METH_VARARGS
},
8261 {"popen3", os2emx_popen3
, METH_VARARGS
},
8262 {"popen4", os2emx_popen4
, METH_VARARGS
},
8265 #endif /* HAVE_POPEN */
8267 {"setuid", posix_setuid
, METH_VARARGS
, posix_setuid__doc__
},
8268 #endif /* HAVE_SETUID */
8270 {"seteuid", posix_seteuid
, METH_VARARGS
, posix_seteuid__doc__
},
8271 #endif /* HAVE_SETEUID */
8273 {"setegid", posix_setegid
, METH_VARARGS
, posix_setegid__doc__
},
8274 #endif /* HAVE_SETEGID */
8275 #ifdef HAVE_SETREUID
8276 {"setreuid", posix_setreuid
, METH_VARARGS
, posix_setreuid__doc__
},
8277 #endif /* HAVE_SETREUID */
8278 #ifdef HAVE_SETREGID
8279 {"setregid", posix_setregid
, METH_VARARGS
, posix_setregid__doc__
},
8280 #endif /* HAVE_SETREGID */
8282 {"setgid", posix_setgid
, METH_VARARGS
, posix_setgid__doc__
},
8283 #endif /* HAVE_SETGID */
8284 #ifdef HAVE_SETGROUPS
8285 {"setgroups", posix_setgroups
, METH_O
, posix_setgroups__doc__
},
8286 #endif /* HAVE_SETGROUPS */
8288 {"getpgid", posix_getpgid
, METH_VARARGS
, posix_getpgid__doc__
},
8289 #endif /* HAVE_GETPGID */
8291 {"setpgrp", posix_setpgrp
, METH_NOARGS
, posix_setpgrp__doc__
},
8292 #endif /* HAVE_SETPGRP */
8294 {"wait", posix_wait
, METH_NOARGS
, posix_wait__doc__
},
8295 #endif /* HAVE_WAIT */
8297 {"wait3", posix_wait3
, METH_VARARGS
, posix_wait3__doc__
},
8298 #endif /* HAVE_WAIT3 */
8300 {"wait4", posix_wait4
, METH_VARARGS
, posix_wait4__doc__
},
8301 #endif /* HAVE_WAIT4 */
8302 #if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
8303 {"waitpid", posix_waitpid
, METH_VARARGS
, posix_waitpid__doc__
},
8304 #endif /* HAVE_WAITPID */
8306 {"getsid", posix_getsid
, METH_VARARGS
, posix_getsid__doc__
},
8307 #endif /* HAVE_GETSID */
8309 {"setsid", posix_setsid
, METH_NOARGS
, posix_setsid__doc__
},
8310 #endif /* HAVE_SETSID */
8312 {"setpgid", posix_setpgid
, METH_VARARGS
, posix_setpgid__doc__
},
8313 #endif /* HAVE_SETPGID */
8314 #ifdef HAVE_TCGETPGRP
8315 {"tcgetpgrp", posix_tcgetpgrp
, METH_VARARGS
, posix_tcgetpgrp__doc__
},
8316 #endif /* HAVE_TCGETPGRP */
8317 #ifdef HAVE_TCSETPGRP
8318 {"tcsetpgrp", posix_tcsetpgrp
, METH_VARARGS
, posix_tcsetpgrp__doc__
},
8319 #endif /* HAVE_TCSETPGRP */
8320 {"open", posix_open
, METH_VARARGS
, posix_open__doc__
},
8321 {"close", posix_close
, METH_VARARGS
, posix_close__doc__
},
8322 {"dup", posix_dup
, METH_VARARGS
, posix_dup__doc__
},
8323 {"dup2", posix_dup2
, METH_VARARGS
, posix_dup2__doc__
},
8324 {"lseek", posix_lseek
, METH_VARARGS
, posix_lseek__doc__
},
8325 {"read", posix_read
, METH_VARARGS
, posix_read__doc__
},
8326 {"write", posix_write
, METH_VARARGS
, posix_write__doc__
},
8327 {"fstat", posix_fstat
, METH_VARARGS
, posix_fstat__doc__
},
8328 {"fdopen", posix_fdopen
, METH_VARARGS
, posix_fdopen__doc__
},
8329 {"isatty", posix_isatty
, METH_VARARGS
, posix_isatty__doc__
},
8331 {"pipe", posix_pipe
, METH_NOARGS
, posix_pipe__doc__
},
8334 {"mkfifo", posix_mkfifo
, METH_VARARGS
, posix_mkfifo__doc__
},
8336 #if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
8337 {"mknod", posix_mknod
, METH_VARARGS
, posix_mknod__doc__
},
8339 #ifdef HAVE_DEVICE_MACROS
8340 {"major", posix_major
, METH_VARARGS
, posix_major__doc__
},
8341 {"minor", posix_minor
, METH_VARARGS
, posix_minor__doc__
},
8342 {"makedev", posix_makedev
, METH_VARARGS
, posix_makedev__doc__
},
8344 #ifdef HAVE_FTRUNCATE
8345 {"ftruncate", posix_ftruncate
, METH_VARARGS
, posix_ftruncate__doc__
},
8348 {"putenv", posix_putenv
, METH_VARARGS
, posix_putenv__doc__
},
8350 #ifdef HAVE_UNSETENV
8351 {"unsetenv", posix_unsetenv
, METH_VARARGS
, posix_unsetenv__doc__
},
8353 #ifdef HAVE_STRERROR
8354 {"strerror", posix_strerror
, METH_VARARGS
, posix_strerror__doc__
},
8357 {"fchdir", posix_fchdir
, METH_O
, posix_fchdir__doc__
},
8360 {"fsync", posix_fsync
, METH_O
, posix_fsync__doc__
},
8362 #ifdef HAVE_FDATASYNC
8363 {"fdatasync", posix_fdatasync
, METH_O
, posix_fdatasync__doc__
},
8365 #ifdef HAVE_SYS_WAIT_H
8367 {"WCOREDUMP", posix_WCOREDUMP
, METH_VARARGS
, posix_WCOREDUMP__doc__
},
8368 #endif /* WCOREDUMP */
8370 {"WIFCONTINUED",posix_WIFCONTINUED
, METH_VARARGS
, posix_WIFCONTINUED__doc__
},
8371 #endif /* WIFCONTINUED */
8373 {"WIFSTOPPED", posix_WIFSTOPPED
, METH_VARARGS
, posix_WIFSTOPPED__doc__
},
8374 #endif /* WIFSTOPPED */
8376 {"WIFSIGNALED", posix_WIFSIGNALED
, METH_VARARGS
, posix_WIFSIGNALED__doc__
},
8377 #endif /* WIFSIGNALED */
8379 {"WIFEXITED", posix_WIFEXITED
, METH_VARARGS
, posix_WIFEXITED__doc__
},
8380 #endif /* WIFEXITED */
8382 {"WEXITSTATUS", posix_WEXITSTATUS
, METH_VARARGS
, posix_WEXITSTATUS__doc__
},
8383 #endif /* WEXITSTATUS */
8385 {"WTERMSIG", posix_WTERMSIG
, METH_VARARGS
, posix_WTERMSIG__doc__
},
8386 #endif /* WTERMSIG */
8388 {"WSTOPSIG", posix_WSTOPSIG
, METH_VARARGS
, posix_WSTOPSIG__doc__
},
8389 #endif /* WSTOPSIG */
8390 #endif /* HAVE_SYS_WAIT_H */
8391 #if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
8392 {"fstatvfs", posix_fstatvfs
, METH_VARARGS
, posix_fstatvfs__doc__
},
8394 #if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
8395 {"statvfs", posix_statvfs
, METH_VARARGS
, posix_statvfs__doc__
},
8398 {"tmpfile", posix_tmpfile
, METH_NOARGS
, posix_tmpfile__doc__
},
8401 {"tempnam", posix_tempnam
, METH_VARARGS
, posix_tempnam__doc__
},
8404 {"tmpnam", posix_tmpnam
, METH_NOARGS
, posix_tmpnam__doc__
},
8407 {"confstr", posix_confstr
, METH_VARARGS
, posix_confstr__doc__
},
8410 {"sysconf", posix_sysconf
, METH_VARARGS
, posix_sysconf__doc__
},
8412 #ifdef HAVE_FPATHCONF
8413 {"fpathconf", posix_fpathconf
, METH_VARARGS
, posix_fpathconf__doc__
},
8415 #ifdef HAVE_PATHCONF
8416 {"pathconf", posix_pathconf
, METH_VARARGS
, posix_pathconf__doc__
},
8418 {"abort", posix_abort
, METH_NOARGS
, posix_abort__doc__
},
8420 {"_getfullpathname", posix__getfullpathname
, METH_VARARGS
, NULL
},
8422 #ifdef HAVE_GETLOADAVG
8423 {"getloadavg", posix_getloadavg
, METH_NOARGS
, posix_getloadavg__doc__
},
8426 {"urandom", win32_urandom
, METH_VARARGS
, win32_urandom__doc__
},
8429 {"urandom", vms_urandom
, METH_VARARGS
, vms_urandom__doc__
},
8431 {NULL
, NULL
} /* Sentinel */
8436 ins(PyObject
*module
, char *symbol
, long value
)
8438 return PyModule_AddIntConstant(module
, symbol
, value
);
8441 #if defined(PYOS_OS2)
8442 /* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
8443 static int insertvalues(PyObject
*module
)
8446 ULONG values
[QSV_MAX
+1];
8450 Py_BEGIN_ALLOW_THREADS
8451 rc
= DosQuerySysInfo(1L, QSV_MAX
, &values
[1], sizeof(ULONG
) * QSV_MAX
);
8452 Py_END_ALLOW_THREADS
8454 if (rc
!= NO_ERROR
) {
8459 if (ins(module
, "meminstalled", values
[QSV_TOTPHYSMEM
])) return -1;
8460 if (ins(module
, "memkernel", values
[QSV_TOTRESMEM
])) return -1;
8461 if (ins(module
, "memvirtual", values
[QSV_TOTAVAILMEM
])) return -1;
8462 if (ins(module
, "maxpathlen", values
[QSV_MAX_PATH_LENGTH
])) return -1;
8463 if (ins(module
, "maxnamelen", values
[QSV_MAX_COMP_LENGTH
])) return -1;
8464 if (ins(module
, "revision", values
[QSV_VERSION_REVISION
])) return -1;
8465 if (ins(module
, "timeslice", values
[QSV_MIN_SLICE
])) return -1;
8467 switch (values
[QSV_VERSION_MINOR
]) {
8468 case 0: ver
= "2.00"; break;
8469 case 10: ver
= "2.10"; break;
8470 case 11: ver
= "2.11"; break;
8471 case 30: ver
= "3.00"; break;
8472 case 40: ver
= "4.00"; break;
8473 case 50: ver
= "5.00"; break;
8475 PyOS_snprintf(tmp
, sizeof(tmp
),
8476 "%d-%d", values
[QSV_VERSION_MAJOR
],
8477 values
[QSV_VERSION_MINOR
]);
8481 /* Add Indicator of the Version of the Operating System */
8482 if (PyModule_AddStringConstant(module
, "version", tmp
) < 0)
8485 /* Add Indicator of Which Drive was Used to Boot the System */
8486 tmp
[0] = 'A' + values
[QSV_BOOT_DRIVE
] - 1;
8490 return PyModule_AddStringConstant(module
, "bootdrive", tmp
);
8495 all_ins(PyObject
*d
)
8498 if (ins(d
, "F_OK", (long)F_OK
)) return -1;
8501 if (ins(d
, "R_OK", (long)R_OK
)) return -1;
8504 if (ins(d
, "W_OK", (long)W_OK
)) return -1;
8507 if (ins(d
, "X_OK", (long)X_OK
)) return -1;
8510 if (ins(d
, "NGROUPS_MAX", (long)NGROUPS_MAX
)) return -1;
8513 if (ins(d
, "TMP_MAX", (long)TMP_MAX
)) return -1;
8516 if (ins(d
, "WCONTINUED", (long)WCONTINUED
)) return -1;
8519 if (ins(d
, "WNOHANG", (long)WNOHANG
)) return -1;
8522 if (ins(d
, "WUNTRACED", (long)WUNTRACED
)) return -1;
8525 if (ins(d
, "O_RDONLY", (long)O_RDONLY
)) return -1;
8528 if (ins(d
, "O_WRONLY", (long)O_WRONLY
)) return -1;
8531 if (ins(d
, "O_RDWR", (long)O_RDWR
)) return -1;
8534 if (ins(d
, "O_NDELAY", (long)O_NDELAY
)) return -1;
8537 if (ins(d
, "O_NONBLOCK", (long)O_NONBLOCK
)) return -1;
8540 if (ins(d
, "O_APPEND", (long)O_APPEND
)) return -1;
8543 if (ins(d
, "O_DSYNC", (long)O_DSYNC
)) return -1;
8546 if (ins(d
, "O_RSYNC", (long)O_RSYNC
)) return -1;
8549 if (ins(d
, "O_SYNC", (long)O_SYNC
)) return -1;
8552 if (ins(d
, "O_NOCTTY", (long)O_NOCTTY
)) return -1;
8555 if (ins(d
, "O_CREAT", (long)O_CREAT
)) return -1;
8558 if (ins(d
, "O_EXCL", (long)O_EXCL
)) return -1;
8561 if (ins(d
, "O_TRUNC", (long)O_TRUNC
)) return -1;
8564 if (ins(d
, "O_BINARY", (long)O_BINARY
)) return -1;
8567 if (ins(d
, "O_TEXT", (long)O_TEXT
)) return -1;
8570 if (ins(d
, "O_LARGEFILE", (long)O_LARGEFILE
)) return -1;
8573 if (ins(d
, "O_SHLOCK", (long)O_SHLOCK
)) return -1;
8576 if (ins(d
, "O_EXLOCK", (long)O_EXLOCK
)) return -1;
8581 /* Don't inherit in child processes. */
8582 if (ins(d
, "O_NOINHERIT", (long)O_NOINHERIT
)) return -1;
8584 #ifdef _O_SHORT_LIVED
8585 /* Optimize for short life (keep in memory). */
8586 /* MS forgot to define this one with a non-underscore form too. */
8587 if (ins(d
, "O_SHORT_LIVED", (long)_O_SHORT_LIVED
)) return -1;
8590 /* Automatically delete when last handle is closed. */
8591 if (ins(d
, "O_TEMPORARY", (long)O_TEMPORARY
)) return -1;
8594 /* Optimize for random access. */
8595 if (ins(d
, "O_RANDOM", (long)O_RANDOM
)) return -1;
8598 /* Optimize for sequential access. */
8599 if (ins(d
, "O_SEQUENTIAL", (long)O_SEQUENTIAL
)) return -1;
8602 /* GNU extensions. */
8604 /* Direct disk access. */
8605 if (ins(d
, "O_DIRECT", (long)O_DIRECT
)) return -1;
8608 /* Must be a directory. */
8609 if (ins(d
, "O_DIRECTORY", (long)O_DIRECTORY
)) return -1;
8612 /* Do not follow links. */
8613 if (ins(d
, "O_NOFOLLOW", (long)O_NOFOLLOW
)) return -1;
8616 /* These come from sysexits.h */
8618 if (ins(d
, "EX_OK", (long)EX_OK
)) return -1;
8621 if (ins(d
, "EX_USAGE", (long)EX_USAGE
)) return -1;
8622 #endif /* EX_USAGE */
8624 if (ins(d
, "EX_DATAERR", (long)EX_DATAERR
)) return -1;
8625 #endif /* EX_DATAERR */
8627 if (ins(d
, "EX_NOINPUT", (long)EX_NOINPUT
)) return -1;
8628 #endif /* EX_NOINPUT */
8630 if (ins(d
, "EX_NOUSER", (long)EX_NOUSER
)) return -1;
8631 #endif /* EX_NOUSER */
8633 if (ins(d
, "EX_NOHOST", (long)EX_NOHOST
)) return -1;
8634 #endif /* EX_NOHOST */
8635 #ifdef EX_UNAVAILABLE
8636 if (ins(d
, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE
)) return -1;
8637 #endif /* EX_UNAVAILABLE */
8639 if (ins(d
, "EX_SOFTWARE", (long)EX_SOFTWARE
)) return -1;
8640 #endif /* EX_SOFTWARE */
8642 if (ins(d
, "EX_OSERR", (long)EX_OSERR
)) return -1;
8643 #endif /* EX_OSERR */
8645 if (ins(d
, "EX_OSFILE", (long)EX_OSFILE
)) return -1;
8646 #endif /* EX_OSFILE */
8648 if (ins(d
, "EX_CANTCREAT", (long)EX_CANTCREAT
)) return -1;
8649 #endif /* EX_CANTCREAT */
8651 if (ins(d
, "EX_IOERR", (long)EX_IOERR
)) return -1;
8652 #endif /* EX_IOERR */
8654 if (ins(d
, "EX_TEMPFAIL", (long)EX_TEMPFAIL
)) return -1;
8655 #endif /* EX_TEMPFAIL */
8657 if (ins(d
, "EX_PROTOCOL", (long)EX_PROTOCOL
)) return -1;
8658 #endif /* EX_PROTOCOL */
8660 if (ins(d
, "EX_NOPERM", (long)EX_NOPERM
)) return -1;
8661 #endif /* EX_NOPERM */
8663 if (ins(d
, "EX_CONFIG", (long)EX_CONFIG
)) return -1;
8664 #endif /* EX_CONFIG */
8666 if (ins(d
, "EX_NOTFOUND", (long)EX_NOTFOUND
)) return -1;
8667 #endif /* EX_NOTFOUND */
8670 #if defined(PYOS_OS2) && defined(PYCC_GCC)
8671 if (ins(d
, "P_WAIT", (long)P_WAIT
)) return -1;
8672 if (ins(d
, "P_NOWAIT", (long)P_NOWAIT
)) return -1;
8673 if (ins(d
, "P_OVERLAY", (long)P_OVERLAY
)) return -1;
8674 if (ins(d
, "P_DEBUG", (long)P_DEBUG
)) return -1;
8675 if (ins(d
, "P_SESSION", (long)P_SESSION
)) return -1;
8676 if (ins(d
, "P_DETACH", (long)P_DETACH
)) return -1;
8677 if (ins(d
, "P_PM", (long)P_PM
)) return -1;
8678 if (ins(d
, "P_DEFAULT", (long)P_DEFAULT
)) return -1;
8679 if (ins(d
, "P_MINIMIZE", (long)P_MINIMIZE
)) return -1;
8680 if (ins(d
, "P_MAXIMIZE", (long)P_MAXIMIZE
)) return -1;
8681 if (ins(d
, "P_FULLSCREEN", (long)P_FULLSCREEN
)) return -1;
8682 if (ins(d
, "P_WINDOWED", (long)P_WINDOWED
)) return -1;
8683 if (ins(d
, "P_FOREGROUND", (long)P_FOREGROUND
)) return -1;
8684 if (ins(d
, "P_BACKGROUND", (long)P_BACKGROUND
)) return -1;
8685 if (ins(d
, "P_NOCLOSE", (long)P_NOCLOSE
)) return -1;
8686 if (ins(d
, "P_NOSESSION", (long)P_NOSESSION
)) return -1;
8687 if (ins(d
, "P_QUOTE", (long)P_QUOTE
)) return -1;
8688 if (ins(d
, "P_TILDE", (long)P_TILDE
)) return -1;
8689 if (ins(d
, "P_UNRELATED", (long)P_UNRELATED
)) return -1;
8690 if (ins(d
, "P_DEBUGDESC", (long)P_DEBUGDESC
)) return -1;
8692 if (ins(d
, "P_WAIT", (long)_P_WAIT
)) return -1;
8693 if (ins(d
, "P_NOWAIT", (long)_P_NOWAIT
)) return -1;
8694 if (ins(d
, "P_OVERLAY", (long)_OLD_P_OVERLAY
)) return -1;
8695 if (ins(d
, "P_NOWAITO", (long)_P_NOWAITO
)) return -1;
8696 if (ins(d
, "P_DETACH", (long)_P_DETACH
)) return -1;
8700 #if defined(PYOS_OS2)
8701 if (insertvalues(d
)) return -1;
8707 #if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
8708 #define INITFUNC initnt
8709 #define MODNAME "nt"
8711 #elif defined(PYOS_OS2)
8712 #define INITFUNC initos2
8713 #define MODNAME "os2"
8716 #define INITFUNC initposix
8717 #define MODNAME "posix"
8725 m
= Py_InitModule3(MODNAME
,
8731 /* Initialize environ dictionary */
8732 v
= convertenviron();
8734 if (v
== NULL
|| PyModule_AddObject(m
, "environ", v
) != 0)
8741 if (setup_confname_tables(m
))
8744 Py_INCREF(PyExc_OSError
);
8745 PyModule_AddObject(m
, "error", PyExc_OSError
);
8748 if (posix_putenv_garbage
== NULL
)
8749 posix_putenv_garbage
= PyDict_New();
8753 stat_result_desc
.name
= MODNAME
".stat_result";
8754 stat_result_desc
.fields
[7].name
= PyStructSequence_UnnamedField
;
8755 stat_result_desc
.fields
[8].name
= PyStructSequence_UnnamedField
;
8756 stat_result_desc
.fields
[9].name
= PyStructSequence_UnnamedField
;
8757 PyStructSequence_InitType(&StatResultType
, &stat_result_desc
);
8758 structseq_new
= StatResultType
.tp_new
;
8759 StatResultType
.tp_new
= statresult_new
;
8761 statvfs_result_desc
.name
= MODNAME
".statvfs_result";
8762 PyStructSequence_InitType(&StatVFSResultType
, &statvfs_result_desc
);
8764 Py_INCREF((PyObject
*) &StatResultType
);
8765 PyModule_AddObject(m
, "stat_result", (PyObject
*) &StatResultType
);
8766 Py_INCREF((PyObject
*) &StatVFSResultType
);
8767 PyModule_AddObject(m
, "statvfs_result",
8768 (PyObject
*) &StatVFSResultType
);
8773 * Step 2 of weak-linking support on Mac OS X.
8775 * The code below removes functions that are not available on the
8776 * currently active platform.
8778 * This block allow one to use a python binary that was build on
8779 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
8782 #ifdef HAVE_FSTATVFS
8783 if (fstatvfs
== NULL
) {
8784 if (PyObject_DelAttrString(m
, "fstatvfs") == -1) {
8788 #endif /* HAVE_FSTATVFS */
8791 if (statvfs
== NULL
) {
8792 if (PyObject_DelAttrString(m
, "statvfs") == -1) {
8796 #endif /* HAVE_STATVFS */
8799 if (lchown
== NULL
) {
8800 if (PyObject_DelAttrString(m
, "lchown") == -1) {
8804 #endif /* HAVE_LCHOWN */
8807 #endif /* __APPLE__ */