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 */
17 #include "structseq.h"
21 #endif /* defined(__VMS) */
23 PyDoc_STRVAR(posix__doc__
,
24 "This module provides access to operating system functionality that is\n\
25 standardized by the C Standard and the POSIX standard (a thinly\n\
26 disguised Unix interface). Refer to the library manual and\n\
27 corresponding Unix manual entries for more information on calls.");
29 #ifndef Py_USING_UNICODE
30 /* This is used in signatures of functions. */
31 #define Py_UNICODE void
36 #define INCL_DOSERRORS
37 #define INCL_DOSPROCESS
49 #include <sys/types.h>
52 #ifdef HAVE_SYS_WAIT_H
53 #include <sys/wait.h> /* For WNOHANG */
60 #endif /* HAVE_FCNTL_H */
66 #ifdef HAVE_SYSEXITS_H
68 #endif /* HAVE_SYSEXITS_H */
70 #ifdef HAVE_SYS_LOADAVG_H
71 #include <sys/loadavg.h>
74 /* Various compilers have only certain posix functions */
75 /* XXX Gosh I wish these were all moved into pyconfig.h */
76 #if defined(PYCC_VACPP) && defined(PYOS_OS2)
79 #if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
81 #define HAVE_OPENDIR 1
89 #ifdef __BORLANDC__ /* Borland compiler */
92 #define HAVE_OPENDIR 1
98 #ifdef _MSC_VER /* Microsoft compiler */
100 #define HAVE_SPAWNV 1
104 #define HAVE_SYSTEM 1
107 #define fsync _commit
109 #if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
110 /* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
111 #else /* all other compilers */
112 /* Unix functions that the configure script doesn't check for */
115 #if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
118 #define HAVE_GETCWD 1
119 #define HAVE_GETEGID 1
120 #define HAVE_GETEUID 1
121 #define HAVE_GETGID 1
122 #define HAVE_GETPPID 1
123 #define HAVE_GETUID 1
125 #define HAVE_OPENDIR 1
130 #define HAVE_SYSTEM 1
132 #define HAVE_TTYNAME 1
133 #endif /* PYOS_OS2 && PYCC_GCC && __VMS */
134 #endif /* _MSC_VER */
135 #endif /* __BORLANDC__ */
136 #endif /* ! __WATCOMC__ || __QNX__ */
137 #endif /* ! __IBMC__ */
141 #if defined(__sgi)&&_COMPILER_VERSION>=700
142 /* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
144 extern char *ctermid_r(char *);
147 #ifndef HAVE_UNISTD_H
148 #if defined(PYCC_VACPP)
149 extern int mkdir(char *);
151 #if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
152 extern int mkdir(const char *);
154 extern int mkdir(const char *, mode_t
);
157 #if defined(__IBMC__) || defined(__IBMCPP__)
158 extern int chdir(char *);
159 extern int rmdir(char *);
161 extern int chdir(const char *);
162 extern int rmdir(const char *);
165 extern int chmod(const char *, int);
167 extern int chmod(const char *, mode_t
);
169 extern int chown(const char *, uid_t
, gid_t
);
170 extern char *getcwd(char *, int);
171 extern char *strerror(int);
172 extern int link(const char *, const char *);
173 extern int rename(const char *, const char *);
174 extern int stat(const char *, struct stat
*);
175 extern int unlink(const char *);
176 extern int pclose(FILE *);
178 extern int symlink(const char *, const char *);
179 #endif /* HAVE_SYMLINK */
181 extern int lstat(const char *, struct stat
*);
182 #endif /* HAVE_LSTAT */
183 #endif /* !HAVE_UNISTD_H */
185 #endif /* !_MSC_VER */
189 #endif /* HAVE_UTIME_H */
191 #ifdef HAVE_SYS_UTIME_H
192 #include <sys/utime.h>
193 #define HAVE_UTIME_H /* pretend we do for the rest of this file */
194 #endif /* HAVE_SYS_UTIME_H */
196 #ifdef HAVE_SYS_TIMES_H
197 #include <sys/times.h>
198 #endif /* HAVE_SYS_TIMES_H */
200 #ifdef HAVE_SYS_PARAM_H
201 #include <sys/param.h>
202 #endif /* HAVE_SYS_PARAM_H */
204 #ifdef HAVE_SYS_UTSNAME_H
205 #include <sys/utsname.h>
206 #endif /* HAVE_SYS_UTSNAME_H */
210 #define NAMLEN(dirent) strlen((dirent)->d_name)
212 #if defined(__WATCOMC__) && !defined(__QNX__)
214 #define NAMLEN(dirent) strlen((dirent)->d_name)
216 #define dirent direct
217 #define NAMLEN(dirent) (dirent)->d_namlen
219 #ifdef HAVE_SYS_NDIR_H
220 #include <sys/ndir.h>
222 #ifdef HAVE_SYS_DIR_H
235 #define _WIN32_WINNT 0x0400 /* Needed for CryptoAPI on some systems */
237 #include <shellapi.h> /* for ShellExecute() */
239 #define pclose _pclose
240 #endif /* _MSC_VER */
242 #if defined(PYCC_VACPP) && defined(PYOS_OS2)
247 #define MAXPATHLEN 1024
248 #endif /* MAXPATHLEN */
251 /* Emulate some macros on systems that have a union instead of macros */
254 #define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
258 #define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
262 #define WTERMSIG(u_wait) ((u_wait).w_termsig)
265 #endif /* UNION_WAIT */
267 /* Don't use the "_r" form if we don't need it (also, won't have a
268 prototype for it, at least on Solaris -- maybe others as well?). */
269 #if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
270 #define USE_CTERMID_R
273 #if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
277 /* choose the appropriate stat and fstat functions and return structs */
279 #if defined(MS_WIN64) || defined(MS_WINDOWS)
280 # define STAT win32_stat
281 # define FSTAT win32_fstat
282 # define STRUCT_STAT struct win32_stat
286 # define STRUCT_STAT struct stat
289 #if defined(MAJOR_IN_MKDEV)
290 #include <sys/mkdev.h>
292 #if defined(MAJOR_IN_SYSMACROS)
293 #include <sys/sysmacros.h>
295 #if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
296 #include <sys/mkdev.h>
300 /* Return a dictionary corresponding to the POSIX environment table */
301 #ifdef WITH_NEXT_FRAMEWORK
302 /* On Darwin/MacOSX a shared library or framework has no access to
303 ** environ directly, we must obtain it with _NSGetEnviron().
305 #include <crt_externs.h>
306 static char **environ
;
307 #elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
308 extern char **environ
;
309 #endif /* !_MSC_VER */
319 #ifdef WITH_NEXT_FRAMEWORK
321 environ
= *_NSGetEnviron();
325 /* This part ignores errors */
326 for (e
= environ
; *e
!= NULL
; e
++) {
329 char *p
= strchr(*e
, '=');
332 k
= PyString_FromStringAndSize(*e
, (int)(p
-*e
));
337 v
= PyString_FromString(p
+1);
343 if (PyDict_GetItem(d
, k
) == NULL
) {
344 if (PyDict_SetItem(d
, k
, v
) != 0)
350 #if defined(PYOS_OS2)
353 char buffer
[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
355 rc
= DosQueryExtLIBPATH(buffer
, BEGIN_LIBPATH
);
356 if (rc
== NO_ERROR
) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
357 PyObject
*v
= PyString_FromString(buffer
);
358 PyDict_SetItemString(d
, "BEGINLIBPATH", v
);
361 rc
= DosQueryExtLIBPATH(buffer
, END_LIBPATH
);
362 if (rc
== NO_ERROR
) { /* (not a typo, envname is NOT 'END_LIBPATH') */
363 PyObject
*v
= PyString_FromString(buffer
);
364 PyDict_SetItemString(d
, "ENDLIBPATH", v
);
373 /* Set a POSIX-specific error from errno, and return NULL */
378 return PyErr_SetFromErrno(PyExc_OSError
);
381 posix_error_with_filename(char* name
)
383 return PyErr_SetFromErrnoWithFilename(PyExc_OSError
, name
);
386 #ifdef Py_WIN_WIDE_FILENAMES
388 posix_error_with_unicode_filename(Py_UNICODE
* name
)
390 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError
, name
);
392 #endif /* Py_WIN_WIDE_FILENAMES */
396 posix_error_with_allocated_filename(char* name
)
398 PyObject
*rc
= PyErr_SetFromErrnoWithFilename(PyExc_OSError
, name
);
405 win32_error(char* function
, char* filename
)
407 /* XXX We should pass the function name along in the future.
408 (_winreg.c also wants to pass the function name.)
409 This would however require an additional param to the
410 Windows error object, which is non-trivial.
412 errno
= GetLastError();
414 return PyErr_SetFromWindowsErrWithFilename(errno
, filename
);
416 return PyErr_SetFromWindowsErr(errno
);
419 #ifdef Py_WIN_WIDE_FILENAMES
421 win32_error_unicode(char* function
, Py_UNICODE
* filename
)
423 /* XXX - see win32_error for comments on 'function' */
424 errno
= GetLastError();
426 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno
, filename
);
428 return PyErr_SetFromWindowsErr(errno
);
431 static PyObject
*_PyUnicode_FromFileSystemEncodedObject(register PyObject
*obj
)
433 /* XXX Perhaps we should make this API an alias of
434 PyObject_Unicode() instead ?! */
435 if (PyUnicode_CheckExact(obj
)) {
439 if (PyUnicode_Check(obj
)) {
440 /* For a Unicode subtype that's not a Unicode object,
441 return a true Unicode object with the same data. */
442 return PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(obj
),
443 PyUnicode_GET_SIZE(obj
));
445 return PyUnicode_FromEncodedObject(obj
,
446 Py_FileSystemDefaultEncoding
,
450 #endif /* Py_WIN_WIDE_FILENAMES */
454 #if defined(PYOS_OS2)
455 /**********************************************************************
456 * Helper Function to Trim and Format OS/2 Messages
457 **********************************************************************/
459 os2_formatmsg(char *msgbuf
, int msglen
, char *reason
)
461 msgbuf
[msglen
] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
463 if (strlen(msgbuf
) > 0) { /* If Non-Empty Msg, Trim CRLF */
464 char *lastc
= &msgbuf
[ strlen(msgbuf
)-1 ];
466 while (lastc
> msgbuf
&& isspace(Py_CHARMASK(*lastc
)))
467 *lastc
-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
470 /* Add Optional Reason Text */
472 strcat(msgbuf
, " : ");
473 strcat(msgbuf
, reason
);
477 /**********************************************************************
478 * Decode an OS/2 Operating System Error Code
480 * A convenience function to lookup an OS/2 error code and return a
481 * text message we can use to raise a Python exception.
484 * The messages for errors returned from the OS/2 kernel reside in
485 * the file OSO001.MSG in the \OS2 directory hierarchy.
487 **********************************************************************/
489 os2_strerror(char *msgbuf
, int msgbuflen
, int errorcode
, char *reason
)
494 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
495 Py_BEGIN_ALLOW_THREADS
496 rc
= DosGetMessage(NULL
, 0, msgbuf
, msgbuflen
,
497 errorcode
, "oso001.msg", &msglen
);
501 os2_formatmsg(msgbuf
, msglen
, reason
);
503 PyOS_snprintf(msgbuf
, msgbuflen
,
504 "unknown OS error #%d", errorcode
);
509 /* Set an OS/2-specific error and return NULL. OS/2 kernel
510 errors are not in a global variable e.g. 'errno' nor are
511 they congruent with posix error numbers. */
513 static PyObject
* os2_error(int code
)
518 os2_strerror(text
, sizeof(text
), code
, "");
520 v
= Py_BuildValue("(is)", code
, text
);
522 PyErr_SetObject(PyExc_OSError
, v
);
525 return NULL
; /* Signal to Python that an Exception is Pending */
530 /* POSIX generic methods */
533 posix_fildes(PyObject
*fdobj
, int (*func
)(int))
537 fd
= PyObject_AsFileDescriptor(fdobj
);
540 Py_BEGIN_ALLOW_THREADS
544 return posix_error();
549 #ifdef Py_WIN_WIDE_FILENAMES
551 unicode_file_names(void)
553 static int canusewide
= -1;
554 if (canusewide
== -1) {
555 /* As per doc for ::GetVersion(), this is the correct test for
556 the Windows NT family. */
557 canusewide
= (GetVersion() < 0x80000000) ? 1 : 0;
564 posix_1str(PyObject
*args
, char *format
, int (*func
)(const char*),
565 char *wformat
, int (*wfunc
)(const Py_UNICODE
*))
569 #ifdef Py_WIN_WIDE_FILENAMES
570 if (unicode_file_names()) {
572 if (PyArg_ParseTuple(args
, wformat
, &po
)) {
573 Py_BEGIN_ALLOW_THREADS
574 /* PyUnicode_AS_UNICODE OK without thread
575 lock as it is a simple dereference. */
576 res
= (*wfunc
)(PyUnicode_AS_UNICODE(po
));
579 return posix_error_with_unicode_filename(PyUnicode_AS_UNICODE(po
));
583 /* Drop the argument parsing error as narrow
584 strings are also valid. */
588 /* Platforms that don't support Unicode filenames
589 shouldn't be passing these extra params */
590 assert(wformat
==NULL
&& wfunc
== NULL
);
593 if (!PyArg_ParseTuple(args
, format
,
594 Py_FileSystemDefaultEncoding
, &path1
))
596 Py_BEGIN_ALLOW_THREADS
597 res
= (*func
)(path1
);
600 return posix_error_with_allocated_filename(path1
);
607 posix_2str(PyObject
*args
,
609 int (*func
)(const char *, const char *),
611 int (*wfunc
)(const Py_UNICODE
*, const Py_UNICODE
*))
613 char *path1
= NULL
, *path2
= NULL
;
615 #ifdef Py_WIN_WIDE_FILENAMES
616 if (unicode_file_names()) {
619 if (PyArg_ParseTuple(args
, wformat
, &po1
, &po2
)) {
620 if (PyUnicode_Check(po1
) || PyUnicode_Check(po2
)) {
623 wpath1
= _PyUnicode_FromFileSystemEncodedObject(po1
);
624 wpath2
= _PyUnicode_FromFileSystemEncodedObject(po2
);
625 if (!wpath1
|| !wpath2
) {
630 Py_BEGIN_ALLOW_THREADS
631 /* PyUnicode_AS_UNICODE OK without thread
632 lock as it is a simple dereference. */
633 res
= (*wfunc
)(PyUnicode_AS_UNICODE(wpath1
),
634 PyUnicode_AS_UNICODE(wpath2
));
639 return posix_error();
643 /* Else flow through as neither is Unicode. */
645 /* Drop the argument parsing error as narrow
646 strings are also valid. */
650 /* Platforms that don't support Unicode filenames
651 shouldn't be passing these extra params */
652 assert(wformat
==NULL
&& wfunc
== NULL
);
655 if (!PyArg_ParseTuple(args
, format
,
656 Py_FileSystemDefaultEncoding
, &path1
,
657 Py_FileSystemDefaultEncoding
, &path2
))
659 Py_BEGIN_ALLOW_THREADS
660 res
= (*func
)(path1
, path2
);
665 /* XXX how to report both path1 and path2??? */
666 return posix_error();
672 /* The CRT of Windows has a number of flaws wrt. its stat() implementation:
673 - time stamps are restricted to second resolution
674 - file modification times suffer from forth-and-back conversions between
676 Therefore, we implement our own stat, based on the Win32 API directly.
678 #define HAVE_STAT_NSEC 1
683 unsigned short st_mode
;
697 static __int64 secs_between_epochs
= 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
700 FILE_TIME_to_time_t_nsec(FILETIME
*in_ptr
, int *time_out
, int* nsec_out
)
703 __int64 in
= *(__int64
*)in_ptr
;
704 *nsec_out
= (int)(in
% 10000000) * 100; /* FILETIME is in units of 100 nsec. */
705 /* XXX Win32 supports time stamps past 2038; we currently don't */
706 *time_out
= Py_SAFE_DOWNCAST((in
/ 10000000) - secs_between_epochs
, __int64
, int);
709 /* Below, we *know* that ugo+r is 0444 */
711 #error Unsupported C library
714 attributes_to_mode(DWORD attr
)
717 if (attr
& FILE_ATTRIBUTE_DIRECTORY
)
718 m
|= _S_IFDIR
| 0111; /* IFEXEC for user,group,other */
721 if (attr
& FILE_ATTRIBUTE_READONLY
)
729 attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA
*info
, struct win32_stat
*result
)
731 memset(result
, 0, sizeof(*result
));
732 result
->st_mode
= attributes_to_mode(info
->dwFileAttributes
);
733 result
->st_size
= (((__int64
)info
->nFileSizeHigh
)<<32) + info
->nFileSizeLow
;
734 FILE_TIME_to_time_t_nsec(&info
->ftCreationTime
, &result
->st_ctime
, &result
->st_ctime_nsec
);
735 FILE_TIME_to_time_t_nsec(&info
->ftLastWriteTime
, &result
->st_mtime
, &result
->st_mtime_nsec
);
736 FILE_TIME_to_time_t_nsec(&info
->ftLastAccessTime
, &result
->st_atime
, &result
->st_atime_nsec
);
742 win32_stat(const char* path
, struct win32_stat
*result
)
744 WIN32_FILE_ATTRIBUTE_DATA info
;
747 /* XXX not supported on Win95 and NT 3.x */
748 if (!GetFileAttributesExA(path
, GetFileExInfoStandard
, &info
)) {
749 /* Protocol violation: we explicitly clear errno, instead of
750 setting it to a POSIX error. Callers should use GetLastError. */
754 code
= attribute_data_to_stat(&info
, result
);
757 /* Set S_IFEXEC if it is an .exe, .bat, ... */
758 dot
= strrchr(path
, '.');
760 if (stricmp(dot
, ".bat") == 0 ||
761 stricmp(dot
, ".cmd") == 0 ||
762 stricmp(dot
, ".exe") == 0 ||
763 stricmp(dot
, ".com") == 0)
764 result
->st_mode
|= 0111;
770 win32_wstat(const wchar_t* path
, struct win32_stat
*result
)
774 WIN32_FILE_ATTRIBUTE_DATA info
;
775 /* XXX not supported on Win95 and NT 3.x */
776 if (!GetFileAttributesExW(path
, GetFileExInfoStandard
, &info
)) {
777 /* Protocol violation: we explicitly clear errno, instead of
778 setting it to a POSIX error. Callers should use GetLastError. */
782 code
= attribute_data_to_stat(&info
, result
);
785 /* Set IFEXEC if it is an .exe, .bat, ... */
786 dot
= wcsrchr(path
, '.');
788 if (_wcsicmp(dot
, L
".bat") == 0 ||
789 _wcsicmp(dot
, L
".cmd") == 0 ||
790 _wcsicmp(dot
, L
".exe") == 0 ||
791 _wcsicmp(dot
, L
".com") == 0)
792 result
->st_mode
|= 0111;
798 win32_fstat(int file_number
, struct win32_stat
*result
)
800 BY_HANDLE_FILE_INFORMATION info
;
804 h
= (HANDLE
)_get_osfhandle(file_number
);
806 /* Protocol violation: we explicitly clear errno, instead of
807 setting it to a POSIX error. Callers should use GetLastError. */
810 if (h
== INVALID_HANDLE_VALUE
) {
811 /* This is really a C library error (invalid file handle).
812 We set the Win32 error to the closes one matching. */
813 SetLastError(ERROR_INVALID_HANDLE
);
816 memset(result
, 0, sizeof(*result
));
818 type
= GetFileType(h
);
819 if (type
== FILE_TYPE_UNKNOWN
) {
820 DWORD error
= GetLastError();
824 /* else: valid but unknown file */
827 if (type
!= FILE_TYPE_DISK
) {
828 if (type
== FILE_TYPE_CHAR
)
829 result
->st_mode
= _S_IFCHR
;
830 else if (type
== FILE_TYPE_PIPE
)
831 result
->st_mode
= _S_IFIFO
;
835 if (!GetFileInformationByHandle(h
, &info
)) {
839 /* similar to stat() */
840 result
->st_mode
= attributes_to_mode(info
.dwFileAttributes
);
841 result
->st_size
= (((__int64
)info
.nFileSizeHigh
)<<32) + info
.nFileSizeLow
;
842 FILE_TIME_to_time_t_nsec(&info
.ftCreationTime
, &result
->st_ctime
, &result
->st_ctime_nsec
);
843 FILE_TIME_to_time_t_nsec(&info
.ftLastWriteTime
, &result
->st_mtime
, &result
->st_mtime_nsec
);
844 FILE_TIME_to_time_t_nsec(&info
.ftLastAccessTime
, &result
->st_atime
, &result
->st_atime_nsec
);
845 /* specific to fstat() */
846 result
->st_nlink
= info
.nNumberOfLinks
;
847 result
->st_ino
= (((__int64
)info
.nFileIndexHigh
)<<32) + info
.nFileIndexLow
;
851 #endif /* MS_WINDOWS */
853 PyDoc_STRVAR(stat_result__doc__
,
854 "stat_result: Result from stat or lstat.\n\n\
855 This object may be accessed either as a tuple of\n\
856 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
857 or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
859 Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
860 or st_flags, they are available as attributes only.\n\
862 See os.stat for more information.");
864 static PyStructSequence_Field stat_result_fields
[] = {
865 {"st_mode", "protection bits"},
867 {"st_dev", "device"},
868 {"st_nlink", "number of hard links"},
869 {"st_uid", "user ID of owner"},
870 {"st_gid", "group ID of owner"},
871 {"st_size", "total size, in bytes"},
872 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
873 {NULL
, "integer time of last access"},
874 {NULL
, "integer time of last modification"},
875 {NULL
, "integer time of last change"},
876 {"st_atime", "time of last access"},
877 {"st_mtime", "time of last modification"},
878 {"st_ctime", "time of last change"},
879 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
880 {"st_blksize", "blocksize for filesystem I/O"},
882 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
883 {"st_blocks", "number of blocks allocated"},
885 #ifdef HAVE_STRUCT_STAT_ST_RDEV
886 {"st_rdev", "device type (if inode device)"},
888 #ifdef HAVE_STRUCT_STAT_ST_FLAGS
889 {"st_flags", "user defined flags for file"},
891 #ifdef HAVE_STRUCT_STAT_ST_GEN
892 {"st_gen", "generation number"},
894 #ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
895 {"st_birthtime", "time of creation"},
900 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
901 #define ST_BLKSIZE_IDX 13
903 #define ST_BLKSIZE_IDX 12
906 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
907 #define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
909 #define ST_BLOCKS_IDX ST_BLKSIZE_IDX
912 #ifdef HAVE_STRUCT_STAT_ST_RDEV
913 #define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
915 #define ST_RDEV_IDX ST_BLOCKS_IDX
918 #ifdef HAVE_STRUCT_STAT_ST_FLAGS
919 #define ST_FLAGS_IDX (ST_RDEV_IDX+1)
921 #define ST_FLAGS_IDX ST_RDEV_IDX
924 #ifdef HAVE_STRUCT_STAT_ST_GEN
925 #define ST_GEN_IDX (ST_FLAGS_IDX+1)
927 #define ST_GEN_IDX ST_FLAGS_IDX
930 #ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
931 #define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
933 #define ST_BIRTHTIME_IDX ST_GEN_IDX
936 static PyStructSequence_Desc stat_result_desc
= {
937 "stat_result", /* name */
938 stat_result__doc__
, /* doc */
943 PyDoc_STRVAR(statvfs_result__doc__
,
944 "statvfs_result: Result from statvfs or fstatvfs.\n\n\
945 This object may be accessed either as a tuple of\n\
946 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
947 or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
949 See os.statvfs for more information.");
951 static PyStructSequence_Field statvfs_result_fields
[] = {
965 static PyStructSequence_Desc statvfs_result_desc
= {
966 "statvfs_result", /* name */
967 statvfs_result__doc__
, /* doc */
968 statvfs_result_fields
,
972 static PyTypeObject StatResultType
;
973 static PyTypeObject StatVFSResultType
;
974 static newfunc structseq_new
;
977 statresult_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwds
)
979 PyStructSequence
*result
;
982 result
= (PyStructSequence
*)structseq_new(type
, args
, kwds
);
985 /* If we have been initialized from a tuple,
986 st_?time might be set to None. Initialize it
987 from the int slots. */
988 for (i
= 7; i
<= 9; i
++) {
989 if (result
->ob_item
[i
+3] == Py_None
) {
991 Py_INCREF(result
->ob_item
[i
]);
992 result
->ob_item
[i
+3] = result
->ob_item
[i
];
995 return (PyObject
*)result
;
1000 /* If true, st_?time is float. */
1001 static int _stat_float_times
= 1;
1003 PyDoc_STRVAR(stat_float_times__doc__
,
1004 "stat_float_times([newval]) -> oldval\n\n\
1005 Determine whether os.[lf]stat represents time stamps as float objects.\n\
1006 If newval is True, future calls to stat() return floats, if it is False,\n\
1007 future calls return ints. \n\
1008 If newval is omitted, return the current setting.\n");
1011 stat_float_times(PyObject
* self
, PyObject
*args
)
1014 if (!PyArg_ParseTuple(args
, "|i:stat_float_times", &newval
))
1017 /* Return old value */
1018 return PyBool_FromLong(_stat_float_times
);
1019 _stat_float_times
= newval
;
1025 fill_time(PyObject
*v
, int index
, time_t sec
, unsigned long nsec
)
1027 PyObject
*fval
,*ival
;
1028 #if SIZEOF_TIME_T > SIZEOF_LONG
1029 ival
= PyLong_FromLongLong((PY_LONG_LONG
)sec
);
1031 ival
= PyInt_FromLong((long)sec
);
1033 if (_stat_float_times
) {
1034 fval
= PyFloat_FromDouble(sec
+ 1e-9*nsec
);
1039 PyStructSequence_SET_ITEM(v
, index
, ival
);
1040 PyStructSequence_SET_ITEM(v
, index
+3, fval
);
1043 /* pack a system stat C structure into the Python stat tuple
1044 (used by posix_stat() and posix_fstat()) */
1046 _pystat_fromstructstat(STRUCT_STAT
*st
)
1048 unsigned long ansec
, mnsec
, cnsec
;
1049 PyObject
*v
= PyStructSequence_New(&StatResultType
);
1053 PyStructSequence_SET_ITEM(v
, 0, PyInt_FromLong((long)st
->st_mode
));
1054 #ifdef HAVE_LARGEFILE_SUPPORT
1055 PyStructSequence_SET_ITEM(v
, 1,
1056 PyLong_FromLongLong((PY_LONG_LONG
)st
->st_ino
));
1058 PyStructSequence_SET_ITEM(v
, 1, PyInt_FromLong((long)st
->st_ino
));
1060 #if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
1061 PyStructSequence_SET_ITEM(v
, 2,
1062 PyLong_FromLongLong((PY_LONG_LONG
)st
->st_dev
));
1064 PyStructSequence_SET_ITEM(v
, 2, PyInt_FromLong((long)st
->st_dev
));
1066 PyStructSequence_SET_ITEM(v
, 3, PyInt_FromLong((long)st
->st_nlink
));
1067 PyStructSequence_SET_ITEM(v
, 4, PyInt_FromLong((long)st
->st_uid
));
1068 PyStructSequence_SET_ITEM(v
, 5, PyInt_FromLong((long)st
->st_gid
));
1069 #ifdef HAVE_LARGEFILE_SUPPORT
1070 PyStructSequence_SET_ITEM(v
, 6,
1071 PyLong_FromLongLong((PY_LONG_LONG
)st
->st_size
));
1073 PyStructSequence_SET_ITEM(v
, 6, PyInt_FromLong(st
->st_size
));
1076 #if defined(HAVE_STAT_TV_NSEC)
1077 ansec
= st
->st_atim
.tv_nsec
;
1078 mnsec
= st
->st_mtim
.tv_nsec
;
1079 cnsec
= st
->st_ctim
.tv_nsec
;
1080 #elif defined(HAVE_STAT_TV_NSEC2)
1081 ansec
= st
->st_atimespec
.tv_nsec
;
1082 mnsec
= st
->st_mtimespec
.tv_nsec
;
1083 cnsec
= st
->st_ctimespec
.tv_nsec
;
1084 #elif defined(HAVE_STAT_NSEC)
1085 ansec
= st
->st_atime_nsec
;
1086 mnsec
= st
->st_mtime_nsec
;
1087 cnsec
= st
->st_ctime_nsec
;
1089 ansec
= mnsec
= cnsec
= 0;
1091 fill_time(v
, 7, st
->st_atime
, ansec
);
1092 fill_time(v
, 8, st
->st_mtime
, mnsec
);
1093 fill_time(v
, 9, st
->st_ctime
, cnsec
);
1095 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
1096 PyStructSequence_SET_ITEM(v
, ST_BLKSIZE_IDX
,
1097 PyInt_FromLong((long)st
->st_blksize
));
1099 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
1100 PyStructSequence_SET_ITEM(v
, ST_BLOCKS_IDX
,
1101 PyInt_FromLong((long)st
->st_blocks
));
1103 #ifdef HAVE_STRUCT_STAT_ST_RDEV
1104 PyStructSequence_SET_ITEM(v
, ST_RDEV_IDX
,
1105 PyInt_FromLong((long)st
->st_rdev
));
1107 #ifdef HAVE_STRUCT_STAT_ST_GEN
1108 PyStructSequence_SET_ITEM(v
, ST_GEN_IDX
,
1109 PyInt_FromLong((long)st
->st_gen
));
1111 #ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1114 unsigned long bsec
,bnsec
;
1115 bsec
= (long)st
->st_birthtime
;
1116 #ifdef HAVE_STAT_TV_NSEC2
1117 bnsec
= st
.st_birthtimespec
->tv_nsec
;
1121 if (_stat_float_times
) {
1122 val
= PyFloat_FromDouble(bsec
+ 1e-9*bnsec
);
1124 val
= PyInt_FromLong((long)bsec
);
1126 PyStructSequence_SET_ITEM(v
, ST_BIRTHTIME_IDX
,
1130 #ifdef HAVE_STRUCT_STAT_ST_FLAGS
1131 PyStructSequence_SET_ITEM(v
, ST_FLAGS_IDX
,
1132 PyInt_FromLong((long)st
->st_flags
));
1135 if (PyErr_Occurred()) {
1145 /* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
1146 where / can be used in place of \ and the trailing slash is optional.
1147 Both SERVER and SHARE must have at least one character.
1150 #define ISSLASHA(c) ((c) == '\\' || (c) == '/')
1151 #define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
1152 #define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
1155 IsUNCRootA(char *path
, int pathlen
)
1157 #define ISSLASH ISSLASHA
1161 if (pathlen
< 5 || !ISSLASH(path
[0]) || !ISSLASH(path
[1]))
1162 /* minimum UNCRoot is \\x\y */
1164 for (i
= 2; i
< pathlen
; i
++)
1165 if (ISSLASH(path
[i
])) break;
1166 if (i
== 2 || i
== pathlen
)
1167 /* do not allow \\\SHARE or \\SERVER */
1170 for (i
= share
; i
< pathlen
; i
++)
1171 if (ISSLASH(path
[i
])) break;
1172 return (i
!= share
&& (i
== pathlen
|| i
== pathlen
-1));
1177 #ifdef Py_WIN_WIDE_FILENAMES
1179 IsUNCRootW(Py_UNICODE
*path
, int pathlen
)
1181 #define ISSLASH ISSLASHW
1185 if (pathlen
< 5 || !ISSLASH(path
[0]) || !ISSLASH(path
[1]))
1186 /* minimum UNCRoot is \\x\y */
1188 for (i
= 2; i
< pathlen
; i
++)
1189 if (ISSLASH(path
[i
])) break;
1190 if (i
== 2 || i
== pathlen
)
1191 /* do not allow \\\SHARE or \\SERVER */
1194 for (i
= share
; i
< pathlen
; i
++)
1195 if (ISSLASH(path
[i
])) break;
1196 return (i
!= share
&& (i
== pathlen
|| i
== pathlen
-1));
1200 #endif /* Py_WIN_WIDE_FILENAMES */
1201 #endif /* MS_WINDOWS */
1204 posix_do_stat(PyObject
*self
, PyObject
*args
,
1207 int (*statfunc
)(const char *, STRUCT_STAT
*, ...),
1209 int (*statfunc
)(const char *, STRUCT_STAT
*),
1212 int (*wstatfunc
)(const Py_UNICODE
*, STRUCT_STAT
*))
1215 char *path
= NULL
; /* pass this to stat; do not free() it */
1216 char *pathfree
= NULL
; /* this memory must be free'd */
1220 #ifdef Py_WIN_WIDE_FILENAMES
1221 /* If on wide-character-capable OS see if argument
1222 is Unicode and if so use wide API. */
1223 if (unicode_file_names()) {
1224 PyUnicodeObject
*po
;
1225 if (PyArg_ParseTuple(args
, wformat
, &po
)) {
1226 Py_UNICODE
*wpath
= PyUnicode_AS_UNICODE(po
);
1228 Py_BEGIN_ALLOW_THREADS
1229 /* PyUnicode_AS_UNICODE result OK without
1230 thread lock as it is a simple dereference. */
1231 res
= wstatfunc(wpath
, &st
);
1232 Py_END_ALLOW_THREADS
1235 return win32_error_unicode("stat", wpath
);
1236 return _pystat_fromstructstat(&st
);
1238 /* Drop the argument parsing error as narrow strings
1244 if (!PyArg_ParseTuple(args
, format
,
1245 Py_FileSystemDefaultEncoding
, &path
))
1249 Py_BEGIN_ALLOW_THREADS
1250 res
= (*statfunc
)(path
, &st
);
1251 Py_END_ALLOW_THREADS
1255 result
= win32_error("stat", pathfree
);
1257 result
= posix_error_with_filename(pathfree
);
1261 result
= _pystat_fromstructstat(&st
);
1263 PyMem_Free(pathfree
);
1269 PyDoc_STRVAR(posix_access__doc__
,
1270 "access(path, mode) -> 1 if granted, 0 otherwise\n\n\
1271 Use the real uid/gid to test for access to a path. Note that most\n\
1272 operations will use the effective uid/gid, therefore this routine can\n\
1273 be used in a suid/sgid environment to test if the invoking user has the\n\
1274 specified access to the path. The mode argument can be F_OK to test\n\
1275 existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
1278 posix_access(PyObject
*self
, PyObject
*args
)
1284 #ifdef Py_WIN_WIDE_FILENAMES
1285 if (unicode_file_names()) {
1286 PyUnicodeObject
*po
;
1287 if (PyArg_ParseTuple(args
, "Ui:access", &po
, &mode
)) {
1288 Py_BEGIN_ALLOW_THREADS
1289 /* PyUnicode_AS_UNICODE OK without thread lock as
1290 it is a simple dereference. */
1291 res
= _waccess(PyUnicode_AS_UNICODE(po
), mode
);
1292 Py_END_ALLOW_THREADS
1293 return PyBool_FromLong(res
== 0);
1295 /* Drop the argument parsing error as narrow strings
1300 if (!PyArg_ParseTuple(args
, "eti:access",
1301 Py_FileSystemDefaultEncoding
, &path
, &mode
))
1303 Py_BEGIN_ALLOW_THREADS
1304 res
= access(path
, mode
);
1305 Py_END_ALLOW_THREADS
1307 return PyBool_FromLong(res
== 0);
1324 PyDoc_STRVAR(posix_ttyname__doc__
,
1325 "ttyname(fd) -> string\n\n\
1326 Return the name of the terminal device connected to 'fd'.");
1329 posix_ttyname(PyObject
*self
, PyObject
*args
)
1334 if (!PyArg_ParseTuple(args
, "i:ttyname", &id
))
1338 /* file descriptor 0 only, the default input device (stdin) */
1349 return posix_error();
1350 return PyString_FromString(ret
);
1355 PyDoc_STRVAR(posix_ctermid__doc__
,
1356 "ctermid() -> string\n\n\
1357 Return the name of the controlling terminal for this process.");
1360 posix_ctermid(PyObject
*self
, PyObject
*noargs
)
1363 char buffer
[L_ctermid
];
1365 #ifdef USE_CTERMID_R
1366 ret
= ctermid_r(buffer
);
1368 ret
= ctermid(buffer
);
1371 return posix_error();
1372 return PyString_FromString(buffer
);
1376 PyDoc_STRVAR(posix_chdir__doc__
,
1378 Change the current working directory to the specified path.");
1381 posix_chdir(PyObject
*self
, PyObject
*args
)
1384 return posix_1str(args
, "et:chdir", chdir
, "U:chdir", _wchdir
);
1385 #elif defined(PYOS_OS2) && defined(PYCC_GCC)
1386 return posix_1str(args
, "et:chdir", _chdir2
, NULL
, NULL
);
1387 #elif defined(__VMS)
1388 return posix_1str(args
, "et:chdir", (int (*)(const char *))chdir
,
1391 return posix_1str(args
, "et:chdir", chdir
, NULL
, NULL
);
1396 PyDoc_STRVAR(posix_fchdir__doc__
,
1397 "fchdir(fildes)\n\n\
1398 Change to the directory of the given file descriptor. fildes must be\n\
1399 opened on a directory, not a file.");
1402 posix_fchdir(PyObject
*self
, PyObject
*fdobj
)
1404 return posix_fildes(fdobj
, fchdir
);
1406 #endif /* HAVE_FCHDIR */
1409 PyDoc_STRVAR(posix_chmod__doc__
,
1410 "chmod(path, mode)\n\n\
1411 Change the access permissions of a file.");
1414 posix_chmod(PyObject
*self
, PyObject
*args
)
1419 #ifdef Py_WIN_WIDE_FILENAMES
1420 if (unicode_file_names()) {
1421 PyUnicodeObject
*po
;
1422 if (PyArg_ParseTuple(args
, "Ui|:chmod", &po
, &i
)) {
1423 Py_BEGIN_ALLOW_THREADS
1424 res
= _wchmod(PyUnicode_AS_UNICODE(po
), i
);
1425 Py_END_ALLOW_THREADS
1427 return posix_error_with_unicode_filename(
1428 PyUnicode_AS_UNICODE(po
));
1432 /* Drop the argument parsing error as narrow strings
1436 #endif /* Py_WIN_WIDE_FILENAMES */
1437 if (!PyArg_ParseTuple(args
, "eti:chmod", Py_FileSystemDefaultEncoding
,
1440 Py_BEGIN_ALLOW_THREADS
1441 res
= chmod(path
, i
);
1442 Py_END_ALLOW_THREADS
1444 return posix_error_with_allocated_filename(path
);
1452 PyDoc_STRVAR(posix_chroot__doc__
,
1454 Change root directory to path.");
1457 posix_chroot(PyObject
*self
, PyObject
*args
)
1459 return posix_1str(args
, "et:chroot", chroot
, NULL
, NULL
);
1464 PyDoc_STRVAR(posix_fsync__doc__
,
1466 force write of file with filedescriptor to disk.");
1469 posix_fsync(PyObject
*self
, PyObject
*fdobj
)
1471 return posix_fildes(fdobj
, fsync
);
1473 #endif /* HAVE_FSYNC */
1475 #ifdef HAVE_FDATASYNC
1478 extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1481 PyDoc_STRVAR(posix_fdatasync__doc__
,
1482 "fdatasync(fildes)\n\n\
1483 force write of file with filedescriptor to disk.\n\
1484 does not force update of metadata.");
1487 posix_fdatasync(PyObject
*self
, PyObject
*fdobj
)
1489 return posix_fildes(fdobj
, fdatasync
);
1491 #endif /* HAVE_FDATASYNC */
1495 PyDoc_STRVAR(posix_chown__doc__
,
1496 "chown(path, uid, gid)\n\n\
1497 Change the owner and group id of path to the numeric uid and gid.");
1500 posix_chown(PyObject
*self
, PyObject
*args
)
1505 if (!PyArg_ParseTuple(args
, "etii:chown",
1506 Py_FileSystemDefaultEncoding
, &path
,
1509 Py_BEGIN_ALLOW_THREADS
1510 res
= chown(path
, (uid_t
) uid
, (gid_t
) gid
);
1511 Py_END_ALLOW_THREADS
1513 return posix_error_with_allocated_filename(path
);
1518 #endif /* HAVE_CHOWN */
1521 PyDoc_STRVAR(posix_lchown__doc__
,
1522 "lchown(path, uid, gid)\n\n\
1523 Change the owner and group id of path to the numeric uid and gid.\n\
1524 This function will not follow symbolic links.");
1527 posix_lchown(PyObject
*self
, PyObject
*args
)
1532 if (!PyArg_ParseTuple(args
, "etii:lchown",
1533 Py_FileSystemDefaultEncoding
, &path
,
1536 Py_BEGIN_ALLOW_THREADS
1537 res
= lchown(path
, (uid_t
) uid
, (gid_t
) gid
);
1538 Py_END_ALLOW_THREADS
1540 return posix_error_with_allocated_filename(path
);
1545 #endif /* HAVE_LCHOWN */
1549 PyDoc_STRVAR(posix_getcwd__doc__
,
1550 "getcwd() -> path\n\n\
1551 Return a string representing the current working directory.");
1554 posix_getcwd(PyObject
*self
, PyObject
*noargs
)
1559 Py_BEGIN_ALLOW_THREADS
1560 #if defined(PYOS_OS2) && defined(PYCC_GCC)
1561 res
= _getcwd2(buf
, sizeof buf
);
1563 res
= getcwd(buf
, sizeof buf
);
1565 Py_END_ALLOW_THREADS
1567 return posix_error();
1568 return PyString_FromString(buf
);
1571 #ifdef Py_USING_UNICODE
1572 PyDoc_STRVAR(posix_getcwdu__doc__
,
1573 "getcwdu() -> path\n\n\
1574 Return a unicode string representing the current working directory.");
1577 posix_getcwdu(PyObject
*self
, PyObject
*noargs
)
1582 #ifdef Py_WIN_WIDE_FILENAMES
1583 if (unicode_file_names()) {
1586 Py_BEGIN_ALLOW_THREADS
1587 wres
= _wgetcwd(wbuf
, sizeof wbuf
/ sizeof wbuf
[0]);
1588 Py_END_ALLOW_THREADS
1590 return posix_error();
1591 return PyUnicode_FromWideChar(wbuf
, wcslen(wbuf
));
1595 Py_BEGIN_ALLOW_THREADS
1596 #if defined(PYOS_OS2) && defined(PYCC_GCC)
1597 res
= _getcwd2(buf
, sizeof buf
);
1599 res
= getcwd(buf
, sizeof buf
);
1601 Py_END_ALLOW_THREADS
1603 return posix_error();
1604 return PyUnicode_Decode(buf
, strlen(buf
), Py_FileSystemDefaultEncoding
,"strict");
1611 PyDoc_STRVAR(posix_link__doc__
,
1612 "link(src, dst)\n\n\
1613 Create a hard link to a file.");
1616 posix_link(PyObject
*self
, PyObject
*args
)
1618 return posix_2str(args
, "etet:link", link
, NULL
, NULL
);
1620 #endif /* HAVE_LINK */
1623 PyDoc_STRVAR(posix_listdir__doc__
,
1624 "listdir(path) -> list_of_strings\n\n\
1625 Return a list containing the names of the entries in the directory.\n\
1627 path: path of directory to list\n\
1629 The list is in arbitrary order. It does not include the special\n\
1630 entries '.' and '..' even if they are present in the directory.");
1633 posix_listdir(PyObject
*self
, PyObject
*args
)
1635 /* XXX Should redo this putting the (now four) versions of opendir
1636 in separate files instead of having them all here... */
1637 #if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
1641 WIN32_FIND_DATA FileData
;
1642 /* MAX_PATH characters could mean a bigger encoded string */
1643 char namebuf
[MAX_PATH
*2+5];
1644 char *bufptr
= namebuf
;
1645 int len
= sizeof(namebuf
)/sizeof(namebuf
[0]);
1647 #ifdef Py_WIN_WIDE_FILENAMES
1648 /* If on wide-character-capable OS see if argument
1649 is Unicode and if so use wide API. */
1650 if (unicode_file_names()) {
1651 PyUnicodeObject
*po
;
1652 if (PyArg_ParseTuple(args
, "U:listdir", &po
)) {
1653 WIN32_FIND_DATAW wFileData
;
1654 Py_UNICODE wnamebuf
[MAX_PATH
*2+5];
1656 wcsncpy(wnamebuf
, PyUnicode_AS_UNICODE(po
), MAX_PATH
);
1657 wnamebuf
[MAX_PATH
] = L
'\0';
1658 len
= wcslen(wnamebuf
);
1659 wch
= (len
> 0) ? wnamebuf
[len
-1] : L
'\0';
1660 if (wch
!= L
'/' && wch
!= L
'\\' && wch
!= L
':')
1661 wnamebuf
[len
++] = L
'/';
1662 wcscpy(wnamebuf
+ len
, L
"*.*");
1663 if ((d
= PyList_New(0)) == NULL
)
1665 hFindFile
= FindFirstFileW(wnamebuf
, &wFileData
);
1666 if (hFindFile
== INVALID_HANDLE_VALUE
) {
1667 errno
= GetLastError();
1668 if (errno
== ERROR_FILE_NOT_FOUND
) {
1672 return win32_error_unicode("FindFirstFileW", wnamebuf
);
1675 if (wFileData
.cFileName
[0] == L
'.' &&
1676 (wFileData
.cFileName
[1] == L
'\0' ||
1677 wFileData
.cFileName
[1] == L
'.' &&
1678 wFileData
.cFileName
[2] == L
'\0'))
1680 v
= PyUnicode_FromUnicode(wFileData
.cFileName
, wcslen(wFileData
.cFileName
));
1686 if (PyList_Append(d
, v
) != 0) {
1693 } while (FindNextFileW(hFindFile
, &wFileData
) == TRUE
);
1695 if (FindClose(hFindFile
) == FALSE
) {
1697 return win32_error_unicode("FindClose", wnamebuf
);
1701 /* Drop the argument parsing error as narrow strings
1707 if (!PyArg_ParseTuple(args
, "et#:listdir",
1708 Py_FileSystemDefaultEncoding
, &bufptr
, &len
))
1711 char ch
= namebuf
[len
-1];
1712 if (ch
!= SEP
&& ch
!= ALTSEP
&& ch
!= ':')
1713 namebuf
[len
++] = '/';
1715 strcpy(namebuf
+ len
, "*.*");
1717 if ((d
= PyList_New(0)) == NULL
)
1720 hFindFile
= FindFirstFile(namebuf
, &FileData
);
1721 if (hFindFile
== INVALID_HANDLE_VALUE
) {
1722 errno
= GetLastError();
1723 if (errno
== ERROR_FILE_NOT_FOUND
)
1726 return win32_error("FindFirstFile", namebuf
);
1729 if (FileData
.cFileName
[0] == '.' &&
1730 (FileData
.cFileName
[1] == '\0' ||
1731 FileData
.cFileName
[1] == '.' &&
1732 FileData
.cFileName
[2] == '\0'))
1734 v
= PyString_FromString(FileData
.cFileName
);
1740 if (PyList_Append(d
, v
) != 0) {
1747 } while (FindNextFile(hFindFile
, &FileData
) == TRUE
);
1749 if (FindClose(hFindFile
) == FALSE
) {
1751 return win32_error("FindClose", namebuf
);
1756 #elif defined(PYOS_OS2)
1759 #define MAX_PATH CCHMAXPATH
1764 char namebuf
[MAX_PATH
+5];
1770 if (!PyArg_ParseTuple(args
, "t#:listdir", &name
, &len
))
1772 if (len
>= MAX_PATH
) {
1773 PyErr_SetString(PyExc_ValueError
, "path too long");
1776 strcpy(namebuf
, name
);
1777 for (pt
= namebuf
; *pt
; pt
++)
1780 if (namebuf
[len
-1] != SEP
)
1781 namebuf
[len
++] = SEP
;
1782 strcpy(namebuf
+ len
, "*.*");
1784 if ((d
= PyList_New(0)) == NULL
)
1787 rc
= DosFindFirst(namebuf
, /* Wildcard Pattern to Match */
1788 &hdir
, /* Handle to Use While Search Directory */
1789 FILE_READONLY
| FILE_HIDDEN
| FILE_SYSTEM
| FILE_DIRECTORY
,
1790 &ep
, sizeof(ep
), /* Structure to Receive Directory Entry */
1791 &srchcnt
, /* Max and Actual Count of Entries Per Iteration */
1792 FIL_STANDARD
); /* Format of Entry (EAs or Not) */
1794 if (rc
!= NO_ERROR
) {
1796 return posix_error_with_filename(name
);
1799 if (srchcnt
> 0) { /* If Directory is NOT Totally Empty, */
1801 if (ep
.achName
[0] == '.'
1802 && (ep
.achName
[1] == '\0' || (ep
.achName
[1] == '.' && ep
.achName
[2] == '\0')))
1803 continue; /* Skip Over "." and ".." Names */
1805 strcpy(namebuf
, ep
.achName
);
1807 /* Leave Case of Name Alone -- In Native Form */
1808 /* (Removed Forced Lowercasing Code) */
1810 v
= PyString_FromString(namebuf
);
1816 if (PyList_Append(d
, v
) != 0) {
1823 } while (DosFindNext(hdir
, &ep
, sizeof(ep
), &srchcnt
) == NO_ERROR
&& srchcnt
> 0);
1833 int arg_is_unicode
= 1;
1835 if (!PyArg_ParseTuple(args
, "U:listdir", &v
)) {
1839 if (!PyArg_ParseTuple(args
, "et:listdir", Py_FileSystemDefaultEncoding
, &name
))
1841 if ((dirp
= opendir(name
)) == NULL
) {
1842 return posix_error_with_allocated_filename(name
);
1844 if ((d
= PyList_New(0)) == NULL
) {
1849 while ((ep
= readdir(dirp
)) != NULL
) {
1850 if (ep
->d_name
[0] == '.' &&
1852 (ep
->d_name
[1] == '.' && NAMLEN(ep
) == 2)))
1854 v
= PyString_FromStringAndSize(ep
->d_name
, NAMLEN(ep
));
1860 #ifdef Py_USING_UNICODE
1861 if (arg_is_unicode
) {
1864 w
= PyUnicode_FromEncodedObject(v
,
1865 Py_FileSystemDefaultEncoding
,
1872 /* fall back to the original byte string, as
1873 discussed in patch #683592 */
1878 if (PyList_Append(d
, v
) != 0) {
1891 #endif /* which OS */
1892 } /* end of posix_listdir */
1895 /* A helper function for abspath on win32 */
1897 posix__getfullpathname(PyObject
*self
, PyObject
*args
)
1899 /* assume encoded strings wont more than double no of chars */
1900 char inbuf
[MAX_PATH
*2];
1901 char *inbufp
= inbuf
;
1902 int insize
= sizeof(inbuf
)/sizeof(inbuf
[0]);
1903 char outbuf
[MAX_PATH
*2];
1905 #ifdef Py_WIN_WIDE_FILENAMES
1906 if (unicode_file_names()) {
1907 PyUnicodeObject
*po
;
1908 if (PyArg_ParseTuple(args
, "U|:_getfullpathname", &po
)) {
1909 Py_UNICODE woutbuf
[MAX_PATH
*2];
1911 if (!GetFullPathNameW(PyUnicode_AS_UNICODE(po
),
1912 sizeof(woutbuf
)/sizeof(woutbuf
[0]),
1914 return win32_error("GetFullPathName", "");
1915 return PyUnicode_FromUnicode(woutbuf
, wcslen(woutbuf
));
1917 /* Drop the argument parsing error as narrow strings
1922 if (!PyArg_ParseTuple (args
, "et#:_getfullpathname",
1923 Py_FileSystemDefaultEncoding
, &inbufp
,
1926 if (!GetFullPathName(inbuf
, sizeof(outbuf
)/sizeof(outbuf
[0]),
1928 return win32_error("GetFullPathName", inbuf
);
1929 if (PyUnicode_Check(PyTuple_GetItem(args
, 0))) {
1930 return PyUnicode_Decode(outbuf
, strlen(outbuf
),
1931 Py_FileSystemDefaultEncoding
, NULL
);
1933 return PyString_FromString(outbuf
);
1934 } /* end of posix__getfullpathname */
1935 #endif /* MS_WINDOWS */
1937 PyDoc_STRVAR(posix_mkdir__doc__
,
1938 "mkdir(path [, mode=0777])\n\n\
1939 Create a directory.");
1942 posix_mkdir(PyObject
*self
, PyObject
*args
)
1948 #ifdef Py_WIN_WIDE_FILENAMES
1949 if (unicode_file_names()) {
1950 PyUnicodeObject
*po
;
1951 if (PyArg_ParseTuple(args
, "U|i:mkdir", &po
, &mode
)) {
1952 Py_BEGIN_ALLOW_THREADS
1953 /* PyUnicode_AS_UNICODE OK without thread lock as
1954 it is a simple dereference. */
1955 res
= _wmkdir(PyUnicode_AS_UNICODE(po
));
1956 Py_END_ALLOW_THREADS
1958 return posix_error();
1962 /* Drop the argument parsing error as narrow strings
1968 if (!PyArg_ParseTuple(args
, "et|i:mkdir",
1969 Py_FileSystemDefaultEncoding
, &path
, &mode
))
1971 Py_BEGIN_ALLOW_THREADS
1972 #if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
1975 res
= mkdir(path
, mode
);
1977 Py_END_ALLOW_THREADS
1979 return posix_error_with_allocated_filename(path
);
1987 #if defined(HAVE_BROKEN_NICE) && defined(HAVE_SYS_RESOURCE_H)
1988 #if defined(HAVE_GETPRIORITY) && !defined(PRIO_PROCESS)
1989 #include <sys/resource.h>
1993 PyDoc_STRVAR(posix_nice__doc__
,
1994 "nice(inc) -> new_priority\n\n\
1995 Decrease the priority of process by inc and return the new priority.");
1998 posix_nice(PyObject
*self
, PyObject
*args
)
2000 int increment
, value
;
2002 if (!PyArg_ParseTuple(args
, "i:nice", &increment
))
2005 /* There are two flavours of 'nice': one that returns the new
2006 priority (as required by almost all standards out there) and the
2007 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2008 the use of getpriority() to get the new priority.
2010 If we are of the nice family that returns the new priority, we
2011 need to clear errno before the call, and check if errno is filled
2012 before calling posix_error() on a returnvalue of -1, because the
2013 -1 may be the actual new priority! */
2016 value
= nice(increment
);
2017 #if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
2019 value
= getpriority(PRIO_PROCESS
, 0);
2021 if (value
== -1 && errno
!= 0)
2022 /* either nice() or getpriority() returned an error */
2023 return posix_error();
2024 return PyInt_FromLong((long) value
);
2026 #endif /* HAVE_NICE */
2029 PyDoc_STRVAR(posix_rename__doc__
,
2030 "rename(old, new)\n\n\
2031 Rename a file or directory.");
2034 posix_rename(PyObject
*self
, PyObject
*args
)
2037 return posix_2str(args
, "etet:rename", rename
, "OO:rename", _wrename
);
2039 return posix_2str(args
, "etet:rename", rename
, NULL
, NULL
);
2044 PyDoc_STRVAR(posix_rmdir__doc__
,
2046 Remove a directory.");
2049 posix_rmdir(PyObject
*self
, PyObject
*args
)
2052 return posix_1str(args
, "et:rmdir", rmdir
, "U:rmdir", _wrmdir
);
2054 return posix_1str(args
, "et:rmdir", rmdir
, NULL
, NULL
);
2059 PyDoc_STRVAR(posix_stat__doc__
,
2060 "stat(path) -> stat result\n\n\
2061 Perform a stat system call on the given path.");
2064 posix_stat(PyObject
*self
, PyObject
*args
)
2067 return posix_do_stat(self
, args
, "et:stat", STAT
, "U:stat", win32_wstat
);
2069 return posix_do_stat(self
, args
, "et:stat", STAT
, NULL
, NULL
);
2075 PyDoc_STRVAR(posix_system__doc__
,
2076 "system(command) -> exit_status\n\n\
2077 Execute the command (a string) in a subshell.");
2080 posix_system(PyObject
*self
, PyObject
*args
)
2084 if (!PyArg_ParseTuple(args
, "s:system", &command
))
2086 Py_BEGIN_ALLOW_THREADS
2087 sts
= system(command
);
2088 Py_END_ALLOW_THREADS
2089 return PyInt_FromLong(sts
);
2094 PyDoc_STRVAR(posix_umask__doc__
,
2095 "umask(new_mask) -> old_mask\n\n\
2096 Set the current numeric umask and return the previous umask.");
2099 posix_umask(PyObject
*self
, PyObject
*args
)
2102 if (!PyArg_ParseTuple(args
, "i:umask", &i
))
2106 return posix_error();
2107 return PyInt_FromLong((long)i
);
2111 PyDoc_STRVAR(posix_unlink__doc__
,
2113 Remove a file (same as remove(path)).");
2115 PyDoc_STRVAR(posix_remove__doc__
,
2117 Remove a file (same as unlink(path)).");
2120 posix_unlink(PyObject
*self
, PyObject
*args
)
2123 return posix_1str(args
, "et:remove", unlink
, "U:remove", _wunlink
);
2125 return posix_1str(args
, "et:remove", unlink
, NULL
, NULL
);
2131 PyDoc_STRVAR(posix_uname__doc__
,
2132 "uname() -> (sysname, nodename, release, version, machine)\n\n\
2133 Return a tuple identifying the current operating system.");
2136 posix_uname(PyObject
*self
, PyObject
*noargs
)
2141 Py_BEGIN_ALLOW_THREADS
2143 Py_END_ALLOW_THREADS
2145 return posix_error();
2146 return Py_BuildValue("(sssss)",
2153 #endif /* HAVE_UNAME */
2156 extract_time(PyObject
*t
, long* sec
, long* usec
)
2159 if (PyFloat_Check(t
)) {
2160 double tval
= PyFloat_AsDouble(t
);
2161 PyObject
*intobj
= t
->ob_type
->tp_as_number
->nb_int(t
);
2164 intval
= PyInt_AsLong(intobj
);
2166 if (intval
== -1 && PyErr_Occurred())
2169 *usec
= (long)((tval
- intval
) * 1e6
); /* can't exceed 1000000 */
2171 /* If rounding gave us a negative number,
2176 intval
= PyInt_AsLong(t
);
2177 if (intval
== -1 && PyErr_Occurred())
2184 PyDoc_STRVAR(posix_utime__doc__
,
2185 "utime(path, (atime, utime))\n\
2186 utime(path, None)\n\n\
2187 Set the access and modified time of the file to the given values. If the\n\
2188 second form is used, set the access and modified times to the current time.");
2191 posix_utime(PyObject
*self
, PyObject
*args
)
2194 long atime
, mtime
, ausec
, musec
;
2198 #if defined(HAVE_UTIMES)
2199 struct timeval buf
[2];
2200 #define ATIME buf[0].tv_sec
2201 #define MTIME buf[1].tv_sec
2202 #elif defined(HAVE_UTIME_H)
2203 /* XXX should define struct utimbuf instead, above */
2205 #define ATIME buf.actime
2206 #define MTIME buf.modtime
2207 #define UTIME_ARG &buf
2208 #else /* HAVE_UTIMES */
2210 #define ATIME buf[0]
2211 #define MTIME buf[1]
2212 #define UTIME_ARG buf
2213 #endif /* HAVE_UTIMES */
2215 int have_unicode_filename
= 0;
2216 #ifdef Py_WIN_WIDE_FILENAMES
2217 PyUnicodeObject
*obwpath
;
2219 if (unicode_file_names()) {
2220 if (PyArg_ParseTuple(args
, "UO|:utime", &obwpath
, &arg
)) {
2221 wpath
= PyUnicode_AS_UNICODE(obwpath
);
2222 have_unicode_filename
= 1;
2224 /* Drop the argument parsing error as narrow strings
2228 #endif /* Py_WIN_WIDE_FILENAMES */
2230 if (!have_unicode_filename
&& \
2231 !PyArg_ParseTuple(args
, "etO:utime",
2232 Py_FileSystemDefaultEncoding
, &path
, &arg
))
2234 if (arg
== Py_None
) {
2235 /* optional time values not given */
2236 Py_BEGIN_ALLOW_THREADS
2237 #ifdef Py_WIN_WIDE_FILENAMES
2238 if (have_unicode_filename
)
2239 res
= _wutime(wpath
, NULL
);
2241 #endif /* Py_WIN_WIDE_FILENAMES */
2242 res
= utime(path
, NULL
);
2243 Py_END_ALLOW_THREADS
2245 else if (!PyTuple_Check(arg
) || PyTuple_Size(arg
) != 2) {
2246 PyErr_SetString(PyExc_TypeError
,
2247 "utime() arg 2 must be a tuple (atime, mtime)");
2252 if (extract_time(PyTuple_GET_ITEM(arg
, 0),
2253 &atime
, &ausec
) == -1) {
2257 if (extract_time(PyTuple_GET_ITEM(arg
, 1),
2258 &mtime
, &musec
) == -1) {
2265 buf
[0].tv_usec
= ausec
;
2266 buf
[1].tv_usec
= musec
;
2267 Py_BEGIN_ALLOW_THREADS
2268 res
= utimes(path
, buf
);
2269 Py_END_ALLOW_THREADS
2271 Py_BEGIN_ALLOW_THREADS
2272 #ifdef Py_WIN_WIDE_FILENAMES
2273 if (have_unicode_filename
)
2274 /* utime is OK with utimbuf, but _wutime insists
2275 on _utimbuf (the msvc headers assert the
2276 underscore version is ansi) */
2277 res
= _wutime(wpath
, (struct _utimbuf
*)UTIME_ARG
);
2279 #endif /* Py_WIN_WIDE_FILENAMES */
2280 res
= utime(path
, UTIME_ARG
);
2281 Py_END_ALLOW_THREADS
2282 #endif /* HAVE_UTIMES */
2285 #ifdef Py_WIN_WIDE_FILENAMES
2286 if (have_unicode_filename
)
2287 return posix_error_with_unicode_filename(wpath
);
2288 #endif /* Py_WIN_WIDE_FILENAMES */
2289 return posix_error_with_allocated_filename(path
);
2300 /* Process operations */
2302 PyDoc_STRVAR(posix__exit__doc__
,
2304 Exit to the system with specified status, without normal exit processing.");
2307 posix__exit(PyObject
*self
, PyObject
*args
)
2310 if (!PyArg_ParseTuple(args
, "i:_exit", &sts
))
2313 return NULL
; /* Make gcc -Wall happy */
2316 #if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
2318 free_string_array(char **array
, int count
)
2321 for (i
= 0; i
< count
; i
++)
2322 PyMem_Free(array
[i
]);
2329 PyDoc_STRVAR(posix_execv__doc__
,
2330 "execv(path, args)\n\n\
2331 Execute an executable path with arguments, replacing current process.\n\
2333 path: path of executable file\n\
2334 args: tuple or list of strings");
2337 posix_execv(PyObject
*self
, PyObject
*args
)
2343 PyObject
*(*getitem
)(PyObject
*, int);
2345 /* execv has two arguments: (path, argv), where
2346 argv is a list or tuple of strings. */
2348 if (!PyArg_ParseTuple(args
, "etO:execv",
2349 Py_FileSystemDefaultEncoding
,
2352 if (PyList_Check(argv
)) {
2353 argc
= PyList_Size(argv
);
2354 getitem
= PyList_GetItem
;
2356 else if (PyTuple_Check(argv
)) {
2357 argc
= PyTuple_Size(argv
);
2358 getitem
= PyTuple_GetItem
;
2361 PyErr_SetString(PyExc_TypeError
, "execv() arg 2 must be a tuple or list");
2366 argvlist
= PyMem_NEW(char *, argc
+1);
2367 if (argvlist
== NULL
) {
2369 return PyErr_NoMemory();
2371 for (i
= 0; i
< argc
; i
++) {
2372 if (!PyArg_Parse((*getitem
)(argv
, i
), "et",
2373 Py_FileSystemDefaultEncoding
,
2375 free_string_array(argvlist
, i
);
2376 PyErr_SetString(PyExc_TypeError
,
2377 "execv() arg 2 must contain only strings");
2383 argvlist
[argc
] = NULL
;
2385 execv(path
, argvlist
);
2387 /* If we get here it's definitely an error */
2389 free_string_array(argvlist
, argc
);
2391 return posix_error();
2395 PyDoc_STRVAR(posix_execve__doc__
,
2396 "execve(path, args, env)\n\n\
2397 Execute a path with arguments and environment, replacing current process.\n\
2399 path: path of executable file\n\
2400 args: tuple or list of arguments\n\
2401 env: dictionary of strings mapping to strings");
2404 posix_execve(PyObject
*self
, PyObject
*args
)
2407 PyObject
*argv
, *env
;
2410 PyObject
*key
, *val
, *keys
=NULL
, *vals
=NULL
;
2411 int i
, pos
, argc
, envc
;
2412 PyObject
*(*getitem
)(PyObject
*, int);
2415 /* execve has three arguments: (path, argv, env), where
2416 argv is a list or tuple of strings and env is a dictionary
2417 like posix.environ. */
2419 if (!PyArg_ParseTuple(args
, "etOO:execve",
2420 Py_FileSystemDefaultEncoding
,
2421 &path
, &argv
, &env
))
2423 if (PyList_Check(argv
)) {
2424 argc
= PyList_Size(argv
);
2425 getitem
= PyList_GetItem
;
2427 else if (PyTuple_Check(argv
)) {
2428 argc
= PyTuple_Size(argv
);
2429 getitem
= PyTuple_GetItem
;
2432 PyErr_SetString(PyExc_TypeError
,
2433 "execve() arg 2 must be a tuple or list");
2436 if (!PyMapping_Check(env
)) {
2437 PyErr_SetString(PyExc_TypeError
,
2438 "execve() arg 3 must be a mapping object");
2442 argvlist
= PyMem_NEW(char *, argc
+1);
2443 if (argvlist
== NULL
) {
2447 for (i
= 0; i
< argc
; i
++) {
2448 if (!PyArg_Parse((*getitem
)(argv
, i
),
2449 "et;execve() arg 2 must contain only strings",
2450 Py_FileSystemDefaultEncoding
,
2458 argvlist
[argc
] = NULL
;
2460 i
= PyMapping_Size(env
);
2463 envlist
= PyMem_NEW(char *, i
+ 1);
2464 if (envlist
== NULL
) {
2469 keys
= PyMapping_Keys(env
);
2470 vals
= PyMapping_Values(env
);
2473 if (!PyList_Check(keys
) || !PyList_Check(vals
)) {
2474 PyErr_SetString(PyExc_TypeError
,
2475 "execve(): env.keys() or env.values() is not a list");
2479 for (pos
= 0; pos
< i
; pos
++) {
2483 key
= PyList_GetItem(keys
, pos
);
2484 val
= PyList_GetItem(vals
, pos
);
2490 "s;execve() arg 3 contains a non-string key",
2494 "s;execve() arg 3 contains a non-string value",
2500 #if defined(PYOS_OS2)
2501 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
2502 if (stricmp(k
, "BEGINLIBPATH") != 0 && stricmp(k
, "ENDLIBPATH") != 0) {
2504 len
= PyString_Size(key
) + PyString_Size(val
) + 2;
2505 p
= PyMem_NEW(char, len
);
2510 PyOS_snprintf(p
, len
, "%s=%s", k
, v
);
2511 envlist
[envc
++] = p
;
2512 #if defined(PYOS_OS2)
2518 execve(path
, argvlist
, envlist
);
2520 /* If we get here it's definitely an error */
2522 (void) posix_error();
2526 PyMem_DEL(envlist
[envc
]);
2529 free_string_array(argvlist
, lastarg
);
2536 #endif /* HAVE_EXECV */
2540 PyDoc_STRVAR(posix_spawnv__doc__
,
2541 "spawnv(mode, path, args)\n\n\
2542 Execute the program 'path' in a new process.\n\
2544 mode: mode of process creation\n\
2545 path: path of executable file\n\
2546 args: tuple or list of strings");
2549 posix_spawnv(PyObject
*self
, PyObject
*args
)
2555 Py_intptr_t spawnval
;
2556 PyObject
*(*getitem
)(PyObject
*, int);
2558 /* spawnv has three arguments: (mode, path, argv), where
2559 argv is a list or tuple of strings. */
2561 if (!PyArg_ParseTuple(args
, "ietO:spawnv", &mode
,
2562 Py_FileSystemDefaultEncoding
,
2565 if (PyList_Check(argv
)) {
2566 argc
= PyList_Size(argv
);
2567 getitem
= PyList_GetItem
;
2569 else if (PyTuple_Check(argv
)) {
2570 argc
= PyTuple_Size(argv
);
2571 getitem
= PyTuple_GetItem
;
2574 PyErr_SetString(PyExc_TypeError
,
2575 "spawnv() arg 2 must be a tuple or list");
2580 argvlist
= PyMem_NEW(char *, argc
+1);
2581 if (argvlist
== NULL
) {
2583 return PyErr_NoMemory();
2585 for (i
= 0; i
< argc
; i
++) {
2586 if (!PyArg_Parse((*getitem
)(argv
, i
), "et",
2587 Py_FileSystemDefaultEncoding
,
2589 free_string_array(argvlist
, i
);
2592 "spawnv() arg 2 must contain only strings");
2597 argvlist
[argc
] = NULL
;
2599 #if defined(PYOS_OS2) && defined(PYCC_GCC)
2600 Py_BEGIN_ALLOW_THREADS
2601 spawnval
= spawnv(mode
, path
, argvlist
);
2602 Py_END_ALLOW_THREADS
2604 if (mode
== _OLD_P_OVERLAY
)
2607 Py_BEGIN_ALLOW_THREADS
2608 spawnval
= _spawnv(mode
, path
, argvlist
);
2609 Py_END_ALLOW_THREADS
2612 free_string_array(argvlist
, argc
);
2616 return posix_error();
2618 #if SIZEOF_LONG == SIZEOF_VOID_P
2619 return Py_BuildValue("l", (long) spawnval
);
2621 return Py_BuildValue("L", (PY_LONG_LONG
) spawnval
);
2626 PyDoc_STRVAR(posix_spawnve__doc__
,
2627 "spawnve(mode, path, args, env)\n\n\
2628 Execute the program 'path' in a new process.\n\
2630 mode: mode of process creation\n\
2631 path: path of executable file\n\
2632 args: tuple or list of arguments\n\
2633 env: dictionary of strings mapping to strings");
2636 posix_spawnve(PyObject
*self
, PyObject
*args
)
2639 PyObject
*argv
, *env
;
2642 PyObject
*key
, *val
, *keys
=NULL
, *vals
=NULL
, *res
=NULL
;
2643 int mode
, i
, pos
, argc
, envc
;
2644 Py_intptr_t spawnval
;
2645 PyObject
*(*getitem
)(PyObject
*, int);
2648 /* spawnve has four arguments: (mode, path, argv, env), where
2649 argv is a list or tuple of strings and env is a dictionary
2650 like posix.environ. */
2652 if (!PyArg_ParseTuple(args
, "ietOO:spawnve", &mode
,
2653 Py_FileSystemDefaultEncoding
,
2654 &path
, &argv
, &env
))
2656 if (PyList_Check(argv
)) {
2657 argc
= PyList_Size(argv
);
2658 getitem
= PyList_GetItem
;
2660 else if (PyTuple_Check(argv
)) {
2661 argc
= PyTuple_Size(argv
);
2662 getitem
= PyTuple_GetItem
;
2665 PyErr_SetString(PyExc_TypeError
,
2666 "spawnve() arg 2 must be a tuple or list");
2669 if (!PyMapping_Check(env
)) {
2670 PyErr_SetString(PyExc_TypeError
,
2671 "spawnve() arg 3 must be a mapping object");
2675 argvlist
= PyMem_NEW(char *, argc
+1);
2676 if (argvlist
== NULL
) {
2680 for (i
= 0; i
< argc
; i
++) {
2681 if (!PyArg_Parse((*getitem
)(argv
, i
),
2682 "et;spawnve() arg 2 must contain only strings",
2683 Py_FileSystemDefaultEncoding
,
2691 argvlist
[argc
] = NULL
;
2693 i
= PyMapping_Size(env
);
2696 envlist
= PyMem_NEW(char *, i
+ 1);
2697 if (envlist
== NULL
) {
2702 keys
= PyMapping_Keys(env
);
2703 vals
= PyMapping_Values(env
);
2706 if (!PyList_Check(keys
) || !PyList_Check(vals
)) {
2707 PyErr_SetString(PyExc_TypeError
,
2708 "spawnve(): env.keys() or env.values() is not a list");
2712 for (pos
= 0; pos
< i
; pos
++) {
2716 key
= PyList_GetItem(keys
, pos
);
2717 val
= PyList_GetItem(vals
, pos
);
2723 "s;spawnve() arg 3 contains a non-string key",
2727 "s;spawnve() arg 3 contains a non-string value",
2732 len
= PyString_Size(key
) + PyString_Size(val
) + 2;
2733 p
= PyMem_NEW(char, len
);
2738 PyOS_snprintf(p
, len
, "%s=%s", k
, v
);
2739 envlist
[envc
++] = p
;
2743 #if defined(PYOS_OS2) && defined(PYCC_GCC)
2744 Py_BEGIN_ALLOW_THREADS
2745 spawnval
= spawnve(mode
, path
, argvlist
, envlist
);
2746 Py_END_ALLOW_THREADS
2748 if (mode
== _OLD_P_OVERLAY
)
2751 Py_BEGIN_ALLOW_THREADS
2752 spawnval
= _spawnve(mode
, path
, argvlist
, envlist
);
2753 Py_END_ALLOW_THREADS
2757 (void) posix_error();
2759 #if SIZEOF_LONG == SIZEOF_VOID_P
2760 res
= Py_BuildValue("l", (long) spawnval
);
2762 res
= Py_BuildValue("L", (PY_LONG_LONG
) spawnval
);
2767 PyMem_DEL(envlist
[envc
]);
2770 free_string_array(argvlist
, lastarg
);
2778 /* OS/2 supports spawnvp & spawnvpe natively */
2779 #if defined(PYOS_OS2)
2780 PyDoc_STRVAR(posix_spawnvp__doc__
,
2781 "spawnvp(mode, file, args)\n\n\
2782 Execute the program 'file' in a new process, using the environment\n\
2783 search path to find the file.\n\
2785 mode: mode of process creation\n\
2786 file: executable file name\n\
2787 args: tuple or list of strings");
2790 posix_spawnvp(PyObject
*self
, PyObject
*args
)
2796 Py_intptr_t spawnval
;
2797 PyObject
*(*getitem
)(PyObject
*, int);
2799 /* spawnvp has three arguments: (mode, path, argv), where
2800 argv is a list or tuple of strings. */
2802 if (!PyArg_ParseTuple(args
, "ietO:spawnvp", &mode
,
2803 Py_FileSystemDefaultEncoding
,
2806 if (PyList_Check(argv
)) {
2807 argc
= PyList_Size(argv
);
2808 getitem
= PyList_GetItem
;
2810 else if (PyTuple_Check(argv
)) {
2811 argc
= PyTuple_Size(argv
);
2812 getitem
= PyTuple_GetItem
;
2815 PyErr_SetString(PyExc_TypeError
,
2816 "spawnvp() arg 2 must be a tuple or list");
2821 argvlist
= PyMem_NEW(char *, argc
+1);
2822 if (argvlist
== NULL
) {
2824 return PyErr_NoMemory();
2826 for (i
= 0; i
< argc
; i
++) {
2827 if (!PyArg_Parse((*getitem
)(argv
, i
), "et",
2828 Py_FileSystemDefaultEncoding
,
2830 free_string_array(argvlist
, i
);
2833 "spawnvp() arg 2 must contain only strings");
2838 argvlist
[argc
] = NULL
;
2840 Py_BEGIN_ALLOW_THREADS
2841 #if defined(PYCC_GCC)
2842 spawnval
= spawnvp(mode
, path
, argvlist
);
2844 spawnval
= _spawnvp(mode
, path
, argvlist
);
2846 Py_END_ALLOW_THREADS
2848 free_string_array(argvlist
, argc
);
2852 return posix_error();
2854 return Py_BuildValue("l", (long) spawnval
);
2858 PyDoc_STRVAR(posix_spawnvpe__doc__
,
2859 "spawnvpe(mode, file, args, env)\n\n\
2860 Execute the program 'file' in a new process, using the environment\n\
2861 search path to find the file.\n\
2863 mode: mode of process creation\n\
2864 file: executable file name\n\
2865 args: tuple or list of arguments\n\
2866 env: dictionary of strings mapping to strings");
2869 posix_spawnvpe(PyObject
*self
, PyObject
*args
)
2872 PyObject
*argv
, *env
;
2875 PyObject
*key
, *val
, *keys
=NULL
, *vals
=NULL
, *res
=NULL
;
2876 int mode
, i
, pos
, argc
, envc
;
2877 Py_intptr_t spawnval
;
2878 PyObject
*(*getitem
)(PyObject
*, int);
2881 /* spawnvpe has four arguments: (mode, path, argv, env), where
2882 argv is a list or tuple of strings and env is a dictionary
2883 like posix.environ. */
2885 if (!PyArg_ParseTuple(args
, "ietOO:spawnvpe", &mode
,
2886 Py_FileSystemDefaultEncoding
,
2887 &path
, &argv
, &env
))
2889 if (PyList_Check(argv
)) {
2890 argc
= PyList_Size(argv
);
2891 getitem
= PyList_GetItem
;
2893 else if (PyTuple_Check(argv
)) {
2894 argc
= PyTuple_Size(argv
);
2895 getitem
= PyTuple_GetItem
;
2898 PyErr_SetString(PyExc_TypeError
,
2899 "spawnvpe() arg 2 must be a tuple or list");
2902 if (!PyMapping_Check(env
)) {
2903 PyErr_SetString(PyExc_TypeError
,
2904 "spawnvpe() arg 3 must be a mapping object");
2908 argvlist
= PyMem_NEW(char *, argc
+1);
2909 if (argvlist
== NULL
) {
2913 for (i
= 0; i
< argc
; i
++) {
2914 if (!PyArg_Parse((*getitem
)(argv
, i
),
2915 "et;spawnvpe() arg 2 must contain only strings",
2916 Py_FileSystemDefaultEncoding
,
2924 argvlist
[argc
] = NULL
;
2926 i
= PyMapping_Size(env
);
2929 envlist
= PyMem_NEW(char *, i
+ 1);
2930 if (envlist
== NULL
) {
2935 keys
= PyMapping_Keys(env
);
2936 vals
= PyMapping_Values(env
);
2939 if (!PyList_Check(keys
) || !PyList_Check(vals
)) {
2940 PyErr_SetString(PyExc_TypeError
,
2941 "spawnvpe(): env.keys() or env.values() is not a list");
2945 for (pos
= 0; pos
< i
; pos
++) {
2949 key
= PyList_GetItem(keys
, pos
);
2950 val
= PyList_GetItem(vals
, pos
);
2956 "s;spawnvpe() arg 3 contains a non-string key",
2960 "s;spawnvpe() arg 3 contains a non-string value",
2965 len
= PyString_Size(key
) + PyString_Size(val
) + 2;
2966 p
= PyMem_NEW(char, len
);
2971 PyOS_snprintf(p
, len
, "%s=%s", k
, v
);
2972 envlist
[envc
++] = p
;
2976 Py_BEGIN_ALLOW_THREADS
2977 #if defined(PYCC_GCC)
2978 spawnval
= spawnve(mode
, path
, argvlist
, envlist
);
2980 spawnval
= _spawnve(mode
, path
, argvlist
, envlist
);
2982 Py_END_ALLOW_THREADS
2985 (void) posix_error();
2987 res
= Py_BuildValue("l", (long) spawnval
);
2991 PyMem_DEL(envlist
[envc
]);
2994 free_string_array(argvlist
, lastarg
);
3001 #endif /* PYOS_OS2 */
3002 #endif /* HAVE_SPAWNV */
3006 PyDoc_STRVAR(posix_fork1__doc__
,
3007 "fork1() -> pid\n\n\
3008 Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3010 Return 0 to child process and PID of child to parent process.");
3013 posix_fork1(PyObject
*self
, PyObject
*noargs
)
3017 return posix_error();
3019 return PyInt_FromLong((long)pid
);
3025 PyDoc_STRVAR(posix_fork__doc__
,
3027 Fork a child process.\n\
3028 Return 0 to child process and PID of child to parent process.");
3031 posix_fork(PyObject
*self
, PyObject
*noargs
)
3035 return posix_error();
3038 return PyInt_FromLong((long)pid
);
3042 /* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
3043 /* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3044 #if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
3045 #define DEV_PTY_FILE "/dev/ptc"
3046 #define HAVE_DEV_PTMX
3048 #define DEV_PTY_FILE "/dev/ptmx"
3051 #if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
3055 #ifdef HAVE_LIBUTIL_H
3056 #include <libutil.h>
3057 #endif /* HAVE_LIBUTIL_H */
3058 #endif /* HAVE_PTY_H */
3059 #ifdef HAVE_STROPTS_H
3060 #include <stropts.h>
3062 #endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
3064 #if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
3065 PyDoc_STRVAR(posix_openpty__doc__
,
3066 "openpty() -> (master_fd, slave_fd)\n\n\
3067 Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
3070 posix_openpty(PyObject
*self
, PyObject
*noargs
)
3072 int master_fd
, slave_fd
;
3073 #ifndef HAVE_OPENPTY
3076 #if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
3077 PyOS_sighandler_t sig_saved
;
3079 extern char *ptsname();
3084 if (openpty(&master_fd
, &slave_fd
, NULL
, NULL
, NULL
) != 0)
3085 return posix_error();
3086 #elif defined(HAVE__GETPTY)
3087 slave_name
= _getpty(&master_fd
, O_RDWR
, 0666, 0);
3088 if (slave_name
== NULL
)
3089 return posix_error();
3091 slave_fd
= open(slave_name
, O_RDWR
);
3093 return posix_error();
3095 master_fd
= open(DEV_PTY_FILE
, O_RDWR
| O_NOCTTY
); /* open master */
3097 return posix_error();
3098 sig_saved
= PyOS_setsig(SIGCHLD
, SIG_DFL
);
3099 /* change permission of slave */
3100 if (grantpt(master_fd
) < 0) {
3101 PyOS_setsig(SIGCHLD
, sig_saved
);
3102 return posix_error();
3105 if (unlockpt(master_fd
) < 0) {
3106 PyOS_setsig(SIGCHLD
, sig_saved
);
3107 return posix_error();
3109 PyOS_setsig(SIGCHLD
, sig_saved
);
3110 slave_name
= ptsname(master_fd
); /* get name of slave */
3111 if (slave_name
== NULL
)
3112 return posix_error();
3113 slave_fd
= open(slave_name
, O_RDWR
| O_NOCTTY
); /* open slave */
3115 return posix_error();
3116 #if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
3117 ioctl(slave_fd
, I_PUSH
, "ptem"); /* push ptem */
3118 ioctl(slave_fd
, I_PUSH
, "ldterm"); /* push ldterm */
3120 ioctl(slave_fd
, I_PUSH
, "ttcompat"); /* push ttcompat */
3122 #endif /* HAVE_CYGWIN */
3123 #endif /* HAVE_OPENPTY */
3125 return Py_BuildValue("(ii)", master_fd
, slave_fd
);
3128 #endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
3131 PyDoc_STRVAR(posix_forkpty__doc__
,
3132 "forkpty() -> (pid, master_fd)\n\n\
3133 Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
3134 Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
3135 To both, return fd of newly opened pseudo-terminal.\n");
3138 posix_forkpty(PyObject
*self
, PyObject
*noargs
)
3140 int master_fd
= -1, pid
;
3142 pid
= forkpty(&master_fd
, NULL
, NULL
, NULL
);
3144 return posix_error();
3147 return Py_BuildValue("(ii)", pid
, master_fd
);
3152 PyDoc_STRVAR(posix_getegid__doc__
,
3153 "getegid() -> egid\n\n\
3154 Return the current process's effective group id.");
3157 posix_getegid(PyObject
*self
, PyObject
*noargs
)
3159 return PyInt_FromLong((long)getegid());
3165 PyDoc_STRVAR(posix_geteuid__doc__
,
3166 "geteuid() -> euid\n\n\
3167 Return the current process's effective user id.");
3170 posix_geteuid(PyObject
*self
, PyObject
*noargs
)
3172 return PyInt_FromLong((long)geteuid());
3178 PyDoc_STRVAR(posix_getgid__doc__
,
3179 "getgid() -> gid\n\n\
3180 Return the current process's group id.");
3183 posix_getgid(PyObject
*self
, PyObject
*noargs
)
3185 return PyInt_FromLong((long)getgid());
3190 PyDoc_STRVAR(posix_getpid__doc__
,
3191 "getpid() -> pid\n\n\
3192 Return the current process id");
3195 posix_getpid(PyObject
*self
, PyObject
*noargs
)
3197 return PyInt_FromLong((long)getpid());
3201 #ifdef HAVE_GETGROUPS
3202 PyDoc_STRVAR(posix_getgroups__doc__
,
3203 "getgroups() -> list of group IDs\n\n\
3204 Return list of supplemental group IDs for the process.");
3207 posix_getgroups(PyObject
*self
, PyObject
*noargs
)
3209 PyObject
*result
= NULL
;
3212 #define MAX_GROUPS NGROUPS_MAX
3214 /* defined to be 16 on Solaris7, so this should be a small number */
3215 #define MAX_GROUPS 64
3217 gid_t grouplist
[MAX_GROUPS
];
3220 n
= getgroups(MAX_GROUPS
, grouplist
);
3224 result
= PyList_New(n
);
3225 if (result
!= NULL
) {
3227 for (i
= 0; i
< n
; ++i
) {
3228 PyObject
*o
= PyInt_FromLong((long)grouplist
[i
]);
3234 PyList_SET_ITEM(result
, i
, o
);
3244 PyDoc_STRVAR(posix_getpgid__doc__
,
3245 "getpgid(pid) -> pgid\n\n\
3246 Call the system call getpgid().");
3249 posix_getpgid(PyObject
*self
, PyObject
*args
)
3252 if (!PyArg_ParseTuple(args
, "i:getpgid", &pid
))
3254 pgid
= getpgid(pid
);
3256 return posix_error();
3257 return PyInt_FromLong((long)pgid
);
3259 #endif /* HAVE_GETPGID */
3263 PyDoc_STRVAR(posix_getpgrp__doc__
,
3264 "getpgrp() -> pgrp\n\n\
3265 Return the current process group id.");
3268 posix_getpgrp(PyObject
*self
, PyObject
*noargs
)
3270 #ifdef GETPGRP_HAVE_ARG
3271 return PyInt_FromLong((long)getpgrp(0));
3272 #else /* GETPGRP_HAVE_ARG */
3273 return PyInt_FromLong((long)getpgrp());
3274 #endif /* GETPGRP_HAVE_ARG */
3276 #endif /* HAVE_GETPGRP */
3280 PyDoc_STRVAR(posix_setpgrp__doc__
,
3282 Make this process a session leader.");
3285 posix_setpgrp(PyObject
*self
, PyObject
*noargs
)
3287 #ifdef SETPGRP_HAVE_ARG
3288 if (setpgrp(0, 0) < 0)
3289 #else /* SETPGRP_HAVE_ARG */
3291 #endif /* SETPGRP_HAVE_ARG */
3292 return posix_error();
3297 #endif /* HAVE_SETPGRP */
3300 PyDoc_STRVAR(posix_getppid__doc__
,
3301 "getppid() -> ppid\n\n\
3302 Return the parent's process id.");
3305 posix_getppid(PyObject
*self
, PyObject
*noargs
)
3307 return PyInt_FromLong((long)getppid());
3312 #ifdef HAVE_GETLOGIN
3313 PyDoc_STRVAR(posix_getlogin__doc__
,
3314 "getlogin() -> string\n\n\
3315 Return the actual login name.");
3318 posix_getlogin(PyObject
*self
, PyObject
*noargs
)
3320 PyObject
*result
= NULL
;
3322 int old_errno
= errno
;
3330 PyErr_SetString(PyExc_OSError
,
3331 "unable to determine login name");
3334 result
= PyString_FromString(name
);
3342 PyDoc_STRVAR(posix_getuid__doc__
,
3343 "getuid() -> uid\n\n\
3344 Return the current process's user id.");
3347 posix_getuid(PyObject
*self
, PyObject
*noargs
)
3349 return PyInt_FromLong((long)getuid());
3355 PyDoc_STRVAR(posix_kill__doc__
,
3356 "kill(pid, sig)\n\n\
3357 Kill a process with a signal.");
3360 posix_kill(PyObject
*self
, PyObject
*args
)
3363 if (!PyArg_ParseTuple(args
, "ii:kill", &pid
, &sig
))
3365 #if defined(PYOS_OS2) && !defined(PYCC_GCC)
3366 if (sig
== XCPT_SIGNAL_INTR
|| sig
== XCPT_SIGNAL_BREAK
) {
3368 if ((rc
= DosSendSignalException(pid
, sig
)) != NO_ERROR
)
3369 return os2_error(rc
);
3371 } else if (sig
== XCPT_SIGNAL_KILLPROC
) {
3373 if ((rc
= DosKillProcess(DKP_PROCESS
, pid
)) != NO_ERROR
)
3374 return os2_error(rc
);
3377 return NULL
; /* Unrecognized Signal Requested */
3379 if (kill(pid
, sig
) == -1)
3380 return posix_error();
3388 PyDoc_STRVAR(posix_killpg__doc__
,
3389 "killpg(pgid, sig)\n\n\
3390 Kill a process group with a signal.");
3393 posix_killpg(PyObject
*self
, PyObject
*args
)
3396 if (!PyArg_ParseTuple(args
, "ii:killpg", &pgid
, &sig
))
3398 if (killpg(pgid
, sig
) == -1)
3399 return posix_error();
3407 #ifdef HAVE_SYS_LOCK_H
3408 #include <sys/lock.h>
3411 PyDoc_STRVAR(posix_plock__doc__
,
3413 Lock program segments into memory.");
3416 posix_plock(PyObject
*self
, PyObject
*args
)
3419 if (!PyArg_ParseTuple(args
, "i:plock", &op
))
3421 if (plock(op
) == -1)
3422 return posix_error();
3430 PyDoc_STRVAR(posix_popen__doc__
,
3431 "popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
3432 Open a pipe to/from a command returning a file object.");
3434 #if defined(PYOS_OS2)
3435 #if defined(PYCC_VACPP)
3437 async_system(const char *command
)
3439 char errormsg
[256], args
[1024];
3443 char *shell
= getenv("COMSPEC");
3447 /* avoid overflowing the argument buffer */
3448 if (strlen(shell
) + 3 + strlen(command
) >= 1024)
3449 return ERROR_NOT_ENOUGH_MEMORY
3452 strcat(args
, shell
);
3453 strcat(args
, "/c ");
3454 strcat(args
, command
);
3456 /* execute asynchronously, inheriting the environment */
3457 rc
= DosExecPgm(errormsg
,
3468 popen(const char *command
, const char *mode
, int pipesize
, int *err
)
3474 /* mode determines which of stdin or stdout is reconnected to
3475 * the pipe to the child
3477 if (strchr(mode
, 'r') != NULL
) {
3478 tgt_fd
= 1; /* stdout */
3479 } else if (strchr(mode
, 'w')) {
3480 tgt_fd
= 0; /* stdin */
3482 *err
= ERROR_INVALID_ACCESS
;
3486 /* setup the pipe */
3487 if ((rc
= DosCreatePipe(&pipeh
[0], &pipeh
[1], pipesize
)) != NO_ERROR
) {
3492 /* prevent other threads accessing stdio */
3495 /* reconnect stdio and execute child */
3498 if (dup2(pipeh
[tgtfd
], tgtfd
) == 0) {
3499 DosClose(pipeh
[tgtfd
]);
3500 rc
= async_system(command
);
3507 /* allow other threads access to stdio */
3510 /* if execution of child was successful return file stream */
3512 return fdopen(pipeh
[1 - tgtfd
], mode
);
3514 DosClose(pipeh
[1 - tgtfd
]);
3521 posix_popen(PyObject
*self
, PyObject
*args
)
3525 int err
, bufsize
= -1;
3528 if (!PyArg_ParseTuple(args
, "s|si:popen", &name
, &mode
, &bufsize
))
3530 Py_BEGIN_ALLOW_THREADS
3531 fp
= popen(name
, mode
, (bufsize
> 0) ? bufsize
: 4096, &err
);
3532 Py_END_ALLOW_THREADS
3534 return os2_error(err
);
3536 f
= PyFile_FromFile(fp
, name
, mode
, fclose
);
3538 PyFile_SetBufSize(f
, bufsize
);
3542 #elif defined(PYCC_GCC)
3544 /* standard posix version of popen() support */
3546 posix_popen(PyObject
*self
, PyObject
*args
)
3553 if (!PyArg_ParseTuple(args
, "s|si:popen", &name
, &mode
, &bufsize
))
3555 Py_BEGIN_ALLOW_THREADS
3556 fp
= popen(name
, mode
);
3557 Py_END_ALLOW_THREADS
3559 return posix_error();
3560 f
= PyFile_FromFile(fp
, name
, mode
, pclose
);
3562 PyFile_SetBufSize(f
, bufsize
);
3566 /* fork() under OS/2 has lots'o'warts
3567 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
3568 * most of this code is a ripoff of the win32 code, but using the
3569 * capabilities of EMX's C library routines
3572 /* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
3578 static PyObject
*_PyPopen(char *, int, int, int);
3579 static int _PyPclose(FILE *file
);
3582 * Internal dictionary mapping popen* file pointers to process handles,
3583 * for use when retrieving the process exit code. See _PyPclose() below
3584 * for more information on this dictionary's use.
3586 static PyObject
*_PyPopenProcs
= NULL
;
3588 /* os2emx version of popen2()
3590 * The result of this function is a pipe (file) connected to the
3591 * process's stdin, and a pipe connected to the process's stdout.
3595 os2emx_popen2(PyObject
*self
, PyObject
*args
)
3603 if (!PyArg_ParseTuple(args
, "s|si:popen2", &cmdstring
, &mode
, &bufsize
))
3608 else if (*mode
!= 'b') {
3609 PyErr_SetString(PyExc_ValueError
, "mode must be 't' or 'b'");
3614 f
= _PyPopen(cmdstring
, tm
, POPEN_2
, bufsize
);
3620 * Variation on os2emx.popen2
3622 * The result of this function is 3 pipes - the process's stdin,
3627 os2emx_popen3(PyObject
*self
, PyObject
*args
)
3635 if (!PyArg_ParseTuple(args
, "s|si:popen3", &cmdstring
, &mode
, &bufsize
))
3640 else if (*mode
!= 'b') {
3641 PyErr_SetString(PyExc_ValueError
, "mode must be 't' or 'b'");
3646 f
= _PyPopen(cmdstring
, tm
, POPEN_3
, bufsize
);
3652 * Variation on os2emx.popen2
3654 * The result of this function is 2 pipes - the processes stdin,
3655 * and stdout+stderr combined as a single pipe.
3659 os2emx_popen4(PyObject
*self
, PyObject
*args
)
3667 if (!PyArg_ParseTuple(args
, "s|si:popen4", &cmdstring
, &mode
, &bufsize
))
3672 else if (*mode
!= 'b') {
3673 PyErr_SetString(PyExc_ValueError
, "mode must be 't' or 'b'");
3678 f
= _PyPopen(cmdstring
, tm
, POPEN_4
, bufsize
);
3683 /* a couple of structures for convenient handling of multiple
3684 * file handles and pipes
3698 /* The following code is derived from the win32 code */
3701 _PyPopen(char *cmdstring
, int mode
, int n
, int bufsize
)
3703 struct file_ref stdio
[3];
3704 struct pipe_ref p_fd
[3];
3706 int file_count
, i
, pipe_err
, pipe_pid
;
3707 char *shell
, *sh_name
, *opt
, *rd_mode
, *wr_mode
;
3708 PyObject
*f
, *p_f
[3];
3710 /* file modes for subsequent fdopen's on pipe handles */
3722 /* prepare shell references */
3723 if ((shell
= getenv("EMXSHELL")) == NULL
)
3724 if ((shell
= getenv("COMSPEC")) == NULL
)
3727 return posix_error();
3730 sh_name
= _getname(shell
);
3731 if (stricmp(sh_name
, "cmd.exe") == 0 || stricmp(sh_name
, "4os2.exe") == 0)
3736 /* save current stdio fds + their flags, and set not inheritable */
3738 while (pipe_err
>= 0 && i
< 3)
3740 pipe_err
= stdio
[i
].handle
= dup(i
);
3741 stdio
[i
].flags
= fcntl(i
, F_GETFD
, 0);
3742 fcntl(stdio
[i
].handle
, F_SETFD
, stdio
[i
].flags
| FD_CLOEXEC
);
3747 /* didn't get them all saved - clean up and bail out */
3748 int saved_err
= errno
;
3751 close(stdio
[i
].handle
);
3754 return posix_error();
3757 /* create pipe ends */
3762 while ((pipe_err
== 0) && (i
< file_count
))
3763 pipe_err
= pipe((int *)&p_fd
[i
++]);
3766 /* didn't get them all made - clean up and bail out */
3773 return posix_error();
3776 /* change the actual standard IO streams over temporarily,
3777 * making the retained pipe ends non-inheritable
3782 if (dup2(p_fd
[0].rd
, 0) == 0)
3785 i
= fcntl(p_fd
[0].wr
, F_GETFD
, 0);
3786 fcntl(p_fd
[0].wr
, F_SETFD
, i
| FD_CLOEXEC
);
3787 if ((p_s
[0] = fdopen(p_fd
[0].wr
, wr_mode
)) == NULL
)
3801 if (dup2(p_fd
[1].wr
, 1) == 1)
3804 i
= fcntl(p_fd
[1].rd
, F_GETFD
, 0);
3805 fcntl(p_fd
[1].rd
, F_SETFD
, i
| FD_CLOEXEC
);
3806 if ((p_s
[1] = fdopen(p_fd
[1].rd
, rd_mode
)) == NULL
)
3818 /* - stderr, as required */
3824 if (dup2(p_fd
[2].wr
, 2) == 2)
3827 i
= fcntl(p_fd
[2].rd
, F_GETFD
, 0);
3828 fcntl(p_fd
[2].rd
, F_SETFD
, i
| FD_CLOEXEC
);
3829 if ((p_s
[2] = fdopen(p_fd
[2].rd
, rd_mode
)) == NULL
)
3844 if (dup2(1, 2) != 2)
3852 /* spawn the child process */
3855 pipe_pid
= spawnlp(P_NOWAIT
, shell
, shell
, opt
, cmdstring
, (char *)0);
3862 /* save the PID into the FILE structure
3863 * NOTE: this implementation doesn't actually
3864 * take advantage of this, but do it for
3865 * completeness - AIM Apr01
3867 for (i
= 0; i
< file_count
; i
++)
3868 p_s
[i
]->_pid
= pipe_pid
;
3872 /* reset standard IO to normal */
3873 for (i
= 0; i
< 3; i
++)
3875 dup2(stdio
[i
].handle
, i
);
3876 fcntl(i
, F_SETFD
, stdio
[i
].flags
);
3877 close(stdio
[i
].handle
);
3880 /* if any remnant problems, clean up and bail out */
3883 for (i
= 0; i
< 3; i
++)
3889 return posix_error_with_filename(cmdstring
);
3892 /* build tuple of file objects to return */
3893 if ((p_f
[0] = PyFile_FromFile(p_s
[0], cmdstring
, wr_mode
, _PyPclose
)) != NULL
)
3894 PyFile_SetBufSize(p_f
[0], bufsize
);
3895 if ((p_f
[1] = PyFile_FromFile(p_s
[1], cmdstring
, rd_mode
, _PyPclose
)) != NULL
)
3896 PyFile_SetBufSize(p_f
[1], bufsize
);
3899 if ((p_f
[2] = PyFile_FromFile(p_s
[2], cmdstring
, rd_mode
, _PyPclose
)) != NULL
)
3900 PyFile_SetBufSize(p_f
[0], bufsize
);
3901 f
= PyTuple_Pack(3, p_f
[0], p_f
[1], p_f
[2]);
3904 f
= PyTuple_Pack(2, p_f
[0], p_f
[1]);
3907 * Insert the files we've created into the process dictionary
3908 * all referencing the list with the process handle and the
3909 * initial number of files (see description below in _PyPclose).
3910 * Since if _PyPclose later tried to wait on a process when all
3911 * handles weren't closed, it could create a deadlock with the
3912 * child, we spend some energy here to try to ensure that we
3913 * either insert all file handles into the dictionary or none
3914 * at all. It's a little clumsy with the various popen modes
3915 * and variable number of files involved.
3919 _PyPopenProcs
= PyDict_New();
3924 PyObject
*procObj
, *pidObj
, *intObj
, *fileObj
[3];
3927 fileObj
[0] = fileObj
[1] = fileObj
[2] = NULL
;
3928 ins_rc
[0] = ins_rc
[1] = ins_rc
[2] = 0;
3930 procObj
= PyList_New(2);
3931 pidObj
= PyInt_FromLong((long) pipe_pid
);
3932 intObj
= PyInt_FromLong((long) file_count
);
3934 if (procObj
&& pidObj
&& intObj
)
3936 PyList_SetItem(procObj
, 0, pidObj
);
3937 PyList_SetItem(procObj
, 1, intObj
);
3939 fileObj
[0] = PyLong_FromVoidPtr(p_s
[0]);
3942 ins_rc
[0] = PyDict_SetItem(_PyPopenProcs
,
3946 fileObj
[1] = PyLong_FromVoidPtr(p_s
[1]);
3949 ins_rc
[1] = PyDict_SetItem(_PyPopenProcs
,
3953 if (file_count
>= 3)
3955 fileObj
[2] = PyLong_FromVoidPtr(p_s
[2]);
3958 ins_rc
[2] = PyDict_SetItem(_PyPopenProcs
,
3964 if (ins_rc
[0] < 0 || !fileObj
[0] ||
3965 ins_rc
[1] < 0 || (file_count
> 1 && !fileObj
[1]) ||
3966 ins_rc
[2] < 0 || (file_count
> 2 && !fileObj
[2]))
3968 /* Something failed - remove any dictionary
3969 * entries that did make it.
3971 if (!ins_rc
[0] && fileObj
[0])
3973 PyDict_DelItem(_PyPopenProcs
,
3976 if (!ins_rc
[1] && fileObj
[1])
3978 PyDict_DelItem(_PyPopenProcs
,
3981 if (!ins_rc
[2] && fileObj
[2])
3983 PyDict_DelItem(_PyPopenProcs
,
3990 * Clean up our localized references for the dictionary keys
3991 * and value since PyDict_SetItem will Py_INCREF any copies
3992 * that got placed in the dictionary.
3994 Py_XDECREF(procObj
);
3995 Py_XDECREF(fileObj
[0]);
3996 Py_XDECREF(fileObj
[1]);
3997 Py_XDECREF(fileObj
[2]);
4000 /* Child is launched. */
4005 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4006 * exit code for the child process and return as a result of the close.
4008 * This function uses the _PyPopenProcs dictionary in order to map the
4009 * input file pointer to information about the process that was
4010 * originally created by the popen* call that created the file pointer.
4011 * The dictionary uses the file pointer as a key (with one entry
4012 * inserted for each file returned by the original popen* call) and a
4013 * single list object as the value for all files from a single call.
4014 * The list object contains the Win32 process handle at [0], and a file
4015 * count at [1], which is initialized to the total number of file
4016 * handles using that list.
4018 * This function closes whichever handle it is passed, and decrements
4019 * the file count in the dictionary for the process handle pointed to
4020 * by this file. On the last close (when the file count reaches zero),
4021 * this function will wait for the child process and then return its
4022 * exit code as the result of the close() operation. This permits the
4023 * files to be closed in any order - it is always the close() of the
4024 * final handle that will return the exit code.
4026 * NOTE: This function is currently called with the GIL released.
4027 * hence we use the GILState API to manage our state.
4030 static int _PyPclose(FILE *file
)
4035 PyObject
*procObj
, *pidObj
, *intObj
, *fileObj
;
4038 PyGILState_STATE state
;
4041 /* Close the file handle first, to ensure it can't block the
4042 * child from exiting if it's the last handle.
4044 result
= fclose(file
);
4047 state
= PyGILState_Ensure();
4051 if ((fileObj
= PyLong_FromVoidPtr(file
)) != NULL
&&
4052 (procObj
= PyDict_GetItem(_PyPopenProcs
,
4053 fileObj
)) != NULL
&&
4054 (pidObj
= PyList_GetItem(procObj
,0)) != NULL
&&
4055 (intObj
= PyList_GetItem(procObj
,1)) != NULL
)
4057 pipe_pid
= (int) PyInt_AsLong(pidObj
);
4058 file_count
= (int) PyInt_AsLong(intObj
);
4062 /* Still other files referencing process */
4064 PyList_SetItem(procObj
,1,
4065 PyInt_FromLong((long) file_count
));
4069 /* Last file for this process */
4070 if (result
!= EOF
&&
4071 waitpid(pipe_pid
, &exit_code
, 0) == pipe_pid
)
4073 /* extract exit status */
4074 if (WIFEXITED(exit_code
))
4076 result
= WEXITSTATUS(exit_code
);
4086 /* Indicate failure - this will cause the file object
4087 * to raise an I/O error and translate the last
4088 * error code from errno. We do have a problem with
4089 * last errors that overlap the normal errno table,
4090 * but that's a consistent problem with the file object.
4096 /* Remove this file pointer from dictionary */
4097 PyDict_DelItem(_PyPopenProcs
, fileObj
);
4099 if (PyDict_Size(_PyPopenProcs
) == 0)
4101 Py_DECREF(_PyPopenProcs
);
4102 _PyPopenProcs
= NULL
;
4105 } /* if object retrieval ok */
4107 Py_XDECREF(fileObj
);
4108 } /* if _PyPopenProcs */
4111 PyGILState_Release(state
);
4116 #endif /* PYCC_??? */
4118 #elif defined(MS_WINDOWS)
4121 * Portable 'popen' replacement for Win32.
4123 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
4124 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
4125 * Return code handling by David Bolen <db3l@fitlinxx.com>.
4132 /* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
4138 static PyObject
*_PyPopen(char *, int, int);
4139 static int _PyPclose(FILE *file
);
4142 * Internal dictionary mapping popen* file pointers to process handles,
4143 * for use when retrieving the process exit code. See _PyPclose() below
4144 * for more information on this dictionary's use.
4146 static PyObject
*_PyPopenProcs
= NULL
;
4149 /* popen that works from a GUI.
4151 * The result of this function is a pipe (file) connected to the
4152 * processes stdin or stdout, depending on the requested mode.
4156 posix_popen(PyObject
*self
, PyObject
*args
)
4164 if (!PyArg_ParseTuple(args
, "s|si:popen", &cmdstring
, &mode
, &bufsize
))
4169 else if (*mode
!= 'w') {
4170 PyErr_SetString(PyExc_ValueError
, "popen() arg 2 must be 'r' or 'w'");
4175 if (bufsize
!= -1) {
4176 PyErr_SetString(PyExc_ValueError
, "popen() arg 3 must be -1");
4180 if (*(mode
+1) == 't')
4181 f
= _PyPopen(cmdstring
, tm
| _O_TEXT
, POPEN_1
);
4182 else if (*(mode
+1) == 'b')
4183 f
= _PyPopen(cmdstring
, tm
| _O_BINARY
, POPEN_1
);
4185 f
= _PyPopen(cmdstring
, tm
| _O_TEXT
, POPEN_1
);
4190 /* Variation on win32pipe.popen
4192 * The result of this function is a pipe (file) connected to the
4193 * process's stdin, and a pipe connected to the process's stdout.
4197 win32_popen2(PyObject
*self
, PyObject
*args
)
4205 if (!PyArg_ParseTuple(args
, "s|si:popen2", &cmdstring
, &mode
, &bufsize
))
4210 else if (*mode
!= 'b') {
4211 PyErr_SetString(PyExc_ValueError
, "popen2() arg 2 must be 't' or 'b'");
4216 if (bufsize
!= -1) {
4217 PyErr_SetString(PyExc_ValueError
, "popen2() arg 3 must be -1");
4221 f
= _PyPopen(cmdstring
, tm
, POPEN_2
);
4227 * Variation on <om win32pipe.popen>
4229 * The result of this function is 3 pipes - the process's stdin,
4234 win32_popen3(PyObject
*self
, PyObject
*args
)
4242 if (!PyArg_ParseTuple(args
, "s|si:popen3", &cmdstring
, &mode
, &bufsize
))
4247 else if (*mode
!= 'b') {
4248 PyErr_SetString(PyExc_ValueError
, "popen3() arg 2 must be 't' or 'b'");
4253 if (bufsize
!= -1) {
4254 PyErr_SetString(PyExc_ValueError
, "popen3() arg 3 must be -1");
4258 f
= _PyPopen(cmdstring
, tm
, POPEN_3
);
4264 * Variation on win32pipe.popen
4266 * The result of this function is 2 pipes - the processes stdin,
4267 * and stdout+stderr combined as a single pipe.
4271 win32_popen4(PyObject
*self
, PyObject
*args
)
4279 if (!PyArg_ParseTuple(args
, "s|si:popen4", &cmdstring
, &mode
, &bufsize
))
4284 else if (*mode
!= 'b') {
4285 PyErr_SetString(PyExc_ValueError
, "popen4() arg 2 must be 't' or 'b'");
4290 if (bufsize
!= -1) {
4291 PyErr_SetString(PyExc_ValueError
, "popen4() arg 3 must be -1");
4295 f
= _PyPopen(cmdstring
, tm
, POPEN_4
);
4301 _PyPopenCreateProcess(char *cmdstring
,
4307 PROCESS_INFORMATION piProcInfo
;
4308 STARTUPINFO siStartInfo
;
4309 DWORD dwProcessFlags
= 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
4310 char *s1
,*s2
, *s3
= " /c ";
4311 const char *szConsoleSpawn
= "w9xpopen.exe";
4315 if (i
= GetEnvironmentVariable("COMSPEC",NULL
,0)) {
4318 s1
= (char *)alloca(i
);
4319 if (!(x
= GetEnvironmentVariable("COMSPEC", s1
, i
)))
4322 /* Explicitly check if we are using COMMAND.COM. If we are
4323 * then use the w9xpopen hack.
4326 while (comshell
>= s1
&& *comshell
!= '\\')
4330 if (GetVersion() < 0x80000000 &&
4331 _stricmp(comshell
, "command.com") != 0) {
4332 /* NT/2000 and not using command.com. */
4333 x
= i
+ strlen(s3
) + strlen(cmdstring
) + 1;
4334 s2
= (char *)alloca(x
);
4336 PyOS_snprintf(s2
, x
, "%s%s%s", s1
, s3
, cmdstring
);
4340 * Oh gag, we're on Win9x or using COMMAND.COM. Use
4341 * the workaround listed in KB: Q150956
4343 char modulepath
[_MAX_PATH
];
4344 struct stat statinfo
;
4345 GetModuleFileName(NULL
, modulepath
, sizeof(modulepath
));
4346 for (i
= x
= 0; modulepath
[i
]; i
++)
4347 if (modulepath
[i
] == SEP
)
4349 modulepath
[x
] = '\0';
4350 /* Create the full-name to w9xpopen, so we can test it exists */
4353 (sizeof(modulepath
)/sizeof(modulepath
[0]))
4354 -strlen(modulepath
));
4355 if (stat(modulepath
, &statinfo
) != 0) {
4356 /* Eeek - file-not-found - possibly an embedding
4357 situation - see if we can locate it in sys.prefix
4361 sizeof(modulepath
)/sizeof(modulepath
[0]));
4362 if (modulepath
[strlen(modulepath
)-1] != '\\')
4363 strcat(modulepath
, "\\");
4366 (sizeof(modulepath
)/sizeof(modulepath
[0]))
4367 -strlen(modulepath
));
4368 /* No where else to look - raise an easily identifiable
4369 error, rather than leaving Windows to report
4370 "file not found" - as the user is probably blissfully
4371 unaware this shim EXE is used, and it will confuse them.
4372 (well, it confused me for a while ;-)
4374 if (stat(modulepath
, &statinfo
) != 0) {
4375 PyErr_Format(PyExc_RuntimeError
,
4376 "Can not locate '%s' which is needed "
4377 "for popen to work with your shell "
4383 x
= i
+ strlen(s3
) + strlen(cmdstring
) + 1 +
4384 strlen(modulepath
) +
4385 strlen(szConsoleSpawn
) + 1;
4387 s2
= (char *)alloca(x
);
4389 /* To maintain correct argument passing semantics,
4390 we pass the command-line as it stands, and allow
4391 quoting to be applied. w9xpopen.exe will then
4392 use its argv vector, and re-quote the necessary
4393 args for the ultimate child process.
4402 /* Not passing CREATE_NEW_CONSOLE has been known to
4403 cause random failures on win9x. Specifically a
4405 "Your program accessed mem currently in use at xxx"
4406 and a hopeful warning about the stability of your
4408 Cost is Ctrl+C wont kill children, but anyone
4409 who cares can have a go!
4411 dwProcessFlags
|= CREATE_NEW_CONSOLE
;
4415 /* Could be an else here to try cmd.exe / command.com in the path
4416 Now we'll just error out.. */
4418 PyErr_SetString(PyExc_RuntimeError
,
4419 "Cannot locate a COMSPEC environment variable to "
4420 "use as the shell");
4424 ZeroMemory(&siStartInfo
, sizeof(STARTUPINFO
));
4425 siStartInfo
.cb
= sizeof(STARTUPINFO
);
4426 siStartInfo
.dwFlags
= STARTF_USESTDHANDLES
| STARTF_USESHOWWINDOW
;
4427 siStartInfo
.hStdInput
= hStdin
;
4428 siStartInfo
.hStdOutput
= hStdout
;
4429 siStartInfo
.hStdError
= hStderr
;
4430 siStartInfo
.wShowWindow
= SW_HIDE
;
4432 if (CreateProcess(NULL
,
4442 /* Close the handles now so anyone waiting is woken. */
4443 CloseHandle(piProcInfo
.hThread
);
4445 /* Return process handle */
4446 *hProcess
= piProcInfo
.hProcess
;
4449 win32_error("CreateProcess", s2
);
4453 /* The following code is based off of KB: Q190351 */
4456 _PyPopen(char *cmdstring
, int mode
, int n
)
4458 HANDLE hChildStdinRd
, hChildStdinWr
, hChildStdoutRd
, hChildStdoutWr
,
4459 hChildStderrRd
, hChildStderrWr
, hChildStdinWrDup
, hChildStdoutRdDup
,
4460 hChildStderrRdDup
, hProcess
; /* hChildStdoutWrDup; */
4462 SECURITY_ATTRIBUTES saAttr
;
4469 saAttr
.nLength
= sizeof(SECURITY_ATTRIBUTES
);
4470 saAttr
.bInheritHandle
= TRUE
;
4471 saAttr
.lpSecurityDescriptor
= NULL
;
4473 if (!CreatePipe(&hChildStdinRd
, &hChildStdinWr
, &saAttr
, 0))
4474 return win32_error("CreatePipe", NULL
);
4476 /* Create new output read handle and the input write handle. Set
4477 * the inheritance properties to FALSE. Otherwise, the child inherits
4478 * these handles; resulting in non-closeable handles to the pipes
4480 fSuccess
= DuplicateHandle(GetCurrentProcess(), hChildStdinWr
,
4481 GetCurrentProcess(), &hChildStdinWrDup
, 0,
4483 DUPLICATE_SAME_ACCESS
);
4485 return win32_error("DuplicateHandle", NULL
);
4487 /* Close the inheritable version of ChildStdin
4488 that we're using. */
4489 CloseHandle(hChildStdinWr
);
4491 if (!CreatePipe(&hChildStdoutRd
, &hChildStdoutWr
, &saAttr
, 0))
4492 return win32_error("CreatePipe", NULL
);
4494 fSuccess
= DuplicateHandle(GetCurrentProcess(), hChildStdoutRd
,
4495 GetCurrentProcess(), &hChildStdoutRdDup
, 0,
4496 FALSE
, DUPLICATE_SAME_ACCESS
);
4498 return win32_error("DuplicateHandle", NULL
);
4500 /* Close the inheritable version of ChildStdout
4501 that we're using. */
4502 CloseHandle(hChildStdoutRd
);
4505 if (!CreatePipe(&hChildStderrRd
, &hChildStderrWr
, &saAttr
, 0))
4506 return win32_error("CreatePipe", NULL
);
4507 fSuccess
= DuplicateHandle(GetCurrentProcess(),
4509 GetCurrentProcess(),
4510 &hChildStderrRdDup
, 0,
4511 FALSE
, DUPLICATE_SAME_ACCESS
);
4513 return win32_error("DuplicateHandle", NULL
);
4514 /* Close the inheritable version of ChildStdErr that we're using. */
4515 CloseHandle(hChildStderrRd
);
4520 switch (mode
& (_O_RDONLY
| _O_TEXT
| _O_BINARY
| _O_WRONLY
)) {
4521 case _O_WRONLY
| _O_TEXT
:
4522 /* Case for writing to child Stdin in text mode. */
4523 fd1
= _open_osfhandle((long)hChildStdinWrDup
, mode
);
4524 f1
= _fdopen(fd1
, "w");
4525 f
= PyFile_FromFile(f1
, cmdstring
, "w", _PyPclose
);
4526 PyFile_SetBufSize(f
, 0);
4527 /* We don't care about these pipes anymore, so close them. */
4528 CloseHandle(hChildStdoutRdDup
);
4529 CloseHandle(hChildStderrRdDup
);
4532 case _O_RDONLY
| _O_TEXT
:
4533 /* Case for reading from child Stdout in text mode. */
4534 fd1
= _open_osfhandle((long)hChildStdoutRdDup
, mode
);
4535 f1
= _fdopen(fd1
, "r");
4536 f
= PyFile_FromFile(f1
, cmdstring
, "r", _PyPclose
);
4537 PyFile_SetBufSize(f
, 0);
4538 /* We don't care about these pipes anymore, so close them. */
4539 CloseHandle(hChildStdinWrDup
);
4540 CloseHandle(hChildStderrRdDup
);
4543 case _O_RDONLY
| _O_BINARY
:
4544 /* Case for readinig from child Stdout in binary mode. */
4545 fd1
= _open_osfhandle((long)hChildStdoutRdDup
, mode
);
4546 f1
= _fdopen(fd1
, "rb");
4547 f
= PyFile_FromFile(f1
, cmdstring
, "rb", _PyPclose
);
4548 PyFile_SetBufSize(f
, 0);
4549 /* We don't care about these pipes anymore, so close them. */
4550 CloseHandle(hChildStdinWrDup
);
4551 CloseHandle(hChildStderrRdDup
);
4554 case _O_WRONLY
| _O_BINARY
:
4555 /* Case for writing to child Stdin in binary mode. */
4556 fd1
= _open_osfhandle((long)hChildStdinWrDup
, mode
);
4557 f1
= _fdopen(fd1
, "wb");
4558 f
= PyFile_FromFile(f1
, cmdstring
, "wb", _PyPclose
);
4559 PyFile_SetBufSize(f
, 0);
4560 /* We don't care about these pipes anymore, so close them. */
4561 CloseHandle(hChildStdoutRdDup
);
4562 CloseHandle(hChildStderrRdDup
);
4574 if (mode
& _O_TEXT
) {
4582 fd1
= _open_osfhandle((long)hChildStdinWrDup
, mode
);
4583 f1
= _fdopen(fd1
, m2
);
4584 fd2
= _open_osfhandle((long)hChildStdoutRdDup
, mode
);
4585 f2
= _fdopen(fd2
, m1
);
4586 p1
= PyFile_FromFile(f1
, cmdstring
, m2
, _PyPclose
);
4587 PyFile_SetBufSize(p1
, 0);
4588 p2
= PyFile_FromFile(f2
, cmdstring
, m1
, _PyPclose
);
4589 PyFile_SetBufSize(p2
, 0);
4592 CloseHandle(hChildStderrRdDup
);
4594 f
= PyTuple_Pack(2,p1
,p2
);
4604 PyObject
*p1
, *p2
, *p3
;
4606 if (mode
& _O_TEXT
) {
4614 fd1
= _open_osfhandle((long)hChildStdinWrDup
, mode
);
4615 f1
= _fdopen(fd1
, m2
);
4616 fd2
= _open_osfhandle((long)hChildStdoutRdDup
, mode
);
4617 f2
= _fdopen(fd2
, m1
);
4618 fd3
= _open_osfhandle((long)hChildStderrRdDup
, mode
);
4619 f3
= _fdopen(fd3
, m1
);
4620 p1
= PyFile_FromFile(f1
, cmdstring
, m2
, _PyPclose
);
4621 p2
= PyFile_FromFile(f2
, cmdstring
, m1
, _PyPclose
);
4622 p3
= PyFile_FromFile(f3
, cmdstring
, m1
, _PyPclose
);
4623 PyFile_SetBufSize(p1
, 0);
4624 PyFile_SetBufSize(p2
, 0);
4625 PyFile_SetBufSize(p3
, 0);
4626 f
= PyTuple_Pack(3,p1
,p2
,p3
);
4636 if (!_PyPopenCreateProcess(cmdstring
,
4644 if (!_PyPopenCreateProcess(cmdstring
,
4653 * Insert the files we've created into the process dictionary
4654 * all referencing the list with the process handle and the
4655 * initial number of files (see description below in _PyPclose).
4656 * Since if _PyPclose later tried to wait on a process when all
4657 * handles weren't closed, it could create a deadlock with the
4658 * child, we spend some energy here to try to ensure that we
4659 * either insert all file handles into the dictionary or none
4660 * at all. It's a little clumsy with the various popen modes
4661 * and variable number of files involved.
4663 if (!_PyPopenProcs
) {
4664 _PyPopenProcs
= PyDict_New();
4667 if (_PyPopenProcs
) {
4668 PyObject
*procObj
, *hProcessObj
, *intObj
, *fileObj
[3];
4671 fileObj
[0] = fileObj
[1] = fileObj
[2] = NULL
;
4672 ins_rc
[0] = ins_rc
[1] = ins_rc
[2] = 0;
4674 procObj
= PyList_New(2);
4675 hProcessObj
= PyLong_FromVoidPtr(hProcess
);
4676 intObj
= PyInt_FromLong(file_count
);
4678 if (procObj
&& hProcessObj
&& intObj
) {
4679 PyList_SetItem(procObj
,0,hProcessObj
);
4680 PyList_SetItem(procObj
,1,intObj
);
4682 fileObj
[0] = PyLong_FromVoidPtr(f1
);
4684 ins_rc
[0] = PyDict_SetItem(_PyPopenProcs
,
4688 if (file_count
>= 2) {
4689 fileObj
[1] = PyLong_FromVoidPtr(f2
);
4691 ins_rc
[1] = PyDict_SetItem(_PyPopenProcs
,
4696 if (file_count
>= 3) {
4697 fileObj
[2] = PyLong_FromVoidPtr(f3
);
4699 ins_rc
[2] = PyDict_SetItem(_PyPopenProcs
,
4705 if (ins_rc
[0] < 0 || !fileObj
[0] ||
4706 ins_rc
[1] < 0 || (file_count
> 1 && !fileObj
[1]) ||
4707 ins_rc
[2] < 0 || (file_count
> 2 && !fileObj
[2])) {
4708 /* Something failed - remove any dictionary
4709 * entries that did make it.
4711 if (!ins_rc
[0] && fileObj
[0]) {
4712 PyDict_DelItem(_PyPopenProcs
,
4715 if (!ins_rc
[1] && fileObj
[1]) {
4716 PyDict_DelItem(_PyPopenProcs
,
4719 if (!ins_rc
[2] && fileObj
[2]) {
4720 PyDict_DelItem(_PyPopenProcs
,
4727 * Clean up our localized references for the dictionary keys
4728 * and value since PyDict_SetItem will Py_INCREF any copies
4729 * that got placed in the dictionary.
4731 Py_XDECREF(procObj
);
4732 Py_XDECREF(fileObj
[0]);
4733 Py_XDECREF(fileObj
[1]);
4734 Py_XDECREF(fileObj
[2]);
4737 /* Child is launched. Close the parents copy of those pipe
4738 * handles that only the child should have open. You need to
4739 * make sure that no handles to the write end of the output pipe
4740 * are maintained in this process or else the pipe will not close
4741 * when the child process exits and the ReadFile will hang. */
4743 if (!CloseHandle(hChildStdinRd
))
4744 return win32_error("CloseHandle", NULL
);
4746 if (!CloseHandle(hChildStdoutWr
))
4747 return win32_error("CloseHandle", NULL
);
4749 if ((n
!= 4) && (!CloseHandle(hChildStderrWr
)))
4750 return win32_error("CloseHandle", NULL
);
4756 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4757 * exit code for the child process and return as a result of the close.
4759 * This function uses the _PyPopenProcs dictionary in order to map the
4760 * input file pointer to information about the process that was
4761 * originally created by the popen* call that created the file pointer.
4762 * The dictionary uses the file pointer as a key (with one entry
4763 * inserted for each file returned by the original popen* call) and a
4764 * single list object as the value for all files from a single call.
4765 * The list object contains the Win32 process handle at [0], and a file
4766 * count at [1], which is initialized to the total number of file
4767 * handles using that list.
4769 * This function closes whichever handle it is passed, and decrements
4770 * the file count in the dictionary for the process handle pointed to
4771 * by this file. On the last close (when the file count reaches zero),
4772 * this function will wait for the child process and then return its
4773 * exit code as the result of the close() operation. This permits the
4774 * files to be closed in any order - it is always the close() of the
4775 * final handle that will return the exit code.
4777 * NOTE: This function is currently called with the GIL released.
4778 * hence we use the GILState API to manage our state.
4781 static int _PyPclose(FILE *file
)
4786 PyObject
*procObj
, *hProcessObj
, *intObj
, *fileObj
;
4789 PyGILState_STATE state
;
4792 /* Close the file handle first, to ensure it can't block the
4793 * child from exiting if it's the last handle.
4795 result
= fclose(file
);
4797 state
= PyGILState_Ensure();
4799 if (_PyPopenProcs
) {
4800 if ((fileObj
= PyLong_FromVoidPtr(file
)) != NULL
&&
4801 (procObj
= PyDict_GetItem(_PyPopenProcs
,
4802 fileObj
)) != NULL
&&
4803 (hProcessObj
= PyList_GetItem(procObj
,0)) != NULL
&&
4804 (intObj
= PyList_GetItem(procObj
,1)) != NULL
) {
4806 hProcess
= PyLong_AsVoidPtr(hProcessObj
);
4807 file_count
= PyInt_AsLong(intObj
);
4809 if (file_count
> 1) {
4810 /* Still other files referencing process */
4812 PyList_SetItem(procObj
,1,
4813 PyInt_FromLong(file_count
));
4815 /* Last file for this process */
4816 if (result
!= EOF
&&
4817 WaitForSingleObject(hProcess
, INFINITE
) != WAIT_FAILED
&&
4818 GetExitCodeProcess(hProcess
, &exit_code
)) {
4819 /* Possible truncation here in 16-bit environments, but
4820 * real exit codes are just the lower byte in any event.
4824 /* Indicate failure - this will cause the file object
4825 * to raise an I/O error and translate the last Win32
4826 * error code from errno. We do have a problem with
4827 * last errors that overlap the normal errno table,
4828 * but that's a consistent problem with the file object.
4830 if (result
!= EOF
) {
4831 /* If the error wasn't from the fclose(), then
4832 * set errno for the file object error handling.
4834 errno
= GetLastError();
4839 /* Free up the native handle at this point */
4840 CloseHandle(hProcess
);
4843 /* Remove this file pointer from dictionary */
4844 PyDict_DelItem(_PyPopenProcs
, fileObj
);
4846 if (PyDict_Size(_PyPopenProcs
) == 0) {
4847 Py_DECREF(_PyPopenProcs
);
4848 _PyPopenProcs
= NULL
;
4851 } /* if object retrieval ok */
4853 Py_XDECREF(fileObj
);
4854 } /* if _PyPopenProcs */
4857 PyGILState_Release(state
);
4862 #else /* which OS? */
4864 posix_popen(PyObject
*self
, PyObject
*args
)
4871 if (!PyArg_ParseTuple(args
, "s|si:popen", &name
, &mode
, &bufsize
))
4873 /* Strip mode of binary or text modifiers */
4874 if (strcmp(mode
, "rb") == 0 || strcmp(mode
, "rt") == 0)
4876 else if (strcmp(mode
, "wb") == 0 || strcmp(mode
, "wt") == 0)
4878 Py_BEGIN_ALLOW_THREADS
4879 fp
= popen(name
, mode
);
4880 Py_END_ALLOW_THREADS
4882 return posix_error();
4883 f
= PyFile_FromFile(fp
, name
, mode
, pclose
);
4885 PyFile_SetBufSize(f
, bufsize
);
4889 #endif /* PYOS_??? */
4890 #endif /* HAVE_POPEN */
4894 PyDoc_STRVAR(posix_setuid__doc__
,
4896 Set the current process's user id.");
4899 posix_setuid(PyObject
*self
, PyObject
*args
)
4902 if (!PyArg_ParseTuple(args
, "i:setuid", &uid
))
4904 if (setuid(uid
) < 0)
4905 return posix_error();
4909 #endif /* HAVE_SETUID */
4913 PyDoc_STRVAR(posix_seteuid__doc__
,
4915 Set the current process's effective user id.");
4918 posix_seteuid (PyObject
*self
, PyObject
*args
)
4921 if (!PyArg_ParseTuple(args
, "i", &euid
)) {
4923 } else if (seteuid(euid
) < 0) {
4924 return posix_error();
4930 #endif /* HAVE_SETEUID */
4933 PyDoc_STRVAR(posix_setegid__doc__
,
4935 Set the current process's effective group id.");
4938 posix_setegid (PyObject
*self
, PyObject
*args
)
4941 if (!PyArg_ParseTuple(args
, "i", &egid
)) {
4943 } else if (setegid(egid
) < 0) {
4944 return posix_error();
4950 #endif /* HAVE_SETEGID */
4952 #ifdef HAVE_SETREUID
4953 PyDoc_STRVAR(posix_setreuid__doc__
,
4954 "setreuid(ruid, euid)\n\n\
4955 Set the current process's real and effective user ids.");
4958 posix_setreuid (PyObject
*self
, PyObject
*args
)
4961 if (!PyArg_ParseTuple(args
, "ii", &ruid
, &euid
)) {
4963 } else if (setreuid(ruid
, euid
) < 0) {
4964 return posix_error();
4970 #endif /* HAVE_SETREUID */
4972 #ifdef HAVE_SETREGID
4973 PyDoc_STRVAR(posix_setregid__doc__
,
4974 "setregid(rgid, egid)\n\n\
4975 Set the current process's real and effective group ids.");
4978 posix_setregid (PyObject
*self
, PyObject
*args
)
4981 if (!PyArg_ParseTuple(args
, "ii", &rgid
, &egid
)) {
4983 } else if (setregid(rgid
, egid
) < 0) {
4984 return posix_error();
4990 #endif /* HAVE_SETREGID */
4993 PyDoc_STRVAR(posix_setgid__doc__
,
4995 Set the current process's group id.");
4998 posix_setgid(PyObject
*self
, PyObject
*args
)
5001 if (!PyArg_ParseTuple(args
, "i:setgid", &gid
))
5003 if (setgid(gid
) < 0)
5004 return posix_error();
5008 #endif /* HAVE_SETGID */
5010 #ifdef HAVE_SETGROUPS
5011 PyDoc_STRVAR(posix_setgroups__doc__
,
5012 "setgroups(list)\n\n\
5013 Set the groups of the current process to list.");
5016 posix_setgroups(PyObject
*self
, PyObject
*args
)
5020 gid_t grouplist
[MAX_GROUPS
];
5022 if (!PyArg_ParseTuple(args
, "O:setgid", &groups
))
5024 if (!PySequence_Check(groups
)) {
5025 PyErr_SetString(PyExc_TypeError
, "setgroups argument must be a sequence");
5028 len
= PySequence_Size(groups
);
5029 if (len
> MAX_GROUPS
) {
5030 PyErr_SetString(PyExc_ValueError
, "too many groups");
5033 for(i
= 0; i
< len
; i
++) {
5035 elem
= PySequence_GetItem(groups
, i
);
5038 if (!PyInt_Check(elem
)) {
5039 if (!PyLong_Check(elem
)) {
5040 PyErr_SetString(PyExc_TypeError
,
5041 "groups must be integers");
5045 unsigned long x
= PyLong_AsUnsignedLong(elem
);
5046 if (PyErr_Occurred()) {
5047 PyErr_SetString(PyExc_TypeError
,
5048 "group id too big");
5053 /* read back the value to see if it fitted in gid_t */
5054 if (grouplist
[i
] != x
) {
5055 PyErr_SetString(PyExc_TypeError
,
5056 "group id too big");
5062 long x
= PyInt_AsLong(elem
);
5064 if (grouplist
[i
] != x
) {
5065 PyErr_SetString(PyExc_TypeError
,
5066 "group id too big");
5074 if (setgroups(len
, grouplist
) < 0)
5075 return posix_error();
5079 #endif /* HAVE_SETGROUPS */
5082 PyDoc_STRVAR(posix_waitpid__doc__
,
5083 "waitpid(pid, options) -> (pid, status)\n\n\
5084 Wait for completion of a given child process.");
5087 posix_waitpid(PyObject
*self
, PyObject
*args
)
5092 #define status_i (status.w_status)
5095 #define status_i status
5099 if (!PyArg_ParseTuple(args
, "ii:waitpid", &pid
, &options
))
5101 Py_BEGIN_ALLOW_THREADS
5102 pid
= waitpid(pid
, &status
, options
);
5103 Py_END_ALLOW_THREADS
5105 return posix_error();
5107 return Py_BuildValue("ii", pid
, status_i
);
5110 #elif defined(HAVE_CWAIT)
5112 /* MS C has a variant of waitpid() that's usable for most purposes. */
5113 PyDoc_STRVAR(posix_waitpid__doc__
,
5114 "waitpid(pid, options) -> (pid, status << 8)\n\n"
5115 "Wait for completion of a given process. options is ignored on Windows.");
5118 posix_waitpid(PyObject
*self
, PyObject
*args
)
5123 if (!PyArg_ParseTuple(args
, "ii:waitpid", &pid
, &options
))
5125 Py_BEGIN_ALLOW_THREADS
5126 pid
= _cwait(&status
, pid
, options
);
5127 Py_END_ALLOW_THREADS
5129 return posix_error();
5131 /* shift the status left a byte so this is more like the
5133 return Py_BuildValue("ii", pid
, status
<< 8);
5135 #endif /* HAVE_WAITPID || HAVE_CWAIT */
5138 PyDoc_STRVAR(posix_wait__doc__
,
5139 "wait() -> (pid, status)\n\n\
5140 Wait for completion of a child process.");
5143 posix_wait(PyObject
*self
, PyObject
*noargs
)
5148 #define status_i (status.w_status)
5151 #define status_i status
5155 Py_BEGIN_ALLOW_THREADS
5156 pid
= wait(&status
);
5157 Py_END_ALLOW_THREADS
5159 return posix_error();
5161 return Py_BuildValue("ii", pid
, status_i
);
5167 PyDoc_STRVAR(posix_lstat__doc__
,
5168 "lstat(path) -> stat result\n\n\
5169 Like stat(path), but do not follow symbolic links.");
5172 posix_lstat(PyObject
*self
, PyObject
*args
)
5175 return posix_do_stat(self
, args
, "et:lstat", lstat
, NULL
, NULL
);
5176 #else /* !HAVE_LSTAT */
5178 return posix_do_stat(self
, args
, "et:lstat", STAT
, "U:lstat", win32_wstat
);
5180 return posix_do_stat(self
, args
, "et:lstat", STAT
, NULL
, NULL
);
5182 #endif /* !HAVE_LSTAT */
5186 #ifdef HAVE_READLINK
5187 PyDoc_STRVAR(posix_readlink__doc__
,
5188 "readlink(path) -> path\n\n\
5189 Return a string representing the path to which the symbolic link points.");
5192 posix_readlink(PyObject
*self
, PyObject
*args
)
5194 char buf
[MAXPATHLEN
];
5197 if (!PyArg_ParseTuple(args
, "s:readlink", &path
))
5199 Py_BEGIN_ALLOW_THREADS
5200 n
= readlink(path
, buf
, (int) sizeof buf
);
5201 Py_END_ALLOW_THREADS
5203 return posix_error_with_filename(path
);
5204 return PyString_FromStringAndSize(buf
, n
);
5206 #endif /* HAVE_READLINK */
5210 PyDoc_STRVAR(posix_symlink__doc__
,
5211 "symlink(src, dst)\n\n\
5212 Create a symbolic link pointing to src named dst.");
5215 posix_symlink(PyObject
*self
, PyObject
*args
)
5217 return posix_2str(args
, "etet:symlink", symlink
, NULL
, NULL
);
5219 #endif /* HAVE_SYMLINK */
5224 #define HZ 60 /* Universal constant :-) */
5227 #if defined(PYCC_VACPP) && defined(PYOS_OS2)
5233 Py_BEGIN_ALLOW_THREADS
5234 DosQuerySysInfo(QSV_MS_COUNT
, QSV_MS_COUNT
, &value
, sizeof(value
));
5235 Py_END_ALLOW_THREADS
5241 posix_times(PyObject
*self
, PyObject
*noargs
)
5243 /* Currently Only Uptime is Provided -- Others Later */
5244 return Py_BuildValue("ddddd",
5245 (double)0 /* t.tms_utime / HZ */,
5246 (double)0 /* t.tms_stime / HZ */,
5247 (double)0 /* t.tms_cutime / HZ */,
5248 (double)0 /* t.tms_cstime / HZ */,
5249 (double)system_uptime() / 1000);
5253 posix_times(PyObject
*self
, PyObject
*noargs
)
5259 if (c
== (clock_t) -1)
5260 return posix_error();
5261 return Py_BuildValue("ddddd",
5262 (double)t
.tms_utime
/ HZ
,
5263 (double)t
.tms_stime
/ HZ
,
5264 (double)t
.tms_cutime
/ HZ
,
5265 (double)t
.tms_cstime
/ HZ
,
5268 #endif /* not OS2 */
5269 #endif /* HAVE_TIMES */
5273 #define HAVE_TIMES /* so the method table will pick it up */
5275 posix_times(PyObject
*self
, PyObject
*noargs
)
5277 FILETIME create
, exit
, kernel
, user
;
5279 hProc
= GetCurrentProcess();
5280 GetProcessTimes(hProc
, &create
, &exit
, &kernel
, &user
);
5281 /* The fields of a FILETIME structure are the hi and lo part
5282 of a 64-bit value expressed in 100 nanosecond units.
5283 1e7 is one second in such units; 1e-7 the inverse.
5284 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
5286 return Py_BuildValue(
5288 (double)(kernel
.dwHighDateTime
*429.4967296 +
5289 kernel
.dwLowDateTime
*1e-7),
5290 (double)(user
.dwHighDateTime
*429.4967296 +
5291 user
.dwLowDateTime
*1e-7),
5296 #endif /* MS_WINDOWS */
5299 PyDoc_STRVAR(posix_times__doc__
,
5300 "times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
5301 Return a tuple of floating point numbers indicating process times.");
5306 PyDoc_STRVAR(posix_getsid__doc__
,
5307 "getsid(pid) -> sid\n\n\
5308 Call the system call getsid().");
5311 posix_getsid(PyObject
*self
, PyObject
*args
)
5314 if (!PyArg_ParseTuple(args
, "i:getsid", &pid
))
5318 return posix_error();
5319 return PyInt_FromLong((long)sid
);
5321 #endif /* HAVE_GETSID */
5325 PyDoc_STRVAR(posix_setsid__doc__
,
5327 Call the system call setsid().");
5330 posix_setsid(PyObject
*self
, PyObject
*noargs
)
5333 return posix_error();
5337 #endif /* HAVE_SETSID */
5340 PyDoc_STRVAR(posix_setpgid__doc__
,
5341 "setpgid(pid, pgrp)\n\n\
5342 Call the system call setpgid().");
5345 posix_setpgid(PyObject
*self
, PyObject
*args
)
5348 if (!PyArg_ParseTuple(args
, "ii:setpgid", &pid
, &pgrp
))
5350 if (setpgid(pid
, pgrp
) < 0)
5351 return posix_error();
5355 #endif /* HAVE_SETPGID */
5358 #ifdef HAVE_TCGETPGRP
5359 PyDoc_STRVAR(posix_tcgetpgrp__doc__
,
5360 "tcgetpgrp(fd) -> pgid\n\n\
5361 Return the process group associated with the terminal given by a fd.");
5364 posix_tcgetpgrp(PyObject
*self
, PyObject
*args
)
5367 if (!PyArg_ParseTuple(args
, "i:tcgetpgrp", &fd
))
5369 pgid
= tcgetpgrp(fd
);
5371 return posix_error();
5372 return PyInt_FromLong((long)pgid
);
5374 #endif /* HAVE_TCGETPGRP */
5377 #ifdef HAVE_TCSETPGRP
5378 PyDoc_STRVAR(posix_tcsetpgrp__doc__
,
5379 "tcsetpgrp(fd, pgid)\n\n\
5380 Set the process group associated with the terminal given by a fd.");
5383 posix_tcsetpgrp(PyObject
*self
, PyObject
*args
)
5386 if (!PyArg_ParseTuple(args
, "ii:tcsetpgrp", &fd
, &pgid
))
5388 if (tcsetpgrp(fd
, pgid
) < 0)
5389 return posix_error();
5393 #endif /* HAVE_TCSETPGRP */
5395 /* Functions acting on file descriptors */
5397 PyDoc_STRVAR(posix_open__doc__
,
5398 "open(filename, flag [, mode=0777]) -> fd\n\n\
5399 Open a file (for low level IO).");
5402 posix_open(PyObject
*self
, PyObject
*args
)
5410 if (unicode_file_names()) {
5411 PyUnicodeObject
*po
;
5412 if (PyArg_ParseTuple(args
, "Ui|i:mkdir", &po
, &flag
, &mode
)) {
5413 Py_BEGIN_ALLOW_THREADS
5414 /* PyUnicode_AS_UNICODE OK without thread
5415 lock as it is a simple dereference. */
5416 fd
= _wopen(PyUnicode_AS_UNICODE(po
), flag
, mode
);
5417 Py_END_ALLOW_THREADS
5419 return posix_error();
5420 return PyInt_FromLong((long)fd
);
5422 /* Drop the argument parsing error as narrow strings
5428 if (!PyArg_ParseTuple(args
, "eti|i",
5429 Py_FileSystemDefaultEncoding
, &file
,
5433 Py_BEGIN_ALLOW_THREADS
5434 fd
= open(file
, flag
, mode
);
5435 Py_END_ALLOW_THREADS
5437 return posix_error_with_allocated_filename(file
);
5439 return PyInt_FromLong((long)fd
);
5443 PyDoc_STRVAR(posix_close__doc__
,
5445 Close a file descriptor (for low level IO).");
5448 posix_close(PyObject
*self
, PyObject
*args
)
5451 if (!PyArg_ParseTuple(args
, "i:close", &fd
))
5453 Py_BEGIN_ALLOW_THREADS
5455 Py_END_ALLOW_THREADS
5457 return posix_error();
5463 PyDoc_STRVAR(posix_dup__doc__
,
5464 "dup(fd) -> fd2\n\n\
5465 Return a duplicate of a file descriptor.");
5468 posix_dup(PyObject
*self
, PyObject
*args
)
5471 if (!PyArg_ParseTuple(args
, "i:dup", &fd
))
5473 Py_BEGIN_ALLOW_THREADS
5475 Py_END_ALLOW_THREADS
5477 return posix_error();
5478 return PyInt_FromLong((long)fd
);
5482 PyDoc_STRVAR(posix_dup2__doc__
,
5483 "dup2(old_fd, new_fd)\n\n\
5484 Duplicate file descriptor.");
5487 posix_dup2(PyObject
*self
, PyObject
*args
)
5490 if (!PyArg_ParseTuple(args
, "ii:dup2", &fd
, &fd2
))
5492 Py_BEGIN_ALLOW_THREADS
5493 res
= dup2(fd
, fd2
);
5494 Py_END_ALLOW_THREADS
5496 return posix_error();
5502 PyDoc_STRVAR(posix_lseek__doc__
,
5503 "lseek(fd, pos, how) -> newpos\n\n\
5504 Set the current position of a file descriptor.");
5507 posix_lseek(PyObject
*self
, PyObject
*args
)
5510 #if defined(MS_WIN64) || defined(MS_WINDOWS)
5511 PY_LONG_LONG pos
, res
;
5516 if (!PyArg_ParseTuple(args
, "iOi:lseek", &fd
, &posobj
, &how
))
5519 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
5521 case 0: how
= SEEK_SET
; break;
5522 case 1: how
= SEEK_CUR
; break;
5523 case 2: how
= SEEK_END
; break;
5525 #endif /* SEEK_END */
5527 #if !defined(HAVE_LARGEFILE_SUPPORT)
5528 pos
= PyInt_AsLong(posobj
);
5530 pos
= PyLong_Check(posobj
) ?
5531 PyLong_AsLongLong(posobj
) : PyInt_AsLong(posobj
);
5533 if (PyErr_Occurred())
5536 Py_BEGIN_ALLOW_THREADS
5537 #if defined(MS_WIN64) || defined(MS_WINDOWS)
5538 res
= _lseeki64(fd
, pos
, how
);
5540 res
= lseek(fd
, pos
, how
);
5542 Py_END_ALLOW_THREADS
5544 return posix_error();
5546 #if !defined(HAVE_LARGEFILE_SUPPORT)
5547 return PyInt_FromLong(res
);
5549 return PyLong_FromLongLong(res
);
5554 PyDoc_STRVAR(posix_read__doc__
,
5555 "read(fd, buffersize) -> string\n\n\
5556 Read a file descriptor.");
5559 posix_read(PyObject
*self
, PyObject
*args
)
5563 if (!PyArg_ParseTuple(args
, "ii:read", &fd
, &size
))
5567 return posix_error();
5569 buffer
= PyString_FromStringAndSize((char *)NULL
, size
);
5572 Py_BEGIN_ALLOW_THREADS
5573 n
= read(fd
, PyString_AsString(buffer
), size
);
5574 Py_END_ALLOW_THREADS
5577 return posix_error();
5580 _PyString_Resize(&buffer
, n
);
5585 PyDoc_STRVAR(posix_write__doc__
,
5586 "write(fd, string) -> byteswritten\n\n\
5587 Write a string to a file descriptor.");
5590 posix_write(PyObject
*self
, PyObject
*args
)
5594 if (!PyArg_ParseTuple(args
, "is#:write", &fd
, &buffer
, &size
))
5596 Py_BEGIN_ALLOW_THREADS
5597 size
= write(fd
, buffer
, size
);
5598 Py_END_ALLOW_THREADS
5600 return posix_error();
5601 return PyInt_FromLong((long)size
);
5605 PyDoc_STRVAR(posix_fstat__doc__
,
5606 "fstat(fd) -> stat result\n\n\
5607 Like stat(), but for an open file descriptor.");
5610 posix_fstat(PyObject
*self
, PyObject
*args
)
5615 if (!PyArg_ParseTuple(args
, "i:fstat", &fd
))
5618 /* on OpenVMS we must ensure that all bytes are written to the file */
5621 Py_BEGIN_ALLOW_THREADS
5622 res
= FSTAT(fd
, &st
);
5623 Py_END_ALLOW_THREADS
5626 return win32_error("fstat", NULL
);
5628 return posix_error();
5632 return _pystat_fromstructstat(&st
);
5636 PyDoc_STRVAR(posix_fdopen__doc__
,
5637 "fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
5638 Return an open file object connected to a file descriptor.");
5641 posix_fdopen(PyObject
*self
, PyObject
*args
)
5648 if (!PyArg_ParseTuple(args
, "i|si", &fd
, &mode
, &bufsize
))
5651 if (mode
[0] != 'r' && mode
[0] != 'w' && mode
[0] != 'a') {
5652 PyErr_Format(PyExc_ValueError
,
5653 "invalid file mode '%s'", mode
);
5657 Py_BEGIN_ALLOW_THREADS
5658 fp
= fdopen(fd
, mode
);
5659 Py_END_ALLOW_THREADS
5661 return posix_error();
5662 f
= PyFile_FromFile(fp
, "<fdopen>", mode
, fclose
);
5664 PyFile_SetBufSize(f
, bufsize
);
5668 PyDoc_STRVAR(posix_isatty__doc__
,
5669 "isatty(fd) -> bool\n\n\
5670 Return True if the file descriptor 'fd' is an open file descriptor\n\
5671 connected to the slave end of a terminal.");
5674 posix_isatty(PyObject
*self
, PyObject
*args
)
5677 if (!PyArg_ParseTuple(args
, "i:isatty", &fd
))
5679 return PyBool_FromLong(isatty(fd
));
5683 PyDoc_STRVAR(posix_pipe__doc__
,
5684 "pipe() -> (read_end, write_end)\n\n\
5688 posix_pipe(PyObject
*self
, PyObject
*noargs
)
5690 #if defined(PYOS_OS2)
5694 Py_BEGIN_ALLOW_THREADS
5695 rc
= DosCreatePipe( &read
, &write
, 4096);
5696 Py_END_ALLOW_THREADS
5698 return os2_error(rc
);
5700 return Py_BuildValue("(ii)", read
, write
);
5702 #if !defined(MS_WINDOWS)
5705 Py_BEGIN_ALLOW_THREADS
5707 Py_END_ALLOW_THREADS
5709 return posix_error();
5710 return Py_BuildValue("(ii)", fds
[0], fds
[1]);
5711 #else /* MS_WINDOWS */
5713 int read_fd
, write_fd
;
5715 Py_BEGIN_ALLOW_THREADS
5716 ok
= CreatePipe(&read
, &write
, NULL
, 0);
5717 Py_END_ALLOW_THREADS
5719 return win32_error("CreatePipe", NULL
);
5720 read_fd
= _open_osfhandle((Py_intptr_t
)read
, 0);
5721 write_fd
= _open_osfhandle((Py_intptr_t
)write
, 1);
5722 return Py_BuildValue("(ii)", read_fd
, write_fd
);
5723 #endif /* MS_WINDOWS */
5726 #endif /* HAVE_PIPE */
5730 PyDoc_STRVAR(posix_mkfifo__doc__
,
5731 "mkfifo(filename [, mode=0666])\n\n\
5732 Create a FIFO (a POSIX named pipe).");
5735 posix_mkfifo(PyObject
*self
, PyObject
*args
)
5740 if (!PyArg_ParseTuple(args
, "s|i:mkfifo", &filename
, &mode
))
5742 Py_BEGIN_ALLOW_THREADS
5743 res
= mkfifo(filename
, mode
);
5744 Py_END_ALLOW_THREADS
5746 return posix_error();
5753 #if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
5754 PyDoc_STRVAR(posix_mknod__doc__
,
5755 "mknod(filename [, mode=0600, device])\n\n\
5756 Create a filesystem node (file, device special file or named pipe)\n\
5757 named filename. mode specifies both the permissions to use and the\n\
5758 type of node to be created, being combined (bitwise OR) with one of\n\
5759 S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
5760 device defines the newly created device special file (probably using\n\
5761 os.makedev()), otherwise it is ignored.");
5765 posix_mknod(PyObject
*self
, PyObject
*args
)
5771 if (!PyArg_ParseTuple(args
, "s|ii:mknod", &filename
, &mode
, &device
))
5773 Py_BEGIN_ALLOW_THREADS
5774 res
= mknod(filename
, mode
, device
);
5775 Py_END_ALLOW_THREADS
5777 return posix_error();
5783 #ifdef HAVE_DEVICE_MACROS
5784 PyDoc_STRVAR(posix_major__doc__
,
5785 "major(device) -> major number\n\
5786 Extracts a device major number from a raw device number.");
5789 posix_major(PyObject
*self
, PyObject
*args
)
5792 if (!PyArg_ParseTuple(args
, "i:major", &device
))
5794 return PyInt_FromLong((long)major(device
));
5797 PyDoc_STRVAR(posix_minor__doc__
,
5798 "minor(device) -> minor number\n\
5799 Extracts a device minor number from a raw device number.");
5802 posix_minor(PyObject
*self
, PyObject
*args
)
5805 if (!PyArg_ParseTuple(args
, "i:minor", &device
))
5807 return PyInt_FromLong((long)minor(device
));
5810 PyDoc_STRVAR(posix_makedev__doc__
,
5811 "makedev(major, minor) -> device number\n\
5812 Composes a raw device number from the major and minor device numbers.");
5815 posix_makedev(PyObject
*self
, PyObject
*args
)
5818 if (!PyArg_ParseTuple(args
, "ii:makedev", &major
, &minor
))
5820 return PyInt_FromLong((long)makedev(major
, minor
));
5822 #endif /* device macros */
5825 #ifdef HAVE_FTRUNCATE
5826 PyDoc_STRVAR(posix_ftruncate__doc__
,
5827 "ftruncate(fd, length)\n\n\
5828 Truncate a file to a specified length.");
5831 posix_ftruncate(PyObject
*self
, PyObject
*args
)
5838 if (!PyArg_ParseTuple(args
, "iO:ftruncate", &fd
, &lenobj
))
5841 #if !defined(HAVE_LARGEFILE_SUPPORT)
5842 length
= PyInt_AsLong(lenobj
);
5844 length
= PyLong_Check(lenobj
) ?
5845 PyLong_AsLongLong(lenobj
) : PyInt_AsLong(lenobj
);
5847 if (PyErr_Occurred())
5850 Py_BEGIN_ALLOW_THREADS
5851 res
= ftruncate(fd
, length
);
5852 Py_END_ALLOW_THREADS
5854 PyErr_SetFromErrno(PyExc_IOError
);
5863 PyDoc_STRVAR(posix_putenv__doc__
,
5864 "putenv(key, value)\n\n\
5865 Change or add an environment variable.");
5867 /* Save putenv() parameters as values here, so we can collect them when they
5868 * get re-set with another call for the same key. */
5869 static PyObject
*posix_putenv_garbage
;
5872 posix_putenv(PyObject
*self
, PyObject
*args
)
5879 if (!PyArg_ParseTuple(args
, "ss:putenv", &s1
, &s2
))
5882 #if defined(PYOS_OS2)
5883 if (stricmp(s1
, "BEGINLIBPATH") == 0) {
5886 rc
= DosSetExtLIBPATH(s2
, BEGIN_LIBPATH
);
5888 return os2_error(rc
);
5890 } else if (stricmp(s1
, "ENDLIBPATH") == 0) {
5893 rc
= DosSetExtLIBPATH(s2
, END_LIBPATH
);
5895 return os2_error(rc
);
5899 /* XXX This can leak memory -- not easy to fix :-( */
5900 len
= strlen(s1
) + strlen(s2
) + 2;
5901 /* len includes space for a trailing \0; the size arg to
5902 PyString_FromStringAndSize does not count that */
5903 newstr
= PyString_FromStringAndSize(NULL
, (int)len
- 1);
5905 return PyErr_NoMemory();
5906 new = PyString_AS_STRING(newstr
);
5907 PyOS_snprintf(new, len
, "%s=%s", s1
, s2
);
5913 /* Install the first arg and newstr in posix_putenv_garbage;
5914 * this will cause previous value to be collected. This has to
5915 * happen after the real putenv() call because the old value
5916 * was still accessible until then. */
5917 if (PyDict_SetItem(posix_putenv_garbage
,
5918 PyTuple_GET_ITEM(args
, 0), newstr
)) {
5919 /* really not much we can do; just leak */
5926 #if defined(PYOS_OS2)
5934 #ifdef HAVE_UNSETENV
5935 PyDoc_STRVAR(posix_unsetenv__doc__
,
5937 Delete an environment variable.");
5940 posix_unsetenv(PyObject
*self
, PyObject
*args
)
5944 if (!PyArg_ParseTuple(args
, "s:unsetenv", &s1
))
5949 /* Remove the key from posix_putenv_garbage;
5950 * this will cause it to be collected. This has to
5951 * happen after the real unsetenv() call because the
5952 * old value was still accessible until then.
5954 if (PyDict_DelItem(posix_putenv_garbage
,
5955 PyTuple_GET_ITEM(args
, 0))) {
5956 /* really not much we can do; just leak */
5963 #endif /* unsetenv */
5965 #ifdef HAVE_STRERROR
5966 PyDoc_STRVAR(posix_strerror__doc__
,
5967 "strerror(code) -> string\n\n\
5968 Translate an error code to a message string.");
5971 posix_strerror(PyObject
*self
, PyObject
*args
)
5975 if (!PyArg_ParseTuple(args
, "i:strerror", &code
))
5977 message
= strerror(code
);
5978 if (message
== NULL
) {
5979 PyErr_SetString(PyExc_ValueError
,
5980 "strerror() argument out of range");
5983 return PyString_FromString(message
);
5985 #endif /* strerror */
5988 #ifdef HAVE_SYS_WAIT_H
5991 PyDoc_STRVAR(posix_WCOREDUMP__doc__
,
5992 "WCOREDUMP(status) -> bool\n\n\
5993 Return True if the process returning 'status' was dumped to a core file.");
5996 posix_WCOREDUMP(PyObject
*self
, PyObject
*args
)
6000 #define status_i (status.w_status)
6003 #define status_i status
6007 if (!PyArg_ParseTuple(args
, "i:WCOREDUMP", &status_i
))
6012 return PyBool_FromLong(WCOREDUMP(status
));
6015 #endif /* WCOREDUMP */
6018 PyDoc_STRVAR(posix_WIFCONTINUED__doc__
,
6019 "WIFCONTINUED(status) -> bool\n\n\
6020 Return True if the process returning 'status' was continued from a\n\
6021 job control stop.");
6024 posix_WIFCONTINUED(PyObject
*self
, PyObject
*args
)
6028 #define status_i (status.w_status)
6031 #define status_i status
6035 if (!PyArg_ParseTuple(args
, "i:WCONTINUED", &status_i
))
6040 return PyBool_FromLong(WIFCONTINUED(status
));
6043 #endif /* WIFCONTINUED */
6046 PyDoc_STRVAR(posix_WIFSTOPPED__doc__
,
6047 "WIFSTOPPED(status) -> bool\n\n\
6048 Return True if the process returning 'status' was stopped.");
6051 posix_WIFSTOPPED(PyObject
*self
, PyObject
*args
)
6055 #define status_i (status.w_status)
6058 #define status_i status
6062 if (!PyArg_ParseTuple(args
, "i:WIFSTOPPED", &status_i
))
6067 return PyBool_FromLong(WIFSTOPPED(status
));
6070 #endif /* WIFSTOPPED */
6073 PyDoc_STRVAR(posix_WIFSIGNALED__doc__
,
6074 "WIFSIGNALED(status) -> bool\n\n\
6075 Return True if the process returning 'status' was terminated by a signal.");
6078 posix_WIFSIGNALED(PyObject
*self
, PyObject
*args
)
6082 #define status_i (status.w_status)
6085 #define status_i status
6089 if (!PyArg_ParseTuple(args
, "i:WIFSIGNALED", &status_i
))
6094 return PyBool_FromLong(WIFSIGNALED(status
));
6097 #endif /* WIFSIGNALED */
6100 PyDoc_STRVAR(posix_WIFEXITED__doc__
,
6101 "WIFEXITED(status) -> bool\n\n\
6102 Return true if the process returning 'status' exited using the exit()\n\
6106 posix_WIFEXITED(PyObject
*self
, PyObject
*args
)
6110 #define status_i (status.w_status)
6113 #define status_i status
6117 if (!PyArg_ParseTuple(args
, "i:WIFEXITED", &status_i
))
6122 return PyBool_FromLong(WIFEXITED(status
));
6125 #endif /* WIFEXITED */
6128 PyDoc_STRVAR(posix_WEXITSTATUS__doc__
,
6129 "WEXITSTATUS(status) -> integer\n\n\
6130 Return the process return code from 'status'.");
6133 posix_WEXITSTATUS(PyObject
*self
, PyObject
*args
)
6137 #define status_i (status.w_status)
6140 #define status_i status
6144 if (!PyArg_ParseTuple(args
, "i:WEXITSTATUS", &status_i
))
6149 return Py_BuildValue("i", WEXITSTATUS(status
));
6152 #endif /* WEXITSTATUS */
6155 PyDoc_STRVAR(posix_WTERMSIG__doc__
,
6156 "WTERMSIG(status) -> integer\n\n\
6157 Return the signal that terminated the process that provided the 'status'\n\
6161 posix_WTERMSIG(PyObject
*self
, PyObject
*args
)
6165 #define status_i (status.w_status)
6168 #define status_i status
6172 if (!PyArg_ParseTuple(args
, "i:WTERMSIG", &status_i
))
6177 return Py_BuildValue("i", WTERMSIG(status
));
6180 #endif /* WTERMSIG */
6183 PyDoc_STRVAR(posix_WSTOPSIG__doc__
,
6184 "WSTOPSIG(status) -> integer\n\n\
6185 Return the signal that stopped the process that provided\n\
6186 the 'status' value.");
6189 posix_WSTOPSIG(PyObject
*self
, PyObject
*args
)
6193 #define status_i (status.w_status)
6196 #define status_i status
6200 if (!PyArg_ParseTuple(args
, "i:WSTOPSIG", &status_i
))
6205 return Py_BuildValue("i", WSTOPSIG(status
));
6208 #endif /* WSTOPSIG */
6210 #endif /* HAVE_SYS_WAIT_H */
6213 #if defined(HAVE_FSTATVFS)
6215 /* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
6216 needed definitions in sys/statvfs.h */
6219 #include <sys/statvfs.h>
6222 _pystatvfs_fromstructstatvfs(struct statvfs st
) {
6223 PyObject
*v
= PyStructSequence_New(&StatVFSResultType
);
6227 #if !defined(HAVE_LARGEFILE_SUPPORT)
6228 PyStructSequence_SET_ITEM(v
, 0, PyInt_FromLong((long) st
.f_bsize
));
6229 PyStructSequence_SET_ITEM(v
, 1, PyInt_FromLong((long) st
.f_frsize
));
6230 PyStructSequence_SET_ITEM(v
, 2, PyInt_FromLong((long) st
.f_blocks
));
6231 PyStructSequence_SET_ITEM(v
, 3, PyInt_FromLong((long) st
.f_bfree
));
6232 PyStructSequence_SET_ITEM(v
, 4, PyInt_FromLong((long) st
.f_bavail
));
6233 PyStructSequence_SET_ITEM(v
, 5, PyInt_FromLong((long) st
.f_files
));
6234 PyStructSequence_SET_ITEM(v
, 6, PyInt_FromLong((long) st
.f_ffree
));
6235 PyStructSequence_SET_ITEM(v
, 7, PyInt_FromLong((long) st
.f_favail
));
6236 PyStructSequence_SET_ITEM(v
, 8, PyInt_FromLong((long) st
.f_flag
));
6237 PyStructSequence_SET_ITEM(v
, 9, PyInt_FromLong((long) st
.f_namemax
));
6239 PyStructSequence_SET_ITEM(v
, 0, PyInt_FromLong((long) st
.f_bsize
));
6240 PyStructSequence_SET_ITEM(v
, 1, PyInt_FromLong((long) st
.f_frsize
));
6241 PyStructSequence_SET_ITEM(v
, 2,
6242 PyLong_FromLongLong((PY_LONG_LONG
) st
.f_blocks
));
6243 PyStructSequence_SET_ITEM(v
, 3,
6244 PyLong_FromLongLong((PY_LONG_LONG
) st
.f_bfree
));
6245 PyStructSequence_SET_ITEM(v
, 4,
6246 PyLong_FromLongLong((PY_LONG_LONG
) st
.f_bavail
));
6247 PyStructSequence_SET_ITEM(v
, 5,
6248 PyLong_FromLongLong((PY_LONG_LONG
) st
.f_files
));
6249 PyStructSequence_SET_ITEM(v
, 6,
6250 PyLong_FromLongLong((PY_LONG_LONG
) st
.f_ffree
));
6251 PyStructSequence_SET_ITEM(v
, 7,
6252 PyLong_FromLongLong((PY_LONG_LONG
) st
.f_favail
));
6253 PyStructSequence_SET_ITEM(v
, 8, PyInt_FromLong((long) st
.f_flag
));
6254 PyStructSequence_SET_ITEM(v
, 9, PyInt_FromLong((long) st
.f_namemax
));
6260 PyDoc_STRVAR(posix_fstatvfs__doc__
,
6261 "fstatvfs(fd) -> statvfs result\n\n\
6262 Perform an fstatvfs system call on the given fd.");
6265 posix_fstatvfs(PyObject
*self
, PyObject
*args
)
6270 if (!PyArg_ParseTuple(args
, "i:fstatvfs", &fd
))
6272 Py_BEGIN_ALLOW_THREADS
6273 res
= fstatvfs(fd
, &st
);
6274 Py_END_ALLOW_THREADS
6276 return posix_error();
6278 return _pystatvfs_fromstructstatvfs(st
);
6280 #endif /* HAVE_FSTATVFS */
6283 #if defined(HAVE_STATVFS)
6284 #include <sys/statvfs.h>
6286 PyDoc_STRVAR(posix_statvfs__doc__
,
6287 "statvfs(path) -> statvfs result\n\n\
6288 Perform a statvfs system call on the given path.");
6291 posix_statvfs(PyObject
*self
, PyObject
*args
)
6296 if (!PyArg_ParseTuple(args
, "s:statvfs", &path
))
6298 Py_BEGIN_ALLOW_THREADS
6299 res
= statvfs(path
, &st
);
6300 Py_END_ALLOW_THREADS
6302 return posix_error_with_filename(path
);
6304 return _pystatvfs_fromstructstatvfs(st
);
6306 #endif /* HAVE_STATVFS */
6310 PyDoc_STRVAR(posix_tempnam__doc__
,
6311 "tempnam([dir[, prefix]]) -> string\n\n\
6312 Return a unique name for a temporary file.\n\
6313 The directory and a prefix may be specified as strings; they may be omitted\n\
6314 or None if not needed.");
6317 posix_tempnam(PyObject
*self
, PyObject
*args
)
6319 PyObject
*result
= NULL
;
6324 if (!PyArg_ParseTuple(args
, "|zz:tempnam", &dir
, &pfx
))
6327 if (PyErr_Warn(PyExc_RuntimeWarning
,
6328 "tempnam is a potential security risk to your program") < 0)
6332 name
= _tempnam(dir
, pfx
);
6334 name
= tempnam(dir
, pfx
);
6337 return PyErr_NoMemory();
6338 result
= PyString_FromString(name
);
6346 PyDoc_STRVAR(posix_tmpfile__doc__
,
6347 "tmpfile() -> file object\n\n\
6348 Create a temporary file with no directory entries.");
6351 posix_tmpfile(PyObject
*self
, PyObject
*noargs
)
6357 return posix_error();
6358 return PyFile_FromFile(fp
, "<tmpfile>", "w+b", fclose
);
6364 PyDoc_STRVAR(posix_tmpnam__doc__
,
6365 "tmpnam() -> string\n\n\
6366 Return a unique name for a temporary file.");
6369 posix_tmpnam(PyObject
*self
, PyObject
*noargs
)
6371 char buffer
[L_tmpnam
];
6374 if (PyErr_Warn(PyExc_RuntimeWarning
,
6375 "tmpnam is a potential security risk to your program") < 0)
6379 name
= tmpnam_r(buffer
);
6381 name
= tmpnam(buffer
);
6384 PyErr_SetObject(PyExc_OSError
,
6385 Py_BuildValue("is", 0,
6387 "unexpected NULL from tmpnam_r"
6389 "unexpected NULL from tmpnam"
6394 return PyString_FromString(buffer
);
6399 /* This is used for fpathconf(), pathconf(), confstr() and sysconf().
6400 * It maps strings representing configuration variable names to
6401 * integer values, allowing those functions to be called with the
6402 * magic names instead of polluting the module's namespace with tons of
6403 * rarely-used constants. There are three separate tables that use
6404 * these definitions.
6406 * This code is always included, even if none of the interfaces that
6407 * need it are included. The #if hackery needed to avoid it would be
6408 * sufficiently pervasive that it's not worth the loss of readability.
6416 conv_confname(PyObject
*arg
, int *valuep
, struct constdef
*table
,
6419 if (PyInt_Check(arg
)) {
6420 *valuep
= PyInt_AS_LONG(arg
);
6423 if (PyString_Check(arg
)) {
6424 /* look up the value in the table using a binary search */
6427 size_t hi
= tablesize
;
6429 char *confname
= PyString_AS_STRING(arg
);
6431 mid
= (lo
+ hi
) / 2;
6432 cmp
= strcmp(confname
, table
[mid
].name
);
6438 *valuep
= table
[mid
].value
;
6442 PyErr_SetString(PyExc_ValueError
, "unrecognized configuration name");
6445 PyErr_SetString(PyExc_TypeError
,
6446 "configuration names must be strings or integers");
6451 #if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
6452 static struct constdef posix_constants_pathconf
[] = {
6453 #ifdef _PC_ABI_AIO_XFER_MAX
6454 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX
},
6456 #ifdef _PC_ABI_ASYNC_IO
6457 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO
},
6460 {"PC_ASYNC_IO", _PC_ASYNC_IO
},
6462 #ifdef _PC_CHOWN_RESTRICTED
6463 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED
},
6465 #ifdef _PC_FILESIZEBITS
6466 {"PC_FILESIZEBITS", _PC_FILESIZEBITS
},
6469 {"PC_LAST", _PC_LAST
},
6472 {"PC_LINK_MAX", _PC_LINK_MAX
},
6474 #ifdef _PC_MAX_CANON
6475 {"PC_MAX_CANON", _PC_MAX_CANON
},
6477 #ifdef _PC_MAX_INPUT
6478 {"PC_MAX_INPUT", _PC_MAX_INPUT
},
6481 {"PC_NAME_MAX", _PC_NAME_MAX
},
6484 {"PC_NO_TRUNC", _PC_NO_TRUNC
},
6487 {"PC_PATH_MAX", _PC_PATH_MAX
},
6490 {"PC_PIPE_BUF", _PC_PIPE_BUF
},
6493 {"PC_PRIO_IO", _PC_PRIO_IO
},
6495 #ifdef _PC_SOCK_MAXBUF
6496 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF
},
6499 {"PC_SYNC_IO", _PC_SYNC_IO
},
6502 {"PC_VDISABLE", _PC_VDISABLE
},
6507 conv_path_confname(PyObject
*arg
, int *valuep
)
6509 return conv_confname(arg
, valuep
, posix_constants_pathconf
,
6510 sizeof(posix_constants_pathconf
)
6511 / sizeof(struct constdef
));
6515 #ifdef HAVE_FPATHCONF
6516 PyDoc_STRVAR(posix_fpathconf__doc__
,
6517 "fpathconf(fd, name) -> integer\n\n\
6518 Return the configuration limit name for the file descriptor fd.\n\
6519 If there is no limit, return -1.");
6522 posix_fpathconf(PyObject
*self
, PyObject
*args
)
6524 PyObject
*result
= NULL
;
6527 if (PyArg_ParseTuple(args
, "iO&:fpathconf", &fd
,
6528 conv_path_confname
, &name
)) {
6532 limit
= fpathconf(fd
, name
);
6533 if (limit
== -1 && errno
!= 0)
6536 result
= PyInt_FromLong(limit
);
6543 #ifdef HAVE_PATHCONF
6544 PyDoc_STRVAR(posix_pathconf__doc__
,
6545 "pathconf(path, name) -> integer\n\n\
6546 Return the configuration limit name for the file or directory path.\n\
6547 If there is no limit, return -1.");
6550 posix_pathconf(PyObject
*self
, PyObject
*args
)
6552 PyObject
*result
= NULL
;
6556 if (PyArg_ParseTuple(args
, "sO&:pathconf", &path
,
6557 conv_path_confname
, &name
)) {
6561 limit
= pathconf(path
, name
);
6562 if (limit
== -1 && errno
!= 0) {
6563 if (errno
== EINVAL
)
6564 /* could be a path or name problem */
6567 posix_error_with_filename(path
);
6570 result
= PyInt_FromLong(limit
);
6577 static struct constdef posix_constants_confstr
[] = {
6578 #ifdef _CS_ARCHITECTURE
6579 {"CS_ARCHITECTURE", _CS_ARCHITECTURE
},
6582 {"CS_HOSTNAME", _CS_HOSTNAME
},
6584 #ifdef _CS_HW_PROVIDER
6585 {"CS_HW_PROVIDER", _CS_HW_PROVIDER
},
6587 #ifdef _CS_HW_SERIAL
6588 {"CS_HW_SERIAL", _CS_HW_SERIAL
},
6590 #ifdef _CS_INITTAB_NAME
6591 {"CS_INITTAB_NAME", _CS_INITTAB_NAME
},
6593 #ifdef _CS_LFS64_CFLAGS
6594 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS
},
6596 #ifdef _CS_LFS64_LDFLAGS
6597 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS
},
6599 #ifdef _CS_LFS64_LIBS
6600 {"CS_LFS64_LIBS", _CS_LFS64_LIBS
},
6602 #ifdef _CS_LFS64_LINTFLAGS
6603 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS
},
6605 #ifdef _CS_LFS_CFLAGS
6606 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS
},
6608 #ifdef _CS_LFS_LDFLAGS
6609 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS
},
6612 {"CS_LFS_LIBS", _CS_LFS_LIBS
},
6614 #ifdef _CS_LFS_LINTFLAGS
6615 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS
},
6618 {"CS_MACHINE", _CS_MACHINE
},
6621 {"CS_PATH", _CS_PATH
},
6624 {"CS_RELEASE", _CS_RELEASE
},
6626 #ifdef _CS_SRPC_DOMAIN
6627 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN
},
6630 {"CS_SYSNAME", _CS_SYSNAME
},
6633 {"CS_VERSION", _CS_VERSION
},
6635 #ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
6636 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS
},
6638 #ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
6639 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS
},
6641 #ifdef _CS_XBS5_ILP32_OFF32_LIBS
6642 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS
},
6644 #ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
6645 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS
},
6647 #ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
6648 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS
},
6650 #ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
6651 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS
},
6653 #ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
6654 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS
},
6656 #ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
6657 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
},
6659 #ifdef _CS_XBS5_LP64_OFF64_CFLAGS
6660 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS
},
6662 #ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
6663 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS
},
6665 #ifdef _CS_XBS5_LP64_OFF64_LIBS
6666 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS
},
6668 #ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
6669 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS
},
6671 #ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
6672 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS
},
6674 #ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
6675 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
},
6677 #ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
6678 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS
},
6680 #ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
6681 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
},
6683 #ifdef _MIPS_CS_AVAIL_PROCESSORS
6684 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS
},
6686 #ifdef _MIPS_CS_BASE
6687 {"MIPS_CS_BASE", _MIPS_CS_BASE
},
6689 #ifdef _MIPS_CS_HOSTID
6690 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID
},
6692 #ifdef _MIPS_CS_HW_NAME
6693 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME
},
6695 #ifdef _MIPS_CS_NUM_PROCESSORS
6696 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS
},
6698 #ifdef _MIPS_CS_OSREL_MAJ
6699 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ
},
6701 #ifdef _MIPS_CS_OSREL_MIN
6702 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN
},
6704 #ifdef _MIPS_CS_OSREL_PATCH
6705 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH
},
6707 #ifdef _MIPS_CS_OS_NAME
6708 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME
},
6710 #ifdef _MIPS_CS_OS_PROVIDER
6711 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER
},
6713 #ifdef _MIPS_CS_PROCESSORS
6714 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS
},
6716 #ifdef _MIPS_CS_SERIAL
6717 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL
},
6719 #ifdef _MIPS_CS_VENDOR
6720 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR
},
6725 conv_confstr_confname(PyObject
*arg
, int *valuep
)
6727 return conv_confname(arg
, valuep
, posix_constants_confstr
,
6728 sizeof(posix_constants_confstr
)
6729 / sizeof(struct constdef
));
6732 PyDoc_STRVAR(posix_confstr__doc__
,
6733 "confstr(name) -> string\n\n\
6734 Return a string-valued system configuration variable.");
6737 posix_confstr(PyObject
*self
, PyObject
*args
)
6739 PyObject
*result
= NULL
;
6743 if (PyArg_ParseTuple(args
, "O&:confstr", conv_confstr_confname
, &name
)) {
6744 int len
= confstr(name
, buffer
, sizeof(buffer
));
6751 result
= PyString_FromString("");
6754 if (len
>= sizeof(buffer
)) {
6755 result
= PyString_FromStringAndSize(NULL
, len
);
6757 confstr(name
, PyString_AS_STRING(result
), len
+1);
6760 result
= PyString_FromString(buffer
);
6769 static struct constdef posix_constants_sysconf
[] = {
6770 #ifdef _SC_2_CHAR_TERM
6771 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM
},
6774 {"SC_2_C_BIND", _SC_2_C_BIND
},
6777 {"SC_2_C_DEV", _SC_2_C_DEV
},
6779 #ifdef _SC_2_C_VERSION
6780 {"SC_2_C_VERSION", _SC_2_C_VERSION
},
6782 #ifdef _SC_2_FORT_DEV
6783 {"SC_2_FORT_DEV", _SC_2_FORT_DEV
},
6785 #ifdef _SC_2_FORT_RUN
6786 {"SC_2_FORT_RUN", _SC_2_FORT_RUN
},
6788 #ifdef _SC_2_LOCALEDEF
6789 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF
},
6792 {"SC_2_SW_DEV", _SC_2_SW_DEV
},
6795 {"SC_2_UPE", _SC_2_UPE
},
6797 #ifdef _SC_2_VERSION
6798 {"SC_2_VERSION", _SC_2_VERSION
},
6800 #ifdef _SC_ABI_ASYNCHRONOUS_IO
6801 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO
},
6804 {"SC_ACL", _SC_ACL
},
6806 #ifdef _SC_AIO_LISTIO_MAX
6807 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX
},
6810 {"SC_AIO_MAX", _SC_AIO_MAX
},
6812 #ifdef _SC_AIO_PRIO_DELTA_MAX
6813 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX
},
6816 {"SC_ARG_MAX", _SC_ARG_MAX
},
6818 #ifdef _SC_ASYNCHRONOUS_IO
6819 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO
},
6821 #ifdef _SC_ATEXIT_MAX
6822 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX
},
6825 {"SC_AUDIT", _SC_AUDIT
},
6827 #ifdef _SC_AVPHYS_PAGES
6828 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES
},
6830 #ifdef _SC_BC_BASE_MAX
6831 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX
},
6833 #ifdef _SC_BC_DIM_MAX
6834 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX
},
6836 #ifdef _SC_BC_SCALE_MAX
6837 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX
},
6839 #ifdef _SC_BC_STRING_MAX
6840 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX
},
6843 {"SC_CAP", _SC_CAP
},
6845 #ifdef _SC_CHARCLASS_NAME_MAX
6846 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX
},
6849 {"SC_CHAR_BIT", _SC_CHAR_BIT
},
6852 {"SC_CHAR_MAX", _SC_CHAR_MAX
},
6855 {"SC_CHAR_MIN", _SC_CHAR_MIN
},
6857 #ifdef _SC_CHILD_MAX
6858 {"SC_CHILD_MAX", _SC_CHILD_MAX
},
6861 {"SC_CLK_TCK", _SC_CLK_TCK
},
6863 #ifdef _SC_COHER_BLKSZ
6864 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ
},
6866 #ifdef _SC_COLL_WEIGHTS_MAX
6867 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX
},
6869 #ifdef _SC_DCACHE_ASSOC
6870 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC
},
6872 #ifdef _SC_DCACHE_BLKSZ
6873 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ
},
6875 #ifdef _SC_DCACHE_LINESZ
6876 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ
},
6878 #ifdef _SC_DCACHE_SZ
6879 {"SC_DCACHE_SZ", _SC_DCACHE_SZ
},
6881 #ifdef _SC_DCACHE_TBLKSZ
6882 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ
},
6884 #ifdef _SC_DELAYTIMER_MAX
6885 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX
},
6887 #ifdef _SC_EQUIV_CLASS_MAX
6888 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX
},
6890 #ifdef _SC_EXPR_NEST_MAX
6891 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX
},
6894 {"SC_FSYNC", _SC_FSYNC
},
6896 #ifdef _SC_GETGR_R_SIZE_MAX
6897 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX
},
6899 #ifdef _SC_GETPW_R_SIZE_MAX
6900 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX
},
6902 #ifdef _SC_ICACHE_ASSOC
6903 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC
},
6905 #ifdef _SC_ICACHE_BLKSZ
6906 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ
},
6908 #ifdef _SC_ICACHE_LINESZ
6909 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ
},
6911 #ifdef _SC_ICACHE_SZ
6912 {"SC_ICACHE_SZ", _SC_ICACHE_SZ
},
6915 {"SC_INF", _SC_INF
},
6918 {"SC_INT_MAX", _SC_INT_MAX
},
6921 {"SC_INT_MIN", _SC_INT_MIN
},
6924 {"SC_IOV_MAX", _SC_IOV_MAX
},
6926 #ifdef _SC_IP_SECOPTS
6927 {"SC_IP_SECOPTS", _SC_IP_SECOPTS
},
6929 #ifdef _SC_JOB_CONTROL
6930 {"SC_JOB_CONTROL", _SC_JOB_CONTROL
},
6932 #ifdef _SC_KERN_POINTERS
6933 {"SC_KERN_POINTERS", _SC_KERN_POINTERS
},
6936 {"SC_KERN_SIM", _SC_KERN_SIM
},
6939 {"SC_LINE_MAX", _SC_LINE_MAX
},
6941 #ifdef _SC_LOGIN_NAME_MAX
6942 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX
},
6944 #ifdef _SC_LOGNAME_MAX
6945 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX
},
6948 {"SC_LONG_BIT", _SC_LONG_BIT
},
6951 {"SC_MAC", _SC_MAC
},
6953 #ifdef _SC_MAPPED_FILES
6954 {"SC_MAPPED_FILES", _SC_MAPPED_FILES
},
6957 {"SC_MAXPID", _SC_MAXPID
},
6959 #ifdef _SC_MB_LEN_MAX
6960 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX
},
6963 {"SC_MEMLOCK", _SC_MEMLOCK
},
6965 #ifdef _SC_MEMLOCK_RANGE
6966 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE
},
6968 #ifdef _SC_MEMORY_PROTECTION
6969 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION
},
6971 #ifdef _SC_MESSAGE_PASSING
6972 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING
},
6974 #ifdef _SC_MMAP_FIXED_ALIGNMENT
6975 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT
},
6977 #ifdef _SC_MQ_OPEN_MAX
6978 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX
},
6980 #ifdef _SC_MQ_PRIO_MAX
6981 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX
},
6983 #ifdef _SC_NACLS_MAX
6984 {"SC_NACLS_MAX", _SC_NACLS_MAX
},
6986 #ifdef _SC_NGROUPS_MAX
6987 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX
},
6989 #ifdef _SC_NL_ARGMAX
6990 {"SC_NL_ARGMAX", _SC_NL_ARGMAX
},
6992 #ifdef _SC_NL_LANGMAX
6993 {"SC_NL_LANGMAX", _SC_NL_LANGMAX
},
6995 #ifdef _SC_NL_MSGMAX
6996 {"SC_NL_MSGMAX", _SC_NL_MSGMAX
},
6999 {"SC_NL_NMAX", _SC_NL_NMAX
},
7001 #ifdef _SC_NL_SETMAX
7002 {"SC_NL_SETMAX", _SC_NL_SETMAX
},
7004 #ifdef _SC_NL_TEXTMAX
7005 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX
},
7007 #ifdef _SC_NPROCESSORS_CONF
7008 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF
},
7010 #ifdef _SC_NPROCESSORS_ONLN
7011 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN
},
7013 #ifdef _SC_NPROC_CONF
7014 {"SC_NPROC_CONF", _SC_NPROC_CONF
},
7016 #ifdef _SC_NPROC_ONLN
7017 {"SC_NPROC_ONLN", _SC_NPROC_ONLN
},
7020 {"SC_NZERO", _SC_NZERO
},
7023 {"SC_OPEN_MAX", _SC_OPEN_MAX
},
7026 {"SC_PAGESIZE", _SC_PAGESIZE
},
7028 #ifdef _SC_PAGE_SIZE
7029 {"SC_PAGE_SIZE", _SC_PAGE_SIZE
},
7032 {"SC_PASS_MAX", _SC_PASS_MAX
},
7034 #ifdef _SC_PHYS_PAGES
7035 {"SC_PHYS_PAGES", _SC_PHYS_PAGES
},
7038 {"SC_PII", _SC_PII
},
7040 #ifdef _SC_PII_INTERNET
7041 {"SC_PII_INTERNET", _SC_PII_INTERNET
},
7043 #ifdef _SC_PII_INTERNET_DGRAM
7044 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM
},
7046 #ifdef _SC_PII_INTERNET_STREAM
7047 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM
},
7050 {"SC_PII_OSI", _SC_PII_OSI
},
7052 #ifdef _SC_PII_OSI_CLTS
7053 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS
},
7055 #ifdef _SC_PII_OSI_COTS
7056 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS
},
7058 #ifdef _SC_PII_OSI_M
7059 {"SC_PII_OSI_M", _SC_PII_OSI_M
},
7061 #ifdef _SC_PII_SOCKET
7062 {"SC_PII_SOCKET", _SC_PII_SOCKET
},
7065 {"SC_PII_XTI", _SC_PII_XTI
},
7068 {"SC_POLL", _SC_POLL
},
7070 #ifdef _SC_PRIORITIZED_IO
7071 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO
},
7073 #ifdef _SC_PRIORITY_SCHEDULING
7074 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING
},
7076 #ifdef _SC_REALTIME_SIGNALS
7077 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS
},
7079 #ifdef _SC_RE_DUP_MAX
7080 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX
},
7082 #ifdef _SC_RTSIG_MAX
7083 {"SC_RTSIG_MAX", _SC_RTSIG_MAX
},
7085 #ifdef _SC_SAVED_IDS
7086 {"SC_SAVED_IDS", _SC_SAVED_IDS
},
7088 #ifdef _SC_SCHAR_MAX
7089 {"SC_SCHAR_MAX", _SC_SCHAR_MAX
},
7091 #ifdef _SC_SCHAR_MIN
7092 {"SC_SCHAR_MIN", _SC_SCHAR_MIN
},
7095 {"SC_SELECT", _SC_SELECT
},
7097 #ifdef _SC_SEMAPHORES
7098 {"SC_SEMAPHORES", _SC_SEMAPHORES
},
7100 #ifdef _SC_SEM_NSEMS_MAX
7101 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX
},
7103 #ifdef _SC_SEM_VALUE_MAX
7104 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX
},
7106 #ifdef _SC_SHARED_MEMORY_OBJECTS
7107 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS
},
7110 {"SC_SHRT_MAX", _SC_SHRT_MAX
},
7113 {"SC_SHRT_MIN", _SC_SHRT_MIN
},
7115 #ifdef _SC_SIGQUEUE_MAX
7116 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX
},
7118 #ifdef _SC_SIGRT_MAX
7119 {"SC_SIGRT_MAX", _SC_SIGRT_MAX
},
7121 #ifdef _SC_SIGRT_MIN
7122 {"SC_SIGRT_MIN", _SC_SIGRT_MIN
},
7124 #ifdef _SC_SOFTPOWER
7125 {"SC_SOFTPOWER", _SC_SOFTPOWER
},
7127 #ifdef _SC_SPLIT_CACHE
7128 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE
},
7130 #ifdef _SC_SSIZE_MAX
7131 {"SC_SSIZE_MAX", _SC_SSIZE_MAX
},
7133 #ifdef _SC_STACK_PROT
7134 {"SC_STACK_PROT", _SC_STACK_PROT
},
7136 #ifdef _SC_STREAM_MAX
7137 {"SC_STREAM_MAX", _SC_STREAM_MAX
},
7139 #ifdef _SC_SYNCHRONIZED_IO
7140 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO
},
7143 {"SC_THREADS", _SC_THREADS
},
7145 #ifdef _SC_THREAD_ATTR_STACKADDR
7146 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR
},
7148 #ifdef _SC_THREAD_ATTR_STACKSIZE
7149 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE
},
7151 #ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
7152 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS
},
7154 #ifdef _SC_THREAD_KEYS_MAX
7155 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX
},
7157 #ifdef _SC_THREAD_PRIORITY_SCHEDULING
7158 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING
},
7160 #ifdef _SC_THREAD_PRIO_INHERIT
7161 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT
},
7163 #ifdef _SC_THREAD_PRIO_PROTECT
7164 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT
},
7166 #ifdef _SC_THREAD_PROCESS_SHARED
7167 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED
},
7169 #ifdef _SC_THREAD_SAFE_FUNCTIONS
7170 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS
},
7172 #ifdef _SC_THREAD_STACK_MIN
7173 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN
},
7175 #ifdef _SC_THREAD_THREADS_MAX
7176 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX
},
7179 {"SC_TIMERS", _SC_TIMERS
},
7181 #ifdef _SC_TIMER_MAX
7182 {"SC_TIMER_MAX", _SC_TIMER_MAX
},
7184 #ifdef _SC_TTY_NAME_MAX
7185 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX
},
7187 #ifdef _SC_TZNAME_MAX
7188 {"SC_TZNAME_MAX", _SC_TZNAME_MAX
},
7190 #ifdef _SC_T_IOV_MAX
7191 {"SC_T_IOV_MAX", _SC_T_IOV_MAX
},
7193 #ifdef _SC_UCHAR_MAX
7194 {"SC_UCHAR_MAX", _SC_UCHAR_MAX
},
7197 {"SC_UINT_MAX", _SC_UINT_MAX
},
7199 #ifdef _SC_UIO_MAXIOV
7200 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV
},
7202 #ifdef _SC_ULONG_MAX
7203 {"SC_ULONG_MAX", _SC_ULONG_MAX
},
7205 #ifdef _SC_USHRT_MAX
7206 {"SC_USHRT_MAX", _SC_USHRT_MAX
},
7209 {"SC_VERSION", _SC_VERSION
},
7212 {"SC_WORD_BIT", _SC_WORD_BIT
},
7214 #ifdef _SC_XBS5_ILP32_OFF32
7215 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32
},
7217 #ifdef _SC_XBS5_ILP32_OFFBIG
7218 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG
},
7220 #ifdef _SC_XBS5_LP64_OFF64
7221 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64
},
7223 #ifdef _SC_XBS5_LPBIG_OFFBIG
7224 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG
},
7226 #ifdef _SC_XOPEN_CRYPT
7227 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT
},
7229 #ifdef _SC_XOPEN_ENH_I18N
7230 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N
},
7232 #ifdef _SC_XOPEN_LEGACY
7233 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY
},
7235 #ifdef _SC_XOPEN_REALTIME
7236 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME
},
7238 #ifdef _SC_XOPEN_REALTIME_THREADS
7239 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS
},
7241 #ifdef _SC_XOPEN_SHM
7242 {"SC_XOPEN_SHM", _SC_XOPEN_SHM
},
7244 #ifdef _SC_XOPEN_UNIX
7245 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX
},
7247 #ifdef _SC_XOPEN_VERSION
7248 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION
},
7250 #ifdef _SC_XOPEN_XCU_VERSION
7251 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION
},
7253 #ifdef _SC_XOPEN_XPG2
7254 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2
},
7256 #ifdef _SC_XOPEN_XPG3
7257 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3
},
7259 #ifdef _SC_XOPEN_XPG4
7260 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4
},
7265 conv_sysconf_confname(PyObject
*arg
, int *valuep
)
7267 return conv_confname(arg
, valuep
, posix_constants_sysconf
,
7268 sizeof(posix_constants_sysconf
)
7269 / sizeof(struct constdef
));
7272 PyDoc_STRVAR(posix_sysconf__doc__
,
7273 "sysconf(name) -> integer\n\n\
7274 Return an integer-valued system configuration variable.");
7277 posix_sysconf(PyObject
*self
, PyObject
*args
)
7279 PyObject
*result
= NULL
;
7282 if (PyArg_ParseTuple(args
, "O&:sysconf", conv_sysconf_confname
, &name
)) {
7286 value
= sysconf(name
);
7287 if (value
== -1 && errno
!= 0)
7290 result
= PyInt_FromLong(value
);
7297 /* This code is used to ensure that the tables of configuration value names
7298 * are in sorted order as required by conv_confname(), and also to build the
7299 * the exported dictionaries that are used to publish information about the
7300 * names available on the host platform.
7302 * Sorting the table at runtime ensures that the table is properly ordered
7303 * when used, even for platforms we're not able to test on. It also makes
7304 * it easier to add additional entries to the tables.
7308 cmp_constdefs(const void *v1
, const void *v2
)
7310 const struct constdef
*c1
=
7311 (const struct constdef
*) v1
;
7312 const struct constdef
*c2
=
7313 (const struct constdef
*) v2
;
7315 return strcmp(c1
->name
, c2
->name
);
7319 setup_confname_table(struct constdef
*table
, size_t tablesize
,
7320 char *tablename
, PyObject
*module
)
7325 qsort(table
, tablesize
, sizeof(struct constdef
), cmp_constdefs
);
7330 for (i
=0; i
< tablesize
; ++i
) {
7331 PyObject
*o
= PyInt_FromLong(table
[i
].value
);
7332 if (o
== NULL
|| PyDict_SetItemString(d
, table
[i
].name
, o
) == -1) {
7339 return PyModule_AddObject(module
, tablename
, d
);
7342 /* Return -1 on failure, 0 on success. */
7344 setup_confname_tables(PyObject
*module
)
7346 #if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
7347 if (setup_confname_table(posix_constants_pathconf
,
7348 sizeof(posix_constants_pathconf
)
7349 / sizeof(struct constdef
),
7350 "pathconf_names", module
))
7354 if (setup_confname_table(posix_constants_confstr
,
7355 sizeof(posix_constants_confstr
)
7356 / sizeof(struct constdef
),
7357 "confstr_names", module
))
7361 if (setup_confname_table(posix_constants_sysconf
,
7362 sizeof(posix_constants_sysconf
)
7363 / sizeof(struct constdef
),
7364 "sysconf_names", module
))
7371 PyDoc_STRVAR(posix_abort__doc__
,
7372 "abort() -> does not return!\n\n\
7373 Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
7374 in the hardest way possible on the hosting operating system.");
7377 posix_abort(PyObject
*self
, PyObject
*noargs
)
7381 Py_FatalError("abort() called from Python code didn't abort!");
7386 PyDoc_STRVAR(win32_startfile__doc__
,
7387 "startfile(filepath) - Start a file with its associated application.\n\
7389 This acts like double-clicking the file in Explorer, or giving the file\n\
7390 name as an argument to the DOS \"start\" command: the file is opened\n\
7391 with whatever application (if any) its extension is associated.\n\
7393 startfile returns as soon as the associated application is launched.\n\
7394 There is no option to wait for the application to close, and no way\n\
7395 to retrieve the application's exit status.\n\
7397 The filepath is relative to the current directory. If you want to use\n\
7398 an absolute path, make sure the first character is not a slash (\"/\");\n\
7399 the underlying Win32 ShellExecute function doesn't work if it is.");
7402 win32_startfile(PyObject
*self
, PyObject
*args
)
7406 if (!PyArg_ParseTuple(args
, "et:startfile",
7407 Py_FileSystemDefaultEncoding
, &filepath
))
7409 Py_BEGIN_ALLOW_THREADS
7410 rc
= ShellExecute((HWND
)0, NULL
, filepath
, NULL
, NULL
, SW_SHOWNORMAL
);
7411 Py_END_ALLOW_THREADS
7412 if (rc
<= (HINSTANCE
)32) {
7413 PyObject
*errval
= win32_error("startfile", filepath
);
7414 PyMem_Free(filepath
);
7417 PyMem_Free(filepath
);
7423 #ifdef HAVE_GETLOADAVG
7424 PyDoc_STRVAR(posix_getloadavg__doc__
,
7425 "getloadavg() -> (float, float, float)\n\n\
7426 Return the number of processes in the system run queue averaged over\n\
7427 the last 1, 5, and 15 minutes or raises OSError if the load average\n\
7431 posix_getloadavg(PyObject
*self
, PyObject
*noargs
)
7434 if (getloadavg(loadavg
, 3)!=3) {
7435 PyErr_SetString(PyExc_OSError
, "Load averages are unobtainable");
7438 return Py_BuildValue("ddd", loadavg
[0], loadavg
[1], loadavg
[2]);
7444 PyDoc_STRVAR(win32_urandom__doc__
,
7445 "urandom(n) -> str\n\n\
7446 Return a string of n random bytes suitable for cryptographic use.");
7448 typedef BOOL (WINAPI
*CRYPTACQUIRECONTEXTA
)(HCRYPTPROV
*phProv
,\
7449 LPCSTR pszContainer
, LPCSTR pszProvider
, DWORD dwProvType
,\
7451 typedef BOOL (WINAPI
*CRYPTGENRANDOM
)(HCRYPTPROV hProv
, DWORD dwLen
,\
7454 static CRYPTGENRANDOM pCryptGenRandom
= NULL
;
7455 static HCRYPTPROV hCryptProv
= 0;
7458 win32_urandom(PyObject
*self
, PyObject
*args
)
7463 /* Read arguments */
7464 if (! PyArg_ParseTuple(args
, "i:urandom", &howMany
))
7467 return PyErr_Format(PyExc_ValueError
,
7468 "negative argument not allowed");
7470 if (hCryptProv
== 0) {
7471 HINSTANCE hAdvAPI32
= NULL
;
7472 CRYPTACQUIRECONTEXTA pCryptAcquireContext
= NULL
;
7474 /* Obtain handle to the DLL containing CryptoAPI
7475 This should not fail */
7476 hAdvAPI32
= GetModuleHandle("advapi32.dll");
7477 if(hAdvAPI32
== NULL
)
7478 return win32_error("GetModuleHandle", NULL
);
7480 /* Obtain pointers to the CryptoAPI functions
7481 This will fail on some early versions of Win95 */
7482 pCryptAcquireContext
= (CRYPTACQUIRECONTEXTA
)GetProcAddress(
7484 "CryptAcquireContextA");
7485 if (pCryptAcquireContext
== NULL
)
7486 return PyErr_Format(PyExc_NotImplementedError
,
7487 "CryptAcquireContextA not found");
7489 pCryptGenRandom
= (CRYPTGENRANDOM
)GetProcAddress(
7490 hAdvAPI32
, "CryptGenRandom");
7491 if (pCryptAcquireContext
== NULL
)
7492 return PyErr_Format(PyExc_NotImplementedError
,
7493 "CryptGenRandom not found");
7495 /* Acquire context */
7496 if (! pCryptAcquireContext(&hCryptProv
, NULL
, NULL
,
7497 PROV_RSA_FULL
, CRYPT_VERIFYCONTEXT
))
7498 return win32_error("CryptAcquireContext", NULL
);
7501 /* Allocate bytes */
7502 result
= PyString_FromStringAndSize(NULL
, howMany
);
7503 if (result
!= NULL
) {
7504 /* Get random data */
7505 if (! pCryptGenRandom(hCryptProv
, howMany
, (unsigned char*)
7506 PyString_AS_STRING(result
))) {
7508 return win32_error("CryptGenRandom", NULL
);
7515 static PyMethodDef posix_methods
[] = {
7516 {"access", posix_access
, METH_VARARGS
, posix_access__doc__
},
7518 {"ttyname", posix_ttyname
, METH_VARARGS
, posix_ttyname__doc__
},
7520 {"chdir", posix_chdir
, METH_VARARGS
, posix_chdir__doc__
},
7521 {"chmod", posix_chmod
, METH_VARARGS
, posix_chmod__doc__
},
7523 {"chown", posix_chown
, METH_VARARGS
, posix_chown__doc__
},
7524 #endif /* HAVE_CHOWN */
7526 {"lchown", posix_lchown
, METH_VARARGS
, posix_lchown__doc__
},
7527 #endif /* HAVE_LCHOWN */
7529 {"chroot", posix_chroot
, METH_VARARGS
, posix_chroot__doc__
},
7532 {"ctermid", posix_ctermid
, METH_NOARGS
, posix_ctermid__doc__
},
7535 {"getcwd", posix_getcwd
, METH_NOARGS
, posix_getcwd__doc__
},
7536 #ifdef Py_USING_UNICODE
7537 {"getcwdu", posix_getcwdu
, METH_NOARGS
, posix_getcwdu__doc__
},
7541 {"link", posix_link
, METH_VARARGS
, posix_link__doc__
},
7542 #endif /* HAVE_LINK */
7543 {"listdir", posix_listdir
, METH_VARARGS
, posix_listdir__doc__
},
7544 {"lstat", posix_lstat
, METH_VARARGS
, posix_lstat__doc__
},
7545 {"mkdir", posix_mkdir
, METH_VARARGS
, posix_mkdir__doc__
},
7547 {"nice", posix_nice
, METH_VARARGS
, posix_nice__doc__
},
7548 #endif /* HAVE_NICE */
7549 #ifdef HAVE_READLINK
7550 {"readlink", posix_readlink
, METH_VARARGS
, posix_readlink__doc__
},
7551 #endif /* HAVE_READLINK */
7552 {"rename", posix_rename
, METH_VARARGS
, posix_rename__doc__
},
7553 {"rmdir", posix_rmdir
, METH_VARARGS
, posix_rmdir__doc__
},
7554 {"stat", posix_stat
, METH_VARARGS
, posix_stat__doc__
},
7555 {"stat_float_times", stat_float_times
, METH_VARARGS
, stat_float_times__doc__
},
7557 {"symlink", posix_symlink
, METH_VARARGS
, posix_symlink__doc__
},
7558 #endif /* HAVE_SYMLINK */
7560 {"system", posix_system
, METH_VARARGS
, posix_system__doc__
},
7562 {"umask", posix_umask
, METH_VARARGS
, posix_umask__doc__
},
7564 {"uname", posix_uname
, METH_NOARGS
, posix_uname__doc__
},
7565 #endif /* HAVE_UNAME */
7566 {"unlink", posix_unlink
, METH_VARARGS
, posix_unlink__doc__
},
7567 {"remove", posix_unlink
, METH_VARARGS
, posix_remove__doc__
},
7568 {"utime", posix_utime
, METH_VARARGS
, posix_utime__doc__
},
7570 {"times", posix_times
, METH_NOARGS
, posix_times__doc__
},
7571 #endif /* HAVE_TIMES */
7572 {"_exit", posix__exit
, METH_VARARGS
, posix__exit__doc__
},
7574 {"execv", posix_execv
, METH_VARARGS
, posix_execv__doc__
},
7575 {"execve", posix_execve
, METH_VARARGS
, posix_execve__doc__
},
7576 #endif /* HAVE_EXECV */
7578 {"spawnv", posix_spawnv
, METH_VARARGS
, posix_spawnv__doc__
},
7579 {"spawnve", posix_spawnve
, METH_VARARGS
, posix_spawnve__doc__
},
7580 #if defined(PYOS_OS2)
7581 {"spawnvp", posix_spawnvp
, METH_VARARGS
, posix_spawnvp__doc__
},
7582 {"spawnvpe", posix_spawnvpe
, METH_VARARGS
, posix_spawnvpe__doc__
},
7583 #endif /* PYOS_OS2 */
7584 #endif /* HAVE_SPAWNV */
7586 {"fork1", posix_fork1
, METH_NOARGS
, posix_fork1__doc__
},
7587 #endif /* HAVE_FORK1 */
7589 {"fork", posix_fork
, METH_NOARGS
, posix_fork__doc__
},
7590 #endif /* HAVE_FORK */
7591 #if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
7592 {"openpty", posix_openpty
, METH_NOARGS
, posix_openpty__doc__
},
7593 #endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
7595 {"forkpty", posix_forkpty
, METH_NOARGS
, posix_forkpty__doc__
},
7596 #endif /* HAVE_FORKPTY */
7598 {"getegid", posix_getegid
, METH_NOARGS
, posix_getegid__doc__
},
7599 #endif /* HAVE_GETEGID */
7601 {"geteuid", posix_geteuid
, METH_NOARGS
, posix_geteuid__doc__
},
7602 #endif /* HAVE_GETEUID */
7604 {"getgid", posix_getgid
, METH_NOARGS
, posix_getgid__doc__
},
7605 #endif /* HAVE_GETGID */
7606 #ifdef HAVE_GETGROUPS
7607 {"getgroups", posix_getgroups
, METH_NOARGS
, posix_getgroups__doc__
},
7609 {"getpid", posix_getpid
, METH_NOARGS
, posix_getpid__doc__
},
7611 {"getpgrp", posix_getpgrp
, METH_NOARGS
, posix_getpgrp__doc__
},
7612 #endif /* HAVE_GETPGRP */
7614 {"getppid", posix_getppid
, METH_NOARGS
, posix_getppid__doc__
},
7615 #endif /* HAVE_GETPPID */
7617 {"getuid", posix_getuid
, METH_NOARGS
, posix_getuid__doc__
},
7618 #endif /* HAVE_GETUID */
7619 #ifdef HAVE_GETLOGIN
7620 {"getlogin", posix_getlogin
, METH_NOARGS
, posix_getlogin__doc__
},
7623 {"kill", posix_kill
, METH_VARARGS
, posix_kill__doc__
},
7624 #endif /* HAVE_KILL */
7626 {"killpg", posix_killpg
, METH_VARARGS
, posix_killpg__doc__
},
7627 #endif /* HAVE_KILLPG */
7629 {"plock", posix_plock
, METH_VARARGS
, posix_plock__doc__
},
7630 #endif /* HAVE_PLOCK */
7632 {"popen", posix_popen
, METH_VARARGS
, posix_popen__doc__
},
7634 {"popen2", win32_popen2
, METH_VARARGS
},
7635 {"popen3", win32_popen3
, METH_VARARGS
},
7636 {"popen4", win32_popen4
, METH_VARARGS
},
7637 {"startfile", win32_startfile
, METH_VARARGS
, win32_startfile__doc__
},
7639 #if defined(PYOS_OS2) && defined(PYCC_GCC)
7640 {"popen2", os2emx_popen2
, METH_VARARGS
},
7641 {"popen3", os2emx_popen3
, METH_VARARGS
},
7642 {"popen4", os2emx_popen4
, METH_VARARGS
},
7645 #endif /* HAVE_POPEN */
7647 {"setuid", posix_setuid
, METH_VARARGS
, posix_setuid__doc__
},
7648 #endif /* HAVE_SETUID */
7650 {"seteuid", posix_seteuid
, METH_VARARGS
, posix_seteuid__doc__
},
7651 #endif /* HAVE_SETEUID */
7653 {"setegid", posix_setegid
, METH_VARARGS
, posix_setegid__doc__
},
7654 #endif /* HAVE_SETEGID */
7655 #ifdef HAVE_SETREUID
7656 {"setreuid", posix_setreuid
, METH_VARARGS
, posix_setreuid__doc__
},
7657 #endif /* HAVE_SETREUID */
7658 #ifdef HAVE_SETREGID
7659 {"setregid", posix_setregid
, METH_VARARGS
, posix_setregid__doc__
},
7660 #endif /* HAVE_SETREGID */
7662 {"setgid", posix_setgid
, METH_VARARGS
, posix_setgid__doc__
},
7663 #endif /* HAVE_SETGID */
7664 #ifdef HAVE_SETGROUPS
7665 {"setgroups", posix_setgroups
, METH_VARARGS
, posix_setgroups__doc__
},
7666 #endif /* HAVE_SETGROUPS */
7668 {"getpgid", posix_getpgid
, METH_VARARGS
, posix_getpgid__doc__
},
7669 #endif /* HAVE_GETPGID */
7671 {"setpgrp", posix_setpgrp
, METH_NOARGS
, posix_setpgrp__doc__
},
7672 #endif /* HAVE_SETPGRP */
7674 {"wait", posix_wait
, METH_NOARGS
, posix_wait__doc__
},
7675 #endif /* HAVE_WAIT */
7676 #if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
7677 {"waitpid", posix_waitpid
, METH_VARARGS
, posix_waitpid__doc__
},
7678 #endif /* HAVE_WAITPID */
7680 {"getsid", posix_getsid
, METH_VARARGS
, posix_getsid__doc__
},
7681 #endif /* HAVE_GETSID */
7683 {"setsid", posix_setsid
, METH_NOARGS
, posix_setsid__doc__
},
7684 #endif /* HAVE_SETSID */
7686 {"setpgid", posix_setpgid
, METH_VARARGS
, posix_setpgid__doc__
},
7687 #endif /* HAVE_SETPGID */
7688 #ifdef HAVE_TCGETPGRP
7689 {"tcgetpgrp", posix_tcgetpgrp
, METH_VARARGS
, posix_tcgetpgrp__doc__
},
7690 #endif /* HAVE_TCGETPGRP */
7691 #ifdef HAVE_TCSETPGRP
7692 {"tcsetpgrp", posix_tcsetpgrp
, METH_VARARGS
, posix_tcsetpgrp__doc__
},
7693 #endif /* HAVE_TCSETPGRP */
7694 {"open", posix_open
, METH_VARARGS
, posix_open__doc__
},
7695 {"close", posix_close
, METH_VARARGS
, posix_close__doc__
},
7696 {"dup", posix_dup
, METH_VARARGS
, posix_dup__doc__
},
7697 {"dup2", posix_dup2
, METH_VARARGS
, posix_dup2__doc__
},
7698 {"lseek", posix_lseek
, METH_VARARGS
, posix_lseek__doc__
},
7699 {"read", posix_read
, METH_VARARGS
, posix_read__doc__
},
7700 {"write", posix_write
, METH_VARARGS
, posix_write__doc__
},
7701 {"fstat", posix_fstat
, METH_VARARGS
, posix_fstat__doc__
},
7702 {"fdopen", posix_fdopen
, METH_VARARGS
, posix_fdopen__doc__
},
7703 {"isatty", posix_isatty
, METH_VARARGS
, posix_isatty__doc__
},
7705 {"pipe", posix_pipe
, METH_NOARGS
, posix_pipe__doc__
},
7708 {"mkfifo", posix_mkfifo
, METH_VARARGS
, posix_mkfifo__doc__
},
7710 #if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
7711 {"mknod", posix_mknod
, METH_VARARGS
, posix_mknod__doc__
},
7713 #ifdef HAVE_DEVICE_MACROS
7714 {"major", posix_major
, METH_VARARGS
, posix_major__doc__
},
7715 {"minor", posix_minor
, METH_VARARGS
, posix_minor__doc__
},
7716 {"makedev", posix_makedev
, METH_VARARGS
, posix_makedev__doc__
},
7718 #ifdef HAVE_FTRUNCATE
7719 {"ftruncate", posix_ftruncate
, METH_VARARGS
, posix_ftruncate__doc__
},
7722 {"putenv", posix_putenv
, METH_VARARGS
, posix_putenv__doc__
},
7724 #ifdef HAVE_UNSETENV
7725 {"unsetenv", posix_unsetenv
, METH_VARARGS
, posix_unsetenv__doc__
},
7727 #ifdef HAVE_STRERROR
7728 {"strerror", posix_strerror
, METH_VARARGS
, posix_strerror__doc__
},
7731 {"fchdir", posix_fchdir
, METH_O
, posix_fchdir__doc__
},
7734 {"fsync", posix_fsync
, METH_O
, posix_fsync__doc__
},
7736 #ifdef HAVE_FDATASYNC
7737 {"fdatasync", posix_fdatasync
, METH_O
, posix_fdatasync__doc__
},
7739 #ifdef HAVE_SYS_WAIT_H
7741 {"WCOREDUMP", posix_WCOREDUMP
, METH_VARARGS
, posix_WCOREDUMP__doc__
},
7742 #endif /* WCOREDUMP */
7744 {"WIFCONTINUED",posix_WIFCONTINUED
, METH_VARARGS
, posix_WIFCONTINUED__doc__
},
7745 #endif /* WIFCONTINUED */
7747 {"WIFSTOPPED", posix_WIFSTOPPED
, METH_VARARGS
, posix_WIFSTOPPED__doc__
},
7748 #endif /* WIFSTOPPED */
7750 {"WIFSIGNALED", posix_WIFSIGNALED
, METH_VARARGS
, posix_WIFSIGNALED__doc__
},
7751 #endif /* WIFSIGNALED */
7753 {"WIFEXITED", posix_WIFEXITED
, METH_VARARGS
, posix_WIFEXITED__doc__
},
7754 #endif /* WIFEXITED */
7756 {"WEXITSTATUS", posix_WEXITSTATUS
, METH_VARARGS
, posix_WEXITSTATUS__doc__
},
7757 #endif /* WEXITSTATUS */
7759 {"WTERMSIG", posix_WTERMSIG
, METH_VARARGS
, posix_WTERMSIG__doc__
},
7760 #endif /* WTERMSIG */
7762 {"WSTOPSIG", posix_WSTOPSIG
, METH_VARARGS
, posix_WSTOPSIG__doc__
},
7763 #endif /* WSTOPSIG */
7764 #endif /* HAVE_SYS_WAIT_H */
7765 #ifdef HAVE_FSTATVFS
7766 {"fstatvfs", posix_fstatvfs
, METH_VARARGS
, posix_fstatvfs__doc__
},
7769 {"statvfs", posix_statvfs
, METH_VARARGS
, posix_statvfs__doc__
},
7772 {"tmpfile", posix_tmpfile
, METH_NOARGS
, posix_tmpfile__doc__
},
7775 {"tempnam", posix_tempnam
, METH_VARARGS
, posix_tempnam__doc__
},
7778 {"tmpnam", posix_tmpnam
, METH_NOARGS
, posix_tmpnam__doc__
},
7781 {"confstr", posix_confstr
, METH_VARARGS
, posix_confstr__doc__
},
7784 {"sysconf", posix_sysconf
, METH_VARARGS
, posix_sysconf__doc__
},
7786 #ifdef HAVE_FPATHCONF
7787 {"fpathconf", posix_fpathconf
, METH_VARARGS
, posix_fpathconf__doc__
},
7789 #ifdef HAVE_PATHCONF
7790 {"pathconf", posix_pathconf
, METH_VARARGS
, posix_pathconf__doc__
},
7792 {"abort", posix_abort
, METH_NOARGS
, posix_abort__doc__
},
7794 {"_getfullpathname", posix__getfullpathname
, METH_VARARGS
, NULL
},
7796 #ifdef HAVE_GETLOADAVG
7797 {"getloadavg", posix_getloadavg
, METH_NOARGS
, posix_getloadavg__doc__
},
7800 {"urandom", win32_urandom
, METH_VARARGS
, win32_urandom__doc__
},
7802 {NULL
, NULL
} /* Sentinel */
7807 ins(PyObject
*module
, char *symbol
, long value
)
7809 return PyModule_AddIntConstant(module
, symbol
, value
);
7812 #if defined(PYOS_OS2)
7813 /* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
7814 static int insertvalues(PyObject
*module
)
7817 ULONG values
[QSV_MAX
+1];
7821 Py_BEGIN_ALLOW_THREADS
7822 rc
= DosQuerySysInfo(1L, QSV_MAX
, &values
[1], sizeof(ULONG
) * QSV_MAX
);
7823 Py_END_ALLOW_THREADS
7825 if (rc
!= NO_ERROR
) {
7830 if (ins(module
, "meminstalled", values
[QSV_TOTPHYSMEM
])) return -1;
7831 if (ins(module
, "memkernel", values
[QSV_TOTRESMEM
])) return -1;
7832 if (ins(module
, "memvirtual", values
[QSV_TOTAVAILMEM
])) return -1;
7833 if (ins(module
, "maxpathlen", values
[QSV_MAX_PATH_LENGTH
])) return -1;
7834 if (ins(module
, "maxnamelen", values
[QSV_MAX_COMP_LENGTH
])) return -1;
7835 if (ins(module
, "revision", values
[QSV_VERSION_REVISION
])) return -1;
7836 if (ins(module
, "timeslice", values
[QSV_MIN_SLICE
])) return -1;
7838 switch (values
[QSV_VERSION_MINOR
]) {
7839 case 0: ver
= "2.00"; break;
7840 case 10: ver
= "2.10"; break;
7841 case 11: ver
= "2.11"; break;
7842 case 30: ver
= "3.00"; break;
7843 case 40: ver
= "4.00"; break;
7844 case 50: ver
= "5.00"; break;
7846 PyOS_snprintf(tmp
, sizeof(tmp
),
7847 "%d-%d", values
[QSV_VERSION_MAJOR
],
7848 values
[QSV_VERSION_MINOR
]);
7852 /* Add Indicator of the Version of the Operating System */
7853 if (PyModule_AddStringConstant(module
, "version", tmp
) < 0)
7856 /* Add Indicator of Which Drive was Used to Boot the System */
7857 tmp
[0] = 'A' + values
[QSV_BOOT_DRIVE
] - 1;
7861 return PyModule_AddStringConstant(module
, "bootdrive", tmp
);
7866 all_ins(PyObject
*d
)
7869 if (ins(d
, "F_OK", (long)F_OK
)) return -1;
7872 if (ins(d
, "R_OK", (long)R_OK
)) return -1;
7875 if (ins(d
, "W_OK", (long)W_OK
)) return -1;
7878 if (ins(d
, "X_OK", (long)X_OK
)) return -1;
7881 if (ins(d
, "NGROUPS_MAX", (long)NGROUPS_MAX
)) return -1;
7884 if (ins(d
, "TMP_MAX", (long)TMP_MAX
)) return -1;
7887 if (ins(d
, "WCONTINUED", (long)WCONTINUED
)) return -1;
7890 if (ins(d
, "WNOHANG", (long)WNOHANG
)) return -1;
7893 if (ins(d
, "WUNTRACED", (long)WUNTRACED
)) return -1;
7896 if (ins(d
, "O_RDONLY", (long)O_RDONLY
)) return -1;
7899 if (ins(d
, "O_WRONLY", (long)O_WRONLY
)) return -1;
7902 if (ins(d
, "O_RDWR", (long)O_RDWR
)) return -1;
7905 if (ins(d
, "O_NDELAY", (long)O_NDELAY
)) return -1;
7908 if (ins(d
, "O_NONBLOCK", (long)O_NONBLOCK
)) return -1;
7911 if (ins(d
, "O_APPEND", (long)O_APPEND
)) return -1;
7914 if (ins(d
, "O_DSYNC", (long)O_DSYNC
)) return -1;
7917 if (ins(d
, "O_RSYNC", (long)O_RSYNC
)) return -1;
7920 if (ins(d
, "O_SYNC", (long)O_SYNC
)) return -1;
7923 if (ins(d
, "O_NOCTTY", (long)O_NOCTTY
)) return -1;
7926 if (ins(d
, "O_CREAT", (long)O_CREAT
)) return -1;
7929 if (ins(d
, "O_EXCL", (long)O_EXCL
)) return -1;
7932 if (ins(d
, "O_TRUNC", (long)O_TRUNC
)) return -1;
7935 if (ins(d
, "O_BINARY", (long)O_BINARY
)) return -1;
7938 if (ins(d
, "O_TEXT", (long)O_TEXT
)) return -1;
7941 if (ins(d
, "O_LARGEFILE", (long)O_LARGEFILE
)) return -1;
7944 if (ins(d
, "O_SHLOCK", (long)O_SHLOCK
)) return -1;
7947 if (ins(d
, "O_EXLOCK", (long)O_EXLOCK
)) return -1;
7952 /* Don't inherit in child processes. */
7953 if (ins(d
, "O_NOINHERIT", (long)O_NOINHERIT
)) return -1;
7955 #ifdef _O_SHORT_LIVED
7956 /* Optimize for short life (keep in memory). */
7957 /* MS forgot to define this one with a non-underscore form too. */
7958 if (ins(d
, "O_SHORT_LIVED", (long)_O_SHORT_LIVED
)) return -1;
7961 /* Automatically delete when last handle is closed. */
7962 if (ins(d
, "O_TEMPORARY", (long)O_TEMPORARY
)) return -1;
7965 /* Optimize for random access. */
7966 if (ins(d
, "O_RANDOM", (long)O_RANDOM
)) return -1;
7969 /* Optimize for sequential access. */
7970 if (ins(d
, "O_SEQUENTIAL", (long)O_SEQUENTIAL
)) return -1;
7973 /* GNU extensions. */
7975 /* Direct disk access. */
7976 if (ins(d
, "O_DIRECT", (long)O_DIRECT
)) return -1;
7979 /* Must be a directory. */
7980 if (ins(d
, "O_DIRECTORY", (long)O_DIRECTORY
)) return -1;
7983 /* Do not follow links. */
7984 if (ins(d
, "O_NOFOLLOW", (long)O_NOFOLLOW
)) return -1;
7987 /* These come from sysexits.h */
7989 if (ins(d
, "EX_OK", (long)EX_OK
)) return -1;
7992 if (ins(d
, "EX_USAGE", (long)EX_USAGE
)) return -1;
7993 #endif /* EX_USAGE */
7995 if (ins(d
, "EX_DATAERR", (long)EX_DATAERR
)) return -1;
7996 #endif /* EX_DATAERR */
7998 if (ins(d
, "EX_NOINPUT", (long)EX_NOINPUT
)) return -1;
7999 #endif /* EX_NOINPUT */
8001 if (ins(d
, "EX_NOUSER", (long)EX_NOUSER
)) return -1;
8002 #endif /* EX_NOUSER */
8004 if (ins(d
, "EX_NOHOST", (long)EX_NOHOST
)) return -1;
8005 #endif /* EX_NOHOST */
8006 #ifdef EX_UNAVAILABLE
8007 if (ins(d
, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE
)) return -1;
8008 #endif /* EX_UNAVAILABLE */
8010 if (ins(d
, "EX_SOFTWARE", (long)EX_SOFTWARE
)) return -1;
8011 #endif /* EX_SOFTWARE */
8013 if (ins(d
, "EX_OSERR", (long)EX_OSERR
)) return -1;
8014 #endif /* EX_OSERR */
8016 if (ins(d
, "EX_OSFILE", (long)EX_OSFILE
)) return -1;
8017 #endif /* EX_OSFILE */
8019 if (ins(d
, "EX_CANTCREAT", (long)EX_CANTCREAT
)) return -1;
8020 #endif /* EX_CANTCREAT */
8022 if (ins(d
, "EX_IOERR", (long)EX_IOERR
)) return -1;
8023 #endif /* EX_IOERR */
8025 if (ins(d
, "EX_TEMPFAIL", (long)EX_TEMPFAIL
)) return -1;
8026 #endif /* EX_TEMPFAIL */
8028 if (ins(d
, "EX_PROTOCOL", (long)EX_PROTOCOL
)) return -1;
8029 #endif /* EX_PROTOCOL */
8031 if (ins(d
, "EX_NOPERM", (long)EX_NOPERM
)) return -1;
8032 #endif /* EX_NOPERM */
8034 if (ins(d
, "EX_CONFIG", (long)EX_CONFIG
)) return -1;
8035 #endif /* EX_CONFIG */
8037 if (ins(d
, "EX_NOTFOUND", (long)EX_NOTFOUND
)) return -1;
8038 #endif /* EX_NOTFOUND */
8041 #if defined(PYOS_OS2) && defined(PYCC_GCC)
8042 if (ins(d
, "P_WAIT", (long)P_WAIT
)) return -1;
8043 if (ins(d
, "P_NOWAIT", (long)P_NOWAIT
)) return -1;
8044 if (ins(d
, "P_OVERLAY", (long)P_OVERLAY
)) return -1;
8045 if (ins(d
, "P_DEBUG", (long)P_DEBUG
)) return -1;
8046 if (ins(d
, "P_SESSION", (long)P_SESSION
)) return -1;
8047 if (ins(d
, "P_DETACH", (long)P_DETACH
)) return -1;
8048 if (ins(d
, "P_PM", (long)P_PM
)) return -1;
8049 if (ins(d
, "P_DEFAULT", (long)P_DEFAULT
)) return -1;
8050 if (ins(d
, "P_MINIMIZE", (long)P_MINIMIZE
)) return -1;
8051 if (ins(d
, "P_MAXIMIZE", (long)P_MAXIMIZE
)) return -1;
8052 if (ins(d
, "P_FULLSCREEN", (long)P_FULLSCREEN
)) return -1;
8053 if (ins(d
, "P_WINDOWED", (long)P_WINDOWED
)) return -1;
8054 if (ins(d
, "P_FOREGROUND", (long)P_FOREGROUND
)) return -1;
8055 if (ins(d
, "P_BACKGROUND", (long)P_BACKGROUND
)) return -1;
8056 if (ins(d
, "P_NOCLOSE", (long)P_NOCLOSE
)) return -1;
8057 if (ins(d
, "P_NOSESSION", (long)P_NOSESSION
)) return -1;
8058 if (ins(d
, "P_QUOTE", (long)P_QUOTE
)) return -1;
8059 if (ins(d
, "P_TILDE", (long)P_TILDE
)) return -1;
8060 if (ins(d
, "P_UNRELATED", (long)P_UNRELATED
)) return -1;
8061 if (ins(d
, "P_DEBUGDESC", (long)P_DEBUGDESC
)) return -1;
8063 if (ins(d
, "P_WAIT", (long)_P_WAIT
)) return -1;
8064 if (ins(d
, "P_NOWAIT", (long)_P_NOWAIT
)) return -1;
8065 if (ins(d
, "P_OVERLAY", (long)_OLD_P_OVERLAY
)) return -1;
8066 if (ins(d
, "P_NOWAITO", (long)_P_NOWAITO
)) return -1;
8067 if (ins(d
, "P_DETACH", (long)_P_DETACH
)) return -1;
8071 #if defined(PYOS_OS2)
8072 if (insertvalues(d
)) return -1;
8078 #if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
8079 #define INITFUNC initnt
8080 #define MODNAME "nt"
8082 #elif defined(PYOS_OS2)
8083 #define INITFUNC initos2
8084 #define MODNAME "os2"
8087 #define INITFUNC initposix
8088 #define MODNAME "posix"
8096 m
= Py_InitModule3(MODNAME
,
8102 /* Initialize environ dictionary */
8103 v
= convertenviron();
8105 if (v
== NULL
|| PyModule_AddObject(m
, "environ", v
) != 0)
8112 if (setup_confname_tables(m
))
8115 Py_INCREF(PyExc_OSError
);
8116 PyModule_AddObject(m
, "error", PyExc_OSError
);
8119 if (posix_putenv_garbage
== NULL
)
8120 posix_putenv_garbage
= PyDict_New();
8123 stat_result_desc
.name
= MODNAME
".stat_result";
8124 stat_result_desc
.fields
[7].name
= PyStructSequence_UnnamedField
;
8125 stat_result_desc
.fields
[8].name
= PyStructSequence_UnnamedField
;
8126 stat_result_desc
.fields
[9].name
= PyStructSequence_UnnamedField
;
8127 PyStructSequence_InitType(&StatResultType
, &stat_result_desc
);
8128 structseq_new
= StatResultType
.tp_new
;
8129 StatResultType
.tp_new
= statresult_new
;
8130 Py_INCREF((PyObject
*) &StatResultType
);
8131 PyModule_AddObject(m
, "stat_result", (PyObject
*) &StatResultType
);
8133 statvfs_result_desc
.name
= MODNAME
".statvfs_result";
8134 PyStructSequence_InitType(&StatVFSResultType
, &statvfs_result_desc
);
8135 Py_INCREF((PyObject
*) &StatVFSResultType
);
8136 PyModule_AddObject(m
, "statvfs_result",
8137 (PyObject
*) &StatVFSResultType
);