1 /***********************************************************
2 Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
7 Permission to use, copy, modify, and distribute this software and its
8 documentation for any purpose and without fee is hereby granted,
9 provided that the above copyright notice appear in all copies and that
10 both that copyright notice and this permission notice appear in
11 supporting documentation, and that the names of Stichting Mathematisch
12 Centrum or CWI or Corporation for National Research Initiatives or
13 CNRI not be used in advertising or publicity pertaining to
14 distribution of the software without specific, written prior
17 While CWI is the initial source for this software, a modified version
18 is made available by the Corporation for National Research Initiatives
19 (CNRI) at the Internet address ftp://ftp.python.org.
21 STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22 REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23 MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24 CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26 PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27 TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28 PERFORMANCE OF THIS SOFTWARE.
30 ******************************************************************/
32 /* POSIX module implementation */
34 /* This file is also used for Windows NT and MS-Win. In that case the module
35 actually calls itself 'nt', not 'posix', and a few functions are
36 either unimplemented or implemented differently. The source
37 assumes that for Windows NT, the macro 'MS_WIN32' is defined independent
38 of the compiler used. Different compilers define their own feature
39 test macro, e.g. '__BORLANDC__' or '_MSC_VER'. */
41 /* See also ../Dos/dosmodule.c */
43 static char posix__doc__
[] =
44 "This module provides access to operating system functionality that is\n\
45 standardized by the C Standard and the POSIX standard (a thinly\n\
46 disguised Unix interface). Refer to the library manual and\n\
47 corresponding Unix manual entries for more information on calls.";
53 #define INCL_DOSERRORS
54 #define INCL_DOSPROCESS
59 #include <sys/types.h>
61 #ifdef HAVE_SYS_WAIT_H
62 #include <sys/wait.h> /* For WNOHANG */
69 #include "mytime.h" /* For clock_t on some systems */
73 #endif /* HAVE_FCNTL_H */
75 /* Various compilers have only certain posix functions */
76 /* XXX Gosh I wish these were all moved into config.h */
77 #if defined(PYCC_VACPP) && defined(PYOS_OS2)
80 #if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
82 #define HAVE_OPENDIR 1
90 #ifdef __BORLANDC__ /* Borland compiler */
93 #define HAVE_GETEGID 1
94 #define HAVE_GETEUID 1
96 #define HAVE_GETPPID 1
99 #define HAVE_OPENDIR 1
102 #define HAVE_SYSTEM 1
105 #ifdef _MSC_VER /* Microsoft compiler */
106 #define HAVE_GETCWD 1
108 #define HAVE_SPAWNV 1
112 #define HAVE_SYSTEM 1
113 #else /* 16-bit Windows */
114 #endif /* !MS_WIN32 */
115 #else /* all other compilers */
116 /* Unix functions that the configure script doesn't check for */
119 #define HAVE_GETCWD 1
120 #define HAVE_GETEGID 1
121 #define HAVE_GETEUID 1
122 #define HAVE_GETGID 1
123 #define HAVE_GETPPID 1
124 #define HAVE_GETUID 1
126 #define HAVE_OPENDIR 1
129 #define HAVE_SYSTEM 1
131 #define HAVE_TTYNAME 1
132 #endif /* _MSC_VER */
133 #endif /* __BORLANDC__ */
134 #endif /* ! __WATCOMC__ || __QNX__ */
135 #endif /* ! __IBMC__ */
144 /* NeXT's <unistd.h> and <utime.h> aren't worth much */
148 /* #undef HAVE_GETCWD */
149 #define UNION_WAIT /* This should really be checked for by autoconf */
153 /* XXX These are for SunOS4.1.3 but shouldn't hurt elsewhere */
157 extern int symlink();
159 #else /* !HAVE_UNISTD_H */
160 #if defined(PYCC_VACPP)
161 extern int mkdir
Py_PROTO((char *));
163 #if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
164 extern int mkdir
Py_PROTO((const char *));
166 extern int mkdir
Py_PROTO((const char *, mode_t
));
169 #if defined(__IBMC__) || defined(__IBMCPP__)
170 extern int chdir
Py_PROTO((char *));
171 extern int rmdir
Py_PROTO((char *));
173 extern int chdir
Py_PROTO((const char *));
174 extern int rmdir
Py_PROTO((const char *));
176 extern int chmod
Py_PROTO((const char *, mode_t
));
177 extern int chown
Py_PROTO((const char *, uid_t
, gid_t
));
178 extern char *getcwd
Py_PROTO((char *, int));
179 extern char *strerror
Py_PROTO((int));
180 extern int link
Py_PROTO((const char *, const char *));
181 extern int rename
Py_PROTO((const char *, const char *));
182 extern int stat
Py_PROTO((const char *, struct stat
*));
183 extern int unlink
Py_PROTO((const char *));
184 extern int pclose
Py_PROTO((FILE *));
186 extern int symlink
Py_PROTO((const char *, const char *));
187 #endif /* HAVE_SYMLINK */
189 extern int lstat
Py_PROTO((const char *, struct stat
*));
190 #endif /* HAVE_LSTAT */
191 #endif /* !HAVE_UNISTD_H */
193 #endif /* !_MSC_VER */
197 #endif /* HAVE_UTIME_H */
199 #ifdef HAVE_SYS_UTIME_H
200 #include <sys/utime.h>
201 #define HAVE_UTIME_H /* pretend we do for the rest of this file */
202 #endif /* HAVE_SYS_UTIME_H */
204 #ifdef HAVE_SYS_TIMES_H
205 #include <sys/times.h>
206 #endif /* HAVE_SYS_TIMES_H */
208 #ifdef HAVE_SYS_PARAM_H
209 #include <sys/param.h>
210 #endif /* HAVE_SYS_PARAM_H */
212 #ifdef HAVE_SYS_UTSNAME_H
213 #include <sys/utsname.h>
214 #endif /* HAVE_SYS_UTSNAME_H */
217 #define MAXPATHLEN 1024
218 #endif /* MAXPATHLEN */
222 #define NAMLEN(dirent) strlen((dirent)->d_name)
224 #if defined(__WATCOMC__) && !defined(__QNX__)
226 #define NAMLEN(dirent) strlen((dirent)->d_name)
228 #define dirent direct
229 #define NAMLEN(dirent) (dirent)->d_namlen
231 #ifdef HAVE_SYS_NDIR_H
232 #include <sys/ndir.h>
234 #ifdef HAVE_SYS_DIR_H
249 #define pclose _pclose
250 #else /* 16-bit Windows */
253 #endif /* MS_WIN32 */
254 #endif /* _MSC_VER */
256 #if defined(PYCC_VACPP) && defined(PYOS_OS2)
261 /* Emulate some macros on systems that have a union instead of macros */
264 #define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
268 #define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
272 #define WTERMSIG(u_wait) ((u_wait).w_termsig)
275 #endif /* UNION_WAIT */
277 /* Return a dictionary corresponding to the POSIX environment table */
279 #if !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
280 extern char **environ
;
281 #endif /* !_MSC_VER */
293 /* This part ignores errors */
294 for (e
= environ
; *e
!= NULL
; e
++) {
297 char *p
= strchr(*e
, '=');
300 k
= PyString_FromStringAndSize(*e
, (int)(p
-*e
));
305 v
= PyString_FromString(p
+1);
311 if (PyDict_GetItem(d
, k
) == NULL
) {
312 if (PyDict_SetItem(d
, k
, v
) != 0)
318 #if defined(PYOS_OS2)
321 char buffer
[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
323 rc
= DosQueryExtLIBPATH(buffer
, BEGIN_LIBPATH
);
324 if (rc
== NO_ERROR
) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
325 PyObject
*v
= PyString_FromString(buffer
);
326 PyDict_SetItemString(d
, "BEGINLIBPATH", v
);
329 rc
= DosQueryExtLIBPATH(buffer
, END_LIBPATH
);
330 if (rc
== NO_ERROR
) { /* (not a typo, envname is NOT 'END_LIBPATH') */
331 PyObject
*v
= PyString_FromString(buffer
);
332 PyDict_SetItemString(d
, "ENDLIBPATH", v
);
341 /* Set a POSIX-specific error from errno, and return NULL */
346 return PyErr_SetFromErrno(PyExc_OSError
);
349 posix_error_with_filename(name
)
352 return PyErr_SetFromErrnoWithFilename(PyExc_OSError
, name
);
356 #if defined(PYOS_OS2)
357 /**********************************************************************
358 * Helper Function to Trim and Format OS/2 Messages
359 **********************************************************************/
361 os2_formatmsg(char *msgbuf
, int msglen
, char *reason
)
363 msgbuf
[msglen
] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
365 if (strlen(msgbuf
) > 0) { /* If Non-Empty Msg, Trim CRLF */
366 char *lastc
= &msgbuf
[ strlen(msgbuf
)-1 ];
368 while (lastc
> msgbuf
&& isspace(*lastc
))
369 *lastc
-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
372 /* Add Optional Reason Text */
374 strcat(msgbuf
, " : ");
375 strcat(msgbuf
, reason
);
379 /**********************************************************************
380 * Decode an OS/2 Operating System Error Code
382 * A convenience function to lookup an OS/2 error code and return a
383 * text message we can use to raise a Python exception.
386 * The messages for errors returned from the OS/2 kernel reside in
387 * the file OSO001.MSG in the \OS2 directory hierarchy.
389 **********************************************************************/
391 os2_strerror(char *msgbuf
, int msgbuflen
, int errorcode
, char *reason
)
396 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
397 Py_BEGIN_ALLOW_THREADS
398 rc
= DosGetMessage(NULL
, 0, msgbuf
, msgbuflen
,
399 errorcode
, "oso001.msg", &msglen
);
403 os2_formatmsg(msgbuf
, msglen
, reason
);
405 sprintf(msgbuf
, "unknown OS error #%d", errorcode
);
410 /* Set an OS/2-specific error and return NULL. OS/2 kernel
411 errors are not in a global variable e.g. 'errno' nor are
412 they congruent with posix error numbers. */
414 static PyObject
* os2_error(int code
)
419 os2_strerror(text
, sizeof(text
), code
, "");
421 v
= Py_BuildValue("(is)", code
, text
);
423 PyErr_SetObject(PyExc_OSError
, v
);
426 return NULL
; /* Signal to Python that an Exception is Pending */
431 /* POSIX generic methods */
434 posix_int(args
, func
)
436 int (*func
) Py_FPROTO((int));
440 if (!PyArg_Parse(args
, "i", &fd
))
442 Py_BEGIN_ALLOW_THREADS
446 return posix_error();
453 posix_1str(args
, func
)
455 int (*func
) Py_FPROTO((const char *));
459 if (!PyArg_Parse(args
, "s", &path1
))
461 Py_BEGIN_ALLOW_THREADS
462 res
= (*func
)(path1
);
465 return posix_error_with_filename(path1
);
471 posix_2str(args
, func
)
473 int (*func
) Py_FPROTO((const char *, const char *));
477 if (!PyArg_Parse(args
, "(ss)", &path1
, &path2
))
479 Py_BEGIN_ALLOW_THREADS
480 res
= (*func
)(path1
, path2
);
483 /* XXX how to report both path1 and path2??? */
484 return posix_error();
490 posix_strint(args
, func
)
492 int (*func
) Py_FPROTO((const char *, int));
497 if (!PyArg_Parse(args
, "(si)", &path
, &i
))
499 Py_BEGIN_ALLOW_THREADS
500 res
= (*func
)(path
, i
);
503 return posix_error_with_filename(path
);
509 posix_strintint(args
, func
)
511 int (*func
) Py_FPROTO((const char *, int, int));
516 if (!PyArg_Parse(args
, "(sii)", &path
, &i
, &i2
))
518 Py_BEGIN_ALLOW_THREADS
519 res
= (*func
)(path
, i
, i2
);
522 return posix_error_with_filename(path
);
528 posix_do_stat(self
, args
, statfunc
)
531 int (*statfunc
) Py_FPROTO((const char *, struct stat
*));
536 if (!PyArg_Parse(args
, "s", &path
))
538 Py_BEGIN_ALLOW_THREADS
539 res
= (*statfunc
)(path
, &st
);
542 return posix_error_with_filename(path
);
543 #if !defined(HAVE_LARGEFILE_SUPPORT)
544 return Py_BuildValue("(llllllllll)",
556 return Py_BuildValue("(lLllllLlll)",
558 (LONG_LONG
)st
.st_ino
,
563 (LONG_LONG
)st
.st_size
,
573 static char posix_access__doc__
[] =
574 "access(path, mode) -> 1 if granted, 0 otherwise\n\
575 Test for access to a file.";
578 posix_access(self
, args
)
586 if (!PyArg_Parse(args
, "(si)", &path
, &mode
))
588 Py_BEGIN_ALLOW_THREADS
589 res
= access(path
, mode
);
591 return(PyInt_FromLong(res
== 0 ? 1L : 0L));
608 static char posix_ttyname__doc__
[] =
609 "ttyname(fd) -> String\n\
610 Return the name of the terminal device connected to 'fd'.";
613 posix_ttyname(self
, args
)
621 if (!PyArg_Parse(args
, "i", &id
))
626 return(posix_error());
627 return(PyString_FromString(ret
));
631 static char posix_chdir__doc__
[] =
632 "chdir(path) -> None\n\
633 Change the current working directory to the specified path.";
636 posix_chdir(self
, args
)
640 return posix_1str(args
, chdir
);
644 static char posix_chmod__doc__
[] =
645 "chmod(path, mode) -> None\n\
646 Change the access permissions of a file.";
649 posix_chmod(self
, args
)
653 return posix_strint(args
, chmod
);
658 static char posix_fsync__doc__
[] =
659 "fsync(fildes) -> None\n\
660 force write of file with filedescriptor to disk.";
663 posix_fsync(self
, args
)
667 return posix_int(args
, fsync
);
669 #endif /* HAVE_FSYNC */
671 #ifdef HAVE_FDATASYNC
672 static char posix_fdatasync__doc__
[] =
673 "fdatasync(fildes) -> None\n\
674 force write of file with filedescriptor to disk.\n\
675 does not force update of metadata.";
677 extern int fdatasync(int); /* Prototype just in case */
680 posix_fdatasync(self
, args
)
684 return posix_int(args
, fdatasync
);
686 #endif /* HAVE_FDATASYNC */
690 static char posix_chown__doc__
[] =
691 "chown(path, uid, gid) -> None\n\
692 Change the owner and group id of path to the numeric uid and gid.";
695 posix_chown(self
, args
)
699 return posix_strintint(args
, chown
);
701 #endif /* HAVE_CHOWN */
705 static char posix_getcwd__doc__
[] =
707 Return a string representing the current working directory.";
710 posix_getcwd(self
, args
)
716 if (!PyArg_NoArgs(args
))
718 Py_BEGIN_ALLOW_THREADS
719 res
= getcwd(buf
, sizeof buf
);
722 return posix_error();
723 return PyString_FromString(buf
);
729 static char posix_link__doc__
[] =
730 "link(src, dst) -> None\n\
731 Create a hard link to a file.";
734 posix_link(self
, args
)
738 return posix_2str(args
, link
);
740 #endif /* HAVE_LINK */
743 static char posix_listdir__doc__
[] =
744 "listdir(path) -> list_of_strings\n\
745 Return a list containing the names of the entries in the directory.\n\
747 path: path of directory to list\n\
749 The list is in arbitrary order. It does not include the special\n\
750 entries '.' and '..' even if they are present in the directory.";
753 posix_listdir(self
, args
)
757 /* XXX Should redo this putting the (now four) versions of opendir
758 in separate files instead of having them all here... */
759 #if defined(MS_WIN32) && !defined(HAVE_OPENDIR)
765 WIN32_FIND_DATA FileData
;
766 char namebuf
[MAX_PATH
+5];
768 if (!PyArg_Parse(args
, "t#", &name
, &len
))
770 if (len
>= MAX_PATH
) {
771 PyErr_SetString(PyExc_ValueError
, "path too long");
774 strcpy(namebuf
, name
);
775 if (namebuf
[len
-1] != '/' && namebuf
[len
-1] != '\\')
776 namebuf
[len
++] = '/';
777 strcpy(namebuf
+ len
, "*.*");
779 if ((d
= PyList_New(0)) == NULL
)
782 hFindFile
= FindFirstFile(namebuf
, &FileData
);
783 if (hFindFile
== INVALID_HANDLE_VALUE
) {
784 errno
= GetLastError();
785 if (errno
== ERROR_FILE_NOT_FOUND
)
786 return PyList_New(0);
787 return posix_error_with_filename(name
);
790 if (FileData
.cFileName
[0] == '.' &&
791 (FileData
.cFileName
[1] == '\0' ||
792 FileData
.cFileName
[1] == '.' &&
793 FileData
.cFileName
[2] == '\0'))
795 v
= PyString_FromString(FileData
.cFileName
);
801 if (PyList_Append(d
, v
) != 0) {
808 } while (FindNextFile(hFindFile
, &FileData
) == TRUE
);
810 if (FindClose(hFindFile
) == FALSE
) {
811 errno
= GetLastError();
812 return posix_error_with_filename(&name
);
817 #else /* !MS_WIN32 */
818 #ifdef _MSC_VER /* 16-bit Windows */
826 char namebuf
[MAX_PATH
+5];
829 if (!PyArg_Parse(args
, "t#", &name
, &len
))
831 if (len
>= MAX_PATH
) {
832 PyErr_SetString(PyExc_ValueError
, "path too long");
835 strcpy(namebuf
, name
);
836 for (pt
= namebuf
; *pt
; pt
++)
839 if (namebuf
[len
-1] != '\\')
840 namebuf
[len
++] = '\\';
841 strcpy(namebuf
+ len
, "*.*");
843 if ((d
= PyList_New(0)) == NULL
)
846 if (_dos_findfirst(namebuf
, _A_RDONLY
|
847 _A_HIDDEN
| _A_SYSTEM
| _A_SUBDIR
, &ep
) != 0)
850 return posix_error_with_filename(name
);
853 if (ep
.name
[0] == '.' &&
854 (ep
.name
[1] == '\0' ||
858 strcpy(namebuf
, ep
.name
);
859 for (pt
= namebuf
; *pt
; pt
++)
862 v
= PyString_FromString(namebuf
);
868 if (PyList_Append(d
, v
) != 0) {
875 } while (_dos_findnext(&ep
) == 0);
880 #if defined(PYOS_OS2)
883 #define MAX_PATH CCHMAXPATH
888 char namebuf
[MAX_PATH
+5];
894 if (!PyArg_Parse(args
, "t#", &name
, &len
))
896 if (len
>= MAX_PATH
) {
897 PyErr_SetString(PyExc_ValueError
, "path too long");
900 strcpy(namebuf
, name
);
901 for (pt
= namebuf
; *pt
; pt
++)
904 if (namebuf
[len
-1] != '\\')
905 namebuf
[len
++] = '\\';
906 strcpy(namebuf
+ len
, "*.*");
908 if ((d
= PyList_New(0)) == NULL
)
911 rc
= DosFindFirst(namebuf
, /* Wildcard Pattern to Match */
912 &hdir
, /* Handle to Use While Search Directory */
913 FILE_READONLY
| FILE_HIDDEN
| FILE_SYSTEM
| FILE_DIRECTORY
,
914 &ep
, sizeof(ep
), /* Structure to Receive Directory Entry */
915 &srchcnt
, /* Max and Actual Count of Entries Per Iteration */
916 FIL_STANDARD
); /* Format of Entry (EAs or Not) */
918 if (rc
!= NO_ERROR
) {
920 return posix_error_with_filename(name
);
923 if (srchcnt
> 0) { /* If Directory is NOT Totally Empty, */
925 if (ep
.achName
[0] == '.'
926 && (ep
.achName
[1] == '\0' || ep
.achName
[1] == '.' && ep
.achName
[2] == '\0'))
927 continue; /* Skip Over "." and ".." Names */
929 strcpy(namebuf
, ep
.achName
);
931 /* Leave Case of Name Alone -- In Native Form */
932 /* (Removed Forced Lowercasing Code) */
934 v
= PyString_FromString(namebuf
);
940 if (PyList_Append(d
, v
) != 0) {
947 } while (DosFindNext(hdir
, &ep
, sizeof(ep
), &srchcnt
) == NO_ERROR
&& srchcnt
> 0);
957 if (!PyArg_Parse(args
, "s", &name
))
959 Py_BEGIN_ALLOW_THREADS
960 if ((dirp
= opendir(name
)) == NULL
) {
962 return posix_error_with_filename(name
);
964 if ((d
= PyList_New(0)) == NULL
) {
969 while ((ep
= readdir(dirp
)) != NULL
) {
970 if (ep
->d_name
[0] == '.' &&
972 (ep
->d_name
[1] == '.' && NAMLEN(ep
) == 2)))
974 v
= PyString_FromStringAndSize(ep
->d_name
, NAMLEN(ep
));
980 if (PyList_Append(d
, v
) != 0) {
993 #endif /* !PYOS_OS2 */
994 #endif /* !_MSC_VER */
995 #endif /* !MS_WIN32 */
998 static char posix_mkdir__doc__
[] =
999 "mkdir(path [, mode=0777]) -> None\n\
1000 Create a directory.";
1003 posix_mkdir(self
, args
)
1010 if (!PyArg_ParseTuple(args
, "s|i", &path
, &mode
))
1012 Py_BEGIN_ALLOW_THREADS
1013 #if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
1016 res
= mkdir(path
, mode
);
1018 Py_END_ALLOW_THREADS
1020 return posix_error_with_filename(path
);
1027 static char posix_nice__doc__
[] =
1028 "nice(inc) -> new_priority\n\
1029 Decrease the priority of process and return new priority.";
1032 posix_nice(self
, args
)
1036 int increment
, value
;
1038 if (!PyArg_Parse(args
, "i", &increment
))
1040 value
= nice(increment
);
1042 return posix_error();
1043 return PyInt_FromLong((long) value
);
1045 #endif /* HAVE_NICE */
1048 static char posix_rename__doc__
[] =
1049 "rename(old, new) -> None\n\
1050 Rename a file or directory.";
1053 posix_rename(self
, args
)
1057 return posix_2str(args
, rename
);
1061 static char posix_rmdir__doc__
[] =
1062 "rmdir(path) -> None\n\
1063 Remove a directory.";
1066 posix_rmdir(self
, args
)
1070 return posix_1str(args
, rmdir
);
1074 static char posix_stat__doc__
[] =
1075 "stat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
1076 Perform a stat system call on the given path.";
1079 posix_stat(self
, args
)
1083 return posix_do_stat(self
, args
, stat
);
1088 static char posix_system__doc__
[] =
1089 "system(command) -> exit_status\n\
1090 Execute the command (a string) in a subshell.";
1093 posix_system(self
, args
)
1099 if (!PyArg_Parse(args
, "s", &command
))
1101 Py_BEGIN_ALLOW_THREADS
1102 sts
= system(command
);
1103 Py_END_ALLOW_THREADS
1104 return PyInt_FromLong(sts
);
1109 static char posix_umask__doc__
[] =
1110 "umask(new_mask) -> old_mask\n\
1111 Set the current numeric umask and return the previous umask.";
1114 posix_umask(self
, args
)
1119 if (!PyArg_Parse(args
, "i", &i
))
1123 return posix_error();
1124 return PyInt_FromLong((long)i
);
1128 static char posix_unlink__doc__
[] =
1129 "unlink(path) -> None\n\
1130 Remove a file (same as remove(path)).";
1132 static char posix_remove__doc__
[] =
1133 "remove(path) -> None\n\
1134 Remove a file (same as unlink(path)).";
1137 posix_unlink(self
, args
)
1141 return posix_1str(args
, unlink
);
1146 static char posix_uname__doc__
[] =
1147 "uname() -> (sysname, nodename, release, version, machine)\n\
1148 Return a tuple identifying the current operating system.";
1151 posix_uname(self
, args
)
1157 if (!PyArg_NoArgs(args
))
1159 Py_BEGIN_ALLOW_THREADS
1161 Py_END_ALLOW_THREADS
1163 return posix_error();
1164 return Py_BuildValue("(sssss)",
1171 #endif /* HAVE_UNAME */
1174 static char posix_utime__doc__
[] =
1175 "utime(path, (atime, utime)) -> None\n\
1176 Set the access and modified time of the file to the given values.";
1179 posix_utime(self
, args
)
1187 /* XXX should define struct utimbuf instead, above */
1190 #define ATIME buf.actime
1191 #define MTIME buf.modtime
1192 #define UTIME_ARG &buf
1193 #else /* HAVE_UTIME_H */
1195 #define ATIME buf[0]
1196 #define MTIME buf[1]
1197 #define UTIME_ARG buf
1198 #endif /* HAVE_UTIME_H */
1200 if (!PyArg_Parse(args
, "(s(ll))", &path
, &atime
, &mtime
))
1204 Py_BEGIN_ALLOW_THREADS
1205 res
= utime(path
, UTIME_ARG
);
1206 Py_END_ALLOW_THREADS
1208 return posix_error_with_filename(path
);
1217 /* Process operations */
1219 static char posix__exit__doc__
[] =
1221 Exit to the system with specified status, without normal exit processing.";
1224 posix__exit(self
, args
)
1229 if (!PyArg_Parse(args
, "i", &sts
))
1232 return NULL
; /* Make gcc -Wall happy */
1237 static char posix_execv__doc__
[] =
1238 "execv(path, args)\n\
1239 Execute an executable path with arguments, replacing current process.\n\
1241 path: path of executable file\n\
1242 args: tuple or list of strings";
1245 posix_execv(self
, args
)
1253 PyObject
*(*getitem
) Py_PROTO((PyObject
*, int));
1255 /* execv has two arguments: (path, argv), where
1256 argv is a list or tuple of strings. */
1258 if (!PyArg_Parse(args
, "(sO)", &path
, &argv
))
1260 if (PyList_Check(argv
)) {
1261 argc
= PyList_Size(argv
);
1262 getitem
= PyList_GetItem
;
1264 else if (PyTuple_Check(argv
)) {
1265 argc
= PyTuple_Size(argv
);
1266 getitem
= PyTuple_GetItem
;
1270 PyErr_BadArgument();
1274 argvlist
= PyMem_NEW(char *, argc
+1);
1275 if (argvlist
== NULL
)
1277 for (i
= 0; i
< argc
; i
++) {
1278 if (!PyArg_Parse((*getitem
)(argv
, i
), "s", &argvlist
[i
])) {
1279 PyMem_DEL(argvlist
);
1283 argvlist
[argc
] = NULL
;
1285 #ifdef BAD_EXEC_PROTOTYPES
1286 execv(path
, (const char **) argvlist
);
1287 #else /* BAD_EXEC_PROTOTYPES */
1288 execv(path
, argvlist
);
1289 #endif /* BAD_EXEC_PROTOTYPES */
1291 /* If we get here it's definitely an error */
1293 PyMem_DEL(argvlist
);
1294 return posix_error();
1298 static char posix_execve__doc__
[] =
1299 "execve(path, args, env)\n\
1300 Execute a path with arguments and environment, replacing current process.\n\
1302 path: path of executable file\n\
1303 args: tuple or list of arguments\n\
1304 env: dictonary of strings mapping to strings";
1307 posix_execve(self
, args
)
1312 PyObject
*argv
, *env
;
1315 PyObject
*key
, *val
, *keys
=NULL
, *vals
=NULL
;
1316 int i
, pos
, argc
, envc
;
1317 PyObject
*(*getitem
) Py_PROTO((PyObject
*, int));
1319 /* execve has three arguments: (path, argv, env), where
1320 argv is a list or tuple of strings and env is a dictionary
1321 like posix.environ. */
1323 if (!PyArg_Parse(args
, "(sOO)", &path
, &argv
, &env
))
1325 if (PyList_Check(argv
)) {
1326 argc
= PyList_Size(argv
);
1327 getitem
= PyList_GetItem
;
1329 else if (PyTuple_Check(argv
)) {
1330 argc
= PyTuple_Size(argv
);
1331 getitem
= PyTuple_GetItem
;
1334 PyErr_SetString(PyExc_TypeError
, "argv must be tuple or list");
1337 if (!PyMapping_Check(env
)) {
1338 PyErr_SetString(PyExc_TypeError
, "env must be mapping object");
1342 argvlist
= PyMem_NEW(char *, argc
+1);
1343 if (argvlist
== NULL
) {
1347 for (i
= 0; i
< argc
; i
++) {
1348 if (!PyArg_Parse((*getitem
)(argv
, i
),
1349 "s;argv must be list of strings",
1355 argvlist
[argc
] = NULL
;
1357 i
= PyMapping_Length(env
);
1358 envlist
= PyMem_NEW(char *, i
+ 1);
1359 if (envlist
== NULL
) {
1364 keys
= PyMapping_Keys(env
);
1365 vals
= PyMapping_Values(env
);
1369 for (pos
= 0; pos
< i
; pos
++) {
1372 key
= PyList_GetItem(keys
, pos
);
1373 val
= PyList_GetItem(vals
, pos
);
1377 if (!PyArg_Parse(key
, "s;non-string key in env", &k
) ||
1378 !PyArg_Parse(val
, "s;non-string value in env", &v
))
1383 #if defined(PYOS_OS2)
1384 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
1385 if (stricmp(k
, "BEGINLIBPATH") != 0 && stricmp(k
, "ENDLIBPATH") != 0) {
1387 p
= PyMem_NEW(char, PyString_Size(key
)+PyString_Size(val
) + 2);
1392 sprintf(p
, "%s=%s", k
, v
);
1393 envlist
[envc
++] = p
;
1394 #if defined(PYOS_OS2)
1401 #ifdef BAD_EXEC_PROTOTYPES
1402 execve(path
, (const char **)argvlist
, envlist
);
1403 #else /* BAD_EXEC_PROTOTYPES */
1404 execve(path
, argvlist
, envlist
);
1405 #endif /* BAD_EXEC_PROTOTYPES */
1407 /* If we get here it's definitely an error */
1409 (void) posix_error();
1413 PyMem_DEL(envlist
[envc
]);
1416 PyMem_DEL(argvlist
);
1421 #endif /* HAVE_EXECV */
1425 static char posix_spawnv__doc__
[] =
1426 "spawnv(mode, path, args)\n\
1427 Execute an executable path with arguments, replacing current process.\n\
1429 mode: mode of process creation\n\
1430 path: path of executable file\n\
1431 args: tuple or list of strings";
1434 posix_spawnv(self
, args
)
1442 PyObject
*(*getitem
) Py_PROTO((PyObject
*, int));
1444 /* spawnv has three arguments: (mode, path, argv), where
1445 argv is a list or tuple of strings. */
1447 if (!PyArg_Parse(args
, "(isO)", &mode
, &path
, &argv
))
1449 if (PyList_Check(argv
)) {
1450 argc
= PyList_Size(argv
);
1451 getitem
= PyList_GetItem
;
1453 else if (PyTuple_Check(argv
)) {
1454 argc
= PyTuple_Size(argv
);
1455 getitem
= PyTuple_GetItem
;
1459 PyErr_BadArgument();
1463 argvlist
= PyMem_NEW(char *, argc
+1);
1464 if (argvlist
== NULL
)
1466 for (i
= 0; i
< argc
; i
++) {
1467 if (!PyArg_Parse((*getitem
)(argv
, i
), "s", &argvlist
[i
])) {
1468 PyMem_DEL(argvlist
);
1472 argvlist
[argc
] = NULL
;
1474 if (mode
== _OLD_P_OVERLAY
)
1476 i
= _spawnv(mode
, path
, argvlist
);
1478 PyMem_DEL(argvlist
);
1481 return posix_error();
1483 return Py_BuildValue("i", i
);
1487 static char posix_spawnve__doc__
[] =
1488 "spawnve(mode, path, args, env)\n\
1489 Execute a path with arguments and environment, replacing current process.\n\
1491 mode: mode of process creation\n\
1492 path: path of executable file\n\
1493 args: tuple or list of arguments\n\
1494 env: dictonary of strings mapping to strings";
1497 posix_spawnve(self
, args
)
1502 PyObject
*argv
, *env
;
1505 PyObject
*key
, *val
, *keys
=NULL
, *vals
=NULL
, *res
=NULL
;
1506 int mode
, i
, pos
, argc
, envc
;
1507 PyObject
*(*getitem
) Py_PROTO((PyObject
*, int));
1509 /* spawnve has four arguments: (mode, path, argv, env), where
1510 argv is a list or tuple of strings and env is a dictionary
1511 like posix.environ. */
1513 if (!PyArg_Parse(args
, "(isOO)", &mode
, &path
, &argv
, &env
))
1515 if (PyList_Check(argv
)) {
1516 argc
= PyList_Size(argv
);
1517 getitem
= PyList_GetItem
;
1519 else if (PyTuple_Check(argv
)) {
1520 argc
= PyTuple_Size(argv
);
1521 getitem
= PyTuple_GetItem
;
1524 PyErr_SetString(PyExc_TypeError
, "argv must be tuple or list");
1527 if (!PyMapping_Check(env
)) {
1528 PyErr_SetString(PyExc_TypeError
, "env must be mapping object");
1532 argvlist
= PyMem_NEW(char *, argc
+1);
1533 if (argvlist
== NULL
) {
1537 for (i
= 0; i
< argc
; i
++) {
1538 if (!PyArg_Parse((*getitem
)(argv
, i
),
1539 "s;argv must be list of strings",
1545 argvlist
[argc
] = NULL
;
1547 i
= PyMapping_Length(env
);
1548 envlist
= PyMem_NEW(char *, i
+ 1);
1549 if (envlist
== NULL
) {
1554 keys
= PyMapping_Keys(env
);
1555 vals
= PyMapping_Values(env
);
1559 for (pos
= 0; pos
< i
; pos
++) {
1562 key
= PyList_GetItem(keys
, pos
);
1563 val
= PyList_GetItem(vals
, pos
);
1567 if (!PyArg_Parse(key
, "s;non-string key in env", &k
) ||
1568 !PyArg_Parse(val
, "s;non-string value in env", &v
))
1572 p
= PyMem_NEW(char, PyString_Size(key
)+PyString_Size(val
) + 2);
1577 sprintf(p
, "%s=%s", k
, v
);
1578 envlist
[envc
++] = p
;
1582 if (mode
== _OLD_P_OVERLAY
)
1584 i
= _spawnve(mode
, path
, argvlist
, envlist
);
1586 (void) posix_error();
1588 res
= Py_BuildValue("i", i
);
1592 PyMem_DEL(envlist
[envc
]);
1595 PyMem_DEL(argvlist
);
1600 #endif /* HAVE_SPAWNV */
1604 static char posix_fork__doc__
[] =
1606 Fork a child process.\n\
1608 Return 0 to child process and PID of child to parent process.";
1611 posix_fork(self
, args
)
1616 if (!PyArg_NoArgs(args
))
1620 return posix_error();
1622 return PyInt_FromLong((long)pid
);
1628 static char posix_getegid__doc__
[] =
1629 "getegid() -> egid\n\
1630 Return the current process's effective group id.";
1633 posix_getegid(self
, args
)
1637 if (!PyArg_NoArgs(args
))
1639 return PyInt_FromLong((long)getegid());
1645 static char posix_geteuid__doc__
[] =
1646 "geteuid() -> euid\n\
1647 Return the current process's effective user id.";
1650 posix_geteuid(self
, args
)
1654 if (!PyArg_NoArgs(args
))
1656 return PyInt_FromLong((long)geteuid());
1662 static char posix_getgid__doc__
[] =
1664 Return the current process's group id.";
1667 posix_getgid(self
, args
)
1671 if (!PyArg_NoArgs(args
))
1673 return PyInt_FromLong((long)getgid());
1678 static char posix_getpid__doc__
[] =
1680 Return the current process id";
1683 posix_getpid(self
, args
)
1687 if (!PyArg_NoArgs(args
))
1689 return PyInt_FromLong((long)getpid());
1694 static char posix_getpgrp__doc__
[] =
1695 "getpgrp() -> pgrp\n\
1696 Return the current process group id.";
1699 posix_getpgrp(self
, args
)
1703 if (!PyArg_NoArgs(args
))
1705 #ifdef GETPGRP_HAVE_ARG
1706 return PyInt_FromLong((long)getpgrp(0));
1707 #else /* GETPGRP_HAVE_ARG */
1708 return PyInt_FromLong((long)getpgrp());
1709 #endif /* GETPGRP_HAVE_ARG */
1711 #endif /* HAVE_GETPGRP */
1715 static char posix_setpgrp__doc__
[] =
1716 "setpgrp() -> None\n\
1717 Make this process a session leader.";
1720 posix_setpgrp(self
, args
)
1724 if (!PyArg_NoArgs(args
))
1726 #ifdef SETPGRP_HAVE_ARG
1727 if (setpgrp(0, 0) < 0)
1728 #else /* SETPGRP_HAVE_ARG */
1730 #endif /* SETPGRP_HAVE_ARG */
1731 return posix_error();
1736 #endif /* HAVE_SETPGRP */
1739 static char posix_getppid__doc__
[] =
1740 "getppid() -> ppid\n\
1741 Return the parent's process id.";
1744 posix_getppid(self
, args
)
1748 if (!PyArg_NoArgs(args
))
1750 return PyInt_FromLong((long)getppid());
1756 static char posix_getuid__doc__
[] =
1758 Return the current process's user id.";
1761 posix_getuid(self
, args
)
1765 if (!PyArg_NoArgs(args
))
1767 return PyInt_FromLong((long)getuid());
1773 static char posix_kill__doc__
[] =
1774 "kill(pid, sig) -> None\n\
1775 Kill a process with a signal.";
1778 posix_kill(self
, args
)
1783 if (!PyArg_Parse(args
, "(ii)", &pid
, &sig
))
1785 #if defined(PYOS_OS2)
1786 if (sig
== XCPT_SIGNAL_INTR
|| sig
== XCPT_SIGNAL_BREAK
) {
1788 if ((rc
= DosSendSignalException(pid
, sig
)) != NO_ERROR
)
1789 return os2_error(rc
);
1791 } else if (sig
== XCPT_SIGNAL_KILLPROC
) {
1793 if ((rc
= DosKillProcess(DKP_PROCESS
, pid
)) != NO_ERROR
)
1794 return os2_error(rc
);
1797 return NULL
; /* Unrecognized Signal Requested */
1799 if (kill(pid
, sig
) == -1)
1800 return posix_error();
1809 #ifdef HAVE_SYS_LOCK_H
1810 #include <sys/lock.h>
1813 static char posix_plock__doc__
[] =
1814 "plock(op) -> None\n\
1815 Lock program segments into memory.";
1818 posix_plock(self
, args
)
1823 if (!PyArg_Parse(args
, "i", &op
))
1825 if (plock(op
) == -1)
1826 return posix_error();
1834 static char posix_popen__doc__
[] =
1835 "popen(command [, mode='r' [, bufsize]]) -> pipe\n\
1836 Open a pipe to/from a command returning a file object.";
1838 #if defined(PYOS_OS2)
1840 async_system(const char *command
)
1842 char *p
, errormsg
[256], args
[1024];
1845 char *shell
= getenv("COMSPEC");
1849 strcpy(args
, shell
);
1850 p
= &args
[ strlen(args
)+1 ];
1856 rc
= DosExecPgm(errormsg
, sizeof(errormsg
),
1857 EXEC_ASYNC
, /* Execute Async w/o Wait for Results */
1859 NULL
, /* Inherit Parent's Environment */
1865 popen(const char *command
, const char *mode
, int pipesize
, int *err
)
1869 APIRET rc
= DosCreatePipe(&rhan
, &whan
, pipesize
);
1871 if (rc
!= NO_ERROR
) {
1873 return NULL
; /* ERROR - Unable to Create Anon Pipe */
1876 if (strchr(mode
, 'r') != NULL
) { /* Treat Command as a Data Source */
1877 int oldfd
= dup(1); /* Save STDOUT Handle in Another Handle */
1879 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
1880 close(1); /* Make STDOUT Available for Reallocation */
1882 if (dup2(whan
, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
1883 DosClose(whan
); /* Close Now-Unused Pipe Write Handle */
1885 if (async_system(command
) == NO_ERROR
)
1886 retfd
= fdopen(rhan
, mode
); /* And Return Pipe Read Handle */
1889 dup2(oldfd
, 1); /* Reconnect STDOUT to Original Handle */
1890 DosExitCritSec(); /* Now Allow Other Threads to Run */
1892 close(oldfd
); /* And Close Saved STDOUT Handle */
1893 return retfd
; /* Return fd of Pipe or NULL if Error */
1895 } else if (strchr(mode
, 'w')) { /* Treat Command as a Data Sink */
1896 int oldfd
= dup(0); /* Save STDIN Handle in Another Handle */
1898 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
1899 close(0); /* Make STDIN Available for Reallocation */
1901 if (dup2(rhan
, 0) == 0) { /* Connect STDIN to Pipe Read Side */
1902 DosClose(rhan
); /* Close Now-Unused Pipe Read Handle */
1904 if (async_system(command
) == NO_ERROR
)
1905 retfd
= fdopen(whan
, mode
); /* And Return Pipe Write Handle */
1908 dup2(oldfd
, 0); /* Reconnect STDIN to Original Handle */
1909 DosExitCritSec(); /* Now Allow Other Threads to Run */
1911 close(oldfd
); /* And Close Saved STDIN Handle */
1912 return retfd
; /* Return fd of Pipe or NULL if Error */
1915 *err
= ERROR_INVALID_ACCESS
;
1916 return NULL
; /* ERROR - Invalid Mode (Neither Read nor Write) */
1921 posix_popen(self
, args
)
1927 int err
, bufsize
= -1;
1930 if (!PyArg_ParseTuple(args
, "s|si", &name
, &mode
, &bufsize
))
1932 Py_BEGIN_ALLOW_THREADS
1933 fp
= popen(name
, mode
, (bufsize
> 0) ? bufsize
: 4096, &err
);
1934 Py_END_ALLOW_THREADS
1936 return os2_error(err
);
1938 f
= PyFile_FromFile(fp
, name
, mode
, fclose
);
1940 PyFile_SetBufSize(f
, bufsize
);
1946 posix_popen(self
, args
)
1955 if (!PyArg_ParseTuple(args
, "s|si", &name
, &mode
, &bufsize
))
1957 Py_BEGIN_ALLOW_THREADS
1958 fp
= popen(name
, mode
);
1959 Py_END_ALLOW_THREADS
1961 return posix_error();
1962 f
= PyFile_FromFile(fp
, name
, mode
, pclose
);
1964 PyFile_SetBufSize(f
, bufsize
);
1969 #endif /* HAVE_POPEN */
1973 static char posix_setuid__doc__
[] =
1974 "setuid(uid) -> None\n\
1975 Set the current process's user id.";
1977 posix_setuid(self
, args
)
1982 if (!PyArg_Parse(args
, "i", &uid
))
1984 if (setuid(uid
) < 0)
1985 return posix_error();
1989 #endif /* HAVE_SETUID */
1993 static char posix_setgid__doc__
[] =
1994 "setgid(gid) -> None\n\
1995 Set the current process's group id.";
1998 posix_setgid(self
, args
)
2003 if (!PyArg_Parse(args
, "i", &gid
))
2005 if (setgid(gid
) < 0)
2006 return posix_error();
2010 #endif /* HAVE_SETGID */
2014 static char posix_waitpid__doc__
[] =
2015 "waitpid(pid, options) -> (pid, status)\n\
2016 Wait for completion of a give child process.";
2019 posix_waitpid(self
, args
)
2026 #define status_i (status.w_status)
2029 #define status_i status
2033 if (!PyArg_Parse(args
, "(ii)", &pid
, &options
))
2035 Py_BEGIN_ALLOW_THREADS
2037 pid
= wait4(pid
, &status
, options
, NULL
);
2039 pid
= waitpid(pid
, &status
, options
);
2041 Py_END_ALLOW_THREADS
2043 return posix_error();
2045 return Py_BuildValue("ii", pid
, status_i
);
2047 #endif /* HAVE_WAITPID */
2051 static char posix_wait__doc__
[] =
2052 "wait() -> (pid, status)\n\
2053 Wait for completion of a child process.";
2056 posix_wait(self
, args
)
2063 #define status_i (status.w_status)
2066 #define status_i status
2069 Py_BEGIN_ALLOW_THREADS
2070 pid
= wait(&status
);
2071 Py_END_ALLOW_THREADS
2073 return posix_error();
2075 return Py_BuildValue("ii", pid
, status_i
);
2080 static char posix_lstat__doc__
[] =
2081 "lstat(path) -> (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
2082 Like stat(path), but do not follow symbolic links.";
2085 posix_lstat(self
, args
)
2090 return posix_do_stat(self
, args
, lstat
);
2091 #else /* !HAVE_LSTAT */
2092 return posix_do_stat(self
, args
, stat
);
2093 #endif /* !HAVE_LSTAT */
2097 #ifdef HAVE_READLINK
2098 static char posix_readlink__doc__
[] =
2099 "readlink(path) -> path\n\
2100 Return a string representing the path to which the symbolic link points.";
2103 posix_readlink(self
, args
)
2107 char buf
[MAXPATHLEN
];
2110 if (!PyArg_Parse(args
, "s", &path
))
2112 Py_BEGIN_ALLOW_THREADS
2113 n
= readlink(path
, buf
, (int) sizeof buf
);
2114 Py_END_ALLOW_THREADS
2116 return posix_error_with_filename(path
);
2117 return PyString_FromStringAndSize(buf
, n
);
2119 #endif /* HAVE_READLINK */
2123 static char posix_symlink__doc__
[] =
2124 "symlink(src, dst) -> None\n\
2125 Create a symbolic link.";
2128 posix_symlink(self
, args
)
2132 return posix_2str(args
, symlink
);
2134 #endif /* HAVE_SYMLINK */
2139 #define HZ 60 /* Universal constant :-) */
2142 #if defined(PYCC_VACPP) && defined(PYOS_OS2)
2148 Py_BEGIN_ALLOW_THREADS
2149 DosQuerySysInfo(QSV_MS_COUNT
, QSV_MS_COUNT
, &value
, sizeof(value
));
2150 Py_END_ALLOW_THREADS
2156 posix_times(self
, args
)
2160 if (!PyArg_NoArgs(args
))
2163 /* Currently Only Uptime is Provided -- Others Later */
2164 return Py_BuildValue("ddddd",
2165 (double)0 /* t.tms_utime / HZ */,
2166 (double)0 /* t.tms_stime / HZ */,
2167 (double)0 /* t.tms_cutime / HZ */,
2168 (double)0 /* t.tms_cstime / HZ */,
2169 (double)system_uptime() / 1000);
2173 posix_times(self
, args
)
2179 if (!PyArg_NoArgs(args
))
2183 if (c
== (clock_t) -1)
2184 return posix_error();
2185 return Py_BuildValue("ddddd",
2186 (double)t
.tms_utime
/ HZ
,
2187 (double)t
.tms_stime
/ HZ
,
2188 (double)t
.tms_cutime
/ HZ
,
2189 (double)t
.tms_cstime
/ HZ
,
2192 #endif /* not OS2 */
2193 #endif /* HAVE_TIMES */
2197 #define HAVE_TIMES /* so the method table will pick it up */
2199 posix_times(self
, args
)
2203 FILETIME create
, exit
, kernel
, user
;
2205 if (!PyArg_NoArgs(args
))
2207 hProc
= GetCurrentProcess();
2208 GetProcessTimes(hProc
, &create
, &exit
, &kernel
, &user
);
2209 /* The fields of a FILETIME structure are the hi and lo part
2210 of a 64-bit value expressed in 100 nanosecond units.
2211 1e7 is one second in such units; 1e-7 the inverse.
2212 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
2214 return Py_BuildValue(
2216 (double)(kernel
.dwHighDateTime
*429.4967296 +
2217 kernel
.dwLowDateTime
*1e-7),
2218 (double)(user
.dwHighDateTime
*429.4967296 +
2219 user
.dwLowDateTime
*1e-7),
2224 #endif /* MS_WIN32 */
2227 static char posix_times__doc__
[] =
2228 "times() -> (utime, stime, cutime, cstime, elapsed_time)\n\
2229 Return a tuple of floating point numbers indicating process times.";
2234 static char posix_setsid__doc__
[] =
2235 "setsid() -> None\n\
2236 Call the system call setsid().";
2239 posix_setsid(self
, args
)
2243 if (!PyArg_NoArgs(args
))
2246 return posix_error();
2250 #endif /* HAVE_SETSID */
2253 static char posix_setpgid__doc__
[] =
2254 "setpgid(pid, pgrp) -> None\n\
2255 Call the system call setpgid().";
2258 posix_setpgid(self
, args
)
2263 if (!PyArg_Parse(args
, "(ii)", &pid
, &pgrp
))
2265 if (setpgid(pid
, pgrp
) < 0)
2266 return posix_error();
2270 #endif /* HAVE_SETPGID */
2273 #ifdef HAVE_TCGETPGRP
2274 static char posix_tcgetpgrp__doc__
[] =
2275 "tcgetpgrp(fd) -> pgid\n\
2276 Return the process group associated with the terminal given by a fd.";
2279 posix_tcgetpgrp(self
, args
)
2284 if (!PyArg_Parse(args
, "i", &fd
))
2286 pgid
= tcgetpgrp(fd
);
2288 return posix_error();
2289 return PyInt_FromLong((long)pgid
);
2291 #endif /* HAVE_TCGETPGRP */
2294 #ifdef HAVE_TCSETPGRP
2295 static char posix_tcsetpgrp__doc__
[] =
2296 "tcsetpgrp(fd, pgid) -> None\n\
2297 Set the process group associated with the terminal given by a fd.";
2300 posix_tcsetpgrp(self
, args
)
2305 if (!PyArg_Parse(args
, "(ii)", &fd
, &pgid
))
2307 if (tcsetpgrp(fd
, pgid
) < 0)
2308 return posix_error();
2312 #endif /* HAVE_TCSETPGRP */
2314 /* Functions acting on file descriptors */
2316 static char posix_open__doc__
[] =
2317 "open(filename, flag [, mode=0777]) -> fd\n\
2318 Open a file (for low level IO).";
2321 posix_open(self
, args
)
2329 if (!PyArg_ParseTuple(args
, "si|i", &file
, &flag
, &mode
))
2332 Py_BEGIN_ALLOW_THREADS
2333 fd
= open(file
, flag
, mode
);
2334 Py_END_ALLOW_THREADS
2336 return posix_error_with_filename(file
);
2337 return PyInt_FromLong((long)fd
);
2341 static char posix_close__doc__
[] =
2342 "close(fd) -> None\n\
2343 Close a file descriptor (for low level IO).";
2346 posix_close(self
, args
)
2351 if (!PyArg_Parse(args
, "i", &fd
))
2353 Py_BEGIN_ALLOW_THREADS
2355 Py_END_ALLOW_THREADS
2357 return posix_error();
2363 static char posix_dup__doc__
[] =
2365 Return a duplicate of a file descriptor.";
2368 posix_dup(self
, args
)
2373 if (!PyArg_Parse(args
, "i", &fd
))
2375 Py_BEGIN_ALLOW_THREADS
2377 Py_END_ALLOW_THREADS
2379 return posix_error();
2380 return PyInt_FromLong((long)fd
);
2384 static char posix_dup2__doc__
[] =
2385 "dup2(fd, fd2) -> None\n\
2386 Duplicate file descriptor.";
2389 posix_dup2(self
, args
)
2394 if (!PyArg_Parse(args
, "(ii)", &fd
, &fd2
))
2396 Py_BEGIN_ALLOW_THREADS
2397 res
= dup2(fd
, fd2
);
2398 Py_END_ALLOW_THREADS
2400 return posix_error();
2406 static char posix_lseek__doc__
[] =
2407 "lseek(fd, pos, how) -> newpos\n\
2408 Set the current position of a file descriptor.";
2411 posix_lseek(self
, args
)
2418 if (!PyArg_Parse(args
, "(iOi)", &fd
, &posobj
, &how
))
2421 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
2423 case 0: how
= SEEK_SET
; break;
2424 case 1: how
= SEEK_CUR
; break;
2425 case 2: how
= SEEK_END
; break;
2427 #endif /* SEEK_END */
2429 #if !defined(HAVE_LARGEFILE_SUPPORT)
2430 pos
= PyInt_AsLong(posobj
);
2432 pos
= PyLong_Check(posobj
) ?
2433 PyLong_AsLongLong(posobj
) : PyInt_AsLong(posobj
);
2435 if (PyErr_Occurred())
2438 Py_BEGIN_ALLOW_THREADS
2439 res
= lseek(fd
, pos
, how
);
2440 Py_END_ALLOW_THREADS
2442 return posix_error();
2444 #if !defined(HAVE_LARGEFILE_SUPPORT)
2445 return PyInt_FromLong(res
);
2447 return PyLong_FromLongLong(res
);
2452 static char posix_read__doc__
[] =
2453 "read(fd, buffersize) -> string\n\
2454 Read a file descriptor.";
2457 posix_read(self
, args
)
2463 if (!PyArg_Parse(args
, "(ii)", &fd
, &size
))
2465 buffer
= PyString_FromStringAndSize((char *)NULL
, size
);
2468 Py_BEGIN_ALLOW_THREADS
2469 n
= read(fd
, PyString_AsString(buffer
), size
);
2470 Py_END_ALLOW_THREADS
2473 return posix_error();
2476 _PyString_Resize(&buffer
, n
);
2481 static char posix_write__doc__
[] =
2482 "write(fd, string) -> byteswritten\n\
2483 Write a string to a file descriptor.";
2486 posix_write(self
, args
)
2492 if (!PyArg_Parse(args
, "(is#)", &fd
, &buffer
, &size
))
2494 Py_BEGIN_ALLOW_THREADS
2495 size
= write(fd
, buffer
, size
);
2496 Py_END_ALLOW_THREADS
2498 return posix_error();
2499 return PyInt_FromLong((long)size
);
2503 static char posix_fstat__doc__
[]=
2504 "fstat(fd) -> (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
2505 Like stat(), but for an open file descriptor.";
2508 posix_fstat(self
, args
)
2515 if (!PyArg_Parse(args
, "i", &fd
))
2517 Py_BEGIN_ALLOW_THREADS
2518 res
= fstat(fd
, &st
);
2519 Py_END_ALLOW_THREADS
2521 return posix_error();
2522 #if !defined(HAVE_LARGEFILE_SUPPORT)
2523 return Py_BuildValue("(llllllllll)",
2535 return Py_BuildValue("(lLllllLlll)",
2537 (LONG_LONG
)st
.st_ino
,
2542 (LONG_LONG
)st
.st_size
,
2550 static char posix_fdopen__doc__
[] =
2551 "fdopen(fd, [, mode='r' [, bufsize]]) -> file_object\n\
2552 Return an open file object connected to a file descriptor.";
2555 posix_fdopen(self
, args
)
2559 extern int fclose
Py_PROTO((FILE *));
2565 if (!PyArg_ParseTuple(args
, "i|si", &fd
, &mode
, &bufsize
))
2568 Py_BEGIN_ALLOW_THREADS
2569 fp
= fdopen(fd
, mode
);
2570 Py_END_ALLOW_THREADS
2572 return posix_error();
2573 f
= PyFile_FromFile(fp
, "(fdopen)", mode
, fclose
);
2575 PyFile_SetBufSize(f
, bufsize
);
2581 static char posix_pipe__doc__
[] =
2582 "pipe() -> (read_end, write_end)\n\
2586 posix_pipe(self
, args
)
2590 #if defined(PYOS_OS2)
2594 if (!PyArg_Parse(args
, ""))
2597 Py_BEGIN_ALLOW_THREADS
2598 rc
= DosCreatePipe( &read
, &write
, 4096);
2599 Py_END_ALLOW_THREADS
2601 return os2_error(rc
);
2603 return Py_BuildValue("(ii)", read
, write
);
2605 #if !defined(MS_WIN32)
2608 if (!PyArg_Parse(args
, ""))
2610 Py_BEGIN_ALLOW_THREADS
2612 Py_END_ALLOW_THREADS
2614 return posix_error();
2615 return Py_BuildValue("(ii)", fds
[0], fds
[1]);
2616 #else /* MS_WIN32 */
2618 int read_fd
, write_fd
;
2620 if (!PyArg_Parse(args
, ""))
2622 Py_BEGIN_ALLOW_THREADS
2623 ok
= CreatePipe(&read
, &write
, NULL
, 0);
2624 Py_END_ALLOW_THREADS
2626 return posix_error();
2627 read_fd
= _open_osfhandle((long)read
, 0);
2628 write_fd
= _open_osfhandle((long)write
, 1);
2629 return Py_BuildValue("(ii)", read_fd
, write_fd
);
2630 #endif /* MS_WIN32 */
2633 #endif /* HAVE_PIPE */
2637 static char posix_mkfifo__doc__
[] =
2638 "mkfifo(file, [, mode=0666]) -> None\n\
2639 Create a FIFO (a POSIX named pipe).";
2642 posix_mkfifo(self
, args
)
2649 if (!PyArg_ParseTuple(args
, "s|i", &file
, &mode
))
2651 Py_BEGIN_ALLOW_THREADS
2652 res
= mkfifo(file
, mode
);
2653 Py_END_ALLOW_THREADS
2655 return posix_error();
2662 #ifdef HAVE_FTRUNCATE
2663 static char posix_ftruncate__doc__
[] =
2664 "ftruncate(fd, length) -> None\n\
2665 Truncate a file to a specified length.";
2668 posix_ftruncate(self
, args
)
2669 PyObject
*self
; /* Not used */
2677 if (!PyArg_Parse(args
, "(iO)", &fd
, &lenobj
))
2680 #if !defined(HAVE_LARGEFILE_SUPPORT)
2681 length
= PyInt_AsLong(lenobj
);
2683 length
= PyLong_Check(lenobj
) ?
2684 PyLong_AsLongLong(lenobj
) : PyInt_AsLong(lenobj
);
2686 if (PyErr_Occurred())
2689 Py_BEGIN_ALLOW_THREADS
2690 res
= ftruncate(fd
, length
);
2691 Py_END_ALLOW_THREADS
2693 PyErr_SetFromErrno(PyExc_IOError
);
2703 /* Steve Spicklemire got this putenv from NeXTAnswers */
2705 putenv(char *newval
)
2707 extern char **environ
;
2709 static int firstTime
= 1;
2715 if (!(np
= strchr(newval
, '=')))
2720 for (ep
=environ
; *ep
; ep
++)
2722 /* this should always be true... */
2723 if (cp
= strchr(*ep
, '='))
2726 if (!strcmp(*ep
, newval
))
2744 /* the string was already there:
2745 just replace it with the new one */
2750 /* expand environ by one */
2751 for (esiz
=2, ep
=environ
; *ep
; ep
++)
2757 if (!(newenv
= malloc(esiz
* sizeof(char *))))
2760 for (ep
=environ
, epp
=newenv
; *ep
;)
2768 if (!(environ
= realloc(environ
, esiz
* sizeof(char *))))
2770 environ
[esiz
- 2] = newval
;
2771 environ
[esiz
- 1] = (char *) 0;
2781 static char posix_putenv__doc__
[] =
2782 "putenv(key, value) -> None\n\
2783 Change or add an environment variable.";
2786 /* We have putenv(), but not in the headers (as of PR2). - [cjh] */
2787 int putenv( const char *str
);
2790 /* Save putenv() parameters as values here, so we can collect them when they
2791 * get re-set with another call for the same key. */
2792 static PyObject
*posix_putenv_garbage
;
2795 posix_putenv(self
, args
)
2803 if (!PyArg_ParseTuple(args
, "ss", &s1
, &s2
))
2806 #if defined(PYOS_OS2)
2807 if (stricmp(s1
, "BEGINLIBPATH") == 0) {
2810 if (strlen(s2
) == 0) /* If New Value is an Empty String */
2811 s2
= NULL
; /* Then OS/2 API Wants a NULL to Undefine It */
2813 rc
= DosSetExtLIBPATH(s2
, BEGIN_LIBPATH
);
2815 return os2_error(rc
);
2817 } else if (stricmp(s1
, "ENDLIBPATH") == 0) {
2820 if (strlen(s2
) == 0) /* If New Value is an Empty String */
2821 s2
= NULL
; /* Then OS/2 API Wants a NULL to Undefine It */
2823 rc
= DosSetExtLIBPATH(s2
, END_LIBPATH
);
2825 return os2_error(rc
);
2829 /* XXX This can leak memory -- not easy to fix :-( */
2830 newstr
= PyString_FromStringAndSize(NULL
, strlen(s1
) + strlen(s2
) + 2);
2832 return PyErr_NoMemory();
2833 new = PyString_AS_STRING(newstr
);
2834 (void) sprintf(new, "%s=%s", s1
, s2
);
2839 /* Install the first arg and newstr in posix_putenv_garbage;
2840 * this will cause previous value to be collected. This has to
2841 * happen after the real putenv() call because the old value
2842 * was still accessible until then. */
2843 if (PyDict_SetItem(posix_putenv_garbage
,
2844 PyTuple_GET_ITEM(args
, 0), newstr
)) {
2845 /* really not much we can do; just leak */
2852 #if defined(PYOS_OS2)
2860 #ifdef HAVE_STRERROR
2861 static char posix_strerror__doc__
[] =
2862 "strerror(code) -> string\n\
2863 Translate an error code to a message string.";
2866 posix_strerror(self
, args
)
2872 if (!PyArg_ParseTuple(args
, "i", &code
))
2874 message
= strerror(code
);
2875 if (message
== NULL
) {
2876 PyErr_SetString(PyExc_ValueError
,
2877 "strerror code out of range");
2880 return PyString_FromString(message
);
2882 #endif /* strerror */
2885 #ifdef HAVE_SYS_WAIT_H
2888 static char posix_WIFSTOPPED__doc__
[] =
2889 "WIFSTOPPED(status) -> Boolean\n\
2890 Return true if the process returning 'status' was stopped.";
2893 posix_WIFSTOPPED(self
, args
)
2899 #define status_i (status.w_status)
2902 #define status_i status
2906 if (!PyArg_Parse(args
, "i", &status_i
))
2911 return Py_BuildValue("i", WIFSTOPPED(status
));
2913 #endif /* WIFSTOPPED */
2916 static char posix_WIFSIGNALED__doc__
[] =
2917 "WIFSIGNALED(status) -> Boolean\n\
2918 Return true if the process returning 'status' was terminated by a signal.";
2921 posix_WIFSIGNALED(self
, args
)
2927 #define status_i (status.w_status)
2930 #define status_i status
2934 if (!PyArg_Parse(args
, "i", &status_i
))
2939 return Py_BuildValue("i", WIFSIGNALED(status
));
2941 #endif /* WIFSIGNALED */
2944 static char posix_WIFEXITED__doc__
[] =
2945 "WIFEXITED(status) -> Boolean\n\
2946 Return true if the process returning 'status' exited using the exit()\n\
2950 posix_WIFEXITED(self
, args
)
2956 #define status_i (status.w_status)
2959 #define status_i status
2963 if (!PyArg_Parse(args
, "i", &status_i
))
2968 return Py_BuildValue("i", WIFEXITED(status
));
2970 #endif /* WIFEXITED */
2973 static char posix_WEXITSTATUS__doc__
[] =
2974 "WEXITSTATUS(status) -> integer\n\
2975 Return the process return code from 'status'.";
2978 posix_WEXITSTATUS(self
, args
)
2984 #define status_i (status.w_status)
2987 #define status_i status
2991 if (!PyArg_Parse(args
, "i", &status_i
))
2996 return Py_BuildValue("i", WEXITSTATUS(status
));
2998 #endif /* WEXITSTATUS */
3001 static char posix_WTERMSIG__doc__
[] =
3002 "WTERMSIG(status) -> integer\n\
3003 Return the signal that terminated the process that provided the 'status'\n\
3007 posix_WTERMSIG(self
, args
)
3013 #define status_i (status.w_status)
3016 #define status_i status
3020 if (!PyArg_Parse(args
, "i", &status_i
))
3025 return Py_BuildValue("i", WTERMSIG(status
));
3027 #endif /* WTERMSIG */
3030 static char posix_WSTOPSIG__doc__
[] =
3031 "WSTOPSIG(status) -> integer\n\
3032 Return the signal that stopped the process that provided the 'status' value.";
3035 posix_WSTOPSIG(self
, args
)
3041 #define status_i (status.w_status)
3044 #define status_i status
3048 if (!PyArg_Parse(args
, "i", &status_i
))
3053 return Py_BuildValue("i", WSTOPSIG(status
));
3055 #endif /* WSTOPSIG */
3057 #endif /* HAVE_SYS_WAIT_H */
3060 #if defined(HAVE_FSTATVFS)
3061 #include <sys/statvfs.h>
3063 static char posix_fstatvfs__doc__
[] =
3064 "fstatvfs(fd) -> \n\
3065 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
3066 Perform an fstatvfs system call on the given fd.";
3069 posix_fstatvfs(self
, args
)
3075 if (!PyArg_ParseTuple(args
, "i", &fd
))
3077 Py_BEGIN_ALLOW_THREADS
3078 res
= fstatvfs(fd
, &st
);
3079 Py_END_ALLOW_THREADS
3081 return posix_error();
3082 #if !defined(HAVE_LARGEFILE_SUPPORT)
3083 return Py_BuildValue("(llllllllll)",
3093 (long) st
.f_namemax
);
3095 return Py_BuildValue("(llLLLLLLll)",
3098 (LONG_LONG
) st
.f_blocks
,
3099 (LONG_LONG
) st
.f_bfree
,
3100 (LONG_LONG
) st
.f_bavail
,
3101 (LONG_LONG
) st
.f_files
,
3102 (LONG_LONG
) st
.f_ffree
,
3103 (LONG_LONG
) st
.f_favail
,
3105 (long) st
.f_namemax
);
3108 #endif /* HAVE_FSTATVFS */
3111 #if defined(HAVE_STATVFS)
3112 #include <sys/statvfs.h>
3114 static char posix_statvfs__doc__
[] =
3115 "statvfs(path) -> \n\
3116 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax)\n\
3117 Perform a statvfs system call on the given path.";
3120 posix_statvfs(self
, args
)
3127 if (!PyArg_ParseTuple(args
, "s", &path
))
3129 Py_BEGIN_ALLOW_THREADS
3130 res
= statvfs(path
, &st
);
3131 Py_END_ALLOW_THREADS
3133 return posix_error_with_filename(path
);
3134 #if !defined(HAVE_LARGEFILE_SUPPORT)
3135 return Py_BuildValue("(llllllllll)",
3145 (long) st
.f_namemax
);
3146 #else /* HAVE_LARGEFILE_SUPPORT */
3147 return Py_BuildValue("(llLLLLLLll)",
3150 (LONG_LONG
) st
.f_blocks
,
3151 (LONG_LONG
) st
.f_bfree
,
3152 (LONG_LONG
) st
.f_bavail
,
3153 (LONG_LONG
) st
.f_files
,
3154 (LONG_LONG
) st
.f_ffree
,
3155 (LONG_LONG
) st
.f_favail
,
3157 (long) st
.f_namemax
);
3160 #endif /* HAVE_STATVFS */
3163 static PyMethodDef posix_methods
[] = {
3164 {"access", posix_access
, 0, posix_access__doc__
},
3166 {"ttyname", posix_ttyname
, 0, posix_ttyname__doc__
},
3168 {"chdir", posix_chdir
, 0, posix_chdir__doc__
},
3169 {"chmod", posix_chmod
, 0, posix_chmod__doc__
},
3171 {"chown", posix_chown
, 0, posix_chown__doc__
},
3172 #endif /* HAVE_CHOWN */
3174 {"getcwd", posix_getcwd
, 0, posix_getcwd__doc__
},
3177 {"link", posix_link
, 0, posix_link__doc__
},
3178 #endif /* HAVE_LINK */
3179 {"listdir", posix_listdir
, 0, posix_listdir__doc__
},
3180 {"lstat", posix_lstat
, 0, posix_lstat__doc__
},
3181 {"mkdir", posix_mkdir
, 1, posix_mkdir__doc__
},
3183 {"nice", posix_nice
, 0, posix_nice__doc__
},
3184 #endif /* HAVE_NICE */
3185 #ifdef HAVE_READLINK
3186 {"readlink", posix_readlink
, 0, posix_readlink__doc__
},
3187 #endif /* HAVE_READLINK */
3188 {"rename", posix_rename
, 0, posix_rename__doc__
},
3189 {"rmdir", posix_rmdir
, 0, posix_rmdir__doc__
},
3190 {"stat", posix_stat
, 0, posix_stat__doc__
},
3192 {"symlink", posix_symlink
, 0, posix_symlink__doc__
},
3193 #endif /* HAVE_SYMLINK */
3195 {"system", posix_system
, 0, posix_system__doc__
},
3197 {"umask", posix_umask
, 0, posix_umask__doc__
},
3199 {"uname", posix_uname
, 0, posix_uname__doc__
},
3200 #endif /* HAVE_UNAME */
3201 {"unlink", posix_unlink
, 0, posix_unlink__doc__
},
3202 {"remove", posix_unlink
, 0, posix_remove__doc__
},
3203 {"utime", posix_utime
, 0, posix_utime__doc__
},
3205 {"times", posix_times
, 0, posix_times__doc__
},
3206 #endif /* HAVE_TIMES */
3207 {"_exit", posix__exit
, 0, posix__exit__doc__
},
3209 {"execv", posix_execv
, 0, posix_execv__doc__
},
3210 {"execve", posix_execve
, 0, posix_execve__doc__
},
3211 #endif /* HAVE_EXECV */
3213 {"spawnv", posix_spawnv
, 0, posix_spawnv__doc__
},
3214 {"spawnve", posix_spawnve
, 0, posix_spawnve__doc__
},
3215 #endif /* HAVE_SPAWNV */
3217 {"fork", posix_fork
, 0, posix_fork__doc__
},
3218 #endif /* HAVE_FORK */
3220 {"getegid", posix_getegid
, 0, posix_getegid__doc__
},
3221 #endif /* HAVE_GETEGID */
3223 {"geteuid", posix_geteuid
, 0, posix_geteuid__doc__
},
3224 #endif /* HAVE_GETEUID */
3226 {"getgid", posix_getgid
, 0, posix_getgid__doc__
},
3227 #endif /* HAVE_GETGID */
3228 {"getpid", posix_getpid
, 0, posix_getpid__doc__
},
3230 {"getpgrp", posix_getpgrp
, 0, posix_getpgrp__doc__
},
3231 #endif /* HAVE_GETPGRP */
3233 {"getppid", posix_getppid
, 0, posix_getppid__doc__
},
3234 #endif /* HAVE_GETPPID */
3236 {"getuid", posix_getuid
, 0, posix_getuid__doc__
},
3237 #endif /* HAVE_GETUID */
3239 {"kill", posix_kill
, 0, posix_kill__doc__
},
3240 #endif /* HAVE_KILL */
3242 {"plock", posix_plock
, 0, posix_plock__doc__
},
3243 #endif /* HAVE_PLOCK */
3245 {"popen", posix_popen
, 1, posix_popen__doc__
},
3246 #endif /* HAVE_POPEN */
3248 {"setuid", posix_setuid
, 0, posix_setuid__doc__
},
3249 #endif /* HAVE_SETUID */
3251 {"setgid", posix_setgid
, 0, posix_setgid__doc__
},
3252 #endif /* HAVE_SETGID */
3254 {"setpgrp", posix_setpgrp
, 0, posix_setpgrp__doc__
},
3255 #endif /* HAVE_SETPGRP */
3257 {"wait", posix_wait
, 0, posix_wait__doc__
},
3258 #endif /* HAVE_WAIT */
3260 {"waitpid", posix_waitpid
, 0, posix_waitpid__doc__
},
3261 #endif /* HAVE_WAITPID */
3263 {"setsid", posix_setsid
, 0, posix_setsid__doc__
},
3264 #endif /* HAVE_SETSID */
3266 {"setpgid", posix_setpgid
, 0, posix_setpgid__doc__
},
3267 #endif /* HAVE_SETPGID */
3268 #ifdef HAVE_TCGETPGRP
3269 {"tcgetpgrp", posix_tcgetpgrp
, 0, posix_tcgetpgrp__doc__
},
3270 #endif /* HAVE_TCGETPGRP */
3271 #ifdef HAVE_TCSETPGRP
3272 {"tcsetpgrp", posix_tcsetpgrp
, 0, posix_tcsetpgrp__doc__
},
3273 #endif /* HAVE_TCSETPGRP */
3274 {"open", posix_open
, 1, posix_open__doc__
},
3275 {"close", posix_close
, 0, posix_close__doc__
},
3276 {"dup", posix_dup
, 0, posix_dup__doc__
},
3277 {"dup2", posix_dup2
, 0, posix_dup2__doc__
},
3278 {"lseek", posix_lseek
, 0, posix_lseek__doc__
},
3279 {"read", posix_read
, 0, posix_read__doc__
},
3280 {"write", posix_write
, 0, posix_write__doc__
},
3281 {"fstat", posix_fstat
, 0, posix_fstat__doc__
},
3282 {"fdopen", posix_fdopen
, 1, posix_fdopen__doc__
},
3284 {"pipe", posix_pipe
, 0, posix_pipe__doc__
},
3287 {"mkfifo", posix_mkfifo
, 1, posix_mkfifo__doc__
},
3289 #ifdef HAVE_FTRUNCATE
3290 {"ftruncate", posix_ftruncate
, 1, posix_ftruncate__doc__
},
3293 {"putenv", posix_putenv
, 1, posix_putenv__doc__
},
3295 #ifdef HAVE_STRERROR
3296 {"strerror", posix_strerror
, 1, posix_strerror__doc__
},
3299 {"fsync", posix_fsync
, 0, posix_fsync__doc__
},
3301 #ifdef HAVE_FDATASYNC
3302 {"fdatasync", posix_fdatasync
, 0, posix_fdatasync__doc__
},
3304 #ifdef HAVE_SYS_WAIT_H
3306 {"WIFSTOPPED", posix_WIFSTOPPED
, 0, posix_WIFSTOPPED__doc__
},
3307 #endif /* WIFSTOPPED */
3309 {"WIFSIGNALED", posix_WIFSIGNALED
, 0, posix_WIFSIGNALED__doc__
},
3310 #endif /* WIFSIGNALED */
3312 {"WIFEXITED", posix_WIFEXITED
, 0, posix_WIFEXITED__doc__
},
3313 #endif /* WIFEXITED */
3315 {"WEXITSTATUS", posix_WEXITSTATUS
, 0, posix_WEXITSTATUS__doc__
},
3316 #endif /* WEXITSTATUS */
3318 {"WTERMSIG", posix_WTERMSIG
, 0, posix_WTERMSIG__doc__
},
3319 #endif /* WTERMSIG */
3321 {"WSTOPSIG", posix_WSTOPSIG
, 0, posix_WSTOPSIG__doc__
},
3322 #endif /* WSTOPSIG */
3323 #endif /* HAVE_SYS_WAIT_H */
3324 #ifdef HAVE_FSTATVFS
3325 {"fstatvfs", posix_fstatvfs
, 1, posix_fstatvfs__doc__
},
3328 {"statvfs", posix_statvfs
, 1, posix_statvfs__doc__
},
3330 {NULL
, NULL
} /* Sentinel */
3335 ins(d
, symbol
, value
)
3340 PyObject
* v
= PyInt_FromLong(value
);
3341 if (!v
|| PyDict_SetItemString(d
, symbol
, v
) < 0)
3342 return -1; /* triggers fatal error */
3348 #if defined(PYOS_OS2)
3349 /* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
3350 static int insertvalues(PyObject
*d
)
3353 ULONG values
[QSV_MAX
+1];
3357 Py_BEGIN_ALLOW_THREADS
3358 rc
= DosQuerySysInfo(1, QSV_MAX
, &values
[1], sizeof(values
));
3359 Py_END_ALLOW_THREADS
3361 if (rc
!= NO_ERROR
) {
3366 if (ins(d
, "meminstalled", values
[QSV_TOTPHYSMEM
])) return -1;
3367 if (ins(d
, "memkernel", values
[QSV_TOTRESMEM
])) return -1;
3368 if (ins(d
, "memvirtual", values
[QSV_TOTAVAILMEM
])) return -1;
3369 if (ins(d
, "maxpathlen", values
[QSV_MAX_PATH_LENGTH
])) return -1;
3370 if (ins(d
, "maxnamelen", values
[QSV_MAX_COMP_LENGTH
])) return -1;
3371 if (ins(d
, "revision", values
[QSV_VERSION_REVISION
])) return -1;
3372 if (ins(d
, "timeslice", values
[QSV_MIN_SLICE
])) return -1;
3374 switch (values
[QSV_VERSION_MINOR
]) {
3375 case 0: ver
= "2.00"; break;
3376 case 10: ver
= "2.10"; break;
3377 case 11: ver
= "2.11"; break;
3378 case 30: ver
= "3.00"; break;
3379 case 40: ver
= "4.00"; break;
3380 case 50: ver
= "5.00"; break;
3382 sprintf(tmp
, "%d-%d", values
[QSV_VERSION_MAJOR
],
3383 values
[QSV_VERSION_MINOR
]);
3387 /* Add Indicator of the Version of the Operating System */
3388 v
= PyString_FromString(ver
);
3389 if (!v
|| PyDict_SetItemString(d
, "version", v
) < 0)
3393 /* Add Indicator of Which Drive was Used to Boot the System */
3394 tmp
[0] = 'A' + values
[QSV_BOOT_DRIVE
] - 1;
3398 v
= PyString_FromString(tmp
);
3399 if (!v
|| PyDict_SetItemString(d
, "bootdrive", v
) < 0)
3412 if (ins(d
, "F_OK", (long)F_OK
)) return -1;
3415 if (ins(d
, "R_OK", (long)R_OK
)) return -1;
3418 if (ins(d
, "W_OK", (long)W_OK
)) return -1;
3421 if (ins(d
, "X_OK", (long)X_OK
)) return -1;
3424 if (ins(d
, "WNOHANG", (long)WNOHANG
)) return -1;
3427 if (ins(d
, "O_RDONLY", (long)O_RDONLY
)) return -1;
3430 if (ins(d
, "O_WRONLY", (long)O_WRONLY
)) return -1;
3433 if (ins(d
, "O_RDWR", (long)O_RDWR
)) return -1;
3436 if (ins(d
, "O_NDELAY", (long)O_NDELAY
)) return -1;
3439 if (ins(d
, "O_NONBLOCK", (long)O_NONBLOCK
)) return -1;
3442 if (ins(d
, "O_APPEND", (long)O_APPEND
)) return -1;
3445 if (ins(d
, "O_DSYNC", (long)O_DSYNC
)) return -1;
3448 if (ins(d
, "O_RSYNC", (long)O_RSYNC
)) return -1;
3451 if (ins(d
, "O_SYNC", (long)O_SYNC
)) return -1;
3454 if (ins(d
, "O_NOCTTY", (long)O_NOCTTY
)) return -1;
3457 if (ins(d
, "O_CREAT", (long)O_CREAT
)) return -1;
3460 if (ins(d
, "O_EXCL", (long)O_EXCL
)) return -1;
3463 if (ins(d
, "O_TRUNC", (long)O_TRUNC
)) return -1;
3466 if (ins(d
, "O_BINARY", (long)O_BINARY
)) return -1;
3469 if (ins(d
, "O_TEXT", (long)O_TEXT
)) return -1;
3473 if (ins(d
, "P_WAIT", (long)_P_WAIT
)) return -1;
3474 if (ins(d
, "P_NOWAIT", (long)_P_NOWAIT
)) return -1;
3475 if (ins(d
, "P_OVERLAY", (long)_OLD_P_OVERLAY
)) return -1;
3476 if (ins(d
, "P_NOWAITO", (long)_P_NOWAITO
)) return -1;
3477 if (ins(d
, "P_DETACH", (long)_P_DETACH
)) return -1;
3480 #if defined(PYOS_OS2)
3481 if (insertvalues(d
)) return -1;
3487 #if ( defined(_MSC_VER) || defined(__WATCOMC__) ) && !defined(__QNX__)
3488 #define INITFUNC initnt
3489 #define MODNAME "nt"
3491 #if defined(PYOS_OS2)
3492 #define INITFUNC initos2
3493 #define MODNAME "os2"
3495 #define INITFUNC initposix
3496 #define MODNAME "posix"
3503 PyObject
*m
, *d
, *v
;
3505 m
= Py_InitModule4(MODNAME
,
3509 PYTHON_API_VERSION
);
3510 d
= PyModule_GetDict(m
);
3512 /* Initialize environ dictionary */
3513 v
= convertenviron();
3514 if (v
== NULL
|| PyDict_SetItemString(d
, "environ", v
) != 0)
3521 PyDict_SetItemString(d
, "error", PyExc_OSError
);
3523 posix_putenv_garbage
= PyDict_New();