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 _stati64
281 # define FSTAT _fstati64
282 # define STRUCT_STAT struct _stati64
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(*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();
671 PyDoc_STRVAR(stat_result__doc__
,
672 "stat_result: Result from stat or lstat.\n\n\
673 This object may be accessed either as a tuple of\n\
674 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
675 or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
677 Posix/windows: If your platform supports st_blksize, st_blocks, or st_rdev,\n\
678 they are available as attributes only.\n\
680 See os.stat for more information.");
682 static PyStructSequence_Field stat_result_fields
[] = {
683 {"st_mode", "protection bits"},
685 {"st_dev", "device"},
686 {"st_nlink", "number of hard links"},
687 {"st_uid", "user ID of owner"},
688 {"st_gid", "group ID of owner"},
689 {"st_size", "total size, in bytes"},
690 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
691 {NULL
, "integer time of last access"},
692 {NULL
, "integer time of last modification"},
693 {NULL
, "integer time of last change"},
694 {"st_atime", "time of last access"},
695 {"st_mtime", "time of last modification"},
696 {"st_ctime", "time of last change"},
697 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
698 {"st_blksize", "blocksize for filesystem I/O"},
700 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
701 {"st_blocks", "number of blocks allocated"},
703 #ifdef HAVE_STRUCT_STAT_ST_RDEV
704 {"st_rdev", "device type (if inode device)"},
709 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
710 #define ST_BLKSIZE_IDX 13
712 #define ST_BLKSIZE_IDX 12
715 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
716 #define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
718 #define ST_BLOCKS_IDX ST_BLKSIZE_IDX
721 #ifdef HAVE_STRUCT_STAT_ST_RDEV
722 #define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
724 #define ST_RDEV_IDX ST_BLOCKS_IDX
727 static PyStructSequence_Desc stat_result_desc
= {
728 "stat_result", /* name */
729 stat_result__doc__
, /* doc */
734 PyDoc_STRVAR(statvfs_result__doc__
,
735 "statvfs_result: Result from statvfs or fstatvfs.\n\n\
736 This object may be accessed either as a tuple of\n\
737 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
738 or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
740 See os.statvfs for more information.");
742 static PyStructSequence_Field statvfs_result_fields
[] = {
756 static PyStructSequence_Desc statvfs_result_desc
= {
757 "statvfs_result", /* name */
758 statvfs_result__doc__
, /* doc */
759 statvfs_result_fields
,
763 static PyTypeObject StatResultType
;
764 static PyTypeObject StatVFSResultType
;
765 static newfunc structseq_new
;
768 statresult_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwds
)
770 PyStructSequence
*result
;
773 result
= (PyStructSequence
*)structseq_new(type
, args
, kwds
);
776 /* If we have been initialized from a tuple,
777 st_?time might be set to None. Initialize it
778 from the int slots. */
779 for (i
= 7; i
<= 9; i
++) {
780 if (result
->ob_item
[i
+3] == Py_None
) {
782 Py_INCREF(result
->ob_item
[i
]);
783 result
->ob_item
[i
+3] = result
->ob_item
[i
];
786 return (PyObject
*)result
;
791 /* If true, st_?time is float. */
792 static int _stat_float_times
= 0;
794 PyDoc_STRVAR(stat_float_times__doc__
,
795 "stat_float_times([newval]) -> oldval\n\n\
796 Determine whether os.[lf]stat represents time stamps as float objects.\n\
797 If newval is True, future calls to stat() return floats, if it is False,\n\
798 future calls return ints. \n\
799 If newval is omitted, return the current setting.\n");
802 stat_float_times(PyObject
* self
, PyObject
*args
)
805 if (!PyArg_ParseTuple(args
, "|i:stat_float_times", &newval
))
808 /* Return old value */
809 return PyBool_FromLong(_stat_float_times
);
810 _stat_float_times
= newval
;
816 fill_time(PyObject
*v
, int index
, time_t sec
, unsigned long nsec
)
818 PyObject
*fval
,*ival
;
819 #if SIZEOF_TIME_T > SIZEOF_LONG
820 ival
= PyLong_FromLongLong((PY_LONG_LONG
)sec
);
822 ival
= PyInt_FromLong((long)sec
);
824 if (_stat_float_times
) {
825 fval
= PyFloat_FromDouble(sec
+ 1e-9*nsec
);
830 PyStructSequence_SET_ITEM(v
, index
, ival
);
831 PyStructSequence_SET_ITEM(v
, index
+3, fval
);
834 /* pack a system stat C structure into the Python stat tuple
835 (used by posix_stat() and posix_fstat()) */
837 _pystat_fromstructstat(STRUCT_STAT st
)
839 unsigned long ansec
, mnsec
, cnsec
;
840 PyObject
*v
= PyStructSequence_New(&StatResultType
);
844 PyStructSequence_SET_ITEM(v
, 0, PyInt_FromLong((long)st
.st_mode
));
845 #ifdef HAVE_LARGEFILE_SUPPORT
846 PyStructSequence_SET_ITEM(v
, 1,
847 PyLong_FromLongLong((PY_LONG_LONG
)st
.st_ino
));
849 PyStructSequence_SET_ITEM(v
, 1, PyInt_FromLong((long)st
.st_ino
));
851 #if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
852 PyStructSequence_SET_ITEM(v
, 2,
853 PyLong_FromLongLong((PY_LONG_LONG
)st
.st_dev
));
855 PyStructSequence_SET_ITEM(v
, 2, PyInt_FromLong((long)st
.st_dev
));
857 PyStructSequence_SET_ITEM(v
, 3, PyInt_FromLong((long)st
.st_nlink
));
858 PyStructSequence_SET_ITEM(v
, 4, PyInt_FromLong((long)st
.st_uid
));
859 PyStructSequence_SET_ITEM(v
, 5, PyInt_FromLong((long)st
.st_gid
));
860 #ifdef HAVE_LARGEFILE_SUPPORT
861 PyStructSequence_SET_ITEM(v
, 6,
862 PyLong_FromLongLong((PY_LONG_LONG
)st
.st_size
));
864 PyStructSequence_SET_ITEM(v
, 6, PyInt_FromLong(st
.st_size
));
867 #ifdef HAVE_STAT_TV_NSEC
868 ansec
= st
.st_atim
.tv_nsec
;
869 mnsec
= st
.st_mtim
.tv_nsec
;
870 cnsec
= st
.st_ctim
.tv_nsec
;
872 ansec
= mnsec
= cnsec
= 0;
874 fill_time(v
, 7, st
.st_atime
, ansec
);
875 fill_time(v
, 8, st
.st_mtime
, mnsec
);
876 fill_time(v
, 9, st
.st_ctime
, cnsec
);
878 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
879 PyStructSequence_SET_ITEM(v
, ST_BLKSIZE_IDX
,
880 PyInt_FromLong((long)st
.st_blksize
));
882 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
883 PyStructSequence_SET_ITEM(v
, ST_BLOCKS_IDX
,
884 PyInt_FromLong((long)st
.st_blocks
));
886 #ifdef HAVE_STRUCT_STAT_ST_RDEV
887 PyStructSequence_SET_ITEM(v
, ST_RDEV_IDX
,
888 PyInt_FromLong((long)st
.st_rdev
));
891 if (PyErr_Occurred()) {
901 /* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
902 where / can be used in place of \ and the trailing slash is optional.
903 Both SERVER and SHARE must have at least one character.
906 #define ISSLASHA(c) ((c) == '\\' || (c) == '/')
907 #define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
908 #define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
911 IsUNCRootA(char *path
, int pathlen
)
913 #define ISSLASH ISSLASHA
917 if (pathlen
< 5 || !ISSLASH(path
[0]) || !ISSLASH(path
[1]))
918 /* minimum UNCRoot is \\x\y */
920 for (i
= 2; i
< pathlen
; i
++)
921 if (ISSLASH(path
[i
])) break;
922 if (i
== 2 || i
== pathlen
)
923 /* do not allow \\\SHARE or \\SERVER */
926 for (i
= share
; i
< pathlen
; i
++)
927 if (ISSLASH(path
[i
])) break;
928 return (i
!= share
&& (i
== pathlen
|| i
== pathlen
-1));
933 #ifdef Py_WIN_WIDE_FILENAMES
935 IsUNCRootW(Py_UNICODE
*path
, int pathlen
)
937 #define ISSLASH ISSLASHW
941 if (pathlen
< 5 || !ISSLASH(path
[0]) || !ISSLASH(path
[1]))
942 /* minimum UNCRoot is \\x\y */
944 for (i
= 2; i
< pathlen
; i
++)
945 if (ISSLASH(path
[i
])) break;
946 if (i
== 2 || i
== pathlen
)
947 /* do not allow \\\SHARE or \\SERVER */
950 for (i
= share
; i
< pathlen
; i
++)
951 if (ISSLASH(path
[i
])) break;
952 return (i
!= share
&& (i
== pathlen
|| i
== pathlen
-1));
956 #endif /* Py_WIN_WIDE_FILENAMES */
957 #endif /* MS_WINDOWS */
960 posix_do_stat(PyObject
*self
, PyObject
*args
,
963 int (*statfunc
)(const char *, STRUCT_STAT
*, ...),
965 int (*statfunc
)(const char *, STRUCT_STAT
*),
968 int (*wstatfunc
)(const Py_UNICODE
*, STRUCT_STAT
*))
971 char *path
= NULL
; /* pass this to stat; do not free() it */
972 char *pathfree
= NULL
; /* this memory must be free'd */
977 char pathcopy
[MAX_PATH
];
978 #endif /* MS_WINDOWS */
981 #ifdef Py_WIN_WIDE_FILENAMES
982 /* If on wide-character-capable OS see if argument
983 is Unicode and if so use wide API. */
984 if (unicode_file_names()) {
986 if (PyArg_ParseTuple(args
, wformat
, &po
)) {
987 Py_UNICODE wpath
[MAX_PATH
+1];
988 pathlen
= wcslen(PyUnicode_AS_UNICODE(po
));
989 /* the library call can blow up if the file name is too long! */
990 if (pathlen
> MAX_PATH
) {
991 errno
= ENAMETOOLONG
;
992 return posix_error();
994 wcscpy(wpath
, PyUnicode_AS_UNICODE(po
));
995 /* Remove trailing slash or backslash, unless it's the current
996 drive root (/ or \) or a specific drive's root (like c:\ or c:/).
999 if (ISSLASHW(wpath
[pathlen
-1])) {
1000 /* It does end with a slash -- exempt the root drive cases. */
1001 if (pathlen
== 1 || (pathlen
== 3 && wpath
[1] == L
':') ||
1002 IsUNCRootW(wpath
, pathlen
))
1003 /* leave it alone */;
1005 /* nuke the trailing backslash */
1006 wpath
[pathlen
-1] = L
'\0';
1009 else if (ISSLASHW(wpath
[1]) && pathlen
< ARRAYSIZE(wpath
)-1 &&
1010 IsUNCRootW(wpath
, pathlen
)) {
1011 /* UNC root w/o trailing slash: add one when there's room */
1012 wpath
[pathlen
++] = L
'\\';
1013 wpath
[pathlen
] = L
'\0';
1016 Py_BEGIN_ALLOW_THREADS
1017 /* PyUnicode_AS_UNICODE result OK without
1018 thread lock as it is a simple dereference. */
1019 res
= wstatfunc(wpath
, &st
);
1020 Py_END_ALLOW_THREADS
1022 return posix_error_with_unicode_filename(wpath
);
1023 return _pystat_fromstructstat(st
);
1025 /* Drop the argument parsing error as narrow strings
1031 if (!PyArg_ParseTuple(args
, format
,
1032 Py_FileSystemDefaultEncoding
, &path
))
1037 pathlen
= strlen(path
);
1038 /* the library call can blow up if the file name is too long! */
1039 if (pathlen
> MAX_PATH
) {
1040 PyMem_Free(pathfree
);
1041 errno
= ENAMETOOLONG
;
1042 return posix_error();
1045 /* Remove trailing slash or backslash, unless it's the current
1046 drive root (/ or \) or a specific drive's root (like c:\ or c:/).
1049 if (ISSLASHA(path
[pathlen
-1])) {
1050 /* It does end with a slash -- exempt the root drive cases. */
1051 if (pathlen
== 1 || (pathlen
== 3 && path
[1] == ':') ||
1052 IsUNCRootA(path
, pathlen
))
1053 /* leave it alone */;
1055 /* nuke the trailing backslash */
1056 strncpy(pathcopy
, path
, pathlen
);
1057 pathcopy
[pathlen
-1] = '\0';
1061 else if (ISSLASHA(path
[1]) && pathlen
< ARRAYSIZE(pathcopy
)-1 &&
1062 IsUNCRootA(path
, pathlen
)) {
1063 /* UNC root w/o trailing slash: add one when there's room */
1064 strncpy(pathcopy
, path
, pathlen
);
1065 pathcopy
[pathlen
++] = '\\';
1066 pathcopy
[pathlen
] = '\0';
1070 #endif /* MS_WINDOWS */
1072 Py_BEGIN_ALLOW_THREADS
1073 res
= (*statfunc
)(path
, &st
);
1074 Py_END_ALLOW_THREADS
1076 return posix_error_with_allocated_filename(pathfree
);
1078 PyMem_Free(pathfree
);
1079 return _pystat_fromstructstat(st
);
1085 PyDoc_STRVAR(posix_access__doc__
,
1086 "access(path, mode) -> 1 if granted, 0 otherwise\n\n\
1087 Use the real uid/gid to test for access to a path. Note that most\n\
1088 operations will use the effective uid/gid, therefore this routine can\n\
1089 be used in a suid/sgid environment to test if the invoking user has the\n\
1090 specified access to the path. The mode argument can be F_OK to test\n\
1091 existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
1094 posix_access(PyObject
*self
, PyObject
*args
)
1100 #ifdef Py_WIN_WIDE_FILENAMES
1101 if (unicode_file_names()) {
1102 PyUnicodeObject
*po
;
1103 if (PyArg_ParseTuple(args
, "Ui:access", &po
, &mode
)) {
1104 Py_BEGIN_ALLOW_THREADS
1105 /* PyUnicode_AS_UNICODE OK without thread lock as
1106 it is a simple dereference. */
1107 res
= _waccess(PyUnicode_AS_UNICODE(po
), mode
);
1108 Py_END_ALLOW_THREADS
1109 return(PyBool_FromLong(res
== 0));
1111 /* Drop the argument parsing error as narrow strings
1116 if (!PyArg_ParseTuple(args
, "si:access", &path
, &mode
))
1118 Py_BEGIN_ALLOW_THREADS
1119 res
= access(path
, mode
);
1120 Py_END_ALLOW_THREADS
1121 return(PyBool_FromLong(res
== 0));
1138 PyDoc_STRVAR(posix_ttyname__doc__
,
1139 "ttyname(fd) -> string\n\n\
1140 Return the name of the terminal device connected to 'fd'.");
1143 posix_ttyname(PyObject
*self
, PyObject
*args
)
1148 if (!PyArg_ParseTuple(args
, "i:ttyname", &id
))
1152 /* file descriptor 0 only, the default input device (stdin) */
1163 return(posix_error());
1164 return(PyString_FromString(ret
));
1169 PyDoc_STRVAR(posix_ctermid__doc__
,
1170 "ctermid() -> string\n\n\
1171 Return the name of the controlling terminal for this process.");
1174 posix_ctermid(PyObject
*self
, PyObject
*noargs
)
1177 char buffer
[L_ctermid
];
1179 #ifdef USE_CTERMID_R
1180 ret
= ctermid_r(buffer
);
1182 ret
= ctermid(buffer
);
1185 return(posix_error());
1186 return(PyString_FromString(buffer
));
1190 PyDoc_STRVAR(posix_chdir__doc__
,
1192 Change the current working directory to the specified path.");
1195 posix_chdir(PyObject
*self
, PyObject
*args
)
1198 return posix_1str(args
, "et:chdir", chdir
, "U:chdir", _wchdir
);
1199 #elif defined(PYOS_OS2) && defined(PYCC_GCC)
1200 return posix_1str(args
, "et:chdir", _chdir2
, NULL
, NULL
);
1201 #elif defined(__VMS)
1202 return posix_1str(args
, "et:chdir", (int (*)(const char *))chdir
,
1205 return posix_1str(args
, "et:chdir", chdir
, NULL
, NULL
);
1210 PyDoc_STRVAR(posix_fchdir__doc__
,
1211 "fchdir(fildes)\n\n\
1212 Change to the directory of the given file descriptor. fildes must be\n\
1213 opened on a directory, not a file.");
1216 posix_fchdir(PyObject
*self
, PyObject
*fdobj
)
1218 return posix_fildes(fdobj
, fchdir
);
1220 #endif /* HAVE_FCHDIR */
1223 PyDoc_STRVAR(posix_chmod__doc__
,
1224 "chmod(path, mode)\n\n\
1225 Change the access permissions of a file.");
1228 posix_chmod(PyObject
*self
, PyObject
*args
)
1233 #ifdef Py_WIN_WIDE_FILENAMES
1234 if (unicode_file_names()) {
1235 PyUnicodeObject
*po
;
1236 if (PyArg_ParseTuple(args
, "Ui|:chmod", &po
, &i
)) {
1237 Py_BEGIN_ALLOW_THREADS
1238 res
= _wchmod(PyUnicode_AS_UNICODE(po
), i
);
1239 Py_END_ALLOW_THREADS
1241 return posix_error_with_unicode_filename(
1242 PyUnicode_AS_UNICODE(po
));
1246 /* Drop the argument parsing error as narrow strings
1250 #endif /* Py_WIN_WIDE_FILENAMES */
1251 if (!PyArg_ParseTuple(args
, "eti:chmod", Py_FileSystemDefaultEncoding
,
1254 Py_BEGIN_ALLOW_THREADS
1255 res
= chmod(path
, i
);
1256 Py_END_ALLOW_THREADS
1258 return posix_error_with_allocated_filename(path
);
1266 PyDoc_STRVAR(posix_chroot__doc__
,
1268 Change root directory to path.");
1271 posix_chroot(PyObject
*self
, PyObject
*args
)
1273 return posix_1str(args
, "et:chroot", chroot
, NULL
, NULL
);
1278 PyDoc_STRVAR(posix_fsync__doc__
,
1280 force write of file with filedescriptor to disk.");
1283 posix_fsync(PyObject
*self
, PyObject
*fdobj
)
1285 return posix_fildes(fdobj
, fsync
);
1287 #endif /* HAVE_FSYNC */
1289 #ifdef HAVE_FDATASYNC
1292 extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1295 PyDoc_STRVAR(posix_fdatasync__doc__
,
1296 "fdatasync(fildes)\n\n\
1297 force write of file with filedescriptor to disk.\n\
1298 does not force update of metadata.");
1301 posix_fdatasync(PyObject
*self
, PyObject
*fdobj
)
1303 return posix_fildes(fdobj
, fdatasync
);
1305 #endif /* HAVE_FDATASYNC */
1309 PyDoc_STRVAR(posix_chown__doc__
,
1310 "chown(path, uid, gid)\n\n\
1311 Change the owner and group id of path to the numeric uid and gid.");
1314 posix_chown(PyObject
*self
, PyObject
*args
)
1319 if (!PyArg_ParseTuple(args
, "etii:chown",
1320 Py_FileSystemDefaultEncoding
, &path
,
1323 Py_BEGIN_ALLOW_THREADS
1324 res
= chown(path
, (uid_t
) uid
, (gid_t
) gid
);
1325 Py_END_ALLOW_THREADS
1327 return posix_error_with_allocated_filename(path
);
1332 #endif /* HAVE_CHOWN */
1335 PyDoc_STRVAR(posix_lchown__doc__
,
1336 "lchown(path, uid, gid)\n\n\
1337 Change the owner and group id of path to the numeric uid and gid.\n\
1338 This function will not follow symbolic links.");
1341 posix_lchown(PyObject
*self
, PyObject
*args
)
1346 if (!PyArg_ParseTuple(args
, "etii:lchown",
1347 Py_FileSystemDefaultEncoding
, &path
,
1350 Py_BEGIN_ALLOW_THREADS
1351 res
= lchown(path
, (uid_t
) uid
, (gid_t
) gid
);
1352 Py_END_ALLOW_THREADS
1354 return posix_error_with_allocated_filename(path
);
1359 #endif /* HAVE_LCHOWN */
1363 PyDoc_STRVAR(posix_getcwd__doc__
,
1364 "getcwd() -> path\n\n\
1365 Return a string representing the current working directory.");
1368 posix_getcwd(PyObject
*self
, PyObject
*noargs
)
1373 Py_BEGIN_ALLOW_THREADS
1374 #if defined(PYOS_OS2) && defined(PYCC_GCC)
1375 res
= _getcwd2(buf
, sizeof buf
);
1377 res
= getcwd(buf
, sizeof buf
);
1379 Py_END_ALLOW_THREADS
1381 return posix_error();
1382 return PyString_FromString(buf
);
1385 #ifdef Py_USING_UNICODE
1386 PyDoc_STRVAR(posix_getcwdu__doc__
,
1387 "getcwdu() -> path\n\n\
1388 Return a unicode string representing the current working directory.");
1391 posix_getcwdu(PyObject
*self
, PyObject
*noargs
)
1396 #ifdef Py_WIN_WIDE_FILENAMES
1397 if (unicode_file_names()) {
1400 Py_BEGIN_ALLOW_THREADS
1401 wres
= _wgetcwd(wbuf
, sizeof wbuf
/ sizeof wbuf
[0]);
1402 Py_END_ALLOW_THREADS
1404 return posix_error();
1405 return PyUnicode_FromWideChar(wbuf
, wcslen(wbuf
));
1409 Py_BEGIN_ALLOW_THREADS
1410 #if defined(PYOS_OS2) && defined(PYCC_GCC)
1411 res
= _getcwd2(buf
, sizeof buf
);
1413 res
= getcwd(buf
, sizeof buf
);
1415 Py_END_ALLOW_THREADS
1417 return posix_error();
1418 return PyUnicode_Decode(buf
, strlen(buf
), Py_FileSystemDefaultEncoding
,"strict");
1425 PyDoc_STRVAR(posix_link__doc__
,
1426 "link(src, dst)\n\n\
1427 Create a hard link to a file.");
1430 posix_link(PyObject
*self
, PyObject
*args
)
1432 return posix_2str(args
, "etet:link", link
, NULL
, NULL
);
1434 #endif /* HAVE_LINK */
1437 PyDoc_STRVAR(posix_listdir__doc__
,
1438 "listdir(path) -> list_of_strings\n\n\
1439 Return a list containing the names of the entries in the directory.\n\
1441 path: path of directory to list\n\
1443 The list is in arbitrary order. It does not include the special\n\
1444 entries '.' and '..' even if they are present in the directory.");
1447 posix_listdir(PyObject
*self
, PyObject
*args
)
1449 /* XXX Should redo this putting the (now four) versions of opendir
1450 in separate files instead of having them all here... */
1451 #if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
1455 WIN32_FIND_DATA FileData
;
1456 /* MAX_PATH characters could mean a bigger encoded string */
1457 char namebuf
[MAX_PATH
*2+5];
1458 char *bufptr
= namebuf
;
1459 int len
= sizeof(namebuf
)/sizeof(namebuf
[0]);
1461 #ifdef Py_WIN_WIDE_FILENAMES
1462 /* If on wide-character-capable OS see if argument
1463 is Unicode and if so use wide API. */
1464 if (unicode_file_names()) {
1465 PyUnicodeObject
*po
;
1466 if (PyArg_ParseTuple(args
, "U:listdir", &po
)) {
1467 WIN32_FIND_DATAW wFileData
;
1468 Py_UNICODE wnamebuf
[MAX_PATH
*2+5];
1470 wcsncpy(wnamebuf
, PyUnicode_AS_UNICODE(po
), MAX_PATH
);
1471 wnamebuf
[MAX_PATH
] = L
'\0';
1472 len
= wcslen(wnamebuf
);
1473 wch
= (len
> 0) ? wnamebuf
[len
-1] : L
'\0';
1474 if (wch
!= L
'/' && wch
!= L
'\\' && wch
!= L
':')
1475 wnamebuf
[len
++] = L
'/';
1476 wcscpy(wnamebuf
+ len
, L
"*.*");
1477 if ((d
= PyList_New(0)) == NULL
)
1479 hFindFile
= FindFirstFileW(wnamebuf
, &wFileData
);
1480 if (hFindFile
== INVALID_HANDLE_VALUE
) {
1481 errno
= GetLastError();
1482 if (errno
== ERROR_FILE_NOT_FOUND
) {
1486 return win32_error_unicode("FindFirstFileW", wnamebuf
);
1489 if (wFileData
.cFileName
[0] == L
'.' &&
1490 (wFileData
.cFileName
[1] == L
'\0' ||
1491 wFileData
.cFileName
[1] == L
'.' &&
1492 wFileData
.cFileName
[2] == L
'\0'))
1494 v
= PyUnicode_FromUnicode(wFileData
.cFileName
, wcslen(wFileData
.cFileName
));
1500 if (PyList_Append(d
, v
) != 0) {
1507 } while (FindNextFileW(hFindFile
, &wFileData
) == TRUE
);
1509 if (FindClose(hFindFile
) == FALSE
) {
1511 return win32_error_unicode("FindClose", wnamebuf
);
1515 /* Drop the argument parsing error as narrow strings
1521 if (!PyArg_ParseTuple(args
, "et#:listdir",
1522 Py_FileSystemDefaultEncoding
, &bufptr
, &len
))
1525 char ch
= namebuf
[len
-1];
1526 if (ch
!= SEP
&& ch
!= ALTSEP
&& ch
!= ':')
1527 namebuf
[len
++] = '/';
1529 strcpy(namebuf
+ len
, "*.*");
1531 if ((d
= PyList_New(0)) == NULL
)
1534 hFindFile
= FindFirstFile(namebuf
, &FileData
);
1535 if (hFindFile
== INVALID_HANDLE_VALUE
) {
1536 errno
= GetLastError();
1537 if (errno
== ERROR_FILE_NOT_FOUND
)
1540 return win32_error("FindFirstFile", namebuf
);
1543 if (FileData
.cFileName
[0] == '.' &&
1544 (FileData
.cFileName
[1] == '\0' ||
1545 FileData
.cFileName
[1] == '.' &&
1546 FileData
.cFileName
[2] == '\0'))
1548 v
= PyString_FromString(FileData
.cFileName
);
1554 if (PyList_Append(d
, v
) != 0) {
1561 } while (FindNextFile(hFindFile
, &FileData
) == TRUE
);
1563 if (FindClose(hFindFile
) == FALSE
) {
1565 return win32_error("FindClose", namebuf
);
1570 #elif defined(PYOS_OS2)
1573 #define MAX_PATH CCHMAXPATH
1578 char namebuf
[MAX_PATH
+5];
1584 if (!PyArg_ParseTuple(args
, "t#:listdir", &name
, &len
))
1586 if (len
>= MAX_PATH
) {
1587 PyErr_SetString(PyExc_ValueError
, "path too long");
1590 strcpy(namebuf
, name
);
1591 for (pt
= namebuf
; *pt
; pt
++)
1594 if (namebuf
[len
-1] != SEP
)
1595 namebuf
[len
++] = SEP
;
1596 strcpy(namebuf
+ len
, "*.*");
1598 if ((d
= PyList_New(0)) == NULL
)
1601 rc
= DosFindFirst(namebuf
, /* Wildcard Pattern to Match */
1602 &hdir
, /* Handle to Use While Search Directory */
1603 FILE_READONLY
| FILE_HIDDEN
| FILE_SYSTEM
| FILE_DIRECTORY
,
1604 &ep
, sizeof(ep
), /* Structure to Receive Directory Entry */
1605 &srchcnt
, /* Max and Actual Count of Entries Per Iteration */
1606 FIL_STANDARD
); /* Format of Entry (EAs or Not) */
1608 if (rc
!= NO_ERROR
) {
1610 return posix_error_with_filename(name
);
1613 if (srchcnt
> 0) { /* If Directory is NOT Totally Empty, */
1615 if (ep
.achName
[0] == '.'
1616 && (ep
.achName
[1] == '\0' || (ep
.achName
[1] == '.' && ep
.achName
[2] == '\0')))
1617 continue; /* Skip Over "." and ".." Names */
1619 strcpy(namebuf
, ep
.achName
);
1621 /* Leave Case of Name Alone -- In Native Form */
1622 /* (Removed Forced Lowercasing Code) */
1624 v
= PyString_FromString(namebuf
);
1630 if (PyList_Append(d
, v
) != 0) {
1637 } while (DosFindNext(hdir
, &ep
, sizeof(ep
), &srchcnt
) == NO_ERROR
&& srchcnt
> 0);
1647 int arg_is_unicode
= 1;
1649 if (!PyArg_ParseTuple(args
, "U:listdir", &v
)) {
1653 if (!PyArg_ParseTuple(args
, "et:listdir", Py_FileSystemDefaultEncoding
, &name
))
1655 if ((dirp
= opendir(name
)) == NULL
) {
1656 return posix_error_with_allocated_filename(name
);
1658 if ((d
= PyList_New(0)) == NULL
) {
1663 while ((ep
= readdir(dirp
)) != NULL
) {
1664 if (ep
->d_name
[0] == '.' &&
1666 (ep
->d_name
[1] == '.' && NAMLEN(ep
) == 2)))
1668 v
= PyString_FromStringAndSize(ep
->d_name
, NAMLEN(ep
));
1674 #ifdef Py_USING_UNICODE
1675 if (arg_is_unicode
) {
1678 w
= PyUnicode_FromEncodedObject(v
,
1679 Py_FileSystemDefaultEncoding
,
1686 /* fall back to the original byte string, as
1687 discussed in patch #683592 */
1692 if (PyList_Append(d
, v
) != 0) {
1705 #endif /* which OS */
1706 } /* end of posix_listdir */
1709 /* A helper function for abspath on win32 */
1711 posix__getfullpathname(PyObject
*self
, PyObject
*args
)
1713 /* assume encoded strings wont more than double no of chars */
1714 char inbuf
[MAX_PATH
*2];
1715 char *inbufp
= inbuf
;
1716 int insize
= sizeof(inbuf
)/sizeof(inbuf
[0]);
1717 char outbuf
[MAX_PATH
*2];
1719 #ifdef Py_WIN_WIDE_FILENAMES
1720 if (unicode_file_names()) {
1721 PyUnicodeObject
*po
;
1722 if (PyArg_ParseTuple(args
, "U|:_getfullpathname", &po
)) {
1723 Py_UNICODE woutbuf
[MAX_PATH
*2];
1725 if (!GetFullPathNameW(PyUnicode_AS_UNICODE(po
),
1726 sizeof(woutbuf
)/sizeof(woutbuf
[0]),
1728 return win32_error("GetFullPathName", "");
1729 return PyUnicode_FromUnicode(woutbuf
, wcslen(woutbuf
));
1731 /* Drop the argument parsing error as narrow strings
1736 if (!PyArg_ParseTuple (args
, "et#:_getfullpathname",
1737 Py_FileSystemDefaultEncoding
, &inbufp
,
1740 if (!GetFullPathName(inbuf
, sizeof(outbuf
)/sizeof(outbuf
[0]),
1742 return win32_error("GetFullPathName", inbuf
);
1743 if (PyUnicode_Check(PyTuple_GetItem(args
, 0))) {
1744 return PyUnicode_Decode(outbuf
, strlen(outbuf
),
1745 Py_FileSystemDefaultEncoding
, NULL
);
1747 return PyString_FromString(outbuf
);
1748 } /* end of posix__getfullpathname */
1749 #endif /* MS_WINDOWS */
1751 PyDoc_STRVAR(posix_mkdir__doc__
,
1752 "mkdir(path [, mode=0777])\n\n\
1753 Create a directory.");
1756 posix_mkdir(PyObject
*self
, PyObject
*args
)
1762 #ifdef Py_WIN_WIDE_FILENAMES
1763 if (unicode_file_names()) {
1764 PyUnicodeObject
*po
;
1765 if (PyArg_ParseTuple(args
, "U|i:mkdir", &po
, &mode
)) {
1766 Py_BEGIN_ALLOW_THREADS
1767 /* PyUnicode_AS_UNICODE OK without thread lock as
1768 it is a simple dereference. */
1769 res
= _wmkdir(PyUnicode_AS_UNICODE(po
));
1770 Py_END_ALLOW_THREADS
1772 return posix_error();
1776 /* Drop the argument parsing error as narrow strings
1782 if (!PyArg_ParseTuple(args
, "et|i:mkdir",
1783 Py_FileSystemDefaultEncoding
, &path
, &mode
))
1785 Py_BEGIN_ALLOW_THREADS
1786 #if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
1789 res
= mkdir(path
, mode
);
1791 Py_END_ALLOW_THREADS
1793 return posix_error_with_allocated_filename(path
);
1801 #if defined(HAVE_BROKEN_NICE) && defined(HAVE_SYS_RESOURCE_H)
1802 #if defined(HAVE_GETPRIORITY) && !defined(PRIO_PROCESS)
1803 #include <sys/resource.h>
1807 PyDoc_STRVAR(posix_nice__doc__
,
1808 "nice(inc) -> new_priority\n\n\
1809 Decrease the priority of process by inc and return the new priority.");
1812 posix_nice(PyObject
*self
, PyObject
*args
)
1814 int increment
, value
;
1816 if (!PyArg_ParseTuple(args
, "i:nice", &increment
))
1819 /* There are two flavours of 'nice': one that returns the new
1820 priority (as required by almost all standards out there) and the
1821 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
1822 the use of getpriority() to get the new priority.
1824 If we are of the nice family that returns the new priority, we
1825 need to clear errno before the call, and check if errno is filled
1826 before calling posix_error() on a returnvalue of -1, because the
1827 -1 may be the actual new priority! */
1830 value
= nice(increment
);
1831 #if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
1833 value
= getpriority(PRIO_PROCESS
, 0);
1835 if (value
== -1 && errno
!= 0)
1836 /* either nice() or getpriority() returned an error */
1837 return posix_error();
1838 return PyInt_FromLong((long) value
);
1840 #endif /* HAVE_NICE */
1843 PyDoc_STRVAR(posix_rename__doc__
,
1844 "rename(old, new)\n\n\
1845 Rename a file or directory.");
1848 posix_rename(PyObject
*self
, PyObject
*args
)
1851 return posix_2str(args
, "etet:rename", rename
, "OO:rename", _wrename
);
1853 return posix_2str(args
, "etet:rename", rename
, NULL
, NULL
);
1858 PyDoc_STRVAR(posix_rmdir__doc__
,
1860 Remove a directory.");
1863 posix_rmdir(PyObject
*self
, PyObject
*args
)
1866 return posix_1str(args
, "et:rmdir", rmdir
, "U:rmdir", _wrmdir
);
1868 return posix_1str(args
, "et:rmdir", rmdir
, NULL
, NULL
);
1873 PyDoc_STRVAR(posix_stat__doc__
,
1874 "stat(path) -> stat result\n\n\
1875 Perform a stat system call on the given path.");
1878 posix_stat(PyObject
*self
, PyObject
*args
)
1881 return posix_do_stat(self
, args
, "et:stat", STAT
, "U:stat", _wstati64
);
1883 return posix_do_stat(self
, args
, "et:stat", STAT
, NULL
, NULL
);
1889 PyDoc_STRVAR(posix_system__doc__
,
1890 "system(command) -> exit_status\n\n\
1891 Execute the command (a string) in a subshell.");
1894 posix_system(PyObject
*self
, PyObject
*args
)
1898 if (!PyArg_ParseTuple(args
, "s:system", &command
))
1900 Py_BEGIN_ALLOW_THREADS
1901 sts
= system(command
);
1902 Py_END_ALLOW_THREADS
1903 return PyInt_FromLong(sts
);
1908 PyDoc_STRVAR(posix_umask__doc__
,
1909 "umask(new_mask) -> old_mask\n\n\
1910 Set the current numeric umask and return the previous umask.");
1913 posix_umask(PyObject
*self
, PyObject
*args
)
1916 if (!PyArg_ParseTuple(args
, "i:umask", &i
))
1920 return posix_error();
1921 return PyInt_FromLong((long)i
);
1925 PyDoc_STRVAR(posix_unlink__doc__
,
1927 Remove a file (same as remove(path)).");
1929 PyDoc_STRVAR(posix_remove__doc__
,
1931 Remove a file (same as unlink(path)).");
1934 posix_unlink(PyObject
*self
, PyObject
*args
)
1937 return posix_1str(args
, "et:remove", unlink
, "U:remove", _wunlink
);
1939 return posix_1str(args
, "et:remove", unlink
, NULL
, NULL
);
1945 PyDoc_STRVAR(posix_uname__doc__
,
1946 "uname() -> (sysname, nodename, release, version, machine)\n\n\
1947 Return a tuple identifying the current operating system.");
1950 posix_uname(PyObject
*self
, PyObject
*noargs
)
1955 Py_BEGIN_ALLOW_THREADS
1957 Py_END_ALLOW_THREADS
1959 return posix_error();
1960 return Py_BuildValue("(sssss)",
1967 #endif /* HAVE_UNAME */
1970 extract_time(PyObject
*t
, long* sec
, long* usec
)
1973 if (PyFloat_Check(t
)) {
1974 double tval
= PyFloat_AsDouble(t
);
1975 PyObject
*intobj
= t
->ob_type
->tp_as_number
->nb_int(t
);
1978 intval
= PyInt_AsLong(intobj
);
1981 *usec
= (long)((tval
- intval
) * 1e6
); /* can't exceed 1000000 */
1983 /* If rounding gave us a negative number,
1988 intval
= PyInt_AsLong(t
);
1989 if (intval
== -1 && PyErr_Occurred())
1996 PyDoc_STRVAR(posix_utime__doc__
,
1997 "utime(path, (atime, utime))\n\
1998 utime(path, None)\n\n\
1999 Set the access and modified time of the file to the given values. If the\n\
2000 second form is used, set the access and modified times to the current time.");
2003 posix_utime(PyObject
*self
, PyObject
*args
)
2006 long atime
, mtime
, ausec
, musec
;
2010 #if defined(HAVE_UTIMES)
2011 struct timeval buf
[2];
2012 #define ATIME buf[0].tv_sec
2013 #define MTIME buf[1].tv_sec
2014 #elif defined(HAVE_UTIME_H)
2015 /* XXX should define struct utimbuf instead, above */
2017 #define ATIME buf.actime
2018 #define MTIME buf.modtime
2019 #define UTIME_ARG &buf
2020 #else /* HAVE_UTIMES */
2022 #define ATIME buf[0]
2023 #define MTIME buf[1]
2024 #define UTIME_ARG buf
2025 #endif /* HAVE_UTIMES */
2027 int have_unicode_filename
= 0;
2028 #ifdef Py_WIN_WIDE_FILENAMES
2029 PyUnicodeObject
*obwpath
;
2031 if (unicode_file_names()) {
2032 if (PyArg_ParseTuple(args
, "UO|:utime", &obwpath
, &arg
)) {
2033 wpath
= PyUnicode_AS_UNICODE(obwpath
);
2034 have_unicode_filename
= 1;
2036 /* Drop the argument parsing error as narrow strings
2040 #endif /* Py_WIN_WIDE_FILENAMES */
2042 if (!have_unicode_filename
&& \
2043 !PyArg_ParseTuple(args
, "etO:utime",
2044 Py_FileSystemDefaultEncoding
, &path
, &arg
))
2046 if (arg
== Py_None
) {
2047 /* optional time values not given */
2048 Py_BEGIN_ALLOW_THREADS
2049 #ifdef Py_WIN_WIDE_FILENAMES
2050 if (have_unicode_filename
)
2051 res
= _wutime(wpath
, NULL
);
2053 #endif /* Py_WIN_WIDE_FILENAMES */
2054 res
= utime(path
, NULL
);
2055 Py_END_ALLOW_THREADS
2057 else if (!PyTuple_Check(arg
) || PyTuple_Size(arg
) != 2) {
2058 PyErr_SetString(PyExc_TypeError
,
2059 "utime() arg 2 must be a tuple (atime, mtime)");
2064 if (extract_time(PyTuple_GET_ITEM(arg
, 0),
2065 &atime
, &ausec
) == -1) {
2069 if (extract_time(PyTuple_GET_ITEM(arg
, 1),
2070 &mtime
, &musec
) == -1) {
2077 buf
[0].tv_usec
= ausec
;
2078 buf
[1].tv_usec
= musec
;
2079 Py_BEGIN_ALLOW_THREADS
2080 res
= utimes(path
, buf
);
2081 Py_END_ALLOW_THREADS
2083 Py_BEGIN_ALLOW_THREADS
2084 #ifdef Py_WIN_WIDE_FILENAMES
2085 if (have_unicode_filename
)
2086 /* utime is OK with utimbuf, but _wutime insists
2087 on _utimbuf (the msvc headers assert the
2088 underscore version is ansi) */
2089 res
= _wutime(wpath
, (struct _utimbuf
*)UTIME_ARG
);
2091 #endif /* Py_WIN_WIDE_FILENAMES */
2092 res
= utime(path
, UTIME_ARG
);
2093 Py_END_ALLOW_THREADS
2094 #endif /* HAVE_UTIMES */
2097 #ifdef Py_WIN_WIDE_FILENAMES
2098 if (have_unicode_filename
)
2099 return posix_error_with_unicode_filename(wpath
);
2100 #endif /* Py_WIN_WIDE_FILENAMES */
2101 return posix_error_with_allocated_filename(path
);
2112 /* Process operations */
2114 PyDoc_STRVAR(posix__exit__doc__
,
2116 Exit to the system with specified status, without normal exit processing.");
2119 posix__exit(PyObject
*self
, PyObject
*args
)
2122 if (!PyArg_ParseTuple(args
, "i:_exit", &sts
))
2125 return NULL
; /* Make gcc -Wall happy */
2128 #if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
2130 free_string_array(char **array
, int count
)
2133 for (i
= 0; i
< count
; i
++)
2134 PyMem_Free(array
[i
]);
2141 PyDoc_STRVAR(posix_execv__doc__
,
2142 "execv(path, args)\n\n\
2143 Execute an executable path with arguments, replacing current process.\n\
2145 path: path of executable file\n\
2146 args: tuple or list of strings");
2149 posix_execv(PyObject
*self
, PyObject
*args
)
2155 PyObject
*(*getitem
)(PyObject
*, int);
2157 /* execv has two arguments: (path, argv), where
2158 argv is a list or tuple of strings. */
2160 if (!PyArg_ParseTuple(args
, "etO:execv",
2161 Py_FileSystemDefaultEncoding
,
2164 if (PyList_Check(argv
)) {
2165 argc
= PyList_Size(argv
);
2166 getitem
= PyList_GetItem
;
2168 else if (PyTuple_Check(argv
)) {
2169 argc
= PyTuple_Size(argv
);
2170 getitem
= PyTuple_GetItem
;
2173 PyErr_SetString(PyExc_TypeError
, "execv() arg 2 must be a tuple or list");
2178 argvlist
= PyMem_NEW(char *, argc
+1);
2179 if (argvlist
== NULL
) {
2181 return PyErr_NoMemory();
2183 for (i
= 0; i
< argc
; i
++) {
2184 if (!PyArg_Parse((*getitem
)(argv
, i
), "et",
2185 Py_FileSystemDefaultEncoding
,
2187 free_string_array(argvlist
, i
);
2188 PyErr_SetString(PyExc_TypeError
,
2189 "execv() arg 2 must contain only strings");
2195 argvlist
[argc
] = NULL
;
2197 execv(path
, argvlist
);
2199 /* If we get here it's definitely an error */
2201 free_string_array(argvlist
, argc
);
2203 return posix_error();
2207 PyDoc_STRVAR(posix_execve__doc__
,
2208 "execve(path, args, env)\n\n\
2209 Execute a path with arguments and environment, replacing current process.\n\
2211 path: path of executable file\n\
2212 args: tuple or list of arguments\n\
2213 env: dictionary of strings mapping to strings");
2216 posix_execve(PyObject
*self
, PyObject
*args
)
2219 PyObject
*argv
, *env
;
2222 PyObject
*key
, *val
, *keys
=NULL
, *vals
=NULL
;
2223 int i
, pos
, argc
, envc
;
2224 PyObject
*(*getitem
)(PyObject
*, int);
2227 /* execve has three arguments: (path, argv, env), where
2228 argv is a list or tuple of strings and env is a dictionary
2229 like posix.environ. */
2231 if (!PyArg_ParseTuple(args
, "etOO:execve",
2232 Py_FileSystemDefaultEncoding
,
2233 &path
, &argv
, &env
))
2235 if (PyList_Check(argv
)) {
2236 argc
= PyList_Size(argv
);
2237 getitem
= PyList_GetItem
;
2239 else if (PyTuple_Check(argv
)) {
2240 argc
= PyTuple_Size(argv
);
2241 getitem
= PyTuple_GetItem
;
2244 PyErr_SetString(PyExc_TypeError
,
2245 "execve() arg 2 must be a tuple or list");
2248 if (!PyMapping_Check(env
)) {
2249 PyErr_SetString(PyExc_TypeError
,
2250 "execve() arg 3 must be a mapping object");
2254 argvlist
= PyMem_NEW(char *, argc
+1);
2255 if (argvlist
== NULL
) {
2259 for (i
= 0; i
< argc
; i
++) {
2260 if (!PyArg_Parse((*getitem
)(argv
, i
),
2261 "et;execve() arg 2 must contain only strings",
2262 Py_FileSystemDefaultEncoding
,
2270 argvlist
[argc
] = NULL
;
2272 i
= PyMapping_Size(env
);
2275 envlist
= PyMem_NEW(char *, i
+ 1);
2276 if (envlist
== NULL
) {
2281 keys
= PyMapping_Keys(env
);
2282 vals
= PyMapping_Values(env
);
2285 if (!PyList_Check(keys
) || !PyList_Check(vals
)) {
2286 PyErr_SetString(PyExc_TypeError
,
2287 "execve(): env.keys() or env.values() is not a list");
2291 for (pos
= 0; pos
< i
; pos
++) {
2295 key
= PyList_GetItem(keys
, pos
);
2296 val
= PyList_GetItem(vals
, pos
);
2302 "s;execve() arg 3 contains a non-string key",
2306 "s;execve() arg 3 contains a non-string value",
2312 #if defined(PYOS_OS2)
2313 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
2314 if (stricmp(k
, "BEGINLIBPATH") != 0 && stricmp(k
, "ENDLIBPATH") != 0) {
2316 len
= PyString_Size(key
) + PyString_Size(val
) + 2;
2317 p
= PyMem_NEW(char, len
);
2322 PyOS_snprintf(p
, len
, "%s=%s", k
, v
);
2323 envlist
[envc
++] = p
;
2324 #if defined(PYOS_OS2)
2330 execve(path
, argvlist
, envlist
);
2332 /* If we get here it's definitely an error */
2334 (void) posix_error();
2338 PyMem_DEL(envlist
[envc
]);
2341 free_string_array(argvlist
, lastarg
);
2348 #endif /* HAVE_EXECV */
2352 PyDoc_STRVAR(posix_spawnv__doc__
,
2353 "spawnv(mode, path, args)\n\n\
2354 Execute the program 'path' in a new process.\n\
2356 mode: mode of process creation\n\
2357 path: path of executable file\n\
2358 args: tuple or list of strings");
2361 posix_spawnv(PyObject
*self
, PyObject
*args
)
2367 Py_intptr_t spawnval
;
2368 PyObject
*(*getitem
)(PyObject
*, int);
2370 /* spawnv has three arguments: (mode, path, argv), where
2371 argv is a list or tuple of strings. */
2373 if (!PyArg_ParseTuple(args
, "ietO:spawnv", &mode
,
2374 Py_FileSystemDefaultEncoding
,
2377 if (PyList_Check(argv
)) {
2378 argc
= PyList_Size(argv
);
2379 getitem
= PyList_GetItem
;
2381 else if (PyTuple_Check(argv
)) {
2382 argc
= PyTuple_Size(argv
);
2383 getitem
= PyTuple_GetItem
;
2386 PyErr_SetString(PyExc_TypeError
,
2387 "spawnv() arg 2 must be a tuple or list");
2392 argvlist
= PyMem_NEW(char *, argc
+1);
2393 if (argvlist
== NULL
) {
2395 return PyErr_NoMemory();
2397 for (i
= 0; i
< argc
; i
++) {
2398 if (!PyArg_Parse((*getitem
)(argv
, i
), "et",
2399 Py_FileSystemDefaultEncoding
,
2401 free_string_array(argvlist
, i
);
2404 "spawnv() arg 2 must contain only strings");
2409 argvlist
[argc
] = NULL
;
2411 #if defined(PYOS_OS2) && defined(PYCC_GCC)
2412 Py_BEGIN_ALLOW_THREADS
2413 spawnval
= spawnv(mode
, path
, argvlist
);
2414 Py_END_ALLOW_THREADS
2416 if (mode
== _OLD_P_OVERLAY
)
2419 Py_BEGIN_ALLOW_THREADS
2420 spawnval
= _spawnv(mode
, path
, argvlist
);
2421 Py_END_ALLOW_THREADS
2424 free_string_array(argvlist
, argc
);
2428 return posix_error();
2430 #if SIZEOF_LONG == SIZEOF_VOID_P
2431 return Py_BuildValue("l", (long) spawnval
);
2433 return Py_BuildValue("L", (PY_LONG_LONG
) spawnval
);
2438 PyDoc_STRVAR(posix_spawnve__doc__
,
2439 "spawnve(mode, path, args, env)\n\n\
2440 Execute the program 'path' in a new process.\n\
2442 mode: mode of process creation\n\
2443 path: path of executable file\n\
2444 args: tuple or list of arguments\n\
2445 env: dictionary of strings mapping to strings");
2448 posix_spawnve(PyObject
*self
, PyObject
*args
)
2451 PyObject
*argv
, *env
;
2454 PyObject
*key
, *val
, *keys
=NULL
, *vals
=NULL
, *res
=NULL
;
2455 int mode
, i
, pos
, argc
, envc
;
2456 Py_intptr_t spawnval
;
2457 PyObject
*(*getitem
)(PyObject
*, int);
2460 /* spawnve has four arguments: (mode, path, argv, env), where
2461 argv is a list or tuple of strings and env is a dictionary
2462 like posix.environ. */
2464 if (!PyArg_ParseTuple(args
, "ietOO:spawnve", &mode
,
2465 Py_FileSystemDefaultEncoding
,
2466 &path
, &argv
, &env
))
2468 if (PyList_Check(argv
)) {
2469 argc
= PyList_Size(argv
);
2470 getitem
= PyList_GetItem
;
2472 else if (PyTuple_Check(argv
)) {
2473 argc
= PyTuple_Size(argv
);
2474 getitem
= PyTuple_GetItem
;
2477 PyErr_SetString(PyExc_TypeError
,
2478 "spawnve() arg 2 must be a tuple or list");
2481 if (!PyMapping_Check(env
)) {
2482 PyErr_SetString(PyExc_TypeError
,
2483 "spawnve() arg 3 must be a mapping object");
2487 argvlist
= PyMem_NEW(char *, argc
+1);
2488 if (argvlist
== NULL
) {
2492 for (i
= 0; i
< argc
; i
++) {
2493 if (!PyArg_Parse((*getitem
)(argv
, i
),
2494 "et;spawnve() arg 2 must contain only strings",
2495 Py_FileSystemDefaultEncoding
,
2503 argvlist
[argc
] = NULL
;
2505 i
= PyMapping_Size(env
);
2508 envlist
= PyMem_NEW(char *, i
+ 1);
2509 if (envlist
== NULL
) {
2514 keys
= PyMapping_Keys(env
);
2515 vals
= PyMapping_Values(env
);
2518 if (!PyList_Check(keys
) || !PyList_Check(vals
)) {
2519 PyErr_SetString(PyExc_TypeError
,
2520 "spawnve(): env.keys() or env.values() is not a list");
2524 for (pos
= 0; pos
< i
; pos
++) {
2528 key
= PyList_GetItem(keys
, pos
);
2529 val
= PyList_GetItem(vals
, pos
);
2535 "s;spawnve() arg 3 contains a non-string key",
2539 "s;spawnve() arg 3 contains a non-string value",
2544 len
= PyString_Size(key
) + PyString_Size(val
) + 2;
2545 p
= PyMem_NEW(char, len
);
2550 PyOS_snprintf(p
, len
, "%s=%s", k
, v
);
2551 envlist
[envc
++] = p
;
2555 #if defined(PYOS_OS2) && defined(PYCC_GCC)
2556 Py_BEGIN_ALLOW_THREADS
2557 spawnval
= spawnve(mode
, path
, argvlist
, envlist
);
2558 Py_END_ALLOW_THREADS
2560 if (mode
== _OLD_P_OVERLAY
)
2563 Py_BEGIN_ALLOW_THREADS
2564 spawnval
= _spawnve(mode
, path
, argvlist
, envlist
);
2565 Py_END_ALLOW_THREADS
2569 (void) posix_error();
2571 #if SIZEOF_LONG == SIZEOF_VOID_P
2572 res
= Py_BuildValue("l", (long) spawnval
);
2574 res
= Py_BuildValue("L", (PY_LONG_LONG
) spawnval
);
2579 PyMem_DEL(envlist
[envc
]);
2582 free_string_array(argvlist
, lastarg
);
2590 /* OS/2 supports spawnvp & spawnvpe natively */
2591 #if defined(PYOS_OS2)
2592 PyDoc_STRVAR(posix_spawnvp__doc__
,
2593 "spawnvp(mode, file, args)\n\n\
2594 Execute the program 'file' in a new process, using the environment\n\
2595 search path to find the file.\n\
2597 mode: mode of process creation\n\
2598 file: executable file name\n\
2599 args: tuple or list of strings");
2602 posix_spawnvp(PyObject
*self
, PyObject
*args
)
2608 Py_intptr_t spawnval
;
2609 PyObject
*(*getitem
)(PyObject
*, int);
2611 /* spawnvp has three arguments: (mode, path, argv), where
2612 argv is a list or tuple of strings. */
2614 if (!PyArg_ParseTuple(args
, "ietO:spawnvp", &mode
,
2615 Py_FileSystemDefaultEncoding
,
2618 if (PyList_Check(argv
)) {
2619 argc
= PyList_Size(argv
);
2620 getitem
= PyList_GetItem
;
2622 else if (PyTuple_Check(argv
)) {
2623 argc
= PyTuple_Size(argv
);
2624 getitem
= PyTuple_GetItem
;
2627 PyErr_SetString(PyExc_TypeError
,
2628 "spawnvp() arg 2 must be a tuple or list");
2633 argvlist
= PyMem_NEW(char *, argc
+1);
2634 if (argvlist
== NULL
) {
2636 return PyErr_NoMemory();
2638 for (i
= 0; i
< argc
; i
++) {
2639 if (!PyArg_Parse((*getitem
)(argv
, i
), "et",
2640 Py_FileSystemDefaultEncoding
,
2642 free_string_array(argvlist
, i
);
2645 "spawnvp() arg 2 must contain only strings");
2650 argvlist
[argc
] = NULL
;
2652 Py_BEGIN_ALLOW_THREADS
2653 #if defined(PYCC_GCC)
2654 spawnval
= spawnvp(mode
, path
, argvlist
);
2656 spawnval
= _spawnvp(mode
, path
, argvlist
);
2658 Py_END_ALLOW_THREADS
2660 free_string_array(argvlist
, argc
);
2664 return posix_error();
2666 return Py_BuildValue("l", (long) spawnval
);
2670 PyDoc_STRVAR(posix_spawnvpe__doc__
,
2671 "spawnvpe(mode, file, args, env)\n\n\
2672 Execute the program 'file' in a new process, using the environment\n\
2673 search path to find the file.\n\
2675 mode: mode of process creation\n\
2676 file: executable file name\n\
2677 args: tuple or list of arguments\n\
2678 env: dictionary of strings mapping to strings");
2681 posix_spawnvpe(PyObject
*self
, PyObject
*args
)
2684 PyObject
*argv
, *env
;
2687 PyObject
*key
, *val
, *keys
=NULL
, *vals
=NULL
, *res
=NULL
;
2688 int mode
, i
, pos
, argc
, envc
;
2689 Py_intptr_t spawnval
;
2690 PyObject
*(*getitem
)(PyObject
*, int);
2693 /* spawnvpe has four arguments: (mode, path, argv, env), where
2694 argv is a list or tuple of strings and env is a dictionary
2695 like posix.environ. */
2697 if (!PyArg_ParseTuple(args
, "ietOO:spawnvpe", &mode
,
2698 Py_FileSystemDefaultEncoding
,
2699 &path
, &argv
, &env
))
2701 if (PyList_Check(argv
)) {
2702 argc
= PyList_Size(argv
);
2703 getitem
= PyList_GetItem
;
2705 else if (PyTuple_Check(argv
)) {
2706 argc
= PyTuple_Size(argv
);
2707 getitem
= PyTuple_GetItem
;
2710 PyErr_SetString(PyExc_TypeError
,
2711 "spawnvpe() arg 2 must be a tuple or list");
2714 if (!PyMapping_Check(env
)) {
2715 PyErr_SetString(PyExc_TypeError
,
2716 "spawnvpe() arg 3 must be a mapping object");
2720 argvlist
= PyMem_NEW(char *, argc
+1);
2721 if (argvlist
== NULL
) {
2725 for (i
= 0; i
< argc
; i
++) {
2726 if (!PyArg_Parse((*getitem
)(argv
, i
),
2727 "et;spawnvpe() arg 2 must contain only strings",
2728 Py_FileSystemDefaultEncoding
,
2736 argvlist
[argc
] = NULL
;
2738 i
= PyMapping_Size(env
);
2741 envlist
= PyMem_NEW(char *, i
+ 1);
2742 if (envlist
== NULL
) {
2747 keys
= PyMapping_Keys(env
);
2748 vals
= PyMapping_Values(env
);
2751 if (!PyList_Check(keys
) || !PyList_Check(vals
)) {
2752 PyErr_SetString(PyExc_TypeError
,
2753 "spawnvpe(): env.keys() or env.values() is not a list");
2757 for (pos
= 0; pos
< i
; pos
++) {
2761 key
= PyList_GetItem(keys
, pos
);
2762 val
= PyList_GetItem(vals
, pos
);
2768 "s;spawnvpe() arg 3 contains a non-string key",
2772 "s;spawnvpe() arg 3 contains a non-string value",
2777 len
= PyString_Size(key
) + PyString_Size(val
) + 2;
2778 p
= PyMem_NEW(char, len
);
2783 PyOS_snprintf(p
, len
, "%s=%s", k
, v
);
2784 envlist
[envc
++] = p
;
2788 Py_BEGIN_ALLOW_THREADS
2789 #if defined(PYCC_GCC)
2790 spawnval
= spawnve(mode
, path
, argvlist
, envlist
);
2792 spawnval
= _spawnve(mode
, path
, argvlist
, envlist
);
2794 Py_END_ALLOW_THREADS
2797 (void) posix_error();
2799 res
= Py_BuildValue("l", (long) spawnval
);
2803 PyMem_DEL(envlist
[envc
]);
2806 free_string_array(argvlist
, lastarg
);
2813 #endif /* PYOS_OS2 */
2814 #endif /* HAVE_SPAWNV */
2818 PyDoc_STRVAR(posix_fork1__doc__
,
2819 "fork1() -> pid\n\n\
2820 Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
2822 Return 0 to child process and PID of child to parent process.");
2825 posix_fork1(PyObject
*self
, PyObject
*noargs
)
2829 return posix_error();
2831 return PyInt_FromLong((long)pid
);
2837 PyDoc_STRVAR(posix_fork__doc__
,
2839 Fork a child process.\n\
2840 Return 0 to child process and PID of child to parent process.");
2843 posix_fork(PyObject
*self
, PyObject
*noargs
)
2847 return posix_error();
2850 return PyInt_FromLong((long)pid
);
2854 /* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
2855 /* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
2856 #if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
2857 #define DEV_PTY_FILE "/dev/ptc"
2858 #define HAVE_DEV_PTMX
2860 #define DEV_PTY_FILE "/dev/ptmx"
2863 #if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
2867 #ifdef HAVE_LIBUTIL_H
2868 #include <libutil.h>
2869 #endif /* HAVE_LIBUTIL_H */
2870 #endif /* HAVE_PTY_H */
2871 #ifdef HAVE_STROPTS_H
2872 #include <stropts.h>
2874 #endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
2876 #if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
2877 PyDoc_STRVAR(posix_openpty__doc__
,
2878 "openpty() -> (master_fd, slave_fd)\n\n\
2879 Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
2882 posix_openpty(PyObject
*self
, PyObject
*noargs
)
2884 int master_fd
, slave_fd
;
2885 #ifndef HAVE_OPENPTY
2888 #if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
2889 PyOS_sighandler_t sig_saved
;
2891 extern char *ptsname();
2896 if (openpty(&master_fd
, &slave_fd
, NULL
, NULL
, NULL
) != 0)
2897 return posix_error();
2898 #elif defined(HAVE__GETPTY)
2899 slave_name
= _getpty(&master_fd
, O_RDWR
, 0666, 0);
2900 if (slave_name
== NULL
)
2901 return posix_error();
2903 slave_fd
= open(slave_name
, O_RDWR
);
2905 return posix_error();
2907 master_fd
= open(DEV_PTY_FILE
, O_RDWR
| O_NOCTTY
); /* open master */
2909 return posix_error();
2910 sig_saved
= PyOS_setsig(SIGCHLD
, SIG_DFL
);
2911 /* change permission of slave */
2912 if (grantpt(master_fd
) < 0) {
2913 PyOS_setsig(SIGCHLD
, sig_saved
);
2914 return posix_error();
2917 if (unlockpt(master_fd
) < 0) {
2918 PyOS_setsig(SIGCHLD
, sig_saved
);
2919 return posix_error();
2921 PyOS_setsig(SIGCHLD
, sig_saved
);
2922 slave_name
= ptsname(master_fd
); /* get name of slave */
2923 if (slave_name
== NULL
)
2924 return posix_error();
2925 slave_fd
= open(slave_name
, O_RDWR
| O_NOCTTY
); /* open slave */
2927 return posix_error();
2928 #if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
2929 ioctl(slave_fd
, I_PUSH
, "ptem"); /* push ptem */
2930 ioctl(slave_fd
, I_PUSH
, "ldterm"); /* push ldterm */
2932 ioctl(slave_fd
, I_PUSH
, "ttcompat"); /* push ttcompat */
2934 #endif /* HAVE_CYGWIN */
2935 #endif /* HAVE_OPENPTY */
2937 return Py_BuildValue("(ii)", master_fd
, slave_fd
);
2940 #endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
2943 PyDoc_STRVAR(posix_forkpty__doc__
,
2944 "forkpty() -> (pid, master_fd)\n\n\
2945 Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
2946 Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
2947 To both, return fd of newly opened pseudo-terminal.\n");
2950 posix_forkpty(PyObject
*self
, PyObject
*noargs
)
2954 pid
= forkpty(&master_fd
, NULL
, NULL
, NULL
);
2956 return posix_error();
2959 return Py_BuildValue("(ii)", pid
, master_fd
);
2964 PyDoc_STRVAR(posix_getegid__doc__
,
2965 "getegid() -> egid\n\n\
2966 Return the current process's effective group id.");
2969 posix_getegid(PyObject
*self
, PyObject
*noargs
)
2971 return PyInt_FromLong((long)getegid());
2977 PyDoc_STRVAR(posix_geteuid__doc__
,
2978 "geteuid() -> euid\n\n\
2979 Return the current process's effective user id.");
2982 posix_geteuid(PyObject
*self
, PyObject
*noargs
)
2984 return PyInt_FromLong((long)geteuid());
2990 PyDoc_STRVAR(posix_getgid__doc__
,
2991 "getgid() -> gid\n\n\
2992 Return the current process's group id.");
2995 posix_getgid(PyObject
*self
, PyObject
*noargs
)
2997 return PyInt_FromLong((long)getgid());
3002 PyDoc_STRVAR(posix_getpid__doc__
,
3003 "getpid() -> pid\n\n\
3004 Return the current process id");
3007 posix_getpid(PyObject
*self
, PyObject
*noargs
)
3009 return PyInt_FromLong((long)getpid());
3013 #ifdef HAVE_GETGROUPS
3014 PyDoc_STRVAR(posix_getgroups__doc__
,
3015 "getgroups() -> list of group IDs\n\n\
3016 Return list of supplemental group IDs for the process.");
3019 posix_getgroups(PyObject
*self
, PyObject
*noargs
)
3021 PyObject
*result
= NULL
;
3024 #define MAX_GROUPS NGROUPS_MAX
3026 /* defined to be 16 on Solaris7, so this should be a small number */
3027 #define MAX_GROUPS 64
3029 gid_t grouplist
[MAX_GROUPS
];
3032 n
= getgroups(MAX_GROUPS
, grouplist
);
3036 result
= PyList_New(n
);
3037 if (result
!= NULL
) {
3039 for (i
= 0; i
< n
; ++i
) {
3040 PyObject
*o
= PyInt_FromLong((long)grouplist
[i
]);
3046 PyList_SET_ITEM(result
, i
, o
);
3056 PyDoc_STRVAR(posix_getpgid__doc__
,
3057 "getpgid(pid) -> pgid\n\n\
3058 Call the system call getpgid().");
3061 posix_getpgid(PyObject
*self
, PyObject
*args
)
3064 if (!PyArg_ParseTuple(args
, "i:getpgid", &pid
))
3066 pgid
= getpgid(pid
);
3068 return posix_error();
3069 return PyInt_FromLong((long)pgid
);
3071 #endif /* HAVE_GETPGID */
3075 PyDoc_STRVAR(posix_getpgrp__doc__
,
3076 "getpgrp() -> pgrp\n\n\
3077 Return the current process group id.");
3080 posix_getpgrp(PyObject
*self
, PyObject
*noargs
)
3082 #ifdef GETPGRP_HAVE_ARG
3083 return PyInt_FromLong((long)getpgrp(0));
3084 #else /* GETPGRP_HAVE_ARG */
3085 return PyInt_FromLong((long)getpgrp());
3086 #endif /* GETPGRP_HAVE_ARG */
3088 #endif /* HAVE_GETPGRP */
3092 PyDoc_STRVAR(posix_setpgrp__doc__
,
3094 Make this process a session leader.");
3097 posix_setpgrp(PyObject
*self
, PyObject
*noargs
)
3099 #ifdef SETPGRP_HAVE_ARG
3100 if (setpgrp(0, 0) < 0)
3101 #else /* SETPGRP_HAVE_ARG */
3103 #endif /* SETPGRP_HAVE_ARG */
3104 return posix_error();
3109 #endif /* HAVE_SETPGRP */
3112 PyDoc_STRVAR(posix_getppid__doc__
,
3113 "getppid() -> ppid\n\n\
3114 Return the parent's process id.");
3117 posix_getppid(PyObject
*self
, PyObject
*noargs
)
3119 return PyInt_FromLong((long)getppid());
3124 #ifdef HAVE_GETLOGIN
3125 PyDoc_STRVAR(posix_getlogin__doc__
,
3126 "getlogin() -> string\n\n\
3127 Return the actual login name.");
3130 posix_getlogin(PyObject
*self
, PyObject
*noargs
)
3132 PyObject
*result
= NULL
;
3134 int old_errno
= errno
;
3142 PyErr_SetString(PyExc_OSError
,
3143 "unable to determine login name");
3146 result
= PyString_FromString(name
);
3154 PyDoc_STRVAR(posix_getuid__doc__
,
3155 "getuid() -> uid\n\n\
3156 Return the current process's user id.");
3159 posix_getuid(PyObject
*self
, PyObject
*noargs
)
3161 return PyInt_FromLong((long)getuid());
3167 PyDoc_STRVAR(posix_kill__doc__
,
3168 "kill(pid, sig)\n\n\
3169 Kill a process with a signal.");
3172 posix_kill(PyObject
*self
, PyObject
*args
)
3175 if (!PyArg_ParseTuple(args
, "ii:kill", &pid
, &sig
))
3177 #if defined(PYOS_OS2) && !defined(PYCC_GCC)
3178 if (sig
== XCPT_SIGNAL_INTR
|| sig
== XCPT_SIGNAL_BREAK
) {
3180 if ((rc
= DosSendSignalException(pid
, sig
)) != NO_ERROR
)
3181 return os2_error(rc
);
3183 } else if (sig
== XCPT_SIGNAL_KILLPROC
) {
3185 if ((rc
= DosKillProcess(DKP_PROCESS
, pid
)) != NO_ERROR
)
3186 return os2_error(rc
);
3189 return NULL
; /* Unrecognized Signal Requested */
3191 if (kill(pid
, sig
) == -1)
3192 return posix_error();
3200 PyDoc_STRVAR(posix_killpg__doc__
,
3201 "killpg(pgid, sig)\n\n\
3202 Kill a process group with a signal.");
3205 posix_killpg(PyObject
*self
, PyObject
*args
)
3208 if (!PyArg_ParseTuple(args
, "ii:killpg", &pgid
, &sig
))
3210 if (killpg(pgid
, sig
) == -1)
3211 return posix_error();
3219 #ifdef HAVE_SYS_LOCK_H
3220 #include <sys/lock.h>
3223 PyDoc_STRVAR(posix_plock__doc__
,
3225 Lock program segments into memory.");
3228 posix_plock(PyObject
*self
, PyObject
*args
)
3231 if (!PyArg_ParseTuple(args
, "i:plock", &op
))
3233 if (plock(op
) == -1)
3234 return posix_error();
3242 PyDoc_STRVAR(posix_popen__doc__
,
3243 "popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
3244 Open a pipe to/from a command returning a file object.");
3246 #if defined(PYOS_OS2)
3247 #if defined(PYCC_VACPP)
3249 async_system(const char *command
)
3251 char errormsg
[256], args
[1024];
3255 char *shell
= getenv("COMSPEC");
3259 /* avoid overflowing the argument buffer */
3260 if (strlen(shell
) + 3 + strlen(command
) >= 1024)
3261 return ERROR_NOT_ENOUGH_MEMORY
3264 strcat(args
, shell
);
3265 strcat(args
, "/c ");
3266 strcat(args
, command
);
3268 /* execute asynchronously, inheriting the environment */
3269 rc
= DosExecPgm(errormsg
,
3280 popen(const char *command
, const char *mode
, int pipesize
, int *err
)
3286 /* mode determines which of stdin or stdout is reconnected to
3287 * the pipe to the child
3289 if (strchr(mode
, 'r') != NULL
) {
3290 tgt_fd
= 1; /* stdout */
3291 } else if (strchr(mode
, 'w')) {
3292 tgt_fd
= 0; /* stdin */
3294 *err
= ERROR_INVALID_ACCESS
;
3298 /* setup the pipe */
3299 if ((rc
= DosCreatePipe(&pipeh
[0], &pipeh
[1], pipesize
)) != NO_ERROR
) {
3304 /* prevent other threads accessing stdio */
3307 /* reconnect stdio and execute child */
3310 if (dup2(pipeh
[tgtfd
], tgtfd
) == 0) {
3311 DosClose(pipeh
[tgtfd
]);
3312 rc
= async_system(command
);
3319 /* allow other threads access to stdio */
3322 /* if execution of child was successful return file stream */
3324 return fdopen(pipeh
[1 - tgtfd
], mode
);
3326 DosClose(pipeh
[1 - tgtfd
]);
3333 posix_popen(PyObject
*self
, PyObject
*args
)
3337 int err
, bufsize
= -1;
3340 if (!PyArg_ParseTuple(args
, "s|si:popen", &name
, &mode
, &bufsize
))
3342 Py_BEGIN_ALLOW_THREADS
3343 fp
= popen(name
, mode
, (bufsize
> 0) ? bufsize
: 4096, &err
);
3344 Py_END_ALLOW_THREADS
3346 return os2_error(err
);
3348 f
= PyFile_FromFile(fp
, name
, mode
, fclose
);
3350 PyFile_SetBufSize(f
, bufsize
);
3354 #elif defined(PYCC_GCC)
3356 /* standard posix version of popen() support */
3358 posix_popen(PyObject
*self
, PyObject
*args
)
3365 if (!PyArg_ParseTuple(args
, "s|si:popen", &name
, &mode
, &bufsize
))
3367 Py_BEGIN_ALLOW_THREADS
3368 fp
= popen(name
, mode
);
3369 Py_END_ALLOW_THREADS
3371 return posix_error();
3372 f
= PyFile_FromFile(fp
, name
, mode
, pclose
);
3374 PyFile_SetBufSize(f
, bufsize
);
3378 /* fork() under OS/2 has lots'o'warts
3379 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
3380 * most of this code is a ripoff of the win32 code, but using the
3381 * capabilities of EMX's C library routines
3384 /* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
3390 static PyObject
*_PyPopen(char *, int, int, int);
3391 static int _PyPclose(FILE *file
);
3394 * Internal dictionary mapping popen* file pointers to process handles,
3395 * for use when retrieving the process exit code. See _PyPclose() below
3396 * for more information on this dictionary's use.
3398 static PyObject
*_PyPopenProcs
= NULL
;
3400 /* os2emx version of popen2()
3402 * The result of this function is a pipe (file) connected to the
3403 * process's stdin, and a pipe connected to the process's stdout.
3407 os2emx_popen2(PyObject
*self
, PyObject
*args
)
3415 if (!PyArg_ParseTuple(args
, "s|si:popen2", &cmdstring
, &mode
, &bufsize
))
3420 else if (*mode
!= 'b') {
3421 PyErr_SetString(PyExc_ValueError
, "mode must be 't' or 'b'");
3426 f
= _PyPopen(cmdstring
, tm
, POPEN_2
, bufsize
);
3432 * Variation on os2emx.popen2
3434 * The result of this function is 3 pipes - the process's stdin,
3439 os2emx_popen3(PyObject
*self
, PyObject
*args
)
3447 if (!PyArg_ParseTuple(args
, "s|si:popen3", &cmdstring
, &mode
, &bufsize
))
3452 else if (*mode
!= 'b') {
3453 PyErr_SetString(PyExc_ValueError
, "mode must be 't' or 'b'");
3458 f
= _PyPopen(cmdstring
, tm
, POPEN_3
, bufsize
);
3464 * Variation on os2emx.popen2
3466 * The result of this function is 2 pipes - the processes stdin,
3467 * and stdout+stderr combined as a single pipe.
3471 os2emx_popen4(PyObject
*self
, PyObject
*args
)
3479 if (!PyArg_ParseTuple(args
, "s|si:popen4", &cmdstring
, &mode
, &bufsize
))
3484 else if (*mode
!= 'b') {
3485 PyErr_SetString(PyExc_ValueError
, "mode must be 't' or 'b'");
3490 f
= _PyPopen(cmdstring
, tm
, POPEN_4
, bufsize
);
3495 /* a couple of structures for convenient handling of multiple
3496 * file handles and pipes
3510 /* The following code is derived from the win32 code */
3513 _PyPopen(char *cmdstring
, int mode
, int n
, int bufsize
)
3515 struct file_ref stdio
[3];
3516 struct pipe_ref p_fd
[3];
3518 int file_count
, i
, pipe_err
, pipe_pid
;
3519 char *shell
, *sh_name
, *opt
, *rd_mode
, *wr_mode
;
3520 PyObject
*f
, *p_f
[3];
3522 /* file modes for subsequent fdopen's on pipe handles */
3534 /* prepare shell references */
3535 if ((shell
= getenv("EMXSHELL")) == NULL
)
3536 if ((shell
= getenv("COMSPEC")) == NULL
)
3539 return posix_error();
3542 sh_name
= _getname(shell
);
3543 if (stricmp(sh_name
, "cmd.exe") == 0 || stricmp(sh_name
, "4os2.exe") == 0)
3548 /* save current stdio fds + their flags, and set not inheritable */
3550 while (pipe_err
>= 0 && i
< 3)
3552 pipe_err
= stdio
[i
].handle
= dup(i
);
3553 stdio
[i
].flags
= fcntl(i
, F_GETFD
, 0);
3554 fcntl(stdio
[i
].handle
, F_SETFD
, stdio
[i
].flags
| FD_CLOEXEC
);
3559 /* didn't get them all saved - clean up and bail out */
3560 int saved_err
= errno
;
3563 close(stdio
[i
].handle
);
3566 return posix_error();
3569 /* create pipe ends */
3574 while ((pipe_err
== 0) && (i
< file_count
))
3575 pipe_err
= pipe((int *)&p_fd
[i
++]);
3578 /* didn't get them all made - clean up and bail out */
3585 return posix_error();
3588 /* change the actual standard IO streams over temporarily,
3589 * making the retained pipe ends non-inheritable
3594 if (dup2(p_fd
[0].rd
, 0) == 0)
3597 i
= fcntl(p_fd
[0].wr
, F_GETFD
, 0);
3598 fcntl(p_fd
[0].wr
, F_SETFD
, i
| FD_CLOEXEC
);
3599 if ((p_s
[0] = fdopen(p_fd
[0].wr
, wr_mode
)) == NULL
)
3613 if (dup2(p_fd
[1].wr
, 1) == 1)
3616 i
= fcntl(p_fd
[1].rd
, F_GETFD
, 0);
3617 fcntl(p_fd
[1].rd
, F_SETFD
, i
| FD_CLOEXEC
);
3618 if ((p_s
[1] = fdopen(p_fd
[1].rd
, rd_mode
)) == NULL
)
3630 /* - stderr, as required */
3636 if (dup2(p_fd
[2].wr
, 2) == 2)
3639 i
= fcntl(p_fd
[2].rd
, F_GETFD
, 0);
3640 fcntl(p_fd
[2].rd
, F_SETFD
, i
| FD_CLOEXEC
);
3641 if ((p_s
[2] = fdopen(p_fd
[2].rd
, rd_mode
)) == NULL
)
3656 if (dup2(1, 2) != 2)
3664 /* spawn the child process */
3667 pipe_pid
= spawnlp(P_NOWAIT
, shell
, shell
, opt
, cmdstring
, (char *)0);
3674 /* save the PID into the FILE structure
3675 * NOTE: this implementation doesn't actually
3676 * take advantage of this, but do it for
3677 * completeness - AIM Apr01
3679 for (i
= 0; i
< file_count
; i
++)
3680 p_s
[i
]->_pid
= pipe_pid
;
3684 /* reset standard IO to normal */
3685 for (i
= 0; i
< 3; i
++)
3687 dup2(stdio
[i
].handle
, i
);
3688 fcntl(i
, F_SETFD
, stdio
[i
].flags
);
3689 close(stdio
[i
].handle
);
3692 /* if any remnant problems, clean up and bail out */
3695 for (i
= 0; i
< 3; i
++)
3701 return posix_error_with_filename(cmdstring
);
3704 /* build tuple of file objects to return */
3705 if ((p_f
[0] = PyFile_FromFile(p_s
[0], cmdstring
, wr_mode
, _PyPclose
)) != NULL
)
3706 PyFile_SetBufSize(p_f
[0], bufsize
);
3707 if ((p_f
[1] = PyFile_FromFile(p_s
[1], cmdstring
, rd_mode
, _PyPclose
)) != NULL
)
3708 PyFile_SetBufSize(p_f
[1], bufsize
);
3711 if ((p_f
[2] = PyFile_FromFile(p_s
[2], cmdstring
, rd_mode
, _PyPclose
)) != NULL
)
3712 PyFile_SetBufSize(p_f
[0], bufsize
);
3713 f
= PyTuple_Pack(3, p_f
[0], p_f
[1], p_f
[2]);
3716 f
= PyTuple_Pack(2, p_f
[0], p_f
[1]);
3719 * Insert the files we've created into the process dictionary
3720 * all referencing the list with the process handle and the
3721 * initial number of files (see description below in _PyPclose).
3722 * Since if _PyPclose later tried to wait on a process when all
3723 * handles weren't closed, it could create a deadlock with the
3724 * child, we spend some energy here to try to ensure that we
3725 * either insert all file handles into the dictionary or none
3726 * at all. It's a little clumsy with the various popen modes
3727 * and variable number of files involved.
3731 _PyPopenProcs
= PyDict_New();
3736 PyObject
*procObj
, *pidObj
, *intObj
, *fileObj
[3];
3739 fileObj
[0] = fileObj
[1] = fileObj
[2] = NULL
;
3740 ins_rc
[0] = ins_rc
[1] = ins_rc
[2] = 0;
3742 procObj
= PyList_New(2);
3743 pidObj
= PyInt_FromLong((long) pipe_pid
);
3744 intObj
= PyInt_FromLong((long) file_count
);
3746 if (procObj
&& pidObj
&& intObj
)
3748 PyList_SetItem(procObj
, 0, pidObj
);
3749 PyList_SetItem(procObj
, 1, intObj
);
3751 fileObj
[0] = PyLong_FromVoidPtr(p_s
[0]);
3754 ins_rc
[0] = PyDict_SetItem(_PyPopenProcs
,
3758 fileObj
[1] = PyLong_FromVoidPtr(p_s
[1]);
3761 ins_rc
[1] = PyDict_SetItem(_PyPopenProcs
,
3765 if (file_count
>= 3)
3767 fileObj
[2] = PyLong_FromVoidPtr(p_s
[2]);
3770 ins_rc
[2] = PyDict_SetItem(_PyPopenProcs
,
3776 if (ins_rc
[0] < 0 || !fileObj
[0] ||
3777 ins_rc
[1] < 0 || (file_count
> 1 && !fileObj
[1]) ||
3778 ins_rc
[2] < 0 || (file_count
> 2 && !fileObj
[2]))
3780 /* Something failed - remove any dictionary
3781 * entries that did make it.
3783 if (!ins_rc
[0] && fileObj
[0])
3785 PyDict_DelItem(_PyPopenProcs
,
3788 if (!ins_rc
[1] && fileObj
[1])
3790 PyDict_DelItem(_PyPopenProcs
,
3793 if (!ins_rc
[2] && fileObj
[2])
3795 PyDict_DelItem(_PyPopenProcs
,
3802 * Clean up our localized references for the dictionary keys
3803 * and value since PyDict_SetItem will Py_INCREF any copies
3804 * that got placed in the dictionary.
3806 Py_XDECREF(procObj
);
3807 Py_XDECREF(fileObj
[0]);
3808 Py_XDECREF(fileObj
[1]);
3809 Py_XDECREF(fileObj
[2]);
3812 /* Child is launched. */
3817 * Wrapper for fclose() to use for popen* files, so we can retrieve the
3818 * exit code for the child process and return as a result of the close.
3820 * This function uses the _PyPopenProcs dictionary in order to map the
3821 * input file pointer to information about the process that was
3822 * originally created by the popen* call that created the file pointer.
3823 * The dictionary uses the file pointer as a key (with one entry
3824 * inserted for each file returned by the original popen* call) and a
3825 * single list object as the value for all files from a single call.
3826 * The list object contains the Win32 process handle at [0], and a file
3827 * count at [1], which is initialized to the total number of file
3828 * handles using that list.
3830 * This function closes whichever handle it is passed, and decrements
3831 * the file count in the dictionary for the process handle pointed to
3832 * by this file. On the last close (when the file count reaches zero),
3833 * this function will wait for the child process and then return its
3834 * exit code as the result of the close() operation. This permits the
3835 * files to be closed in any order - it is always the close() of the
3836 * final handle that will return the exit code.
3838 * NOTE: This function is currently called with the GIL released.
3839 * hence we use the GILState API to manage our state.
3842 static int _PyPclose(FILE *file
)
3847 PyObject
*procObj
, *pidObj
, *intObj
, *fileObj
;
3850 PyGILState_STATE state
;
3853 /* Close the file handle first, to ensure it can't block the
3854 * child from exiting if it's the last handle.
3856 result
= fclose(file
);
3859 state
= PyGILState_Ensure();
3863 if ((fileObj
= PyLong_FromVoidPtr(file
)) != NULL
&&
3864 (procObj
= PyDict_GetItem(_PyPopenProcs
,
3865 fileObj
)) != NULL
&&
3866 (pidObj
= PyList_GetItem(procObj
,0)) != NULL
&&
3867 (intObj
= PyList_GetItem(procObj
,1)) != NULL
)
3869 pipe_pid
= (int) PyInt_AsLong(pidObj
);
3870 file_count
= (int) PyInt_AsLong(intObj
);
3874 /* Still other files referencing process */
3876 PyList_SetItem(procObj
,1,
3877 PyInt_FromLong((long) file_count
));
3881 /* Last file for this process */
3882 if (result
!= EOF
&&
3883 waitpid(pipe_pid
, &exit_code
, 0) == pipe_pid
)
3885 /* extract exit status */
3886 if (WIFEXITED(exit_code
))
3888 result
= WEXITSTATUS(exit_code
);
3898 /* Indicate failure - this will cause the file object
3899 * to raise an I/O error and translate the last
3900 * error code from errno. We do have a problem with
3901 * last errors that overlap the normal errno table,
3902 * but that's a consistent problem with the file object.
3908 /* Remove this file pointer from dictionary */
3909 PyDict_DelItem(_PyPopenProcs
, fileObj
);
3911 if (PyDict_Size(_PyPopenProcs
) == 0)
3913 Py_DECREF(_PyPopenProcs
);
3914 _PyPopenProcs
= NULL
;
3917 } /* if object retrieval ok */
3919 Py_XDECREF(fileObj
);
3920 } /* if _PyPopenProcs */
3923 PyGILState_Release(state
);
3928 #endif /* PYCC_??? */
3930 #elif defined(MS_WINDOWS)
3933 * Portable 'popen' replacement for Win32.
3935 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
3936 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
3937 * Return code handling by David Bolen <db3l@fitlinxx.com>.
3944 /* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
3950 static PyObject
*_PyPopen(char *, int, int);
3951 static int _PyPclose(FILE *file
);
3954 * Internal dictionary mapping popen* file pointers to process handles,
3955 * for use when retrieving the process exit code. See _PyPclose() below
3956 * for more information on this dictionary's use.
3958 static PyObject
*_PyPopenProcs
= NULL
;
3961 /* popen that works from a GUI.
3963 * The result of this function is a pipe (file) connected to the
3964 * processes stdin or stdout, depending on the requested mode.
3968 posix_popen(PyObject
*self
, PyObject
*args
)
3976 if (!PyArg_ParseTuple(args
, "s|si:popen", &cmdstring
, &mode
, &bufsize
))
3981 else if (*mode
!= 'w') {
3982 PyErr_SetString(PyExc_ValueError
, "popen() arg 2 must be 'r' or 'w'");
3987 if (bufsize
!= -1) {
3988 PyErr_SetString(PyExc_ValueError
, "popen() arg 3 must be -1");
3992 if (*(mode
+1) == 't')
3993 f
= _PyPopen(cmdstring
, tm
| _O_TEXT
, POPEN_1
);
3994 else if (*(mode
+1) == 'b')
3995 f
= _PyPopen(cmdstring
, tm
| _O_BINARY
, POPEN_1
);
3997 f
= _PyPopen(cmdstring
, tm
| _O_TEXT
, POPEN_1
);
4002 /* Variation on win32pipe.popen
4004 * The result of this function is a pipe (file) connected to the
4005 * process's stdin, and a pipe connected to the process's stdout.
4009 win32_popen2(PyObject
*self
, PyObject
*args
)
4017 if (!PyArg_ParseTuple(args
, "s|si:popen2", &cmdstring
, &mode
, &bufsize
))
4022 else if (*mode
!= 'b') {
4023 PyErr_SetString(PyExc_ValueError
, "popen2() arg 2 must be 't' or 'b'");
4028 if (bufsize
!= -1) {
4029 PyErr_SetString(PyExc_ValueError
, "popen2() arg 3 must be -1");
4033 f
= _PyPopen(cmdstring
, tm
, POPEN_2
);
4039 * Variation on <om win32pipe.popen>
4041 * The result of this function is 3 pipes - the process's stdin,
4046 win32_popen3(PyObject
*self
, PyObject
*args
)
4054 if (!PyArg_ParseTuple(args
, "s|si:popen3", &cmdstring
, &mode
, &bufsize
))
4059 else if (*mode
!= 'b') {
4060 PyErr_SetString(PyExc_ValueError
, "popen3() arg 2 must be 't' or 'b'");
4065 if (bufsize
!= -1) {
4066 PyErr_SetString(PyExc_ValueError
, "popen3() arg 3 must be -1");
4070 f
= _PyPopen(cmdstring
, tm
, POPEN_3
);
4076 * Variation on win32pipe.popen
4078 * The result of this function is 2 pipes - the processes stdin,
4079 * and stdout+stderr combined as a single pipe.
4083 win32_popen4(PyObject
*self
, PyObject
*args
)
4091 if (!PyArg_ParseTuple(args
, "s|si:popen4", &cmdstring
, &mode
, &bufsize
))
4096 else if (*mode
!= 'b') {
4097 PyErr_SetString(PyExc_ValueError
, "popen4() arg 2 must be 't' or 'b'");
4102 if (bufsize
!= -1) {
4103 PyErr_SetString(PyExc_ValueError
, "popen4() arg 3 must be -1");
4107 f
= _PyPopen(cmdstring
, tm
, POPEN_4
);
4113 _PyPopenCreateProcess(char *cmdstring
,
4119 PROCESS_INFORMATION piProcInfo
;
4120 STARTUPINFO siStartInfo
;
4121 DWORD dwProcessFlags
= 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
4122 char *s1
,*s2
, *s3
= " /c ";
4123 const char *szConsoleSpawn
= "w9xpopen.exe";
4127 if (i
= GetEnvironmentVariable("COMSPEC",NULL
,0)) {
4130 s1
= (char *)alloca(i
);
4131 if (!(x
= GetEnvironmentVariable("COMSPEC", s1
, i
)))
4134 /* Explicitly check if we are using COMMAND.COM. If we are
4135 * then use the w9xpopen hack.
4138 while (comshell
>= s1
&& *comshell
!= '\\')
4142 if (GetVersion() < 0x80000000 &&
4143 _stricmp(comshell
, "command.com") != 0) {
4144 /* NT/2000 and not using command.com. */
4145 x
= i
+ strlen(s3
) + strlen(cmdstring
) + 1;
4146 s2
= (char *)alloca(x
);
4148 PyOS_snprintf(s2
, x
, "%s%s%s", s1
, s3
, cmdstring
);
4152 * Oh gag, we're on Win9x or using COMMAND.COM. Use
4153 * the workaround listed in KB: Q150956
4155 char modulepath
[_MAX_PATH
];
4156 struct stat statinfo
;
4157 GetModuleFileName(NULL
, modulepath
, sizeof(modulepath
));
4158 for (i
= x
= 0; modulepath
[i
]; i
++)
4159 if (modulepath
[i
] == SEP
)
4161 modulepath
[x
] = '\0';
4162 /* Create the full-name to w9xpopen, so we can test it exists */
4165 (sizeof(modulepath
)/sizeof(modulepath
[0]))
4166 -strlen(modulepath
));
4167 if (stat(modulepath
, &statinfo
) != 0) {
4168 /* Eeek - file-not-found - possibly an embedding
4169 situation - see if we can locate it in sys.prefix
4173 sizeof(modulepath
)/sizeof(modulepath
[0]));
4174 if (modulepath
[strlen(modulepath
)-1] != '\\')
4175 strcat(modulepath
, "\\");
4178 (sizeof(modulepath
)/sizeof(modulepath
[0]))
4179 -strlen(modulepath
));
4180 /* No where else to look - raise an easily identifiable
4181 error, rather than leaving Windows to report
4182 "file not found" - as the user is probably blissfully
4183 unaware this shim EXE is used, and it will confuse them.
4184 (well, it confused me for a while ;-)
4186 if (stat(modulepath
, &statinfo
) != 0) {
4187 PyErr_Format(PyExc_RuntimeError
,
4188 "Can not locate '%s' which is needed "
4189 "for popen to work with your shell "
4195 x
= i
+ strlen(s3
) + strlen(cmdstring
) + 1 +
4196 strlen(modulepath
) +
4197 strlen(szConsoleSpawn
) + 1;
4199 s2
= (char *)alloca(x
);
4201 /* To maintain correct argument passing semantics,
4202 we pass the command-line as it stands, and allow
4203 quoting to be applied. w9xpopen.exe will then
4204 use its argv vector, and re-quote the necessary
4205 args for the ultimate child process.
4214 /* Not passing CREATE_NEW_CONSOLE has been known to
4215 cause random failures on win9x. Specifically a
4217 "Your program accessed mem currently in use at xxx"
4218 and a hopeful warning about the stability of your
4220 Cost is Ctrl+C wont kill children, but anyone
4221 who cares can have a go!
4223 dwProcessFlags
|= CREATE_NEW_CONSOLE
;
4227 /* Could be an else here to try cmd.exe / command.com in the path
4228 Now we'll just error out.. */
4230 PyErr_SetString(PyExc_RuntimeError
,
4231 "Cannot locate a COMSPEC environment variable to "
4232 "use as the shell");
4236 ZeroMemory(&siStartInfo
, sizeof(STARTUPINFO
));
4237 siStartInfo
.cb
= sizeof(STARTUPINFO
);
4238 siStartInfo
.dwFlags
= STARTF_USESTDHANDLES
| STARTF_USESHOWWINDOW
;
4239 siStartInfo
.hStdInput
= hStdin
;
4240 siStartInfo
.hStdOutput
= hStdout
;
4241 siStartInfo
.hStdError
= hStderr
;
4242 siStartInfo
.wShowWindow
= SW_HIDE
;
4244 if (CreateProcess(NULL
,
4254 /* Close the handles now so anyone waiting is woken. */
4255 CloseHandle(piProcInfo
.hThread
);
4257 /* Return process handle */
4258 *hProcess
= piProcInfo
.hProcess
;
4261 win32_error("CreateProcess", s2
);
4265 /* The following code is based off of KB: Q190351 */
4268 _PyPopen(char *cmdstring
, int mode
, int n
)
4270 HANDLE hChildStdinRd
, hChildStdinWr
, hChildStdoutRd
, hChildStdoutWr
,
4271 hChildStderrRd
, hChildStderrWr
, hChildStdinWrDup
, hChildStdoutRdDup
,
4272 hChildStderrRdDup
, hProcess
; /* hChildStdoutWrDup; */
4274 SECURITY_ATTRIBUTES saAttr
;
4281 saAttr
.nLength
= sizeof(SECURITY_ATTRIBUTES
);
4282 saAttr
.bInheritHandle
= TRUE
;
4283 saAttr
.lpSecurityDescriptor
= NULL
;
4285 if (!CreatePipe(&hChildStdinRd
, &hChildStdinWr
, &saAttr
, 0))
4286 return win32_error("CreatePipe", NULL
);
4288 /* Create new output read handle and the input write handle. Set
4289 * the inheritance properties to FALSE. Otherwise, the child inherits
4290 * these handles; resulting in non-closeable handles to the pipes
4292 fSuccess
= DuplicateHandle(GetCurrentProcess(), hChildStdinWr
,
4293 GetCurrentProcess(), &hChildStdinWrDup
, 0,
4295 DUPLICATE_SAME_ACCESS
);
4297 return win32_error("DuplicateHandle", NULL
);
4299 /* Close the inheritable version of ChildStdin
4300 that we're using. */
4301 CloseHandle(hChildStdinWr
);
4303 if (!CreatePipe(&hChildStdoutRd
, &hChildStdoutWr
, &saAttr
, 0))
4304 return win32_error("CreatePipe", NULL
);
4306 fSuccess
= DuplicateHandle(GetCurrentProcess(), hChildStdoutRd
,
4307 GetCurrentProcess(), &hChildStdoutRdDup
, 0,
4308 FALSE
, DUPLICATE_SAME_ACCESS
);
4310 return win32_error("DuplicateHandle", NULL
);
4312 /* Close the inheritable version of ChildStdout
4313 that we're using. */
4314 CloseHandle(hChildStdoutRd
);
4317 if (!CreatePipe(&hChildStderrRd
, &hChildStderrWr
, &saAttr
, 0))
4318 return win32_error("CreatePipe", NULL
);
4319 fSuccess
= DuplicateHandle(GetCurrentProcess(),
4321 GetCurrentProcess(),
4322 &hChildStderrRdDup
, 0,
4323 FALSE
, DUPLICATE_SAME_ACCESS
);
4325 return win32_error("DuplicateHandle", NULL
);
4326 /* Close the inheritable version of ChildStdErr that we're using. */
4327 CloseHandle(hChildStderrRd
);
4332 switch (mode
& (_O_RDONLY
| _O_TEXT
| _O_BINARY
| _O_WRONLY
)) {
4333 case _O_WRONLY
| _O_TEXT
:
4334 /* Case for writing to child Stdin in text mode. */
4335 fd1
= _open_osfhandle((long)hChildStdinWrDup
, mode
);
4336 f1
= _fdopen(fd1
, "w");
4337 f
= PyFile_FromFile(f1
, cmdstring
, "w", _PyPclose
);
4338 PyFile_SetBufSize(f
, 0);
4339 /* We don't care about these pipes anymore, so close them. */
4340 CloseHandle(hChildStdoutRdDup
);
4341 CloseHandle(hChildStderrRdDup
);
4344 case _O_RDONLY
| _O_TEXT
:
4345 /* Case for reading from child Stdout in text mode. */
4346 fd1
= _open_osfhandle((long)hChildStdoutRdDup
, mode
);
4347 f1
= _fdopen(fd1
, "r");
4348 f
= PyFile_FromFile(f1
, cmdstring
, "r", _PyPclose
);
4349 PyFile_SetBufSize(f
, 0);
4350 /* We don't care about these pipes anymore, so close them. */
4351 CloseHandle(hChildStdinWrDup
);
4352 CloseHandle(hChildStderrRdDup
);
4355 case _O_RDONLY
| _O_BINARY
:
4356 /* Case for readinig from child Stdout in binary mode. */
4357 fd1
= _open_osfhandle((long)hChildStdoutRdDup
, mode
);
4358 f1
= _fdopen(fd1
, "rb");
4359 f
= PyFile_FromFile(f1
, cmdstring
, "rb", _PyPclose
);
4360 PyFile_SetBufSize(f
, 0);
4361 /* We don't care about these pipes anymore, so close them. */
4362 CloseHandle(hChildStdinWrDup
);
4363 CloseHandle(hChildStderrRdDup
);
4366 case _O_WRONLY
| _O_BINARY
:
4367 /* Case for writing to child Stdin in binary mode. */
4368 fd1
= _open_osfhandle((long)hChildStdinWrDup
, mode
);
4369 f1
= _fdopen(fd1
, "wb");
4370 f
= PyFile_FromFile(f1
, cmdstring
, "wb", _PyPclose
);
4371 PyFile_SetBufSize(f
, 0);
4372 /* We don't care about these pipes anymore, so close them. */
4373 CloseHandle(hChildStdoutRdDup
);
4374 CloseHandle(hChildStderrRdDup
);
4386 if (mode
& _O_TEXT
) {
4394 fd1
= _open_osfhandle((long)hChildStdinWrDup
, mode
);
4395 f1
= _fdopen(fd1
, m2
);
4396 fd2
= _open_osfhandle((long)hChildStdoutRdDup
, mode
);
4397 f2
= _fdopen(fd2
, m1
);
4398 p1
= PyFile_FromFile(f1
, cmdstring
, m2
, _PyPclose
);
4399 PyFile_SetBufSize(p1
, 0);
4400 p2
= PyFile_FromFile(f2
, cmdstring
, m1
, _PyPclose
);
4401 PyFile_SetBufSize(p2
, 0);
4404 CloseHandle(hChildStderrRdDup
);
4406 f
= PyTuple_Pack(2,p1
,p2
);
4416 PyObject
*p1
, *p2
, *p3
;
4418 if (mode
& _O_TEXT
) {
4426 fd1
= _open_osfhandle((long)hChildStdinWrDup
, mode
);
4427 f1
= _fdopen(fd1
, m2
);
4428 fd2
= _open_osfhandle((long)hChildStdoutRdDup
, mode
);
4429 f2
= _fdopen(fd2
, m1
);
4430 fd3
= _open_osfhandle((long)hChildStderrRdDup
, mode
);
4431 f3
= _fdopen(fd3
, m1
);
4432 p1
= PyFile_FromFile(f1
, cmdstring
, m2
, _PyPclose
);
4433 p2
= PyFile_FromFile(f2
, cmdstring
, m1
, _PyPclose
);
4434 p3
= PyFile_FromFile(f3
, cmdstring
, m1
, _PyPclose
);
4435 PyFile_SetBufSize(p1
, 0);
4436 PyFile_SetBufSize(p2
, 0);
4437 PyFile_SetBufSize(p3
, 0);
4438 f
= PyTuple_Pack(3,p1
,p2
,p3
);
4448 if (!_PyPopenCreateProcess(cmdstring
,
4456 if (!_PyPopenCreateProcess(cmdstring
,
4465 * Insert the files we've created into the process dictionary
4466 * all referencing the list with the process handle and the
4467 * initial number of files (see description below in _PyPclose).
4468 * Since if _PyPclose later tried to wait on a process when all
4469 * handles weren't closed, it could create a deadlock with the
4470 * child, we spend some energy here to try to ensure that we
4471 * either insert all file handles into the dictionary or none
4472 * at all. It's a little clumsy with the various popen modes
4473 * and variable number of files involved.
4475 if (!_PyPopenProcs
) {
4476 _PyPopenProcs
= PyDict_New();
4479 if (_PyPopenProcs
) {
4480 PyObject
*procObj
, *hProcessObj
, *intObj
, *fileObj
[3];
4483 fileObj
[0] = fileObj
[1] = fileObj
[2] = NULL
;
4484 ins_rc
[0] = ins_rc
[1] = ins_rc
[2] = 0;
4486 procObj
= PyList_New(2);
4487 hProcessObj
= PyLong_FromVoidPtr(hProcess
);
4488 intObj
= PyInt_FromLong(file_count
);
4490 if (procObj
&& hProcessObj
&& intObj
) {
4491 PyList_SetItem(procObj
,0,hProcessObj
);
4492 PyList_SetItem(procObj
,1,intObj
);
4494 fileObj
[0] = PyLong_FromVoidPtr(f1
);
4496 ins_rc
[0] = PyDict_SetItem(_PyPopenProcs
,
4500 if (file_count
>= 2) {
4501 fileObj
[1] = PyLong_FromVoidPtr(f2
);
4503 ins_rc
[1] = PyDict_SetItem(_PyPopenProcs
,
4508 if (file_count
>= 3) {
4509 fileObj
[2] = PyLong_FromVoidPtr(f3
);
4511 ins_rc
[2] = PyDict_SetItem(_PyPopenProcs
,
4517 if (ins_rc
[0] < 0 || !fileObj
[0] ||
4518 ins_rc
[1] < 0 || (file_count
> 1 && !fileObj
[1]) ||
4519 ins_rc
[2] < 0 || (file_count
> 2 && !fileObj
[2])) {
4520 /* Something failed - remove any dictionary
4521 * entries that did make it.
4523 if (!ins_rc
[0] && fileObj
[0]) {
4524 PyDict_DelItem(_PyPopenProcs
,
4527 if (!ins_rc
[1] && fileObj
[1]) {
4528 PyDict_DelItem(_PyPopenProcs
,
4531 if (!ins_rc
[2] && fileObj
[2]) {
4532 PyDict_DelItem(_PyPopenProcs
,
4539 * Clean up our localized references for the dictionary keys
4540 * and value since PyDict_SetItem will Py_INCREF any copies
4541 * that got placed in the dictionary.
4543 Py_XDECREF(procObj
);
4544 Py_XDECREF(fileObj
[0]);
4545 Py_XDECREF(fileObj
[1]);
4546 Py_XDECREF(fileObj
[2]);
4549 /* Child is launched. Close the parents copy of those pipe
4550 * handles that only the child should have open. You need to
4551 * make sure that no handles to the write end of the output pipe
4552 * are maintained in this process or else the pipe will not close
4553 * when the child process exits and the ReadFile will hang. */
4555 if (!CloseHandle(hChildStdinRd
))
4556 return win32_error("CloseHandle", NULL
);
4558 if (!CloseHandle(hChildStdoutWr
))
4559 return win32_error("CloseHandle", NULL
);
4561 if ((n
!= 4) && (!CloseHandle(hChildStderrWr
)))
4562 return win32_error("CloseHandle", NULL
);
4568 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4569 * exit code for the child process and return as a result of the close.
4571 * This function uses the _PyPopenProcs dictionary in order to map the
4572 * input file pointer to information about the process that was
4573 * originally created by the popen* call that created the file pointer.
4574 * The dictionary uses the file pointer as a key (with one entry
4575 * inserted for each file returned by the original popen* call) and a
4576 * single list object as the value for all files from a single call.
4577 * The list object contains the Win32 process handle at [0], and a file
4578 * count at [1], which is initialized to the total number of file
4579 * handles using that list.
4581 * This function closes whichever handle it is passed, and decrements
4582 * the file count in the dictionary for the process handle pointed to
4583 * by this file. On the last close (when the file count reaches zero),
4584 * this function will wait for the child process and then return its
4585 * exit code as the result of the close() operation. This permits the
4586 * files to be closed in any order - it is always the close() of the
4587 * final handle that will return the exit code.
4589 * NOTE: This function is currently called with the GIL released.
4590 * hence we use the GILState API to manage our state.
4593 static int _PyPclose(FILE *file
)
4598 PyObject
*procObj
, *hProcessObj
, *intObj
, *fileObj
;
4601 PyGILState_STATE state
;
4604 /* Close the file handle first, to ensure it can't block the
4605 * child from exiting if it's the last handle.
4607 result
= fclose(file
);
4609 state
= PyGILState_Ensure();
4611 if (_PyPopenProcs
) {
4612 if ((fileObj
= PyLong_FromVoidPtr(file
)) != NULL
&&
4613 (procObj
= PyDict_GetItem(_PyPopenProcs
,
4614 fileObj
)) != NULL
&&
4615 (hProcessObj
= PyList_GetItem(procObj
,0)) != NULL
&&
4616 (intObj
= PyList_GetItem(procObj
,1)) != NULL
) {
4618 hProcess
= PyLong_AsVoidPtr(hProcessObj
);
4619 file_count
= PyInt_AsLong(intObj
);
4621 if (file_count
> 1) {
4622 /* Still other files referencing process */
4624 PyList_SetItem(procObj
,1,
4625 PyInt_FromLong(file_count
));
4627 /* Last file for this process */
4628 if (result
!= EOF
&&
4629 WaitForSingleObject(hProcess
, INFINITE
) != WAIT_FAILED
&&
4630 GetExitCodeProcess(hProcess
, &exit_code
)) {
4631 /* Possible truncation here in 16-bit environments, but
4632 * real exit codes are just the lower byte in any event.
4636 /* Indicate failure - this will cause the file object
4637 * to raise an I/O error and translate the last Win32
4638 * error code from errno. We do have a problem with
4639 * last errors that overlap the normal errno table,
4640 * but that's a consistent problem with the file object.
4642 if (result
!= EOF
) {
4643 /* If the error wasn't from the fclose(), then
4644 * set errno for the file object error handling.
4646 errno
= GetLastError();
4651 /* Free up the native handle at this point */
4652 CloseHandle(hProcess
);
4655 /* Remove this file pointer from dictionary */
4656 PyDict_DelItem(_PyPopenProcs
, fileObj
);
4658 if (PyDict_Size(_PyPopenProcs
) == 0) {
4659 Py_DECREF(_PyPopenProcs
);
4660 _PyPopenProcs
= NULL
;
4663 } /* if object retrieval ok */
4665 Py_XDECREF(fileObj
);
4666 } /* if _PyPopenProcs */
4669 PyGILState_Release(state
);
4674 #else /* which OS? */
4676 posix_popen(PyObject
*self
, PyObject
*args
)
4683 if (!PyArg_ParseTuple(args
, "s|si:popen", &name
, &mode
, &bufsize
))
4685 /* Strip mode of binary or text modifiers */
4686 if (strcmp(mode
, "rb") == 0 || strcmp(mode
, "rt") == 0)
4688 else if (strcmp(mode
, "wb") == 0 || strcmp(mode
, "wt") == 0)
4690 Py_BEGIN_ALLOW_THREADS
4691 fp
= popen(name
, mode
);
4692 Py_END_ALLOW_THREADS
4694 return posix_error();
4695 f
= PyFile_FromFile(fp
, name
, mode
, pclose
);
4697 PyFile_SetBufSize(f
, bufsize
);
4701 #endif /* PYOS_??? */
4702 #endif /* HAVE_POPEN */
4706 PyDoc_STRVAR(posix_setuid__doc__
,
4708 Set the current process's user id.");
4711 posix_setuid(PyObject
*self
, PyObject
*args
)
4714 if (!PyArg_ParseTuple(args
, "i:setuid", &uid
))
4716 if (setuid(uid
) < 0)
4717 return posix_error();
4721 #endif /* HAVE_SETUID */
4725 PyDoc_STRVAR(posix_seteuid__doc__
,
4727 Set the current process's effective user id.");
4730 posix_seteuid (PyObject
*self
, PyObject
*args
)
4733 if (!PyArg_ParseTuple(args
, "i", &euid
)) {
4735 } else if (seteuid(euid
) < 0) {
4736 return posix_error();
4742 #endif /* HAVE_SETEUID */
4745 PyDoc_STRVAR(posix_setegid__doc__
,
4747 Set the current process's effective group id.");
4750 posix_setegid (PyObject
*self
, PyObject
*args
)
4753 if (!PyArg_ParseTuple(args
, "i", &egid
)) {
4755 } else if (setegid(egid
) < 0) {
4756 return posix_error();
4762 #endif /* HAVE_SETEGID */
4764 #ifdef HAVE_SETREUID
4765 PyDoc_STRVAR(posix_setreuid__doc__
,
4766 "setreuid(ruid, euid)\n\n\
4767 Set the current process's real and effective user ids.");
4770 posix_setreuid (PyObject
*self
, PyObject
*args
)
4773 if (!PyArg_ParseTuple(args
, "ii", &ruid
, &euid
)) {
4775 } else if (setreuid(ruid
, euid
) < 0) {
4776 return posix_error();
4782 #endif /* HAVE_SETREUID */
4784 #ifdef HAVE_SETREGID
4785 PyDoc_STRVAR(posix_setregid__doc__
,
4786 "setregid(rgid, egid)\n\n\
4787 Set the current process's real and effective group ids.");
4790 posix_setregid (PyObject
*self
, PyObject
*args
)
4793 if (!PyArg_ParseTuple(args
, "ii", &rgid
, &egid
)) {
4795 } else if (setregid(rgid
, egid
) < 0) {
4796 return posix_error();
4802 #endif /* HAVE_SETREGID */
4805 PyDoc_STRVAR(posix_setgid__doc__
,
4807 Set the current process's group id.");
4810 posix_setgid(PyObject
*self
, PyObject
*args
)
4813 if (!PyArg_ParseTuple(args
, "i:setgid", &gid
))
4815 if (setgid(gid
) < 0)
4816 return posix_error();
4820 #endif /* HAVE_SETGID */
4822 #ifdef HAVE_SETGROUPS
4823 PyDoc_STRVAR(posix_setgroups__doc__
,
4824 "setgroups(list)\n\n\
4825 Set the groups of the current process to list.");
4828 posix_setgroups(PyObject
*self
, PyObject
*args
)
4832 gid_t grouplist
[MAX_GROUPS
];
4834 if (!PyArg_ParseTuple(args
, "O:setgid", &groups
))
4836 if (!PySequence_Check(groups
)) {
4837 PyErr_SetString(PyExc_TypeError
, "setgroups argument must be a sequence");
4840 len
= PySequence_Size(groups
);
4841 if (len
> MAX_GROUPS
) {
4842 PyErr_SetString(PyExc_ValueError
, "too many groups");
4845 for(i
= 0; i
< len
; i
++) {
4847 elem
= PySequence_GetItem(groups
, i
);
4850 if (!PyInt_Check(elem
)) {
4851 PyErr_SetString(PyExc_TypeError
,
4852 "groups must be integers");
4856 /* XXX: check that value fits into gid_t. */
4857 grouplist
[i
] = PyInt_AsLong(elem
);
4861 if (setgroups(len
, grouplist
) < 0)
4862 return posix_error();
4866 #endif /* HAVE_SETGROUPS */
4869 PyDoc_STRVAR(posix_waitpid__doc__
,
4870 "waitpid(pid, options) -> (pid, status)\n\n\
4871 Wait for completion of a given child process.");
4874 posix_waitpid(PyObject
*self
, PyObject
*args
)
4879 #define status_i (status.w_status)
4882 #define status_i status
4886 if (!PyArg_ParseTuple(args
, "ii:waitpid", &pid
, &options
))
4888 Py_BEGIN_ALLOW_THREADS
4889 pid
= waitpid(pid
, &status
, options
);
4890 Py_END_ALLOW_THREADS
4892 return posix_error();
4894 return Py_BuildValue("ii", pid
, status_i
);
4897 #elif defined(HAVE_CWAIT)
4899 /* MS C has a variant of waitpid() that's usable for most purposes. */
4900 PyDoc_STRVAR(posix_waitpid__doc__
,
4901 "waitpid(pid, options) -> (pid, status << 8)\n\n"
4902 "Wait for completion of a given process. options is ignored on Windows.");
4905 posix_waitpid(PyObject
*self
, PyObject
*args
)
4910 if (!PyArg_ParseTuple(args
, "ii:waitpid", &pid
, &options
))
4912 Py_BEGIN_ALLOW_THREADS
4913 pid
= _cwait(&status
, pid
, options
);
4914 Py_END_ALLOW_THREADS
4916 return posix_error();
4918 /* shift the status left a byte so this is more like the
4920 return Py_BuildValue("ii", pid
, status
<< 8);
4922 #endif /* HAVE_WAITPID || HAVE_CWAIT */
4925 PyDoc_STRVAR(posix_wait__doc__
,
4926 "wait() -> (pid, status)\n\n\
4927 Wait for completion of a child process.");
4930 posix_wait(PyObject
*self
, PyObject
*noargs
)
4935 #define status_i (status.w_status)
4938 #define status_i status
4942 Py_BEGIN_ALLOW_THREADS
4943 pid
= wait(&status
);
4944 Py_END_ALLOW_THREADS
4946 return posix_error();
4948 return Py_BuildValue("ii", pid
, status_i
);
4954 PyDoc_STRVAR(posix_lstat__doc__
,
4955 "lstat(path) -> stat result\n\n\
4956 Like stat(path), but do not follow symbolic links.");
4959 posix_lstat(PyObject
*self
, PyObject
*args
)
4962 return posix_do_stat(self
, args
, "et:lstat", lstat
, NULL
, NULL
);
4963 #else /* !HAVE_LSTAT */
4965 return posix_do_stat(self
, args
, "et:lstat", STAT
, "U:lstat", _wstati64
);
4967 return posix_do_stat(self
, args
, "et:lstat", STAT
, NULL
, NULL
);
4969 #endif /* !HAVE_LSTAT */
4973 #ifdef HAVE_READLINK
4974 PyDoc_STRVAR(posix_readlink__doc__
,
4975 "readlink(path) -> path\n\n\
4976 Return a string representing the path to which the symbolic link points.");
4979 posix_readlink(PyObject
*self
, PyObject
*args
)
4981 char buf
[MAXPATHLEN
];
4984 if (!PyArg_ParseTuple(args
, "s:readlink", &path
))
4986 Py_BEGIN_ALLOW_THREADS
4987 n
= readlink(path
, buf
, (int) sizeof buf
);
4988 Py_END_ALLOW_THREADS
4990 return posix_error_with_filename(path
);
4991 return PyString_FromStringAndSize(buf
, n
);
4993 #endif /* HAVE_READLINK */
4997 PyDoc_STRVAR(posix_symlink__doc__
,
4998 "symlink(src, dst)\n\n\
4999 Create a symbolic link pointing to src named dst.");
5002 posix_symlink(PyObject
*self
, PyObject
*args
)
5004 return posix_2str(args
, "etet:symlink", symlink
, NULL
, NULL
);
5006 #endif /* HAVE_SYMLINK */
5011 #define HZ 60 /* Universal constant :-) */
5014 #if defined(PYCC_VACPP) && defined(PYOS_OS2)
5020 Py_BEGIN_ALLOW_THREADS
5021 DosQuerySysInfo(QSV_MS_COUNT
, QSV_MS_COUNT
, &value
, sizeof(value
));
5022 Py_END_ALLOW_THREADS
5028 posix_times(PyObject
*self
, PyObject
*noargs
)
5030 /* Currently Only Uptime is Provided -- Others Later */
5031 return Py_BuildValue("ddddd",
5032 (double)0 /* t.tms_utime / HZ */,
5033 (double)0 /* t.tms_stime / HZ */,
5034 (double)0 /* t.tms_cutime / HZ */,
5035 (double)0 /* t.tms_cstime / HZ */,
5036 (double)system_uptime() / 1000);
5040 posix_times(PyObject
*self
, PyObject
*noargs
)
5046 if (c
== (clock_t) -1)
5047 return posix_error();
5048 return Py_BuildValue("ddddd",
5049 (double)t
.tms_utime
/ HZ
,
5050 (double)t
.tms_stime
/ HZ
,
5051 (double)t
.tms_cutime
/ HZ
,
5052 (double)t
.tms_cstime
/ HZ
,
5055 #endif /* not OS2 */
5056 #endif /* HAVE_TIMES */
5060 #define HAVE_TIMES /* so the method table will pick it up */
5062 posix_times(PyObject
*self
, PyObject
*noargs
)
5064 FILETIME create
, exit
, kernel
, user
;
5066 hProc
= GetCurrentProcess();
5067 GetProcessTimes(hProc
, &create
, &exit
, &kernel
, &user
);
5068 /* The fields of a FILETIME structure are the hi and lo part
5069 of a 64-bit value expressed in 100 nanosecond units.
5070 1e7 is one second in such units; 1e-7 the inverse.
5071 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
5073 return Py_BuildValue(
5075 (double)(kernel
.dwHighDateTime
*429.4967296 +
5076 kernel
.dwLowDateTime
*1e-7),
5077 (double)(user
.dwHighDateTime
*429.4967296 +
5078 user
.dwLowDateTime
*1e-7),
5083 #endif /* MS_WINDOWS */
5086 PyDoc_STRVAR(posix_times__doc__
,
5087 "times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
5088 Return a tuple of floating point numbers indicating process times.");
5093 PyDoc_STRVAR(posix_getsid__doc__
,
5094 "getsid(pid) -> sid\n\n\
5095 Call the system call getsid().");
5098 posix_getsid(PyObject
*self
, PyObject
*args
)
5101 if (!PyArg_ParseTuple(args
, "i:getsid", &pid
))
5105 return posix_error();
5106 return PyInt_FromLong((long)sid
);
5108 #endif /* HAVE_GETSID */
5112 PyDoc_STRVAR(posix_setsid__doc__
,
5114 Call the system call setsid().");
5117 posix_setsid(PyObject
*self
, PyObject
*noargs
)
5120 return posix_error();
5124 #endif /* HAVE_SETSID */
5127 PyDoc_STRVAR(posix_setpgid__doc__
,
5128 "setpgid(pid, pgrp)\n\n\
5129 Call the system call setpgid().");
5132 posix_setpgid(PyObject
*self
, PyObject
*args
)
5135 if (!PyArg_ParseTuple(args
, "ii:setpgid", &pid
, &pgrp
))
5137 if (setpgid(pid
, pgrp
) < 0)
5138 return posix_error();
5142 #endif /* HAVE_SETPGID */
5145 #ifdef HAVE_TCGETPGRP
5146 PyDoc_STRVAR(posix_tcgetpgrp__doc__
,
5147 "tcgetpgrp(fd) -> pgid\n\n\
5148 Return the process group associated with the terminal given by a fd.");
5151 posix_tcgetpgrp(PyObject
*self
, PyObject
*args
)
5154 if (!PyArg_ParseTuple(args
, "i:tcgetpgrp", &fd
))
5156 pgid
= tcgetpgrp(fd
);
5158 return posix_error();
5159 return PyInt_FromLong((long)pgid
);
5161 #endif /* HAVE_TCGETPGRP */
5164 #ifdef HAVE_TCSETPGRP
5165 PyDoc_STRVAR(posix_tcsetpgrp__doc__
,
5166 "tcsetpgrp(fd, pgid)\n\n\
5167 Set the process group associated with the terminal given by a fd.");
5170 posix_tcsetpgrp(PyObject
*self
, PyObject
*args
)
5173 if (!PyArg_ParseTuple(args
, "ii:tcsetpgrp", &fd
, &pgid
))
5175 if (tcsetpgrp(fd
, pgid
) < 0)
5176 return posix_error();
5180 #endif /* HAVE_TCSETPGRP */
5182 /* Functions acting on file descriptors */
5184 PyDoc_STRVAR(posix_open__doc__
,
5185 "open(filename, flag [, mode=0777]) -> fd\n\n\
5186 Open a file (for low level IO).");
5189 posix_open(PyObject
*self
, PyObject
*args
)
5197 if (unicode_file_names()) {
5198 PyUnicodeObject
*po
;
5199 if (PyArg_ParseTuple(args
, "Ui|i:mkdir", &po
, &flag
, &mode
)) {
5200 Py_BEGIN_ALLOW_THREADS
5201 /* PyUnicode_AS_UNICODE OK without thread
5202 lock as it is a simple dereference. */
5203 fd
= _wopen(PyUnicode_AS_UNICODE(po
), flag
, mode
);
5204 Py_END_ALLOW_THREADS
5206 return posix_error();
5207 return PyInt_FromLong((long)fd
);
5209 /* Drop the argument parsing error as narrow strings
5215 if (!PyArg_ParseTuple(args
, "eti|i",
5216 Py_FileSystemDefaultEncoding
, &file
,
5220 Py_BEGIN_ALLOW_THREADS
5221 fd
= open(file
, flag
, mode
);
5222 Py_END_ALLOW_THREADS
5224 return posix_error_with_allocated_filename(file
);
5226 return PyInt_FromLong((long)fd
);
5230 PyDoc_STRVAR(posix_close__doc__
,
5232 Close a file descriptor (for low level IO).");
5235 posix_close(PyObject
*self
, PyObject
*args
)
5238 if (!PyArg_ParseTuple(args
, "i:close", &fd
))
5240 Py_BEGIN_ALLOW_THREADS
5242 Py_END_ALLOW_THREADS
5244 return posix_error();
5250 PyDoc_STRVAR(posix_dup__doc__
,
5251 "dup(fd) -> fd2\n\n\
5252 Return a duplicate of a file descriptor.");
5255 posix_dup(PyObject
*self
, PyObject
*args
)
5258 if (!PyArg_ParseTuple(args
, "i:dup", &fd
))
5260 Py_BEGIN_ALLOW_THREADS
5262 Py_END_ALLOW_THREADS
5264 return posix_error();
5265 return PyInt_FromLong((long)fd
);
5269 PyDoc_STRVAR(posix_dup2__doc__
,
5270 "dup2(old_fd, new_fd)\n\n\
5271 Duplicate file descriptor.");
5274 posix_dup2(PyObject
*self
, PyObject
*args
)
5277 if (!PyArg_ParseTuple(args
, "ii:dup2", &fd
, &fd2
))
5279 Py_BEGIN_ALLOW_THREADS
5280 res
= dup2(fd
, fd2
);
5281 Py_END_ALLOW_THREADS
5283 return posix_error();
5289 PyDoc_STRVAR(posix_lseek__doc__
,
5290 "lseek(fd, pos, how) -> newpos\n\n\
5291 Set the current position of a file descriptor.");
5294 posix_lseek(PyObject
*self
, PyObject
*args
)
5297 #if defined(MS_WIN64) || defined(MS_WINDOWS)
5298 PY_LONG_LONG pos
, res
;
5303 if (!PyArg_ParseTuple(args
, "iOi:lseek", &fd
, &posobj
, &how
))
5306 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
5308 case 0: how
= SEEK_SET
; break;
5309 case 1: how
= SEEK_CUR
; break;
5310 case 2: how
= SEEK_END
; break;
5312 #endif /* SEEK_END */
5314 #if !defined(HAVE_LARGEFILE_SUPPORT)
5315 pos
= PyInt_AsLong(posobj
);
5317 pos
= PyLong_Check(posobj
) ?
5318 PyLong_AsLongLong(posobj
) : PyInt_AsLong(posobj
);
5320 if (PyErr_Occurred())
5323 Py_BEGIN_ALLOW_THREADS
5324 #if defined(MS_WIN64) || defined(MS_WINDOWS)
5325 res
= _lseeki64(fd
, pos
, how
);
5327 res
= lseek(fd
, pos
, how
);
5329 Py_END_ALLOW_THREADS
5331 return posix_error();
5333 #if !defined(HAVE_LARGEFILE_SUPPORT)
5334 return PyInt_FromLong(res
);
5336 return PyLong_FromLongLong(res
);
5341 PyDoc_STRVAR(posix_read__doc__
,
5342 "read(fd, buffersize) -> string\n\n\
5343 Read a file descriptor.");
5346 posix_read(PyObject
*self
, PyObject
*args
)
5350 if (!PyArg_ParseTuple(args
, "ii:read", &fd
, &size
))
5352 buffer
= PyString_FromStringAndSize((char *)NULL
, size
);
5355 Py_BEGIN_ALLOW_THREADS
5356 n
= read(fd
, PyString_AsString(buffer
), size
);
5357 Py_END_ALLOW_THREADS
5360 return posix_error();
5363 _PyString_Resize(&buffer
, n
);
5368 PyDoc_STRVAR(posix_write__doc__
,
5369 "write(fd, string) -> byteswritten\n\n\
5370 Write a string to a file descriptor.");
5373 posix_write(PyObject
*self
, PyObject
*args
)
5377 if (!PyArg_ParseTuple(args
, "is#:write", &fd
, &buffer
, &size
))
5379 Py_BEGIN_ALLOW_THREADS
5380 size
= write(fd
, buffer
, size
);
5381 Py_END_ALLOW_THREADS
5383 return posix_error();
5384 return PyInt_FromLong((long)size
);
5388 PyDoc_STRVAR(posix_fstat__doc__
,
5389 "fstat(fd) -> stat result\n\n\
5390 Like stat(), but for an open file descriptor.");
5393 posix_fstat(PyObject
*self
, PyObject
*args
)
5398 if (!PyArg_ParseTuple(args
, "i:fstat", &fd
))
5401 /* on OpenVMS we must ensure that all bytes are written to the file */
5404 Py_BEGIN_ALLOW_THREADS
5405 res
= FSTAT(fd
, &st
);
5406 Py_END_ALLOW_THREADS
5408 return posix_error();
5410 return _pystat_fromstructstat(st
);
5414 PyDoc_STRVAR(posix_fdopen__doc__
,
5415 "fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
5416 Return an open file object connected to a file descriptor.");
5419 posix_fdopen(PyObject
*self
, PyObject
*args
)
5426 if (!PyArg_ParseTuple(args
, "i|si", &fd
, &mode
, &bufsize
))
5429 if (mode
[0] != 'r' && mode
[0] != 'w' && mode
[0] != 'a') {
5430 PyErr_Format(PyExc_ValueError
,
5431 "invalid file mode '%s'", mode
);
5435 Py_BEGIN_ALLOW_THREADS
5436 fp
= fdopen(fd
, mode
);
5437 Py_END_ALLOW_THREADS
5439 return posix_error();
5440 f
= PyFile_FromFile(fp
, "<fdopen>", mode
, fclose
);
5442 PyFile_SetBufSize(f
, bufsize
);
5446 PyDoc_STRVAR(posix_isatty__doc__
,
5447 "isatty(fd) -> bool\n\n\
5448 Return True if the file descriptor 'fd' is an open file descriptor\n\
5449 connected to the slave end of a terminal.");
5452 posix_isatty(PyObject
*self
, PyObject
*args
)
5455 if (!PyArg_ParseTuple(args
, "i:isatty", &fd
))
5457 return PyBool_FromLong(isatty(fd
));
5461 PyDoc_STRVAR(posix_pipe__doc__
,
5462 "pipe() -> (read_end, write_end)\n\n\
5466 posix_pipe(PyObject
*self
, PyObject
*noargs
)
5468 #if defined(PYOS_OS2)
5472 Py_BEGIN_ALLOW_THREADS
5473 rc
= DosCreatePipe( &read
, &write
, 4096);
5474 Py_END_ALLOW_THREADS
5476 return os2_error(rc
);
5478 return Py_BuildValue("(ii)", read
, write
);
5480 #if !defined(MS_WINDOWS)
5483 Py_BEGIN_ALLOW_THREADS
5485 Py_END_ALLOW_THREADS
5487 return posix_error();
5488 return Py_BuildValue("(ii)", fds
[0], fds
[1]);
5489 #else /* MS_WINDOWS */
5491 int read_fd
, write_fd
;
5493 Py_BEGIN_ALLOW_THREADS
5494 ok
= CreatePipe(&read
, &write
, NULL
, 0);
5495 Py_END_ALLOW_THREADS
5497 return win32_error("CreatePipe", NULL
);
5498 read_fd
= _open_osfhandle((Py_intptr_t
)read
, 0);
5499 write_fd
= _open_osfhandle((Py_intptr_t
)write
, 1);
5500 return Py_BuildValue("(ii)", read_fd
, write_fd
);
5501 #endif /* MS_WINDOWS */
5504 #endif /* HAVE_PIPE */
5508 PyDoc_STRVAR(posix_mkfifo__doc__
,
5509 "mkfifo(filename [, mode=0666])\n\n\
5510 Create a FIFO (a POSIX named pipe).");
5513 posix_mkfifo(PyObject
*self
, PyObject
*args
)
5518 if (!PyArg_ParseTuple(args
, "s|i:mkfifo", &filename
, &mode
))
5520 Py_BEGIN_ALLOW_THREADS
5521 res
= mkfifo(filename
, mode
);
5522 Py_END_ALLOW_THREADS
5524 return posix_error();
5531 #if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
5532 PyDoc_STRVAR(posix_mknod__doc__
,
5533 "mknod(filename [, mode=0600, device])\n\n\
5534 Create a filesystem node (file, device special file or named pipe)\n\
5535 named filename. mode specifies both the permissions to use and the\n\
5536 type of node to be created, being combined (bitwise OR) with one of\n\
5537 S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
5538 device defines the newly created device special file (probably using\n\
5539 os.makedev()), otherwise it is ignored.");
5543 posix_mknod(PyObject
*self
, PyObject
*args
)
5549 if (!PyArg_ParseTuple(args
, "s|ii:mknod", &filename
, &mode
, &device
))
5551 Py_BEGIN_ALLOW_THREADS
5552 res
= mknod(filename
, mode
, device
);
5553 Py_END_ALLOW_THREADS
5555 return posix_error();
5561 #ifdef HAVE_DEVICE_MACROS
5562 PyDoc_STRVAR(posix_major__doc__
,
5563 "major(device) -> major number\n\
5564 Extracts a device major number from a raw device number.");
5567 posix_major(PyObject
*self
, PyObject
*args
)
5570 if (!PyArg_ParseTuple(args
, "i:major", &device
))
5572 return PyInt_FromLong((long)major(device
));
5575 PyDoc_STRVAR(posix_minor__doc__
,
5576 "minor(device) -> minor number\n\
5577 Extracts a device minor number from a raw device number.");
5580 posix_minor(PyObject
*self
, PyObject
*args
)
5583 if (!PyArg_ParseTuple(args
, "i:minor", &device
))
5585 return PyInt_FromLong((long)minor(device
));
5588 PyDoc_STRVAR(posix_makedev__doc__
,
5589 "makedev(major, minor) -> device number\n\
5590 Composes a raw device number from the major and minor device numbers.");
5593 posix_makedev(PyObject
*self
, PyObject
*args
)
5596 if (!PyArg_ParseTuple(args
, "ii:makedev", &major
, &minor
))
5598 return PyInt_FromLong((long)makedev(major
, minor
));
5600 #endif /* device macros */
5603 #ifdef HAVE_FTRUNCATE
5604 PyDoc_STRVAR(posix_ftruncate__doc__
,
5605 "ftruncate(fd, length)\n\n\
5606 Truncate a file to a specified length.");
5609 posix_ftruncate(PyObject
*self
, PyObject
*args
)
5616 if (!PyArg_ParseTuple(args
, "iO:ftruncate", &fd
, &lenobj
))
5619 #if !defined(HAVE_LARGEFILE_SUPPORT)
5620 length
= PyInt_AsLong(lenobj
);
5622 length
= PyLong_Check(lenobj
) ?
5623 PyLong_AsLongLong(lenobj
) : PyInt_AsLong(lenobj
);
5625 if (PyErr_Occurred())
5628 Py_BEGIN_ALLOW_THREADS
5629 res
= ftruncate(fd
, length
);
5630 Py_END_ALLOW_THREADS
5632 PyErr_SetFromErrno(PyExc_IOError
);
5641 PyDoc_STRVAR(posix_putenv__doc__
,
5642 "putenv(key, value)\n\n\
5643 Change or add an environment variable.");
5645 /* Save putenv() parameters as values here, so we can collect them when they
5646 * get re-set with another call for the same key. */
5647 static PyObject
*posix_putenv_garbage
;
5650 posix_putenv(PyObject
*self
, PyObject
*args
)
5657 if (!PyArg_ParseTuple(args
, "ss:putenv", &s1
, &s2
))
5660 #if defined(PYOS_OS2)
5661 if (stricmp(s1
, "BEGINLIBPATH") == 0) {
5664 rc
= DosSetExtLIBPATH(s2
, BEGIN_LIBPATH
);
5666 return os2_error(rc
);
5668 } else if (stricmp(s1
, "ENDLIBPATH") == 0) {
5671 rc
= DosSetExtLIBPATH(s2
, END_LIBPATH
);
5673 return os2_error(rc
);
5677 /* XXX This can leak memory -- not easy to fix :-( */
5678 len
= strlen(s1
) + strlen(s2
) + 2;
5679 /* len includes space for a trailing \0; the size arg to
5680 PyString_FromStringAndSize does not count that */
5681 newstr
= PyString_FromStringAndSize(NULL
, (int)len
- 1);
5683 return PyErr_NoMemory();
5684 new = PyString_AS_STRING(newstr
);
5685 PyOS_snprintf(new, len
, "%s=%s", s1
, s2
);
5691 /* Install the first arg and newstr in posix_putenv_garbage;
5692 * this will cause previous value to be collected. This has to
5693 * happen after the real putenv() call because the old value
5694 * was still accessible until then. */
5695 if (PyDict_SetItem(posix_putenv_garbage
,
5696 PyTuple_GET_ITEM(args
, 0), newstr
)) {
5697 /* really not much we can do; just leak */
5704 #if defined(PYOS_OS2)
5712 #ifdef HAVE_UNSETENV
5713 PyDoc_STRVAR(posix_unsetenv__doc__
,
5715 Delete an environment variable.");
5718 posix_unsetenv(PyObject
*self
, PyObject
*args
)
5722 if (!PyArg_ParseTuple(args
, "s:unsetenv", &s1
))
5727 /* Remove the key from posix_putenv_garbage;
5728 * this will cause it to be collected. This has to
5729 * happen after the real unsetenv() call because the
5730 * old value was still accessible until then.
5732 if (PyDict_DelItem(posix_putenv_garbage
,
5733 PyTuple_GET_ITEM(args
, 0))) {
5734 /* really not much we can do; just leak */
5741 #endif /* unsetenv */
5743 #ifdef HAVE_STRERROR
5744 PyDoc_STRVAR(posix_strerror__doc__
,
5745 "strerror(code) -> string\n\n\
5746 Translate an error code to a message string.");
5749 posix_strerror(PyObject
*self
, PyObject
*args
)
5753 if (!PyArg_ParseTuple(args
, "i:strerror", &code
))
5755 message
= strerror(code
);
5756 if (message
== NULL
) {
5757 PyErr_SetString(PyExc_ValueError
,
5758 "strerror() argument out of range");
5761 return PyString_FromString(message
);
5763 #endif /* strerror */
5766 #ifdef HAVE_SYS_WAIT_H
5769 PyDoc_STRVAR(posix_WCOREDUMP__doc__
,
5770 "WCOREDUMP(status) -> bool\n\n\
5771 Return True if the process returning 'status' was dumped to a core file.");
5774 posix_WCOREDUMP(PyObject
*self
, PyObject
*args
)
5778 #define status_i (status.w_status)
5781 #define status_i status
5785 if (!PyArg_ParseTuple(args
, "i:WCOREDUMP", &status_i
))
5790 return PyBool_FromLong(WCOREDUMP(status
));
5793 #endif /* WCOREDUMP */
5796 PyDoc_STRVAR(posix_WIFCONTINUED__doc__
,
5797 "WIFCONTINUED(status) -> bool\n\n\
5798 Return True if the process returning 'status' was continued from a\n\
5799 job control stop.");
5802 posix_WIFCONTINUED(PyObject
*self
, PyObject
*args
)
5806 #define status_i (status.w_status)
5809 #define status_i status
5813 if (!PyArg_ParseTuple(args
, "i:WCONTINUED", &status_i
))
5818 return PyBool_FromLong(WIFCONTINUED(status
));
5821 #endif /* WIFCONTINUED */
5824 PyDoc_STRVAR(posix_WIFSTOPPED__doc__
,
5825 "WIFSTOPPED(status) -> bool\n\n\
5826 Return True if the process returning 'status' was stopped.");
5829 posix_WIFSTOPPED(PyObject
*self
, PyObject
*args
)
5833 #define status_i (status.w_status)
5836 #define status_i status
5840 if (!PyArg_ParseTuple(args
, "i:WIFSTOPPED", &status_i
))
5845 return PyBool_FromLong(WIFSTOPPED(status
));
5848 #endif /* WIFSTOPPED */
5851 PyDoc_STRVAR(posix_WIFSIGNALED__doc__
,
5852 "WIFSIGNALED(status) -> bool\n\n\
5853 Return True if the process returning 'status' was terminated by a signal.");
5856 posix_WIFSIGNALED(PyObject
*self
, PyObject
*args
)
5860 #define status_i (status.w_status)
5863 #define status_i status
5867 if (!PyArg_ParseTuple(args
, "i:WIFSIGNALED", &status_i
))
5872 return PyBool_FromLong(WIFSIGNALED(status
));
5875 #endif /* WIFSIGNALED */
5878 PyDoc_STRVAR(posix_WIFEXITED__doc__
,
5879 "WIFEXITED(status) -> bool\n\n\
5880 Return true if the process returning 'status' exited using the exit()\n\
5884 posix_WIFEXITED(PyObject
*self
, PyObject
*args
)
5888 #define status_i (status.w_status)
5891 #define status_i status
5895 if (!PyArg_ParseTuple(args
, "i:WIFEXITED", &status_i
))
5900 return PyBool_FromLong(WIFEXITED(status
));
5903 #endif /* WIFEXITED */
5906 PyDoc_STRVAR(posix_WEXITSTATUS__doc__
,
5907 "WEXITSTATUS(status) -> integer\n\n\
5908 Return the process return code from 'status'.");
5911 posix_WEXITSTATUS(PyObject
*self
, PyObject
*args
)
5915 #define status_i (status.w_status)
5918 #define status_i status
5922 if (!PyArg_ParseTuple(args
, "i:WEXITSTATUS", &status_i
))
5927 return Py_BuildValue("i", WEXITSTATUS(status
));
5930 #endif /* WEXITSTATUS */
5933 PyDoc_STRVAR(posix_WTERMSIG__doc__
,
5934 "WTERMSIG(status) -> integer\n\n\
5935 Return the signal that terminated the process that provided the 'status'\n\
5939 posix_WTERMSIG(PyObject
*self
, PyObject
*args
)
5943 #define status_i (status.w_status)
5946 #define status_i status
5950 if (!PyArg_ParseTuple(args
, "i:WTERMSIG", &status_i
))
5955 return Py_BuildValue("i", WTERMSIG(status
));
5958 #endif /* WTERMSIG */
5961 PyDoc_STRVAR(posix_WSTOPSIG__doc__
,
5962 "WSTOPSIG(status) -> integer\n\n\
5963 Return the signal that stopped the process that provided\n\
5964 the 'status' value.");
5967 posix_WSTOPSIG(PyObject
*self
, PyObject
*args
)
5971 #define status_i (status.w_status)
5974 #define status_i status
5978 if (!PyArg_ParseTuple(args
, "i:WSTOPSIG", &status_i
))
5983 return Py_BuildValue("i", WSTOPSIG(status
));
5986 #endif /* WSTOPSIG */
5988 #endif /* HAVE_SYS_WAIT_H */
5991 #if defined(HAVE_FSTATVFS)
5993 /* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
5994 needed definitions in sys/statvfs.h */
5997 #include <sys/statvfs.h>
6000 _pystatvfs_fromstructstatvfs(struct statvfs st
) {
6001 PyObject
*v
= PyStructSequence_New(&StatVFSResultType
);
6005 #if !defined(HAVE_LARGEFILE_SUPPORT)
6006 PyStructSequence_SET_ITEM(v
, 0, PyInt_FromLong((long) st
.f_bsize
));
6007 PyStructSequence_SET_ITEM(v
, 1, PyInt_FromLong((long) st
.f_frsize
));
6008 PyStructSequence_SET_ITEM(v
, 2, PyInt_FromLong((long) st
.f_blocks
));
6009 PyStructSequence_SET_ITEM(v
, 3, PyInt_FromLong((long) st
.f_bfree
));
6010 PyStructSequence_SET_ITEM(v
, 4, PyInt_FromLong((long) st
.f_bavail
));
6011 PyStructSequence_SET_ITEM(v
, 5, PyInt_FromLong((long) st
.f_files
));
6012 PyStructSequence_SET_ITEM(v
, 6, PyInt_FromLong((long) st
.f_ffree
));
6013 PyStructSequence_SET_ITEM(v
, 7, PyInt_FromLong((long) st
.f_favail
));
6014 PyStructSequence_SET_ITEM(v
, 8, PyInt_FromLong((long) st
.f_flag
));
6015 PyStructSequence_SET_ITEM(v
, 9, PyInt_FromLong((long) st
.f_namemax
));
6017 PyStructSequence_SET_ITEM(v
, 0, PyInt_FromLong((long) st
.f_bsize
));
6018 PyStructSequence_SET_ITEM(v
, 1, PyInt_FromLong((long) st
.f_frsize
));
6019 PyStructSequence_SET_ITEM(v
, 2,
6020 PyLong_FromLongLong((PY_LONG_LONG
) st
.f_blocks
));
6021 PyStructSequence_SET_ITEM(v
, 3,
6022 PyLong_FromLongLong((PY_LONG_LONG
) st
.f_bfree
));
6023 PyStructSequence_SET_ITEM(v
, 4,
6024 PyLong_FromLongLong((PY_LONG_LONG
) st
.f_bavail
));
6025 PyStructSequence_SET_ITEM(v
, 5,
6026 PyLong_FromLongLong((PY_LONG_LONG
) st
.f_files
));
6027 PyStructSequence_SET_ITEM(v
, 6,
6028 PyLong_FromLongLong((PY_LONG_LONG
) st
.f_ffree
));
6029 PyStructSequence_SET_ITEM(v
, 7,
6030 PyLong_FromLongLong((PY_LONG_LONG
) st
.f_favail
));
6031 PyStructSequence_SET_ITEM(v
, 8, PyInt_FromLong((long) st
.f_flag
));
6032 PyStructSequence_SET_ITEM(v
, 9, PyInt_FromLong((long) st
.f_namemax
));
6038 PyDoc_STRVAR(posix_fstatvfs__doc__
,
6039 "fstatvfs(fd) -> statvfs result\n\n\
6040 Perform an fstatvfs system call on the given fd.");
6043 posix_fstatvfs(PyObject
*self
, PyObject
*args
)
6048 if (!PyArg_ParseTuple(args
, "i:fstatvfs", &fd
))
6050 Py_BEGIN_ALLOW_THREADS
6051 res
= fstatvfs(fd
, &st
);
6052 Py_END_ALLOW_THREADS
6054 return posix_error();
6056 return _pystatvfs_fromstructstatvfs(st
);
6058 #endif /* HAVE_FSTATVFS */
6061 #if defined(HAVE_STATVFS)
6062 #include <sys/statvfs.h>
6064 PyDoc_STRVAR(posix_statvfs__doc__
,
6065 "statvfs(path) -> statvfs result\n\n\
6066 Perform a statvfs system call on the given path.");
6069 posix_statvfs(PyObject
*self
, PyObject
*args
)
6074 if (!PyArg_ParseTuple(args
, "s:statvfs", &path
))
6076 Py_BEGIN_ALLOW_THREADS
6077 res
= statvfs(path
, &st
);
6078 Py_END_ALLOW_THREADS
6080 return posix_error_with_filename(path
);
6082 return _pystatvfs_fromstructstatvfs(st
);
6084 #endif /* HAVE_STATVFS */
6088 PyDoc_STRVAR(posix_tempnam__doc__
,
6089 "tempnam([dir[, prefix]]) -> string\n\n\
6090 Return a unique name for a temporary file.\n\
6091 The directory and a prefix may be specified as strings; they may be omitted\n\
6092 or None if not needed.");
6095 posix_tempnam(PyObject
*self
, PyObject
*args
)
6097 PyObject
*result
= NULL
;
6102 if (!PyArg_ParseTuple(args
, "|zz:tempnam", &dir
, &pfx
))
6105 if (PyErr_Warn(PyExc_RuntimeWarning
,
6106 "tempnam is a potential security risk to your program") < 0)
6110 name
= _tempnam(dir
, pfx
);
6112 name
= tempnam(dir
, pfx
);
6115 return PyErr_NoMemory();
6116 result
= PyString_FromString(name
);
6124 PyDoc_STRVAR(posix_tmpfile__doc__
,
6125 "tmpfile() -> file object\n\n\
6126 Create a temporary file with no directory entries.");
6129 posix_tmpfile(PyObject
*self
, PyObject
*noargs
)
6135 return posix_error();
6136 return PyFile_FromFile(fp
, "<tmpfile>", "w+b", fclose
);
6142 PyDoc_STRVAR(posix_tmpnam__doc__
,
6143 "tmpnam() -> string\n\n\
6144 Return a unique name for a temporary file.");
6147 posix_tmpnam(PyObject
*self
, PyObject
*noargs
)
6149 char buffer
[L_tmpnam
];
6152 if (PyErr_Warn(PyExc_RuntimeWarning
,
6153 "tmpnam is a potential security risk to your program") < 0)
6157 name
= tmpnam_r(buffer
);
6159 name
= tmpnam(buffer
);
6162 PyErr_SetObject(PyExc_OSError
,
6163 Py_BuildValue("is", 0,
6165 "unexpected NULL from tmpnam_r"
6167 "unexpected NULL from tmpnam"
6172 return PyString_FromString(buffer
);
6177 /* This is used for fpathconf(), pathconf(), confstr() and sysconf().
6178 * It maps strings representing configuration variable names to
6179 * integer values, allowing those functions to be called with the
6180 * magic names instead of polluting the module's namespace with tons of
6181 * rarely-used constants. There are three separate tables that use
6182 * these definitions.
6184 * This code is always included, even if none of the interfaces that
6185 * need it are included. The #if hackery needed to avoid it would be
6186 * sufficiently pervasive that it's not worth the loss of readability.
6194 conv_confname(PyObject
*arg
, int *valuep
, struct constdef
*table
,
6197 if (PyInt_Check(arg
)) {
6198 *valuep
= PyInt_AS_LONG(arg
);
6201 if (PyString_Check(arg
)) {
6202 /* look up the value in the table using a binary search */
6205 size_t hi
= tablesize
;
6207 char *confname
= PyString_AS_STRING(arg
);
6209 mid
= (lo
+ hi
) / 2;
6210 cmp
= strcmp(confname
, table
[mid
].name
);
6216 *valuep
= table
[mid
].value
;
6220 PyErr_SetString(PyExc_ValueError
, "unrecognized configuration name");
6223 PyErr_SetString(PyExc_TypeError
,
6224 "configuration names must be strings or integers");
6229 #if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
6230 static struct constdef posix_constants_pathconf
[] = {
6231 #ifdef _PC_ABI_AIO_XFER_MAX
6232 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX
},
6234 #ifdef _PC_ABI_ASYNC_IO
6235 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO
},
6238 {"PC_ASYNC_IO", _PC_ASYNC_IO
},
6240 #ifdef _PC_CHOWN_RESTRICTED
6241 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED
},
6243 #ifdef _PC_FILESIZEBITS
6244 {"PC_FILESIZEBITS", _PC_FILESIZEBITS
},
6247 {"PC_LAST", _PC_LAST
},
6250 {"PC_LINK_MAX", _PC_LINK_MAX
},
6252 #ifdef _PC_MAX_CANON
6253 {"PC_MAX_CANON", _PC_MAX_CANON
},
6255 #ifdef _PC_MAX_INPUT
6256 {"PC_MAX_INPUT", _PC_MAX_INPUT
},
6259 {"PC_NAME_MAX", _PC_NAME_MAX
},
6262 {"PC_NO_TRUNC", _PC_NO_TRUNC
},
6265 {"PC_PATH_MAX", _PC_PATH_MAX
},
6268 {"PC_PIPE_BUF", _PC_PIPE_BUF
},
6271 {"PC_PRIO_IO", _PC_PRIO_IO
},
6273 #ifdef _PC_SOCK_MAXBUF
6274 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF
},
6277 {"PC_SYNC_IO", _PC_SYNC_IO
},
6280 {"PC_VDISABLE", _PC_VDISABLE
},
6285 conv_path_confname(PyObject
*arg
, int *valuep
)
6287 return conv_confname(arg
, valuep
, posix_constants_pathconf
,
6288 sizeof(posix_constants_pathconf
)
6289 / sizeof(struct constdef
));
6293 #ifdef HAVE_FPATHCONF
6294 PyDoc_STRVAR(posix_fpathconf__doc__
,
6295 "fpathconf(fd, name) -> integer\n\n\
6296 Return the configuration limit name for the file descriptor fd.\n\
6297 If there is no limit, return -1.");
6300 posix_fpathconf(PyObject
*self
, PyObject
*args
)
6302 PyObject
*result
= NULL
;
6305 if (PyArg_ParseTuple(args
, "iO&:fpathconf", &fd
,
6306 conv_path_confname
, &name
)) {
6310 limit
= fpathconf(fd
, name
);
6311 if (limit
== -1 && errno
!= 0)
6314 result
= PyInt_FromLong(limit
);
6321 #ifdef HAVE_PATHCONF
6322 PyDoc_STRVAR(posix_pathconf__doc__
,
6323 "pathconf(path, name) -> integer\n\n\
6324 Return the configuration limit name for the file or directory path.\n\
6325 If there is no limit, return -1.");
6328 posix_pathconf(PyObject
*self
, PyObject
*args
)
6330 PyObject
*result
= NULL
;
6334 if (PyArg_ParseTuple(args
, "sO&:pathconf", &path
,
6335 conv_path_confname
, &name
)) {
6339 limit
= pathconf(path
, name
);
6340 if (limit
== -1 && errno
!= 0) {
6341 if (errno
== EINVAL
)
6342 /* could be a path or name problem */
6345 posix_error_with_filename(path
);
6348 result
= PyInt_FromLong(limit
);
6355 static struct constdef posix_constants_confstr
[] = {
6356 #ifdef _CS_ARCHITECTURE
6357 {"CS_ARCHITECTURE", _CS_ARCHITECTURE
},
6360 {"CS_HOSTNAME", _CS_HOSTNAME
},
6362 #ifdef _CS_HW_PROVIDER
6363 {"CS_HW_PROVIDER", _CS_HW_PROVIDER
},
6365 #ifdef _CS_HW_SERIAL
6366 {"CS_HW_SERIAL", _CS_HW_SERIAL
},
6368 #ifdef _CS_INITTAB_NAME
6369 {"CS_INITTAB_NAME", _CS_INITTAB_NAME
},
6371 #ifdef _CS_LFS64_CFLAGS
6372 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS
},
6374 #ifdef _CS_LFS64_LDFLAGS
6375 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS
},
6377 #ifdef _CS_LFS64_LIBS
6378 {"CS_LFS64_LIBS", _CS_LFS64_LIBS
},
6380 #ifdef _CS_LFS64_LINTFLAGS
6381 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS
},
6383 #ifdef _CS_LFS_CFLAGS
6384 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS
},
6386 #ifdef _CS_LFS_LDFLAGS
6387 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS
},
6390 {"CS_LFS_LIBS", _CS_LFS_LIBS
},
6392 #ifdef _CS_LFS_LINTFLAGS
6393 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS
},
6396 {"CS_MACHINE", _CS_MACHINE
},
6399 {"CS_PATH", _CS_PATH
},
6402 {"CS_RELEASE", _CS_RELEASE
},
6404 #ifdef _CS_SRPC_DOMAIN
6405 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN
},
6408 {"CS_SYSNAME", _CS_SYSNAME
},
6411 {"CS_VERSION", _CS_VERSION
},
6413 #ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
6414 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS
},
6416 #ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
6417 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS
},
6419 #ifdef _CS_XBS5_ILP32_OFF32_LIBS
6420 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS
},
6422 #ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
6423 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS
},
6425 #ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
6426 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS
},
6428 #ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
6429 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS
},
6431 #ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
6432 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS
},
6434 #ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
6435 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
},
6437 #ifdef _CS_XBS5_LP64_OFF64_CFLAGS
6438 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS
},
6440 #ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
6441 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS
},
6443 #ifdef _CS_XBS5_LP64_OFF64_LIBS
6444 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS
},
6446 #ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
6447 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS
},
6449 #ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
6450 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS
},
6452 #ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
6453 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
},
6455 #ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
6456 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS
},
6458 #ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
6459 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
},
6461 #ifdef _MIPS_CS_AVAIL_PROCESSORS
6462 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS
},
6464 #ifdef _MIPS_CS_BASE
6465 {"MIPS_CS_BASE", _MIPS_CS_BASE
},
6467 #ifdef _MIPS_CS_HOSTID
6468 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID
},
6470 #ifdef _MIPS_CS_HW_NAME
6471 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME
},
6473 #ifdef _MIPS_CS_NUM_PROCESSORS
6474 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS
},
6476 #ifdef _MIPS_CS_OSREL_MAJ
6477 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ
},
6479 #ifdef _MIPS_CS_OSREL_MIN
6480 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN
},
6482 #ifdef _MIPS_CS_OSREL_PATCH
6483 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH
},
6485 #ifdef _MIPS_CS_OS_NAME
6486 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME
},
6488 #ifdef _MIPS_CS_OS_PROVIDER
6489 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER
},
6491 #ifdef _MIPS_CS_PROCESSORS
6492 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS
},
6494 #ifdef _MIPS_CS_SERIAL
6495 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL
},
6497 #ifdef _MIPS_CS_VENDOR
6498 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR
},
6503 conv_confstr_confname(PyObject
*arg
, int *valuep
)
6505 return conv_confname(arg
, valuep
, posix_constants_confstr
,
6506 sizeof(posix_constants_confstr
)
6507 / sizeof(struct constdef
));
6510 PyDoc_STRVAR(posix_confstr__doc__
,
6511 "confstr(name) -> string\n\n\
6512 Return a string-valued system configuration variable.");
6515 posix_confstr(PyObject
*self
, PyObject
*args
)
6517 PyObject
*result
= NULL
;
6521 if (PyArg_ParseTuple(args
, "O&:confstr", conv_confstr_confname
, &name
)) {
6522 int len
= confstr(name
, buffer
, sizeof(buffer
));
6529 result
= PyString_FromString("");
6532 if (len
>= sizeof(buffer
)) {
6533 result
= PyString_FromStringAndSize(NULL
, len
);
6535 confstr(name
, PyString_AS_STRING(result
), len
+1);
6538 result
= PyString_FromString(buffer
);
6547 static struct constdef posix_constants_sysconf
[] = {
6548 #ifdef _SC_2_CHAR_TERM
6549 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM
},
6552 {"SC_2_C_BIND", _SC_2_C_BIND
},
6555 {"SC_2_C_DEV", _SC_2_C_DEV
},
6557 #ifdef _SC_2_C_VERSION
6558 {"SC_2_C_VERSION", _SC_2_C_VERSION
},
6560 #ifdef _SC_2_FORT_DEV
6561 {"SC_2_FORT_DEV", _SC_2_FORT_DEV
},
6563 #ifdef _SC_2_FORT_RUN
6564 {"SC_2_FORT_RUN", _SC_2_FORT_RUN
},
6566 #ifdef _SC_2_LOCALEDEF
6567 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF
},
6570 {"SC_2_SW_DEV", _SC_2_SW_DEV
},
6573 {"SC_2_UPE", _SC_2_UPE
},
6575 #ifdef _SC_2_VERSION
6576 {"SC_2_VERSION", _SC_2_VERSION
},
6578 #ifdef _SC_ABI_ASYNCHRONOUS_IO
6579 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO
},
6582 {"SC_ACL", _SC_ACL
},
6584 #ifdef _SC_AIO_LISTIO_MAX
6585 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX
},
6588 {"SC_AIO_MAX", _SC_AIO_MAX
},
6590 #ifdef _SC_AIO_PRIO_DELTA_MAX
6591 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX
},
6594 {"SC_ARG_MAX", _SC_ARG_MAX
},
6596 #ifdef _SC_ASYNCHRONOUS_IO
6597 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO
},
6599 #ifdef _SC_ATEXIT_MAX
6600 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX
},
6603 {"SC_AUDIT", _SC_AUDIT
},
6605 #ifdef _SC_AVPHYS_PAGES
6606 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES
},
6608 #ifdef _SC_BC_BASE_MAX
6609 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX
},
6611 #ifdef _SC_BC_DIM_MAX
6612 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX
},
6614 #ifdef _SC_BC_SCALE_MAX
6615 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX
},
6617 #ifdef _SC_BC_STRING_MAX
6618 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX
},
6621 {"SC_CAP", _SC_CAP
},
6623 #ifdef _SC_CHARCLASS_NAME_MAX
6624 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX
},
6627 {"SC_CHAR_BIT", _SC_CHAR_BIT
},
6630 {"SC_CHAR_MAX", _SC_CHAR_MAX
},
6633 {"SC_CHAR_MIN", _SC_CHAR_MIN
},
6635 #ifdef _SC_CHILD_MAX
6636 {"SC_CHILD_MAX", _SC_CHILD_MAX
},
6639 {"SC_CLK_TCK", _SC_CLK_TCK
},
6641 #ifdef _SC_COHER_BLKSZ
6642 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ
},
6644 #ifdef _SC_COLL_WEIGHTS_MAX
6645 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX
},
6647 #ifdef _SC_DCACHE_ASSOC
6648 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC
},
6650 #ifdef _SC_DCACHE_BLKSZ
6651 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ
},
6653 #ifdef _SC_DCACHE_LINESZ
6654 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ
},
6656 #ifdef _SC_DCACHE_SZ
6657 {"SC_DCACHE_SZ", _SC_DCACHE_SZ
},
6659 #ifdef _SC_DCACHE_TBLKSZ
6660 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ
},
6662 #ifdef _SC_DELAYTIMER_MAX
6663 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX
},
6665 #ifdef _SC_EQUIV_CLASS_MAX
6666 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX
},
6668 #ifdef _SC_EXPR_NEST_MAX
6669 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX
},
6672 {"SC_FSYNC", _SC_FSYNC
},
6674 #ifdef _SC_GETGR_R_SIZE_MAX
6675 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX
},
6677 #ifdef _SC_GETPW_R_SIZE_MAX
6678 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX
},
6680 #ifdef _SC_ICACHE_ASSOC
6681 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC
},
6683 #ifdef _SC_ICACHE_BLKSZ
6684 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ
},
6686 #ifdef _SC_ICACHE_LINESZ
6687 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ
},
6689 #ifdef _SC_ICACHE_SZ
6690 {"SC_ICACHE_SZ", _SC_ICACHE_SZ
},
6693 {"SC_INF", _SC_INF
},
6696 {"SC_INT_MAX", _SC_INT_MAX
},
6699 {"SC_INT_MIN", _SC_INT_MIN
},
6702 {"SC_IOV_MAX", _SC_IOV_MAX
},
6704 #ifdef _SC_IP_SECOPTS
6705 {"SC_IP_SECOPTS", _SC_IP_SECOPTS
},
6707 #ifdef _SC_JOB_CONTROL
6708 {"SC_JOB_CONTROL", _SC_JOB_CONTROL
},
6710 #ifdef _SC_KERN_POINTERS
6711 {"SC_KERN_POINTERS", _SC_KERN_POINTERS
},
6714 {"SC_KERN_SIM", _SC_KERN_SIM
},
6717 {"SC_LINE_MAX", _SC_LINE_MAX
},
6719 #ifdef _SC_LOGIN_NAME_MAX
6720 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX
},
6722 #ifdef _SC_LOGNAME_MAX
6723 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX
},
6726 {"SC_LONG_BIT", _SC_LONG_BIT
},
6729 {"SC_MAC", _SC_MAC
},
6731 #ifdef _SC_MAPPED_FILES
6732 {"SC_MAPPED_FILES", _SC_MAPPED_FILES
},
6735 {"SC_MAXPID", _SC_MAXPID
},
6737 #ifdef _SC_MB_LEN_MAX
6738 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX
},
6741 {"SC_MEMLOCK", _SC_MEMLOCK
},
6743 #ifdef _SC_MEMLOCK_RANGE
6744 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE
},
6746 #ifdef _SC_MEMORY_PROTECTION
6747 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION
},
6749 #ifdef _SC_MESSAGE_PASSING
6750 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING
},
6752 #ifdef _SC_MMAP_FIXED_ALIGNMENT
6753 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT
},
6755 #ifdef _SC_MQ_OPEN_MAX
6756 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX
},
6758 #ifdef _SC_MQ_PRIO_MAX
6759 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX
},
6761 #ifdef _SC_NACLS_MAX
6762 {"SC_NACLS_MAX", _SC_NACLS_MAX
},
6764 #ifdef _SC_NGROUPS_MAX
6765 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX
},
6767 #ifdef _SC_NL_ARGMAX
6768 {"SC_NL_ARGMAX", _SC_NL_ARGMAX
},
6770 #ifdef _SC_NL_LANGMAX
6771 {"SC_NL_LANGMAX", _SC_NL_LANGMAX
},
6773 #ifdef _SC_NL_MSGMAX
6774 {"SC_NL_MSGMAX", _SC_NL_MSGMAX
},
6777 {"SC_NL_NMAX", _SC_NL_NMAX
},
6779 #ifdef _SC_NL_SETMAX
6780 {"SC_NL_SETMAX", _SC_NL_SETMAX
},
6782 #ifdef _SC_NL_TEXTMAX
6783 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX
},
6785 #ifdef _SC_NPROCESSORS_CONF
6786 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF
},
6788 #ifdef _SC_NPROCESSORS_ONLN
6789 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN
},
6791 #ifdef _SC_NPROC_CONF
6792 {"SC_NPROC_CONF", _SC_NPROC_CONF
},
6794 #ifdef _SC_NPROC_ONLN
6795 {"SC_NPROC_ONLN", _SC_NPROC_ONLN
},
6798 {"SC_NZERO", _SC_NZERO
},
6801 {"SC_OPEN_MAX", _SC_OPEN_MAX
},
6804 {"SC_PAGESIZE", _SC_PAGESIZE
},
6806 #ifdef _SC_PAGE_SIZE
6807 {"SC_PAGE_SIZE", _SC_PAGE_SIZE
},
6810 {"SC_PASS_MAX", _SC_PASS_MAX
},
6812 #ifdef _SC_PHYS_PAGES
6813 {"SC_PHYS_PAGES", _SC_PHYS_PAGES
},
6816 {"SC_PII", _SC_PII
},
6818 #ifdef _SC_PII_INTERNET
6819 {"SC_PII_INTERNET", _SC_PII_INTERNET
},
6821 #ifdef _SC_PII_INTERNET_DGRAM
6822 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM
},
6824 #ifdef _SC_PII_INTERNET_STREAM
6825 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM
},
6828 {"SC_PII_OSI", _SC_PII_OSI
},
6830 #ifdef _SC_PII_OSI_CLTS
6831 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS
},
6833 #ifdef _SC_PII_OSI_COTS
6834 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS
},
6836 #ifdef _SC_PII_OSI_M
6837 {"SC_PII_OSI_M", _SC_PII_OSI_M
},
6839 #ifdef _SC_PII_SOCKET
6840 {"SC_PII_SOCKET", _SC_PII_SOCKET
},
6843 {"SC_PII_XTI", _SC_PII_XTI
},
6846 {"SC_POLL", _SC_POLL
},
6848 #ifdef _SC_PRIORITIZED_IO
6849 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO
},
6851 #ifdef _SC_PRIORITY_SCHEDULING
6852 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING
},
6854 #ifdef _SC_REALTIME_SIGNALS
6855 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS
},
6857 #ifdef _SC_RE_DUP_MAX
6858 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX
},
6860 #ifdef _SC_RTSIG_MAX
6861 {"SC_RTSIG_MAX", _SC_RTSIG_MAX
},
6863 #ifdef _SC_SAVED_IDS
6864 {"SC_SAVED_IDS", _SC_SAVED_IDS
},
6866 #ifdef _SC_SCHAR_MAX
6867 {"SC_SCHAR_MAX", _SC_SCHAR_MAX
},
6869 #ifdef _SC_SCHAR_MIN
6870 {"SC_SCHAR_MIN", _SC_SCHAR_MIN
},
6873 {"SC_SELECT", _SC_SELECT
},
6875 #ifdef _SC_SEMAPHORES
6876 {"SC_SEMAPHORES", _SC_SEMAPHORES
},
6878 #ifdef _SC_SEM_NSEMS_MAX
6879 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX
},
6881 #ifdef _SC_SEM_VALUE_MAX
6882 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX
},
6884 #ifdef _SC_SHARED_MEMORY_OBJECTS
6885 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS
},
6888 {"SC_SHRT_MAX", _SC_SHRT_MAX
},
6891 {"SC_SHRT_MIN", _SC_SHRT_MIN
},
6893 #ifdef _SC_SIGQUEUE_MAX
6894 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX
},
6896 #ifdef _SC_SIGRT_MAX
6897 {"SC_SIGRT_MAX", _SC_SIGRT_MAX
},
6899 #ifdef _SC_SIGRT_MIN
6900 {"SC_SIGRT_MIN", _SC_SIGRT_MIN
},
6902 #ifdef _SC_SOFTPOWER
6903 {"SC_SOFTPOWER", _SC_SOFTPOWER
},
6905 #ifdef _SC_SPLIT_CACHE
6906 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE
},
6908 #ifdef _SC_SSIZE_MAX
6909 {"SC_SSIZE_MAX", _SC_SSIZE_MAX
},
6911 #ifdef _SC_STACK_PROT
6912 {"SC_STACK_PROT", _SC_STACK_PROT
},
6914 #ifdef _SC_STREAM_MAX
6915 {"SC_STREAM_MAX", _SC_STREAM_MAX
},
6917 #ifdef _SC_SYNCHRONIZED_IO
6918 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO
},
6921 {"SC_THREADS", _SC_THREADS
},
6923 #ifdef _SC_THREAD_ATTR_STACKADDR
6924 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR
},
6926 #ifdef _SC_THREAD_ATTR_STACKSIZE
6927 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE
},
6929 #ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
6930 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS
},
6932 #ifdef _SC_THREAD_KEYS_MAX
6933 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX
},
6935 #ifdef _SC_THREAD_PRIORITY_SCHEDULING
6936 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING
},
6938 #ifdef _SC_THREAD_PRIO_INHERIT
6939 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT
},
6941 #ifdef _SC_THREAD_PRIO_PROTECT
6942 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT
},
6944 #ifdef _SC_THREAD_PROCESS_SHARED
6945 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED
},
6947 #ifdef _SC_THREAD_SAFE_FUNCTIONS
6948 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS
},
6950 #ifdef _SC_THREAD_STACK_MIN
6951 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN
},
6953 #ifdef _SC_THREAD_THREADS_MAX
6954 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX
},
6957 {"SC_TIMERS", _SC_TIMERS
},
6959 #ifdef _SC_TIMER_MAX
6960 {"SC_TIMER_MAX", _SC_TIMER_MAX
},
6962 #ifdef _SC_TTY_NAME_MAX
6963 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX
},
6965 #ifdef _SC_TZNAME_MAX
6966 {"SC_TZNAME_MAX", _SC_TZNAME_MAX
},
6968 #ifdef _SC_T_IOV_MAX
6969 {"SC_T_IOV_MAX", _SC_T_IOV_MAX
},
6971 #ifdef _SC_UCHAR_MAX
6972 {"SC_UCHAR_MAX", _SC_UCHAR_MAX
},
6975 {"SC_UINT_MAX", _SC_UINT_MAX
},
6977 #ifdef _SC_UIO_MAXIOV
6978 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV
},
6980 #ifdef _SC_ULONG_MAX
6981 {"SC_ULONG_MAX", _SC_ULONG_MAX
},
6983 #ifdef _SC_USHRT_MAX
6984 {"SC_USHRT_MAX", _SC_USHRT_MAX
},
6987 {"SC_VERSION", _SC_VERSION
},
6990 {"SC_WORD_BIT", _SC_WORD_BIT
},
6992 #ifdef _SC_XBS5_ILP32_OFF32
6993 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32
},
6995 #ifdef _SC_XBS5_ILP32_OFFBIG
6996 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG
},
6998 #ifdef _SC_XBS5_LP64_OFF64
6999 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64
},
7001 #ifdef _SC_XBS5_LPBIG_OFFBIG
7002 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG
},
7004 #ifdef _SC_XOPEN_CRYPT
7005 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT
},
7007 #ifdef _SC_XOPEN_ENH_I18N
7008 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N
},
7010 #ifdef _SC_XOPEN_LEGACY
7011 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY
},
7013 #ifdef _SC_XOPEN_REALTIME
7014 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME
},
7016 #ifdef _SC_XOPEN_REALTIME_THREADS
7017 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS
},
7019 #ifdef _SC_XOPEN_SHM
7020 {"SC_XOPEN_SHM", _SC_XOPEN_SHM
},
7022 #ifdef _SC_XOPEN_UNIX
7023 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX
},
7025 #ifdef _SC_XOPEN_VERSION
7026 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION
},
7028 #ifdef _SC_XOPEN_XCU_VERSION
7029 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION
},
7031 #ifdef _SC_XOPEN_XPG2
7032 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2
},
7034 #ifdef _SC_XOPEN_XPG3
7035 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3
},
7037 #ifdef _SC_XOPEN_XPG4
7038 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4
},
7043 conv_sysconf_confname(PyObject
*arg
, int *valuep
)
7045 return conv_confname(arg
, valuep
, posix_constants_sysconf
,
7046 sizeof(posix_constants_sysconf
)
7047 / sizeof(struct constdef
));
7050 PyDoc_STRVAR(posix_sysconf__doc__
,
7051 "sysconf(name) -> integer\n\n\
7052 Return an integer-valued system configuration variable.");
7055 posix_sysconf(PyObject
*self
, PyObject
*args
)
7057 PyObject
*result
= NULL
;
7060 if (PyArg_ParseTuple(args
, "O&:sysconf", conv_sysconf_confname
, &name
)) {
7064 value
= sysconf(name
);
7065 if (value
== -1 && errno
!= 0)
7068 result
= PyInt_FromLong(value
);
7075 /* This code is used to ensure that the tables of configuration value names
7076 * are in sorted order as required by conv_confname(), and also to build the
7077 * the exported dictionaries that are used to publish information about the
7078 * names available on the host platform.
7080 * Sorting the table at runtime ensures that the table is properly ordered
7081 * when used, even for platforms we're not able to test on. It also makes
7082 * it easier to add additional entries to the tables.
7086 cmp_constdefs(const void *v1
, const void *v2
)
7088 const struct constdef
*c1
=
7089 (const struct constdef
*) v1
;
7090 const struct constdef
*c2
=
7091 (const struct constdef
*) v2
;
7093 return strcmp(c1
->name
, c2
->name
);
7097 setup_confname_table(struct constdef
*table
, size_t tablesize
,
7098 char *tablename
, PyObject
*module
)
7103 qsort(table
, tablesize
, sizeof(struct constdef
), cmp_constdefs
);
7108 for (i
=0; i
< tablesize
; ++i
) {
7109 PyObject
*o
= PyInt_FromLong(table
[i
].value
);
7110 if (o
== NULL
|| PyDict_SetItemString(d
, table
[i
].name
, o
) == -1) {
7117 return PyModule_AddObject(module
, tablename
, d
);
7120 /* Return -1 on failure, 0 on success. */
7122 setup_confname_tables(PyObject
*module
)
7124 #if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
7125 if (setup_confname_table(posix_constants_pathconf
,
7126 sizeof(posix_constants_pathconf
)
7127 / sizeof(struct constdef
),
7128 "pathconf_names", module
))
7132 if (setup_confname_table(posix_constants_confstr
,
7133 sizeof(posix_constants_confstr
)
7134 / sizeof(struct constdef
),
7135 "confstr_names", module
))
7139 if (setup_confname_table(posix_constants_sysconf
,
7140 sizeof(posix_constants_sysconf
)
7141 / sizeof(struct constdef
),
7142 "sysconf_names", module
))
7149 PyDoc_STRVAR(posix_abort__doc__
,
7150 "abort() -> does not return!\n\n\
7151 Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
7152 in the hardest way possible on the hosting operating system.");
7155 posix_abort(PyObject
*self
, PyObject
*noargs
)
7159 Py_FatalError("abort() called from Python code didn't abort!");
7164 PyDoc_STRVAR(win32_startfile__doc__
,
7165 "startfile(filepath) - Start a file with its associated application.\n\
7167 This acts like double-clicking the file in Explorer, or giving the file\n\
7168 name as an argument to the DOS \"start\" command: the file is opened\n\
7169 with whatever application (if any) its extension is associated.\n\
7171 startfile returns as soon as the associated application is launched.\n\
7172 There is no option to wait for the application to close, and no way\n\
7173 to retrieve the application's exit status.\n\
7175 The filepath is relative to the current directory. If you want to use\n\
7176 an absolute path, make sure the first character is not a slash (\"/\");\n\
7177 the underlying Win32 ShellExecute function doesn't work if it is.");
7180 win32_startfile(PyObject
*self
, PyObject
*args
)
7184 if (!PyArg_ParseTuple(args
, "s:startfile", &filepath
))
7186 Py_BEGIN_ALLOW_THREADS
7187 rc
= ShellExecute((HWND
)0, NULL
, filepath
, NULL
, NULL
, SW_SHOWNORMAL
);
7188 Py_END_ALLOW_THREADS
7189 if (rc
<= (HINSTANCE
)32)
7190 return win32_error("startfile", filepath
);
7196 #ifdef HAVE_GETLOADAVG
7197 PyDoc_STRVAR(posix_getloadavg__doc__
,
7198 "getloadavg() -> (float, float, float)\n\n\
7199 Return the number of processes in the system run queue averaged over\n\
7200 the last 1, 5, and 15 minutes or raises OSError if the load average\n\
7204 posix_getloadavg(PyObject
*self
, PyObject
*noargs
)
7207 if (getloadavg(loadavg
, 3)!=3) {
7208 PyErr_SetString(PyExc_OSError
, "Load averages are unobtainable");
7211 return Py_BuildValue("ddd", loadavg
[0], loadavg
[1], loadavg
[2]);
7217 PyDoc_STRVAR(win32_urandom__doc__
,
7218 "urandom(n) -> str\n\n\
7219 Return a string of n random bytes suitable for cryptographic use.");
7221 typedef BOOL (WINAPI
*CRYPTACQUIRECONTEXTA
)(HCRYPTPROV
*phProv
,\
7222 LPCSTR pszContainer
, LPCSTR pszProvider
, DWORD dwProvType
,\
7224 typedef BOOL (WINAPI
*CRYPTGENRANDOM
)(HCRYPTPROV hProv
, DWORD dwLen
,\
7227 static CRYPTGENRANDOM pCryptGenRandom
= NULL
;
7228 static HCRYPTPROV hCryptProv
= 0;
7231 win32_urandom(PyObject
*self
, PyObject
*args
)
7236 /* Read arguments */
7237 if (! PyArg_ParseTuple(args
, "i:urandom", &howMany
))
7240 return PyErr_Format(PyExc_ValueError
,
7241 "negative argument not allowed");
7243 if (hCryptProv
== 0) {
7244 HINSTANCE hAdvAPI32
= NULL
;
7245 CRYPTACQUIRECONTEXTA pCryptAcquireContext
= NULL
;
7247 /* Obtain handle to the DLL containing CryptoAPI
7248 This should not fail */
7249 hAdvAPI32
= GetModuleHandle("advapi32.dll");
7250 if(hAdvAPI32
== NULL
)
7251 return win32_error("GetModuleHandle", NULL
);
7253 /* Obtain pointers to the CryptoAPI functions
7254 This will fail on some early versions of Win95 */
7255 pCryptAcquireContext
= (CRYPTACQUIRECONTEXTA
)GetProcAddress(
7257 "CryptAcquireContextA");
7258 if (pCryptAcquireContext
== NULL
)
7259 return PyErr_Format(PyExc_NotImplementedError
,
7260 "CryptAcquireContextA not found");
7262 pCryptGenRandom
= (CRYPTGENRANDOM
)GetProcAddress(
7263 hAdvAPI32
, "CryptGenRandom");
7264 if (pCryptAcquireContext
== NULL
)
7265 return PyErr_Format(PyExc_NotImplementedError
,
7266 "CryptGenRandom not found");
7268 /* Acquire context */
7269 if (! pCryptAcquireContext(&hCryptProv
, NULL
, NULL
,
7270 PROV_RSA_FULL
, CRYPT_VERIFYCONTEXT
))
7271 return win32_error("CryptAcquireContext", NULL
);
7274 /* Allocate bytes */
7275 result
= PyString_FromStringAndSize(NULL
, howMany
);
7276 if (result
!= NULL
) {
7277 /* Get random data */
7278 if (! pCryptGenRandom(hCryptProv
, howMany
, (unsigned char*)
7279 PyString_AS_STRING(result
))) {
7281 return win32_error("CryptGenRandom", NULL
);
7288 static PyMethodDef posix_methods
[] = {
7289 {"access", posix_access
, METH_VARARGS
, posix_access__doc__
},
7291 {"ttyname", posix_ttyname
, METH_VARARGS
, posix_ttyname__doc__
},
7293 {"chdir", posix_chdir
, METH_VARARGS
, posix_chdir__doc__
},
7294 {"chmod", posix_chmod
, METH_VARARGS
, posix_chmod__doc__
},
7296 {"chown", posix_chown
, METH_VARARGS
, posix_chown__doc__
},
7297 #endif /* HAVE_CHOWN */
7299 {"lchown", posix_lchown
, METH_VARARGS
, posix_lchown__doc__
},
7300 #endif /* HAVE_LCHOWN */
7302 {"chroot", posix_chroot
, METH_VARARGS
, posix_chroot__doc__
},
7305 {"ctermid", posix_ctermid
, METH_NOARGS
, posix_ctermid__doc__
},
7308 {"getcwd", posix_getcwd
, METH_NOARGS
, posix_getcwd__doc__
},
7309 #ifdef Py_USING_UNICODE
7310 {"getcwdu", posix_getcwdu
, METH_NOARGS
, posix_getcwdu__doc__
},
7314 {"link", posix_link
, METH_VARARGS
, posix_link__doc__
},
7315 #endif /* HAVE_LINK */
7316 {"listdir", posix_listdir
, METH_VARARGS
, posix_listdir__doc__
},
7317 {"lstat", posix_lstat
, METH_VARARGS
, posix_lstat__doc__
},
7318 {"mkdir", posix_mkdir
, METH_VARARGS
, posix_mkdir__doc__
},
7320 {"nice", posix_nice
, METH_VARARGS
, posix_nice__doc__
},
7321 #endif /* HAVE_NICE */
7322 #ifdef HAVE_READLINK
7323 {"readlink", posix_readlink
, METH_VARARGS
, posix_readlink__doc__
},
7324 #endif /* HAVE_READLINK */
7325 {"rename", posix_rename
, METH_VARARGS
, posix_rename__doc__
},
7326 {"rmdir", posix_rmdir
, METH_VARARGS
, posix_rmdir__doc__
},
7327 {"stat", posix_stat
, METH_VARARGS
, posix_stat__doc__
},
7328 {"stat_float_times", stat_float_times
, METH_VARARGS
, stat_float_times__doc__
},
7330 {"symlink", posix_symlink
, METH_VARARGS
, posix_symlink__doc__
},
7331 #endif /* HAVE_SYMLINK */
7333 {"system", posix_system
, METH_VARARGS
, posix_system__doc__
},
7335 {"umask", posix_umask
, METH_VARARGS
, posix_umask__doc__
},
7337 {"uname", posix_uname
, METH_NOARGS
, posix_uname__doc__
},
7338 #endif /* HAVE_UNAME */
7339 {"unlink", posix_unlink
, METH_VARARGS
, posix_unlink__doc__
},
7340 {"remove", posix_unlink
, METH_VARARGS
, posix_remove__doc__
},
7341 {"utime", posix_utime
, METH_VARARGS
, posix_utime__doc__
},
7343 {"times", posix_times
, METH_NOARGS
, posix_times__doc__
},
7344 #endif /* HAVE_TIMES */
7345 {"_exit", posix__exit
, METH_VARARGS
, posix__exit__doc__
},
7347 {"execv", posix_execv
, METH_VARARGS
, posix_execv__doc__
},
7348 {"execve", posix_execve
, METH_VARARGS
, posix_execve__doc__
},
7349 #endif /* HAVE_EXECV */
7351 {"spawnv", posix_spawnv
, METH_VARARGS
, posix_spawnv__doc__
},
7352 {"spawnve", posix_spawnve
, METH_VARARGS
, posix_spawnve__doc__
},
7353 #if defined(PYOS_OS2)
7354 {"spawnvp", posix_spawnvp
, METH_VARARGS
, posix_spawnvp__doc__
},
7355 {"spawnvpe", posix_spawnvpe
, METH_VARARGS
, posix_spawnvpe__doc__
},
7356 #endif /* PYOS_OS2 */
7357 #endif /* HAVE_SPAWNV */
7359 {"fork1", posix_fork1
, METH_NOARGS
, posix_fork1__doc__
},
7360 #endif /* HAVE_FORK1 */
7362 {"fork", posix_fork
, METH_NOARGS
, posix_fork__doc__
},
7363 #endif /* HAVE_FORK */
7364 #if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
7365 {"openpty", posix_openpty
, METH_NOARGS
, posix_openpty__doc__
},
7366 #endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
7368 {"forkpty", posix_forkpty
, METH_NOARGS
, posix_forkpty__doc__
},
7369 #endif /* HAVE_FORKPTY */
7371 {"getegid", posix_getegid
, METH_NOARGS
, posix_getegid__doc__
},
7372 #endif /* HAVE_GETEGID */
7374 {"geteuid", posix_geteuid
, METH_NOARGS
, posix_geteuid__doc__
},
7375 #endif /* HAVE_GETEUID */
7377 {"getgid", posix_getgid
, METH_NOARGS
, posix_getgid__doc__
},
7378 #endif /* HAVE_GETGID */
7379 #ifdef HAVE_GETGROUPS
7380 {"getgroups", posix_getgroups
, METH_NOARGS
, posix_getgroups__doc__
},
7382 {"getpid", posix_getpid
, METH_NOARGS
, posix_getpid__doc__
},
7384 {"getpgrp", posix_getpgrp
, METH_NOARGS
, posix_getpgrp__doc__
},
7385 #endif /* HAVE_GETPGRP */
7387 {"getppid", posix_getppid
, METH_NOARGS
, posix_getppid__doc__
},
7388 #endif /* HAVE_GETPPID */
7390 {"getuid", posix_getuid
, METH_NOARGS
, posix_getuid__doc__
},
7391 #endif /* HAVE_GETUID */
7392 #ifdef HAVE_GETLOGIN
7393 {"getlogin", posix_getlogin
, METH_NOARGS
, posix_getlogin__doc__
},
7396 {"kill", posix_kill
, METH_VARARGS
, posix_kill__doc__
},
7397 #endif /* HAVE_KILL */
7399 {"killpg", posix_killpg
, METH_VARARGS
, posix_killpg__doc__
},
7400 #endif /* HAVE_KILLPG */
7402 {"plock", posix_plock
, METH_VARARGS
, posix_plock__doc__
},
7403 #endif /* HAVE_PLOCK */
7405 {"popen", posix_popen
, METH_VARARGS
, posix_popen__doc__
},
7407 {"popen2", win32_popen2
, METH_VARARGS
},
7408 {"popen3", win32_popen3
, METH_VARARGS
},
7409 {"popen4", win32_popen4
, METH_VARARGS
},
7410 {"startfile", win32_startfile
, METH_VARARGS
, win32_startfile__doc__
},
7412 #if defined(PYOS_OS2) && defined(PYCC_GCC)
7413 {"popen2", os2emx_popen2
, METH_VARARGS
},
7414 {"popen3", os2emx_popen3
, METH_VARARGS
},
7415 {"popen4", os2emx_popen4
, METH_VARARGS
},
7418 #endif /* HAVE_POPEN */
7420 {"setuid", posix_setuid
, METH_VARARGS
, posix_setuid__doc__
},
7421 #endif /* HAVE_SETUID */
7423 {"seteuid", posix_seteuid
, METH_VARARGS
, posix_seteuid__doc__
},
7424 #endif /* HAVE_SETEUID */
7426 {"setegid", posix_setegid
, METH_VARARGS
, posix_setegid__doc__
},
7427 #endif /* HAVE_SETEGID */
7428 #ifdef HAVE_SETREUID
7429 {"setreuid", posix_setreuid
, METH_VARARGS
, posix_setreuid__doc__
},
7430 #endif /* HAVE_SETREUID */
7431 #ifdef HAVE_SETREGID
7432 {"setregid", posix_setregid
, METH_VARARGS
, posix_setregid__doc__
},
7433 #endif /* HAVE_SETREGID */
7435 {"setgid", posix_setgid
, METH_VARARGS
, posix_setgid__doc__
},
7436 #endif /* HAVE_SETGID */
7437 #ifdef HAVE_SETGROUPS
7438 {"setgroups", posix_setgroups
, METH_VARARGS
, posix_setgroups__doc__
},
7439 #endif /* HAVE_SETGROUPS */
7441 {"getpgid", posix_getpgid
, METH_VARARGS
, posix_getpgid__doc__
},
7442 #endif /* HAVE_GETPGID */
7444 {"setpgrp", posix_setpgrp
, METH_NOARGS
, posix_setpgrp__doc__
},
7445 #endif /* HAVE_SETPGRP */
7447 {"wait", posix_wait
, METH_NOARGS
, posix_wait__doc__
},
7448 #endif /* HAVE_WAIT */
7449 #if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
7450 {"waitpid", posix_waitpid
, METH_VARARGS
, posix_waitpid__doc__
},
7451 #endif /* HAVE_WAITPID */
7453 {"getsid", posix_getsid
, METH_VARARGS
, posix_getsid__doc__
},
7454 #endif /* HAVE_GETSID */
7456 {"setsid", posix_setsid
, METH_NOARGS
, posix_setsid__doc__
},
7457 #endif /* HAVE_SETSID */
7459 {"setpgid", posix_setpgid
, METH_VARARGS
, posix_setpgid__doc__
},
7460 #endif /* HAVE_SETPGID */
7461 #ifdef HAVE_TCGETPGRP
7462 {"tcgetpgrp", posix_tcgetpgrp
, METH_VARARGS
, posix_tcgetpgrp__doc__
},
7463 #endif /* HAVE_TCGETPGRP */
7464 #ifdef HAVE_TCSETPGRP
7465 {"tcsetpgrp", posix_tcsetpgrp
, METH_VARARGS
, posix_tcsetpgrp__doc__
},
7466 #endif /* HAVE_TCSETPGRP */
7467 {"open", posix_open
, METH_VARARGS
, posix_open__doc__
},
7468 {"close", posix_close
, METH_VARARGS
, posix_close__doc__
},
7469 {"dup", posix_dup
, METH_VARARGS
, posix_dup__doc__
},
7470 {"dup2", posix_dup2
, METH_VARARGS
, posix_dup2__doc__
},
7471 {"lseek", posix_lseek
, METH_VARARGS
, posix_lseek__doc__
},
7472 {"read", posix_read
, METH_VARARGS
, posix_read__doc__
},
7473 {"write", posix_write
, METH_VARARGS
, posix_write__doc__
},
7474 {"fstat", posix_fstat
, METH_VARARGS
, posix_fstat__doc__
},
7475 {"fdopen", posix_fdopen
, METH_VARARGS
, posix_fdopen__doc__
},
7476 {"isatty", posix_isatty
, METH_VARARGS
, posix_isatty__doc__
},
7478 {"pipe", posix_pipe
, METH_NOARGS
, posix_pipe__doc__
},
7481 {"mkfifo", posix_mkfifo
, METH_VARARGS
, posix_mkfifo__doc__
},
7483 #if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
7484 {"mknod", posix_mknod
, METH_VARARGS
, posix_mknod__doc__
},
7486 #ifdef HAVE_DEVICE_MACROS
7487 {"major", posix_major
, METH_VARARGS
, posix_major__doc__
},
7488 {"minor", posix_minor
, METH_VARARGS
, posix_minor__doc__
},
7489 {"makedev", posix_makedev
, METH_VARARGS
, posix_makedev__doc__
},
7491 #ifdef HAVE_FTRUNCATE
7492 {"ftruncate", posix_ftruncate
, METH_VARARGS
, posix_ftruncate__doc__
},
7495 {"putenv", posix_putenv
, METH_VARARGS
, posix_putenv__doc__
},
7497 #ifdef HAVE_UNSETENV
7498 {"unsetenv", posix_unsetenv
, METH_VARARGS
, posix_unsetenv__doc__
},
7500 #ifdef HAVE_STRERROR
7501 {"strerror", posix_strerror
, METH_VARARGS
, posix_strerror__doc__
},
7504 {"fchdir", posix_fchdir
, METH_O
, posix_fchdir__doc__
},
7507 {"fsync", posix_fsync
, METH_O
, posix_fsync__doc__
},
7509 #ifdef HAVE_FDATASYNC
7510 {"fdatasync", posix_fdatasync
, METH_O
, posix_fdatasync__doc__
},
7512 #ifdef HAVE_SYS_WAIT_H
7514 {"WCOREDUMP", posix_WCOREDUMP
, METH_VARARGS
, posix_WCOREDUMP__doc__
},
7515 #endif /* WCOREDUMP */
7517 {"WIFCONTINUED",posix_WIFCONTINUED
, METH_VARARGS
, posix_WIFCONTINUED__doc__
},
7518 #endif /* WIFCONTINUED */
7520 {"WIFSTOPPED", posix_WIFSTOPPED
, METH_VARARGS
, posix_WIFSTOPPED__doc__
},
7521 #endif /* WIFSTOPPED */
7523 {"WIFSIGNALED", posix_WIFSIGNALED
, METH_VARARGS
, posix_WIFSIGNALED__doc__
},
7524 #endif /* WIFSIGNALED */
7526 {"WIFEXITED", posix_WIFEXITED
, METH_VARARGS
, posix_WIFEXITED__doc__
},
7527 #endif /* WIFEXITED */
7529 {"WEXITSTATUS", posix_WEXITSTATUS
, METH_VARARGS
, posix_WEXITSTATUS__doc__
},
7530 #endif /* WEXITSTATUS */
7532 {"WTERMSIG", posix_WTERMSIG
, METH_VARARGS
, posix_WTERMSIG__doc__
},
7533 #endif /* WTERMSIG */
7535 {"WSTOPSIG", posix_WSTOPSIG
, METH_VARARGS
, posix_WSTOPSIG__doc__
},
7536 #endif /* WSTOPSIG */
7537 #endif /* HAVE_SYS_WAIT_H */
7538 #ifdef HAVE_FSTATVFS
7539 {"fstatvfs", posix_fstatvfs
, METH_VARARGS
, posix_fstatvfs__doc__
},
7542 {"statvfs", posix_statvfs
, METH_VARARGS
, posix_statvfs__doc__
},
7545 {"tmpfile", posix_tmpfile
, METH_NOARGS
, posix_tmpfile__doc__
},
7548 {"tempnam", posix_tempnam
, METH_VARARGS
, posix_tempnam__doc__
},
7551 {"tmpnam", posix_tmpnam
, METH_NOARGS
, posix_tmpnam__doc__
},
7554 {"confstr", posix_confstr
, METH_VARARGS
, posix_confstr__doc__
},
7557 {"sysconf", posix_sysconf
, METH_VARARGS
, posix_sysconf__doc__
},
7559 #ifdef HAVE_FPATHCONF
7560 {"fpathconf", posix_fpathconf
, METH_VARARGS
, posix_fpathconf__doc__
},
7562 #ifdef HAVE_PATHCONF
7563 {"pathconf", posix_pathconf
, METH_VARARGS
, posix_pathconf__doc__
},
7565 {"abort", posix_abort
, METH_NOARGS
, posix_abort__doc__
},
7567 {"_getfullpathname", posix__getfullpathname
, METH_VARARGS
, NULL
},
7569 #ifdef HAVE_GETLOADAVG
7570 {"getloadavg", posix_getloadavg
, METH_NOARGS
, posix_getloadavg__doc__
},
7573 {"urandom", win32_urandom
, METH_VARARGS
, win32_urandom__doc__
},
7575 {NULL
, NULL
} /* Sentinel */
7580 ins(PyObject
*module
, char *symbol
, long value
)
7582 return PyModule_AddIntConstant(module
, symbol
, value
);
7585 #if defined(PYOS_OS2)
7586 /* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
7587 static int insertvalues(PyObject
*module
)
7590 ULONG values
[QSV_MAX
+1];
7594 Py_BEGIN_ALLOW_THREADS
7595 rc
= DosQuerySysInfo(1L, QSV_MAX
, &values
[1], sizeof(ULONG
) * QSV_MAX
);
7596 Py_END_ALLOW_THREADS
7598 if (rc
!= NO_ERROR
) {
7603 if (ins(module
, "meminstalled", values
[QSV_TOTPHYSMEM
])) return -1;
7604 if (ins(module
, "memkernel", values
[QSV_TOTRESMEM
])) return -1;
7605 if (ins(module
, "memvirtual", values
[QSV_TOTAVAILMEM
])) return -1;
7606 if (ins(module
, "maxpathlen", values
[QSV_MAX_PATH_LENGTH
])) return -1;
7607 if (ins(module
, "maxnamelen", values
[QSV_MAX_COMP_LENGTH
])) return -1;
7608 if (ins(module
, "revision", values
[QSV_VERSION_REVISION
])) return -1;
7609 if (ins(module
, "timeslice", values
[QSV_MIN_SLICE
])) return -1;
7611 switch (values
[QSV_VERSION_MINOR
]) {
7612 case 0: ver
= "2.00"; break;
7613 case 10: ver
= "2.10"; break;
7614 case 11: ver
= "2.11"; break;
7615 case 30: ver
= "3.00"; break;
7616 case 40: ver
= "4.00"; break;
7617 case 50: ver
= "5.00"; break;
7619 PyOS_snprintf(tmp
, sizeof(tmp
),
7620 "%d-%d", values
[QSV_VERSION_MAJOR
],
7621 values
[QSV_VERSION_MINOR
]);
7625 /* Add Indicator of the Version of the Operating System */
7626 if (PyModule_AddStringConstant(module
, "version", tmp
) < 0)
7629 /* Add Indicator of Which Drive was Used to Boot the System */
7630 tmp
[0] = 'A' + values
[QSV_BOOT_DRIVE
] - 1;
7634 return PyModule_AddStringConstant(module
, "bootdrive", tmp
);
7639 all_ins(PyObject
*d
)
7642 if (ins(d
, "F_OK", (long)F_OK
)) return -1;
7645 if (ins(d
, "R_OK", (long)R_OK
)) return -1;
7648 if (ins(d
, "W_OK", (long)W_OK
)) return -1;
7651 if (ins(d
, "X_OK", (long)X_OK
)) return -1;
7654 if (ins(d
, "NGROUPS_MAX", (long)NGROUPS_MAX
)) return -1;
7657 if (ins(d
, "TMP_MAX", (long)TMP_MAX
)) return -1;
7660 if (ins(d
, "WCONTINUED", (long)WCONTINUED
)) return -1;
7663 if (ins(d
, "WNOHANG", (long)WNOHANG
)) return -1;
7666 if (ins(d
, "WUNTRACED", (long)WUNTRACED
)) return -1;
7669 if (ins(d
, "O_RDONLY", (long)O_RDONLY
)) return -1;
7672 if (ins(d
, "O_WRONLY", (long)O_WRONLY
)) return -1;
7675 if (ins(d
, "O_RDWR", (long)O_RDWR
)) return -1;
7678 if (ins(d
, "O_NDELAY", (long)O_NDELAY
)) return -1;
7681 if (ins(d
, "O_NONBLOCK", (long)O_NONBLOCK
)) return -1;
7684 if (ins(d
, "O_APPEND", (long)O_APPEND
)) return -1;
7687 if (ins(d
, "O_DSYNC", (long)O_DSYNC
)) return -1;
7690 if (ins(d
, "O_RSYNC", (long)O_RSYNC
)) return -1;
7693 if (ins(d
, "O_SYNC", (long)O_SYNC
)) return -1;
7696 if (ins(d
, "O_NOCTTY", (long)O_NOCTTY
)) return -1;
7699 if (ins(d
, "O_CREAT", (long)O_CREAT
)) return -1;
7702 if (ins(d
, "O_EXCL", (long)O_EXCL
)) return -1;
7705 if (ins(d
, "O_TRUNC", (long)O_TRUNC
)) return -1;
7708 if (ins(d
, "O_BINARY", (long)O_BINARY
)) return -1;
7711 if (ins(d
, "O_TEXT", (long)O_TEXT
)) return -1;
7714 if (ins(d
, "O_LARGEFILE", (long)O_LARGEFILE
)) return -1;
7719 /* Don't inherit in child processes. */
7720 if (ins(d
, "O_NOINHERIT", (long)O_NOINHERIT
)) return -1;
7722 #ifdef _O_SHORT_LIVED
7723 /* Optimize for short life (keep in memory). */
7724 /* MS forgot to define this one with a non-underscore form too. */
7725 if (ins(d
, "O_SHORT_LIVED", (long)_O_SHORT_LIVED
)) return -1;
7728 /* Automatically delete when last handle is closed. */
7729 if (ins(d
, "O_TEMPORARY", (long)O_TEMPORARY
)) return -1;
7732 /* Optimize for random access. */
7733 if (ins(d
, "O_RANDOM", (long)O_RANDOM
)) return -1;
7736 /* Optimize for sequential access. */
7737 if (ins(d
, "O_SEQUENTIAL", (long)O_SEQUENTIAL
)) return -1;
7740 /* GNU extensions. */
7742 /* Direct disk access. */
7743 if (ins(d
, "O_DIRECT", (long)O_DIRECT
)) return -1;
7746 /* Must be a directory. */
7747 if (ins(d
, "O_DIRECTORY", (long)O_DIRECTORY
)) return -1;
7750 /* Do not follow links. */
7751 if (ins(d
, "O_NOFOLLOW", (long)O_NOFOLLOW
)) return -1;
7754 /* These come from sysexits.h */
7756 if (ins(d
, "EX_OK", (long)EX_OK
)) return -1;
7759 if (ins(d
, "EX_USAGE", (long)EX_USAGE
)) return -1;
7760 #endif /* EX_USAGE */
7762 if (ins(d
, "EX_DATAERR", (long)EX_DATAERR
)) return -1;
7763 #endif /* EX_DATAERR */
7765 if (ins(d
, "EX_NOINPUT", (long)EX_NOINPUT
)) return -1;
7766 #endif /* EX_NOINPUT */
7768 if (ins(d
, "EX_NOUSER", (long)EX_NOUSER
)) return -1;
7769 #endif /* EX_NOUSER */
7771 if (ins(d
, "EX_NOHOST", (long)EX_NOHOST
)) return -1;
7772 #endif /* EX_NOHOST */
7773 #ifdef EX_UNAVAILABLE
7774 if (ins(d
, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE
)) return -1;
7775 #endif /* EX_UNAVAILABLE */
7777 if (ins(d
, "EX_SOFTWARE", (long)EX_SOFTWARE
)) return -1;
7778 #endif /* EX_SOFTWARE */
7780 if (ins(d
, "EX_OSERR", (long)EX_OSERR
)) return -1;
7781 #endif /* EX_OSERR */
7783 if (ins(d
, "EX_OSFILE", (long)EX_OSFILE
)) return -1;
7784 #endif /* EX_OSFILE */
7786 if (ins(d
, "EX_CANTCREAT", (long)EX_CANTCREAT
)) return -1;
7787 #endif /* EX_CANTCREAT */
7789 if (ins(d
, "EX_IOERR", (long)EX_IOERR
)) return -1;
7790 #endif /* EX_IOERR */
7792 if (ins(d
, "EX_TEMPFAIL", (long)EX_TEMPFAIL
)) return -1;
7793 #endif /* EX_TEMPFAIL */
7795 if (ins(d
, "EX_PROTOCOL", (long)EX_PROTOCOL
)) return -1;
7796 #endif /* EX_PROTOCOL */
7798 if (ins(d
, "EX_NOPERM", (long)EX_NOPERM
)) return -1;
7799 #endif /* EX_NOPERM */
7801 if (ins(d
, "EX_CONFIG", (long)EX_CONFIG
)) return -1;
7802 #endif /* EX_CONFIG */
7804 if (ins(d
, "EX_NOTFOUND", (long)EX_NOTFOUND
)) return -1;
7805 #endif /* EX_NOTFOUND */
7808 #if defined(PYOS_OS2) && defined(PYCC_GCC)
7809 if (ins(d
, "P_WAIT", (long)P_WAIT
)) return -1;
7810 if (ins(d
, "P_NOWAIT", (long)P_NOWAIT
)) return -1;
7811 if (ins(d
, "P_OVERLAY", (long)P_OVERLAY
)) return -1;
7812 if (ins(d
, "P_DEBUG", (long)P_DEBUG
)) return -1;
7813 if (ins(d
, "P_SESSION", (long)P_SESSION
)) return -1;
7814 if (ins(d
, "P_DETACH", (long)P_DETACH
)) return -1;
7815 if (ins(d
, "P_PM", (long)P_PM
)) return -1;
7816 if (ins(d
, "P_DEFAULT", (long)P_DEFAULT
)) return -1;
7817 if (ins(d
, "P_MINIMIZE", (long)P_MINIMIZE
)) return -1;
7818 if (ins(d
, "P_MAXIMIZE", (long)P_MAXIMIZE
)) return -1;
7819 if (ins(d
, "P_FULLSCREEN", (long)P_FULLSCREEN
)) return -1;
7820 if (ins(d
, "P_WINDOWED", (long)P_WINDOWED
)) return -1;
7821 if (ins(d
, "P_FOREGROUND", (long)P_FOREGROUND
)) return -1;
7822 if (ins(d
, "P_BACKGROUND", (long)P_BACKGROUND
)) return -1;
7823 if (ins(d
, "P_NOCLOSE", (long)P_NOCLOSE
)) return -1;
7824 if (ins(d
, "P_NOSESSION", (long)P_NOSESSION
)) return -1;
7825 if (ins(d
, "P_QUOTE", (long)P_QUOTE
)) return -1;
7826 if (ins(d
, "P_TILDE", (long)P_TILDE
)) return -1;
7827 if (ins(d
, "P_UNRELATED", (long)P_UNRELATED
)) return -1;
7828 if (ins(d
, "P_DEBUGDESC", (long)P_DEBUGDESC
)) return -1;
7830 if (ins(d
, "P_WAIT", (long)_P_WAIT
)) return -1;
7831 if (ins(d
, "P_NOWAIT", (long)_P_NOWAIT
)) return -1;
7832 if (ins(d
, "P_OVERLAY", (long)_OLD_P_OVERLAY
)) return -1;
7833 if (ins(d
, "P_NOWAITO", (long)_P_NOWAITO
)) return -1;
7834 if (ins(d
, "P_DETACH", (long)_P_DETACH
)) return -1;
7838 #if defined(PYOS_OS2)
7839 if (insertvalues(d
)) return -1;
7845 #if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
7846 #define INITFUNC initnt
7847 #define MODNAME "nt"
7849 #elif defined(PYOS_OS2)
7850 #define INITFUNC initos2
7851 #define MODNAME "os2"
7854 #define INITFUNC initposix
7855 #define MODNAME "posix"
7863 m
= Py_InitModule3(MODNAME
,
7867 /* Initialize environ dictionary */
7868 v
= convertenviron();
7870 if (v
== NULL
|| PyModule_AddObject(m
, "environ", v
) != 0)
7877 if (setup_confname_tables(m
))
7880 Py_INCREF(PyExc_OSError
);
7881 PyModule_AddObject(m
, "error", PyExc_OSError
);
7884 if (posix_putenv_garbage
== NULL
)
7885 posix_putenv_garbage
= PyDict_New();
7888 stat_result_desc
.name
= MODNAME
".stat_result";
7889 stat_result_desc
.fields
[7].name
= PyStructSequence_UnnamedField
;
7890 stat_result_desc
.fields
[8].name
= PyStructSequence_UnnamedField
;
7891 stat_result_desc
.fields
[9].name
= PyStructSequence_UnnamedField
;
7892 PyStructSequence_InitType(&StatResultType
, &stat_result_desc
);
7893 structseq_new
= StatResultType
.tp_new
;
7894 StatResultType
.tp_new
= statresult_new
;
7895 Py_INCREF((PyObject
*) &StatResultType
);
7896 PyModule_AddObject(m
, "stat_result", (PyObject
*) &StatResultType
);
7898 statvfs_result_desc
.name
= MODNAME
".statvfs_result";
7899 PyStructSequence_InitType(&StatVFSResultType
, &statvfs_result_desc
);
7900 Py_INCREF((PyObject
*) &StatVFSResultType
);
7901 PyModule_AddObject(m
, "statvfs_result",
7902 (PyObject
*) &StatVFSResultType
);