2 /* POSIX module implementation */
4 /* This file is also used for Windows NT and MS-Win. In that case the module
5 actually calls itself 'nt', not 'posix', and a few functions are
6 either unimplemented or implemented differently. The source
7 assumes that for Windows NT, the macro 'MS_WIN32' is defined independent
8 of the compiler used. Different compilers define their own feature
9 test macro, e.g. '__BORLANDC__' or '_MSC_VER'. */
11 /* See also ../Dos/dosmodule.c */
13 static char posix__doc__
[] =
14 "This module provides access to operating system functionality that is\n\
15 standardized by the C Standard and the POSIX standard (a thinly\n\
16 disguised Unix interface). Refer to the library manual and\n\
17 corresponding Unix manual entries for more information on calls.";
23 #define INCL_DOSERRORS
24 #define INCL_DOSPROCESS
29 #include <sys/types.h>
31 #ifdef HAVE_SYS_WAIT_H
32 #include <sys/wait.h> /* For WNOHANG */
41 #endif /* HAVE_FCNTL_H */
43 /* pick up declaration of confstr on some systems? */
46 #endif /* HAVE_UNISTD_H */
48 /* Various compilers have only certain posix functions */
49 /* XXX Gosh I wish these were all moved into config.h */
50 #if defined(PYCC_VACPP) && defined(PYOS_OS2)
53 #if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
55 #define HAVE_OPENDIR 1
63 #ifdef __BORLANDC__ /* Borland compiler */
66 #define HAVE_OPENDIR 1
72 #ifdef _MSC_VER /* Microsoft compiler */
80 #else /* 16-bit Windows */
81 #endif /* !MS_WIN32 */
82 #else /* all other compilers */
83 /* Unix functions that the configure script doesn't check for */
86 #if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
90 #define HAVE_GETEGID 1
91 #define HAVE_GETEUID 1
93 #define HAVE_GETPPID 1
96 #define HAVE_OPENDIR 1
101 #define HAVE_TTYNAME 1
102 #endif /* _MSC_VER */
103 #endif /* __BORLANDC__ */
104 #endif /* ! __WATCOMC__ || __QNX__ */
105 #endif /* ! __IBMC__ */
113 #if defined(sun) && !defined(__SVR4)
114 /* SunOS 4.1.4 doesn't have prototypes for these: */
115 extern int rename(const char *, const char *);
116 extern int pclose(FILE *);
117 extern int fclose(FILE *);
118 extern int fsync(int);
119 extern int lstat(const char *, struct stat
*);
120 extern int symlink(const char *, const char *);
124 /* NeXT's <unistd.h> and <utime.h> aren't worth much */
128 /* #undef HAVE_GETCWD */
129 #define UNION_WAIT /* This should really be checked for by autoconf */
132 #ifndef HAVE_UNISTD_H
133 #if defined(PYCC_VACPP)
134 extern int mkdir(char *);
136 #if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
137 extern int mkdir(const char *);
139 extern int mkdir(const char *, mode_t
);
142 #if defined(__IBMC__) || defined(__IBMCPP__)
143 extern int chdir(char *);
144 extern int rmdir(char *);
146 extern int chdir(const char *);
147 extern int rmdir(const char *);
150 extern int chmod(const char *, int);
152 extern int chmod(const char *, mode_t
);
154 extern int chown(const char *, uid_t
, gid_t
);
155 extern char *getcwd(char *, int);
156 extern char *strerror(int);
157 extern int link(const char *, const char *);
158 extern int rename(const char *, const char *);
159 extern int stat(const char *, struct stat
*);
160 extern int unlink(const char *);
161 extern int pclose(FILE *);
163 extern int symlink(const char *, const char *);
164 #endif /* HAVE_SYMLINK */
166 extern int lstat(const char *, struct stat
*);
167 #endif /* HAVE_LSTAT */
168 #endif /* !HAVE_UNISTD_H */
170 #endif /* !_MSC_VER */
174 #endif /* HAVE_UTIME_H */
176 #ifdef HAVE_SYS_UTIME_H
177 #include <sys/utime.h>
178 #define HAVE_UTIME_H /* pretend we do for the rest of this file */
179 #endif /* HAVE_SYS_UTIME_H */
181 #ifdef HAVE_SYS_TIMES_H
182 #include <sys/times.h>
183 #endif /* HAVE_SYS_TIMES_H */
185 #ifdef HAVE_SYS_PARAM_H
186 #include <sys/param.h>
187 #endif /* HAVE_SYS_PARAM_H */
189 #ifdef HAVE_SYS_UTSNAME_H
190 #include <sys/utsname.h>
191 #endif /* HAVE_SYS_UTSNAME_H */
194 #define MAXPATHLEN 1024
195 #endif /* MAXPATHLEN */
199 #define NAMLEN(dirent) strlen((dirent)->d_name)
201 #if defined(__WATCOMC__) && !defined(__QNX__)
203 #define NAMLEN(dirent) strlen((dirent)->d_name)
205 #define dirent direct
206 #define NAMLEN(dirent) (dirent)->d_namlen
208 #ifdef HAVE_SYS_NDIR_H
209 #include <sys/ndir.h>
211 #ifdef HAVE_SYS_DIR_H
223 #define WINDOWS_LEAN_AND_MEAN
227 #define pclose _pclose
228 #else /* 16-bit Windows */
231 #endif /* MS_WIN32 */
232 #endif /* _MSC_VER */
234 #if defined(PYCC_VACPP) && defined(PYOS_OS2)
239 /* Emulate some macros on systems that have a union instead of macros */
242 #define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
246 #define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
250 #define WTERMSIG(u_wait) ((u_wait).w_termsig)
253 #endif /* UNION_WAIT */
255 /* Don't use the "_r" form if we don't need it (also, won't have a
256 prototype for it, at least on Solaris -- maybe others as well?). */
257 #if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
258 #define USE_CTERMID_R
261 #if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
265 /* choose the appropriate stat and fstat functions and return structs */
268 # define STAT _stati64
269 # define FSTAT _fstati64
270 # define STRUCT_STAT struct _stati64
274 # define STRUCT_STAT struct stat
278 /* Return a dictionary corresponding to the POSIX environment table */
280 #if !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
281 extern char **environ
;
282 #endif /* !_MSC_VER */
294 /* This part ignores errors */
295 for (e
= environ
; *e
!= NULL
; e
++) {
298 char *p
= strchr(*e
, '=');
301 k
= PyString_FromStringAndSize(*e
, (int)(p
-*e
));
306 v
= PyString_FromString(p
+1);
312 if (PyDict_GetItem(d
, k
) == NULL
) {
313 if (PyDict_SetItem(d
, k
, v
) != 0)
319 #if defined(PYOS_OS2)
322 char buffer
[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
324 rc
= DosQueryExtLIBPATH(buffer
, BEGIN_LIBPATH
);
325 if (rc
== NO_ERROR
) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
326 PyObject
*v
= PyString_FromString(buffer
);
327 PyDict_SetItemString(d
, "BEGINLIBPATH", v
);
330 rc
= DosQueryExtLIBPATH(buffer
, END_LIBPATH
);
331 if (rc
== NO_ERROR
) { /* (not a typo, envname is NOT 'END_LIBPATH') */
332 PyObject
*v
= PyString_FromString(buffer
);
333 PyDict_SetItemString(d
, "ENDLIBPATH", v
);
342 /* Set a POSIX-specific error from errno, and return NULL */
347 return PyErr_SetFromErrno(PyExc_OSError
);
350 posix_error_with_filename(char* name
)
352 return PyErr_SetFromErrnoWithFilename(PyExc_OSError
, name
);
357 win32_error(char* function
, char* filename
)
359 /* XXX We should pass the function name along in the future.
360 (_winreg.c also wants to pass the function name.)
361 This would however require an additional param to the
362 Windows error object, which is non-trivial.
364 errno
= GetLastError();
366 return PyErr_SetFromWindowsErrWithFilename(errno
, filename
);
368 return PyErr_SetFromWindowsErr(errno
);
372 #if defined(PYOS_OS2)
373 /**********************************************************************
374 * Helper Function to Trim and Format OS/2 Messages
375 **********************************************************************/
377 os2_formatmsg(char *msgbuf
, int msglen
, char *reason
)
379 msgbuf
[msglen
] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
381 if (strlen(msgbuf
) > 0) { /* If Non-Empty Msg, Trim CRLF */
382 char *lastc
= &msgbuf
[ strlen(msgbuf
)-1 ];
384 while (lastc
> msgbuf
&& isspace(*lastc
))
385 *lastc
-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
388 /* Add Optional Reason Text */
390 strcat(msgbuf
, " : ");
391 strcat(msgbuf
, reason
);
395 /**********************************************************************
396 * Decode an OS/2 Operating System Error Code
398 * A convenience function to lookup an OS/2 error code and return a
399 * text message we can use to raise a Python exception.
402 * The messages for errors returned from the OS/2 kernel reside in
403 * the file OSO001.MSG in the \OS2 directory hierarchy.
405 **********************************************************************/
407 os2_strerror(char *msgbuf
, int msgbuflen
, int errorcode
, char *reason
)
412 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
413 Py_BEGIN_ALLOW_THREADS
414 rc
= DosGetMessage(NULL
, 0, msgbuf
, msgbuflen
,
415 errorcode
, "oso001.msg", &msglen
);
419 os2_formatmsg(msgbuf
, msglen
, reason
);
421 sprintf(msgbuf
, "unknown OS error #%d", errorcode
);
426 /* Set an OS/2-specific error and return NULL. OS/2 kernel
427 errors are not in a global variable e.g. 'errno' nor are
428 they congruent with posix error numbers. */
430 static PyObject
* os2_error(int code
)
435 os2_strerror(text
, sizeof(text
), code
, "");
437 v
= Py_BuildValue("(is)", code
, text
);
439 PyErr_SetObject(PyExc_OSError
, v
);
442 return NULL
; /* Signal to Python that an Exception is Pending */
447 /* POSIX generic methods */
450 posix_int(PyObject
*args
, char *format
, int (*func
)(int))
454 if (!PyArg_ParseTuple(args
, format
, &fd
))
456 Py_BEGIN_ALLOW_THREADS
460 return posix_error();
467 posix_1str(PyObject
*args
, char *format
, int (*func
)(const char*))
471 if (!PyArg_ParseTuple(args
, format
, &path1
))
473 Py_BEGIN_ALLOW_THREADS
474 res
= (*func
)(path1
);
477 return posix_error_with_filename(path1
);
483 posix_2str(PyObject
*args
, char *format
,
484 int (*func
)(const char *, const char *))
488 if (!PyArg_ParseTuple(args
, format
, &path1
, &path2
))
490 Py_BEGIN_ALLOW_THREADS
491 res
= (*func
)(path1
, path2
);
494 /* XXX how to report both path1 and path2??? */
495 return posix_error();
500 /* pack a system stat C structure into the Python stat tuple
501 (used by posix_stat() and posix_fstat()) */
503 _pystat_fromstructstat(STRUCT_STAT st
)
505 PyObject
*v
= PyTuple_New(10);
509 PyTuple_SetItem(v
, 0, PyInt_FromLong((long)st
.st_mode
));
510 #ifdef HAVE_LARGEFILE_SUPPORT
511 PyTuple_SetItem(v
, 1, PyLong_FromLongLong((LONG_LONG
)st
.st_ino
));
513 PyTuple_SetItem(v
, 1, PyInt_FromLong((long)st
.st_ino
));
515 #if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
516 PyTuple_SetItem(v
, 2, PyLong_FromLongLong((LONG_LONG
)st
.st_dev
));
518 PyTuple_SetItem(v
, 2, PyInt_FromLong((long)st
.st_dev
));
520 PyTuple_SetItem(v
, 3, PyInt_FromLong((long)st
.st_nlink
));
521 PyTuple_SetItem(v
, 4, PyInt_FromLong((long)st
.st_uid
));
522 PyTuple_SetItem(v
, 5, PyInt_FromLong((long)st
.st_gid
));
523 #ifdef HAVE_LARGEFILE_SUPPORT
524 PyTuple_SetItem(v
, 6, PyLong_FromLongLong((LONG_LONG
)st
.st_size
));
526 PyTuple_SetItem(v
, 6, PyInt_FromLong(st
.st_size
));
528 #if SIZEOF_TIME_T > SIZEOF_LONG
529 PyTuple_SetItem(v
, 7, PyLong_FromLongLong((LONG_LONG
)st
.st_atime
));
530 PyTuple_SetItem(v
, 8, PyLong_FromLongLong((LONG_LONG
)st
.st_mtime
));
531 PyTuple_SetItem(v
, 9, PyLong_FromLongLong((LONG_LONG
)st
.st_ctime
));
533 PyTuple_SetItem(v
, 7, PyInt_FromLong((long)st
.st_atime
));
534 PyTuple_SetItem(v
, 8, PyInt_FromLong((long)st
.st_mtime
));
535 PyTuple_SetItem(v
, 9, PyInt_FromLong((long)st
.st_ctime
));
538 if (PyErr_Occurred()) {
548 posix_do_stat(PyObject
*self
, PyObject
*args
, char *format
,
549 int (*statfunc
)(const char *, STRUCT_STAT
*))
557 char pathcopy
[MAX_PATH
];
558 #endif /* MS_WIN32 */
560 if (!PyArg_ParseTuple(args
, format
, &path
))
564 pathlen
= strlen(path
);
565 /* the library call can blow up if the file name is too long! */
566 if (pathlen
> MAX_PATH
) {
567 errno
= ENAMETOOLONG
;
568 return posix_error();
571 if ((pathlen
> 0) && (path
[pathlen
-1] == '\\' || path
[pathlen
-1] == '/')) {
572 /* exception for specific or current drive root */
573 if (!((pathlen
== 1) ||
576 (path
[2] == '\\' || path
[2] == '/'))))
578 strncpy(pathcopy
, path
, pathlen
);
579 pathcopy
[pathlen
-1] = '\0'; /* nuke the trailing backslash */
583 #endif /* MS_WIN32 */
585 Py_BEGIN_ALLOW_THREADS
586 res
= (*statfunc
)(path
, &st
);
589 return posix_error_with_filename(path
);
591 return _pystat_fromstructstat(st
);
597 static char posix_access__doc__
[] =
598 "access(path, mode) -> 1 if granted, 0 otherwise\n\
599 Test for access to a file.";
602 posix_access(PyObject
*self
, PyObject
*args
)
608 if (!PyArg_ParseTuple(args
, "si:access", &path
, &mode
))
610 Py_BEGIN_ALLOW_THREADS
611 res
= access(path
, mode
);
613 return(PyInt_FromLong(res
== 0 ? 1L : 0L));
630 static char posix_ttyname__doc__
[] =
631 "ttyname(fd) -> String\n\
632 Return the name of the terminal device connected to 'fd'.";
635 posix_ttyname(PyObject
*self
, PyObject
*args
)
640 if (!PyArg_ParseTuple(args
, "i:ttyname", &id
))
645 return(posix_error());
646 return(PyString_FromString(ret
));
651 static char posix_ctermid__doc__
[] =
652 "ctermid() -> String\n\
653 Return the name of the controlling terminal for this process.";
656 posix_ctermid(PyObject
*self
, PyObject
*args
)
659 char buffer
[L_ctermid
];
661 if (!PyArg_ParseTuple(args
, ":ctermid"))
665 ret
= ctermid_r(buffer
);
667 ret
= ctermid(buffer
);
670 return(posix_error());
671 return(PyString_FromString(buffer
));
675 static char posix_chdir__doc__
[] =
676 "chdir(path) -> None\n\
677 Change the current working directory to the specified path.";
680 posix_chdir(PyObject
*self
, PyObject
*args
)
682 return posix_1str(args
, "s:chdir", chdir
);
686 static char posix_chmod__doc__
[] =
687 "chmod(path, mode) -> None\n\
688 Change the access permissions of a file.";
691 posix_chmod(PyObject
*self
, PyObject
*args
)
696 if (!PyArg_ParseTuple(args
, "si", &path
, &i
))
698 Py_BEGIN_ALLOW_THREADS
699 res
= chmod(path
, i
);
702 return posix_error_with_filename(path
);
709 static char posix_fsync__doc__
[] =
710 "fsync(fildes) -> None\n\
711 force write of file with filedescriptor to disk.";
714 posix_fsync(PyObject
*self
, PyObject
*args
)
716 return posix_int(args
, "i:fsync", fsync
);
718 #endif /* HAVE_FSYNC */
720 #ifdef HAVE_FDATASYNC
723 extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
726 static char posix_fdatasync__doc__
[] =
727 "fdatasync(fildes) -> None\n\
728 force write of file with filedescriptor to disk.\n\
729 does not force update of metadata.";
732 posix_fdatasync(PyObject
*self
, PyObject
*args
)
734 return posix_int(args
, "i:fdatasync", fdatasync
);
736 #endif /* HAVE_FDATASYNC */
740 static char posix_chown__doc__
[] =
741 "chown(path, uid, gid) -> None\n\
742 Change the owner and group id of path to the numeric uid and gid.";
745 posix_chown(PyObject
*self
, PyObject
*args
)
750 if (!PyArg_ParseTuple(args
, "sii:chown", &path
, &uid
, &gid
))
752 Py_BEGIN_ALLOW_THREADS
753 res
= chown(path
, (uid_t
) uid
, (gid_t
) gid
);
756 return posix_error_with_filename(path
);
760 #endif /* HAVE_CHOWN */
764 static char posix_getcwd__doc__
[] =
766 Return a string representing the current working directory.";
769 posix_getcwd(PyObject
*self
, PyObject
*args
)
773 if (!PyArg_ParseTuple(args
, ":getcwd"))
775 Py_BEGIN_ALLOW_THREADS
776 res
= getcwd(buf
, sizeof buf
);
779 return posix_error();
780 return PyString_FromString(buf
);
786 static char posix_link__doc__
[] =
787 "link(src, dst) -> None\n\
788 Create a hard link to a file.";
791 posix_link(PyObject
*self
, PyObject
*args
)
793 return posix_2str(args
, "ss:link", link
);
795 #endif /* HAVE_LINK */
798 static char posix_listdir__doc__
[] =
799 "listdir(path) -> list_of_strings\n\
800 Return a list containing the names of the entries in the directory.\n\
802 path: path of directory to list\n\
804 The list is in arbitrary order. It does not include the special\n\
805 entries '.' and '..' even if they are present in the directory.";
808 posix_listdir(PyObject
*self
, PyObject
*args
)
810 /* XXX Should redo this putting the (now four) versions of opendir
811 in separate files instead of having them all here... */
812 #if defined(MS_WIN32) && !defined(HAVE_OPENDIR)
818 WIN32_FIND_DATA FileData
;
819 char namebuf
[MAX_PATH
+5];
822 if (!PyArg_ParseTuple(args
, "t#:listdir", &name
, &len
))
824 if (len
>= MAX_PATH
) {
825 PyErr_SetString(PyExc_ValueError
, "path too long");
828 strcpy(namebuf
, name
);
830 if (ch
!= '/' && ch
!= '\\' && ch
!= ':')
831 namebuf
[len
++] = '/';
832 strcpy(namebuf
+ len
, "*.*");
834 if ((d
= PyList_New(0)) == NULL
)
837 hFindFile
= FindFirstFile(namebuf
, &FileData
);
838 if (hFindFile
== INVALID_HANDLE_VALUE
) {
839 errno
= GetLastError();
840 if (errno
== ERROR_FILE_NOT_FOUND
)
841 return PyList_New(0);
842 return win32_error("FindFirstFile", name
);
845 if (FileData
.cFileName
[0] == '.' &&
846 (FileData
.cFileName
[1] == '\0' ||
847 FileData
.cFileName
[1] == '.' &&
848 FileData
.cFileName
[2] == '\0'))
850 v
= PyString_FromString(FileData
.cFileName
);
856 if (PyList_Append(d
, v
) != 0) {
863 } while (FindNextFile(hFindFile
, &FileData
) == TRUE
);
865 if (FindClose(hFindFile
) == FALSE
)
866 return win32_error("FindClose", name
);
870 #elif defined(_MSC_VER) /* 16-bit Windows */
878 char namebuf
[MAX_PATH
+5];
881 if (!PyArg_ParseTuple(args
, "t#:listdir", &name
, &len
))
883 if (len
>= MAX_PATH
) {
884 PyErr_SetString(PyExc_ValueError
, "path too long");
887 strcpy(namebuf
, name
);
888 for (pt
= namebuf
; *pt
; pt
++)
891 if (namebuf
[len
-1] != '\\')
892 namebuf
[len
++] = '\\';
893 strcpy(namebuf
+ len
, "*.*");
895 if ((d
= PyList_New(0)) == NULL
)
898 if (_dos_findfirst(namebuf
, _A_RDONLY
|
899 _A_HIDDEN
| _A_SYSTEM
| _A_SUBDIR
, &ep
) != 0)
902 return posix_error_with_filename(name
);
905 if (ep
.name
[0] == '.' &&
906 (ep
.name
[1] == '\0' ||
910 strcpy(namebuf
, ep
.name
);
911 for (pt
= namebuf
; *pt
; pt
++)
914 v
= PyString_FromString(namebuf
);
920 if (PyList_Append(d
, v
) != 0) {
927 } while (_dos_findnext(&ep
) == 0);
931 #elif defined(PYOS_OS2)
934 #define MAX_PATH CCHMAXPATH
939 char namebuf
[MAX_PATH
+5];
945 if (!PyArg_ParseTuple(args
, "t#:listdir", &name
, &len
))
947 if (len
>= MAX_PATH
) {
948 PyErr_SetString(PyExc_ValueError
, "path too long");
951 strcpy(namebuf
, name
);
952 for (pt
= namebuf
; *pt
; pt
++)
955 if (namebuf
[len
-1] != '\\')
956 namebuf
[len
++] = '\\';
957 strcpy(namebuf
+ len
, "*.*");
959 if ((d
= PyList_New(0)) == NULL
)
962 rc
= DosFindFirst(namebuf
, /* Wildcard Pattern to Match */
963 &hdir
, /* Handle to Use While Search Directory */
964 FILE_READONLY
| FILE_HIDDEN
| FILE_SYSTEM
| FILE_DIRECTORY
,
965 &ep
, sizeof(ep
), /* Structure to Receive Directory Entry */
966 &srchcnt
, /* Max and Actual Count of Entries Per Iteration */
967 FIL_STANDARD
); /* Format of Entry (EAs or Not) */
969 if (rc
!= NO_ERROR
) {
971 return posix_error_with_filename(name
);
974 if (srchcnt
> 0) { /* If Directory is NOT Totally Empty, */
976 if (ep
.achName
[0] == '.'
977 && (ep
.achName
[1] == '\0' || ep
.achName
[1] == '.' && ep
.achName
[2] == '\0'))
978 continue; /* Skip Over "." and ".." Names */
980 strcpy(namebuf
, ep
.achName
);
982 /* Leave Case of Name Alone -- In Native Form */
983 /* (Removed Forced Lowercasing Code) */
985 v
= PyString_FromString(namebuf
);
991 if (PyList_Append(d
, v
) != 0) {
998 } while (DosFindNext(hdir
, &ep
, sizeof(ep
), &srchcnt
) == NO_ERROR
&& srchcnt
> 0);
1008 if (!PyArg_ParseTuple(args
, "s:listdir", &name
))
1010 if ((dirp
= opendir(name
)) == NULL
) {
1011 return posix_error_with_filename(name
);
1013 if ((d
= PyList_New(0)) == NULL
) {
1017 while ((ep
= readdir(dirp
)) != NULL
) {
1018 if (ep
->d_name
[0] == '.' &&
1020 (ep
->d_name
[1] == '.' && NAMLEN(ep
) == 2)))
1022 v
= PyString_FromStringAndSize(ep
->d_name
, NAMLEN(ep
));
1028 if (PyList_Append(d
, v
) != 0) {
1040 #endif /* which OS */
1041 } /* end of posix_listdir */
1043 static char posix_mkdir__doc__
[] =
1044 "mkdir(path [, mode=0777]) -> None\n\
1045 Create a directory.";
1048 posix_mkdir(PyObject
*self
, PyObject
*args
)
1053 if (!PyArg_ParseTuple(args
, "s|i:mkdir", &path
, &mode
))
1055 Py_BEGIN_ALLOW_THREADS
1056 #if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
1059 res
= mkdir(path
, mode
);
1061 Py_END_ALLOW_THREADS
1063 return posix_error_with_filename(path
);
1070 #if defined(HAVE_BROKEN_NICE) && defined(HAVE_SYS_RESOURCE_H)
1071 #if defined(HAVE_GETPRIORITY) && !defined(PRIO_PROCESS)
1072 #include <sys/resource.h>
1076 static char posix_nice__doc__
[] =
1077 "nice(inc) -> new_priority\n\
1078 Decrease the priority of process and return new priority.";
1081 posix_nice(PyObject
*self
, PyObject
*args
)
1083 int increment
, value
;
1085 if (!PyArg_ParseTuple(args
, "i:nice", &increment
))
1088 /* There are two flavours of 'nice': one that returns the new
1089 priority (as required by almost all standards out there) and the
1090 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
1091 the use of getpriority() to get the new priority.
1093 If we are of the nice family that returns the new priority, we
1094 need to clear errno before the call, and check if errno is filled
1095 before calling posix_error() on a returnvalue of -1, because the
1096 -1 may be the actual new priority! */
1099 value
= nice(increment
);
1100 #if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
1102 value
= getpriority(PRIO_PROCESS
, 0);
1104 if (value
== -1 && errno
!= 0)
1105 /* either nice() or getpriority() returned an error */
1106 return posix_error();
1107 return PyInt_FromLong((long) value
);
1109 #endif /* HAVE_NICE */
1112 static char posix_rename__doc__
[] =
1113 "rename(old, new) -> None\n\
1114 Rename a file or directory.";
1117 posix_rename(PyObject
*self
, PyObject
*args
)
1119 return posix_2str(args
, "ss:rename", rename
);
1123 static char posix_rmdir__doc__
[] =
1124 "rmdir(path) -> None\n\
1125 Remove a directory.";
1128 posix_rmdir(PyObject
*self
, PyObject
*args
)
1130 return posix_1str(args
, "s:rmdir", rmdir
);
1134 static char posix_stat__doc__
[] =
1135 "stat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
1136 Perform a stat system call on the given path.";
1139 posix_stat(PyObject
*self
, PyObject
*args
)
1141 return posix_do_stat(self
, args
, "s:stat", STAT
);
1146 static char posix_system__doc__
[] =
1147 "system(command) -> exit_status\n\
1148 Execute the command (a string) in a subshell.";
1151 posix_system(PyObject
*self
, PyObject
*args
)
1155 if (!PyArg_ParseTuple(args
, "s:system", &command
))
1157 Py_BEGIN_ALLOW_THREADS
1158 sts
= system(command
);
1159 Py_END_ALLOW_THREADS
1160 return PyInt_FromLong(sts
);
1165 static char posix_umask__doc__
[] =
1166 "umask(new_mask) -> old_mask\n\
1167 Set the current numeric umask and return the previous umask.";
1170 posix_umask(PyObject
*self
, PyObject
*args
)
1173 if (!PyArg_ParseTuple(args
, "i:umask", &i
))
1177 return posix_error();
1178 return PyInt_FromLong((long)i
);
1182 static char posix_unlink__doc__
[] =
1183 "unlink(path) -> None\n\
1184 Remove a file (same as remove(path)).";
1186 static char posix_remove__doc__
[] =
1187 "remove(path) -> None\n\
1188 Remove a file (same as unlink(path)).";
1191 posix_unlink(PyObject
*self
, PyObject
*args
)
1193 return posix_1str(args
, "s:remove", unlink
);
1198 static char posix_uname__doc__
[] =
1199 "uname() -> (sysname, nodename, release, version, machine)\n\
1200 Return a tuple identifying the current operating system.";
1203 posix_uname(PyObject
*self
, PyObject
*args
)
1207 if (!PyArg_ParseTuple(args
, ":uname"))
1209 Py_BEGIN_ALLOW_THREADS
1211 Py_END_ALLOW_THREADS
1213 return posix_error();
1214 return Py_BuildValue("(sssss)",
1221 #endif /* HAVE_UNAME */
1224 static char posix_utime__doc__
[] =
1225 "utime(path, (atime, utime)) -> None\n\
1226 utime(path, None) -> None\n\
1227 Set the access and modified time of the file to the given values. If the\n\
1228 second form is used, set the access and modified times to the current time.";
1231 posix_utime(PyObject
*self
, PyObject
*args
)
1238 /* XXX should define struct utimbuf instead, above */
1241 #define ATIME buf.actime
1242 #define MTIME buf.modtime
1243 #define UTIME_ARG &buf
1244 #else /* HAVE_UTIME_H */
1246 #define ATIME buf[0]
1247 #define MTIME buf[1]
1248 #define UTIME_ARG buf
1249 #endif /* HAVE_UTIME_H */
1251 if (!PyArg_ParseTuple(args
, "sO:utime", &path
, &arg
))
1253 if (arg
== Py_None
) {
1254 /* optional time values not given */
1255 Py_BEGIN_ALLOW_THREADS
1256 res
= utime(path
, NULL
);
1257 Py_END_ALLOW_THREADS
1259 else if (!PyArg_Parse(arg
, "(ll)", &atime
, &mtime
)) {
1260 PyErr_SetString(PyExc_TypeError
,
1261 "utime() arg 2 must be a tuple (atime, mtime)");
1267 Py_BEGIN_ALLOW_THREADS
1268 res
= utime(path
, UTIME_ARG
);
1269 Py_END_ALLOW_THREADS
1272 return posix_error_with_filename(path
);
1281 /* Process operations */
1283 static char posix__exit__doc__
[] =
1285 Exit to the system with specified status, without normal exit processing.";
1288 posix__exit(PyObject
*self
, PyObject
*args
)
1291 if (!PyArg_ParseTuple(args
, "i:_exit", &sts
))
1294 return NULL
; /* Make gcc -Wall happy */
1299 static char posix_execv__doc__
[] =
1300 "execv(path, args)\n\
1301 Execute an executable path with arguments, replacing current process.\n\
1303 path: path of executable file\n\
1304 args: tuple or list of strings";
1307 posix_execv(PyObject
*self
, PyObject
*args
)
1313 PyObject
*(*getitem
)(PyObject
*, int);
1315 /* execv has two arguments: (path, argv), where
1316 argv is a list or tuple of strings. */
1318 if (!PyArg_ParseTuple(args
, "sO:execv", &path
, &argv
))
1320 if (PyList_Check(argv
)) {
1321 argc
= PyList_Size(argv
);
1322 getitem
= PyList_GetItem
;
1324 else if (PyTuple_Check(argv
)) {
1325 argc
= PyTuple_Size(argv
);
1326 getitem
= PyTuple_GetItem
;
1329 PyErr_SetString(PyExc_TypeError
, "execv() arg 2 must be a tuple or list");
1334 PyErr_SetString(PyExc_ValueError
, "execv() arg 2 must not be empty");
1338 argvlist
= PyMem_NEW(char *, argc
+1);
1339 if (argvlist
== NULL
)
1341 for (i
= 0; i
< argc
; i
++) {
1342 if (!PyArg_Parse((*getitem
)(argv
, i
), "s", &argvlist
[i
])) {
1343 PyMem_DEL(argvlist
);
1344 PyErr_SetString(PyExc_TypeError
,
1345 "execv() arg 2 must contain only strings");
1350 argvlist
[argc
] = NULL
;
1352 #ifdef BAD_EXEC_PROTOTYPES
1353 execv(path
, (const char **) argvlist
);
1354 #else /* BAD_EXEC_PROTOTYPES */
1355 execv(path
, argvlist
);
1356 #endif /* BAD_EXEC_PROTOTYPES */
1358 /* If we get here it's definitely an error */
1360 PyMem_DEL(argvlist
);
1361 return posix_error();
1365 static char posix_execve__doc__
[] =
1366 "execve(path, args, env)\n\
1367 Execute a path with arguments and environment, replacing current process.\n\
1369 path: path of executable file\n\
1370 args: tuple or list of arguments\n\
1371 env: dictionary of strings mapping to strings";
1374 posix_execve(PyObject
*self
, PyObject
*args
)
1377 PyObject
*argv
, *env
;
1380 PyObject
*key
, *val
, *keys
=NULL
, *vals
=NULL
;
1381 int i
, pos
, argc
, envc
;
1382 PyObject
*(*getitem
)(PyObject
*, int);
1384 /* execve has three arguments: (path, argv, env), where
1385 argv is a list or tuple of strings and env is a dictionary
1386 like posix.environ. */
1388 if (!PyArg_ParseTuple(args
, "sOO:execve", &path
, &argv
, &env
))
1390 if (PyList_Check(argv
)) {
1391 argc
= PyList_Size(argv
);
1392 getitem
= PyList_GetItem
;
1394 else if (PyTuple_Check(argv
)) {
1395 argc
= PyTuple_Size(argv
);
1396 getitem
= PyTuple_GetItem
;
1399 PyErr_SetString(PyExc_TypeError
, "execve() arg 2 must be a tuple or list");
1402 if (!PyMapping_Check(env
)) {
1403 PyErr_SetString(PyExc_TypeError
, "execve() arg 3 must be a mapping object");
1408 PyErr_SetString(PyExc_ValueError
,
1409 "execve() arg 2 must not be empty");
1413 argvlist
= PyMem_NEW(char *, argc
+1);
1414 if (argvlist
== NULL
) {
1418 for (i
= 0; i
< argc
; i
++) {
1419 if (!PyArg_Parse((*getitem
)(argv
, i
),
1420 "s;execve() arg 2 must contain only strings",
1426 argvlist
[argc
] = NULL
;
1428 i
= PyMapping_Size(env
);
1429 envlist
= PyMem_NEW(char *, i
+ 1);
1430 if (envlist
== NULL
) {
1435 keys
= PyMapping_Keys(env
);
1436 vals
= PyMapping_Values(env
);
1440 for (pos
= 0; pos
< i
; pos
++) {
1443 key
= PyList_GetItem(keys
, pos
);
1444 val
= PyList_GetItem(vals
, pos
);
1448 if (!PyArg_Parse(key
, "s;execve() arg 3 contains a non-string key", &k
) ||
1449 !PyArg_Parse(val
, "s;execve() arg 3 contains a non-string value", &v
))
1454 #if defined(PYOS_OS2)
1455 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
1456 if (stricmp(k
, "BEGINLIBPATH") != 0 && stricmp(k
, "ENDLIBPATH") != 0) {
1458 p
= PyMem_NEW(char, PyString_Size(key
)+PyString_Size(val
) + 2);
1463 sprintf(p
, "%s=%s", k
, v
);
1464 envlist
[envc
++] = p
;
1465 #if defined(PYOS_OS2)
1472 #ifdef BAD_EXEC_PROTOTYPES
1473 execve(path
, (const char **)argvlist
, envlist
);
1474 #else /* BAD_EXEC_PROTOTYPES */
1475 execve(path
, argvlist
, envlist
);
1476 #endif /* BAD_EXEC_PROTOTYPES */
1478 /* If we get here it's definitely an error */
1480 (void) posix_error();
1484 PyMem_DEL(envlist
[envc
]);
1487 PyMem_DEL(argvlist
);
1492 #endif /* HAVE_EXECV */
1496 static char posix_spawnv__doc__
[] =
1497 "spawnv(mode, path, args)\n\
1498 Execute an executable path with arguments, replacing current process.\n\
1500 mode: mode of process creation\n\
1501 path: path of executable file\n\
1502 args: tuple or list of strings";
1505 posix_spawnv(PyObject
*self
, PyObject
*args
)
1512 PyObject
*(*getitem
)(PyObject
*, int);
1514 /* spawnv has three arguments: (mode, path, argv), where
1515 argv is a list or tuple of strings. */
1517 if (!PyArg_ParseTuple(args
, "isO:spawnv", &mode
, &path
, &argv
))
1519 if (PyList_Check(argv
)) {
1520 argc
= PyList_Size(argv
);
1521 getitem
= PyList_GetItem
;
1523 else if (PyTuple_Check(argv
)) {
1524 argc
= PyTuple_Size(argv
);
1525 getitem
= PyTuple_GetItem
;
1528 PyErr_SetString(PyExc_TypeError
, "spawmv() arg 2 must be a tuple or list");
1532 argvlist
= PyMem_NEW(char *, argc
+1);
1533 if (argvlist
== NULL
)
1535 for (i
= 0; i
< argc
; i
++) {
1536 if (!PyArg_Parse((*getitem
)(argv
, i
), "s", &argvlist
[i
])) {
1537 PyMem_DEL(argvlist
);
1538 PyErr_SetString(PyExc_TypeError
,
1539 "spawnv() arg 2 must contain only strings");
1543 argvlist
[argc
] = NULL
;
1545 if (mode
== _OLD_P_OVERLAY
)
1547 spawnval
= _spawnv(mode
, path
, argvlist
);
1549 PyMem_DEL(argvlist
);
1552 return posix_error();
1554 #if SIZEOF_LONG == SIZEOF_VOID_P
1555 return Py_BuildValue("l", (long) spawnval
);
1557 return Py_BuildValue("L", (LONG_LONG
) spawnval
);
1562 static char posix_spawnve__doc__
[] =
1563 "spawnve(mode, path, args, env)\n\
1564 Execute a path with arguments and environment, replacing current process.\n\
1566 mode: mode of process creation\n\
1567 path: path of executable file\n\
1568 args: tuple or list of arguments\n\
1569 env: dictionary of strings mapping to strings";
1572 posix_spawnve(PyObject
*self
, PyObject
*args
)
1575 PyObject
*argv
, *env
;
1578 PyObject
*key
, *val
, *keys
=NULL
, *vals
=NULL
, *res
=NULL
;
1579 int mode
, i
, pos
, argc
, envc
;
1581 PyObject
*(*getitem
)(PyObject
*, int);
1583 /* spawnve has four arguments: (mode, path, argv, env), where
1584 argv is a list or tuple of strings and env is a dictionary
1585 like posix.environ. */
1587 if (!PyArg_ParseTuple(args
, "isOO:spawnve", &mode
, &path
, &argv
, &env
))
1589 if (PyList_Check(argv
)) {
1590 argc
= PyList_Size(argv
);
1591 getitem
= PyList_GetItem
;
1593 else if (PyTuple_Check(argv
)) {
1594 argc
= PyTuple_Size(argv
);
1595 getitem
= PyTuple_GetItem
;
1598 PyErr_SetString(PyExc_TypeError
, "spawnve() arg 2 must be a tuple or list");
1601 if (!PyMapping_Check(env
)) {
1602 PyErr_SetString(PyExc_TypeError
, "spawnve() arg 3 must be a mapping object");
1606 argvlist
= PyMem_NEW(char *, argc
+1);
1607 if (argvlist
== NULL
) {
1611 for (i
= 0; i
< argc
; i
++) {
1612 if (!PyArg_Parse((*getitem
)(argv
, i
),
1613 "s;spawnve() arg 2 must contain only strings",
1619 argvlist
[argc
] = NULL
;
1621 i
= PyMapping_Size(env
);
1622 envlist
= PyMem_NEW(char *, i
+ 1);
1623 if (envlist
== NULL
) {
1628 keys
= PyMapping_Keys(env
);
1629 vals
= PyMapping_Values(env
);
1633 for (pos
= 0; pos
< i
; pos
++) {
1636 key
= PyList_GetItem(keys
, pos
);
1637 val
= PyList_GetItem(vals
, pos
);
1641 if (!PyArg_Parse(key
, "s;spawnve() arg 3 contains a non-string key", &k
) ||
1642 !PyArg_Parse(val
, "s;spawnve() arg 3 contains a non-string value", &v
))
1646 p
= PyMem_NEW(char, PyString_Size(key
)+PyString_Size(val
) + 2);
1651 sprintf(p
, "%s=%s", k
, v
);
1652 envlist
[envc
++] = p
;
1656 if (mode
== _OLD_P_OVERLAY
)
1658 spawnval
= _spawnve(mode
, path
, argvlist
, envlist
);
1660 (void) posix_error();
1662 #if SIZEOF_LONG == SIZEOF_VOID_P
1663 res
= Py_BuildValue("l", (long) spawnval
);
1665 res
= Py_BuildValue("L", (LONG_LONG
) spawnval
);
1670 PyMem_DEL(envlist
[envc
]);
1673 PyMem_DEL(argvlist
);
1678 #endif /* HAVE_SPAWNV */
1682 static char posix_fork1__doc__
[] =
1684 Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
1686 Return 0 to child process and PID of child to parent process.";
1689 posix_fork1(self
, args
)
1694 if (!PyArg_ParseTuple(args
, ":fork1"))
1698 return posix_error();
1700 return PyInt_FromLong((long)pid
);
1706 static char posix_fork__doc__
[] =
1708 Fork a child process.\n\
1710 Return 0 to child process and PID of child to parent process.";
1713 posix_fork(PyObject
*self
, PyObject
*args
)
1716 if (!PyArg_ParseTuple(args
, ":fork"))
1720 return posix_error();
1723 return PyInt_FromLong((long)pid
);
1727 #if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY)
1731 #ifdef HAVE_LIBUTIL_H
1732 #include <libutil.h>
1733 #endif /* HAVE_LIBUTIL_H */
1734 #endif /* HAVE_PTY_H */
1735 #endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */
1737 #if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
1738 static char posix_openpty__doc__
[] =
1739 "openpty() -> (master_fd, slave_fd)\n\
1740 Open a pseudo-terminal, returning open fd's for both master and slave end.\n";
1743 posix_openpty(PyObject
*self
, PyObject
*args
)
1745 int master_fd
, slave_fd
;
1746 #ifndef HAVE_OPENPTY
1750 if (!PyArg_ParseTuple(args
, ":openpty"))
1754 if (openpty(&master_fd
, &slave_fd
, NULL
, NULL
, NULL
) != 0)
1755 return posix_error();
1757 slave_name
= _getpty(&master_fd
, O_RDWR
, 0666, 0);
1758 if (slave_name
== NULL
)
1759 return posix_error();
1761 slave_fd
= open(slave_name
, O_RDWR
);
1763 return posix_error();
1764 #endif /* HAVE_OPENPTY */
1766 return Py_BuildValue("(ii)", master_fd
, slave_fd
);
1769 #endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) */
1772 static char posix_forkpty__doc__
[] =
1773 "forkpty() -> (pid, master_fd)\n\
1774 Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
1775 Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
1776 To both, return fd of newly opened pseudo-terminal.\n";
1779 posix_forkpty(PyObject
*self
, PyObject
*args
)
1783 if (!PyArg_ParseTuple(args
, ":forkpty"))
1785 pid
= forkpty(&master_fd
, NULL
, NULL
, NULL
);
1787 return posix_error();
1790 return Py_BuildValue("(ii)", pid
, master_fd
);
1795 static char posix_getegid__doc__
[] =
1796 "getegid() -> egid\n\
1797 Return the current process's effective group id.";
1800 posix_getegid(PyObject
*self
, PyObject
*args
)
1802 if (!PyArg_ParseTuple(args
, ":getegid"))
1804 return PyInt_FromLong((long)getegid());
1810 static char posix_geteuid__doc__
[] =
1811 "geteuid() -> euid\n\
1812 Return the current process's effective user id.";
1815 posix_geteuid(PyObject
*self
, PyObject
*args
)
1817 if (!PyArg_ParseTuple(args
, ":geteuid"))
1819 return PyInt_FromLong((long)geteuid());
1825 static char posix_getgid__doc__
[] =
1827 Return the current process's group id.";
1830 posix_getgid(PyObject
*self
, PyObject
*args
)
1832 if (!PyArg_ParseTuple(args
, ":getgid"))
1834 return PyInt_FromLong((long)getgid());
1839 static char posix_getpid__doc__
[] =
1841 Return the current process id";
1844 posix_getpid(PyObject
*self
, PyObject
*args
)
1846 if (!PyArg_ParseTuple(args
, ":getpid"))
1848 return PyInt_FromLong((long)getpid());
1852 #ifdef HAVE_GETGROUPS
1853 static char posix_getgroups__doc__
[] = "\
1854 getgroups() -> list of group IDs\n\
1855 Return list of supplemental group IDs for the process.";
1858 posix_getgroups(PyObject
*self
, PyObject
*args
)
1860 PyObject
*result
= NULL
;
1862 if (PyArg_ParseTuple(args
, ":getgroups")) {
1864 #define MAX_GROUPS NGROUPS_MAX
1866 /* defined to be 16 on Solaris7, so this should be a small number */
1867 #define MAX_GROUPS 64
1869 gid_t grouplist
[MAX_GROUPS
];
1872 n
= getgroups(MAX_GROUPS
, grouplist
);
1876 result
= PyList_New(n
);
1877 if (result
!= NULL
) {
1880 for (i
= 0; i
< n
; ++i
) {
1881 o
= PyInt_FromLong((long)grouplist
[i
]);
1887 PyList_SET_ITEM(result
, i
, o
);
1897 static char posix_getpgrp__doc__
[] =
1898 "getpgrp() -> pgrp\n\
1899 Return the current process group id.";
1902 posix_getpgrp(PyObject
*self
, PyObject
*args
)
1904 if (!PyArg_ParseTuple(args
, ":getpgrp"))
1906 #ifdef GETPGRP_HAVE_ARG
1907 return PyInt_FromLong((long)getpgrp(0));
1908 #else /* GETPGRP_HAVE_ARG */
1909 return PyInt_FromLong((long)getpgrp());
1910 #endif /* GETPGRP_HAVE_ARG */
1912 #endif /* HAVE_GETPGRP */
1916 static char posix_setpgrp__doc__
[] =
1917 "setpgrp() -> None\n\
1918 Make this process a session leader.";
1921 posix_setpgrp(PyObject
*self
, PyObject
*args
)
1923 if (!PyArg_ParseTuple(args
, ":setpgrp"))
1925 #ifdef SETPGRP_HAVE_ARG
1926 if (setpgrp(0, 0) < 0)
1927 #else /* SETPGRP_HAVE_ARG */
1929 #endif /* SETPGRP_HAVE_ARG */
1930 return posix_error();
1935 #endif /* HAVE_SETPGRP */
1938 static char posix_getppid__doc__
[] =
1939 "getppid() -> ppid\n\
1940 Return the parent's process id.";
1943 posix_getppid(PyObject
*self
, PyObject
*args
)
1945 if (!PyArg_ParseTuple(args
, ":getppid"))
1947 return PyInt_FromLong((long)getppid());
1952 #ifdef HAVE_GETLOGIN
1953 static char posix_getlogin__doc__
[] = "\
1954 getlogin() -> string\n\
1955 Return the actual login name.";
1958 posix_getlogin(PyObject
*self
, PyObject
*args
)
1960 PyObject
*result
= NULL
;
1962 if (PyArg_ParseTuple(args
, ":getlogin")) {
1964 int old_errno
= errno
;
1972 PyErr_SetString(PyExc_OSError
,
1973 "unable to determine login name");
1976 result
= PyString_FromString(name
);
1984 static char posix_getuid__doc__
[] =
1986 Return the current process's user id.";
1989 posix_getuid(PyObject
*self
, PyObject
*args
)
1991 if (!PyArg_ParseTuple(args
, ":getuid"))
1993 return PyInt_FromLong((long)getuid());
1999 static char posix_kill__doc__
[] =
2000 "kill(pid, sig) -> None\n\
2001 Kill a process with a signal.";
2004 posix_kill(PyObject
*self
, PyObject
*args
)
2007 if (!PyArg_ParseTuple(args
, "ii:kill", &pid
, &sig
))
2009 #if defined(PYOS_OS2)
2010 if (sig
== XCPT_SIGNAL_INTR
|| sig
== XCPT_SIGNAL_BREAK
) {
2012 if ((rc
= DosSendSignalException(pid
, sig
)) != NO_ERROR
)
2013 return os2_error(rc
);
2015 } else if (sig
== XCPT_SIGNAL_KILLPROC
) {
2017 if ((rc
= DosKillProcess(DKP_PROCESS
, pid
)) != NO_ERROR
)
2018 return os2_error(rc
);
2021 return NULL
; /* Unrecognized Signal Requested */
2023 if (kill(pid
, sig
) == -1)
2024 return posix_error();
2033 #ifdef HAVE_SYS_LOCK_H
2034 #include <sys/lock.h>
2037 static char posix_plock__doc__
[] =
2038 "plock(op) -> None\n\
2039 Lock program segments into memory.";
2042 posix_plock(PyObject
*self
, PyObject
*args
)
2045 if (!PyArg_ParseTuple(args
, "i:plock", &op
))
2047 if (plock(op
) == -1)
2048 return posix_error();
2056 static char posix_popen__doc__
[] =
2057 "popen(command [, mode='r' [, bufsize]]) -> pipe\n\
2058 Open a pipe to/from a command returning a file object.";
2060 #if defined(PYOS_OS2)
2062 async_system(const char *command
)
2064 char *p
, errormsg
[256], args
[1024];
2067 char *shell
= getenv("COMSPEC");
2071 strcpy(args
, shell
);
2072 p
= &args
[ strlen(args
)+1 ];
2078 rc
= DosExecPgm(errormsg
, sizeof(errormsg
),
2079 EXEC_ASYNC
, /* Execute Async w/o Wait for Results */
2081 NULL
, /* Inherit Parent's Environment */
2087 popen(const char *command
, const char *mode
, int pipesize
, int *err
)
2091 APIRET rc
= DosCreatePipe(&rhan
, &whan
, pipesize
);
2093 if (rc
!= NO_ERROR
) {
2095 return NULL
; /* ERROR - Unable to Create Anon Pipe */
2098 if (strchr(mode
, 'r') != NULL
) { /* Treat Command as a Data Source */
2099 int oldfd
= dup(1); /* Save STDOUT Handle in Another Handle */
2101 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2102 close(1); /* Make STDOUT Available for Reallocation */
2104 if (dup2(whan
, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
2105 DosClose(whan
); /* Close Now-Unused Pipe Write Handle */
2107 if (async_system(command
) == NO_ERROR
)
2108 retfd
= fdopen(rhan
, mode
); /* And Return Pipe Read Handle */
2111 dup2(oldfd
, 1); /* Reconnect STDOUT to Original Handle */
2112 DosExitCritSec(); /* Now Allow Other Threads to Run */
2114 close(oldfd
); /* And Close Saved STDOUT Handle */
2115 return retfd
; /* Return fd of Pipe or NULL if Error */
2117 } else if (strchr(mode
, 'w')) { /* Treat Command as a Data Sink */
2118 int oldfd
= dup(0); /* Save STDIN Handle in Another Handle */
2120 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
2121 close(0); /* Make STDIN Available for Reallocation */
2123 if (dup2(rhan
, 0) == 0) { /* Connect STDIN to Pipe Read Side */
2124 DosClose(rhan
); /* Close Now-Unused Pipe Read Handle */
2126 if (async_system(command
) == NO_ERROR
)
2127 retfd
= fdopen(whan
, mode
); /* And Return Pipe Write Handle */
2130 dup2(oldfd
, 0); /* Reconnect STDIN to Original Handle */
2131 DosExitCritSec(); /* Now Allow Other Threads to Run */
2133 close(oldfd
); /* And Close Saved STDIN Handle */
2134 return retfd
; /* Return fd of Pipe or NULL if Error */
2137 *err
= ERROR_INVALID_ACCESS
;
2138 return NULL
; /* ERROR - Invalid Mode (Neither Read nor Write) */
2143 posix_popen(PyObject
*self
, PyObject
*args
)
2147 int err
, bufsize
= -1;
2150 if (!PyArg_ParseTuple(args
, "s|si:popen", &name
, &mode
, &bufsize
))
2152 Py_BEGIN_ALLOW_THREADS
2153 fp
= popen(name
, mode
, (bufsize
> 0) ? bufsize
: 4096, &err
);
2154 Py_END_ALLOW_THREADS
2156 return os2_error(err
);
2158 f
= PyFile_FromFile(fp
, name
, mode
, fclose
);
2160 PyFile_SetBufSize(f
, bufsize
);
2164 #elif defined(MS_WIN32)
2167 * Portable 'popen' replacement for Win32.
2169 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
2170 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
2171 * Return code handling by David Bolen <db3l@fitlinxx.com>.
2178 /* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
2184 static PyObject
*_PyPopen(char *, int, int);
2185 static int _PyPclose(FILE *file
);
2188 * Internal dictionary mapping popen* file pointers to process handles,
2189 * for use when retrieving the process exit code. See _PyPclose() below
2190 * for more information on this dictionary's use.
2192 static PyObject
*_PyPopenProcs
= NULL
;
2195 /* popen that works from a GUI.
2197 * The result of this function is a pipe (file) connected to the
2198 * processes stdin or stdout, depending on the requested mode.
2202 posix_popen(PyObject
*self
, PyObject
*args
)
2210 if (!PyArg_ParseTuple(args
, "s|si:popen", &cmdstring
, &mode
, &bufsize
))
2217 else if (*mode
!= 'w') {
2218 PyErr_SetString(PyExc_ValueError
, "popen() arg 2 must be 'r' or 'w'");
2223 if (bufsize
!= -1) {
2224 PyErr_SetString(PyExc_ValueError
, "popen() arg 3 must be -1");
2228 if (*(mode
+1) == 't')
2229 f
= _PyPopen(cmdstring
, tm
| _O_TEXT
, POPEN_1
);
2230 else if (*(mode
+1) == 'b')
2231 f
= _PyPopen(cmdstring
, tm
| _O_BINARY
, POPEN_1
);
2233 f
= _PyPopen(cmdstring
, tm
| _O_TEXT
, POPEN_1
);
2238 /* Variation on win32pipe.popen
2240 * The result of this function is a pipe (file) connected to the
2241 * process's stdin, and a pipe connected to the process's stdout.
2245 win32_popen2(PyObject
*self
, PyObject
*args
)
2253 if (!PyArg_ParseTuple(args
, "s|si:popen2", &cmdstring
, &mode
, &bufsize
))
2258 else if (*mode
!= 'b') {
2259 PyErr_SetString(PyExc_ValueError
, "popen2() arg 2 must be 't' or 'b'");
2264 if (bufsize
!= -1) {
2265 PyErr_SetString(PyExc_ValueError
, "popen2() arg 3 must be -1");
2269 f
= _PyPopen(cmdstring
, tm
, POPEN_2
);
2275 * Variation on <om win32pipe.popen>
2277 * The result of this function is 3 pipes - the process's stdin,
2282 win32_popen3(PyObject
*self
, PyObject
*args
)
2290 if (!PyArg_ParseTuple(args
, "s|si:popen3", &cmdstring
, &mode
, &bufsize
))
2295 else if (*mode
!= 'b') {
2296 PyErr_SetString(PyExc_ValueError
, "popen3() arg 2 must be 't' or 'b'");
2301 if (bufsize
!= -1) {
2302 PyErr_SetString(PyExc_ValueError
, "popen3() arg 3 must be -1");
2306 f
= _PyPopen(cmdstring
, tm
, POPEN_3
);
2312 * Variation on win32pipe.popen
2314 * The result of this function is 2 pipes - the processes stdin,
2315 * and stdout+stderr combined as a single pipe.
2319 win32_popen4(PyObject
*self
, PyObject
*args
)
2327 if (!PyArg_ParseTuple(args
, "s|si:popen4", &cmdstring
, &mode
, &bufsize
))
2332 else if (*mode
!= 'b') {
2333 PyErr_SetString(PyExc_ValueError
, "popen4() arg 2 must be 't' or 'b'");
2338 if (bufsize
!= -1) {
2339 PyErr_SetString(PyExc_ValueError
, "popen4() arg 3 must be -1");
2343 f
= _PyPopen(cmdstring
, tm
, POPEN_4
);
2349 _PyPopenCreateProcess(char *cmdstring
,
2355 PROCESS_INFORMATION piProcInfo
;
2356 STARTUPINFO siStartInfo
;
2357 char *s1
,*s2
, *s3
= " /c ";
2358 const char *szConsoleSpawn
= "w9xpopen.exe";
2362 if (i
= GetEnvironmentVariable("COMSPEC",NULL
,0)) {
2363 s1
= (char *)_alloca(i
);
2364 if (!(x
= GetEnvironmentVariable("COMSPEC", s1
, i
)))
2366 if (GetVersion() < 0x80000000) {
2370 x
= i
+ strlen(s3
) + strlen(cmdstring
) + 1;
2371 s2
= (char *)_alloca(x
);
2373 sprintf(s2
, "%s%s%s", s1
, s3
, cmdstring
);
2377 * Oh gag, we're on Win9x. Use the workaround listed in
2380 char modulepath
[_MAX_PATH
];
2381 struct stat statinfo
;
2382 GetModuleFileName(NULL
, modulepath
, sizeof(modulepath
));
2383 for (i
= x
= 0; modulepath
[i
]; i
++)
2384 if (modulepath
[i
] == '\\')
2386 modulepath
[x
] = '\0';
2387 /* Create the full-name to w9xpopen, so we can test it exists */
2390 (sizeof(modulepath
)/sizeof(modulepath
[0]))
2391 -strlen(modulepath
));
2392 if (stat(modulepath
, &statinfo
) != 0) {
2393 /* Eeek - file-not-found - possibly an embedding
2394 situation - see if we can locate it in sys.prefix
2398 sizeof(modulepath
)/sizeof(modulepath
[0]));
2399 if (modulepath
[strlen(modulepath
)-1] != '\\')
2400 strcat(modulepath
, "\\");
2403 (sizeof(modulepath
)/sizeof(modulepath
[0]))
2404 -strlen(modulepath
));
2405 /* No where else to look - raise an easily identifiable
2406 error, rather than leaving Windows to report
2407 "file not found" - as the user is probably blissfully
2408 unaware this shim EXE is used, and it will confuse them.
2409 (well, it confused me for a while ;-)
2411 if (stat(modulepath
, &statinfo
) != 0) {
2412 PyErr_Format(PyExc_RuntimeError
,
2413 "Can not locate '%s' which is needed "
2414 "for popen to work on this platform.",
2419 x
= i
+ strlen(s3
) + strlen(cmdstring
) + 1 +
2420 strlen(modulepath
) +
2421 strlen(szConsoleSpawn
) + 1;
2423 s2
= (char *)_alloca(x
);
2435 /* Could be an else here to try cmd.exe / command.com in the path
2436 Now we'll just error out.. */
2438 PyErr_SetString(PyExc_RuntimeError
, "Can not locate a COMSPEC environment variable to use as the shell");
2442 ZeroMemory(&siStartInfo
, sizeof(STARTUPINFO
));
2443 siStartInfo
.cb
= sizeof(STARTUPINFO
);
2444 siStartInfo
.dwFlags
= STARTF_USESTDHANDLES
| STARTF_USESHOWWINDOW
;
2445 siStartInfo
.hStdInput
= hStdin
;
2446 siStartInfo
.hStdOutput
= hStdout
;
2447 siStartInfo
.hStdError
= hStderr
;
2448 siStartInfo
.wShowWindow
= SW_HIDE
;
2450 if (CreateProcess(NULL
,
2460 /* Close the handles now so anyone waiting is woken. */
2461 CloseHandle(piProcInfo
.hThread
);
2463 /* Return process handle */
2464 *hProcess
= piProcInfo
.hProcess
;
2467 win32_error("CreateProcess", NULL
);
2471 /* The following code is based off of KB: Q190351 */
2474 _PyPopen(char *cmdstring
, int mode
, int n
)
2476 HANDLE hChildStdinRd
, hChildStdinWr
, hChildStdoutRd
, hChildStdoutWr
,
2477 hChildStderrRd
, hChildStderrWr
, hChildStdinWrDup
, hChildStdoutRdDup
,
2478 hChildStderrRdDup
, hProcess
; /* hChildStdoutWrDup; */
2480 SECURITY_ATTRIBUTES saAttr
;
2487 saAttr
.nLength
= sizeof(SECURITY_ATTRIBUTES
);
2488 saAttr
.bInheritHandle
= TRUE
;
2489 saAttr
.lpSecurityDescriptor
= NULL
;
2491 if (!CreatePipe(&hChildStdinRd
, &hChildStdinWr
, &saAttr
, 0))
2492 return win32_error("CreatePipe", NULL
);
2494 /* Create new output read handle and the input write handle. Set
2495 * the inheritance properties to FALSE. Otherwise, the child inherits
2496 * the these handles; resulting in non-closeable handles to the pipes
2498 fSuccess
= DuplicateHandle(GetCurrentProcess(), hChildStdinWr
,
2499 GetCurrentProcess(), &hChildStdinWrDup
, 0,
2501 DUPLICATE_SAME_ACCESS
);
2503 return win32_error("DuplicateHandle", NULL
);
2505 /* Close the inheritable version of ChildStdin
2506 that we're using. */
2507 CloseHandle(hChildStdinWr
);
2509 if (!CreatePipe(&hChildStdoutRd
, &hChildStdoutWr
, &saAttr
, 0))
2510 return win32_error("CreatePipe", NULL
);
2512 fSuccess
= DuplicateHandle(GetCurrentProcess(), hChildStdoutRd
,
2513 GetCurrentProcess(), &hChildStdoutRdDup
, 0,
2514 FALSE
, DUPLICATE_SAME_ACCESS
);
2516 return win32_error("DuplicateHandle", NULL
);
2518 /* Close the inheritable version of ChildStdout
2519 that we're using. */
2520 CloseHandle(hChildStdoutRd
);
2523 if (!CreatePipe(&hChildStderrRd
, &hChildStderrWr
, &saAttr
, 0))
2524 return win32_error("CreatePipe", NULL
);
2525 fSuccess
= DuplicateHandle(GetCurrentProcess(),
2527 GetCurrentProcess(),
2528 &hChildStderrRdDup
, 0,
2529 FALSE
, DUPLICATE_SAME_ACCESS
);
2531 return win32_error("DuplicateHandle", NULL
);
2532 /* Close the inheritable version of ChildStdErr that we're using. */
2533 CloseHandle(hChildStderrRd
);
2538 switch (mode
& (_O_RDONLY
| _O_TEXT
| _O_BINARY
| _O_WRONLY
)) {
2539 case _O_WRONLY
| _O_TEXT
:
2540 /* Case for writing to child Stdin in text mode. */
2541 fd1
= _open_osfhandle((long)hChildStdinWrDup
, mode
);
2542 f1
= _fdopen(fd1
, "w");
2543 f
= PyFile_FromFile(f1
, cmdstring
, "w", _PyPclose
);
2544 PyFile_SetBufSize(f
, 0);
2545 /* We don't care about these pipes anymore, so close them. */
2546 CloseHandle(hChildStdoutRdDup
);
2547 CloseHandle(hChildStderrRdDup
);
2550 case _O_RDONLY
| _O_TEXT
:
2551 /* Case for reading from child Stdout in text mode. */
2552 fd1
= _open_osfhandle((long)hChildStdoutRdDup
, mode
);
2553 f1
= _fdopen(fd1
, "r");
2554 f
= PyFile_FromFile(f1
, cmdstring
, "r", _PyPclose
);
2555 PyFile_SetBufSize(f
, 0);
2556 /* We don't care about these pipes anymore, so close them. */
2557 CloseHandle(hChildStdinWrDup
);
2558 CloseHandle(hChildStderrRdDup
);
2561 case _O_RDONLY
| _O_BINARY
:
2562 /* Case for readinig from child Stdout in binary mode. */
2563 fd1
= _open_osfhandle((long)hChildStdoutRdDup
, mode
);
2564 f1
= _fdopen(fd1
, "rb");
2565 f
= PyFile_FromFile(f1
, cmdstring
, "rb", _PyPclose
);
2566 PyFile_SetBufSize(f
, 0);
2567 /* We don't care about these pipes anymore, so close them. */
2568 CloseHandle(hChildStdinWrDup
);
2569 CloseHandle(hChildStderrRdDup
);
2572 case _O_WRONLY
| _O_BINARY
:
2573 /* Case for writing to child Stdin in binary mode. */
2574 fd1
= _open_osfhandle((long)hChildStdinWrDup
, mode
);
2575 f1
= _fdopen(fd1
, "wb");
2576 f
= PyFile_FromFile(f1
, cmdstring
, "wb", _PyPclose
);
2577 PyFile_SetBufSize(f
, 0);
2578 /* We don't care about these pipes anymore, so close them. */
2579 CloseHandle(hChildStdoutRdDup
);
2580 CloseHandle(hChildStderrRdDup
);
2592 if (mode
&& _O_TEXT
) {
2600 fd1
= _open_osfhandle((long)hChildStdinWrDup
, mode
);
2601 f1
= _fdopen(fd1
, m2
);
2602 fd2
= _open_osfhandle((long)hChildStdoutRdDup
, mode
);
2603 f2
= _fdopen(fd2
, m1
);
2604 p1
= PyFile_FromFile(f1
, cmdstring
, m2
, _PyPclose
);
2605 PyFile_SetBufSize(p1
, 0);
2606 p2
= PyFile_FromFile(f2
, cmdstring
, m1
, _PyPclose
);
2607 PyFile_SetBufSize(p2
, 0);
2610 CloseHandle(hChildStderrRdDup
);
2612 f
= Py_BuildValue("OO",p1
,p2
);
2622 PyObject
*p1
, *p2
, *p3
;
2624 if (mode
&& _O_TEXT
) {
2632 fd1
= _open_osfhandle((long)hChildStdinWrDup
, mode
);
2633 f1
= _fdopen(fd1
, m2
);
2634 fd2
= _open_osfhandle((long)hChildStdoutRdDup
, mode
);
2635 f2
= _fdopen(fd2
, m1
);
2636 fd3
= _open_osfhandle((long)hChildStderrRdDup
, mode
);
2637 f3
= _fdopen(fd3
, m1
);
2638 p1
= PyFile_FromFile(f1
, cmdstring
, m2
, _PyPclose
);
2639 p2
= PyFile_FromFile(f2
, cmdstring
, m1
, _PyPclose
);
2640 p3
= PyFile_FromFile(f3
, cmdstring
, m1
, _PyPclose
);
2641 PyFile_SetBufSize(p1
, 0);
2642 PyFile_SetBufSize(p2
, 0);
2643 PyFile_SetBufSize(p3
, 0);
2644 f
= Py_BuildValue("OOO",p1
,p2
,p3
);
2654 if (!_PyPopenCreateProcess(cmdstring
,
2662 if (!_PyPopenCreateProcess(cmdstring
,
2671 * Insert the files we've created into the process dictionary
2672 * all referencing the list with the process handle and the
2673 * initial number of files (see description below in _PyPclose).
2674 * Since if _PyPclose later tried to wait on a process when all
2675 * handles weren't closed, it could create a deadlock with the
2676 * child, we spend some energy here to try to ensure that we
2677 * either insert all file handles into the dictionary or none
2678 * at all. It's a little clumsy with the various popen modes
2679 * and variable number of files involved.
2681 if (!_PyPopenProcs
) {
2682 _PyPopenProcs
= PyDict_New();
2685 if (_PyPopenProcs
) {
2686 PyObject
*procObj
, *hProcessObj
, *intObj
, *fileObj
[3];
2689 fileObj
[0] = fileObj
[1] = fileObj
[2] = NULL
;
2690 ins_rc
[0] = ins_rc
[1] = ins_rc
[2] = 0;
2692 procObj
= PyList_New(2);
2693 hProcessObj
= PyLong_FromVoidPtr(hProcess
);
2694 intObj
= PyInt_FromLong(file_count
);
2696 if (procObj
&& hProcessObj
&& intObj
) {
2697 PyList_SetItem(procObj
,0,hProcessObj
);
2698 PyList_SetItem(procObj
,1,intObj
);
2700 fileObj
[0] = PyLong_FromVoidPtr(f1
);
2702 ins_rc
[0] = PyDict_SetItem(_PyPopenProcs
,
2706 if (file_count
>= 2) {
2707 fileObj
[1] = PyLong_FromVoidPtr(f2
);
2709 ins_rc
[1] = PyDict_SetItem(_PyPopenProcs
,
2714 if (file_count
>= 3) {
2715 fileObj
[2] = PyLong_FromVoidPtr(f3
);
2717 ins_rc
[2] = PyDict_SetItem(_PyPopenProcs
,
2723 if (ins_rc
[0] < 0 || !fileObj
[0] ||
2724 ins_rc
[1] < 0 || (file_count
> 1 && !fileObj
[1]) ||
2725 ins_rc
[2] < 0 || (file_count
> 2 && !fileObj
[2])) {
2726 /* Something failed - remove any dictionary
2727 * entries that did make it.
2729 if (!ins_rc
[0] && fileObj
[0]) {
2730 PyDict_DelItem(_PyPopenProcs
,
2733 if (!ins_rc
[1] && fileObj
[1]) {
2734 PyDict_DelItem(_PyPopenProcs
,
2737 if (!ins_rc
[2] && fileObj
[2]) {
2738 PyDict_DelItem(_PyPopenProcs
,
2745 * Clean up our localized references for the dictionary keys
2746 * and value since PyDict_SetItem will Py_INCREF any copies
2747 * that got placed in the dictionary.
2749 Py_XDECREF(procObj
);
2750 Py_XDECREF(fileObj
[0]);
2751 Py_XDECREF(fileObj
[1]);
2752 Py_XDECREF(fileObj
[2]);
2755 /* Child is launched. Close the parents copy of those pipe
2756 * handles that only the child should have open. You need to
2757 * make sure that no handles to the write end of the output pipe
2758 * are maintained in this process or else the pipe will not close
2759 * when the child process exits and the ReadFile will hang. */
2761 if (!CloseHandle(hChildStdinRd
))
2762 return win32_error("CloseHandle", NULL
);
2764 if (!CloseHandle(hChildStdoutWr
))
2765 return win32_error("CloseHandle", NULL
);
2767 if ((n
!= 4) && (!CloseHandle(hChildStderrWr
)))
2768 return win32_error("CloseHandle", NULL
);
2774 * Wrapper for fclose() to use for popen* files, so we can retrieve the
2775 * exit code for the child process and return as a result of the close.
2777 * This function uses the _PyPopenProcs dictionary in order to map the
2778 * input file pointer to information about the process that was
2779 * originally created by the popen* call that created the file pointer.
2780 * The dictionary uses the file pointer as a key (with one entry
2781 * inserted for each file returned by the original popen* call) and a
2782 * single list object as the value for all files from a single call.
2783 * The list object contains the Win32 process handle at [0], and a file
2784 * count at [1], which is initialized to the total number of file
2785 * handles using that list.
2787 * This function closes whichever handle it is passed, and decrements
2788 * the file count in the dictionary for the process handle pointed to
2789 * by this file. On the last close (when the file count reaches zero),
2790 * this function will wait for the child process and then return its
2791 * exit code as the result of the close() operation. This permits the
2792 * files to be closed in any order - it is always the close() of the
2793 * final handle that will return the exit code.
2796 /* RED_FLAG 31-Aug-2000 Tim
2797 * This is always called (today!) between a pair of
2798 * Py_BEGIN_ALLOW_THREADS/ Py_END_ALLOW_THREADS
2799 * macros. So the thread running this has no valid thread state, as
2800 * far as Python is concerned. However, this calls some Python API
2801 * functions that cannot be called safely without a valid thread
2802 * state, in particular PyDict_GetItem.
2803 * As a temporary hack (although it may last for years ...), we
2804 * *rely* on not having a valid thread state in this function, in
2805 * order to create our own "from scratch".
2806 * This will deadlock if _PyPclose is ever called by a thread
2807 * holding the global lock.
2810 static int _PyPclose(FILE *file
)
2815 PyObject
*procObj
, *hProcessObj
, *intObj
, *fileObj
;
2818 PyInterpreterState
* pInterpreterState
;
2819 PyThreadState
* pThreadState
;
2822 /* Close the file handle first, to ensure it can't block the
2823 * child from exiting if it's the last handle.
2825 result
= fclose(file
);
2828 /* Bootstrap a valid thread state into existence. */
2829 pInterpreterState
= PyInterpreterState_New();
2830 if (!pInterpreterState
) {
2831 /* Well, we're hosed now! We don't have a thread
2832 * state, so can't call a nice error routine, or raise
2833 * an exception. Just die.
2835 Py_FatalError("unable to allocate interpreter state "
2836 "when closing popen object");
2837 return -1; /* unreachable */
2839 pThreadState
= PyThreadState_New(pInterpreterState
);
2840 if (!pThreadState
) {
2841 Py_FatalError("unable to allocate thread state "
2842 "when closing popen object");
2843 return -1; /* unreachable */
2845 /* Grab the global lock. Note that this will deadlock if the
2846 * current thread already has the lock! (see RED_FLAG comments
2847 * before this function)
2849 PyEval_RestoreThread(pThreadState
);
2852 if (_PyPopenProcs
) {
2853 if ((fileObj
= PyLong_FromVoidPtr(file
)) != NULL
&&
2854 (procObj
= PyDict_GetItem(_PyPopenProcs
,
2855 fileObj
)) != NULL
&&
2856 (hProcessObj
= PyList_GetItem(procObj
,0)) != NULL
&&
2857 (intObj
= PyList_GetItem(procObj
,1)) != NULL
) {
2859 hProcess
= PyLong_AsVoidPtr(hProcessObj
);
2860 file_count
= PyInt_AsLong(intObj
);
2862 if (file_count
> 1) {
2863 /* Still other files referencing process */
2865 PyList_SetItem(procObj
,1,
2866 PyInt_FromLong(file_count
));
2868 /* Last file for this process */
2869 if (result
!= EOF
&&
2870 WaitForSingleObject(hProcess
, INFINITE
) != WAIT_FAILED
&&
2871 GetExitCodeProcess(hProcess
, &exit_code
)) {
2872 /* Possible truncation here in 16-bit environments, but
2873 * real exit codes are just the lower byte in any event.
2877 /* Indicate failure - this will cause the file object
2878 * to raise an I/O error and translate the last Win32
2879 * error code from errno. We do have a problem with
2880 * last errors that overlap the normal errno table,
2881 * but that's a consistent problem with the file object.
2883 if (result
!= EOF
) {
2884 /* If the error wasn't from the fclose(), then
2885 * set errno for the file object error handling.
2887 errno
= GetLastError();
2892 /* Free up the native handle at this point */
2893 CloseHandle(hProcess
);
2896 /* Remove this file pointer from dictionary */
2897 PyDict_DelItem(_PyPopenProcs
, fileObj
);
2899 if (PyDict_Size(_PyPopenProcs
) == 0) {
2900 Py_DECREF(_PyPopenProcs
);
2901 _PyPopenProcs
= NULL
;
2904 } /* if object retrieval ok */
2906 Py_XDECREF(fileObj
);
2907 } /* if _PyPopenProcs */
2910 /* Tear down the thread & interpreter states.
2911 * Note that interpreter state clear & delete functions automatically
2912 * call the thread clear & delete functions, and indeed insist on
2913 * doing that themselves. The lock must be held during the clear, but
2914 * need not be held during the delete.
2916 PyInterpreterState_Clear(pInterpreterState
);
2917 PyEval_ReleaseThread(pThreadState
);
2918 PyInterpreterState_Delete(pInterpreterState
);
2924 #else /* which OS? */
2926 posix_popen(PyObject
*self
, PyObject
*args
)
2933 if (!PyArg_ParseTuple(args
, "s|si:popen", &name
, &mode
, &bufsize
))
2935 Py_BEGIN_ALLOW_THREADS
2936 fp
= popen(name
, mode
);
2937 Py_END_ALLOW_THREADS
2939 return posix_error();
2940 f
= PyFile_FromFile(fp
, name
, mode
, pclose
);
2942 PyFile_SetBufSize(f
, bufsize
);
2947 #endif /* HAVE_POPEN */
2951 static char posix_setuid__doc__
[] =
2952 "setuid(uid) -> None\n\
2953 Set the current process's user id.";
2955 posix_setuid(PyObject
*self
, PyObject
*args
)
2958 if (!PyArg_ParseTuple(args
, "i:setuid", &uid
))
2960 if (setuid(uid
) < 0)
2961 return posix_error();
2965 #endif /* HAVE_SETUID */
2969 static char posix_seteuid__doc__
[] =
2970 "seteuid(uid) -> None\n\
2971 Set the current process's effective user id.";
2973 posix_seteuid (PyObject
*self
, PyObject
*args
)
2976 if (!PyArg_ParseTuple(args
, "i", &euid
)) {
2978 } else if (seteuid(euid
) < 0) {
2979 return posix_error();
2985 #endif /* HAVE_SETEUID */
2988 static char posix_setegid__doc__
[] =
2989 "setegid(gid) -> None\n\
2990 Set the current process's effective group id.";
2992 posix_setegid (PyObject
*self
, PyObject
*args
)
2995 if (!PyArg_ParseTuple(args
, "i", &egid
)) {
2997 } else if (setegid(egid
) < 0) {
2998 return posix_error();
3004 #endif /* HAVE_SETEGID */
3006 #ifdef HAVE_SETREUID
3007 static char posix_setreuid__doc__
[] =
3008 "seteuid(ruid, euid) -> None\n\
3009 Set the current process's real and effective user ids.";
3011 posix_setreuid (PyObject
*self
, PyObject
*args
)
3014 if (!PyArg_ParseTuple(args
, "ii", &ruid
, &euid
)) {
3016 } else if (setreuid(ruid
, euid
) < 0) {
3017 return posix_error();
3023 #endif /* HAVE_SETREUID */
3025 #ifdef HAVE_SETREGID
3026 static char posix_setregid__doc__
[] =
3027 "setegid(rgid, egid) -> None\n\
3028 Set the current process's real and effective group ids.";
3030 posix_setregid (PyObject
*self
, PyObject
*args
)
3033 if (!PyArg_ParseTuple(args
, "ii", &rgid
, &egid
)) {
3035 } else if (setregid(rgid
, egid
) < 0) {
3036 return posix_error();
3042 #endif /* HAVE_SETREGID */
3045 static char posix_setgid__doc__
[] =
3046 "setgid(gid) -> None\n\
3047 Set the current process's group id.";
3050 posix_setgid(PyObject
*self
, PyObject
*args
)
3053 if (!PyArg_ParseTuple(args
, "i:setgid", &gid
))
3055 if (setgid(gid
) < 0)
3056 return posix_error();
3060 #endif /* HAVE_SETGID */
3064 static char posix_waitpid__doc__
[] =
3065 "waitpid(pid, options) -> (pid, status)\n\
3066 Wait for completion of a given child process.";
3069 posix_waitpid(PyObject
*self
, PyObject
*args
)
3074 #define status_i (status.w_status)
3077 #define status_i status
3081 if (!PyArg_ParseTuple(args
, "ii:waitpid", &pid
, &options
))
3083 Py_BEGIN_ALLOW_THREADS
3085 pid
= wait4(pid
, &status
, options
, NULL
);
3087 pid
= waitpid(pid
, &status
, options
);
3089 Py_END_ALLOW_THREADS
3091 return posix_error();
3093 return Py_BuildValue("ii", pid
, status_i
);
3095 #endif /* HAVE_WAITPID */
3099 static char posix_wait__doc__
[] =
3100 "wait() -> (pid, status)\n\
3101 Wait for completion of a child process.";
3104 posix_wait(PyObject
*self
, PyObject
*args
)
3109 #define status_i (status.w_status)
3112 #define status_i status
3114 if (!PyArg_ParseTuple(args
, ":wait"))
3117 Py_BEGIN_ALLOW_THREADS
3118 pid
= wait(&status
);
3119 Py_END_ALLOW_THREADS
3121 return posix_error();
3123 return Py_BuildValue("ii", pid
, status_i
);
3129 static char posix_lstat__doc__
[] =
3130 "lstat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
3131 Like stat(path), but do not follow symbolic links.";
3134 posix_lstat(PyObject
*self
, PyObject
*args
)
3137 return posix_do_stat(self
, args
, "s:lstat", lstat
);
3138 #else /* !HAVE_LSTAT */
3139 return posix_do_stat(self
, args
, "s:lstat", STAT
);
3140 #endif /* !HAVE_LSTAT */
3144 #ifdef HAVE_READLINK
3145 static char posix_readlink__doc__
[] =
3146 "readlink(path) -> path\n\
3147 Return a string representing the path to which the symbolic link points.";
3150 posix_readlink(PyObject
*self
, PyObject
*args
)
3152 char buf
[MAXPATHLEN
];
3155 if (!PyArg_ParseTuple(args
, "s:readlink", &path
))
3157 Py_BEGIN_ALLOW_THREADS
3158 n
= readlink(path
, buf
, (int) sizeof buf
);
3159 Py_END_ALLOW_THREADS
3161 return posix_error_with_filename(path
);
3162 return PyString_FromStringAndSize(buf
, n
);
3164 #endif /* HAVE_READLINK */
3168 static char posix_symlink__doc__
[] =
3169 "symlink(src, dst) -> None\n\
3170 Create a symbolic link.";
3173 posix_symlink(PyObject
*self
, PyObject
*args
)
3175 return posix_2str(args
, "ss:symlink", symlink
);
3177 #endif /* HAVE_SYMLINK */
3182 #define HZ 60 /* Universal constant :-) */
3185 #if defined(PYCC_VACPP) && defined(PYOS_OS2)
3191 Py_BEGIN_ALLOW_THREADS
3192 DosQuerySysInfo(QSV_MS_COUNT
, QSV_MS_COUNT
, &value
, sizeof(value
));
3193 Py_END_ALLOW_THREADS
3199 posix_times(PyObject
*self
, PyObject
*args
)
3201 if (!PyArg_ParseTuple(args
, ":times"))
3204 /* Currently Only Uptime is Provided -- Others Later */
3205 return Py_BuildValue("ddddd",
3206 (double)0 /* t.tms_utime / HZ */,
3207 (double)0 /* t.tms_stime / HZ */,
3208 (double)0 /* t.tms_cutime / HZ */,
3209 (double)0 /* t.tms_cstime / HZ */,
3210 (double)system_uptime() / 1000);
3214 posix_times(PyObject
*self
, PyObject
*args
)
3218 if (!PyArg_ParseTuple(args
, ":times"))
3222 if (c
== (clock_t) -1)
3223 return posix_error();
3224 return Py_BuildValue("ddddd",
3225 (double)t
.tms_utime
/ HZ
,
3226 (double)t
.tms_stime
/ HZ
,
3227 (double)t
.tms_cutime
/ HZ
,
3228 (double)t
.tms_cstime
/ HZ
,
3231 #endif /* not OS2 */
3232 #endif /* HAVE_TIMES */
3236 #define HAVE_TIMES /* so the method table will pick it up */
3238 posix_times(PyObject
*self
, PyObject
*args
)
3240 FILETIME create
, exit
, kernel
, user
;
3242 if (!PyArg_ParseTuple(args
, ":times"))
3244 hProc
= GetCurrentProcess();
3245 GetProcessTimes(hProc
, &create
, &exit
, &kernel
, &user
);
3246 /* The fields of a FILETIME structure are the hi and lo part
3247 of a 64-bit value expressed in 100 nanosecond units.
3248 1e7 is one second in such units; 1e-7 the inverse.
3249 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
3251 return Py_BuildValue(
3253 (double)(kernel
.dwHighDateTime
*429.4967296 +
3254 kernel
.dwLowDateTime
*1e-7),
3255 (double)(user
.dwHighDateTime
*429.4967296 +
3256 user
.dwLowDateTime
*1e-7),
3261 #endif /* MS_WIN32 */
3264 static char posix_times__doc__
[] =
3265 "times() -> (utime, stime, cutime, cstime, elapsed_time)\n\
3266 Return a tuple of floating point numbers indicating process times.";
3271 static char posix_setsid__doc__
[] =
3272 "setsid() -> None\n\
3273 Call the system call setsid().";
3276 posix_setsid(PyObject
*self
, PyObject
*args
)
3278 if (!PyArg_ParseTuple(args
, ":setsid"))
3281 return posix_error();
3285 #endif /* HAVE_SETSID */
3288 static char posix_setpgid__doc__
[] =
3289 "setpgid(pid, pgrp) -> None\n\
3290 Call the system call setpgid().";
3293 posix_setpgid(PyObject
*self
, PyObject
*args
)
3296 if (!PyArg_ParseTuple(args
, "ii:setpgid", &pid
, &pgrp
))
3298 if (setpgid(pid
, pgrp
) < 0)
3299 return posix_error();
3303 #endif /* HAVE_SETPGID */
3306 #ifdef HAVE_TCGETPGRP
3307 static char posix_tcgetpgrp__doc__
[] =
3308 "tcgetpgrp(fd) -> pgid\n\
3309 Return the process group associated with the terminal given by a fd.";
3312 posix_tcgetpgrp(PyObject
*self
, PyObject
*args
)
3315 if (!PyArg_ParseTuple(args
, "i:tcgetpgrp", &fd
))
3317 pgid
= tcgetpgrp(fd
);
3319 return posix_error();
3320 return PyInt_FromLong((long)pgid
);
3322 #endif /* HAVE_TCGETPGRP */
3325 #ifdef HAVE_TCSETPGRP
3326 static char posix_tcsetpgrp__doc__
[] =
3327 "tcsetpgrp(fd, pgid) -> None\n\
3328 Set the process group associated with the terminal given by a fd.";
3331 posix_tcsetpgrp(PyObject
*self
, PyObject
*args
)
3334 if (!PyArg_ParseTuple(args
, "ii:tcsetpgrp", &fd
, &pgid
))
3336 if (tcsetpgrp(fd
, pgid
) < 0)
3337 return posix_error();
3341 #endif /* HAVE_TCSETPGRP */
3343 /* Functions acting on file descriptors */
3345 static char posix_open__doc__
[] =
3346 "open(filename, flag [, mode=0777]) -> fd\n\
3347 Open a file (for low level IO).";
3350 posix_open(PyObject
*self
, PyObject
*args
)
3356 if (!PyArg_ParseTuple(args
, "si|i", &file
, &flag
, &mode
))
3359 Py_BEGIN_ALLOW_THREADS
3360 fd
= open(file
, flag
, mode
);
3361 Py_END_ALLOW_THREADS
3363 return posix_error_with_filename(file
);
3364 return PyInt_FromLong((long)fd
);
3368 static char posix_close__doc__
[] =
3369 "close(fd) -> None\n\
3370 Close a file descriptor (for low level IO).";
3373 posix_close(PyObject
*self
, PyObject
*args
)
3376 if (!PyArg_ParseTuple(args
, "i:close", &fd
))
3378 Py_BEGIN_ALLOW_THREADS
3380 Py_END_ALLOW_THREADS
3382 return posix_error();
3388 static char posix_dup__doc__
[] =
3390 Return a duplicate of a file descriptor.";
3393 posix_dup(PyObject
*self
, PyObject
*args
)
3396 if (!PyArg_ParseTuple(args
, "i:dup", &fd
))
3398 Py_BEGIN_ALLOW_THREADS
3400 Py_END_ALLOW_THREADS
3402 return posix_error();
3403 return PyInt_FromLong((long)fd
);
3407 static char posix_dup2__doc__
[] =
3408 "dup2(fd, fd2) -> None\n\
3409 Duplicate file descriptor.";
3412 posix_dup2(PyObject
*self
, PyObject
*args
)
3415 if (!PyArg_ParseTuple(args
, "ii:dup2", &fd
, &fd2
))
3417 Py_BEGIN_ALLOW_THREADS
3418 res
= dup2(fd
, fd2
);
3419 Py_END_ALLOW_THREADS
3421 return posix_error();
3427 static char posix_lseek__doc__
[] =
3428 "lseek(fd, pos, how) -> newpos\n\
3429 Set the current position of a file descriptor.";
3432 posix_lseek(PyObject
*self
, PyObject
*args
)
3441 if (!PyArg_ParseTuple(args
, "iOi:lseek", &fd
, &posobj
, &how
))
3444 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
3446 case 0: how
= SEEK_SET
; break;
3447 case 1: how
= SEEK_CUR
; break;
3448 case 2: how
= SEEK_END
; break;
3450 #endif /* SEEK_END */
3452 #if !defined(HAVE_LARGEFILE_SUPPORT)
3453 pos
= PyInt_AsLong(posobj
);
3455 pos
= PyLong_Check(posobj
) ?
3456 PyLong_AsLongLong(posobj
) : PyInt_AsLong(posobj
);
3458 if (PyErr_Occurred())
3461 Py_BEGIN_ALLOW_THREADS
3463 res
= _lseeki64(fd
, pos
, how
);
3465 res
= lseek(fd
, pos
, how
);
3467 Py_END_ALLOW_THREADS
3469 return posix_error();
3471 #if !defined(HAVE_LARGEFILE_SUPPORT)
3472 return PyInt_FromLong(res
);
3474 return PyLong_FromLongLong(res
);
3479 static char posix_read__doc__
[] =
3480 "read(fd, buffersize) -> string\n\
3481 Read a file descriptor.";
3484 posix_read(PyObject
*self
, PyObject
*args
)
3488 if (!PyArg_ParseTuple(args
, "ii:read", &fd
, &size
))
3490 buffer
= PyString_FromStringAndSize((char *)NULL
, size
);
3493 Py_BEGIN_ALLOW_THREADS
3494 n
= read(fd
, PyString_AsString(buffer
), size
);
3495 Py_END_ALLOW_THREADS
3498 return posix_error();
3501 _PyString_Resize(&buffer
, n
);
3506 static char posix_write__doc__
[] =
3507 "write(fd, string) -> byteswritten\n\
3508 Write a string to a file descriptor.";
3511 posix_write(PyObject
*self
, PyObject
*args
)
3515 if (!PyArg_ParseTuple(args
, "is#:write", &fd
, &buffer
, &size
))
3517 Py_BEGIN_ALLOW_THREADS
3518 size
= write(fd
, buffer
, size
);
3519 Py_END_ALLOW_THREADS
3521 return posix_error();
3522 return PyInt_FromLong((long)size
);
3526 static char posix_fstat__doc__
[]=
3527 "fstat(fd) -> (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
3528 Like stat(), but for an open file descriptor.";
3531 posix_fstat(PyObject
*self
, PyObject
*args
)
3536 if (!PyArg_ParseTuple(args
, "i:fstat", &fd
))
3538 Py_BEGIN_ALLOW_THREADS
3539 res
= FSTAT(fd
, &st
);
3540 Py_END_ALLOW_THREADS
3542 return posix_error();
3544 return _pystat_fromstructstat(st
);
3548 static char posix_fdopen__doc__
[] =
3549 "fdopen(fd, [, mode='r' [, bufsize]]) -> file_object\n\
3550 Return an open file object connected to a file descriptor.";
3553 posix_fdopen(PyObject
*self
, PyObject
*args
)
3560 if (!PyArg_ParseTuple(args
, "i|si", &fd
, &mode
, &bufsize
))
3563 Py_BEGIN_ALLOW_THREADS
3564 fp
= fdopen(fd
, mode
);
3565 Py_END_ALLOW_THREADS
3567 return posix_error();
3568 f
= PyFile_FromFile(fp
, "(fdopen)", mode
, fclose
);
3570 PyFile_SetBufSize(f
, bufsize
);
3574 static char posix_isatty__doc__
[] =
3575 "isatty(fd) -> Boolean\n\
3576 Return true if the file descriptor 'fd' is an open file descriptor\n\
3577 connected to the slave end of a terminal.";
3580 posix_isatty(PyObject
*self
, PyObject
*args
)
3583 if (!PyArg_ParseTuple(args
, "i:isatty", &fd
))
3585 return Py_BuildValue("i", isatty(fd
));
3589 static char posix_pipe__doc__
[] =
3590 "pipe() -> (read_end, write_end)\n\
3594 posix_pipe(PyObject
*self
, PyObject
*args
)
3596 #if defined(PYOS_OS2)
3600 if (!PyArg_ParseTuple(args
, ":pipe"))
3603 Py_BEGIN_ALLOW_THREADS
3604 rc
= DosCreatePipe( &read
, &write
, 4096);
3605 Py_END_ALLOW_THREADS
3607 return os2_error(rc
);
3609 return Py_BuildValue("(ii)", read
, write
);
3611 #if !defined(MS_WIN32)
3614 if (!PyArg_ParseTuple(args
, ":pipe"))
3616 Py_BEGIN_ALLOW_THREADS
3618 Py_END_ALLOW_THREADS
3620 return posix_error();
3621 return Py_BuildValue("(ii)", fds
[0], fds
[1]);
3622 #else /* MS_WIN32 */
3624 int read_fd
, write_fd
;
3626 if (!PyArg_ParseTuple(args
, ":pipe"))
3628 Py_BEGIN_ALLOW_THREADS
3629 ok
= CreatePipe(&read
, &write
, NULL
, 0);
3630 Py_END_ALLOW_THREADS
3632 return win32_error("CreatePipe", NULL
);
3633 read_fd
= _open_osfhandle((intptr_t)read
, 0);
3634 write_fd
= _open_osfhandle((intptr_t)write
, 1);
3635 return Py_BuildValue("(ii)", read_fd
, write_fd
);
3636 #endif /* MS_WIN32 */
3639 #endif /* HAVE_PIPE */
3643 static char posix_mkfifo__doc__
[] =
3644 "mkfifo(file, [, mode=0666]) -> None\n\
3645 Create a FIFO (a POSIX named pipe).";
3648 posix_mkfifo(PyObject
*self
, PyObject
*args
)
3653 if (!PyArg_ParseTuple(args
, "s|i:mkfifo", &file
, &mode
))
3655 Py_BEGIN_ALLOW_THREADS
3656 res
= mkfifo(file
, mode
);
3657 Py_END_ALLOW_THREADS
3659 return posix_error();
3666 #ifdef HAVE_FTRUNCATE
3667 static char posix_ftruncate__doc__
[] =
3668 "ftruncate(fd, length) -> None\n\
3669 Truncate a file to a specified length.";
3672 posix_ftruncate(PyObject
*self
, PyObject
*args
)
3679 if (!PyArg_ParseTuple(args
, "iO:ftruncate", &fd
, &lenobj
))
3682 #if !defined(HAVE_LARGEFILE_SUPPORT)
3683 length
= PyInt_AsLong(lenobj
);
3685 length
= PyLong_Check(lenobj
) ?
3686 PyLong_AsLongLong(lenobj
) : PyInt_AsLong(lenobj
);
3688 if (PyErr_Occurred())
3691 Py_BEGIN_ALLOW_THREADS
3692 res
= ftruncate(fd
, length
);
3693 Py_END_ALLOW_THREADS
3695 PyErr_SetFromErrno(PyExc_IOError
);
3705 /* Steve Spicklemire got this putenv from NeXTAnswers */
3707 putenv(char *newval
)
3709 extern char **environ
;
3711 static int firstTime
= 1;
3717 if (!(np
= strchr(newval
, '=')))
3722 for (ep
=environ
; *ep
; ep
++)
3724 /* this should always be true... */
3725 if (cp
= strchr(*ep
, '='))
3728 if (!strcmp(*ep
, newval
))
3746 /* the string was already there:
3747 just replace it with the new one */
3752 /* expand environ by one */
3753 for (esiz
=2, ep
=environ
; *ep
; ep
++)
3759 if (!(newenv
= malloc(esiz
* sizeof(char *))))
3762 for (ep
=environ
, epp
=newenv
; *ep
;)
3770 if (!(environ
= realloc(environ
, esiz
* sizeof(char *))))
3772 environ
[esiz
- 2] = newval
;
3773 environ
[esiz
- 1] = (char *) 0;
3783 static char posix_putenv__doc__
[] =
3784 "putenv(key, value) -> None\n\
3785 Change or add an environment variable.";
3787 /* Save putenv() parameters as values here, so we can collect them when they
3788 * get re-set with another call for the same key. */
3789 static PyObject
*posix_putenv_garbage
;
3792 posix_putenv(PyObject
*self
, PyObject
*args
)
3798 if (!PyArg_ParseTuple(args
, "ss:putenv", &s1
, &s2
))
3801 #if defined(PYOS_OS2)
3802 if (stricmp(s1
, "BEGINLIBPATH") == 0) {
3805 if (strlen(s2
) == 0) /* If New Value is an Empty String */
3806 s2
= NULL
; /* Then OS/2 API Wants a NULL to Undefine It */
3808 rc
= DosSetExtLIBPATH(s2
, BEGIN_LIBPATH
);
3810 return os2_error(rc
);
3812 } else if (stricmp(s1
, "ENDLIBPATH") == 0) {
3815 if (strlen(s2
) == 0) /* If New Value is an Empty String */
3816 s2
= NULL
; /* Then OS/2 API Wants a NULL to Undefine It */
3818 rc
= DosSetExtLIBPATH(s2
, END_LIBPATH
);
3820 return os2_error(rc
);
3824 /* XXX This can leak memory -- not easy to fix :-( */
3825 newstr
= PyString_FromStringAndSize(NULL
, strlen(s1
) + strlen(s2
) + 2);
3827 return PyErr_NoMemory();
3828 new = PyString_AS_STRING(newstr
);
3829 (void) sprintf(new, "%s=%s", s1
, s2
);
3834 /* Install the first arg and newstr in posix_putenv_garbage;
3835 * this will cause previous value to be collected. This has to
3836 * happen after the real putenv() call because the old value
3837 * was still accessible until then. */
3838 if (PyDict_SetItem(posix_putenv_garbage
,
3839 PyTuple_GET_ITEM(args
, 0), newstr
)) {
3840 /* really not much we can do; just leak */
3847 #if defined(PYOS_OS2)
3855 #ifdef HAVE_STRERROR
3856 static char posix_strerror__doc__
[] =
3857 "strerror(code) -> string\n\
3858 Translate an error code to a message string.";
3861 posix_strerror(PyObject
*self
, PyObject
*args
)
3865 if (!PyArg_ParseTuple(args
, "i:strerror", &code
))
3867 message
= strerror(code
);
3868 if (message
== NULL
) {
3869 PyErr_SetString(PyExc_ValueError
,
3870 "strerror() argument out of range");
3873 return PyString_FromString(message
);
3875 #endif /* strerror */
3878 #ifdef HAVE_SYS_WAIT_H
3881 static char posix_WIFSTOPPED__doc__
[] =
3882 "WIFSTOPPED(status) -> Boolean\n\
3883 Return true if the process returning 'status' was stopped.";
3886 posix_WIFSTOPPED(PyObject
*self
, PyObject
*args
)
3890 #define status_i (status.w_status)
3893 #define status_i status
3897 if (!PyArg_ParseTuple(args
, "i:WIFSTOPPED", &status_i
))
3902 return Py_BuildValue("i", WIFSTOPPED(status
));
3905 #endif /* WIFSTOPPED */
3908 static char posix_WIFSIGNALED__doc__
[] =
3909 "WIFSIGNALED(status) -> Boolean\n\
3910 Return true if the process returning 'status' was terminated by a signal.";
3913 posix_WIFSIGNALED(PyObject
*self
, PyObject
*args
)
3917 #define status_i (status.w_status)
3920 #define status_i status
3924 if (!PyArg_ParseTuple(args
, "i:WIFSIGNALED", &status_i
))
3929 return Py_BuildValue("i", WIFSIGNALED(status
));
3932 #endif /* WIFSIGNALED */
3935 static char posix_WIFEXITED__doc__
[] =
3936 "WIFEXITED(status) -> Boolean\n\
3937 Return true if the process returning 'status' exited using the exit()\n\
3941 posix_WIFEXITED(PyObject
*self
, PyObject
*args
)
3945 #define status_i (status.w_status)
3948 #define status_i status
3952 if (!PyArg_ParseTuple(args
, "i:WIFEXITED", &status_i
))
3957 return Py_BuildValue("i", WIFEXITED(status
));
3960 #endif /* WIFEXITED */
3963 static char posix_WEXITSTATUS__doc__
[] =
3964 "WEXITSTATUS(status) -> integer\n\
3965 Return the process return code from 'status'.";
3968 posix_WEXITSTATUS(PyObject
*self
, PyObject
*args
)
3972 #define status_i (status.w_status)
3975 #define status_i status
3979 if (!PyArg_ParseTuple(args
, "i:WEXITSTATUS", &status_i
))
3984 return Py_BuildValue("i", WEXITSTATUS(status
));
3987 #endif /* WEXITSTATUS */
3990 static char posix_WTERMSIG__doc__
[] =
3991 "WTERMSIG(status) -> integer\n\
3992 Return the signal that terminated the process that provided the 'status'\n\
3996 posix_WTERMSIG(PyObject
*self
, PyObject
*args
)
4000 #define status_i (status.w_status)
4003 #define status_i status
4007 if (!PyArg_ParseTuple(args
, "i:WTERMSIG", &status_i
))
4012 return Py_BuildValue("i", WTERMSIG(status
));
4015 #endif /* WTERMSIG */
4018 static char posix_WSTOPSIG__doc__
[] =
4019 "WSTOPSIG(status) -> integer\n\
4020 Return the signal that stopped the process that provided the 'status' value.";
4023 posix_WSTOPSIG(PyObject
*self
, PyObject
*args
)
4027 #define status_i (status.w_status)
4030 #define status_i status
4034 if (!PyArg_ParseTuple(args
, "i:WSTOPSIG", &status_i
))
4039 return Py_BuildValue("i", WSTOPSIG(status
));
4042 #endif /* WSTOPSIG */
4044 #endif /* HAVE_SYS_WAIT_H */
4047 #if defined(HAVE_FSTATVFS)
4049 /* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
4050 needed definitions in sys/statvfs.h */
4053 #include <sys/statvfs.h>
4055 static char posix_fstatvfs__doc__
[] =
4056 "fstatvfs(fd) -> \n\
4057 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
4058 Perform an fstatvfs system call on the given fd.";
4061 posix_fstatvfs(PyObject
*self
, PyObject
*args
)
4065 if (!PyArg_ParseTuple(args
, "i:fstatvfs", &fd
))
4067 Py_BEGIN_ALLOW_THREADS
4068 res
= fstatvfs(fd
, &st
);
4069 Py_END_ALLOW_THREADS
4071 return posix_error();
4072 #if !defined(HAVE_LARGEFILE_SUPPORT)
4073 return Py_BuildValue("(llllllllll)",
4083 (long) st
.f_namemax
);
4085 return Py_BuildValue("(llLLLLLLll)",
4088 (LONG_LONG
) st
.f_blocks
,
4089 (LONG_LONG
) st
.f_bfree
,
4090 (LONG_LONG
) st
.f_bavail
,
4091 (LONG_LONG
) st
.f_files
,
4092 (LONG_LONG
) st
.f_ffree
,
4093 (LONG_LONG
) st
.f_favail
,
4095 (long) st
.f_namemax
);
4098 #endif /* HAVE_FSTATVFS */
4101 #if defined(HAVE_STATVFS)
4102 #include <sys/statvfs.h>
4104 static char posix_statvfs__doc__
[] =
4105 "statvfs(path) -> \n\
4106 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
4107 Perform a statvfs system call on the given path.";
4110 posix_statvfs(PyObject
*self
, PyObject
*args
)
4115 if (!PyArg_ParseTuple(args
, "s:statvfs", &path
))
4117 Py_BEGIN_ALLOW_THREADS
4118 res
= statvfs(path
, &st
);
4119 Py_END_ALLOW_THREADS
4121 return posix_error_with_filename(path
);
4122 #if !defined(HAVE_LARGEFILE_SUPPORT)
4123 return Py_BuildValue("(llllllllll)",
4133 (long) st
.f_namemax
);
4134 #else /* HAVE_LARGEFILE_SUPPORT */
4135 return Py_BuildValue("(llLLLLLLll)",
4138 (LONG_LONG
) st
.f_blocks
,
4139 (LONG_LONG
) st
.f_bfree
,
4140 (LONG_LONG
) st
.f_bavail
,
4141 (LONG_LONG
) st
.f_files
,
4142 (LONG_LONG
) st
.f_ffree
,
4143 (LONG_LONG
) st
.f_favail
,
4145 (long) st
.f_namemax
);
4148 #endif /* HAVE_STATVFS */
4152 static char posix_tempnam__doc__
[] = "\
4153 tempnam([dir[, prefix]]) -> string\n\
4154 Return a unique name for a temporary file.\n\
4155 The directory and a short may be specified as strings; they may be omitted\n\
4156 or None if not needed.";
4159 posix_tempnam(PyObject
*self
, PyObject
*args
)
4161 PyObject
*result
= NULL
;
4166 if (!PyArg_ParseTuple(args
, "|zz:tempnam", &dir
, &pfx
))
4168 name
= tempnam(dir
, pfx
);
4170 return PyErr_NoMemory();
4171 result
= PyString_FromString(name
);
4179 static char posix_tmpfile__doc__
[] = "\
4180 tmpfile() -> file object\n\
4181 Create a temporary file with no directory entries.";
4184 posix_tmpfile(PyObject
*self
, PyObject
*args
)
4188 if (!PyArg_ParseTuple(args
, ":tmpfile"))
4192 return posix_error();
4193 return PyFile_FromFile(fp
, "<tmpfile>", "w+", fclose
);
4199 static char posix_tmpnam__doc__
[] = "\
4200 tmpnam() -> string\n\
4201 Return a unique name for a temporary file.";
4204 posix_tmpnam(PyObject
*self
, PyObject
*args
)
4206 char buffer
[L_tmpnam
];
4209 if (!PyArg_ParseTuple(args
, ":tmpnam"))
4212 name
= tmpnam_r(buffer
);
4214 name
= tmpnam(buffer
);
4217 PyErr_SetObject(PyExc_OSError
,
4218 Py_BuildValue("is", 0,
4220 "unexpected NULL from tmpnam_r"
4222 "unexpected NULL from tmpnam"
4227 return PyString_FromString(buffer
);
4232 /* This is used for fpathconf(), pathconf(), confstr() and sysconf().
4233 * It maps strings representing configuration variable names to
4234 * integer values, allowing those functions to be called with the
4235 * magic names instead of polluting the module's namespace with tons of
4236 * rarely-used constants. There are three separate tables that use
4237 * these definitions.
4239 * This code is always included, even if none of the interfaces that
4240 * need it are included. The #if hackery needed to avoid it would be
4241 * sufficiently pervasive that it's not worth the loss of readability.
4249 conv_confname(PyObject
*arg
, int *valuep
, struct constdef
*table
,
4252 if (PyInt_Check(arg
)) {
4253 *valuep
= PyInt_AS_LONG(arg
);
4256 if (PyString_Check(arg
)) {
4257 /* look up the value in the table using a binary search */
4260 size_t hi
= tablesize
;
4262 char *confname
= PyString_AS_STRING(arg
);
4264 mid
= (lo
+ hi
) / 2;
4265 cmp
= strcmp(confname
, table
[mid
].name
);
4271 *valuep
= table
[mid
].value
;
4275 PyErr_SetString(PyExc_ValueError
, "unrecognized configuration name");
4278 PyErr_SetString(PyExc_TypeError
,
4279 "configuration names must be strings or integers");
4284 #if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
4285 static struct constdef posix_constants_pathconf
[] = {
4286 #ifdef _PC_ABI_AIO_XFER_MAX
4287 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX
},
4289 #ifdef _PC_ABI_ASYNC_IO
4290 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO
},
4293 {"PC_ASYNC_IO", _PC_ASYNC_IO
},
4295 #ifdef _PC_CHOWN_RESTRICTED
4296 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED
},
4298 #ifdef _PC_FILESIZEBITS
4299 {"PC_FILESIZEBITS", _PC_FILESIZEBITS
},
4302 {"PC_LAST", _PC_LAST
},
4305 {"PC_LINK_MAX", _PC_LINK_MAX
},
4307 #ifdef _PC_MAX_CANON
4308 {"PC_MAX_CANON", _PC_MAX_CANON
},
4310 #ifdef _PC_MAX_INPUT
4311 {"PC_MAX_INPUT", _PC_MAX_INPUT
},
4314 {"PC_NAME_MAX", _PC_NAME_MAX
},
4317 {"PC_NO_TRUNC", _PC_NO_TRUNC
},
4320 {"PC_PATH_MAX", _PC_PATH_MAX
},
4323 {"PC_PIPE_BUF", _PC_PIPE_BUF
},
4326 {"PC_PRIO_IO", _PC_PRIO_IO
},
4328 #ifdef _PC_SOCK_MAXBUF
4329 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF
},
4332 {"PC_SYNC_IO", _PC_SYNC_IO
},
4335 {"PC_VDISABLE", _PC_VDISABLE
},
4340 conv_path_confname(PyObject
*arg
, int *valuep
)
4342 return conv_confname(arg
, valuep
, posix_constants_pathconf
,
4343 sizeof(posix_constants_pathconf
)
4344 / sizeof(struct constdef
));
4348 #ifdef HAVE_FPATHCONF
4349 static char posix_fpathconf__doc__
[] = "\
4350 fpathconf(fd, name) -> integer\n\
4351 Return the configuration limit name for the file descriptor fd.\n\
4352 If there is no limit, return -1.";
4355 posix_fpathconf(PyObject
*self
, PyObject
*args
)
4357 PyObject
*result
= NULL
;
4360 if (PyArg_ParseTuple(args
, "iO&:fpathconf", &fd
,
4361 conv_path_confname
, &name
)) {
4365 limit
= fpathconf(fd
, name
);
4366 if (limit
== -1 && errno
!= 0)
4369 result
= PyInt_FromLong(limit
);
4376 #ifdef HAVE_PATHCONF
4377 static char posix_pathconf__doc__
[] = "\
4378 pathconf(path, name) -> integer\n\
4379 Return the configuration limit name for the file or directory path.\n\
4380 If there is no limit, return -1.";
4383 posix_pathconf(PyObject
*self
, PyObject
*args
)
4385 PyObject
*result
= NULL
;
4389 if (PyArg_ParseTuple(args
, "sO&:pathconf", &path
,
4390 conv_path_confname
, &name
)) {
4394 limit
= pathconf(path
, name
);
4395 if (limit
== -1 && errno
!= 0) {
4396 if (errno
== EINVAL
)
4397 /* could be a path or name problem */
4400 posix_error_with_filename(path
);
4403 result
= PyInt_FromLong(limit
);
4410 static struct constdef posix_constants_confstr
[] = {
4411 #ifdef _CS_ARCHITECTURE
4412 {"CS_ARCHITECTURE", _CS_ARCHITECTURE
},
4415 {"CS_HOSTNAME", _CS_HOSTNAME
},
4417 #ifdef _CS_HW_PROVIDER
4418 {"CS_HW_PROVIDER", _CS_HW_PROVIDER
},
4420 #ifdef _CS_HW_SERIAL
4421 {"CS_HW_SERIAL", _CS_HW_SERIAL
},
4423 #ifdef _CS_INITTAB_NAME
4424 {"CS_INITTAB_NAME", _CS_INITTAB_NAME
},
4426 #ifdef _CS_LFS64_CFLAGS
4427 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS
},
4429 #ifdef _CS_LFS64_LDFLAGS
4430 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS
},
4432 #ifdef _CS_LFS64_LIBS
4433 {"CS_LFS64_LIBS", _CS_LFS64_LIBS
},
4435 #ifdef _CS_LFS64_LINTFLAGS
4436 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS
},
4438 #ifdef _CS_LFS_CFLAGS
4439 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS
},
4441 #ifdef _CS_LFS_LDFLAGS
4442 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS
},
4445 {"CS_LFS_LIBS", _CS_LFS_LIBS
},
4447 #ifdef _CS_LFS_LINTFLAGS
4448 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS
},
4451 {"CS_MACHINE", _CS_MACHINE
},
4454 {"CS_PATH", _CS_PATH
},
4457 {"CS_RELEASE", _CS_RELEASE
},
4459 #ifdef _CS_SRPC_DOMAIN
4460 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN
},
4463 {"CS_SYSNAME", _CS_SYSNAME
},
4466 {"CS_VERSION", _CS_VERSION
},
4468 #ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
4469 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS
},
4471 #ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
4472 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS
},
4474 #ifdef _CS_XBS5_ILP32_OFF32_LIBS
4475 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS
},
4477 #ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
4478 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS
},
4480 #ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
4481 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS
},
4483 #ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
4484 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS
},
4486 #ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
4487 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS
},
4489 #ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
4490 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
},
4492 #ifdef _CS_XBS5_LP64_OFF64_CFLAGS
4493 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS
},
4495 #ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
4496 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS
},
4498 #ifdef _CS_XBS5_LP64_OFF64_LIBS
4499 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS
},
4501 #ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
4502 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS
},
4504 #ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
4505 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS
},
4507 #ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
4508 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
},
4510 #ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
4511 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS
},
4513 #ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
4514 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
},
4516 #ifdef _MIPS_CS_AVAIL_PROCESSORS
4517 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS
},
4519 #ifdef _MIPS_CS_BASE
4520 {"MIPS_CS_BASE", _MIPS_CS_BASE
},
4522 #ifdef _MIPS_CS_HOSTID
4523 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID
},
4525 #ifdef _MIPS_CS_HW_NAME
4526 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME
},
4528 #ifdef _MIPS_CS_NUM_PROCESSORS
4529 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS
},
4531 #ifdef _MIPS_CS_OSREL_MAJ
4532 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ
},
4534 #ifdef _MIPS_CS_OSREL_MIN
4535 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN
},
4537 #ifdef _MIPS_CS_OSREL_PATCH
4538 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH
},
4540 #ifdef _MIPS_CS_OS_NAME
4541 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME
},
4543 #ifdef _MIPS_CS_OS_PROVIDER
4544 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER
},
4546 #ifdef _MIPS_CS_PROCESSORS
4547 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS
},
4549 #ifdef _MIPS_CS_SERIAL
4550 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL
},
4552 #ifdef _MIPS_CS_VENDOR
4553 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR
},
4558 conv_confstr_confname(PyObject
*arg
, int *valuep
)
4560 return conv_confname(arg
, valuep
, posix_constants_confstr
,
4561 sizeof(posix_constants_confstr
)
4562 / sizeof(struct constdef
));
4565 static char posix_confstr__doc__
[] = "\
4566 confstr(name) -> string\n\
4567 Return a string-valued system configuration variable.";
4570 posix_confstr(PyObject
*self
, PyObject
*args
)
4572 PyObject
*result
= NULL
;
4576 if (PyArg_ParseTuple(args
, "O&:confstr", conv_confstr_confname
, &name
)) {
4577 int len
= confstr(name
, buffer
, sizeof(buffer
));
4584 result
= PyString_FromString("");
4587 if (len
>= sizeof(buffer
)) {
4588 result
= PyString_FromStringAndSize(NULL
, len
);
4590 confstr(name
, PyString_AS_STRING(result
), len
+1);
4593 result
= PyString_FromString(buffer
);
4602 static struct constdef posix_constants_sysconf
[] = {
4603 #ifdef _SC_2_CHAR_TERM
4604 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM
},
4607 {"SC_2_C_BIND", _SC_2_C_BIND
},
4610 {"SC_2_C_DEV", _SC_2_C_DEV
},
4612 #ifdef _SC_2_C_VERSION
4613 {"SC_2_C_VERSION", _SC_2_C_VERSION
},
4615 #ifdef _SC_2_FORT_DEV
4616 {"SC_2_FORT_DEV", _SC_2_FORT_DEV
},
4618 #ifdef _SC_2_FORT_RUN
4619 {"SC_2_FORT_RUN", _SC_2_FORT_RUN
},
4621 #ifdef _SC_2_LOCALEDEF
4622 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF
},
4625 {"SC_2_SW_DEV", _SC_2_SW_DEV
},
4628 {"SC_2_UPE", _SC_2_UPE
},
4630 #ifdef _SC_2_VERSION
4631 {"SC_2_VERSION", _SC_2_VERSION
},
4633 #ifdef _SC_ABI_ASYNCHRONOUS_IO
4634 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO
},
4637 {"SC_ACL", _SC_ACL
},
4639 #ifdef _SC_AIO_LISTIO_MAX
4640 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX
},
4643 {"SC_AIO_MAX", _SC_AIO_MAX
},
4645 #ifdef _SC_AIO_PRIO_DELTA_MAX
4646 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX
},
4649 {"SC_ARG_MAX", _SC_ARG_MAX
},
4651 #ifdef _SC_ASYNCHRONOUS_IO
4652 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO
},
4654 #ifdef _SC_ATEXIT_MAX
4655 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX
},
4658 {"SC_AUDIT", _SC_AUDIT
},
4660 #ifdef _SC_AVPHYS_PAGES
4661 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES
},
4663 #ifdef _SC_BC_BASE_MAX
4664 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX
},
4666 #ifdef _SC_BC_DIM_MAX
4667 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX
},
4669 #ifdef _SC_BC_SCALE_MAX
4670 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX
},
4672 #ifdef _SC_BC_STRING_MAX
4673 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX
},
4676 {"SC_CAP", _SC_CAP
},
4678 #ifdef _SC_CHARCLASS_NAME_MAX
4679 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX
},
4682 {"SC_CHAR_BIT", _SC_CHAR_BIT
},
4685 {"SC_CHAR_MAX", _SC_CHAR_MAX
},
4688 {"SC_CHAR_MIN", _SC_CHAR_MIN
},
4690 #ifdef _SC_CHILD_MAX
4691 {"SC_CHILD_MAX", _SC_CHILD_MAX
},
4694 {"SC_CLK_TCK", _SC_CLK_TCK
},
4696 #ifdef _SC_COHER_BLKSZ
4697 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ
},
4699 #ifdef _SC_COLL_WEIGHTS_MAX
4700 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX
},
4702 #ifdef _SC_DCACHE_ASSOC
4703 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC
},
4705 #ifdef _SC_DCACHE_BLKSZ
4706 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ
},
4708 #ifdef _SC_DCACHE_LINESZ
4709 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ
},
4711 #ifdef _SC_DCACHE_SZ
4712 {"SC_DCACHE_SZ", _SC_DCACHE_SZ
},
4714 #ifdef _SC_DCACHE_TBLKSZ
4715 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ
},
4717 #ifdef _SC_DELAYTIMER_MAX
4718 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX
},
4720 #ifdef _SC_EQUIV_CLASS_MAX
4721 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX
},
4723 #ifdef _SC_EXPR_NEST_MAX
4724 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX
},
4727 {"SC_FSYNC", _SC_FSYNC
},
4729 #ifdef _SC_GETGR_R_SIZE_MAX
4730 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX
},
4732 #ifdef _SC_GETPW_R_SIZE_MAX
4733 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX
},
4735 #ifdef _SC_ICACHE_ASSOC
4736 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC
},
4738 #ifdef _SC_ICACHE_BLKSZ
4739 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ
},
4741 #ifdef _SC_ICACHE_LINESZ
4742 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ
},
4744 #ifdef _SC_ICACHE_SZ
4745 {"SC_ICACHE_SZ", _SC_ICACHE_SZ
},
4748 {"SC_INF", _SC_INF
},
4751 {"SC_INT_MAX", _SC_INT_MAX
},
4754 {"SC_INT_MIN", _SC_INT_MIN
},
4757 {"SC_IOV_MAX", _SC_IOV_MAX
},
4759 #ifdef _SC_IP_SECOPTS
4760 {"SC_IP_SECOPTS", _SC_IP_SECOPTS
},
4762 #ifdef _SC_JOB_CONTROL
4763 {"SC_JOB_CONTROL", _SC_JOB_CONTROL
},
4765 #ifdef _SC_KERN_POINTERS
4766 {"SC_KERN_POINTERS", _SC_KERN_POINTERS
},
4769 {"SC_KERN_SIM", _SC_KERN_SIM
},
4772 {"SC_LINE_MAX", _SC_LINE_MAX
},
4774 #ifdef _SC_LOGIN_NAME_MAX
4775 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX
},
4777 #ifdef _SC_LOGNAME_MAX
4778 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX
},
4781 {"SC_LONG_BIT", _SC_LONG_BIT
},
4784 {"SC_MAC", _SC_MAC
},
4786 #ifdef _SC_MAPPED_FILES
4787 {"SC_MAPPED_FILES", _SC_MAPPED_FILES
},
4790 {"SC_MAXPID", _SC_MAXPID
},
4792 #ifdef _SC_MB_LEN_MAX
4793 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX
},
4796 {"SC_MEMLOCK", _SC_MEMLOCK
},
4798 #ifdef _SC_MEMLOCK_RANGE
4799 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE
},
4801 #ifdef _SC_MEMORY_PROTECTION
4802 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION
},
4804 #ifdef _SC_MESSAGE_PASSING
4805 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING
},
4807 #ifdef _SC_MMAP_FIXED_ALIGNMENT
4808 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT
},
4810 #ifdef _SC_MQ_OPEN_MAX
4811 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX
},
4813 #ifdef _SC_MQ_PRIO_MAX
4814 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX
},
4816 #ifdef _SC_NACLS_MAX
4817 {"SC_NACLS_MAX", _SC_NACLS_MAX
},
4819 #ifdef _SC_NGROUPS_MAX
4820 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX
},
4822 #ifdef _SC_NL_ARGMAX
4823 {"SC_NL_ARGMAX", _SC_NL_ARGMAX
},
4825 #ifdef _SC_NL_LANGMAX
4826 {"SC_NL_LANGMAX", _SC_NL_LANGMAX
},
4828 #ifdef _SC_NL_MSGMAX
4829 {"SC_NL_MSGMAX", _SC_NL_MSGMAX
},
4832 {"SC_NL_NMAX", _SC_NL_NMAX
},
4834 #ifdef _SC_NL_SETMAX
4835 {"SC_NL_SETMAX", _SC_NL_SETMAX
},
4837 #ifdef _SC_NL_TEXTMAX
4838 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX
},
4840 #ifdef _SC_NPROCESSORS_CONF
4841 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF
},
4843 #ifdef _SC_NPROCESSORS_ONLN
4844 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN
},
4846 #ifdef _SC_NPROC_CONF
4847 {"SC_NPROC_CONF", _SC_NPROC_CONF
},
4849 #ifdef _SC_NPROC_ONLN
4850 {"SC_NPROC_ONLN", _SC_NPROC_ONLN
},
4853 {"SC_NZERO", _SC_NZERO
},
4856 {"SC_OPEN_MAX", _SC_OPEN_MAX
},
4859 {"SC_PAGESIZE", _SC_PAGESIZE
},
4861 #ifdef _SC_PAGE_SIZE
4862 {"SC_PAGE_SIZE", _SC_PAGE_SIZE
},
4865 {"SC_PASS_MAX", _SC_PASS_MAX
},
4867 #ifdef _SC_PHYS_PAGES
4868 {"SC_PHYS_PAGES", _SC_PHYS_PAGES
},
4871 {"SC_PII", _SC_PII
},
4873 #ifdef _SC_PII_INTERNET
4874 {"SC_PII_INTERNET", _SC_PII_INTERNET
},
4876 #ifdef _SC_PII_INTERNET_DGRAM
4877 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM
},
4879 #ifdef _SC_PII_INTERNET_STREAM
4880 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM
},
4883 {"SC_PII_OSI", _SC_PII_OSI
},
4885 #ifdef _SC_PII_OSI_CLTS
4886 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS
},
4888 #ifdef _SC_PII_OSI_COTS
4889 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS
},
4891 #ifdef _SC_PII_OSI_M
4892 {"SC_PII_OSI_M", _SC_PII_OSI_M
},
4894 #ifdef _SC_PII_SOCKET
4895 {"SC_PII_SOCKET", _SC_PII_SOCKET
},
4898 {"SC_PII_XTI", _SC_PII_XTI
},
4901 {"SC_POLL", _SC_POLL
},
4903 #ifdef _SC_PRIORITIZED_IO
4904 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO
},
4906 #ifdef _SC_PRIORITY_SCHEDULING
4907 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING
},
4909 #ifdef _SC_REALTIME_SIGNALS
4910 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS
},
4912 #ifdef _SC_RE_DUP_MAX
4913 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX
},
4915 #ifdef _SC_RTSIG_MAX
4916 {"SC_RTSIG_MAX", _SC_RTSIG_MAX
},
4918 #ifdef _SC_SAVED_IDS
4919 {"SC_SAVED_IDS", _SC_SAVED_IDS
},
4921 #ifdef _SC_SCHAR_MAX
4922 {"SC_SCHAR_MAX", _SC_SCHAR_MAX
},
4924 #ifdef _SC_SCHAR_MIN
4925 {"SC_SCHAR_MIN", _SC_SCHAR_MIN
},
4928 {"SC_SELECT", _SC_SELECT
},
4930 #ifdef _SC_SEMAPHORES
4931 {"SC_SEMAPHORES", _SC_SEMAPHORES
},
4933 #ifdef _SC_SEM_NSEMS_MAX
4934 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX
},
4936 #ifdef _SC_SEM_VALUE_MAX
4937 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX
},
4939 #ifdef _SC_SHARED_MEMORY_OBJECTS
4940 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS
},
4943 {"SC_SHRT_MAX", _SC_SHRT_MAX
},
4946 {"SC_SHRT_MIN", _SC_SHRT_MIN
},
4948 #ifdef _SC_SIGQUEUE_MAX
4949 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX
},
4951 #ifdef _SC_SIGRT_MAX
4952 {"SC_SIGRT_MAX", _SC_SIGRT_MAX
},
4954 #ifdef _SC_SIGRT_MIN
4955 {"SC_SIGRT_MIN", _SC_SIGRT_MIN
},
4957 #ifdef _SC_SOFTPOWER
4958 {"SC_SOFTPOWER", _SC_SOFTPOWER
},
4960 #ifdef _SC_SPLIT_CACHE
4961 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE
},
4963 #ifdef _SC_SSIZE_MAX
4964 {"SC_SSIZE_MAX", _SC_SSIZE_MAX
},
4966 #ifdef _SC_STACK_PROT
4967 {"SC_STACK_PROT", _SC_STACK_PROT
},
4969 #ifdef _SC_STREAM_MAX
4970 {"SC_STREAM_MAX", _SC_STREAM_MAX
},
4972 #ifdef _SC_SYNCHRONIZED_IO
4973 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO
},
4976 {"SC_THREADS", _SC_THREADS
},
4978 #ifdef _SC_THREAD_ATTR_STACKADDR
4979 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR
},
4981 #ifdef _SC_THREAD_ATTR_STACKSIZE
4982 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE
},
4984 #ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
4985 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS
},
4987 #ifdef _SC_THREAD_KEYS_MAX
4988 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX
},
4990 #ifdef _SC_THREAD_PRIORITY_SCHEDULING
4991 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING
},
4993 #ifdef _SC_THREAD_PRIO_INHERIT
4994 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT
},
4996 #ifdef _SC_THREAD_PRIO_PROTECT
4997 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT
},
4999 #ifdef _SC_THREAD_PROCESS_SHARED
5000 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED
},
5002 #ifdef _SC_THREAD_SAFE_FUNCTIONS
5003 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS
},
5005 #ifdef _SC_THREAD_STACK_MIN
5006 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN
},
5008 #ifdef _SC_THREAD_THREADS_MAX
5009 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX
},
5012 {"SC_TIMERS", _SC_TIMERS
},
5014 #ifdef _SC_TIMER_MAX
5015 {"SC_TIMER_MAX", _SC_TIMER_MAX
},
5017 #ifdef _SC_TTY_NAME_MAX
5018 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX
},
5020 #ifdef _SC_TZNAME_MAX
5021 {"SC_TZNAME_MAX", _SC_TZNAME_MAX
},
5023 #ifdef _SC_T_IOV_MAX
5024 {"SC_T_IOV_MAX", _SC_T_IOV_MAX
},
5026 #ifdef _SC_UCHAR_MAX
5027 {"SC_UCHAR_MAX", _SC_UCHAR_MAX
},
5030 {"SC_UINT_MAX", _SC_UINT_MAX
},
5032 #ifdef _SC_UIO_MAXIOV
5033 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV
},
5035 #ifdef _SC_ULONG_MAX
5036 {"SC_ULONG_MAX", _SC_ULONG_MAX
},
5038 #ifdef _SC_USHRT_MAX
5039 {"SC_USHRT_MAX", _SC_USHRT_MAX
},
5042 {"SC_VERSION", _SC_VERSION
},
5045 {"SC_WORD_BIT", _SC_WORD_BIT
},
5047 #ifdef _SC_XBS5_ILP32_OFF32
5048 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32
},
5050 #ifdef _SC_XBS5_ILP32_OFFBIG
5051 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG
},
5053 #ifdef _SC_XBS5_LP64_OFF64
5054 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64
},
5056 #ifdef _SC_XBS5_LPBIG_OFFBIG
5057 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG
},
5059 #ifdef _SC_XOPEN_CRYPT
5060 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT
},
5062 #ifdef _SC_XOPEN_ENH_I18N
5063 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N
},
5065 #ifdef _SC_XOPEN_LEGACY
5066 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY
},
5068 #ifdef _SC_XOPEN_REALTIME
5069 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME
},
5071 #ifdef _SC_XOPEN_REALTIME_THREADS
5072 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS
},
5074 #ifdef _SC_XOPEN_SHM
5075 {"SC_XOPEN_SHM", _SC_XOPEN_SHM
},
5077 #ifdef _SC_XOPEN_UNIX
5078 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX
},
5080 #ifdef _SC_XOPEN_VERSION
5081 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION
},
5083 #ifdef _SC_XOPEN_XCU_VERSION
5084 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION
},
5086 #ifdef _SC_XOPEN_XPG2
5087 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2
},
5089 #ifdef _SC_XOPEN_XPG3
5090 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3
},
5092 #ifdef _SC_XOPEN_XPG4
5093 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4
},
5098 conv_sysconf_confname(PyObject
*arg
, int *valuep
)
5100 return conv_confname(arg
, valuep
, posix_constants_sysconf
,
5101 sizeof(posix_constants_sysconf
)
5102 / sizeof(struct constdef
));
5105 static char posix_sysconf__doc__
[] = "\
5106 sysconf(name) -> integer\n\
5107 Return an integer-valued system configuration variable.";
5110 posix_sysconf(PyObject
*self
, PyObject
*args
)
5112 PyObject
*result
= NULL
;
5115 if (PyArg_ParseTuple(args
, "O&:sysconf", conv_sysconf_confname
, &name
)) {
5119 value
= sysconf(name
);
5120 if (value
== -1 && errno
!= 0)
5123 result
= PyInt_FromLong(value
);
5130 /* This code is used to ensure that the tables of configuration value names
5131 * are in sorted order as required by conv_confname(), and also to build the
5132 * the exported dictionaries that are used to publish information about the
5133 * names available on the host platform.
5135 * Sorting the table at runtime ensures that the table is properly ordered
5136 * when used, even for platforms we're not able to test on. It also makes
5137 * it easier to add additional entries to the tables.
5141 cmp_constdefs(const void *v1
, const void *v2
)
5143 const struct constdef
*c1
=
5144 (const struct constdef
*) v1
;
5145 const struct constdef
*c2
=
5146 (const struct constdef
*) v2
;
5148 return strcmp(c1
->name
, c2
->name
);
5152 setup_confname_table(struct constdef
*table
, size_t tablesize
,
5153 char *tablename
, PyObject
*moddict
)
5159 qsort(table
, tablesize
, sizeof(struct constdef
), cmp_constdefs
);
5164 for (i
=0; i
< tablesize
; ++i
) {
5165 PyObject
*o
= PyInt_FromLong(table
[i
].value
);
5166 if (o
== NULL
|| PyDict_SetItemString(d
, table
[i
].name
, o
) == -1) {
5173 status
= PyDict_SetItemString(moddict
, tablename
, d
);
5178 /* Return -1 on failure, 0 on success. */
5180 setup_confname_tables(PyObject
*moddict
)
5182 #if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
5183 if (setup_confname_table(posix_constants_pathconf
,
5184 sizeof(posix_constants_pathconf
)
5185 / sizeof(struct constdef
),
5186 "pathconf_names", moddict
))
5190 if (setup_confname_table(posix_constants_confstr
,
5191 sizeof(posix_constants_confstr
)
5192 / sizeof(struct constdef
),
5193 "confstr_names", moddict
))
5197 if (setup_confname_table(posix_constants_sysconf
,
5198 sizeof(posix_constants_sysconf
)
5199 / sizeof(struct constdef
),
5200 "sysconf_names", moddict
))
5207 static char posix_abort__doc__
[] = "\
5208 abort() -> does not return!\n\
5209 Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
5210 in the hardest way possible on the hosting operating system.";
5213 posix_abort(PyObject
*self
, PyObject
*args
)
5215 if (!PyArg_ParseTuple(args
, ":abort"))
5219 Py_FatalError("abort() called from Python code didn't abort!");
5224 static char win32_startfile__doc__
[] = "\
5225 startfile(filepath) - Start a file with its associated application.\n\
5227 This acts like double-clicking the file in Explorer, or giving the file\n\
5228 name as an argument to the DOS \"start\" command: the file is opened\n\
5229 with whatever application (if any) its extension is associated.\n\
5231 startfile returns as soon as the associated application is launched.\n\
5232 There is no option to wait for the application to close, and no way\n\
5233 to retrieve the application's exit status.\n\
5235 The filepath is relative to the current directory. If you want to use\n\
5236 an absolute path, make sure the first character is not a slash (\"/\");\n\
5237 the underlying Win32 ShellExecute function doesn't work if it is.";
5240 win32_startfile(PyObject
*self
, PyObject
*args
)
5244 if (!PyArg_ParseTuple(args
, "s:startfile", &filepath
))
5246 Py_BEGIN_ALLOW_THREADS
5247 rc
= ShellExecute((HWND
)0, NULL
, filepath
, NULL
, NULL
, SW_SHOWNORMAL
);
5248 Py_END_ALLOW_THREADS
5249 if (rc
<= (HINSTANCE
)32)
5250 return win32_error("startfile", filepath
);
5256 static PyMethodDef posix_methods
[] = {
5257 {"access", posix_access
, METH_VARARGS
, posix_access__doc__
},
5259 {"ttyname", posix_ttyname
, METH_VARARGS
, posix_ttyname__doc__
},
5261 {"chdir", posix_chdir
, METH_VARARGS
, posix_chdir__doc__
},
5262 {"chmod", posix_chmod
, METH_VARARGS
, posix_chmod__doc__
},
5264 {"chown", posix_chown
, METH_VARARGS
, posix_chown__doc__
},
5265 #endif /* HAVE_CHOWN */
5267 {"ctermid", posix_ctermid
, METH_VARARGS
, posix_ctermid__doc__
},
5270 {"getcwd", posix_getcwd
, METH_VARARGS
, posix_getcwd__doc__
},
5273 {"link", posix_link
, METH_VARARGS
, posix_link__doc__
},
5274 #endif /* HAVE_LINK */
5275 {"listdir", posix_listdir
, METH_VARARGS
, posix_listdir__doc__
},
5276 {"lstat", posix_lstat
, METH_VARARGS
, posix_lstat__doc__
},
5277 {"mkdir", posix_mkdir
, METH_VARARGS
, posix_mkdir__doc__
},
5279 {"nice", posix_nice
, METH_VARARGS
, posix_nice__doc__
},
5280 #endif /* HAVE_NICE */
5281 #ifdef HAVE_READLINK
5282 {"readlink", posix_readlink
, METH_VARARGS
, posix_readlink__doc__
},
5283 #endif /* HAVE_READLINK */
5284 {"rename", posix_rename
, METH_VARARGS
, posix_rename__doc__
},
5285 {"rmdir", posix_rmdir
, METH_VARARGS
, posix_rmdir__doc__
},
5286 {"stat", posix_stat
, METH_VARARGS
, posix_stat__doc__
},
5288 {"symlink", posix_symlink
, METH_VARARGS
, posix_symlink__doc__
},
5289 #endif /* HAVE_SYMLINK */
5291 {"system", posix_system
, METH_VARARGS
, posix_system__doc__
},
5293 {"umask", posix_umask
, METH_VARARGS
, posix_umask__doc__
},
5295 {"uname", posix_uname
, METH_VARARGS
, posix_uname__doc__
},
5296 #endif /* HAVE_UNAME */
5297 {"unlink", posix_unlink
, METH_VARARGS
, posix_unlink__doc__
},
5298 {"remove", posix_unlink
, METH_VARARGS
, posix_remove__doc__
},
5299 {"utime", posix_utime
, METH_VARARGS
, posix_utime__doc__
},
5301 {"times", posix_times
, METH_VARARGS
, posix_times__doc__
},
5302 #endif /* HAVE_TIMES */
5303 {"_exit", posix__exit
, METH_VARARGS
, posix__exit__doc__
},
5305 {"execv", posix_execv
, METH_VARARGS
, posix_execv__doc__
},
5306 {"execve", posix_execve
, METH_VARARGS
, posix_execve__doc__
},
5307 #endif /* HAVE_EXECV */
5309 {"spawnv", posix_spawnv
, METH_VARARGS
, posix_spawnv__doc__
},
5310 {"spawnve", posix_spawnve
, METH_VARARGS
, posix_spawnve__doc__
},
5311 #endif /* HAVE_SPAWNV */
5313 {"fork1", posix_fork1
, METH_VARARGS
, posix_fork1__doc__
},
5314 #endif /* HAVE_FORK1 */
5316 {"fork", posix_fork
, METH_VARARGS
, posix_fork__doc__
},
5317 #endif /* HAVE_FORK */
5318 #if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY)
5319 {"openpty", posix_openpty
, METH_VARARGS
, posix_openpty__doc__
},
5320 #endif /* HAVE_OPENPTY || HAVE__GETPTY */
5322 {"forkpty", posix_forkpty
, METH_VARARGS
, posix_forkpty__doc__
},
5323 #endif /* HAVE_FORKPTY */
5325 {"getegid", posix_getegid
, METH_VARARGS
, posix_getegid__doc__
},
5326 #endif /* HAVE_GETEGID */
5328 {"geteuid", posix_geteuid
, METH_VARARGS
, posix_geteuid__doc__
},
5329 #endif /* HAVE_GETEUID */
5331 {"getgid", posix_getgid
, METH_VARARGS
, posix_getgid__doc__
},
5332 #endif /* HAVE_GETGID */
5333 #ifdef HAVE_GETGROUPS
5334 {"getgroups", posix_getgroups
, METH_VARARGS
, posix_getgroups__doc__
},
5336 {"getpid", posix_getpid
, METH_VARARGS
, posix_getpid__doc__
},
5338 {"getpgrp", posix_getpgrp
, METH_VARARGS
, posix_getpgrp__doc__
},
5339 #endif /* HAVE_GETPGRP */
5341 {"getppid", posix_getppid
, METH_VARARGS
, posix_getppid__doc__
},
5342 #endif /* HAVE_GETPPID */
5344 {"getuid", posix_getuid
, METH_VARARGS
, posix_getuid__doc__
},
5345 #endif /* HAVE_GETUID */
5346 #ifdef HAVE_GETLOGIN
5347 {"getlogin", posix_getlogin
, METH_VARARGS
, posix_getlogin__doc__
},
5350 {"kill", posix_kill
, METH_VARARGS
, posix_kill__doc__
},
5351 #endif /* HAVE_KILL */
5353 {"plock", posix_plock
, METH_VARARGS
, posix_plock__doc__
},
5354 #endif /* HAVE_PLOCK */
5356 {"popen", posix_popen
, METH_VARARGS
, posix_popen__doc__
},
5358 {"popen2", win32_popen2
, METH_VARARGS
},
5359 {"popen3", win32_popen3
, METH_VARARGS
},
5360 {"popen4", win32_popen4
, METH_VARARGS
},
5361 {"startfile", win32_startfile
, METH_VARARGS
, win32_startfile__doc__
},
5363 #endif /* HAVE_POPEN */
5365 {"setuid", posix_setuid
, METH_VARARGS
, posix_setuid__doc__
},
5366 #endif /* HAVE_SETUID */
5368 {"seteuid", posix_seteuid
, METH_VARARGS
, posix_seteuid__doc__
},
5369 #endif /* HAVE_SETEUID */
5371 {"setegid", posix_setegid
, METH_VARARGS
, posix_setegid__doc__
},
5372 #endif /* HAVE_SETEGID */
5373 #ifdef HAVE_SETREUID
5374 {"setreuid", posix_setreuid
, METH_VARARGS
, posix_setreuid__doc__
},
5375 #endif /* HAVE_SETREUID */
5376 #ifdef HAVE_SETREGID
5377 {"setregid", posix_setregid
, METH_VARARGS
, posix_setregid__doc__
},
5378 #endif /* HAVE_SETREGID */
5380 {"setgid", posix_setgid
, METH_VARARGS
, posix_setgid__doc__
},
5381 #endif /* HAVE_SETGID */
5383 {"setpgrp", posix_setpgrp
, METH_VARARGS
, posix_setpgrp__doc__
},
5384 #endif /* HAVE_SETPGRP */
5386 {"wait", posix_wait
, METH_VARARGS
, posix_wait__doc__
},
5387 #endif /* HAVE_WAIT */
5389 {"waitpid", posix_waitpid
, METH_VARARGS
, posix_waitpid__doc__
},
5390 #endif /* HAVE_WAITPID */
5392 {"setsid", posix_setsid
, METH_VARARGS
, posix_setsid__doc__
},
5393 #endif /* HAVE_SETSID */
5395 {"setpgid", posix_setpgid
, METH_VARARGS
, posix_setpgid__doc__
},
5396 #endif /* HAVE_SETPGID */
5397 #ifdef HAVE_TCGETPGRP
5398 {"tcgetpgrp", posix_tcgetpgrp
, METH_VARARGS
, posix_tcgetpgrp__doc__
},
5399 #endif /* HAVE_TCGETPGRP */
5400 #ifdef HAVE_TCSETPGRP
5401 {"tcsetpgrp", posix_tcsetpgrp
, METH_VARARGS
, posix_tcsetpgrp__doc__
},
5402 #endif /* HAVE_TCSETPGRP */
5403 {"open", posix_open
, METH_VARARGS
, posix_open__doc__
},
5404 {"close", posix_close
, METH_VARARGS
, posix_close__doc__
},
5405 {"dup", posix_dup
, METH_VARARGS
, posix_dup__doc__
},
5406 {"dup2", posix_dup2
, METH_VARARGS
, posix_dup2__doc__
},
5407 {"lseek", posix_lseek
, METH_VARARGS
, posix_lseek__doc__
},
5408 {"read", posix_read
, METH_VARARGS
, posix_read__doc__
},
5409 {"write", posix_write
, METH_VARARGS
, posix_write__doc__
},
5410 {"fstat", posix_fstat
, METH_VARARGS
, posix_fstat__doc__
},
5411 {"fdopen", posix_fdopen
, METH_VARARGS
, posix_fdopen__doc__
},
5412 {"isatty", posix_isatty
, METH_VARARGS
, posix_isatty__doc__
},
5414 {"pipe", posix_pipe
, METH_VARARGS
, posix_pipe__doc__
},
5417 {"mkfifo", posix_mkfifo
, METH_VARARGS
, posix_mkfifo__doc__
},
5419 #ifdef HAVE_FTRUNCATE
5420 {"ftruncate", posix_ftruncate
, METH_VARARGS
, posix_ftruncate__doc__
},
5423 {"putenv", posix_putenv
, METH_VARARGS
, posix_putenv__doc__
},
5425 #ifdef HAVE_STRERROR
5426 {"strerror", posix_strerror
, METH_VARARGS
, posix_strerror__doc__
},
5429 {"fsync", posix_fsync
, METH_VARARGS
, posix_fsync__doc__
},
5431 #ifdef HAVE_FDATASYNC
5432 {"fdatasync", posix_fdatasync
, METH_VARARGS
, posix_fdatasync__doc__
},
5434 #ifdef HAVE_SYS_WAIT_H
5436 {"WIFSTOPPED", posix_WIFSTOPPED
, METH_VARARGS
, posix_WIFSTOPPED__doc__
},
5437 #endif /* WIFSTOPPED */
5439 {"WIFSIGNALED", posix_WIFSIGNALED
, METH_VARARGS
, posix_WIFSIGNALED__doc__
},
5440 #endif /* WIFSIGNALED */
5442 {"WIFEXITED", posix_WIFEXITED
, METH_VARARGS
, posix_WIFEXITED__doc__
},
5443 #endif /* WIFEXITED */
5445 {"WEXITSTATUS", posix_WEXITSTATUS
, METH_VARARGS
, posix_WEXITSTATUS__doc__
},
5446 #endif /* WEXITSTATUS */
5448 {"WTERMSIG", posix_WTERMSIG
, METH_VARARGS
, posix_WTERMSIG__doc__
},
5449 #endif /* WTERMSIG */
5451 {"WSTOPSIG", posix_WSTOPSIG
, METH_VARARGS
, posix_WSTOPSIG__doc__
},
5452 #endif /* WSTOPSIG */
5453 #endif /* HAVE_SYS_WAIT_H */
5454 #ifdef HAVE_FSTATVFS
5455 {"fstatvfs", posix_fstatvfs
, METH_VARARGS
, posix_fstatvfs__doc__
},
5458 {"statvfs", posix_statvfs
, METH_VARARGS
, posix_statvfs__doc__
},
5461 {"tmpfile", posix_tmpfile
, METH_VARARGS
, posix_tmpfile__doc__
},
5464 {"tempnam", posix_tempnam
, METH_VARARGS
, posix_tempnam__doc__
},
5467 {"tmpnam", posix_tmpnam
, METH_VARARGS
, posix_tmpnam__doc__
},
5470 {"confstr", posix_confstr
, METH_VARARGS
, posix_confstr__doc__
},
5473 {"sysconf", posix_sysconf
, METH_VARARGS
, posix_sysconf__doc__
},
5475 #ifdef HAVE_FPATHCONF
5476 {"fpathconf", posix_fpathconf
, METH_VARARGS
, posix_fpathconf__doc__
},
5478 #ifdef HAVE_PATHCONF
5479 {"pathconf", posix_pathconf
, METH_VARARGS
, posix_pathconf__doc__
},
5481 {"abort", posix_abort
, METH_VARARGS
, posix_abort__doc__
},
5482 {NULL
, NULL
} /* Sentinel */
5487 ins(PyObject
*d
, char *symbol
, long value
)
5489 PyObject
* v
= PyInt_FromLong(value
);
5490 if (!v
|| PyDict_SetItemString(d
, symbol
, v
) < 0)
5491 return -1; /* triggers fatal error */
5497 #if defined(PYOS_OS2)
5498 /* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
5499 static int insertvalues(PyObject
*d
)
5502 ULONG values
[QSV_MAX
+1];
5506 Py_BEGIN_ALLOW_THREADS
5507 rc
= DosQuerySysInfo(1, QSV_MAX
, &values
[1], sizeof(values
));
5508 Py_END_ALLOW_THREADS
5510 if (rc
!= NO_ERROR
) {
5515 if (ins(d
, "meminstalled", values
[QSV_TOTPHYSMEM
])) return -1;
5516 if (ins(d
, "memkernel", values
[QSV_TOTRESMEM
])) return -1;
5517 if (ins(d
, "memvirtual", values
[QSV_TOTAVAILMEM
])) return -1;
5518 if (ins(d
, "maxpathlen", values
[QSV_MAX_PATH_LENGTH
])) return -1;
5519 if (ins(d
, "maxnamelen", values
[QSV_MAX_COMP_LENGTH
])) return -1;
5520 if (ins(d
, "revision", values
[QSV_VERSION_REVISION
])) return -1;
5521 if (ins(d
, "timeslice", values
[QSV_MIN_SLICE
])) return -1;
5523 switch (values
[QSV_VERSION_MINOR
]) {
5524 case 0: ver
= "2.00"; break;
5525 case 10: ver
= "2.10"; break;
5526 case 11: ver
= "2.11"; break;
5527 case 30: ver
= "3.00"; break;
5528 case 40: ver
= "4.00"; break;
5529 case 50: ver
= "5.00"; break;
5531 sprintf(tmp
, "%d-%d", values
[QSV_VERSION_MAJOR
],
5532 values
[QSV_VERSION_MINOR
]);
5536 /* Add Indicator of the Version of the Operating System */
5537 v
= PyString_FromString(ver
);
5538 if (!v
|| PyDict_SetItemString(d
, "version", v
) < 0)
5542 /* Add Indicator of Which Drive was Used to Boot the System */
5543 tmp
[0] = 'A' + values
[QSV_BOOT_DRIVE
] - 1;
5547 v
= PyString_FromString(tmp
);
5548 if (!v
|| PyDict_SetItemString(d
, "bootdrive", v
) < 0)
5557 all_ins(PyObject
*d
)
5560 if (ins(d
, "F_OK", (long)F_OK
)) return -1;
5563 if (ins(d
, "R_OK", (long)R_OK
)) return -1;
5566 if (ins(d
, "W_OK", (long)W_OK
)) return -1;
5569 if (ins(d
, "X_OK", (long)X_OK
)) return -1;
5572 if (ins(d
, "NGROUPS_MAX", (long)NGROUPS_MAX
)) return -1;
5575 if (ins(d
, "TMP_MAX", (long)TMP_MAX
)) return -1;
5578 if (ins(d
, "WNOHANG", (long)WNOHANG
)) return -1;
5581 if (ins(d
, "O_RDONLY", (long)O_RDONLY
)) return -1;
5584 if (ins(d
, "O_WRONLY", (long)O_WRONLY
)) return -1;
5587 if (ins(d
, "O_RDWR", (long)O_RDWR
)) return -1;
5590 if (ins(d
, "O_NDELAY", (long)O_NDELAY
)) return -1;
5593 if (ins(d
, "O_NONBLOCK", (long)O_NONBLOCK
)) return -1;
5596 if (ins(d
, "O_APPEND", (long)O_APPEND
)) return -1;
5599 if (ins(d
, "O_DSYNC", (long)O_DSYNC
)) return -1;
5602 if (ins(d
, "O_RSYNC", (long)O_RSYNC
)) return -1;
5605 if (ins(d
, "O_SYNC", (long)O_SYNC
)) return -1;
5608 if (ins(d
, "O_NOCTTY", (long)O_NOCTTY
)) return -1;
5611 if (ins(d
, "O_CREAT", (long)O_CREAT
)) return -1;
5614 if (ins(d
, "O_EXCL", (long)O_EXCL
)) return -1;
5617 if (ins(d
, "O_TRUNC", (long)O_TRUNC
)) return -1;
5620 if (ins(d
, "O_BINARY", (long)O_BINARY
)) return -1;
5623 if (ins(d
, "O_TEXT", (long)O_TEXT
)) return -1;
5627 if (ins(d
, "P_WAIT", (long)_P_WAIT
)) return -1;
5628 if (ins(d
, "P_NOWAIT", (long)_P_NOWAIT
)) return -1;
5629 if (ins(d
, "P_OVERLAY", (long)_OLD_P_OVERLAY
)) return -1;
5630 if (ins(d
, "P_NOWAITO", (long)_P_NOWAITO
)) return -1;
5631 if (ins(d
, "P_DETACH", (long)_P_DETACH
)) return -1;
5634 #if defined(PYOS_OS2)
5635 if (insertvalues(d
)) return -1;
5641 #if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
5642 #define INITFUNC initnt
5643 #define MODNAME "nt"
5645 #elif defined(PYOS_OS2)
5646 #define INITFUNC initos2
5647 #define MODNAME "os2"
5650 #define INITFUNC initposix
5651 #define MODNAME "posix"
5657 PyObject
*m
, *d
, *v
;
5659 m
= Py_InitModule4(MODNAME
,
5663 PYTHON_API_VERSION
);
5664 d
= PyModule_GetDict(m
);
5666 /* Initialize environ dictionary */
5667 v
= convertenviron();
5668 if (v
== NULL
|| PyDict_SetItemString(d
, "environ", v
) != 0)
5675 if (setup_confname_tables(d
))
5678 PyDict_SetItemString(d
, "error", PyExc_OSError
);
5681 if (posix_putenv_garbage
== NULL
)
5682 posix_putenv_garbage
= PyDict_New();