blob: 7f2356c067084a7ca52e4aee562ec14cac7af87b [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002/* POSIX module implementation */
3
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004/* This file is also used for Windows NT/MS-Win and OS/2. In that case the
5 module actually calls itself 'nt' or 'os2', not 'posix', and a few
6 functions are either unimplemented or implemented differently. The source
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007 assumes that for Windows NT, the macro 'MS_WINDOWS' is defined independent
Guido van Rossumad0ee831995-03-01 10:34:45 +00008 of the compiler used. Different compilers define their own feature
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009 test macro, e.g. '__BORLANDC__' or '_MSC_VER'. For OS/2, the compiler
10 independent macro PYOS_OS2 should be defined. On OS/2 the default
11 compiler is assumed to be IBM's VisualAge C++ (VACPP). PYCC_GCC is used
12 as the compiler specific macro for the EMX port of gcc to OS/2. */
Guido van Rossumad0ee831995-03-01 10:34:45 +000013
Guido van Rossuma4916fa1996-05-23 22:58:55 +000014/* See also ../Dos/dosmodule.c */
Guido van Rossumad0ee831995-03-01 10:34:45 +000015
Ronald Oussorend06b6f22006-04-23 11:59:25 +000016#ifdef __APPLE__
17 /*
18 * Step 1 of support for weak-linking a number of symbols existing on
19 * OSX 10.4 and later, see the comment in the #ifdef __APPLE__ block
20 * at the end of this file for more information.
21 */
22# pragma weak lchown
23# pragma weak statvfs
24# pragma weak fstatvfs
25
26#endif /* __APPLE__ */
27
Thomas Wouters68bc4f92006-03-01 01:05:10 +000028#define PY_SSIZE_T_CLEAN
29
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000030#include "Python.h"
31#include "structseq.h"
32
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000033#if defined(__VMS)
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000034# include <unixio.h>
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000035#endif /* defined(__VMS) */
36
Anthony Baxterac6bd462006-04-13 02:06:09 +000037#ifdef __cplusplus
38extern "C" {
39#endif
40
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000041PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000042"This module provides access to operating system functionality that is\n\
43standardized by the C Standard and the POSIX standard (a thinly\n\
44disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000045corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000046
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000047#ifndef Py_USING_UNICODE
48/* This is used in signatures of functions. */
49#define Py_UNICODE void
50#endif
51
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000052#if defined(PYOS_OS2)
53#define INCL_DOS
54#define INCL_DOSERRORS
55#define INCL_DOSPROCESS
56#define INCL_NOPMAPI
57#include <os2.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000058#if defined(PYCC_GCC)
59#include <ctype.h>
60#include <io.h>
61#include <stdio.h>
62#include <process.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000063#endif
Andrew MacIntyreda4d6cb2004-03-29 11:53:38 +000064#include "osdefs.h"
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000065#endif
66
Guido van Rossumb6775db1994-08-01 11:34:53 +000067#include <sys/types.h>
68#include <sys/stat.h>
Guido van Rossuma6535fd2001-10-18 19:44:10 +000069
Guido van Rossum36bc6801995-06-14 22:54:23 +000070#ifdef HAVE_SYS_WAIT_H
71#include <sys/wait.h> /* For WNOHANG */
72#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000073
Guido van Rossuma376cc51996-12-05 23:43:35 +000074#include <signal.h>
Guido van Rossuma376cc51996-12-05 23:43:35 +000075
Guido van Rossumb6775db1994-08-01 11:34:53 +000076#ifdef HAVE_FCNTL_H
77#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000078#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000079
Guido van Rossuma6535fd2001-10-18 19:44:10 +000080#ifdef HAVE_GRP_H
81#include <grp.h>
82#endif
83
Barry Warsaw5676bd12003-01-07 20:57:09 +000084#ifdef HAVE_SYSEXITS_H
85#include <sysexits.h>
86#endif /* HAVE_SYSEXITS_H */
87
Anthony Baxter8a560de2004-10-13 15:30:56 +000088#ifdef HAVE_SYS_LOADAVG_H
89#include <sys/loadavg.h>
90#endif
91
Guido van Rossuma4916fa1996-05-23 22:58:55 +000092/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +000093/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000094#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000095#include <process.h>
96#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +000097#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000098#define HAVE_GETCWD 1
99#define HAVE_OPENDIR 1
100#define HAVE_SYSTEM 1
101#if defined(__OS2__)
102#define HAVE_EXECV 1
103#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +0000104#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000105#include <process.h>
106#else
107#ifdef __BORLANDC__ /* Borland compiler */
108#define HAVE_EXECV 1
109#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000110#define HAVE_OPENDIR 1
111#define HAVE_PIPE 1
112#define HAVE_POPEN 1
113#define HAVE_SYSTEM 1
114#define HAVE_WAIT 1
115#else
116#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000117#define HAVE_GETCWD 1
Guido van Rossuma1065681999-01-25 23:20:23 +0000118#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000119#define HAVE_EXECV 1
120#define HAVE_PIPE 1
121#define HAVE_POPEN 1
122#define HAVE_SYSTEM 1
Tim Petersab034fa2002-02-01 11:27:43 +0000123#define HAVE_CWAIT 1
Tim Peters11b23062003-04-23 02:39:17 +0000124#define HAVE_FSYNC 1
125#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000126#else
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000127#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
128/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000129#else /* all other compilers */
130/* Unix functions that the configure script doesn't check for */
131#define HAVE_EXECV 1
132#define HAVE_FORK 1
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000133#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
134#define HAVE_FORK1 1
135#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000136#define HAVE_GETCWD 1
137#define HAVE_GETEGID 1
138#define HAVE_GETEUID 1
139#define HAVE_GETGID 1
140#define HAVE_GETPPID 1
141#define HAVE_GETUID 1
142#define HAVE_KILL 1
143#define HAVE_OPENDIR 1
144#define HAVE_PIPE 1
Martin v. Löwis212ede62003-09-20 11:20:30 +0000145#ifndef __rtems__
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000146#define HAVE_POPEN 1
Martin v. Löwis212ede62003-09-20 11:20:30 +0000147#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000148#define HAVE_SYSTEM 1
149#define HAVE_WAIT 1
Guido van Rossumd371ff11999-01-25 16:12:23 +0000150#define HAVE_TTYNAME 1
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000151#endif /* PYOS_OS2 && PYCC_GCC && __VMS */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000152#endif /* _MSC_VER */
153#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000154#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000155#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000156
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000157#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000158
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000159#if defined(__sgi)&&_COMPILER_VERSION>=700
160/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
161 (default) */
162extern char *ctermid_r(char *);
163#endif
164
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000165#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000166#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000167extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000168#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000169#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000170extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000171#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000172extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000173#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000174#endif
175#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000176extern int chdir(char *);
177extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000178#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000179extern int chdir(const char *);
180extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000181#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000182#ifdef __BORLANDC__
183extern int chmod(const char *, int);
184#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000185extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000186#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000187extern int chown(const char *, uid_t, gid_t);
188extern char *getcwd(char *, int);
189extern char *strerror(int);
190extern int link(const char *, const char *);
191extern int rename(const char *, const char *);
192extern int stat(const char *, struct stat *);
193extern int unlink(const char *);
194extern int pclose(FILE *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000195#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000196extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000197#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000198#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000199extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000200#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000201#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000202
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000203#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000204
Guido van Rossumb6775db1994-08-01 11:34:53 +0000205#ifdef HAVE_UTIME_H
206#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000207#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000208
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000209#ifdef HAVE_SYS_UTIME_H
210#include <sys/utime.h>
211#define HAVE_UTIME_H /* pretend we do for the rest of this file */
212#endif /* HAVE_SYS_UTIME_H */
213
Guido van Rossumb6775db1994-08-01 11:34:53 +0000214#ifdef HAVE_SYS_TIMES_H
215#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000216#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000217
218#ifdef HAVE_SYS_PARAM_H
219#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000220#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000221
222#ifdef HAVE_SYS_UTSNAME_H
223#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000224#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000225
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000226#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000227#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000228#define NAMLEN(dirent) strlen((dirent)->d_name)
229#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000230#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000231#include <direct.h>
232#define NAMLEN(dirent) strlen((dirent)->d_name)
233#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000234#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000235#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000236#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000237#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000238#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000239#endif
240#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000241#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000242#endif
243#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000244#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000245#endif
246#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000247
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000248#ifdef _MSC_VER
Guido van Rossumb6775db1994-08-01 11:34:53 +0000249#include <direct.h>
250#include <io.h>
251#include <process.h>
Tim Petersbc2e10e2002-03-03 23:17:02 +0000252#include "osdefs.h"
Martin v. Löwisdc3883f2004-08-29 15:46:35 +0000253#define _WIN32_WINNT 0x0400 /* Needed for CryptoAPI on some systems */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000254#include <windows.h>
Tim Petersee66d0c2002-07-15 16:10:55 +0000255#include <shellapi.h> /* for ShellExecute() */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000256#define popen _popen
Guido van Rossum794d8131994-08-23 13:48:48 +0000257#define pclose _pclose
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000258#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000259
Guido van Rossumd48f2521997-12-05 22:19:34 +0000260#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000261#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000262#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000263
Tim Petersbc2e10e2002-03-03 23:17:02 +0000264#ifndef MAXPATHLEN
Thomas Wouters1ddba602006-04-25 15:29:46 +0000265#if defined(PATH_MAX) && PATH_MAX > 1024
266#define MAXPATHLEN PATH_MAX
267#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000268#define MAXPATHLEN 1024
Thomas Wouters1ddba602006-04-25 15:29:46 +0000269#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000270#endif /* MAXPATHLEN */
271
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000272#ifdef UNION_WAIT
273/* Emulate some macros on systems that have a union instead of macros */
274
275#ifndef WIFEXITED
276#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
277#endif
278
279#ifndef WEXITSTATUS
280#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
281#endif
282
283#ifndef WTERMSIG
284#define WTERMSIG(u_wait) ((u_wait).w_termsig)
285#endif
286
Neal Norwitzd5a37542006-03-20 06:48:34 +0000287#define WAIT_TYPE union wait
288#define WAIT_STATUS_INT(s) (s.w_status)
289
290#else /* !UNION_WAIT */
291#define WAIT_TYPE int
292#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000293#endif /* UNION_WAIT */
294
Greg Wardb48bc172000-03-01 21:51:56 +0000295/* Don't use the "_r" form if we don't need it (also, won't have a
296 prototype for it, at least on Solaris -- maybe others as well?). */
297#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
298#define USE_CTERMID_R
299#endif
300
301#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
302#define USE_TMPNAM_R
303#endif
304
Fred Drake699f3522000-06-29 21:12:41 +0000305/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000306#undef STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000307#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwis14694662006-02-03 12:54:16 +0000308# define STAT win32_stat
309# define FSTAT win32_fstat
310# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000311#else
312# define STAT stat
313# define FSTAT fstat
314# define STRUCT_STAT struct stat
315#endif
316
Tim Peters11b23062003-04-23 02:39:17 +0000317#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000318#include <sys/mkdev.h>
319#else
320#if defined(MAJOR_IN_SYSMACROS)
321#include <sys/sysmacros.h>
322#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000323#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
324#include <sys/mkdev.h>
325#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000326#endif
Fred Drake699f3522000-06-29 21:12:41 +0000327
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000328/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000329#ifdef WITH_NEXT_FRAMEWORK
330/* On Darwin/MacOSX a shared library or framework has no access to
331** environ directly, we must obtain it with _NSGetEnviron().
332*/
333#include <crt_externs.h>
334static char **environ;
335#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000336extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000337#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000338
Barry Warsaw53699e91996-12-10 23:23:01 +0000339static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000340convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000341{
Barry Warsaw53699e91996-12-10 23:23:01 +0000342 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000343 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000344 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000345 if (d == NULL)
346 return NULL;
Jack Jansenea0c3822002-08-01 21:57:49 +0000347#ifdef WITH_NEXT_FRAMEWORK
348 if (environ == NULL)
349 environ = *_NSGetEnviron();
350#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000351 if (environ == NULL)
352 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000353 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000354 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000355 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000356 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000357 char *p = strchr(*e, '=');
358 if (p == NULL)
359 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000360 k = PyString_FromStringAndSize(*e, (int)(p-*e));
361 if (k == NULL) {
362 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000363 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000364 }
365 v = PyString_FromString(p+1);
366 if (v == NULL) {
367 PyErr_Clear();
368 Py_DECREF(k);
369 continue;
370 }
371 if (PyDict_GetItem(d, k) == NULL) {
372 if (PyDict_SetItem(d, k, v) != 0)
373 PyErr_Clear();
374 }
375 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000376 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000377 }
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000378#if defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000379 {
380 APIRET rc;
381 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
382
383 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000384 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000385 PyObject *v = PyString_FromString(buffer);
386 PyDict_SetItemString(d, "BEGINLIBPATH", v);
387 Py_DECREF(v);
388 }
389 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
390 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
391 PyObject *v = PyString_FromString(buffer);
392 PyDict_SetItemString(d, "ENDLIBPATH", v);
393 Py_DECREF(v);
394 }
395 }
396#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000397 return d;
398}
399
400
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000401/* Set a POSIX-specific error from errno, and return NULL */
402
Barry Warsawd58d7641998-07-23 16:14:40 +0000403static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000404posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000405{
Barry Warsawca74da41999-02-09 19:31:45 +0000406 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000407}
Barry Warsawd58d7641998-07-23 16:14:40 +0000408static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000409posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000410{
Barry Warsawca74da41999-02-09 19:31:45 +0000411 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000412}
413
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000414#ifdef Py_WIN_WIDE_FILENAMES
415static PyObject *
416posix_error_with_unicode_filename(Py_UNICODE* name)
417{
418 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
419}
420#endif /* Py_WIN_WIDE_FILENAMES */
421
422
Mark Hammondef8b6542001-05-13 08:04:26 +0000423static PyObject *
424posix_error_with_allocated_filename(char* name)
425{
426 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
427 PyMem_Free(name);
428 return rc;
429}
430
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000431#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000432static PyObject *
433win32_error(char* function, char* filename)
434{
Mark Hammond33a6da92000-08-15 00:46:38 +0000435 /* XXX We should pass the function name along in the future.
436 (_winreg.c also wants to pass the function name.)
Tim Peters5aa91602002-01-30 05:46:57 +0000437 This would however require an additional param to the
Mark Hammond33a6da92000-08-15 00:46:38 +0000438 Windows error object, which is non-trivial.
439 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000440 errno = GetLastError();
441 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000442 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000443 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000444 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000445}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000446
447#ifdef Py_WIN_WIDE_FILENAMES
448static PyObject *
449win32_error_unicode(char* function, Py_UNICODE* filename)
450{
451 /* XXX - see win32_error for comments on 'function' */
452 errno = GetLastError();
453 if (filename)
454 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
455 else
456 return PyErr_SetFromWindowsErr(errno);
457}
458
459static PyObject *_PyUnicode_FromFileSystemEncodedObject(register PyObject *obj)
460{
461 /* XXX Perhaps we should make this API an alias of
462 PyObject_Unicode() instead ?! */
463 if (PyUnicode_CheckExact(obj)) {
464 Py_INCREF(obj);
465 return obj;
466 }
467 if (PyUnicode_Check(obj)) {
468 /* For a Unicode subtype that's not a Unicode object,
469 return a true Unicode object with the same data. */
470 return PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(obj),
471 PyUnicode_GET_SIZE(obj));
472 }
Tim Peters11b23062003-04-23 02:39:17 +0000473 return PyUnicode_FromEncodedObject(obj,
474 Py_FileSystemDefaultEncoding,
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000475 "strict");
476}
477
478#endif /* Py_WIN_WIDE_FILENAMES */
479
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000480#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000481
Guido van Rossumd48f2521997-12-05 22:19:34 +0000482#if defined(PYOS_OS2)
483/**********************************************************************
484 * Helper Function to Trim and Format OS/2 Messages
485 **********************************************************************/
486 static void
487os2_formatmsg(char *msgbuf, int msglen, char *reason)
488{
489 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
490
491 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
492 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
493
Neal Norwitz30b5c5d2005-12-19 06:05:18 +0000494 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
Guido van Rossumd48f2521997-12-05 22:19:34 +0000495 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
496 }
497
498 /* Add Optional Reason Text */
499 if (reason) {
500 strcat(msgbuf, " : ");
501 strcat(msgbuf, reason);
502 }
503}
504
505/**********************************************************************
506 * Decode an OS/2 Operating System Error Code
507 *
508 * A convenience function to lookup an OS/2 error code and return a
509 * text message we can use to raise a Python exception.
510 *
511 * Notes:
512 * The messages for errors returned from the OS/2 kernel reside in
513 * the file OSO001.MSG in the \OS2 directory hierarchy.
514 *
515 **********************************************************************/
516 static char *
517os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
518{
519 APIRET rc;
520 ULONG msglen;
521
522 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
523 Py_BEGIN_ALLOW_THREADS
524 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
525 errorcode, "oso001.msg", &msglen);
526 Py_END_ALLOW_THREADS
527
528 if (rc == NO_ERROR)
529 os2_formatmsg(msgbuf, msglen, reason);
530 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000531 PyOS_snprintf(msgbuf, msgbuflen,
Tim Peters885d4572001-11-28 20:27:42 +0000532 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000533
534 return msgbuf;
535}
536
537/* Set an OS/2-specific error and return NULL. OS/2 kernel
538 errors are not in a global variable e.g. 'errno' nor are
539 they congruent with posix error numbers. */
540
541static PyObject * os2_error(int code)
542{
543 char text[1024];
544 PyObject *v;
545
546 os2_strerror(text, sizeof(text), code, "");
547
548 v = Py_BuildValue("(is)", code, text);
549 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000550 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000551 Py_DECREF(v);
552 }
553 return NULL; /* Signal to Python that an Exception is Pending */
554}
555
556#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000557
558/* POSIX generic methods */
559
Barry Warsaw53699e91996-12-10 23:23:01 +0000560static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000561posix_fildes(PyObject *fdobj, int (*func)(int))
562{
563 int fd;
564 int res;
565 fd = PyObject_AsFileDescriptor(fdobj);
566 if (fd < 0)
567 return NULL;
568 Py_BEGIN_ALLOW_THREADS
569 res = (*func)(fd);
570 Py_END_ALLOW_THREADS
571 if (res < 0)
572 return posix_error();
573 Py_INCREF(Py_None);
574 return Py_None;
575}
Guido van Rossum21142a01999-01-08 21:05:37 +0000576
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000577#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters11b23062003-04-23 02:39:17 +0000578static int
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000579unicode_file_names(void)
580{
581 static int canusewide = -1;
582 if (canusewide == -1) {
Tim Peters11b23062003-04-23 02:39:17 +0000583 /* As per doc for ::GetVersion(), this is the correct test for
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000584 the Windows NT family. */
585 canusewide = (GetVersion() < 0x80000000) ? 1 : 0;
586 }
587 return canusewide;
588}
589#endif
Tim Peters11b23062003-04-23 02:39:17 +0000590
Guido van Rossum21142a01999-01-08 21:05:37 +0000591static PyObject *
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000592posix_1str(PyObject *args, char *format, int (*func)(const char*),
593 char *wformat, int (*wfunc)(const Py_UNICODE*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000594{
Mark Hammondef8b6542001-05-13 08:04:26 +0000595 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000596 int res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000597#ifdef Py_WIN_WIDE_FILENAMES
598 if (unicode_file_names()) {
599 PyUnicodeObject *po;
600 if (PyArg_ParseTuple(args, wformat, &po)) {
601 Py_BEGIN_ALLOW_THREADS
602 /* PyUnicode_AS_UNICODE OK without thread
603 lock as it is a simple dereference. */
604 res = (*wfunc)(PyUnicode_AS_UNICODE(po));
605 Py_END_ALLOW_THREADS
606 if (res < 0)
Mark Hammondd3890362002-10-03 07:24:48 +0000607 return posix_error_with_unicode_filename(PyUnicode_AS_UNICODE(po));
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000608 Py_INCREF(Py_None);
609 return Py_None;
610 }
611 /* Drop the argument parsing error as narrow
612 strings are also valid. */
613 PyErr_Clear();
614 }
615#else
616 /* Platforms that don't support Unicode filenames
617 shouldn't be passing these extra params */
618 assert(wformat==NULL && wfunc == NULL);
619#endif
620
Tim Peters5aa91602002-01-30 05:46:57 +0000621 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000622 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000623 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000624 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000625 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000626 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000627 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000628 return posix_error_with_allocated_filename(path1);
629 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000630 Py_INCREF(Py_None);
631 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000632}
633
Barry Warsaw53699e91996-12-10 23:23:01 +0000634static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000635posix_2str(PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000636 char *format,
637 int (*func)(const char *, const char *),
638 char *wformat,
639 int (*wfunc)(const Py_UNICODE *, const Py_UNICODE *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000640{
Mark Hammondef8b6542001-05-13 08:04:26 +0000641 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000642 int res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000643#ifdef Py_WIN_WIDE_FILENAMES
644 if (unicode_file_names()) {
645 PyObject *po1;
646 PyObject *po2;
647 if (PyArg_ParseTuple(args, wformat, &po1, &po2)) {
648 if (PyUnicode_Check(po1) || PyUnicode_Check(po2)) {
649 PyObject *wpath1;
650 PyObject *wpath2;
651 wpath1 = _PyUnicode_FromFileSystemEncodedObject(po1);
652 wpath2 = _PyUnicode_FromFileSystemEncodedObject(po2);
653 if (!wpath1 || !wpath2) {
654 Py_XDECREF(wpath1);
655 Py_XDECREF(wpath2);
656 return NULL;
657 }
658 Py_BEGIN_ALLOW_THREADS
659 /* PyUnicode_AS_UNICODE OK without thread
660 lock as it is a simple dereference. */
661 res = (*wfunc)(PyUnicode_AS_UNICODE(wpath1),
662 PyUnicode_AS_UNICODE(wpath2));
663 Py_END_ALLOW_THREADS
664 Py_XDECREF(wpath1);
665 Py_XDECREF(wpath2);
666 if (res != 0)
667 return posix_error();
668 Py_INCREF(Py_None);
669 return Py_None;
670 }
671 /* Else flow through as neither is Unicode. */
672 }
673 /* Drop the argument parsing error as narrow
674 strings are also valid. */
675 PyErr_Clear();
676 }
677#else
678 /* Platforms that don't support Unicode filenames
679 shouldn't be passing these extra params */
680 assert(wformat==NULL && wfunc == NULL);
681#endif
682
Mark Hammondef8b6542001-05-13 08:04:26 +0000683 if (!PyArg_ParseTuple(args, format,
Tim Peters5aa91602002-01-30 05:46:57 +0000684 Py_FileSystemDefaultEncoding, &path1,
Mark Hammondef8b6542001-05-13 08:04:26 +0000685 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000686 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000687 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000688 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000689 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000690 PyMem_Free(path1);
691 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000692 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000693 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000694 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000695 Py_INCREF(Py_None);
696 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000697}
698
Martin v. Löwis14694662006-02-03 12:54:16 +0000699#ifdef MS_WINDOWS
700/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
701 - time stamps are restricted to second resolution
702 - file modification times suffer from forth-and-back conversions between
703 UTC and local time
704 Therefore, we implement our own stat, based on the Win32 API directly.
705*/
706#define HAVE_STAT_NSEC 1
707
708struct win32_stat{
709 int st_dev;
710 __int64 st_ino;
711 unsigned short st_mode;
712 int st_nlink;
713 int st_uid;
714 int st_gid;
715 int st_rdev;
716 __int64 st_size;
717 int st_atime;
718 int st_atime_nsec;
719 int st_mtime;
720 int st_mtime_nsec;
721 int st_ctime;
722 int st_ctime_nsec;
723};
724
725static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
726
727static void
728FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, int *time_out, int* nsec_out)
729{
730 /* XXX endianness */
731 __int64 in = *(__int64*)in_ptr;
732 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
733 /* XXX Win32 supports time stamps past 2038; we currently don't */
734 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, int);
735}
736
737/* Below, we *know* that ugo+r is 0444 */
738#if _S_IREAD != 0400
739#error Unsupported C library
740#endif
741static int
742attributes_to_mode(DWORD attr)
743{
744 int m = 0;
745 if (attr & FILE_ATTRIBUTE_DIRECTORY)
746 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
747 else
748 m |= _S_IFREG;
749 if (attr & FILE_ATTRIBUTE_READONLY)
750 m |= 0444;
751 else
752 m |= 0666;
753 return m;
754}
755
756static int
757attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *result)
758{
759 memset(result, 0, sizeof(*result));
760 result->st_mode = attributes_to_mode(info->dwFileAttributes);
761 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
762 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
763 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
764 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
765
766 return 0;
767}
768
769static int
770win32_stat(const char* path, struct win32_stat *result)
771{
772 WIN32_FILE_ATTRIBUTE_DATA info;
773 int code;
774 char *dot;
775 /* XXX not supported on Win95 and NT 3.x */
776 if (!GetFileAttributesExA(path, GetFileExInfoStandard, &info)) {
777 /* Protocol violation: we explicitly clear errno, instead of
778 setting it to a POSIX error. Callers should use GetLastError. */
779 errno = 0;
780 return -1;
781 }
782 code = attribute_data_to_stat(&info, result);
783 if (code != 0)
784 return code;
785 /* Set S_IFEXEC if it is an .exe, .bat, ... */
786 dot = strrchr(path, '.');
787 if (dot) {
788 if (stricmp(dot, ".bat") == 0 ||
789 stricmp(dot, ".cmd") == 0 ||
790 stricmp(dot, ".exe") == 0 ||
791 stricmp(dot, ".com") == 0)
792 result->st_mode |= 0111;
793 }
794 return code;
795}
796
797static int
798win32_wstat(const wchar_t* path, struct win32_stat *result)
799{
800 int code;
801 const wchar_t *dot;
802 WIN32_FILE_ATTRIBUTE_DATA info;
803 /* XXX not supported on Win95 and NT 3.x */
804 if (!GetFileAttributesExW(path, GetFileExInfoStandard, &info)) {
805 /* Protocol violation: we explicitly clear errno, instead of
806 setting it to a POSIX error. Callers should use GetLastError. */
807 errno = 0;
808 return -1;
809 }
810 code = attribute_data_to_stat(&info, result);
811 if (code < 0)
812 return code;
813 /* Set IFEXEC if it is an .exe, .bat, ... */
814 dot = wcsrchr(path, '.');
815 if (dot) {
816 if (_wcsicmp(dot, L".bat") == 0 ||
817 _wcsicmp(dot, L".cmd") == 0 ||
818 _wcsicmp(dot, L".exe") == 0 ||
819 _wcsicmp(dot, L".com") == 0)
820 result->st_mode |= 0111;
821 }
822 return code;
823}
824
825static int
826win32_fstat(int file_number, struct win32_stat *result)
827{
828 BY_HANDLE_FILE_INFORMATION info;
829 HANDLE h;
830 int type;
831
832 h = (HANDLE)_get_osfhandle(file_number);
833
834 /* Protocol violation: we explicitly clear errno, instead of
835 setting it to a POSIX error. Callers should use GetLastError. */
836 errno = 0;
837
838 if (h == INVALID_HANDLE_VALUE) {
839 /* This is really a C library error (invalid file handle).
840 We set the Win32 error to the closes one matching. */
841 SetLastError(ERROR_INVALID_HANDLE);
842 return -1;
843 }
844 memset(result, 0, sizeof(*result));
845
846 type = GetFileType(h);
847 if (type == FILE_TYPE_UNKNOWN) {
848 DWORD error = GetLastError();
849 if (error != 0) {
850 return -1;
851 }
852 /* else: valid but unknown file */
853 }
854
855 if (type != FILE_TYPE_DISK) {
856 if (type == FILE_TYPE_CHAR)
857 result->st_mode = _S_IFCHR;
858 else if (type == FILE_TYPE_PIPE)
859 result->st_mode = _S_IFIFO;
860 return 0;
861 }
862
863 if (!GetFileInformationByHandle(h, &info)) {
864 return -1;
865 }
866
867 /* similar to stat() */
868 result->st_mode = attributes_to_mode(info.dwFileAttributes);
869 result->st_size = (((__int64)info.nFileSizeHigh)<<32) + info.nFileSizeLow;
870 FILE_TIME_to_time_t_nsec(&info.ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
871 FILE_TIME_to_time_t_nsec(&info.ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
872 FILE_TIME_to_time_t_nsec(&info.ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
873 /* specific to fstat() */
874 result->st_nlink = info.nNumberOfLinks;
875 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
876 return 0;
877}
878
879#endif /* MS_WINDOWS */
880
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000881PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000882"stat_result: Result from stat or lstat.\n\n\
883This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +0000884 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000885or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
886\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +0000887Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
888or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000889\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000890See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000891
892static PyStructSequence_Field stat_result_fields[] = {
893 {"st_mode", "protection bits"},
894 {"st_ino", "inode"},
895 {"st_dev", "device"},
896 {"st_nlink", "number of hard links"},
897 {"st_uid", "user ID of owner"},
898 {"st_gid", "group ID of owner"},
899 {"st_size", "total size, in bytes"},
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000900 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
901 {NULL, "integer time of last access"},
902 {NULL, "integer time of last modification"},
903 {NULL, "integer time of last change"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000904 {"st_atime", "time of last access"},
905 {"st_mtime", "time of last modification"},
906 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000907#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000908 {"st_blksize", "blocksize for filesystem I/O"},
909#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000910#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000911 {"st_blocks", "number of blocks allocated"},
912#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000913#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000914 {"st_rdev", "device type (if inode device)"},
915#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +0000916#ifdef HAVE_STRUCT_STAT_ST_FLAGS
917 {"st_flags", "user defined flags for file"},
918#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +0000919#ifdef HAVE_STRUCT_STAT_ST_GEN
920 {"st_gen", "generation number"},
921#endif
922#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
923 {"st_birthtime", "time of creation"},
924#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000925 {0}
926};
927
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000928#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000929#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000930#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000931#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000932#endif
933
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000934#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000935#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
936#else
937#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
938#endif
939
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000940#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000941#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
942#else
943#define ST_RDEV_IDX ST_BLOCKS_IDX
944#endif
945
Hye-Shik Chang5f937a72005-06-02 13:09:30 +0000946#ifdef HAVE_STRUCT_STAT_ST_FLAGS
947#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
948#else
949#define ST_FLAGS_IDX ST_RDEV_IDX
950#endif
951
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +0000952#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +0000953#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +0000954#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +0000955#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +0000956#endif
957
958#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
959#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
960#else
961#define ST_BIRTHTIME_IDX ST_GEN_IDX
962#endif
963
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000964static PyStructSequence_Desc stat_result_desc = {
965 "stat_result", /* name */
966 stat_result__doc__, /* doc */
967 stat_result_fields,
968 10
969};
970
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000971PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000972"statvfs_result: Result from statvfs or fstatvfs.\n\n\
973This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +0000974 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000975or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000976\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000977See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000978
979static PyStructSequence_Field statvfs_result_fields[] = {
980 {"f_bsize", },
981 {"f_frsize", },
982 {"f_blocks", },
983 {"f_bfree", },
984 {"f_bavail", },
985 {"f_files", },
986 {"f_ffree", },
987 {"f_favail", },
988 {"f_flag", },
989 {"f_namemax",},
990 {0}
991};
992
993static PyStructSequence_Desc statvfs_result_desc = {
994 "statvfs_result", /* name */
995 statvfs_result__doc__, /* doc */
996 statvfs_result_fields,
997 10
998};
999
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00001000static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001001static PyTypeObject StatResultType;
1002static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001003static newfunc structseq_new;
1004
1005static PyObject *
1006statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1007{
1008 PyStructSequence *result;
1009 int i;
1010
1011 result = (PyStructSequence*)structseq_new(type, args, kwds);
1012 if (!result)
1013 return NULL;
1014 /* If we have been initialized from a tuple,
1015 st_?time might be set to None. Initialize it
1016 from the int slots. */
1017 for (i = 7; i <= 9; i++) {
1018 if (result->ob_item[i+3] == Py_None) {
1019 Py_DECREF(Py_None);
1020 Py_INCREF(result->ob_item[i]);
1021 result->ob_item[i+3] = result->ob_item[i];
1022 }
1023 }
1024 return (PyObject*)result;
1025}
1026
1027
1028
1029/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001030static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001031
1032PyDoc_STRVAR(stat_float_times__doc__,
1033"stat_float_times([newval]) -> oldval\n\n\
1034Determine whether os.[lf]stat represents time stamps as float objects.\n\
1035If newval is True, future calls to stat() return floats, if it is False,\n\
1036future calls return ints. \n\
1037If newval is omitted, return the current setting.\n");
1038
1039static PyObject*
1040stat_float_times(PyObject* self, PyObject *args)
1041{
1042 int newval = -1;
1043 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1044 return NULL;
1045 if (newval == -1)
1046 /* Return old value */
1047 return PyBool_FromLong(_stat_float_times);
1048 _stat_float_times = newval;
1049 Py_INCREF(Py_None);
1050 return Py_None;
1051}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001052
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001053static void
1054fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1055{
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001056 PyObject *fval,*ival;
1057#if SIZEOF_TIME_T > SIZEOF_LONG
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00001058 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001059#else
1060 ival = PyInt_FromLong((long)sec);
1061#endif
1062 if (_stat_float_times) {
1063 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1064 } else {
1065 fval = ival;
1066 Py_INCREF(fval);
1067 }
1068 PyStructSequence_SET_ITEM(v, index, ival);
1069 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001070}
1071
Tim Peters5aa91602002-01-30 05:46:57 +00001072/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001073 (used by posix_stat() and posix_fstat()) */
1074static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001075_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001076{
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001077 unsigned long ansec, mnsec, cnsec;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001078 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +00001079 if (v == NULL)
1080 return NULL;
1081
Martin v. Löwis14694662006-02-03 12:54:16 +00001082 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001083#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001084 PyStructSequence_SET_ITEM(v, 1,
Martin v. Löwis14694662006-02-03 12:54:16 +00001085 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001086#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001087 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001088#endif
1089#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +00001090 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwis14694662006-02-03 12:54:16 +00001091 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001092#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001093 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001094#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001095 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st->st_nlink));
1096 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st->st_uid));
1097 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001098#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001099 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwis14694662006-02-03 12:54:16 +00001100 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001101#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001102 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001103#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001104
Martin v. Löwis14694662006-02-03 12:54:16 +00001105#if defined(HAVE_STAT_TV_NSEC)
1106 ansec = st->st_atim.tv_nsec;
1107 mnsec = st->st_mtim.tv_nsec;
1108 cnsec = st->st_ctim.tv_nsec;
1109#elif defined(HAVE_STAT_TV_NSEC2)
1110 ansec = st->st_atimespec.tv_nsec;
1111 mnsec = st->st_mtimespec.tv_nsec;
1112 cnsec = st->st_ctimespec.tv_nsec;
1113#elif defined(HAVE_STAT_NSEC)
1114 ansec = st->st_atime_nsec;
1115 mnsec = st->st_mtime_nsec;
1116 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001117#else
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001118 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001119#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001120 fill_time(v, 7, st->st_atime, ansec);
1121 fill_time(v, 8, st->st_mtime, mnsec);
1122 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001123
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001124#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +00001125 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001126 PyInt_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001127#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001128#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +00001129 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001130 PyInt_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001131#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001132#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001133 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001134 PyInt_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001135#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001136#ifdef HAVE_STRUCT_STAT_ST_GEN
1137 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001138 PyInt_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001139#endif
1140#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1141 {
1142 PyObject *val;
1143 unsigned long bsec,bnsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001144 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001145#ifdef HAVE_STAT_TV_NSEC2
Hye-Shik Changd69e0342006-02-19 16:22:22 +00001146 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001147#else
1148 bnsec = 0;
1149#endif
1150 if (_stat_float_times) {
1151 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1152 } else {
1153 val = PyInt_FromLong((long)bsec);
1154 }
1155 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1156 val);
1157 }
1158#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001159#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1160 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001161 PyInt_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001162#endif
Fred Drake699f3522000-06-29 21:12:41 +00001163
1164 if (PyErr_Occurred()) {
1165 Py_DECREF(v);
1166 return NULL;
1167 }
1168
1169 return v;
1170}
1171
Martin v. Löwisd8948722004-06-02 09:57:56 +00001172#ifdef MS_WINDOWS
1173
1174/* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
1175 where / can be used in place of \ and the trailing slash is optional.
1176 Both SERVER and SHARE must have at least one character.
1177*/
1178
1179#define ISSLASHA(c) ((c) == '\\' || (c) == '/')
1180#define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
1181#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
1182
Tim Peters4ad82172004-08-30 17:02:04 +00001183static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001184IsUNCRootA(char *path, int pathlen)
1185{
1186 #define ISSLASH ISSLASHA
1187
1188 int i, share;
1189
1190 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1191 /* minimum UNCRoot is \\x\y */
1192 return FALSE;
1193 for (i = 2; i < pathlen ; i++)
1194 if (ISSLASH(path[i])) break;
1195 if (i == 2 || i == pathlen)
1196 /* do not allow \\\SHARE or \\SERVER */
1197 return FALSE;
1198 share = i+1;
1199 for (i = share; i < pathlen; i++)
1200 if (ISSLASH(path[i])) break;
1201 return (i != share && (i == pathlen || i == pathlen-1));
1202
1203 #undef ISSLASH
1204}
1205
1206#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters4ad82172004-08-30 17:02:04 +00001207static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001208IsUNCRootW(Py_UNICODE *path, int pathlen)
1209{
1210 #define ISSLASH ISSLASHW
1211
1212 int i, share;
1213
1214 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1215 /* minimum UNCRoot is \\x\y */
1216 return FALSE;
1217 for (i = 2; i < pathlen ; i++)
1218 if (ISSLASH(path[i])) break;
1219 if (i == 2 || i == pathlen)
1220 /* do not allow \\\SHARE or \\SERVER */
1221 return FALSE;
1222 share = i+1;
1223 for (i = share; i < pathlen; i++)
1224 if (ISSLASH(path[i])) break;
1225 return (i != share && (i == pathlen || i == pathlen-1));
1226
1227 #undef ISSLASH
1228}
1229#endif /* Py_WIN_WIDE_FILENAMES */
1230#endif /* MS_WINDOWS */
1231
Barry Warsaw53699e91996-12-10 23:23:01 +00001232static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001233posix_do_stat(PyObject *self, PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001234 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001235#ifdef __VMS
1236 int (*statfunc)(const char *, STRUCT_STAT *, ...),
1237#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001238 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001239#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001240 char *wformat,
1241 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001242{
Fred Drake699f3522000-06-29 21:12:41 +00001243 STRUCT_STAT st;
Tim Peters500bd032001-12-19 19:05:01 +00001244 char *path = NULL; /* pass this to stat; do not free() it */
1245 char *pathfree = NULL; /* this memory must be free'd */
Guido van Rossumff4949e1992-08-05 19:58:53 +00001246 int res;
Martin v. Löwis14694662006-02-03 12:54:16 +00001247 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001248
1249#ifdef Py_WIN_WIDE_FILENAMES
1250 /* If on wide-character-capable OS see if argument
1251 is Unicode and if so use wide API. */
1252 if (unicode_file_names()) {
1253 PyUnicodeObject *po;
1254 if (PyArg_ParseTuple(args, wformat, &po)) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001255 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
1256
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001257 Py_BEGIN_ALLOW_THREADS
1258 /* PyUnicode_AS_UNICODE result OK without
1259 thread lock as it is a simple dereference. */
1260 res = wstatfunc(wpath, &st);
1261 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001262
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001263 if (res != 0)
Martin v. Löwis14694662006-02-03 12:54:16 +00001264 return win32_error_unicode("stat", wpath);
1265 return _pystat_fromstructstat(&st);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001266 }
1267 /* Drop the argument parsing error as narrow strings
1268 are also valid. */
1269 PyErr_Clear();
1270 }
1271#endif
1272
Tim Peters5aa91602002-01-30 05:46:57 +00001273 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +00001274 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001275 return NULL;
Tim Peters500bd032001-12-19 19:05:01 +00001276 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +00001277
Barry Warsaw53699e91996-12-10 23:23:01 +00001278 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001279 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00001280 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001281
1282 if (res != 0) {
1283#ifdef MS_WINDOWS
1284 result = win32_error("stat", pathfree);
1285#else
1286 result = posix_error_with_filename(pathfree);
1287#endif
1288 }
1289 else
1290 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001291
Tim Peters500bd032001-12-19 19:05:01 +00001292 PyMem_Free(pathfree);
Martin v. Löwis14694662006-02-03 12:54:16 +00001293 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001294}
1295
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001296/* POSIX methods */
1297
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001298PyDoc_STRVAR(posix_access__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001299"access(path, mode) -> 1 if granted, 0 otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001300Use the real uid/gid to test for access to a path. Note that most\n\
1301operations will use the effective uid/gid, therefore this routine can\n\
1302be used in a suid/sgid environment to test if the invoking user has the\n\
1303specified access to the path. The mode argument can be F_OK to test\n\
1304existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001305
1306static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001307posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001308{
Guido van Rossum015f22a1999-01-06 22:52:38 +00001309 char *path;
1310 int mode;
1311 int res;
1312
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001313#ifdef Py_WIN_WIDE_FILENAMES
1314 if (unicode_file_names()) {
1315 PyUnicodeObject *po;
1316 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1317 Py_BEGIN_ALLOW_THREADS
1318 /* PyUnicode_AS_UNICODE OK without thread lock as
1319 it is a simple dereference. */
1320 res = _waccess(PyUnicode_AS_UNICODE(po), mode);
1321 Py_END_ALLOW_THREADS
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001322 return PyBool_FromLong(res == 0);
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001323 }
1324 /* Drop the argument parsing error as narrow strings
1325 are also valid. */
1326 PyErr_Clear();
1327 }
1328#endif
Martin v. Löwisb60ae992005-03-08 09:10:29 +00001329 if (!PyArg_ParseTuple(args, "eti:access",
1330 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +00001331 return NULL;
1332 Py_BEGIN_ALLOW_THREADS
1333 res = access(path, mode);
1334 Py_END_ALLOW_THREADS
Neal Norwitz24b3c222005-09-19 06:43:44 +00001335 PyMem_Free(path);
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001336 return PyBool_FromLong(res == 0);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001337}
1338
Guido van Rossumd371ff11999-01-25 16:12:23 +00001339#ifndef F_OK
1340#define F_OK 0
1341#endif
1342#ifndef R_OK
1343#define R_OK 4
1344#endif
1345#ifndef W_OK
1346#define W_OK 2
1347#endif
1348#ifndef X_OK
1349#define X_OK 1
1350#endif
1351
1352#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001353PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001354"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001355Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001356
1357static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001358posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001359{
Guido van Rossum94f6f721999-01-06 18:42:14 +00001360 int id;
1361 char *ret;
1362
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001363 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +00001364 return NULL;
1365
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001366#if defined(__VMS)
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +00001367 /* file descriptor 0 only, the default input device (stdin) */
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001368 if (id == 0) {
1369 ret = ttyname();
1370 }
1371 else {
1372 ret = NULL;
1373 }
1374#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00001375 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001376#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001377 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001378 return posix_error();
1379 return PyString_FromString(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001380}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001381#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001382
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001383#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001384PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001385"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001386Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001387
1388static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001389posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001390{
1391 char *ret;
1392 char buffer[L_ctermid];
1393
Greg Wardb48bc172000-03-01 21:51:56 +00001394#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001395 ret = ctermid_r(buffer);
1396#else
1397 ret = ctermid(buffer);
1398#endif
1399 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001400 return posix_error();
1401 return PyString_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001402}
1403#endif
1404
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001405PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001406"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001407Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001408
Barry Warsaw53699e91996-12-10 23:23:01 +00001409static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001410posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001411{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001412#ifdef MS_WINDOWS
1413 return posix_1str(args, "et:chdir", chdir, "U:chdir", _wchdir);
1414#elif defined(PYOS_OS2) && defined(PYCC_GCC)
1415 return posix_1str(args, "et:chdir", _chdir2, NULL, NULL);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001416#elif defined(__VMS)
Tim Peters11b23062003-04-23 02:39:17 +00001417 return posix_1str(args, "et:chdir", (int (*)(const char *))chdir,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001418 NULL, NULL);
1419#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001420 return posix_1str(args, "et:chdir", chdir, NULL, NULL);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001421#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001422}
1423
Fred Drake4d1e64b2002-04-15 19:40:07 +00001424#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001425PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001426"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001427Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001428opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001429
1430static PyObject *
1431posix_fchdir(PyObject *self, PyObject *fdobj)
1432{
1433 return posix_fildes(fdobj, fchdir);
1434}
1435#endif /* HAVE_FCHDIR */
1436
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001437
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001438PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001439"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001440Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001441
Barry Warsaw53699e91996-12-10 23:23:01 +00001442static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001443posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001444{
Mark Hammondef8b6542001-05-13 08:04:26 +00001445 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +00001446 int i;
1447 int res;
Mark Hammond817c9292003-12-03 01:22:38 +00001448#ifdef Py_WIN_WIDE_FILENAMES
1449 if (unicode_file_names()) {
1450 PyUnicodeObject *po;
1451 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1452 Py_BEGIN_ALLOW_THREADS
1453 res = _wchmod(PyUnicode_AS_UNICODE(po), i);
1454 Py_END_ALLOW_THREADS
1455 if (res < 0)
1456 return posix_error_with_unicode_filename(
1457 PyUnicode_AS_UNICODE(po));
1458 Py_INCREF(Py_None);
1459 return Py_None;
1460 }
1461 /* Drop the argument parsing error as narrow strings
1462 are also valid. */
1463 PyErr_Clear();
1464 }
1465#endif /* Py_WIN_WIDE_FILENAMES */
1466 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
Mark Hammondef8b6542001-05-13 08:04:26 +00001467 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +00001468 return NULL;
1469 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +00001470 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001471 Py_END_ALLOW_THREADS
1472 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001473 return posix_error_with_allocated_filename(path);
1474 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001475 Py_INCREF(Py_None);
1476 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001477}
1478
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001479
Martin v. Löwis244edc82001-10-04 22:44:26 +00001480#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001481PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001482"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001483Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00001484
1485static PyObject *
1486posix_chroot(PyObject *self, PyObject *args)
1487{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001488 return posix_1str(args, "et:chroot", chroot, NULL, NULL);
Martin v. Löwis244edc82001-10-04 22:44:26 +00001489}
1490#endif
1491
Guido van Rossum21142a01999-01-08 21:05:37 +00001492#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001493PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001494"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001495force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001496
1497static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001498posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001499{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001500 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001501}
1502#endif /* HAVE_FSYNC */
1503
1504#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00001505
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00001506#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00001507extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1508#endif
1509
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001510PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001511"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00001512force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001513 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001514
1515static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001516posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001517{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001518 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001519}
1520#endif /* HAVE_FDATASYNC */
1521
1522
Fredrik Lundh10723342000-07-10 16:38:09 +00001523#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001524PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001525"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001526Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001527
Barry Warsaw53699e91996-12-10 23:23:01 +00001528static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001529posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001530{
Mark Hammondef8b6542001-05-13 08:04:26 +00001531 char *path = NULL;
Fredrik Lundh44328e62000-07-10 15:59:30 +00001532 int uid, gid;
1533 int res;
Tim Peters5aa91602002-01-30 05:46:57 +00001534 if (!PyArg_ParseTuple(args, "etii:chown",
1535 Py_FileSystemDefaultEncoding, &path,
Mark Hammondef8b6542001-05-13 08:04:26 +00001536 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +00001537 return NULL;
1538 Py_BEGIN_ALLOW_THREADS
1539 res = chown(path, (uid_t) uid, (gid_t) gid);
1540 Py_END_ALLOW_THREADS
1541 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001542 return posix_error_with_allocated_filename(path);
1543 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +00001544 Py_INCREF(Py_None);
1545 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001546}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001547#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001548
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001549#ifdef HAVE_LCHOWN
1550PyDoc_STRVAR(posix_lchown__doc__,
1551"lchown(path, uid, gid)\n\n\
1552Change the owner and group id of path to the numeric uid and gid.\n\
1553This function will not follow symbolic links.");
1554
1555static PyObject *
1556posix_lchown(PyObject *self, PyObject *args)
1557{
1558 char *path = NULL;
1559 int uid, gid;
1560 int res;
1561 if (!PyArg_ParseTuple(args, "etii:lchown",
1562 Py_FileSystemDefaultEncoding, &path,
1563 &uid, &gid))
1564 return NULL;
1565 Py_BEGIN_ALLOW_THREADS
1566 res = lchown(path, (uid_t) uid, (gid_t) gid);
1567 Py_END_ALLOW_THREADS
Tim Peters11b23062003-04-23 02:39:17 +00001568 if (res < 0)
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001569 return posix_error_with_allocated_filename(path);
1570 PyMem_Free(path);
1571 Py_INCREF(Py_None);
1572 return Py_None;
1573}
1574#endif /* HAVE_LCHOWN */
1575
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001576
Guido van Rossum36bc6801995-06-14 22:54:23 +00001577#ifdef HAVE_GETCWD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001578PyDoc_STRVAR(posix_getcwd__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001579"getcwd() -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001580Return a string representing the current working directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001581
Barry Warsaw53699e91996-12-10 23:23:01 +00001582static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001583posix_getcwd(PyObject *self, PyObject *noargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001584{
1585 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +00001586 char *res;
Neal Norwitze241ce82003-02-17 18:17:05 +00001587
Barry Warsaw53699e91996-12-10 23:23:01 +00001588 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001589#if defined(PYOS_OS2) && defined(PYCC_GCC)
1590 res = _getcwd2(buf, sizeof buf);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001591#else
Guido van Rossumff4949e1992-08-05 19:58:53 +00001592 res = getcwd(buf, sizeof buf);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001593#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001594 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001595 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001596 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001597 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001598}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001599
Walter Dörwald3b918c32002-11-21 20:18:46 +00001600#ifdef Py_USING_UNICODE
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001601PyDoc_STRVAR(posix_getcwdu__doc__,
1602"getcwdu() -> path\n\n\
1603Return a unicode string representing the current working directory.");
1604
1605static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001606posix_getcwdu(PyObject *self, PyObject *noargs)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001607{
1608 char buf[1026];
1609 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001610
1611#ifdef Py_WIN_WIDE_FILENAMES
1612 if (unicode_file_names()) {
1613 wchar_t *wres;
1614 wchar_t wbuf[1026];
1615 Py_BEGIN_ALLOW_THREADS
1616 wres = _wgetcwd(wbuf, sizeof wbuf/ sizeof wbuf[0]);
1617 Py_END_ALLOW_THREADS
1618 if (wres == NULL)
1619 return posix_error();
1620 return PyUnicode_FromWideChar(wbuf, wcslen(wbuf));
1621 }
1622#endif
1623
1624 Py_BEGIN_ALLOW_THREADS
1625#if defined(PYOS_OS2) && defined(PYCC_GCC)
1626 res = _getcwd2(buf, sizeof buf);
1627#else
1628 res = getcwd(buf, sizeof buf);
1629#endif
1630 Py_END_ALLOW_THREADS
1631 if (res == NULL)
1632 return posix_error();
1633 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
1634}
Guido van Rossum36bc6801995-06-14 22:54:23 +00001635#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00001636#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001637
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001638
Guido van Rossumb6775db1994-08-01 11:34:53 +00001639#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001640PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001641"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001642Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001643
Barry Warsaw53699e91996-12-10 23:23:01 +00001644static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001645posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001646{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001647 return posix_2str(args, "etet:link", link, NULL, NULL);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001648}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001649#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001650
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001651
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001652PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001653"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001654Return a list containing the names of the entries in the directory.\n\
1655\n\
1656 path: path of directory to list\n\
1657\n\
1658The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001659entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001660
Barry Warsaw53699e91996-12-10 23:23:01 +00001661static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001662posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001663{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001664 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001665 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001666#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001667
Barry Warsaw53699e91996-12-10 23:23:01 +00001668 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001669 HANDLE hFindFile;
Martin v. Löwise920f0d2006-03-07 23:59:33 +00001670 BOOL result;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001671 WIN32_FIND_DATA FileData;
Mark Hammondef8b6542001-05-13 08:04:26 +00001672 /* MAX_PATH characters could mean a bigger encoded string */
1673 char namebuf[MAX_PATH*2+5];
1674 char *bufptr = namebuf;
Martin v. Löwis18e16552006-02-15 17:27:45 +00001675 Py_ssize_t len = sizeof(namebuf)/sizeof(namebuf[0]);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001676
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001677#ifdef Py_WIN_WIDE_FILENAMES
1678 /* If on wide-character-capable OS see if argument
1679 is Unicode and if so use wide API. */
1680 if (unicode_file_names()) {
1681 PyUnicodeObject *po;
1682 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
1683 WIN32_FIND_DATAW wFileData;
1684 Py_UNICODE wnamebuf[MAX_PATH*2+5];
1685 Py_UNICODE wch;
1686 wcsncpy(wnamebuf, PyUnicode_AS_UNICODE(po), MAX_PATH);
1687 wnamebuf[MAX_PATH] = L'\0';
1688 len = wcslen(wnamebuf);
1689 wch = (len > 0) ? wnamebuf[len-1] : L'\0';
1690 if (wch != L'/' && wch != L'\\' && wch != L':')
1691 wnamebuf[len++] = L'/';
1692 wcscpy(wnamebuf + len, L"*.*");
1693 if ((d = PyList_New(0)) == NULL)
1694 return NULL;
1695 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
1696 if (hFindFile == INVALID_HANDLE_VALUE) {
1697 errno = GetLastError();
1698 if (errno == ERROR_FILE_NOT_FOUND) {
1699 return d;
1700 }
1701 Py_DECREF(d);
1702 return win32_error_unicode("FindFirstFileW", wnamebuf);
1703 }
1704 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00001705 /* Skip over . and .. */
1706 if (wcscmp(wFileData.cFileName, L".") != 0 &&
1707 wcscmp(wFileData.cFileName, L"..") != 0) {
1708 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
1709 if (v == NULL) {
1710 Py_DECREF(d);
1711 d = NULL;
1712 break;
1713 }
1714 if (PyList_Append(d, v) != 0) {
1715 Py_DECREF(v);
1716 Py_DECREF(d);
1717 d = NULL;
1718 break;
1719 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001720 Py_DECREF(v);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001721 }
Georg Brandl622927b2006-03-07 12:48:03 +00001722 Py_BEGIN_ALLOW_THREADS
1723 result = FindNextFileW(hFindFile, &wFileData);
1724 Py_END_ALLOW_THREADS
1725 } while (result == TRUE);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001726
1727 if (FindClose(hFindFile) == FALSE) {
1728 Py_DECREF(d);
1729 return win32_error_unicode("FindClose", wnamebuf);
1730 }
1731 return d;
1732 }
1733 /* Drop the argument parsing error as narrow strings
1734 are also valid. */
1735 PyErr_Clear();
1736 }
1737#endif
1738
Tim Peters5aa91602002-01-30 05:46:57 +00001739 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001740 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +00001741 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +00001742 if (len > 0) {
1743 char ch = namebuf[len-1];
1744 if (ch != SEP && ch != ALTSEP && ch != ':')
1745 namebuf[len++] = '/';
1746 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001747 strcpy(namebuf + len, "*.*");
1748
Barry Warsaw53699e91996-12-10 23:23:01 +00001749 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001750 return NULL;
1751
1752 hFindFile = FindFirstFile(namebuf, &FileData);
1753 if (hFindFile == INVALID_HANDLE_VALUE) {
1754 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +00001755 if (errno == ERROR_FILE_NOT_FOUND)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001756 return d;
1757 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00001758 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001759 }
1760 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00001761 /* Skip over . and .. */
1762 if (strcmp(FileData.cFileName, ".") != 0 &&
1763 strcmp(FileData.cFileName, "..") != 0) {
1764 v = PyString_FromString(FileData.cFileName);
1765 if (v == NULL) {
1766 Py_DECREF(d);
1767 d = NULL;
1768 break;
1769 }
1770 if (PyList_Append(d, v) != 0) {
1771 Py_DECREF(v);
1772 Py_DECREF(d);
1773 d = NULL;
1774 break;
1775 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001776 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001777 }
Georg Brandl622927b2006-03-07 12:48:03 +00001778 Py_BEGIN_ALLOW_THREADS
1779 result = FindNextFile(hFindFile, &FileData);
1780 Py_END_ALLOW_THREADS
1781 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001782
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001783 if (FindClose(hFindFile) == FALSE) {
1784 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00001785 return win32_error("FindClose", namebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001786 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001787
1788 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001789
Tim Peters0bb44a42000-09-15 07:44:49 +00001790#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001791
1792#ifndef MAX_PATH
1793#define MAX_PATH CCHMAXPATH
1794#endif
1795 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00001796 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001797 PyObject *d, *v;
1798 char namebuf[MAX_PATH+5];
1799 HDIR hdir = 1;
1800 ULONG srchcnt = 1;
1801 FILEFINDBUF3 ep;
1802 APIRET rc;
1803
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001804 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001805 return NULL;
1806 if (len >= MAX_PATH) {
1807 PyErr_SetString(PyExc_ValueError, "path too long");
1808 return NULL;
1809 }
1810 strcpy(namebuf, name);
1811 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001812 if (*pt == ALTSEP)
1813 *pt = SEP;
1814 if (namebuf[len-1] != SEP)
1815 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001816 strcpy(namebuf + len, "*.*");
1817
1818 if ((d = PyList_New(0)) == NULL)
1819 return NULL;
1820
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001821 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
1822 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001823 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001824 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
1825 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
1826 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001827
1828 if (rc != NO_ERROR) {
1829 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001830 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001831 }
1832
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001833 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001834 do {
1835 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001836 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001837 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001838
1839 strcpy(namebuf, ep.achName);
1840
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001841 /* Leave Case of Name Alone -- In Native Form */
1842 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001843
1844 v = PyString_FromString(namebuf);
1845 if (v == NULL) {
1846 Py_DECREF(d);
1847 d = NULL;
1848 break;
1849 }
1850 if (PyList_Append(d, v) != 0) {
1851 Py_DECREF(v);
1852 Py_DECREF(d);
1853 d = NULL;
1854 break;
1855 }
1856 Py_DECREF(v);
1857 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1858 }
1859
1860 return d;
1861#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001862
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001863 char *name = NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001864 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001865 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001866 struct dirent *ep;
Just van Rossum96b1c902003-03-03 17:32:15 +00001867 int arg_is_unicode = 1;
1868
Georg Brandl05e89b82006-04-11 07:04:06 +00001869 errno = 0;
Just van Rossum96b1c902003-03-03 17:32:15 +00001870 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
1871 arg_is_unicode = 0;
1872 PyErr_Clear();
1873 }
1874 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001875 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001876 if ((dirp = opendir(name)) == NULL) {
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001877 return posix_error_with_allocated_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001878 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001879 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001880 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001881 PyMem_Free(name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001882 return NULL;
1883 }
Georg Brandl622927b2006-03-07 12:48:03 +00001884 for (;;) {
1885 Py_BEGIN_ALLOW_THREADS
1886 ep = readdir(dirp);
1887 Py_END_ALLOW_THREADS
1888 if (ep == NULL)
1889 break;
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001890 if (ep->d_name[0] == '.' &&
1891 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001892 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001893 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001894 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001895 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001896 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001897 d = NULL;
1898 break;
1899 }
Just van Rossum46c97842003-02-25 21:42:15 +00001900#ifdef Py_USING_UNICODE
Just van Rossum96b1c902003-03-03 17:32:15 +00001901 if (arg_is_unicode) {
Just van Rossum46c97842003-02-25 21:42:15 +00001902 PyObject *w;
1903
1904 w = PyUnicode_FromEncodedObject(v,
Tim Peters11b23062003-04-23 02:39:17 +00001905 Py_FileSystemDefaultEncoding,
Just van Rossum46c97842003-02-25 21:42:15 +00001906 "strict");
Just van Rossum6a421832003-03-04 19:30:44 +00001907 if (w != NULL) {
1908 Py_DECREF(v);
1909 v = w;
1910 }
1911 else {
1912 /* fall back to the original byte string, as
1913 discussed in patch #683592 */
1914 PyErr_Clear();
Just van Rossum46c97842003-02-25 21:42:15 +00001915 }
Just van Rossum46c97842003-02-25 21:42:15 +00001916 }
1917#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001918 if (PyList_Append(d, v) != 0) {
1919 Py_DECREF(v);
1920 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001921 d = NULL;
1922 break;
1923 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001924 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001925 }
Georg Brandlbbfe4fa2006-04-11 06:47:43 +00001926 if (errno != 0 && d != NULL) {
1927 /* readdir() returned NULL and set errno */
1928 closedir(dirp);
1929 Py_DECREF(d);
1930 return posix_error_with_allocated_filename(name);
1931 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001932 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001933 PyMem_Free(name);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001934
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001935 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001936
Tim Peters0bb44a42000-09-15 07:44:49 +00001937#endif /* which OS */
1938} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001939
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001940#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00001941/* A helper function for abspath on win32 */
1942static PyObject *
1943posix__getfullpathname(PyObject *self, PyObject *args)
1944{
1945 /* assume encoded strings wont more than double no of chars */
1946 char inbuf[MAX_PATH*2];
1947 char *inbufp = inbuf;
Tim Peters67d70eb2006-03-01 04:35:45 +00001948 Py_ssize_t insize = sizeof(inbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00001949 char outbuf[MAX_PATH*2];
1950 char *temp;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001951#ifdef Py_WIN_WIDE_FILENAMES
1952 if (unicode_file_names()) {
1953 PyUnicodeObject *po;
1954 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
1955 Py_UNICODE woutbuf[MAX_PATH*2];
1956 Py_UNICODE *wtemp;
Tim Peters11b23062003-04-23 02:39:17 +00001957 if (!GetFullPathNameW(PyUnicode_AS_UNICODE(po),
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001958 sizeof(woutbuf)/sizeof(woutbuf[0]),
1959 woutbuf, &wtemp))
1960 return win32_error("GetFullPathName", "");
1961 return PyUnicode_FromUnicode(woutbuf, wcslen(woutbuf));
1962 }
1963 /* Drop the argument parsing error as narrow strings
1964 are also valid. */
1965 PyErr_Clear();
1966 }
1967#endif
Tim Peters5aa91602002-01-30 05:46:57 +00001968 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
1969 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00001970 &insize))
1971 return NULL;
1972 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
1973 outbuf, &temp))
1974 return win32_error("GetFullPathName", inbuf);
Martin v. Löwis969297f2004-06-15 18:49:58 +00001975 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
1976 return PyUnicode_Decode(outbuf, strlen(outbuf),
1977 Py_FileSystemDefaultEncoding, NULL);
1978 }
Mark Hammondef8b6542001-05-13 08:04:26 +00001979 return PyString_FromString(outbuf);
1980} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001981#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00001982
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001983PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001984"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001985Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001986
Barry Warsaw53699e91996-12-10 23:23:01 +00001987static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001988posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001989{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001990 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00001991 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001992 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001993
1994#ifdef Py_WIN_WIDE_FILENAMES
1995 if (unicode_file_names()) {
1996 PyUnicodeObject *po;
Mark Hammond05107b62003-02-19 04:08:27 +00001997 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001998 Py_BEGIN_ALLOW_THREADS
1999 /* PyUnicode_AS_UNICODE OK without thread lock as
2000 it is a simple dereference. */
2001 res = _wmkdir(PyUnicode_AS_UNICODE(po));
2002 Py_END_ALLOW_THREADS
2003 if (res < 0)
2004 return posix_error();
2005 Py_INCREF(Py_None);
2006 return Py_None;
2007 }
2008 /* Drop the argument parsing error as narrow strings
2009 are also valid. */
2010 PyErr_Clear();
2011 }
2012#endif
2013
Tim Peters5aa91602002-01-30 05:46:57 +00002014 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00002015 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00002016 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002017 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002018#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002019 res = mkdir(path);
2020#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00002021 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002022#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002023 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00002024 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00002025 return posix_error_with_allocated_filename(path);
2026 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002027 Py_INCREF(Py_None);
2028 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002029}
2030
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002031
Neal Norwitz1818ed72006-03-26 00:29:48 +00002032/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2033#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002034#include <sys/resource.h>
2035#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002036
Neal Norwitz1818ed72006-03-26 00:29:48 +00002037
2038#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002039PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002040"nice(inc) -> new_priority\n\n\
2041Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002042
Barry Warsaw53699e91996-12-10 23:23:01 +00002043static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002044posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002045{
2046 int increment, value;
2047
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002048 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00002049 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002050
2051 /* There are two flavours of 'nice': one that returns the new
2052 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002053 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2054 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002055
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002056 If we are of the nice family that returns the new priority, we
2057 need to clear errno before the call, and check if errno is filled
2058 before calling posix_error() on a returnvalue of -1, because the
2059 -1 may be the actual new priority! */
2060
2061 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002062 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002063#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002064 if (value == 0)
2065 value = getpriority(PRIO_PROCESS, 0);
2066#endif
2067 if (value == -1 && errno != 0)
2068 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00002069 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002070 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002071}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002072#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002073
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002074
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002075PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002076"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002077Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002078
Barry Warsaw53699e91996-12-10 23:23:01 +00002079static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002080posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002081{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002082#ifdef MS_WINDOWS
2083 return posix_2str(args, "etet:rename", rename, "OO:rename", _wrename);
2084#else
2085 return posix_2str(args, "etet:rename", rename, NULL, NULL);
2086#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002087}
2088
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002089
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002090PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002091"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002092Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002093
Barry Warsaw53699e91996-12-10 23:23:01 +00002094static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002095posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002096{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002097#ifdef MS_WINDOWS
2098 return posix_1str(args, "et:rmdir", rmdir, "U:rmdir", _wrmdir);
2099#else
2100 return posix_1str(args, "et:rmdir", rmdir, NULL, NULL);
2101#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002102}
2103
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002104
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002105PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002106"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002107Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002108
Barry Warsaw53699e91996-12-10 23:23:01 +00002109static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002110posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002111{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002112#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00002113 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002114#else
2115 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
2116#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002117}
2118
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002119
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002120#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002121PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002122"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002123Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002124
Barry Warsaw53699e91996-12-10 23:23:01 +00002125static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002126posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002127{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002128 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002129 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002130 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002131 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002132 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002133 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00002134 Py_END_ALLOW_THREADS
2135 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002136}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002137#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002138
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002139
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002140PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002141"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002142Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002143
Barry Warsaw53699e91996-12-10 23:23:01 +00002144static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002145posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002146{
2147 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002148 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002149 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00002150 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002151 if (i < 0)
2152 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002153 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002154}
2155
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002156
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002157PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002158"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002159Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002160
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002161PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002162"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002163Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002164
Barry Warsaw53699e91996-12-10 23:23:01 +00002165static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002166posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002167{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002168#ifdef MS_WINDOWS
2169 return posix_1str(args, "et:remove", unlink, "U:remove", _wunlink);
2170#else
2171 return posix_1str(args, "et:remove", unlink, NULL, NULL);
2172#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002173}
2174
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002175
Guido van Rossumb6775db1994-08-01 11:34:53 +00002176#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002177PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002178"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002179Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002180
Barry Warsaw53699e91996-12-10 23:23:01 +00002181static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002182posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002183{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002184 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002185 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00002186
Barry Warsaw53699e91996-12-10 23:23:01 +00002187 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002188 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00002189 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002190 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002191 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002192 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00002193 u.sysname,
2194 u.nodename,
2195 u.release,
2196 u.version,
2197 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002198}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002199#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002200
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002201static int
2202extract_time(PyObject *t, long* sec, long* usec)
2203{
2204 long intval;
2205 if (PyFloat_Check(t)) {
2206 double tval = PyFloat_AsDouble(t);
2207 PyObject *intobj = t->ob_type->tp_as_number->nb_int(t);
2208 if (!intobj)
2209 return -1;
2210 intval = PyInt_AsLong(intobj);
2211 Py_DECREF(intobj);
Michael W. Hudsonb8963812005-07-05 15:21:58 +00002212 if (intval == -1 && PyErr_Occurred())
2213 return -1;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002214 *sec = intval;
Tim Peters96940cf2002-09-10 15:37:28 +00002215 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002216 if (*usec < 0)
2217 /* If rounding gave us a negative number,
2218 truncate. */
2219 *usec = 0;
2220 return 0;
2221 }
2222 intval = PyInt_AsLong(t);
2223 if (intval == -1 && PyErr_Occurred())
2224 return -1;
2225 *sec = intval;
2226 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00002227 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002228}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002229
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002230PyDoc_STRVAR(posix_utime__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002231"utime(path, (atime, utime))\n\
2232utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00002233Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002234second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002235
Barry Warsaw53699e91996-12-10 23:23:01 +00002236static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002237posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002238{
Neal Norwitz2adf2102004-06-09 01:46:02 +00002239 char *path = NULL;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002240 long atime, mtime, ausec, musec;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002241 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002242 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002243
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002244#if defined(HAVE_UTIMES)
2245 struct timeval buf[2];
2246#define ATIME buf[0].tv_sec
2247#define MTIME buf[1].tv_sec
2248#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002249/* XXX should define struct utimbuf instead, above */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002250 struct utimbuf buf;
2251#define ATIME buf.actime
2252#define MTIME buf.modtime
2253#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002254#else /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002255 time_t buf[2];
2256#define ATIME buf[0]
2257#define MTIME buf[1]
2258#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002259#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002260
Mark Hammond817c9292003-12-03 01:22:38 +00002261 int have_unicode_filename = 0;
2262#ifdef Py_WIN_WIDE_FILENAMES
2263 PyUnicodeObject *obwpath;
2264 wchar_t *wpath;
2265 if (unicode_file_names()) {
2266 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
2267 wpath = PyUnicode_AS_UNICODE(obwpath);
2268 have_unicode_filename = 1;
2269 } else
2270 /* Drop the argument parsing error as narrow strings
2271 are also valid. */
2272 PyErr_Clear();
2273 }
2274#endif /* Py_WIN_WIDE_FILENAMES */
2275
2276 if (!have_unicode_filename && \
Hye-Shik Chang2b2c9732004-01-04 13:54:25 +00002277 !PyArg_ParseTuple(args, "etO:utime",
2278 Py_FileSystemDefaultEncoding, &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002279 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002280 if (arg == Py_None) {
2281 /* optional time values not given */
2282 Py_BEGIN_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002283#ifdef Py_WIN_WIDE_FILENAMES
2284 if (have_unicode_filename)
2285 res = _wutime(wpath, NULL);
2286 else
2287#endif /* Py_WIN_WIDE_FILENAMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002288 res = utime(path, NULL);
2289 Py_END_ALLOW_THREADS
2290 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002291 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00002292 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002293 "utime() arg 2 must be a tuple (atime, mtime)");
Neal Norwitz96652712004-06-06 20:40:27 +00002294 PyMem_Free(path);
Barry Warsaw3cef8562000-05-01 16:17:24 +00002295 return NULL;
2296 }
2297 else {
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002298 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Neal Norwitz96652712004-06-06 20:40:27 +00002299 &atime, &ausec) == -1) {
2300 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002301 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002302 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002303 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Neal Norwitz96652712004-06-06 20:40:27 +00002304 &mtime, &musec) == -1) {
2305 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002306 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002307 }
Barry Warsaw3cef8562000-05-01 16:17:24 +00002308 ATIME = atime;
2309 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002310#ifdef HAVE_UTIMES
2311 buf[0].tv_usec = ausec;
2312 buf[1].tv_usec = musec;
2313 Py_BEGIN_ALLOW_THREADS
2314 res = utimes(path, buf);
2315 Py_END_ALLOW_THREADS
2316#else
Barry Warsaw3cef8562000-05-01 16:17:24 +00002317 Py_BEGIN_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002318#ifdef Py_WIN_WIDE_FILENAMES
2319 if (have_unicode_filename)
Tim Peters4ad82172004-08-30 17:02:04 +00002320 /* utime is OK with utimbuf, but _wutime insists
2321 on _utimbuf (the msvc headers assert the
Mark Hammond817c9292003-12-03 01:22:38 +00002322 underscore version is ansi) */
2323 res = _wutime(wpath, (struct _utimbuf *)UTIME_ARG);
2324 else
2325#endif /* Py_WIN_WIDE_FILENAMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002326 res = utime(path, UTIME_ARG);
2327 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002328#endif /* HAVE_UTIMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002329 }
Mark Hammond2d5914b2004-05-04 08:10:37 +00002330 if (res < 0) {
2331#ifdef Py_WIN_WIDE_FILENAMES
Neal Norwitz2adf2102004-06-09 01:46:02 +00002332 if (have_unicode_filename)
Mark Hammond2d5914b2004-05-04 08:10:37 +00002333 return posix_error_with_unicode_filename(wpath);
2334#endif /* Py_WIN_WIDE_FILENAMES */
Neal Norwitz96652712004-06-06 20:40:27 +00002335 return posix_error_with_allocated_filename(path);
Mark Hammond2d5914b2004-05-04 08:10:37 +00002336 }
Neal Norwitz96652712004-06-06 20:40:27 +00002337 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002338 Py_INCREF(Py_None);
2339 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002340#undef UTIME_ARG
2341#undef ATIME
2342#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002343}
2344
Guido van Rossum85e3b011991-06-03 12:42:10 +00002345
Guido van Rossum3b066191991-06-04 19:40:25 +00002346/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002347
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002348PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002349"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002350Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002351
Barry Warsaw53699e91996-12-10 23:23:01 +00002352static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002353posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002354{
2355 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002356 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002357 return NULL;
2358 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00002359 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002360}
2361
Martin v. Löwis114619e2002-10-07 06:44:21 +00002362#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
2363static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00002364free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00002365{
Martin v. Löwis725507b2006-03-07 12:08:51 +00002366 Py_ssize_t i;
Martin v. Löwis114619e2002-10-07 06:44:21 +00002367 for (i = 0; i < count; i++)
2368 PyMem_Free(array[i]);
2369 PyMem_DEL(array);
2370}
2371#endif
2372
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002373
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002374#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002375PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002376"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002377Execute an executable path with arguments, replacing current process.\n\
2378\n\
2379 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002380 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002381
Barry Warsaw53699e91996-12-10 23:23:01 +00002382static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002383posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002384{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002385 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002386 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002387 char **argvlist;
Martin v. Löwis725507b2006-03-07 12:08:51 +00002388 Py_ssize_t i, argc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002389 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002390
Guido van Rossum89b33251993-10-22 14:26:06 +00002391 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00002392 argv is a list or tuple of strings. */
2393
Martin v. Löwis114619e2002-10-07 06:44:21 +00002394 if (!PyArg_ParseTuple(args, "etO:execv",
2395 Py_FileSystemDefaultEncoding,
2396 &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002397 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002398 if (PyList_Check(argv)) {
2399 argc = PyList_Size(argv);
2400 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002401 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002402 else if (PyTuple_Check(argv)) {
2403 argc = PyTuple_Size(argv);
2404 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002405 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002406 else {
Fred Drake661ea262000-10-24 19:57:45 +00002407 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002408 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002409 return NULL;
2410 }
2411
Barry Warsaw53699e91996-12-10 23:23:01 +00002412 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002413 if (argvlist == NULL) {
2414 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002415 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002416 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002417 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002418 if (!PyArg_Parse((*getitem)(argv, i), "et",
2419 Py_FileSystemDefaultEncoding,
2420 &argvlist[i])) {
2421 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00002422 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002423 "execv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002424 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002425 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00002426
Guido van Rossum85e3b011991-06-03 12:42:10 +00002427 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002428 }
2429 argvlist[argc] = NULL;
2430
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002431 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002432
Guido van Rossum85e3b011991-06-03 12:42:10 +00002433 /* If we get here it's definitely an error */
2434
Martin v. Löwis114619e2002-10-07 06:44:21 +00002435 free_string_array(argvlist, argc);
2436 PyMem_Free(path);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002437 return posix_error();
2438}
2439
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002440
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002441PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002442"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002443Execute a path with arguments and environment, replacing current process.\n\
2444\n\
2445 path: path of executable file\n\
2446 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002447 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002448
Barry Warsaw53699e91996-12-10 23:23:01 +00002449static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002450posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002451{
2452 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002453 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002454 char **argvlist;
2455 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002456 PyObject *key, *val, *keys=NULL, *vals=NULL;
Martin v. Löwis725507b2006-03-07 12:08:51 +00002457 Py_ssize_t i, pos, argc, envc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002458 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Martin v. Löwis26fd9602006-04-22 11:15:41 +00002459 Py_ssize_t lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002460
2461 /* execve has three arguments: (path, argv, env), where
2462 argv is a list or tuple of strings and env is a dictionary
2463 like posix.environ. */
2464
Martin v. Löwis114619e2002-10-07 06:44:21 +00002465 if (!PyArg_ParseTuple(args, "etOO:execve",
2466 Py_FileSystemDefaultEncoding,
2467 &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002468 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002469 if (PyList_Check(argv)) {
2470 argc = PyList_Size(argv);
2471 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002472 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002473 else if (PyTuple_Check(argv)) {
2474 argc = PyTuple_Size(argv);
2475 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002476 }
2477 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002478 PyErr_SetString(PyExc_TypeError,
2479 "execve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002480 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002481 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002482 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002483 PyErr_SetString(PyExc_TypeError,
2484 "execve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002485 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002486 }
2487
Barry Warsaw53699e91996-12-10 23:23:01 +00002488 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002489 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002490 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002491 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002492 }
2493 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002494 if (!PyArg_Parse((*getitem)(argv, i),
Martin v. Löwis114619e2002-10-07 06:44:21 +00002495 "et;execve() arg 2 must contain only strings",
Guido van Rossum1e700d22002-10-16 16:52:11 +00002496 Py_FileSystemDefaultEncoding,
Barry Warsaw43d68b81996-12-19 22:10:44 +00002497 &argvlist[i]))
2498 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002499 lastarg = i;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002500 goto fail_1;
2501 }
2502 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002503 lastarg = argc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002504 argvlist[argc] = NULL;
2505
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002506 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002507 if (i < 0)
2508 goto fail_1;
Barry Warsaw53699e91996-12-10 23:23:01 +00002509 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002510 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002511 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002512 goto fail_1;
2513 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002514 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002515 keys = PyMapping_Keys(env);
2516 vals = PyMapping_Values(env);
2517 if (!keys || !vals)
2518 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002519 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2520 PyErr_SetString(PyExc_TypeError,
2521 "execve(): env.keys() or env.values() is not a list");
2522 goto fail_2;
2523 }
Tim Peters5aa91602002-01-30 05:46:57 +00002524
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002525 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002526 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002527 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002528
2529 key = PyList_GetItem(keys, pos);
2530 val = PyList_GetItem(vals, pos);
2531 if (!key || !val)
2532 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002533
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002534 if (!PyArg_Parse(
2535 key,
2536 "s;execve() arg 3 contains a non-string key",
2537 &k) ||
2538 !PyArg_Parse(
2539 val,
2540 "s;execve() arg 3 contains a non-string value",
2541 &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00002542 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002543 goto fail_2;
2544 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00002545
2546#if defined(PYOS_OS2)
2547 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
2548 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
2549#endif
Tim Petersc8996f52001-12-03 20:41:00 +00002550 len = PyString_Size(key) + PyString_Size(val) + 2;
2551 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002552 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002553 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002554 goto fail_2;
2555 }
Tim Petersc8996f52001-12-03 20:41:00 +00002556 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002557 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00002558#if defined(PYOS_OS2)
2559 }
2560#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002561 }
2562 envlist[envc] = 0;
2563
2564 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00002565
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002566 /* If we get here it's definitely an error */
2567
2568 (void) posix_error();
2569
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002570 fail_2:
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002571 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00002572 PyMem_DEL(envlist[envc]);
2573 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002574 fail_1:
2575 free_string_array(argvlist, lastarg);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002576 Py_XDECREF(vals);
2577 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002578 fail_0:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002579 PyMem_Free(path);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002580 return NULL;
2581}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002582#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002583
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002584
Guido van Rossuma1065681999-01-25 23:20:23 +00002585#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002586PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002587"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002588Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002589\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002590 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002591 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002592 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002593
2594static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002595posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002596{
2597 char *path;
2598 PyObject *argv;
2599 char **argvlist;
Martin v. Löwis26fd9602006-04-22 11:15:41 +00002600 int mode, i;
2601 Py_ssize_t argc;
Tim Peters79248aa2001-08-29 21:37:10 +00002602 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002603 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00002604
2605 /* spawnv has three arguments: (mode, path, argv), where
2606 argv is a list or tuple of strings. */
2607
Martin v. Löwis114619e2002-10-07 06:44:21 +00002608 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
2609 Py_FileSystemDefaultEncoding,
2610 &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00002611 return NULL;
2612 if (PyList_Check(argv)) {
2613 argc = PyList_Size(argv);
2614 getitem = PyList_GetItem;
2615 }
2616 else if (PyTuple_Check(argv)) {
2617 argc = PyTuple_Size(argv);
2618 getitem = PyTuple_GetItem;
2619 }
2620 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002621 PyErr_SetString(PyExc_TypeError,
2622 "spawnv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002623 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002624 return NULL;
2625 }
2626
2627 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002628 if (argvlist == NULL) {
2629 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002630 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002631 }
Guido van Rossuma1065681999-01-25 23:20:23 +00002632 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002633 if (!PyArg_Parse((*getitem)(argv, i), "et",
2634 Py_FileSystemDefaultEncoding,
2635 &argvlist[i])) {
2636 free_string_array(argvlist, i);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002637 PyErr_SetString(
2638 PyExc_TypeError,
2639 "spawnv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002640 PyMem_Free(path);
Fred Drake137507e2000-06-01 02:02:46 +00002641 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00002642 }
2643 }
2644 argvlist[argc] = NULL;
2645
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002646#if defined(PYOS_OS2) && defined(PYCC_GCC)
2647 Py_BEGIN_ALLOW_THREADS
2648 spawnval = spawnv(mode, path, argvlist);
2649 Py_END_ALLOW_THREADS
2650#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002651 if (mode == _OLD_P_OVERLAY)
2652 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00002653
Tim Peters25059d32001-12-07 20:35:43 +00002654 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002655 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00002656 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002657#endif
Tim Peters5aa91602002-01-30 05:46:57 +00002658
Martin v. Löwis114619e2002-10-07 06:44:21 +00002659 free_string_array(argvlist, argc);
2660 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002661
Fred Drake699f3522000-06-29 21:12:41 +00002662 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002663 return posix_error();
2664 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002665#if SIZEOF_LONG == SIZEOF_VOID_P
2666 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002667#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00002668 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002669#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002670}
2671
2672
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002673PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002674"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002675Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002676\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002677 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002678 path: path of executable file\n\
2679 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002680 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002681
2682static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002683posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002684{
2685 char *path;
2686 PyObject *argv, *env;
2687 char **argvlist;
2688 char **envlist;
2689 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
Martin v. Löwis26fd9602006-04-22 11:15:41 +00002690 int mode, pos, envc;
2691 Py_ssize_t argc, i;
Tim Peters79248aa2001-08-29 21:37:10 +00002692 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002693 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Martin v. Löwis26fd9602006-04-22 11:15:41 +00002694 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002695
2696 /* spawnve has four arguments: (mode, path, argv, env), where
2697 argv is a list or tuple of strings and env is a dictionary
2698 like posix.environ. */
2699
Martin v. Löwis114619e2002-10-07 06:44:21 +00002700 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
2701 Py_FileSystemDefaultEncoding,
2702 &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00002703 return NULL;
2704 if (PyList_Check(argv)) {
2705 argc = PyList_Size(argv);
2706 getitem = PyList_GetItem;
2707 }
2708 else if (PyTuple_Check(argv)) {
2709 argc = PyTuple_Size(argv);
2710 getitem = PyTuple_GetItem;
2711 }
2712 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002713 PyErr_SetString(PyExc_TypeError,
2714 "spawnve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002715 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002716 }
2717 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002718 PyErr_SetString(PyExc_TypeError,
2719 "spawnve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002720 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002721 }
2722
2723 argvlist = PyMem_NEW(char *, argc+1);
2724 if (argvlist == NULL) {
2725 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002726 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002727 }
2728 for (i = 0; i < argc; i++) {
2729 if (!PyArg_Parse((*getitem)(argv, i),
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002730 "et;spawnve() arg 2 must contain only strings",
Martin v. Löwis114619e2002-10-07 06:44:21 +00002731 Py_FileSystemDefaultEncoding,
Guido van Rossuma1065681999-01-25 23:20:23 +00002732 &argvlist[i]))
2733 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002734 lastarg = i;
Guido van Rossuma1065681999-01-25 23:20:23 +00002735 goto fail_1;
2736 }
2737 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002738 lastarg = argc;
Guido van Rossuma1065681999-01-25 23:20:23 +00002739 argvlist[argc] = NULL;
2740
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002741 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002742 if (i < 0)
2743 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00002744 envlist = PyMem_NEW(char *, i + 1);
2745 if (envlist == NULL) {
2746 PyErr_NoMemory();
2747 goto fail_1;
2748 }
2749 envc = 0;
2750 keys = PyMapping_Keys(env);
2751 vals = PyMapping_Values(env);
2752 if (!keys || !vals)
2753 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002754 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2755 PyErr_SetString(PyExc_TypeError,
2756 "spawnve(): env.keys() or env.values() is not a list");
2757 goto fail_2;
2758 }
Tim Peters5aa91602002-01-30 05:46:57 +00002759
Guido van Rossuma1065681999-01-25 23:20:23 +00002760 for (pos = 0; pos < i; pos++) {
2761 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002762 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00002763
2764 key = PyList_GetItem(keys, pos);
2765 val = PyList_GetItem(vals, pos);
2766 if (!key || !val)
2767 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002768
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002769 if (!PyArg_Parse(
2770 key,
2771 "s;spawnve() arg 3 contains a non-string key",
2772 &k) ||
2773 !PyArg_Parse(
2774 val,
2775 "s;spawnve() arg 3 contains a non-string value",
2776 &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00002777 {
2778 goto fail_2;
2779 }
Tim Petersc8996f52001-12-03 20:41:00 +00002780 len = PyString_Size(key) + PyString_Size(val) + 2;
2781 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00002782 if (p == NULL) {
2783 PyErr_NoMemory();
2784 goto fail_2;
2785 }
Tim Petersc8996f52001-12-03 20:41:00 +00002786 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00002787 envlist[envc++] = p;
2788 }
2789 envlist[envc] = 0;
2790
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002791#if defined(PYOS_OS2) && defined(PYCC_GCC)
2792 Py_BEGIN_ALLOW_THREADS
2793 spawnval = spawnve(mode, path, argvlist, envlist);
2794 Py_END_ALLOW_THREADS
2795#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002796 if (mode == _OLD_P_OVERLAY)
2797 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00002798
2799 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002800 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00002801 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002802#endif
Tim Peters25059d32001-12-07 20:35:43 +00002803
Fred Drake699f3522000-06-29 21:12:41 +00002804 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002805 (void) posix_error();
2806 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002807#if SIZEOF_LONG == SIZEOF_VOID_P
2808 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002809#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00002810 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002811#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002812
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002813 fail_2:
Guido van Rossuma1065681999-01-25 23:20:23 +00002814 while (--envc >= 0)
2815 PyMem_DEL(envlist[envc]);
2816 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002817 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002818 free_string_array(argvlist, lastarg);
Guido van Rossuma1065681999-01-25 23:20:23 +00002819 Py_XDECREF(vals);
2820 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002821 fail_0:
2822 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002823 return res;
2824}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00002825
2826/* OS/2 supports spawnvp & spawnvpe natively */
2827#if defined(PYOS_OS2)
2828PyDoc_STRVAR(posix_spawnvp__doc__,
2829"spawnvp(mode, file, args)\n\n\
2830Execute the program 'file' in a new process, using the environment\n\
2831search path to find the file.\n\
2832\n\
2833 mode: mode of process creation\n\
2834 file: executable file name\n\
2835 args: tuple or list of strings");
2836
2837static PyObject *
2838posix_spawnvp(PyObject *self, PyObject *args)
2839{
2840 char *path;
2841 PyObject *argv;
2842 char **argvlist;
2843 int mode, i, argc;
2844 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002845 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00002846
2847 /* spawnvp has three arguments: (mode, path, argv), where
2848 argv is a list or tuple of strings. */
2849
2850 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
2851 Py_FileSystemDefaultEncoding,
2852 &path, &argv))
2853 return NULL;
2854 if (PyList_Check(argv)) {
2855 argc = PyList_Size(argv);
2856 getitem = PyList_GetItem;
2857 }
2858 else if (PyTuple_Check(argv)) {
2859 argc = PyTuple_Size(argv);
2860 getitem = PyTuple_GetItem;
2861 }
2862 else {
2863 PyErr_SetString(PyExc_TypeError,
2864 "spawnvp() arg 2 must be a tuple or list");
2865 PyMem_Free(path);
2866 return NULL;
2867 }
2868
2869 argvlist = PyMem_NEW(char *, argc+1);
2870 if (argvlist == NULL) {
2871 PyMem_Free(path);
2872 return PyErr_NoMemory();
2873 }
2874 for (i = 0; i < argc; i++) {
2875 if (!PyArg_Parse((*getitem)(argv, i), "et",
2876 Py_FileSystemDefaultEncoding,
2877 &argvlist[i])) {
2878 free_string_array(argvlist, i);
2879 PyErr_SetString(
2880 PyExc_TypeError,
2881 "spawnvp() arg 2 must contain only strings");
2882 PyMem_Free(path);
2883 return NULL;
2884 }
2885 }
2886 argvlist[argc] = NULL;
2887
2888 Py_BEGIN_ALLOW_THREADS
2889#if defined(PYCC_GCC)
2890 spawnval = spawnvp(mode, path, argvlist);
2891#else
2892 spawnval = _spawnvp(mode, path, argvlist);
2893#endif
2894 Py_END_ALLOW_THREADS
2895
2896 free_string_array(argvlist, argc);
2897 PyMem_Free(path);
2898
2899 if (spawnval == -1)
2900 return posix_error();
2901 else
2902 return Py_BuildValue("l", (long) spawnval);
2903}
2904
2905
2906PyDoc_STRVAR(posix_spawnvpe__doc__,
2907"spawnvpe(mode, file, args, env)\n\n\
2908Execute the program 'file' in a new process, using the environment\n\
2909search path to find the file.\n\
2910\n\
2911 mode: mode of process creation\n\
2912 file: executable file name\n\
2913 args: tuple or list of arguments\n\
2914 env: dictionary of strings mapping to strings");
2915
2916static PyObject *
2917posix_spawnvpe(PyObject *self, PyObject *args)
2918{
2919 char *path;
2920 PyObject *argv, *env;
2921 char **argvlist;
2922 char **envlist;
2923 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
2924 int mode, i, pos, argc, envc;
2925 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002926 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00002927 int lastarg = 0;
2928
2929 /* spawnvpe has four arguments: (mode, path, argv, env), where
2930 argv is a list or tuple of strings and env is a dictionary
2931 like posix.environ. */
2932
2933 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
2934 Py_FileSystemDefaultEncoding,
2935 &path, &argv, &env))
2936 return NULL;
2937 if (PyList_Check(argv)) {
2938 argc = PyList_Size(argv);
2939 getitem = PyList_GetItem;
2940 }
2941 else if (PyTuple_Check(argv)) {
2942 argc = PyTuple_Size(argv);
2943 getitem = PyTuple_GetItem;
2944 }
2945 else {
2946 PyErr_SetString(PyExc_TypeError,
2947 "spawnvpe() arg 2 must be a tuple or list");
2948 goto fail_0;
2949 }
2950 if (!PyMapping_Check(env)) {
2951 PyErr_SetString(PyExc_TypeError,
2952 "spawnvpe() arg 3 must be a mapping object");
2953 goto fail_0;
2954 }
2955
2956 argvlist = PyMem_NEW(char *, argc+1);
2957 if (argvlist == NULL) {
2958 PyErr_NoMemory();
2959 goto fail_0;
2960 }
2961 for (i = 0; i < argc; i++) {
2962 if (!PyArg_Parse((*getitem)(argv, i),
2963 "et;spawnvpe() arg 2 must contain only strings",
2964 Py_FileSystemDefaultEncoding,
2965 &argvlist[i]))
2966 {
2967 lastarg = i;
2968 goto fail_1;
2969 }
2970 }
2971 lastarg = argc;
2972 argvlist[argc] = NULL;
2973
2974 i = PyMapping_Size(env);
2975 if (i < 0)
2976 goto fail_1;
2977 envlist = PyMem_NEW(char *, i + 1);
2978 if (envlist == NULL) {
2979 PyErr_NoMemory();
2980 goto fail_1;
2981 }
2982 envc = 0;
2983 keys = PyMapping_Keys(env);
2984 vals = PyMapping_Values(env);
2985 if (!keys || !vals)
2986 goto fail_2;
2987 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2988 PyErr_SetString(PyExc_TypeError,
2989 "spawnvpe(): env.keys() or env.values() is not a list");
2990 goto fail_2;
2991 }
2992
2993 for (pos = 0; pos < i; pos++) {
2994 char *p, *k, *v;
2995 size_t len;
2996
2997 key = PyList_GetItem(keys, pos);
2998 val = PyList_GetItem(vals, pos);
2999 if (!key || !val)
3000 goto fail_2;
3001
3002 if (!PyArg_Parse(
3003 key,
3004 "s;spawnvpe() arg 3 contains a non-string key",
3005 &k) ||
3006 !PyArg_Parse(
3007 val,
3008 "s;spawnvpe() arg 3 contains a non-string value",
3009 &v))
3010 {
3011 goto fail_2;
3012 }
3013 len = PyString_Size(key) + PyString_Size(val) + 2;
3014 p = PyMem_NEW(char, len);
3015 if (p == NULL) {
3016 PyErr_NoMemory();
3017 goto fail_2;
3018 }
3019 PyOS_snprintf(p, len, "%s=%s", k, v);
3020 envlist[envc++] = p;
3021 }
3022 envlist[envc] = 0;
3023
3024 Py_BEGIN_ALLOW_THREADS
3025#if defined(PYCC_GCC)
3026 spawnval = spawnve(mode, path, argvlist, envlist);
3027#else
3028 spawnval = _spawnve(mode, path, argvlist, envlist);
3029#endif
3030 Py_END_ALLOW_THREADS
3031
3032 if (spawnval == -1)
3033 (void) posix_error();
3034 else
3035 res = Py_BuildValue("l", (long) spawnval);
3036
3037 fail_2:
3038 while (--envc >= 0)
3039 PyMem_DEL(envlist[envc]);
3040 PyMem_DEL(envlist);
3041 fail_1:
3042 free_string_array(argvlist, lastarg);
3043 Py_XDECREF(vals);
3044 Py_XDECREF(keys);
3045 fail_0:
3046 PyMem_Free(path);
3047 return res;
3048}
3049#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003050#endif /* HAVE_SPAWNV */
3051
3052
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003053#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003054PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003055"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003056Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3057\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003058Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003059
3060static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003061posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003062{
Neal Norwitze241ce82003-02-17 18:17:05 +00003063 int pid = fork1();
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003064 if (pid == -1)
3065 return posix_error();
3066 PyOS_AfterFork();
3067 return PyInt_FromLong((long)pid);
3068}
3069#endif
3070
3071
Guido van Rossumad0ee831995-03-01 10:34:45 +00003072#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003073PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003074"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003075Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003076Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003077
Barry Warsaw53699e91996-12-10 23:23:01 +00003078static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003079posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003080{
Neal Norwitze241ce82003-02-17 18:17:05 +00003081 int pid = fork();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003082 if (pid == -1)
3083 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003084 if (pid == 0)
3085 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00003086 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003087}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003088#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003089
Neal Norwitzb59798b2003-03-21 01:43:31 +00003090/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00003091/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3092#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00003093#define DEV_PTY_FILE "/dev/ptc"
3094#define HAVE_DEV_PTMX
3095#else
3096#define DEV_PTY_FILE "/dev/ptmx"
3097#endif
3098
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003099#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003100#ifdef HAVE_PTY_H
3101#include <pty.h>
3102#else
3103#ifdef HAVE_LIBUTIL_H
3104#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00003105#endif /* HAVE_LIBUTIL_H */
3106#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00003107#ifdef HAVE_STROPTS_H
3108#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003109#endif
3110#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003111
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003112#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003113PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003114"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003115Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003116
3117static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003118posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003119{
3120 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003121#ifndef HAVE_OPENPTY
3122 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003123#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003124#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003125 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003126#ifdef sun
Neal Norwitz84a98e02006-04-10 07:44:23 +00003127 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003128#endif
3129#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00003130
Thomas Wouters70c21a12000-07-14 14:28:33 +00003131#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00003132 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
3133 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003134#elif defined(HAVE__GETPTY)
Thomas Wouters70c21a12000-07-14 14:28:33 +00003135 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
3136 if (slave_name == NULL)
3137 return posix_error();
3138
3139 slave_fd = open(slave_name, O_RDWR);
3140 if (slave_fd < 0)
3141 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003142#else
Neal Norwitzb59798b2003-03-21 01:43:31 +00003143 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003144 if (master_fd < 0)
3145 return posix_error();
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003146 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003147 /* change permission of slave */
3148 if (grantpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003149 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003150 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003151 }
3152 /* unlock slave */
3153 if (unlockpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003154 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003155 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003156 }
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003157 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003158 slave_name = ptsname(master_fd); /* get name of slave */
3159 if (slave_name == NULL)
3160 return posix_error();
3161 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
3162 if (slave_fd < 0)
3163 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003164#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003165 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
3166 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00003167#ifndef __hpux
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003168 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00003169#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003170#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00003171#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00003172
Fred Drake8cef4cf2000-06-28 16:40:38 +00003173 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00003174
Fred Drake8cef4cf2000-06-28 16:40:38 +00003175}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003176#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003177
3178#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003179PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003180"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00003181Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
3182Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003183To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003184
3185static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003186posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003187{
Neal Norwitz24b3c222005-09-19 06:43:44 +00003188 int master_fd = -1, pid;
Tim Peters5aa91602002-01-30 05:46:57 +00003189
Fred Drake8cef4cf2000-06-28 16:40:38 +00003190 pid = forkpty(&master_fd, NULL, NULL, NULL);
3191 if (pid == -1)
3192 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003193 if (pid == 0)
3194 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00003195 return Py_BuildValue("(ii)", pid, master_fd);
3196}
3197#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003198
Guido van Rossumad0ee831995-03-01 10:34:45 +00003199#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003200PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003201"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003202Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003203
Barry Warsaw53699e91996-12-10 23:23:01 +00003204static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003205posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003206{
Barry Warsaw53699e91996-12-10 23:23:01 +00003207 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003208}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003209#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003210
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003211
Guido van Rossumad0ee831995-03-01 10:34:45 +00003212#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003213PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003214"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003215Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003216
Barry Warsaw53699e91996-12-10 23:23:01 +00003217static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003218posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003219{
Barry Warsaw53699e91996-12-10 23:23:01 +00003220 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003221}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003222#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003223
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003224
Guido van Rossumad0ee831995-03-01 10:34:45 +00003225#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003226PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003227"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003228Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003229
Barry Warsaw53699e91996-12-10 23:23:01 +00003230static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003231posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003232{
Barry Warsaw53699e91996-12-10 23:23:01 +00003233 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003234}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003235#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003236
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003237
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003238PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003239"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003240Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003241
Barry Warsaw53699e91996-12-10 23:23:01 +00003242static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003243posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003244{
Barry Warsaw53699e91996-12-10 23:23:01 +00003245 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003246}
3247
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003248
Fred Drakec9680921999-12-13 16:37:25 +00003249#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003250PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003251"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003252Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00003253
3254static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003255posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00003256{
3257 PyObject *result = NULL;
3258
Fred Drakec9680921999-12-13 16:37:25 +00003259#ifdef NGROUPS_MAX
3260#define MAX_GROUPS NGROUPS_MAX
3261#else
3262 /* defined to be 16 on Solaris7, so this should be a small number */
3263#define MAX_GROUPS 64
3264#endif
3265 gid_t grouplist[MAX_GROUPS];
3266 int n;
3267
3268 n = getgroups(MAX_GROUPS, grouplist);
3269 if (n < 0)
3270 posix_error();
3271 else {
3272 result = PyList_New(n);
3273 if (result != NULL) {
Fred Drakec9680921999-12-13 16:37:25 +00003274 int i;
3275 for (i = 0; i < n; ++i) {
Neal Norwitze241ce82003-02-17 18:17:05 +00003276 PyObject *o = PyInt_FromLong((long)grouplist[i]);
Fred Drakec9680921999-12-13 16:37:25 +00003277 if (o == NULL) {
3278 Py_DECREF(result);
3279 result = NULL;
3280 break;
3281 }
3282 PyList_SET_ITEM(result, i, o);
3283 }
3284 }
3285 }
Neal Norwitze241ce82003-02-17 18:17:05 +00003286
Fred Drakec9680921999-12-13 16:37:25 +00003287 return result;
3288}
3289#endif
3290
Martin v. Löwis606edc12002-06-13 21:09:11 +00003291#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003292PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003293"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003294Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00003295
3296static PyObject *
3297posix_getpgid(PyObject *self, PyObject *args)
3298{
3299 int pid, pgid;
3300 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
3301 return NULL;
3302 pgid = getpgid(pid);
3303 if (pgid < 0)
3304 return posix_error();
3305 return PyInt_FromLong((long)pgid);
3306}
3307#endif /* HAVE_GETPGID */
3308
3309
Guido van Rossumb6775db1994-08-01 11:34:53 +00003310#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003311PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003312"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003313Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003314
Barry Warsaw53699e91996-12-10 23:23:01 +00003315static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003316posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00003317{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003318#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00003319 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003320#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00003321 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003322#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00003323}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003324#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00003325
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003326
Guido van Rossumb6775db1994-08-01 11:34:53 +00003327#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003328PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003329"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003330Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003331
Barry Warsaw53699e91996-12-10 23:23:01 +00003332static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003333posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003334{
Guido van Rossum64933891994-10-20 21:56:42 +00003335#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00003336 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003337#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003338 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003339#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00003340 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003341 Py_INCREF(Py_None);
3342 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003343}
3344
Guido van Rossumb6775db1994-08-01 11:34:53 +00003345#endif /* HAVE_SETPGRP */
3346
Guido van Rossumad0ee831995-03-01 10:34:45 +00003347#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003348PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003349"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003350Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003351
Barry Warsaw53699e91996-12-10 23:23:01 +00003352static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003353posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003354{
Barry Warsaw53699e91996-12-10 23:23:01 +00003355 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003356}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003357#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003358
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003359
Fred Drake12c6e2d1999-12-14 21:25:03 +00003360#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003361PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003362"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003363Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00003364
3365static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003366posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00003367{
Neal Norwitze241ce82003-02-17 18:17:05 +00003368 PyObject *result = NULL;
Fred Drakea30680b2000-12-06 21:24:28 +00003369 char *name;
3370 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00003371
Fred Drakea30680b2000-12-06 21:24:28 +00003372 errno = 0;
3373 name = getlogin();
3374 if (name == NULL) {
3375 if (errno)
3376 posix_error();
3377 else
3378 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00003379 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00003380 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00003381 else
3382 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00003383 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00003384
Fred Drake12c6e2d1999-12-14 21:25:03 +00003385 return result;
3386}
3387#endif
3388
Guido van Rossumad0ee831995-03-01 10:34:45 +00003389#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003390PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003391"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003392Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003393
Barry Warsaw53699e91996-12-10 23:23:01 +00003394static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003395posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003396{
Barry Warsaw53699e91996-12-10 23:23:01 +00003397 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003398}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003399#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003400
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003401
Guido van Rossumad0ee831995-03-01 10:34:45 +00003402#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003403PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003404"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003405Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003406
Barry Warsaw53699e91996-12-10 23:23:01 +00003407static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003408posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003409{
3410 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003411 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00003412 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003413#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003414 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
3415 APIRET rc;
3416 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003417 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003418
3419 } else if (sig == XCPT_SIGNAL_KILLPROC) {
3420 APIRET rc;
3421 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003422 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003423
3424 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003425 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003426#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00003427 if (kill(pid, sig) == -1)
3428 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003429#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003430 Py_INCREF(Py_None);
3431 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003432}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003433#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003434
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003435#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003436PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003437"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003438Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003439
3440static PyObject *
3441posix_killpg(PyObject *self, PyObject *args)
3442{
3443 int pgid, sig;
3444 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
3445 return NULL;
3446 if (killpg(pgid, sig) == -1)
3447 return posix_error();
3448 Py_INCREF(Py_None);
3449 return Py_None;
3450}
3451#endif
3452
Guido van Rossumc0125471996-06-28 18:55:32 +00003453#ifdef HAVE_PLOCK
3454
3455#ifdef HAVE_SYS_LOCK_H
3456#include <sys/lock.h>
3457#endif
3458
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003459PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003460"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003461Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003462
Barry Warsaw53699e91996-12-10 23:23:01 +00003463static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003464posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00003465{
3466 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003467 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00003468 return NULL;
3469 if (plock(op) == -1)
3470 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003471 Py_INCREF(Py_None);
3472 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00003473}
3474#endif
3475
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003476
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003477#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003478PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003479"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003480Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003481
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003482#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003483#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003484static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003485async_system(const char *command)
3486{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003487 char errormsg[256], args[1024];
3488 RESULTCODES rcodes;
3489 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003490
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003491 char *shell = getenv("COMSPEC");
3492 if (!shell)
3493 shell = "cmd";
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003494
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003495 /* avoid overflowing the argument buffer */
3496 if (strlen(shell) + 3 + strlen(command) >= 1024)
3497 return ERROR_NOT_ENOUGH_MEMORY
3498
3499 args[0] = '\0';
3500 strcat(args, shell);
3501 strcat(args, "/c ");
3502 strcat(args, command);
3503
3504 /* execute asynchronously, inheriting the environment */
3505 rc = DosExecPgm(errormsg,
3506 sizeof(errormsg),
3507 EXEC_ASYNC,
3508 args,
3509 NULL,
3510 &rcodes,
3511 shell);
3512 return rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003513}
3514
Guido van Rossumd48f2521997-12-05 22:19:34 +00003515static FILE *
3516popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003517{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003518 int oldfd, tgtfd;
3519 HFILE pipeh[2];
3520 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003521
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003522 /* mode determines which of stdin or stdout is reconnected to
3523 * the pipe to the child
3524 */
3525 if (strchr(mode, 'r') != NULL) {
3526 tgt_fd = 1; /* stdout */
3527 } else if (strchr(mode, 'w')) {
3528 tgt_fd = 0; /* stdin */
3529 } else {
3530 *err = ERROR_INVALID_ACCESS;
3531 return NULL;
3532 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003533
Andrew MacIntyrea3be2582004-12-18 09:51:05 +00003534 /* setup the pipe */
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003535 if ((rc = DosCreatePipe(&pipeh[0], &pipeh[1], pipesize)) != NO_ERROR) {
3536 *err = rc;
3537 return NULL;
3538 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003539
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003540 /* prevent other threads accessing stdio */
3541 DosEnterCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003542
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003543 /* reconnect stdio and execute child */
3544 oldfd = dup(tgtfd);
3545 close(tgtfd);
3546 if (dup2(pipeh[tgtfd], tgtfd) == 0) {
3547 DosClose(pipeh[tgtfd]);
3548 rc = async_system(command);
3549 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003550
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003551 /* restore stdio */
3552 dup2(oldfd, tgtfd);
3553 close(oldfd);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003554
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003555 /* allow other threads access to stdio */
3556 DosExitCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003557
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003558 /* if execution of child was successful return file stream */
3559 if (rc == NO_ERROR)
3560 return fdopen(pipeh[1 - tgtfd], mode);
3561 else {
3562 DosClose(pipeh[1 - tgtfd]);
3563 *err = rc;
3564 return NULL;
3565 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003566}
3567
3568static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003569posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003570{
3571 char *name;
3572 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00003573 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003574 FILE *fp;
3575 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003576 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003577 return NULL;
3578 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00003579 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003580 Py_END_ALLOW_THREADS
3581 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003582 return os2_error(err);
3583
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003584 f = PyFile_FromFile(fp, name, mode, fclose);
3585 if (f != NULL)
3586 PyFile_SetBufSize(f, bufsize);
3587 return f;
3588}
3589
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003590#elif defined(PYCC_GCC)
3591
3592/* standard posix version of popen() support */
3593static PyObject *
3594posix_popen(PyObject *self, PyObject *args)
3595{
3596 char *name;
3597 char *mode = "r";
3598 int bufsize = -1;
3599 FILE *fp;
3600 PyObject *f;
3601 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
3602 return NULL;
3603 Py_BEGIN_ALLOW_THREADS
3604 fp = popen(name, mode);
3605 Py_END_ALLOW_THREADS
3606 if (fp == NULL)
3607 return posix_error();
3608 f = PyFile_FromFile(fp, name, mode, pclose);
3609 if (f != NULL)
3610 PyFile_SetBufSize(f, bufsize);
3611 return f;
3612}
3613
3614/* fork() under OS/2 has lots'o'warts
3615 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
3616 * most of this code is a ripoff of the win32 code, but using the
3617 * capabilities of EMX's C library routines
3618 */
3619
3620/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
3621#define POPEN_1 1
3622#define POPEN_2 2
3623#define POPEN_3 3
3624#define POPEN_4 4
3625
3626static PyObject *_PyPopen(char *, int, int, int);
3627static int _PyPclose(FILE *file);
3628
3629/*
3630 * Internal dictionary mapping popen* file pointers to process handles,
3631 * for use when retrieving the process exit code. See _PyPclose() below
3632 * for more information on this dictionary's use.
3633 */
3634static PyObject *_PyPopenProcs = NULL;
3635
3636/* os2emx version of popen2()
3637 *
3638 * The result of this function is a pipe (file) connected to the
3639 * process's stdin, and a pipe connected to the process's stdout.
3640 */
3641
3642static PyObject *
3643os2emx_popen2(PyObject *self, PyObject *args)
3644{
3645 PyObject *f;
3646 int tm=0;
3647
3648 char *cmdstring;
3649 char *mode = "t";
3650 int bufsize = -1;
3651 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
3652 return NULL;
3653
3654 if (*mode == 't')
3655 tm = O_TEXT;
3656 else if (*mode != 'b') {
3657 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3658 return NULL;
3659 } else
3660 tm = O_BINARY;
3661
3662 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
3663
3664 return f;
3665}
3666
3667/*
3668 * Variation on os2emx.popen2
3669 *
3670 * The result of this function is 3 pipes - the process's stdin,
3671 * stdout and stderr
3672 */
3673
3674static PyObject *
3675os2emx_popen3(PyObject *self, PyObject *args)
3676{
3677 PyObject *f;
3678 int tm = 0;
3679
3680 char *cmdstring;
3681 char *mode = "t";
3682 int bufsize = -1;
3683 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
3684 return NULL;
3685
3686 if (*mode == 't')
3687 tm = O_TEXT;
3688 else if (*mode != 'b') {
3689 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3690 return NULL;
3691 } else
3692 tm = O_BINARY;
3693
3694 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
3695
3696 return f;
3697}
3698
3699/*
3700 * Variation on os2emx.popen2
3701 *
Tim Peters11b23062003-04-23 02:39:17 +00003702 * The result of this function is 2 pipes - the processes stdin,
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003703 * and stdout+stderr combined as a single pipe.
3704 */
3705
3706static PyObject *
3707os2emx_popen4(PyObject *self, PyObject *args)
3708{
3709 PyObject *f;
3710 int tm = 0;
3711
3712 char *cmdstring;
3713 char *mode = "t";
3714 int bufsize = -1;
3715 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
3716 return NULL;
3717
3718 if (*mode == 't')
3719 tm = O_TEXT;
3720 else if (*mode != 'b') {
3721 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3722 return NULL;
3723 } else
3724 tm = O_BINARY;
3725
3726 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
3727
3728 return f;
3729}
3730
3731/* a couple of structures for convenient handling of multiple
3732 * file handles and pipes
3733 */
3734struct file_ref
3735{
3736 int handle;
3737 int flags;
3738};
3739
3740struct pipe_ref
3741{
3742 int rd;
3743 int wr;
3744};
3745
3746/* The following code is derived from the win32 code */
3747
3748static PyObject *
3749_PyPopen(char *cmdstring, int mode, int n, int bufsize)
3750{
3751 struct file_ref stdio[3];
3752 struct pipe_ref p_fd[3];
3753 FILE *p_s[3];
3754 int file_count, i, pipe_err, pipe_pid;
3755 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
3756 PyObject *f, *p_f[3];
3757
3758 /* file modes for subsequent fdopen's on pipe handles */
3759 if (mode == O_TEXT)
3760 {
3761 rd_mode = "rt";
3762 wr_mode = "wt";
3763 }
3764 else
3765 {
3766 rd_mode = "rb";
3767 wr_mode = "wb";
3768 }
3769
3770 /* prepare shell references */
3771 if ((shell = getenv("EMXSHELL")) == NULL)
3772 if ((shell = getenv("COMSPEC")) == NULL)
3773 {
3774 errno = ENOENT;
3775 return posix_error();
3776 }
3777
3778 sh_name = _getname(shell);
3779 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
3780 opt = "/c";
3781 else
3782 opt = "-c";
3783
3784 /* save current stdio fds + their flags, and set not inheritable */
3785 i = pipe_err = 0;
3786 while (pipe_err >= 0 && i < 3)
3787 {
3788 pipe_err = stdio[i].handle = dup(i);
3789 stdio[i].flags = fcntl(i, F_GETFD, 0);
3790 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
3791 i++;
3792 }
3793 if (pipe_err < 0)
3794 {
3795 /* didn't get them all saved - clean up and bail out */
3796 int saved_err = errno;
3797 while (i-- > 0)
3798 {
3799 close(stdio[i].handle);
3800 }
3801 errno = saved_err;
3802 return posix_error();
3803 }
3804
3805 /* create pipe ends */
3806 file_count = 2;
3807 if (n == POPEN_3)
3808 file_count = 3;
3809 i = pipe_err = 0;
3810 while ((pipe_err == 0) && (i < file_count))
3811 pipe_err = pipe((int *)&p_fd[i++]);
3812 if (pipe_err < 0)
3813 {
3814 /* didn't get them all made - clean up and bail out */
3815 while (i-- > 0)
3816 {
3817 close(p_fd[i].wr);
3818 close(p_fd[i].rd);
3819 }
3820 errno = EPIPE;
3821 return posix_error();
3822 }
3823
3824 /* change the actual standard IO streams over temporarily,
3825 * making the retained pipe ends non-inheritable
3826 */
3827 pipe_err = 0;
3828
3829 /* - stdin */
3830 if (dup2(p_fd[0].rd, 0) == 0)
3831 {
3832 close(p_fd[0].rd);
3833 i = fcntl(p_fd[0].wr, F_GETFD, 0);
3834 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
3835 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
3836 {
3837 close(p_fd[0].wr);
3838 pipe_err = -1;
3839 }
3840 }
3841 else
3842 {
3843 pipe_err = -1;
3844 }
3845
3846 /* - stdout */
3847 if (pipe_err == 0)
3848 {
3849 if (dup2(p_fd[1].wr, 1) == 1)
3850 {
3851 close(p_fd[1].wr);
3852 i = fcntl(p_fd[1].rd, F_GETFD, 0);
3853 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
3854 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
3855 {
3856 close(p_fd[1].rd);
3857 pipe_err = -1;
3858 }
3859 }
3860 else
3861 {
3862 pipe_err = -1;
3863 }
3864 }
3865
3866 /* - stderr, as required */
3867 if (pipe_err == 0)
3868 switch (n)
3869 {
3870 case POPEN_3:
3871 {
3872 if (dup2(p_fd[2].wr, 2) == 2)
3873 {
3874 close(p_fd[2].wr);
3875 i = fcntl(p_fd[2].rd, F_GETFD, 0);
3876 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
3877 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
3878 {
3879 close(p_fd[2].rd);
3880 pipe_err = -1;
3881 }
3882 }
3883 else
3884 {
3885 pipe_err = -1;
3886 }
3887 break;
3888 }
3889
3890 case POPEN_4:
3891 {
3892 if (dup2(1, 2) != 2)
3893 {
3894 pipe_err = -1;
3895 }
3896 break;
3897 }
3898 }
3899
3900 /* spawn the child process */
3901 if (pipe_err == 0)
3902 {
3903 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
3904 if (pipe_pid == -1)
3905 {
3906 pipe_err = -1;
3907 }
3908 else
3909 {
3910 /* save the PID into the FILE structure
3911 * NOTE: this implementation doesn't actually
3912 * take advantage of this, but do it for
3913 * completeness - AIM Apr01
3914 */
3915 for (i = 0; i < file_count; i++)
3916 p_s[i]->_pid = pipe_pid;
3917 }
3918 }
3919
3920 /* reset standard IO to normal */
3921 for (i = 0; i < 3; i++)
3922 {
3923 dup2(stdio[i].handle, i);
3924 fcntl(i, F_SETFD, stdio[i].flags);
3925 close(stdio[i].handle);
3926 }
3927
3928 /* if any remnant problems, clean up and bail out */
3929 if (pipe_err < 0)
3930 {
3931 for (i = 0; i < 3; i++)
3932 {
3933 close(p_fd[i].rd);
3934 close(p_fd[i].wr);
3935 }
3936 errno = EPIPE;
3937 return posix_error_with_filename(cmdstring);
3938 }
3939
3940 /* build tuple of file objects to return */
3941 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
3942 PyFile_SetBufSize(p_f[0], bufsize);
3943 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
3944 PyFile_SetBufSize(p_f[1], bufsize);
3945 if (n == POPEN_3)
3946 {
3947 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
3948 PyFile_SetBufSize(p_f[0], bufsize);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00003949 f = PyTuple_Pack(3, p_f[0], p_f[1], p_f[2]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003950 }
3951 else
Raymond Hettinger8ae46892003-10-12 19:09:37 +00003952 f = PyTuple_Pack(2, p_f[0], p_f[1]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003953
3954 /*
3955 * Insert the files we've created into the process dictionary
3956 * all referencing the list with the process handle and the
3957 * initial number of files (see description below in _PyPclose).
3958 * Since if _PyPclose later tried to wait on a process when all
3959 * handles weren't closed, it could create a deadlock with the
3960 * child, we spend some energy here to try to ensure that we
3961 * either insert all file handles into the dictionary or none
3962 * at all. It's a little clumsy with the various popen modes
3963 * and variable number of files involved.
3964 */
3965 if (!_PyPopenProcs)
3966 {
3967 _PyPopenProcs = PyDict_New();
3968 }
3969
3970 if (_PyPopenProcs)
3971 {
3972 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
3973 int ins_rc[3];
3974
3975 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
3976 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
3977
3978 procObj = PyList_New(2);
3979 pidObj = PyInt_FromLong((long) pipe_pid);
3980 intObj = PyInt_FromLong((long) file_count);
3981
3982 if (procObj && pidObj && intObj)
3983 {
3984 PyList_SetItem(procObj, 0, pidObj);
3985 PyList_SetItem(procObj, 1, intObj);
3986
3987 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
3988 if (fileObj[0])
3989 {
3990 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
3991 fileObj[0],
3992 procObj);
3993 }
3994 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
3995 if (fileObj[1])
3996 {
3997 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
3998 fileObj[1],
3999 procObj);
4000 }
4001 if (file_count >= 3)
4002 {
4003 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
4004 if (fileObj[2])
4005 {
4006 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4007 fileObj[2],
4008 procObj);
4009 }
4010 }
4011
4012 if (ins_rc[0] < 0 || !fileObj[0] ||
4013 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4014 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
4015 {
4016 /* Something failed - remove any dictionary
4017 * entries that did make it.
4018 */
4019 if (!ins_rc[0] && fileObj[0])
4020 {
4021 PyDict_DelItem(_PyPopenProcs,
4022 fileObj[0]);
4023 }
4024 if (!ins_rc[1] && fileObj[1])
4025 {
4026 PyDict_DelItem(_PyPopenProcs,
4027 fileObj[1]);
4028 }
4029 if (!ins_rc[2] && fileObj[2])
4030 {
4031 PyDict_DelItem(_PyPopenProcs,
4032 fileObj[2]);
4033 }
4034 }
4035 }
Tim Peters11b23062003-04-23 02:39:17 +00004036
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004037 /*
4038 * Clean up our localized references for the dictionary keys
4039 * and value since PyDict_SetItem will Py_INCREF any copies
4040 * that got placed in the dictionary.
4041 */
4042 Py_XDECREF(procObj);
4043 Py_XDECREF(fileObj[0]);
4044 Py_XDECREF(fileObj[1]);
4045 Py_XDECREF(fileObj[2]);
4046 }
4047
4048 /* Child is launched. */
4049 return f;
4050}
4051
4052/*
4053 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4054 * exit code for the child process and return as a result of the close.
4055 *
4056 * This function uses the _PyPopenProcs dictionary in order to map the
4057 * input file pointer to information about the process that was
4058 * originally created by the popen* call that created the file pointer.
4059 * The dictionary uses the file pointer as a key (with one entry
4060 * inserted for each file returned by the original popen* call) and a
4061 * single list object as the value for all files from a single call.
4062 * The list object contains the Win32 process handle at [0], and a file
4063 * count at [1], which is initialized to the total number of file
4064 * handles using that list.
4065 *
4066 * This function closes whichever handle it is passed, and decrements
4067 * the file count in the dictionary for the process handle pointed to
4068 * by this file. On the last close (when the file count reaches zero),
4069 * this function will wait for the child process and then return its
4070 * exit code as the result of the close() operation. This permits the
4071 * files to be closed in any order - it is always the close() of the
4072 * final handle that will return the exit code.
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004073 *
4074 * NOTE: This function is currently called with the GIL released.
4075 * hence we use the GILState API to manage our state.
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004076 */
4077
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004078static int _PyPclose(FILE *file)
4079{
4080 int result;
4081 int exit_code;
4082 int pipe_pid;
4083 PyObject *procObj, *pidObj, *intObj, *fileObj;
4084 int file_count;
4085#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004086 PyGILState_STATE state;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004087#endif
4088
4089 /* Close the file handle first, to ensure it can't block the
4090 * child from exiting if it's the last handle.
4091 */
4092 result = fclose(file);
4093
4094#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004095 state = PyGILState_Ensure();
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004096#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004097 if (_PyPopenProcs)
4098 {
4099 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4100 (procObj = PyDict_GetItem(_PyPopenProcs,
4101 fileObj)) != NULL &&
4102 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
4103 (intObj = PyList_GetItem(procObj,1)) != NULL)
4104 {
4105 pipe_pid = (int) PyInt_AsLong(pidObj);
4106 file_count = (int) PyInt_AsLong(intObj);
4107
4108 if (file_count > 1)
4109 {
4110 /* Still other files referencing process */
4111 file_count--;
4112 PyList_SetItem(procObj,1,
4113 PyInt_FromLong((long) file_count));
4114 }
4115 else
4116 {
4117 /* Last file for this process */
4118 if (result != EOF &&
4119 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
4120 {
4121 /* extract exit status */
4122 if (WIFEXITED(exit_code))
4123 {
4124 result = WEXITSTATUS(exit_code);
4125 }
4126 else
4127 {
4128 errno = EPIPE;
4129 result = -1;
4130 }
4131 }
4132 else
4133 {
4134 /* Indicate failure - this will cause the file object
4135 * to raise an I/O error and translate the last
4136 * error code from errno. We do have a problem with
4137 * last errors that overlap the normal errno table,
4138 * but that's a consistent problem with the file object.
4139 */
4140 result = -1;
4141 }
4142 }
4143
4144 /* Remove this file pointer from dictionary */
4145 PyDict_DelItem(_PyPopenProcs, fileObj);
4146
4147 if (PyDict_Size(_PyPopenProcs) == 0)
4148 {
4149 Py_DECREF(_PyPopenProcs);
4150 _PyPopenProcs = NULL;
4151 }
4152
4153 } /* if object retrieval ok */
4154
4155 Py_XDECREF(fileObj);
4156 } /* if _PyPopenProcs */
4157
4158#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004159 PyGILState_Release(state);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004160#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004161 return result;
4162}
4163
4164#endif /* PYCC_??? */
4165
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004166#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004167
4168/*
4169 * Portable 'popen' replacement for Win32.
4170 *
4171 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
4172 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00004173 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004174 */
4175
4176#include <malloc.h>
4177#include <io.h>
4178#include <fcntl.h>
4179
4180/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
4181#define POPEN_1 1
4182#define POPEN_2 2
4183#define POPEN_3 3
4184#define POPEN_4 4
4185
4186static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004187static int _PyPclose(FILE *file);
4188
4189/*
4190 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00004191 * for use when retrieving the process exit code. See _PyPclose() below
4192 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004193 */
4194static PyObject *_PyPopenProcs = NULL;
4195
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004196
4197/* popen that works from a GUI.
4198 *
4199 * The result of this function is a pipe (file) connected to the
4200 * processes stdin or stdout, depending on the requested mode.
4201 */
4202
4203static PyObject *
4204posix_popen(PyObject *self, PyObject *args)
4205{
Raymond Hettingerb5cb6652003-09-01 22:25:41 +00004206 PyObject *f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004207 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004208
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004209 char *cmdstring;
4210 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004211 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004212 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004213 return NULL;
4214
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004215 if (*mode == 'r')
4216 tm = _O_RDONLY;
4217 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00004218 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004219 return NULL;
4220 } else
4221 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00004222
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004223 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004224 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004225 return NULL;
4226 }
4227
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004228 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004229 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004230 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004231 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004232 else
4233 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
4234
4235 return f;
4236}
4237
4238/* Variation on win32pipe.popen
4239 *
4240 * The result of this function is a pipe (file) connected to the
4241 * process's stdin, and a pipe connected to the process's stdout.
4242 */
4243
4244static PyObject *
4245win32_popen2(PyObject *self, PyObject *args)
4246{
4247 PyObject *f;
4248 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00004249
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004250 char *cmdstring;
4251 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004252 int bufsize = -1;
4253 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004254 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004255
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004256 if (*mode == 't')
4257 tm = _O_TEXT;
4258 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004259 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004260 return NULL;
4261 } else
4262 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004263
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004264 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004265 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004266 return NULL;
4267 }
4268
4269 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00004270
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004271 return f;
4272}
4273
4274/*
4275 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004276 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004277 * The result of this function is 3 pipes - the process's stdin,
4278 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004279 */
4280
4281static PyObject *
4282win32_popen3(PyObject *self, PyObject *args)
4283{
4284 PyObject *f;
4285 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004286
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004287 char *cmdstring;
4288 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004289 int bufsize = -1;
4290 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004291 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004292
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004293 if (*mode == 't')
4294 tm = _O_TEXT;
4295 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004296 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004297 return NULL;
4298 } else
4299 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004300
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004301 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004302 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004303 return NULL;
4304 }
4305
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004306 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00004307
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004308 return f;
4309}
4310
4311/*
4312 * Variation on win32pipe.popen
4313 *
Tim Peters5aa91602002-01-30 05:46:57 +00004314 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004315 * and stdout+stderr combined as a single pipe.
4316 */
4317
4318static PyObject *
4319win32_popen4(PyObject *self, PyObject *args)
4320{
4321 PyObject *f;
4322 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004323
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004324 char *cmdstring;
4325 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004326 int bufsize = -1;
4327 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004328 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004329
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004330 if (*mode == 't')
4331 tm = _O_TEXT;
4332 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004333 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004334 return NULL;
4335 } else
4336 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004337
4338 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004339 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004340 return NULL;
4341 }
4342
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004343 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004344
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004345 return f;
4346}
4347
Mark Hammond08501372001-01-31 07:30:29 +00004348static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00004349_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004350 HANDLE hStdin,
4351 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00004352 HANDLE hStderr,
4353 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004354{
4355 PROCESS_INFORMATION piProcInfo;
4356 STARTUPINFO siStartInfo;
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004357 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004358 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00004359 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004360 int i;
Martin v. Löwis18e16552006-02-15 17:27:45 +00004361 Py_ssize_t x;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004362
4363 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00004364 char *comshell;
4365
Tim Peters92e4dd82002-10-05 01:47:34 +00004366 s1 = (char *)alloca(i);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004367 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
Martin v. Löwis18e16552006-02-15 17:27:45 +00004368 /* x < i, so x fits into an integer */
4369 return (int)x;
Tim Peters402d5982001-08-27 06:37:48 +00004370
4371 /* Explicitly check if we are using COMMAND.COM. If we are
4372 * then use the w9xpopen hack.
4373 */
4374 comshell = s1 + x;
4375 while (comshell >= s1 && *comshell != '\\')
4376 --comshell;
4377 ++comshell;
4378
4379 if (GetVersion() < 0x80000000 &&
4380 _stricmp(comshell, "command.com") != 0) {
4381 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004382 x = i + strlen(s3) + strlen(cmdstring) + 1;
Tim Peters92e4dd82002-10-05 01:47:34 +00004383 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004384 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00004385 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004386 }
4387 else {
4388 /*
Tim Peters402d5982001-08-27 06:37:48 +00004389 * Oh gag, we're on Win9x or using COMMAND.COM. Use
4390 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004391 */
Mark Hammond08501372001-01-31 07:30:29 +00004392 char modulepath[_MAX_PATH];
4393 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004394 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
Martin v. Löwis26fd9602006-04-22 11:15:41 +00004395 for (x = i = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004396 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004397 x = i+1;
4398 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00004399 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00004400 strncat(modulepath,
4401 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00004402 (sizeof(modulepath)/sizeof(modulepath[0]))
4403 -strlen(modulepath));
4404 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00004405 /* Eeek - file-not-found - possibly an embedding
4406 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00004407 */
Tim Peters5aa91602002-01-30 05:46:57 +00004408 strncpy(modulepath,
4409 Py_GetExecPrefix(),
Mark Hammond08501372001-01-31 07:30:29 +00004410 sizeof(modulepath)/sizeof(modulepath[0]));
4411 if (modulepath[strlen(modulepath)-1] != '\\')
4412 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00004413 strncat(modulepath,
4414 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00004415 (sizeof(modulepath)/sizeof(modulepath[0]))
4416 -strlen(modulepath));
4417 /* No where else to look - raise an easily identifiable
4418 error, rather than leaving Windows to report
4419 "file not found" - as the user is probably blissfully
4420 unaware this shim EXE is used, and it will confuse them.
4421 (well, it confused me for a while ;-)
4422 */
4423 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00004424 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00004425 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00004426 "for popen to work with your shell "
4427 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00004428 szConsoleSpawn);
4429 return FALSE;
4430 }
4431 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004432 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00004433 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004434 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00004435
Tim Peters92e4dd82002-10-05 01:47:34 +00004436 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004437 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004438 /* To maintain correct argument passing semantics,
4439 we pass the command-line as it stands, and allow
4440 quoting to be applied. w9xpopen.exe will then
4441 use its argv vector, and re-quote the necessary
4442 args for the ultimate child process.
4443 */
Tim Peters75cdad52001-11-28 22:07:30 +00004444 PyOS_snprintf(
4445 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004446 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004447 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004448 s1,
4449 s3,
4450 cmdstring);
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004451 /* Not passing CREATE_NEW_CONSOLE has been known to
Tim Peters11b23062003-04-23 02:39:17 +00004452 cause random failures on win9x. Specifically a
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004453 dialog:
4454 "Your program accessed mem currently in use at xxx"
4455 and a hopeful warning about the stability of your
4456 system.
4457 Cost is Ctrl+C wont kill children, but anyone
4458 who cares can have a go!
4459 */
4460 dwProcessFlags |= CREATE_NEW_CONSOLE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004461 }
4462 }
4463
4464 /* Could be an else here to try cmd.exe / command.com in the path
4465 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00004466 else {
Tim Peters402d5982001-08-27 06:37:48 +00004467 PyErr_SetString(PyExc_RuntimeError,
4468 "Cannot locate a COMSPEC environment variable to "
4469 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00004470 return FALSE;
4471 }
Tim Peters5aa91602002-01-30 05:46:57 +00004472
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004473 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
4474 siStartInfo.cb = sizeof(STARTUPINFO);
4475 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
4476 siStartInfo.hStdInput = hStdin;
4477 siStartInfo.hStdOutput = hStdout;
4478 siStartInfo.hStdError = hStderr;
4479 siStartInfo.wShowWindow = SW_HIDE;
4480
4481 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004482 s2,
4483 NULL,
4484 NULL,
4485 TRUE,
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004486 dwProcessFlags,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004487 NULL,
4488 NULL,
4489 &siStartInfo,
4490 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004491 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004492 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004493
Mark Hammondb37a3732000-08-14 04:47:33 +00004494 /* Return process handle */
4495 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004496 return TRUE;
4497 }
Tim Peters402d5982001-08-27 06:37:48 +00004498 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004499 return FALSE;
4500}
4501
4502/* The following code is based off of KB: Q190351 */
4503
4504static PyObject *
4505_PyPopen(char *cmdstring, int mode, int n)
4506{
4507 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
4508 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00004509 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00004510
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004511 SECURITY_ATTRIBUTES saAttr;
4512 BOOL fSuccess;
4513 int fd1, fd2, fd3;
4514 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00004515 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004516 PyObject *f;
4517
4518 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
4519 saAttr.bInheritHandle = TRUE;
4520 saAttr.lpSecurityDescriptor = NULL;
4521
4522 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
4523 return win32_error("CreatePipe", NULL);
4524
4525 /* Create new output read handle and the input write handle. Set
4526 * the inheritance properties to FALSE. Otherwise, the child inherits
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00004527 * these handles; resulting in non-closeable handles to the pipes
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004528 * being created. */
4529 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004530 GetCurrentProcess(), &hChildStdinWrDup, 0,
4531 FALSE,
4532 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004533 if (!fSuccess)
4534 return win32_error("DuplicateHandle", NULL);
4535
4536 /* Close the inheritable version of ChildStdin
4537 that we're using. */
4538 CloseHandle(hChildStdinWr);
4539
4540 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
4541 return win32_error("CreatePipe", NULL);
4542
4543 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004544 GetCurrentProcess(), &hChildStdoutRdDup, 0,
4545 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004546 if (!fSuccess)
4547 return win32_error("DuplicateHandle", NULL);
4548
4549 /* Close the inheritable version of ChildStdout
4550 that we're using. */
4551 CloseHandle(hChildStdoutRd);
4552
4553 if (n != POPEN_4) {
4554 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
4555 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004556 fSuccess = DuplicateHandle(GetCurrentProcess(),
4557 hChildStderrRd,
4558 GetCurrentProcess(),
4559 &hChildStderrRdDup, 0,
4560 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004561 if (!fSuccess)
4562 return win32_error("DuplicateHandle", NULL);
4563 /* Close the inheritable version of ChildStdErr that we're using. */
4564 CloseHandle(hChildStderrRd);
4565 }
Tim Peters5aa91602002-01-30 05:46:57 +00004566
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004567 switch (n) {
4568 case POPEN_1:
4569 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
4570 case _O_WRONLY | _O_TEXT:
4571 /* Case for writing to child Stdin in text mode. */
Martin v. Löwis18e16552006-02-15 17:27:45 +00004572 fd1 = _open_osfhandle((intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004573 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004574 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004575 PyFile_SetBufSize(f, 0);
4576 /* We don't care about these pipes anymore, so close them. */
4577 CloseHandle(hChildStdoutRdDup);
4578 CloseHandle(hChildStderrRdDup);
4579 break;
4580
4581 case _O_RDONLY | _O_TEXT:
4582 /* Case for reading from child Stdout in text mode. */
Martin v. Löwis18e16552006-02-15 17:27:45 +00004583 fd1 = _open_osfhandle((intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004584 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004585 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004586 PyFile_SetBufSize(f, 0);
4587 /* We don't care about these pipes anymore, so close them. */
4588 CloseHandle(hChildStdinWrDup);
4589 CloseHandle(hChildStderrRdDup);
4590 break;
4591
4592 case _O_RDONLY | _O_BINARY:
4593 /* Case for readinig from child Stdout in binary mode. */
Martin v. Löwis18e16552006-02-15 17:27:45 +00004594 fd1 = _open_osfhandle((intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004595 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004596 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004597 PyFile_SetBufSize(f, 0);
4598 /* We don't care about these pipes anymore, so close them. */
4599 CloseHandle(hChildStdinWrDup);
4600 CloseHandle(hChildStderrRdDup);
4601 break;
4602
4603 case _O_WRONLY | _O_BINARY:
4604 /* Case for writing to child Stdin in binary mode. */
Martin v. Löwis18e16552006-02-15 17:27:45 +00004605 fd1 = _open_osfhandle((intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004606 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004607 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004608 PyFile_SetBufSize(f, 0);
4609 /* We don't care about these pipes anymore, so close them. */
4610 CloseHandle(hChildStdoutRdDup);
4611 CloseHandle(hChildStderrRdDup);
4612 break;
4613 }
Mark Hammondb37a3732000-08-14 04:47:33 +00004614 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004615 break;
Tim Peters5aa91602002-01-30 05:46:57 +00004616
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004617 case POPEN_2:
4618 case POPEN_4:
4619 {
4620 char *m1, *m2;
4621 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00004622
Tim Peters7dca21e2002-08-19 00:42:29 +00004623 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004624 m1 = "r";
4625 m2 = "w";
4626 } else {
4627 m1 = "rb";
4628 m2 = "wb";
4629 }
4630
Martin v. Löwis18e16552006-02-15 17:27:45 +00004631 fd1 = _open_osfhandle((intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004632 f1 = _fdopen(fd1, m2);
Martin v. Löwis18e16552006-02-15 17:27:45 +00004633 fd2 = _open_osfhandle((intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004634 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004635 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004636 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00004637 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004638 PyFile_SetBufSize(p2, 0);
4639
4640 if (n != 4)
4641 CloseHandle(hChildStderrRdDup);
4642
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004643 f = PyTuple_Pack(2,p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00004644 Py_XDECREF(p1);
4645 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00004646 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004647 break;
4648 }
Tim Peters5aa91602002-01-30 05:46:57 +00004649
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004650 case POPEN_3:
4651 {
4652 char *m1, *m2;
4653 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00004654
Tim Peters7dca21e2002-08-19 00:42:29 +00004655 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004656 m1 = "r";
4657 m2 = "w";
4658 } else {
4659 m1 = "rb";
4660 m2 = "wb";
4661 }
4662
Martin v. Löwis18e16552006-02-15 17:27:45 +00004663 fd1 = _open_osfhandle((intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004664 f1 = _fdopen(fd1, m2);
Martin v. Löwis18e16552006-02-15 17:27:45 +00004665 fd2 = _open_osfhandle((intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004666 f2 = _fdopen(fd2, m1);
Martin v. Löwis18e16552006-02-15 17:27:45 +00004667 fd3 = _open_osfhandle((intptr_t)hChildStderrRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004668 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004669 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00004670 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
4671 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004672 PyFile_SetBufSize(p1, 0);
4673 PyFile_SetBufSize(p2, 0);
4674 PyFile_SetBufSize(p3, 0);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004675 f = PyTuple_Pack(3,p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00004676 Py_XDECREF(p1);
4677 Py_XDECREF(p2);
4678 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00004679 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004680 break;
4681 }
4682 }
4683
4684 if (n == POPEN_4) {
4685 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004686 hChildStdinRd,
4687 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004688 hChildStdoutWr,
4689 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004690 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004691 }
4692 else {
4693 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004694 hChildStdinRd,
4695 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004696 hChildStderrWr,
4697 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004698 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004699 }
4700
Mark Hammondb37a3732000-08-14 04:47:33 +00004701 /*
4702 * Insert the files we've created into the process dictionary
4703 * all referencing the list with the process handle and the
4704 * initial number of files (see description below in _PyPclose).
4705 * Since if _PyPclose later tried to wait on a process when all
4706 * handles weren't closed, it could create a deadlock with the
4707 * child, we spend some energy here to try to ensure that we
4708 * either insert all file handles into the dictionary or none
4709 * at all. It's a little clumsy with the various popen modes
4710 * and variable number of files involved.
4711 */
4712 if (!_PyPopenProcs) {
4713 _PyPopenProcs = PyDict_New();
4714 }
4715
4716 if (_PyPopenProcs) {
4717 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
4718 int ins_rc[3];
4719
4720 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4721 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4722
4723 procObj = PyList_New(2);
4724 hProcessObj = PyLong_FromVoidPtr(hProcess);
4725 intObj = PyInt_FromLong(file_count);
4726
4727 if (procObj && hProcessObj && intObj) {
4728 PyList_SetItem(procObj,0,hProcessObj);
4729 PyList_SetItem(procObj,1,intObj);
4730
4731 fileObj[0] = PyLong_FromVoidPtr(f1);
4732 if (fileObj[0]) {
4733 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4734 fileObj[0],
4735 procObj);
4736 }
4737 if (file_count >= 2) {
4738 fileObj[1] = PyLong_FromVoidPtr(f2);
4739 if (fileObj[1]) {
4740 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4741 fileObj[1],
4742 procObj);
4743 }
4744 }
4745 if (file_count >= 3) {
4746 fileObj[2] = PyLong_FromVoidPtr(f3);
4747 if (fileObj[2]) {
4748 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4749 fileObj[2],
4750 procObj);
4751 }
4752 }
4753
4754 if (ins_rc[0] < 0 || !fileObj[0] ||
4755 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4756 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
4757 /* Something failed - remove any dictionary
4758 * entries that did make it.
4759 */
4760 if (!ins_rc[0] && fileObj[0]) {
4761 PyDict_DelItem(_PyPopenProcs,
4762 fileObj[0]);
4763 }
4764 if (!ins_rc[1] && fileObj[1]) {
4765 PyDict_DelItem(_PyPopenProcs,
4766 fileObj[1]);
4767 }
4768 if (!ins_rc[2] && fileObj[2]) {
4769 PyDict_DelItem(_PyPopenProcs,
4770 fileObj[2]);
4771 }
4772 }
4773 }
Tim Peters5aa91602002-01-30 05:46:57 +00004774
Mark Hammondb37a3732000-08-14 04:47:33 +00004775 /*
4776 * Clean up our localized references for the dictionary keys
4777 * and value since PyDict_SetItem will Py_INCREF any copies
4778 * that got placed in the dictionary.
4779 */
4780 Py_XDECREF(procObj);
4781 Py_XDECREF(fileObj[0]);
4782 Py_XDECREF(fileObj[1]);
4783 Py_XDECREF(fileObj[2]);
4784 }
4785
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004786 /* Child is launched. Close the parents copy of those pipe
4787 * handles that only the child should have open. You need to
4788 * make sure that no handles to the write end of the output pipe
4789 * are maintained in this process or else the pipe will not close
4790 * when the child process exits and the ReadFile will hang. */
4791
4792 if (!CloseHandle(hChildStdinRd))
4793 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004794
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004795 if (!CloseHandle(hChildStdoutWr))
4796 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004797
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004798 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
4799 return win32_error("CloseHandle", NULL);
4800
4801 return f;
4802}
Fredrik Lundh56055a42000-07-23 19:47:12 +00004803
4804/*
4805 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4806 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00004807 *
4808 * This function uses the _PyPopenProcs dictionary in order to map the
4809 * input file pointer to information about the process that was
4810 * originally created by the popen* call that created the file pointer.
4811 * The dictionary uses the file pointer as a key (with one entry
4812 * inserted for each file returned by the original popen* call) and a
4813 * single list object as the value for all files from a single call.
4814 * The list object contains the Win32 process handle at [0], and a file
4815 * count at [1], which is initialized to the total number of file
4816 * handles using that list.
4817 *
4818 * This function closes whichever handle it is passed, and decrements
4819 * the file count in the dictionary for the process handle pointed to
4820 * by this file. On the last close (when the file count reaches zero),
4821 * this function will wait for the child process and then return its
4822 * exit code as the result of the close() operation. This permits the
4823 * files to be closed in any order - it is always the close() of the
4824 * final handle that will return the exit code.
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004825 *
4826 * NOTE: This function is currently called with the GIL released.
4827 * hence we use the GILState API to manage our state.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004828 */
Tim Peters736aa322000-09-01 06:51:24 +00004829
Fredrik Lundh56055a42000-07-23 19:47:12 +00004830static int _PyPclose(FILE *file)
4831{
Fredrik Lundh20318932000-07-26 17:29:12 +00004832 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004833 DWORD exit_code;
4834 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00004835 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
4836 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00004837#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004838 PyGILState_STATE state;
Tim Peters736aa322000-09-01 06:51:24 +00004839#endif
4840
Fredrik Lundh20318932000-07-26 17:29:12 +00004841 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00004842 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00004843 */
4844 result = fclose(file);
Tim Peters736aa322000-09-01 06:51:24 +00004845#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004846 state = PyGILState_Ensure();
Tim Peters736aa322000-09-01 06:51:24 +00004847#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00004848 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00004849 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4850 (procObj = PyDict_GetItem(_PyPopenProcs,
4851 fileObj)) != NULL &&
4852 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
4853 (intObj = PyList_GetItem(procObj,1)) != NULL) {
4854
4855 hProcess = PyLong_AsVoidPtr(hProcessObj);
4856 file_count = PyInt_AsLong(intObj);
4857
4858 if (file_count > 1) {
4859 /* Still other files referencing process */
4860 file_count--;
4861 PyList_SetItem(procObj,1,
4862 PyInt_FromLong(file_count));
4863 } else {
4864 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00004865 if (result != EOF &&
4866 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
4867 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00004868 /* Possible truncation here in 16-bit environments, but
4869 * real exit codes are just the lower byte in any event.
4870 */
4871 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004872 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00004873 /* Indicate failure - this will cause the file object
4874 * to raise an I/O error and translate the last Win32
4875 * error code from errno. We do have a problem with
4876 * last errors that overlap the normal errno table,
4877 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004878 */
Fredrik Lundh20318932000-07-26 17:29:12 +00004879 if (result != EOF) {
4880 /* If the error wasn't from the fclose(), then
4881 * set errno for the file object error handling.
4882 */
4883 errno = GetLastError();
4884 }
4885 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004886 }
4887
4888 /* Free up the native handle at this point */
4889 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00004890 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00004891
Mark Hammondb37a3732000-08-14 04:47:33 +00004892 /* Remove this file pointer from dictionary */
4893 PyDict_DelItem(_PyPopenProcs, fileObj);
4894
4895 if (PyDict_Size(_PyPopenProcs) == 0) {
4896 Py_DECREF(_PyPopenProcs);
4897 _PyPopenProcs = NULL;
4898 }
4899
4900 } /* if object retrieval ok */
4901
4902 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004903 } /* if _PyPopenProcs */
4904
Tim Peters736aa322000-09-01 06:51:24 +00004905#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004906 PyGILState_Release(state);
Tim Peters736aa322000-09-01 06:51:24 +00004907#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00004908 return result;
4909}
Tim Peters9acdd3a2000-09-01 19:26:36 +00004910
4911#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00004912static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004913posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00004914{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004915 char *name;
4916 char *mode = "r";
4917 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00004918 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00004919 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004920 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00004921 return NULL;
Martin v. Löwis9ad853b2003-10-31 10:01:53 +00004922 /* Strip mode of binary or text modifiers */
4923 if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
4924 mode = "r";
4925 else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
4926 mode = "w";
Barry Warsaw53699e91996-12-10 23:23:01 +00004927 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004928 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004929 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00004930 if (fp == NULL)
4931 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004932 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004933 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00004934 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004935 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00004936}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004937
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004938#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004939#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00004940
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004941
Guido van Rossumb6775db1994-08-01 11:34:53 +00004942#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004943PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004944"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004945Set the current process's user id.");
4946
Barry Warsaw53699e91996-12-10 23:23:01 +00004947static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004948posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004949{
4950 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004951 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004952 return NULL;
4953 if (setuid(uid) < 0)
4954 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004955 Py_INCREF(Py_None);
4956 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004957}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004958#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004959
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004960
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004961#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004962PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004963"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004964Set the current process's effective user id.");
4965
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004966static PyObject *
4967posix_seteuid (PyObject *self, PyObject *args)
4968{
4969 int euid;
4970 if (!PyArg_ParseTuple(args, "i", &euid)) {
4971 return NULL;
4972 } else if (seteuid(euid) < 0) {
4973 return posix_error();
4974 } else {
4975 Py_INCREF(Py_None);
4976 return Py_None;
4977 }
4978}
4979#endif /* HAVE_SETEUID */
4980
4981#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004982PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004983"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004984Set the current process's effective group id.");
4985
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004986static PyObject *
4987posix_setegid (PyObject *self, PyObject *args)
4988{
4989 int egid;
4990 if (!PyArg_ParseTuple(args, "i", &egid)) {
4991 return NULL;
4992 } else if (setegid(egid) < 0) {
4993 return posix_error();
4994 } else {
4995 Py_INCREF(Py_None);
4996 return Py_None;
4997 }
4998}
4999#endif /* HAVE_SETEGID */
5000
5001#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005002PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005003"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005004Set the current process's real and effective user ids.");
5005
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005006static PyObject *
5007posix_setreuid (PyObject *self, PyObject *args)
5008{
5009 int ruid, euid;
5010 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
5011 return NULL;
5012 } else if (setreuid(ruid, euid) < 0) {
5013 return posix_error();
5014 } else {
5015 Py_INCREF(Py_None);
5016 return Py_None;
5017 }
5018}
5019#endif /* HAVE_SETREUID */
5020
5021#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005022PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005023"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005024Set the current process's real and effective group ids.");
5025
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005026static PyObject *
5027posix_setregid (PyObject *self, PyObject *args)
5028{
5029 int rgid, egid;
5030 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
5031 return NULL;
5032 } else if (setregid(rgid, egid) < 0) {
5033 return posix_error();
5034 } else {
5035 Py_INCREF(Py_None);
5036 return Py_None;
5037 }
5038}
5039#endif /* HAVE_SETREGID */
5040
Guido van Rossumb6775db1994-08-01 11:34:53 +00005041#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005042PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005043"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005044Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005045
Barry Warsaw53699e91996-12-10 23:23:01 +00005046static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005047posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005048{
5049 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005050 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005051 return NULL;
5052 if (setgid(gid) < 0)
5053 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005054 Py_INCREF(Py_None);
5055 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005056}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005057#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005058
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005059#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005060PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005061"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005062Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005063
5064static PyObject *
5065posix_setgroups(PyObject *self, PyObject *args)
5066{
5067 PyObject *groups;
5068 int i, len;
5069 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00005070
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005071 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
5072 return NULL;
5073 if (!PySequence_Check(groups)) {
5074 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
5075 return NULL;
5076 }
5077 len = PySequence_Size(groups);
5078 if (len > MAX_GROUPS) {
5079 PyErr_SetString(PyExc_ValueError, "too many groups");
5080 return NULL;
5081 }
5082 for(i = 0; i < len; i++) {
5083 PyObject *elem;
5084 elem = PySequence_GetItem(groups, i);
5085 if (!elem)
5086 return NULL;
5087 if (!PyInt_Check(elem)) {
Georg Brandla13c2442005-11-22 19:30:31 +00005088 if (!PyLong_Check(elem)) {
5089 PyErr_SetString(PyExc_TypeError,
5090 "groups must be integers");
5091 Py_DECREF(elem);
5092 return NULL;
5093 } else {
5094 unsigned long x = PyLong_AsUnsignedLong(elem);
5095 if (PyErr_Occurred()) {
5096 PyErr_SetString(PyExc_TypeError,
5097 "group id too big");
5098 Py_DECREF(elem);
5099 return NULL;
5100 }
5101 grouplist[i] = x;
5102 /* read back the value to see if it fitted in gid_t */
5103 if (grouplist[i] != x) {
5104 PyErr_SetString(PyExc_TypeError,
5105 "group id too big");
5106 Py_DECREF(elem);
5107 return NULL;
5108 }
5109 }
5110 } else {
5111 long x = PyInt_AsLong(elem);
5112 grouplist[i] = x;
5113 if (grouplist[i] != x) {
5114 PyErr_SetString(PyExc_TypeError,
5115 "group id too big");
5116 Py_DECREF(elem);
5117 return NULL;
5118 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005119 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005120 Py_DECREF(elem);
5121 }
5122
5123 if (setgroups(len, grouplist) < 0)
5124 return posix_error();
5125 Py_INCREF(Py_None);
5126 return Py_None;
5127}
5128#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005129
Neal Norwitz6c2f9132006-03-20 07:25:26 +00005130#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Neal Norwitz05a45592006-03-20 06:30:08 +00005131static PyObject *
5132wait_helper(int pid, int status, struct rusage *ru)
5133{
5134 PyObject *result;
5135 static PyObject *struct_rusage;
5136
5137 if (pid == -1)
5138 return posix_error();
5139
5140 if (struct_rusage == NULL) {
5141 PyObject *m = PyImport_ImportModule("resource");
5142 if (m == NULL)
5143 return NULL;
5144 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
5145 Py_DECREF(m);
5146 if (struct_rusage == NULL)
5147 return NULL;
5148 }
5149
5150 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
5151 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
5152 if (!result)
5153 return NULL;
5154
5155#ifndef doubletime
5156#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
5157#endif
5158
5159 PyStructSequence_SET_ITEM(result, 0,
5160 PyFloat_FromDouble(doubletime(ru->ru_utime)));
5161 PyStructSequence_SET_ITEM(result, 1,
5162 PyFloat_FromDouble(doubletime(ru->ru_stime)));
5163#define SET_INT(result, index, value)\
5164 PyStructSequence_SET_ITEM(result, index, PyInt_FromLong(value))
5165 SET_INT(result, 2, ru->ru_maxrss);
5166 SET_INT(result, 3, ru->ru_ixrss);
5167 SET_INT(result, 4, ru->ru_idrss);
5168 SET_INT(result, 5, ru->ru_isrss);
5169 SET_INT(result, 6, ru->ru_minflt);
5170 SET_INT(result, 7, ru->ru_majflt);
5171 SET_INT(result, 8, ru->ru_nswap);
5172 SET_INT(result, 9, ru->ru_inblock);
5173 SET_INT(result, 10, ru->ru_oublock);
5174 SET_INT(result, 11, ru->ru_msgsnd);
5175 SET_INT(result, 12, ru->ru_msgrcv);
5176 SET_INT(result, 13, ru->ru_nsignals);
5177 SET_INT(result, 14, ru->ru_nvcsw);
5178 SET_INT(result, 15, ru->ru_nivcsw);
5179#undef SET_INT
5180
5181 if (PyErr_Occurred()) {
5182 Py_DECREF(result);
5183 return NULL;
5184 }
5185
Neal Norwitz9b00a562006-03-20 08:47:12 +00005186 return Py_BuildValue("iiN", pid, status, result);
Neal Norwitz05a45592006-03-20 06:30:08 +00005187}
Neal Norwitz6c2f9132006-03-20 07:25:26 +00005188#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
Neal Norwitz05a45592006-03-20 06:30:08 +00005189
5190#ifdef HAVE_WAIT3
5191PyDoc_STRVAR(posix_wait3__doc__,
5192"wait3(options) -> (pid, status, rusage)\n\n\
5193Wait for completion of a child process.");
5194
5195static PyObject *
5196posix_wait3(PyObject *self, PyObject *args)
5197{
5198 int pid, options;
5199 struct rusage ru;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005200 WAIT_TYPE status;
5201 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00005202
5203 if (!PyArg_ParseTuple(args, "i:wait3", &options))
5204 return NULL;
5205
5206 Py_BEGIN_ALLOW_THREADS
5207 pid = wait3(&status, options, &ru);
5208 Py_END_ALLOW_THREADS
5209
Neal Norwitzd5a37542006-03-20 06:48:34 +00005210 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00005211}
5212#endif /* HAVE_WAIT3 */
5213
5214#ifdef HAVE_WAIT4
5215PyDoc_STRVAR(posix_wait4__doc__,
5216"wait4(pid, options) -> (pid, status, rusage)\n\n\
5217Wait for completion of a given child process.");
5218
5219static PyObject *
5220posix_wait4(PyObject *self, PyObject *args)
5221{
5222 int pid, options;
5223 struct rusage ru;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005224 WAIT_TYPE status;
5225 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00005226
5227 if (!PyArg_ParseTuple(args, "ii:wait4", &pid, &options))
5228 return NULL;
5229
5230 Py_BEGIN_ALLOW_THREADS
5231 pid = wait4(pid, &status, options, &ru);
5232 Py_END_ALLOW_THREADS
5233
Neal Norwitzd5a37542006-03-20 06:48:34 +00005234 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00005235}
5236#endif /* HAVE_WAIT4 */
5237
Guido van Rossumb6775db1994-08-01 11:34:53 +00005238#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005239PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005240"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005241Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005242
Barry Warsaw53699e91996-12-10 23:23:01 +00005243static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005244posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005245{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005246 int pid, options;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005247 WAIT_TYPE status;
5248 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005249
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005250 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00005251 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005252 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00005253 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00005254 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00005255 if (pid == -1)
5256 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00005257
5258 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00005259}
5260
Tim Petersab034fa2002-02-01 11:27:43 +00005261#elif defined(HAVE_CWAIT)
5262
5263/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005264PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005265"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005266"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00005267
5268static PyObject *
5269posix_waitpid(PyObject *self, PyObject *args)
5270{
Martin v. Löwis18e16552006-02-15 17:27:45 +00005271 intptr_t pid;
5272 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00005273
5274 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
5275 return NULL;
5276 Py_BEGIN_ALLOW_THREADS
5277 pid = _cwait(&status, pid, options);
5278 Py_END_ALLOW_THREADS
5279 if (pid == -1)
5280 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00005281
5282 /* shift the status left a byte so this is more like the POSIX waitpid */
5283 return Py_BuildValue("ii", pid, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00005284}
5285#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005286
Guido van Rossumad0ee831995-03-01 10:34:45 +00005287#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005288PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005289"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005290Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005291
Barry Warsaw53699e91996-12-10 23:23:01 +00005292static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005293posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00005294{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005295 int pid;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005296 WAIT_TYPE status;
5297 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00005298
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005299 Py_BEGIN_ALLOW_THREADS
5300 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00005301 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00005302 if (pid == -1)
5303 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00005304
5305 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00005306}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005307#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005308
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005309
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005310PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005311"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005312Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005313
Barry Warsaw53699e91996-12-10 23:23:01 +00005314static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005315posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005316{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005317#ifdef HAVE_LSTAT
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005318 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005319#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005320#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00005321 return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005322#else
5323 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
5324#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005325#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005326}
5327
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005328
Guido van Rossumb6775db1994-08-01 11:34:53 +00005329#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005330PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005331"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005332Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005333
Barry Warsaw53699e91996-12-10 23:23:01 +00005334static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005335posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005336{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005337 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00005338 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005339 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005340 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005341 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005342 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00005343 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00005344 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005345 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00005346 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00005347 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005348}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005349#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005350
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005351
Guido van Rossumb6775db1994-08-01 11:34:53 +00005352#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005353PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005354"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00005355Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005356
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005357static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005358posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005359{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005360 return posix_2str(args, "etet:symlink", symlink, NULL, NULL);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005361}
5362#endif /* HAVE_SYMLINK */
5363
5364
5365#ifdef HAVE_TIMES
5366#ifndef HZ
5367#define HZ 60 /* Universal constant :-) */
5368#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00005369
Guido van Rossumd48f2521997-12-05 22:19:34 +00005370#if defined(PYCC_VACPP) && defined(PYOS_OS2)
5371static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005372system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005373{
5374 ULONG value = 0;
5375
5376 Py_BEGIN_ALLOW_THREADS
5377 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
5378 Py_END_ALLOW_THREADS
5379
5380 return value;
5381}
5382
5383static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005384posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005385{
Guido van Rossumd48f2521997-12-05 22:19:34 +00005386 /* Currently Only Uptime is Provided -- Others Later */
5387 return Py_BuildValue("ddddd",
5388 (double)0 /* t.tms_utime / HZ */,
5389 (double)0 /* t.tms_stime / HZ */,
5390 (double)0 /* t.tms_cutime / HZ */,
5391 (double)0 /* t.tms_cstime / HZ */,
5392 (double)system_uptime() / 1000);
5393}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005394#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00005395static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005396posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00005397{
5398 struct tms t;
5399 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +00005400 errno = 0;
5401 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00005402 if (c == (clock_t) -1)
5403 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005404 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00005405 (double)t.tms_utime / HZ,
5406 (double)t.tms_stime / HZ,
5407 (double)t.tms_cutime / HZ,
5408 (double)t.tms_cstime / HZ,
5409 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00005410}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005411#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005412#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005413
5414
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005415#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005416#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00005417static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005418posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005419{
5420 FILETIME create, exit, kernel, user;
5421 HANDLE hProc;
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005422 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00005423 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
5424 /* The fields of a FILETIME structure are the hi and lo part
5425 of a 64-bit value expressed in 100 nanosecond units.
5426 1e7 is one second in such units; 1e-7 the inverse.
5427 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
5428 */
Barry Warsaw53699e91996-12-10 23:23:01 +00005429 return Py_BuildValue(
5430 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00005431 (double)(kernel.dwHighDateTime*429.4967296 +
5432 kernel.dwLowDateTime*1e-7),
5433 (double)(user.dwHighDateTime*429.4967296 +
5434 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00005435 (double)0,
5436 (double)0,
5437 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005438}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005439#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005440
5441#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005442PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005443"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005444Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005445#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005446
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005447
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00005448#ifdef HAVE_GETSID
5449PyDoc_STRVAR(posix_getsid__doc__,
5450"getsid(pid) -> sid\n\n\
5451Call the system call getsid().");
5452
5453static PyObject *
5454posix_getsid(PyObject *self, PyObject *args)
5455{
5456 int pid, sid;
5457 if (!PyArg_ParseTuple(args, "i:getsid", &pid))
5458 return NULL;
5459 sid = getsid(pid);
5460 if (sid < 0)
5461 return posix_error();
5462 return PyInt_FromLong((long)sid);
5463}
5464#endif /* HAVE_GETSID */
5465
5466
Guido van Rossumb6775db1994-08-01 11:34:53 +00005467#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005468PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005469"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005470Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005471
Barry Warsaw53699e91996-12-10 23:23:01 +00005472static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005473posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005474{
Guido van Rossum687dd131993-05-17 08:34:16 +00005475 if (setsid() < 0)
5476 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005477 Py_INCREF(Py_None);
5478 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005479}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005480#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005481
Guido van Rossumb6775db1994-08-01 11:34:53 +00005482#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005483PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005484"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005485Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005486
Barry Warsaw53699e91996-12-10 23:23:01 +00005487static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005488posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005489{
5490 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005491 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00005492 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005493 if (setpgid(pid, pgrp) < 0)
5494 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005495 Py_INCREF(Py_None);
5496 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005497}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005498#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005499
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005500
Guido van Rossumb6775db1994-08-01 11:34:53 +00005501#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005502PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005503"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005504Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005505
Barry Warsaw53699e91996-12-10 23:23:01 +00005506static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005507posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005508{
5509 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005510 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00005511 return NULL;
5512 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005513 if (pgid < 0)
5514 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005515 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00005516}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005517#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00005518
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005519
Guido van Rossumb6775db1994-08-01 11:34:53 +00005520#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005521PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005522"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005523Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005524
Barry Warsaw53699e91996-12-10 23:23:01 +00005525static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005526posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005527{
5528 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005529 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00005530 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005531 if (tcsetpgrp(fd, pgid) < 0)
5532 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00005533 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00005534 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00005535}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005536#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00005537
Guido van Rossum687dd131993-05-17 08:34:16 +00005538/* Functions acting on file descriptors */
5539
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005540PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005541"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005542Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005543
Barry Warsaw53699e91996-12-10 23:23:01 +00005544static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005545posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005546{
Mark Hammondef8b6542001-05-13 08:04:26 +00005547 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005548 int flag;
5549 int mode = 0777;
5550 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005551
5552#ifdef MS_WINDOWS
5553 if (unicode_file_names()) {
5554 PyUnicodeObject *po;
5555 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
5556 Py_BEGIN_ALLOW_THREADS
5557 /* PyUnicode_AS_UNICODE OK without thread
5558 lock as it is a simple dereference. */
5559 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
5560 Py_END_ALLOW_THREADS
5561 if (fd < 0)
5562 return posix_error();
5563 return PyInt_FromLong((long)fd);
5564 }
5565 /* Drop the argument parsing error as narrow strings
5566 are also valid. */
5567 PyErr_Clear();
5568 }
5569#endif
5570
Tim Peters5aa91602002-01-30 05:46:57 +00005571 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00005572 Py_FileSystemDefaultEncoding, &file,
5573 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00005574 return NULL;
5575
Barry Warsaw53699e91996-12-10 23:23:01 +00005576 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005577 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005578 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005579 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00005580 return posix_error_with_allocated_filename(file);
5581 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00005582 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005583}
5584
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005585
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005586PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005587"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005588Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005589
Barry Warsaw53699e91996-12-10 23:23:01 +00005590static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005591posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005592{
5593 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005594 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005595 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005596 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005597 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00005598 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005599 if (res < 0)
5600 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005601 Py_INCREF(Py_None);
5602 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005603}
5604
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005605
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005606PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005607"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005608Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005609
Barry Warsaw53699e91996-12-10 23:23:01 +00005610static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005611posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005612{
5613 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005614 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005615 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005616 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005617 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00005618 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005619 if (fd < 0)
5620 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005621 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005622}
5623
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005624
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005625PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00005626"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005627Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005628
Barry Warsaw53699e91996-12-10 23:23:01 +00005629static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005630posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005631{
5632 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005633 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00005634 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005635 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005636 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00005637 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005638 if (res < 0)
5639 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005640 Py_INCREF(Py_None);
5641 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005642}
5643
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005644
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005645PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005646"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005647Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005648
Barry Warsaw53699e91996-12-10 23:23:01 +00005649static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005650posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005651{
5652 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005653#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005654 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005655#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00005656 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005657#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005658 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005659 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00005660 return NULL;
5661#ifdef SEEK_SET
5662 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
5663 switch (how) {
5664 case 0: how = SEEK_SET; break;
5665 case 1: how = SEEK_CUR; break;
5666 case 2: how = SEEK_END; break;
5667 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005668#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005669
5670#if !defined(HAVE_LARGEFILE_SUPPORT)
5671 pos = PyInt_AsLong(posobj);
5672#else
5673 pos = PyLong_Check(posobj) ?
5674 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
5675#endif
5676 if (PyErr_Occurred())
5677 return NULL;
5678
Barry Warsaw53699e91996-12-10 23:23:01 +00005679 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005680#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00005681 res = _lseeki64(fd, pos, how);
5682#else
Guido van Rossum687dd131993-05-17 08:34:16 +00005683 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005684#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005685 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005686 if (res < 0)
5687 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00005688
5689#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00005690 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005691#else
5692 return PyLong_FromLongLong(res);
5693#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005694}
5695
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005696
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005697PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005698"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005699Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005700
Barry Warsaw53699e91996-12-10 23:23:01 +00005701static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005702posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005703{
Guido van Rossum8bac5461996-06-11 18:38:48 +00005704 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00005705 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005706 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005707 return NULL;
Michael W. Hudson9867ced2005-01-31 17:01:59 +00005708 if (size < 0) {
5709 errno = EINVAL;
5710 return posix_error();
5711 }
Barry Warsaw53699e91996-12-10 23:23:01 +00005712 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005713 if (buffer == NULL)
5714 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005715 Py_BEGIN_ALLOW_THREADS
5716 n = read(fd, PyString_AsString(buffer), size);
5717 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00005718 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005719 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00005720 return posix_error();
5721 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00005722 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00005723 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00005724 return buffer;
5725}
5726
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005727
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005728PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005729"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005730Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005731
Barry Warsaw53699e91996-12-10 23:23:01 +00005732static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005733posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005734{
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005735 int fd;
5736 Py_ssize_t size;
Guido van Rossum687dd131993-05-17 08:34:16 +00005737 char *buffer;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005738
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005739 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005740 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005741 Py_BEGIN_ALLOW_THREADS
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005742 size = write(fd, buffer, (size_t)size);
Barry Warsaw53699e91996-12-10 23:23:01 +00005743 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005744 if (size < 0)
5745 return posix_error();
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005746 return PyInt_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005747}
5748
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005749
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005750PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005751"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005752Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005753
Barry Warsaw53699e91996-12-10 23:23:01 +00005754static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005755posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005756{
5757 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00005758 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00005759 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005760 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005761 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005762#ifdef __VMS
5763 /* on OpenVMS we must ensure that all bytes are written to the file */
5764 fsync(fd);
5765#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005766 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00005767 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00005768 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00005769 if (res != 0) {
5770#ifdef MS_WINDOWS
5771 return win32_error("fstat", NULL);
5772#else
Guido van Rossum687dd131993-05-17 08:34:16 +00005773 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00005774#endif
5775 }
Tim Peters5aa91602002-01-30 05:46:57 +00005776
Martin v. Löwis14694662006-02-03 12:54:16 +00005777 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00005778}
5779
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005780
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005781PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005782"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005783Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005784
Barry Warsaw53699e91996-12-10 23:23:01 +00005785static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005786posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005787{
Guido van Rossum687dd131993-05-17 08:34:16 +00005788 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005789 char *mode = "r";
5790 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00005791 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00005792 PyObject *f;
5793 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00005794 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00005795
Thomas Heller1f043e22002-11-07 16:00:59 +00005796 if (mode[0] != 'r' && mode[0] != 'w' && mode[0] != 'a') {
5797 PyErr_Format(PyExc_ValueError,
5798 "invalid file mode '%s'", mode);
5799 return NULL;
5800 }
Barry Warsaw53699e91996-12-10 23:23:01 +00005801 Py_BEGIN_ALLOW_THREADS
Georg Brandl644b1e72006-03-31 20:27:22 +00005802#if !defined(MS_WINDOWS) && defined(HAVE_FCNTL_H)
Georg Brandl54a188a2006-03-31 20:00:11 +00005803 if (mode[0] == 'a') {
5804 /* try to make sure the O_APPEND flag is set */
5805 int flags;
5806 flags = fcntl(fd, F_GETFL);
5807 if (flags != -1)
5808 fcntl(fd, F_SETFL, flags | O_APPEND);
5809 fp = fdopen(fd, mode);
Thomas Wouters2a9a6b02006-03-31 22:38:19 +00005810 if (fp == NULL && flags != -1)
Georg Brandl54a188a2006-03-31 20:00:11 +00005811 /* restore old mode if fdopen failed */
5812 fcntl(fd, F_SETFL, flags);
5813 } else {
5814 fp = fdopen(fd, mode);
5815 }
Georg Brandl644b1e72006-03-31 20:27:22 +00005816#else
5817 fp = fdopen(fd, mode);
5818#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005819 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005820 if (fp == NULL)
5821 return posix_error();
Guido van Rossumbd6be7a2002-09-15 18:45:46 +00005822 f = PyFile_FromFile(fp, "<fdopen>", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005823 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00005824 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005825 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00005826}
5827
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005828PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005829"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005830Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005831connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00005832
5833static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00005834posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00005835{
5836 int fd;
5837 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
5838 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005839 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00005840}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005841
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005842#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005843PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005844"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005845Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005846
Barry Warsaw53699e91996-12-10 23:23:01 +00005847static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005848posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00005849{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005850#if defined(PYOS_OS2)
5851 HFILE read, write;
5852 APIRET rc;
5853
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005854 Py_BEGIN_ALLOW_THREADS
5855 rc = DosCreatePipe( &read, &write, 4096);
5856 Py_END_ALLOW_THREADS
5857 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005858 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005859
5860 return Py_BuildValue("(ii)", read, write);
5861#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005862#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00005863 int fds[2];
5864 int res;
Barry Warsaw53699e91996-12-10 23:23:01 +00005865 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005866 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00005867 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005868 if (res != 0)
5869 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005870 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005871#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00005872 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005873 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00005874 BOOL ok;
Barry Warsaw53699e91996-12-10 23:23:01 +00005875 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005876 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00005877 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00005878 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005879 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00005880 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
5881 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005882 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005883#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005884#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005885}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005886#endif /* HAVE_PIPE */
5887
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005888
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005889#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005890PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005891"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005892Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005893
Barry Warsaw53699e91996-12-10 23:23:01 +00005894static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005895posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005896{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005897 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005898 int mode = 0666;
5899 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005900 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005901 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005902 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005903 res = mkfifo(filename, mode);
5904 Py_END_ALLOW_THREADS
5905 if (res < 0)
5906 return posix_error();
5907 Py_INCREF(Py_None);
5908 return Py_None;
5909}
5910#endif
5911
5912
Neal Norwitz11690112002-07-30 01:08:28 +00005913#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005914PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005915"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005916Create a filesystem node (file, device special file or named pipe)\n\
5917named filename. mode specifies both the permissions to use and the\n\
5918type of node to be created, being combined (bitwise OR) with one of\n\
5919S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005920device defines the newly created device special file (probably using\n\
5921os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005922
5923
5924static PyObject *
5925posix_mknod(PyObject *self, PyObject *args)
5926{
5927 char *filename;
5928 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005929 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005930 int res;
Martin v. Löwisd631ebe2002-11-02 17:42:33 +00005931 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005932 return NULL;
5933 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005934 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00005935 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005936 if (res < 0)
5937 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005938 Py_INCREF(Py_None);
5939 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005940}
5941#endif
5942
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005943#ifdef HAVE_DEVICE_MACROS
5944PyDoc_STRVAR(posix_major__doc__,
5945"major(device) -> major number\n\
5946Extracts a device major number from a raw device number.");
5947
5948static PyObject *
5949posix_major(PyObject *self, PyObject *args)
5950{
5951 int device;
5952 if (!PyArg_ParseTuple(args, "i:major", &device))
5953 return NULL;
5954 return PyInt_FromLong((long)major(device));
5955}
5956
5957PyDoc_STRVAR(posix_minor__doc__,
5958"minor(device) -> minor number\n\
5959Extracts a device minor number from a raw device number.");
5960
5961static PyObject *
5962posix_minor(PyObject *self, PyObject *args)
5963{
5964 int device;
5965 if (!PyArg_ParseTuple(args, "i:minor", &device))
5966 return NULL;
5967 return PyInt_FromLong((long)minor(device));
5968}
5969
5970PyDoc_STRVAR(posix_makedev__doc__,
5971"makedev(major, minor) -> device number\n\
5972Composes a raw device number from the major and minor device numbers.");
5973
5974static PyObject *
5975posix_makedev(PyObject *self, PyObject *args)
5976{
5977 int major, minor;
5978 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
5979 return NULL;
5980 return PyInt_FromLong((long)makedev(major, minor));
5981}
5982#endif /* device macros */
5983
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005984
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005985#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005986PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005987"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005988Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005989
Barry Warsaw53699e91996-12-10 23:23:01 +00005990static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005991posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005992{
5993 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005994 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005995 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005996 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005997
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005998 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005999 return NULL;
6000
6001#if !defined(HAVE_LARGEFILE_SUPPORT)
6002 length = PyInt_AsLong(lenobj);
6003#else
6004 length = PyLong_Check(lenobj) ?
6005 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
6006#endif
6007 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006008 return NULL;
6009
Barry Warsaw53699e91996-12-10 23:23:01 +00006010 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006011 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00006012 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006013 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00006014 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006015 return NULL;
6016 }
Barry Warsaw53699e91996-12-10 23:23:01 +00006017 Py_INCREF(Py_None);
6018 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006019}
6020#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006021
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006022#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006023PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006024"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006025Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006026
Fred Drake762e2061999-08-26 17:23:54 +00006027/* Save putenv() parameters as values here, so we can collect them when they
6028 * get re-set with another call for the same key. */
6029static PyObject *posix_putenv_garbage;
6030
Tim Peters5aa91602002-01-30 05:46:57 +00006031static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006032posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006033{
6034 char *s1, *s2;
Anthony Baxter64182fe2006-04-11 12:14:09 +00006035 char *newenv;
Fred Drake762e2061999-08-26 17:23:54 +00006036 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00006037 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006038
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006039 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006040 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00006041
6042#if defined(PYOS_OS2)
6043 if (stricmp(s1, "BEGINLIBPATH") == 0) {
6044 APIRET rc;
6045
Guido van Rossumd48f2521997-12-05 22:19:34 +00006046 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
6047 if (rc != NO_ERROR)
6048 return os2_error(rc);
6049
6050 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
6051 APIRET rc;
6052
Guido van Rossumd48f2521997-12-05 22:19:34 +00006053 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
6054 if (rc != NO_ERROR)
6055 return os2_error(rc);
6056 } else {
6057#endif
6058
Fred Drake762e2061999-08-26 17:23:54 +00006059 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00006060 len = strlen(s1) + strlen(s2) + 2;
6061 /* len includes space for a trailing \0; the size arg to
6062 PyString_FromStringAndSize does not count that */
6063 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00006064 if (newstr == NULL)
6065 return PyErr_NoMemory();
Anthony Baxter64182fe2006-04-11 12:14:09 +00006066 newenv = PyString_AS_STRING(newstr);
6067 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
6068 if (putenv(newenv)) {
Neal Norwitz4adc9ab2003-02-10 03:10:43 +00006069 Py_DECREF(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006070 posix_error();
6071 return NULL;
6072 }
Fred Drake762e2061999-08-26 17:23:54 +00006073 /* Install the first arg and newstr in posix_putenv_garbage;
6074 * this will cause previous value to be collected. This has to
6075 * happen after the real putenv() call because the old value
6076 * was still accessible until then. */
6077 if (PyDict_SetItem(posix_putenv_garbage,
6078 PyTuple_GET_ITEM(args, 0), newstr)) {
6079 /* really not much we can do; just leak */
6080 PyErr_Clear();
6081 }
6082 else {
6083 Py_DECREF(newstr);
6084 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00006085
6086#if defined(PYOS_OS2)
6087 }
6088#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006089 Py_INCREF(Py_None);
6090 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006091}
Guido van Rossumb6a47161997-09-15 22:54:34 +00006092#endif /* putenv */
6093
Guido van Rossumc524d952001-10-19 01:31:59 +00006094#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006095PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006096"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006097Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00006098
6099static PyObject *
6100posix_unsetenv(PyObject *self, PyObject *args)
6101{
6102 char *s1;
6103
6104 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
6105 return NULL;
6106
6107 unsetenv(s1);
6108
6109 /* Remove the key from posix_putenv_garbage;
6110 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00006111 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00006112 * old value was still accessible until then.
6113 */
6114 if (PyDict_DelItem(posix_putenv_garbage,
6115 PyTuple_GET_ITEM(args, 0))) {
6116 /* really not much we can do; just leak */
6117 PyErr_Clear();
6118 }
6119
6120 Py_INCREF(Py_None);
6121 return Py_None;
6122}
6123#endif /* unsetenv */
6124
Guido van Rossumb6a47161997-09-15 22:54:34 +00006125#ifdef HAVE_STRERROR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006126PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006127"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006128Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00006129
Guido van Rossumf68d8e52001-04-14 17:55:09 +00006130static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006131posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00006132{
6133 int code;
6134 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006135 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00006136 return NULL;
6137 message = strerror(code);
6138 if (message == NULL) {
6139 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00006140 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00006141 return NULL;
6142 }
6143 return PyString_FromString(message);
6144}
6145#endif /* strerror */
6146
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006147
Guido van Rossumc9641791998-08-04 15:26:23 +00006148#ifdef HAVE_SYS_WAIT_H
6149
Fred Drake106c1a02002-04-23 15:58:02 +00006150#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006151PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006152"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006153Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00006154
6155static PyObject *
6156posix_WCOREDUMP(PyObject *self, PyObject *args)
6157{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006158 WAIT_TYPE status;
6159 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006160
Neal Norwitzd5a37542006-03-20 06:48:34 +00006161 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00006162 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006163
6164 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006165}
6166#endif /* WCOREDUMP */
6167
6168#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006169PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006170"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006171Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006172job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00006173
6174static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006175posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00006176{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006177 WAIT_TYPE status;
6178 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006179
Neal Norwitzd5a37542006-03-20 06:48:34 +00006180 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00006181 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006182
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006183 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006184}
6185#endif /* WIFCONTINUED */
6186
Guido van Rossumc9641791998-08-04 15:26:23 +00006187#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006188PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006189"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006190Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006191
6192static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006193posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006194{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006195 WAIT_TYPE status;
6196 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006197
Neal Norwitzd5a37542006-03-20 06:48:34 +00006198 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006199 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006200
Fred Drake106c1a02002-04-23 15:58:02 +00006201 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006202}
6203#endif /* WIFSTOPPED */
6204
6205#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006206PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006207"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006208Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006209
6210static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006211posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006212{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006213 WAIT_TYPE status;
6214 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006215
Neal Norwitzd5a37542006-03-20 06:48:34 +00006216 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006217 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006218
Fred Drake106c1a02002-04-23 15:58:02 +00006219 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006220}
6221#endif /* WIFSIGNALED */
6222
6223#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006224PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006225"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006226Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006227system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006228
6229static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006230posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006231{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006232 WAIT_TYPE status;
6233 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006234
Neal Norwitzd5a37542006-03-20 06:48:34 +00006235 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006236 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006237
Fred Drake106c1a02002-04-23 15:58:02 +00006238 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006239}
6240#endif /* WIFEXITED */
6241
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006242#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006243PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006244"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006245Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006246
6247static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006248posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006249{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006250 WAIT_TYPE status;
6251 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006252
Neal Norwitzd5a37542006-03-20 06:48:34 +00006253 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006254 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006255
Guido van Rossumc9641791998-08-04 15:26:23 +00006256 return Py_BuildValue("i", WEXITSTATUS(status));
6257}
6258#endif /* WEXITSTATUS */
6259
6260#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006261PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006262"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006263Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006264value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006265
6266static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006267posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006268{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006269 WAIT_TYPE status;
6270 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006271
Neal Norwitzd5a37542006-03-20 06:48:34 +00006272 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006273 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006274
Guido van Rossumc9641791998-08-04 15:26:23 +00006275 return Py_BuildValue("i", WTERMSIG(status));
6276}
6277#endif /* WTERMSIG */
6278
6279#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006280PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006281"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006282Return the signal that stopped the process that provided\n\
6283the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006284
6285static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006286posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006287{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006288 WAIT_TYPE status;
6289 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006290
Neal Norwitzd5a37542006-03-20 06:48:34 +00006291 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006292 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006293
Guido van Rossumc9641791998-08-04 15:26:23 +00006294 return Py_BuildValue("i", WSTOPSIG(status));
6295}
6296#endif /* WSTOPSIG */
6297
6298#endif /* HAVE_SYS_WAIT_H */
6299
6300
Guido van Rossum94f6f721999-01-06 18:42:14 +00006301#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00006302#ifdef _SCO_DS
6303/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
6304 needed definitions in sys/statvfs.h */
6305#define _SVID3
6306#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006307#include <sys/statvfs.h>
6308
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006309static PyObject*
6310_pystatvfs_fromstructstatvfs(struct statvfs st) {
6311 PyObject *v = PyStructSequence_New(&StatVFSResultType);
6312 if (v == NULL)
6313 return NULL;
6314
6315#if !defined(HAVE_LARGEFILE_SUPPORT)
6316 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6317 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
6318 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
6319 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
6320 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
6321 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
6322 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
6323 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
6324 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6325 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6326#else
6327 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6328 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00006329 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006330 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00006331 PyStructSequence_SET_ITEM(v, 3,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006332 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006333 PyStructSequence_SET_ITEM(v, 4,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006334 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00006335 PyStructSequence_SET_ITEM(v, 5,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006336 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00006337 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006338 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00006339 PyStructSequence_SET_ITEM(v, 7,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006340 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006341 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6342 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6343#endif
6344
6345 return v;
6346}
6347
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006348PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006349"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006350Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006351
6352static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006353posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006354{
6355 int fd, res;
6356 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006357
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006358 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006359 return NULL;
6360 Py_BEGIN_ALLOW_THREADS
6361 res = fstatvfs(fd, &st);
6362 Py_END_ALLOW_THREADS
6363 if (res != 0)
6364 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006365
6366 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006367}
6368#endif /* HAVE_FSTATVFS */
6369
6370
6371#if defined(HAVE_STATVFS)
6372#include <sys/statvfs.h>
6373
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006374PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006375"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006376Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006377
6378static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006379posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006380{
6381 char *path;
6382 int res;
6383 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006384 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006385 return NULL;
6386 Py_BEGIN_ALLOW_THREADS
6387 res = statvfs(path, &st);
6388 Py_END_ALLOW_THREADS
6389 if (res != 0)
6390 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006391
6392 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006393}
6394#endif /* HAVE_STATVFS */
6395
6396
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006397#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006398PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006399"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006400Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00006401The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006402or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006403
6404static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006405posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006406{
6407 PyObject *result = NULL;
6408 char *dir = NULL;
6409 char *pfx = NULL;
6410 char *name;
6411
6412 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
6413 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00006414
6415 if (PyErr_Warn(PyExc_RuntimeWarning,
6416 "tempnam is a potential security risk to your program") < 0)
6417 return NULL;
6418
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006419#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00006420 name = _tempnam(dir, pfx);
6421#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006422 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00006423#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006424 if (name == NULL)
6425 return PyErr_NoMemory();
6426 result = PyString_FromString(name);
6427 free(name);
6428 return result;
6429}
Guido van Rossumd371ff11999-01-25 16:12:23 +00006430#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006431
6432
6433#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006434PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006435"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006436Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006437
6438static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006439posix_tmpfile(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006440{
6441 FILE *fp;
6442
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006443 fp = tmpfile();
6444 if (fp == NULL)
6445 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00006446 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006447}
6448#endif
6449
6450
6451#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006452PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006453"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006454Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006455
6456static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006457posix_tmpnam(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006458{
6459 char buffer[L_tmpnam];
6460 char *name;
6461
Skip Montanaro95618b52001-08-18 18:52:10 +00006462 if (PyErr_Warn(PyExc_RuntimeWarning,
6463 "tmpnam is a potential security risk to your program") < 0)
6464 return NULL;
6465
Greg Wardb48bc172000-03-01 21:51:56 +00006466#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006467 name = tmpnam_r(buffer);
6468#else
6469 name = tmpnam(buffer);
6470#endif
6471 if (name == NULL) {
Neal Norwitzd1e0ef62006-03-20 04:08:12 +00006472 PyObject *err = Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00006473#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006474 "unexpected NULL from tmpnam_r"
6475#else
6476 "unexpected NULL from tmpnam"
6477#endif
Neal Norwitzd1e0ef62006-03-20 04:08:12 +00006478 );
6479 PyErr_SetObject(PyExc_OSError, err);
6480 Py_XDECREF(err);
6481 return NULL;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006482 }
6483 return PyString_FromString(buffer);
6484}
6485#endif
6486
6487
Fred Drakec9680921999-12-13 16:37:25 +00006488/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
6489 * It maps strings representing configuration variable names to
6490 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00006491 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00006492 * rarely-used constants. There are three separate tables that use
6493 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00006494 *
6495 * This code is always included, even if none of the interfaces that
6496 * need it are included. The #if hackery needed to avoid it would be
6497 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00006498 */
6499struct constdef {
6500 char *name;
6501 long value;
6502};
6503
Fred Drake12c6e2d1999-12-14 21:25:03 +00006504static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006505conv_confname(PyObject *arg, int *valuep, struct constdef *table,
6506 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006507{
6508 if (PyInt_Check(arg)) {
6509 *valuep = PyInt_AS_LONG(arg);
6510 return 1;
6511 }
6512 if (PyString_Check(arg)) {
6513 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00006514 size_t lo = 0;
6515 size_t mid;
6516 size_t hi = tablesize;
6517 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006518 char *confname = PyString_AS_STRING(arg);
6519 while (lo < hi) {
6520 mid = (lo + hi) / 2;
6521 cmp = strcmp(confname, table[mid].name);
6522 if (cmp < 0)
6523 hi = mid;
6524 else if (cmp > 0)
6525 lo = mid + 1;
6526 else {
6527 *valuep = table[mid].value;
6528 return 1;
6529 }
6530 }
6531 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
6532 }
6533 else
6534 PyErr_SetString(PyExc_TypeError,
6535 "configuration names must be strings or integers");
6536 return 0;
6537}
6538
6539
6540#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
6541static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006542#ifdef _PC_ABI_AIO_XFER_MAX
6543 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
6544#endif
6545#ifdef _PC_ABI_ASYNC_IO
6546 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
6547#endif
Fred Drakec9680921999-12-13 16:37:25 +00006548#ifdef _PC_ASYNC_IO
6549 {"PC_ASYNC_IO", _PC_ASYNC_IO},
6550#endif
6551#ifdef _PC_CHOWN_RESTRICTED
6552 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
6553#endif
6554#ifdef _PC_FILESIZEBITS
6555 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
6556#endif
6557#ifdef _PC_LAST
6558 {"PC_LAST", _PC_LAST},
6559#endif
6560#ifdef _PC_LINK_MAX
6561 {"PC_LINK_MAX", _PC_LINK_MAX},
6562#endif
6563#ifdef _PC_MAX_CANON
6564 {"PC_MAX_CANON", _PC_MAX_CANON},
6565#endif
6566#ifdef _PC_MAX_INPUT
6567 {"PC_MAX_INPUT", _PC_MAX_INPUT},
6568#endif
6569#ifdef _PC_NAME_MAX
6570 {"PC_NAME_MAX", _PC_NAME_MAX},
6571#endif
6572#ifdef _PC_NO_TRUNC
6573 {"PC_NO_TRUNC", _PC_NO_TRUNC},
6574#endif
6575#ifdef _PC_PATH_MAX
6576 {"PC_PATH_MAX", _PC_PATH_MAX},
6577#endif
6578#ifdef _PC_PIPE_BUF
6579 {"PC_PIPE_BUF", _PC_PIPE_BUF},
6580#endif
6581#ifdef _PC_PRIO_IO
6582 {"PC_PRIO_IO", _PC_PRIO_IO},
6583#endif
6584#ifdef _PC_SOCK_MAXBUF
6585 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
6586#endif
6587#ifdef _PC_SYNC_IO
6588 {"PC_SYNC_IO", _PC_SYNC_IO},
6589#endif
6590#ifdef _PC_VDISABLE
6591 {"PC_VDISABLE", _PC_VDISABLE},
6592#endif
6593};
6594
Fred Drakec9680921999-12-13 16:37:25 +00006595static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006596conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006597{
6598 return conv_confname(arg, valuep, posix_constants_pathconf,
6599 sizeof(posix_constants_pathconf)
6600 / sizeof(struct constdef));
6601}
6602#endif
6603
6604#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006605PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006606"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006607Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006608If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006609
6610static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006611posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006612{
6613 PyObject *result = NULL;
6614 int name, fd;
6615
Fred Drake12c6e2d1999-12-14 21:25:03 +00006616 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
6617 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00006618 long limit;
6619
6620 errno = 0;
6621 limit = fpathconf(fd, name);
6622 if (limit == -1 && errno != 0)
6623 posix_error();
6624 else
6625 result = PyInt_FromLong(limit);
6626 }
6627 return result;
6628}
6629#endif
6630
6631
6632#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006633PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006634"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006635Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006636If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006637
6638static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006639posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006640{
6641 PyObject *result = NULL;
6642 int name;
6643 char *path;
6644
6645 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
6646 conv_path_confname, &name)) {
6647 long limit;
6648
6649 errno = 0;
6650 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006651 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00006652 if (errno == EINVAL)
6653 /* could be a path or name problem */
6654 posix_error();
6655 else
6656 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006657 }
Fred Drakec9680921999-12-13 16:37:25 +00006658 else
6659 result = PyInt_FromLong(limit);
6660 }
6661 return result;
6662}
6663#endif
6664
6665#ifdef HAVE_CONFSTR
6666static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006667#ifdef _CS_ARCHITECTURE
6668 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
6669#endif
6670#ifdef _CS_HOSTNAME
6671 {"CS_HOSTNAME", _CS_HOSTNAME},
6672#endif
6673#ifdef _CS_HW_PROVIDER
6674 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
6675#endif
6676#ifdef _CS_HW_SERIAL
6677 {"CS_HW_SERIAL", _CS_HW_SERIAL},
6678#endif
6679#ifdef _CS_INITTAB_NAME
6680 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
6681#endif
Fred Drakec9680921999-12-13 16:37:25 +00006682#ifdef _CS_LFS64_CFLAGS
6683 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
6684#endif
6685#ifdef _CS_LFS64_LDFLAGS
6686 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
6687#endif
6688#ifdef _CS_LFS64_LIBS
6689 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
6690#endif
6691#ifdef _CS_LFS64_LINTFLAGS
6692 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
6693#endif
6694#ifdef _CS_LFS_CFLAGS
6695 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
6696#endif
6697#ifdef _CS_LFS_LDFLAGS
6698 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
6699#endif
6700#ifdef _CS_LFS_LIBS
6701 {"CS_LFS_LIBS", _CS_LFS_LIBS},
6702#endif
6703#ifdef _CS_LFS_LINTFLAGS
6704 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
6705#endif
Fred Draked86ed291999-12-15 15:34:33 +00006706#ifdef _CS_MACHINE
6707 {"CS_MACHINE", _CS_MACHINE},
6708#endif
Fred Drakec9680921999-12-13 16:37:25 +00006709#ifdef _CS_PATH
6710 {"CS_PATH", _CS_PATH},
6711#endif
Fred Draked86ed291999-12-15 15:34:33 +00006712#ifdef _CS_RELEASE
6713 {"CS_RELEASE", _CS_RELEASE},
6714#endif
6715#ifdef _CS_SRPC_DOMAIN
6716 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
6717#endif
6718#ifdef _CS_SYSNAME
6719 {"CS_SYSNAME", _CS_SYSNAME},
6720#endif
6721#ifdef _CS_VERSION
6722 {"CS_VERSION", _CS_VERSION},
6723#endif
Fred Drakec9680921999-12-13 16:37:25 +00006724#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
6725 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
6726#endif
6727#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
6728 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
6729#endif
6730#ifdef _CS_XBS5_ILP32_OFF32_LIBS
6731 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
6732#endif
6733#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
6734 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
6735#endif
6736#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
6737 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
6738#endif
6739#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
6740 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
6741#endif
6742#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
6743 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
6744#endif
6745#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
6746 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
6747#endif
6748#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
6749 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
6750#endif
6751#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
6752 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
6753#endif
6754#ifdef _CS_XBS5_LP64_OFF64_LIBS
6755 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
6756#endif
6757#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
6758 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
6759#endif
6760#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
6761 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
6762#endif
6763#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
6764 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
6765#endif
6766#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
6767 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
6768#endif
6769#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
6770 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
6771#endif
Fred Draked86ed291999-12-15 15:34:33 +00006772#ifdef _MIPS_CS_AVAIL_PROCESSORS
6773 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
6774#endif
6775#ifdef _MIPS_CS_BASE
6776 {"MIPS_CS_BASE", _MIPS_CS_BASE},
6777#endif
6778#ifdef _MIPS_CS_HOSTID
6779 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
6780#endif
6781#ifdef _MIPS_CS_HW_NAME
6782 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
6783#endif
6784#ifdef _MIPS_CS_NUM_PROCESSORS
6785 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
6786#endif
6787#ifdef _MIPS_CS_OSREL_MAJ
6788 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
6789#endif
6790#ifdef _MIPS_CS_OSREL_MIN
6791 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
6792#endif
6793#ifdef _MIPS_CS_OSREL_PATCH
6794 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
6795#endif
6796#ifdef _MIPS_CS_OS_NAME
6797 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
6798#endif
6799#ifdef _MIPS_CS_OS_PROVIDER
6800 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
6801#endif
6802#ifdef _MIPS_CS_PROCESSORS
6803 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
6804#endif
6805#ifdef _MIPS_CS_SERIAL
6806 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
6807#endif
6808#ifdef _MIPS_CS_VENDOR
6809 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
6810#endif
Fred Drakec9680921999-12-13 16:37:25 +00006811};
6812
6813static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006814conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006815{
6816 return conv_confname(arg, valuep, posix_constants_confstr,
6817 sizeof(posix_constants_confstr)
6818 / sizeof(struct constdef));
6819}
6820
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006821PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006822"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006823Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006824
6825static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006826posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006827{
6828 PyObject *result = NULL;
6829 int name;
Neal Norwitz449b24e2006-04-20 06:56:05 +00006830 char buffer[256];
Fred Drakec9680921999-12-13 16:37:25 +00006831
6832 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
Skip Montanarodd527fc2006-04-18 00:49:49 +00006833 int len;
Fred Drakec9680921999-12-13 16:37:25 +00006834
Fred Drakec9680921999-12-13 16:37:25 +00006835 errno = 0;
Skip Montanarodd527fc2006-04-18 00:49:49 +00006836 len = confstr(name, buffer, sizeof(buffer));
Skip Montanaro94785ef2006-04-20 01:29:48 +00006837 if (len == 0) {
6838 if (errno) {
6839 posix_error();
6840 }
6841 else {
6842 result = Py_None;
6843 Py_INCREF(Py_None);
6844 }
Fred Drakec9680921999-12-13 16:37:25 +00006845 }
6846 else {
Neal Norwitz0d21b1e2006-04-20 06:44:42 +00006847 if ((unsigned int)len >= sizeof(buffer)) {
Neal Norwitz449b24e2006-04-20 06:56:05 +00006848 result = PyString_FromStringAndSize(NULL, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00006849 if (result != NULL)
Neal Norwitz449b24e2006-04-20 06:56:05 +00006850 confstr(name, PyString_AS_STRING(result), len);
Fred Drakec9680921999-12-13 16:37:25 +00006851 }
6852 else
Neal Norwitz449b24e2006-04-20 06:56:05 +00006853 result = PyString_FromStringAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00006854 }
6855 }
6856 return result;
6857}
6858#endif
6859
6860
6861#ifdef HAVE_SYSCONF
6862static struct constdef posix_constants_sysconf[] = {
6863#ifdef _SC_2_CHAR_TERM
6864 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
6865#endif
6866#ifdef _SC_2_C_BIND
6867 {"SC_2_C_BIND", _SC_2_C_BIND},
6868#endif
6869#ifdef _SC_2_C_DEV
6870 {"SC_2_C_DEV", _SC_2_C_DEV},
6871#endif
6872#ifdef _SC_2_C_VERSION
6873 {"SC_2_C_VERSION", _SC_2_C_VERSION},
6874#endif
6875#ifdef _SC_2_FORT_DEV
6876 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
6877#endif
6878#ifdef _SC_2_FORT_RUN
6879 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
6880#endif
6881#ifdef _SC_2_LOCALEDEF
6882 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
6883#endif
6884#ifdef _SC_2_SW_DEV
6885 {"SC_2_SW_DEV", _SC_2_SW_DEV},
6886#endif
6887#ifdef _SC_2_UPE
6888 {"SC_2_UPE", _SC_2_UPE},
6889#endif
6890#ifdef _SC_2_VERSION
6891 {"SC_2_VERSION", _SC_2_VERSION},
6892#endif
Fred Draked86ed291999-12-15 15:34:33 +00006893#ifdef _SC_ABI_ASYNCHRONOUS_IO
6894 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
6895#endif
6896#ifdef _SC_ACL
6897 {"SC_ACL", _SC_ACL},
6898#endif
Fred Drakec9680921999-12-13 16:37:25 +00006899#ifdef _SC_AIO_LISTIO_MAX
6900 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
6901#endif
Fred Drakec9680921999-12-13 16:37:25 +00006902#ifdef _SC_AIO_MAX
6903 {"SC_AIO_MAX", _SC_AIO_MAX},
6904#endif
6905#ifdef _SC_AIO_PRIO_DELTA_MAX
6906 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
6907#endif
6908#ifdef _SC_ARG_MAX
6909 {"SC_ARG_MAX", _SC_ARG_MAX},
6910#endif
6911#ifdef _SC_ASYNCHRONOUS_IO
6912 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
6913#endif
6914#ifdef _SC_ATEXIT_MAX
6915 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
6916#endif
Fred Draked86ed291999-12-15 15:34:33 +00006917#ifdef _SC_AUDIT
6918 {"SC_AUDIT", _SC_AUDIT},
6919#endif
Fred Drakec9680921999-12-13 16:37:25 +00006920#ifdef _SC_AVPHYS_PAGES
6921 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
6922#endif
6923#ifdef _SC_BC_BASE_MAX
6924 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
6925#endif
6926#ifdef _SC_BC_DIM_MAX
6927 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
6928#endif
6929#ifdef _SC_BC_SCALE_MAX
6930 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
6931#endif
6932#ifdef _SC_BC_STRING_MAX
6933 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
6934#endif
Fred Draked86ed291999-12-15 15:34:33 +00006935#ifdef _SC_CAP
6936 {"SC_CAP", _SC_CAP},
6937#endif
Fred Drakec9680921999-12-13 16:37:25 +00006938#ifdef _SC_CHARCLASS_NAME_MAX
6939 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
6940#endif
6941#ifdef _SC_CHAR_BIT
6942 {"SC_CHAR_BIT", _SC_CHAR_BIT},
6943#endif
6944#ifdef _SC_CHAR_MAX
6945 {"SC_CHAR_MAX", _SC_CHAR_MAX},
6946#endif
6947#ifdef _SC_CHAR_MIN
6948 {"SC_CHAR_MIN", _SC_CHAR_MIN},
6949#endif
6950#ifdef _SC_CHILD_MAX
6951 {"SC_CHILD_MAX", _SC_CHILD_MAX},
6952#endif
6953#ifdef _SC_CLK_TCK
6954 {"SC_CLK_TCK", _SC_CLK_TCK},
6955#endif
6956#ifdef _SC_COHER_BLKSZ
6957 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
6958#endif
6959#ifdef _SC_COLL_WEIGHTS_MAX
6960 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
6961#endif
6962#ifdef _SC_DCACHE_ASSOC
6963 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
6964#endif
6965#ifdef _SC_DCACHE_BLKSZ
6966 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
6967#endif
6968#ifdef _SC_DCACHE_LINESZ
6969 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
6970#endif
6971#ifdef _SC_DCACHE_SZ
6972 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
6973#endif
6974#ifdef _SC_DCACHE_TBLKSZ
6975 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
6976#endif
6977#ifdef _SC_DELAYTIMER_MAX
6978 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
6979#endif
6980#ifdef _SC_EQUIV_CLASS_MAX
6981 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
6982#endif
6983#ifdef _SC_EXPR_NEST_MAX
6984 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
6985#endif
6986#ifdef _SC_FSYNC
6987 {"SC_FSYNC", _SC_FSYNC},
6988#endif
6989#ifdef _SC_GETGR_R_SIZE_MAX
6990 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
6991#endif
6992#ifdef _SC_GETPW_R_SIZE_MAX
6993 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
6994#endif
6995#ifdef _SC_ICACHE_ASSOC
6996 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
6997#endif
6998#ifdef _SC_ICACHE_BLKSZ
6999 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
7000#endif
7001#ifdef _SC_ICACHE_LINESZ
7002 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
7003#endif
7004#ifdef _SC_ICACHE_SZ
7005 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
7006#endif
Fred Draked86ed291999-12-15 15:34:33 +00007007#ifdef _SC_INF
7008 {"SC_INF", _SC_INF},
7009#endif
Fred Drakec9680921999-12-13 16:37:25 +00007010#ifdef _SC_INT_MAX
7011 {"SC_INT_MAX", _SC_INT_MAX},
7012#endif
7013#ifdef _SC_INT_MIN
7014 {"SC_INT_MIN", _SC_INT_MIN},
7015#endif
7016#ifdef _SC_IOV_MAX
7017 {"SC_IOV_MAX", _SC_IOV_MAX},
7018#endif
Fred Draked86ed291999-12-15 15:34:33 +00007019#ifdef _SC_IP_SECOPTS
7020 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
7021#endif
Fred Drakec9680921999-12-13 16:37:25 +00007022#ifdef _SC_JOB_CONTROL
7023 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
7024#endif
Fred Draked86ed291999-12-15 15:34:33 +00007025#ifdef _SC_KERN_POINTERS
7026 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
7027#endif
7028#ifdef _SC_KERN_SIM
7029 {"SC_KERN_SIM", _SC_KERN_SIM},
7030#endif
Fred Drakec9680921999-12-13 16:37:25 +00007031#ifdef _SC_LINE_MAX
7032 {"SC_LINE_MAX", _SC_LINE_MAX},
7033#endif
7034#ifdef _SC_LOGIN_NAME_MAX
7035 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
7036#endif
7037#ifdef _SC_LOGNAME_MAX
7038 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
7039#endif
7040#ifdef _SC_LONG_BIT
7041 {"SC_LONG_BIT", _SC_LONG_BIT},
7042#endif
Fred Draked86ed291999-12-15 15:34:33 +00007043#ifdef _SC_MAC
7044 {"SC_MAC", _SC_MAC},
7045#endif
Fred Drakec9680921999-12-13 16:37:25 +00007046#ifdef _SC_MAPPED_FILES
7047 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
7048#endif
7049#ifdef _SC_MAXPID
7050 {"SC_MAXPID", _SC_MAXPID},
7051#endif
7052#ifdef _SC_MB_LEN_MAX
7053 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
7054#endif
7055#ifdef _SC_MEMLOCK
7056 {"SC_MEMLOCK", _SC_MEMLOCK},
7057#endif
7058#ifdef _SC_MEMLOCK_RANGE
7059 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
7060#endif
7061#ifdef _SC_MEMORY_PROTECTION
7062 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
7063#endif
7064#ifdef _SC_MESSAGE_PASSING
7065 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
7066#endif
Fred Draked86ed291999-12-15 15:34:33 +00007067#ifdef _SC_MMAP_FIXED_ALIGNMENT
7068 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
7069#endif
Fred Drakec9680921999-12-13 16:37:25 +00007070#ifdef _SC_MQ_OPEN_MAX
7071 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
7072#endif
7073#ifdef _SC_MQ_PRIO_MAX
7074 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
7075#endif
Fred Draked86ed291999-12-15 15:34:33 +00007076#ifdef _SC_NACLS_MAX
7077 {"SC_NACLS_MAX", _SC_NACLS_MAX},
7078#endif
Fred Drakec9680921999-12-13 16:37:25 +00007079#ifdef _SC_NGROUPS_MAX
7080 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
7081#endif
7082#ifdef _SC_NL_ARGMAX
7083 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
7084#endif
7085#ifdef _SC_NL_LANGMAX
7086 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
7087#endif
7088#ifdef _SC_NL_MSGMAX
7089 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
7090#endif
7091#ifdef _SC_NL_NMAX
7092 {"SC_NL_NMAX", _SC_NL_NMAX},
7093#endif
7094#ifdef _SC_NL_SETMAX
7095 {"SC_NL_SETMAX", _SC_NL_SETMAX},
7096#endif
7097#ifdef _SC_NL_TEXTMAX
7098 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
7099#endif
7100#ifdef _SC_NPROCESSORS_CONF
7101 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
7102#endif
7103#ifdef _SC_NPROCESSORS_ONLN
7104 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
7105#endif
Fred Draked86ed291999-12-15 15:34:33 +00007106#ifdef _SC_NPROC_CONF
7107 {"SC_NPROC_CONF", _SC_NPROC_CONF},
7108#endif
7109#ifdef _SC_NPROC_ONLN
7110 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
7111#endif
Fred Drakec9680921999-12-13 16:37:25 +00007112#ifdef _SC_NZERO
7113 {"SC_NZERO", _SC_NZERO},
7114#endif
7115#ifdef _SC_OPEN_MAX
7116 {"SC_OPEN_MAX", _SC_OPEN_MAX},
7117#endif
7118#ifdef _SC_PAGESIZE
7119 {"SC_PAGESIZE", _SC_PAGESIZE},
7120#endif
7121#ifdef _SC_PAGE_SIZE
7122 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
7123#endif
7124#ifdef _SC_PASS_MAX
7125 {"SC_PASS_MAX", _SC_PASS_MAX},
7126#endif
7127#ifdef _SC_PHYS_PAGES
7128 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
7129#endif
7130#ifdef _SC_PII
7131 {"SC_PII", _SC_PII},
7132#endif
7133#ifdef _SC_PII_INTERNET
7134 {"SC_PII_INTERNET", _SC_PII_INTERNET},
7135#endif
7136#ifdef _SC_PII_INTERNET_DGRAM
7137 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
7138#endif
7139#ifdef _SC_PII_INTERNET_STREAM
7140 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
7141#endif
7142#ifdef _SC_PII_OSI
7143 {"SC_PII_OSI", _SC_PII_OSI},
7144#endif
7145#ifdef _SC_PII_OSI_CLTS
7146 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
7147#endif
7148#ifdef _SC_PII_OSI_COTS
7149 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
7150#endif
7151#ifdef _SC_PII_OSI_M
7152 {"SC_PII_OSI_M", _SC_PII_OSI_M},
7153#endif
7154#ifdef _SC_PII_SOCKET
7155 {"SC_PII_SOCKET", _SC_PII_SOCKET},
7156#endif
7157#ifdef _SC_PII_XTI
7158 {"SC_PII_XTI", _SC_PII_XTI},
7159#endif
7160#ifdef _SC_POLL
7161 {"SC_POLL", _SC_POLL},
7162#endif
7163#ifdef _SC_PRIORITIZED_IO
7164 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
7165#endif
7166#ifdef _SC_PRIORITY_SCHEDULING
7167 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
7168#endif
7169#ifdef _SC_REALTIME_SIGNALS
7170 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
7171#endif
7172#ifdef _SC_RE_DUP_MAX
7173 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
7174#endif
7175#ifdef _SC_RTSIG_MAX
7176 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
7177#endif
7178#ifdef _SC_SAVED_IDS
7179 {"SC_SAVED_IDS", _SC_SAVED_IDS},
7180#endif
7181#ifdef _SC_SCHAR_MAX
7182 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
7183#endif
7184#ifdef _SC_SCHAR_MIN
7185 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
7186#endif
7187#ifdef _SC_SELECT
7188 {"SC_SELECT", _SC_SELECT},
7189#endif
7190#ifdef _SC_SEMAPHORES
7191 {"SC_SEMAPHORES", _SC_SEMAPHORES},
7192#endif
7193#ifdef _SC_SEM_NSEMS_MAX
7194 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
7195#endif
7196#ifdef _SC_SEM_VALUE_MAX
7197 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
7198#endif
7199#ifdef _SC_SHARED_MEMORY_OBJECTS
7200 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
7201#endif
7202#ifdef _SC_SHRT_MAX
7203 {"SC_SHRT_MAX", _SC_SHRT_MAX},
7204#endif
7205#ifdef _SC_SHRT_MIN
7206 {"SC_SHRT_MIN", _SC_SHRT_MIN},
7207#endif
7208#ifdef _SC_SIGQUEUE_MAX
7209 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
7210#endif
7211#ifdef _SC_SIGRT_MAX
7212 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
7213#endif
7214#ifdef _SC_SIGRT_MIN
7215 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
7216#endif
Fred Draked86ed291999-12-15 15:34:33 +00007217#ifdef _SC_SOFTPOWER
7218 {"SC_SOFTPOWER", _SC_SOFTPOWER},
7219#endif
Fred Drakec9680921999-12-13 16:37:25 +00007220#ifdef _SC_SPLIT_CACHE
7221 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
7222#endif
7223#ifdef _SC_SSIZE_MAX
7224 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
7225#endif
7226#ifdef _SC_STACK_PROT
7227 {"SC_STACK_PROT", _SC_STACK_PROT},
7228#endif
7229#ifdef _SC_STREAM_MAX
7230 {"SC_STREAM_MAX", _SC_STREAM_MAX},
7231#endif
7232#ifdef _SC_SYNCHRONIZED_IO
7233 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
7234#endif
7235#ifdef _SC_THREADS
7236 {"SC_THREADS", _SC_THREADS},
7237#endif
7238#ifdef _SC_THREAD_ATTR_STACKADDR
7239 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
7240#endif
7241#ifdef _SC_THREAD_ATTR_STACKSIZE
7242 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
7243#endif
7244#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
7245 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
7246#endif
7247#ifdef _SC_THREAD_KEYS_MAX
7248 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
7249#endif
7250#ifdef _SC_THREAD_PRIORITY_SCHEDULING
7251 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
7252#endif
7253#ifdef _SC_THREAD_PRIO_INHERIT
7254 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
7255#endif
7256#ifdef _SC_THREAD_PRIO_PROTECT
7257 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
7258#endif
7259#ifdef _SC_THREAD_PROCESS_SHARED
7260 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
7261#endif
7262#ifdef _SC_THREAD_SAFE_FUNCTIONS
7263 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
7264#endif
7265#ifdef _SC_THREAD_STACK_MIN
7266 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
7267#endif
7268#ifdef _SC_THREAD_THREADS_MAX
7269 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
7270#endif
7271#ifdef _SC_TIMERS
7272 {"SC_TIMERS", _SC_TIMERS},
7273#endif
7274#ifdef _SC_TIMER_MAX
7275 {"SC_TIMER_MAX", _SC_TIMER_MAX},
7276#endif
7277#ifdef _SC_TTY_NAME_MAX
7278 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
7279#endif
7280#ifdef _SC_TZNAME_MAX
7281 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
7282#endif
7283#ifdef _SC_T_IOV_MAX
7284 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
7285#endif
7286#ifdef _SC_UCHAR_MAX
7287 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
7288#endif
7289#ifdef _SC_UINT_MAX
7290 {"SC_UINT_MAX", _SC_UINT_MAX},
7291#endif
7292#ifdef _SC_UIO_MAXIOV
7293 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
7294#endif
7295#ifdef _SC_ULONG_MAX
7296 {"SC_ULONG_MAX", _SC_ULONG_MAX},
7297#endif
7298#ifdef _SC_USHRT_MAX
7299 {"SC_USHRT_MAX", _SC_USHRT_MAX},
7300#endif
7301#ifdef _SC_VERSION
7302 {"SC_VERSION", _SC_VERSION},
7303#endif
7304#ifdef _SC_WORD_BIT
7305 {"SC_WORD_BIT", _SC_WORD_BIT},
7306#endif
7307#ifdef _SC_XBS5_ILP32_OFF32
7308 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
7309#endif
7310#ifdef _SC_XBS5_ILP32_OFFBIG
7311 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
7312#endif
7313#ifdef _SC_XBS5_LP64_OFF64
7314 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
7315#endif
7316#ifdef _SC_XBS5_LPBIG_OFFBIG
7317 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
7318#endif
7319#ifdef _SC_XOPEN_CRYPT
7320 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
7321#endif
7322#ifdef _SC_XOPEN_ENH_I18N
7323 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
7324#endif
7325#ifdef _SC_XOPEN_LEGACY
7326 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
7327#endif
7328#ifdef _SC_XOPEN_REALTIME
7329 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
7330#endif
7331#ifdef _SC_XOPEN_REALTIME_THREADS
7332 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
7333#endif
7334#ifdef _SC_XOPEN_SHM
7335 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
7336#endif
7337#ifdef _SC_XOPEN_UNIX
7338 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
7339#endif
7340#ifdef _SC_XOPEN_VERSION
7341 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
7342#endif
7343#ifdef _SC_XOPEN_XCU_VERSION
7344 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
7345#endif
7346#ifdef _SC_XOPEN_XPG2
7347 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
7348#endif
7349#ifdef _SC_XOPEN_XPG3
7350 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
7351#endif
7352#ifdef _SC_XOPEN_XPG4
7353 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
7354#endif
7355};
7356
7357static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007358conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007359{
7360 return conv_confname(arg, valuep, posix_constants_sysconf,
7361 sizeof(posix_constants_sysconf)
7362 / sizeof(struct constdef));
7363}
7364
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007365PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007366"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007367Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007368
7369static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007370posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007371{
7372 PyObject *result = NULL;
7373 int name;
7374
7375 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
7376 int value;
7377
7378 errno = 0;
7379 value = sysconf(name);
7380 if (value == -1 && errno != 0)
7381 posix_error();
7382 else
7383 result = PyInt_FromLong(value);
7384 }
7385 return result;
7386}
7387#endif
7388
7389
Fred Drakebec628d1999-12-15 18:31:10 +00007390/* This code is used to ensure that the tables of configuration value names
7391 * are in sorted order as required by conv_confname(), and also to build the
7392 * the exported dictionaries that are used to publish information about the
7393 * names available on the host platform.
7394 *
7395 * Sorting the table at runtime ensures that the table is properly ordered
7396 * when used, even for platforms we're not able to test on. It also makes
7397 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00007398 */
Fred Drakebec628d1999-12-15 18:31:10 +00007399
7400static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007401cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00007402{
7403 const struct constdef *c1 =
7404 (const struct constdef *) v1;
7405 const struct constdef *c2 =
7406 (const struct constdef *) v2;
7407
7408 return strcmp(c1->name, c2->name);
7409}
7410
7411static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007412setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00007413 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007414{
Fred Drakebec628d1999-12-15 18:31:10 +00007415 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00007416 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00007417
7418 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
7419 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00007420 if (d == NULL)
7421 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007422
Barry Warsaw3155db32000-04-13 15:20:40 +00007423 for (i=0; i < tablesize; ++i) {
7424 PyObject *o = PyInt_FromLong(table[i].value);
7425 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
7426 Py_XDECREF(o);
7427 Py_DECREF(d);
7428 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007429 }
Barry Warsaw3155db32000-04-13 15:20:40 +00007430 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00007431 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00007432 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00007433}
7434
Fred Drakebec628d1999-12-15 18:31:10 +00007435/* Return -1 on failure, 0 on success. */
7436static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007437setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007438{
7439#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00007440 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00007441 sizeof(posix_constants_pathconf)
7442 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007443 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007444 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007445#endif
7446#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00007447 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00007448 sizeof(posix_constants_confstr)
7449 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007450 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007451 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007452#endif
7453#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00007454 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00007455 sizeof(posix_constants_sysconf)
7456 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007457 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007458 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007459#endif
Fred Drakebec628d1999-12-15 18:31:10 +00007460 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00007461}
Fred Draked86ed291999-12-15 15:34:33 +00007462
7463
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007464PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007465"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007466Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007467in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007468
7469static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007470posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007471{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007472 abort();
7473 /*NOTREACHED*/
7474 Py_FatalError("abort() called from Python code didn't abort!");
7475 return NULL;
7476}
Fred Drakebec628d1999-12-15 18:31:10 +00007477
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007478#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007479PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00007480"startfile(filepath [, operation]) - Start a file with its associated\n\
7481application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007482\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00007483When \"operation\" is not specified or \"open\", this acts like\n\
7484double-clicking the file in Explorer, or giving the file name as an\n\
7485argument to the DOS \"start\" command: the file is opened with whatever\n\
7486application (if any) its extension is associated.\n\
7487When another \"operation\" is given, it specifies what should be done with\n\
7488the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007489\n\
7490startfile returns as soon as the associated application is launched.\n\
7491There is no option to wait for the application to close, and no way\n\
7492to retrieve the application's exit status.\n\
7493\n\
7494The filepath is relative to the current directory. If you want to use\n\
7495an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007496the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00007497
7498static PyObject *
7499win32_startfile(PyObject *self, PyObject *args)
7500{
7501 char *filepath;
Georg Brandlf4f44152006-02-18 22:29:33 +00007502 char *operation = NULL;
Tim Petersf58a7aa2000-09-22 10:05:54 +00007503 HINSTANCE rc;
Georg Brandlad89dc82006-04-03 12:26:26 +00007504#ifdef Py_WIN_WIDE_FILENAMES
7505 if (unicode_file_names()) {
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00007506 PyObject *unipath, *woperation = NULL;
Georg Brandlad89dc82006-04-03 12:26:26 +00007507 if (!PyArg_ParseTuple(args, "U|s:startfile",
7508 &unipath, &operation)) {
7509 PyErr_Clear();
7510 goto normal;
7511 }
7512
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00007513
7514 if (operation) {
7515 woperation = PyUnicode_DecodeASCII(operation,
7516 strlen(operation), NULL);
7517 if (!woperation) {
7518 PyErr_Clear();
7519 operation = NULL;
7520 goto normal;
7521 }
Georg Brandlad89dc82006-04-03 12:26:26 +00007522 }
7523
7524 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00007525 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
Georg Brandlad89dc82006-04-03 12:26:26 +00007526 PyUnicode_AS_UNICODE(unipath),
Georg Brandlad89dc82006-04-03 12:26:26 +00007527 NULL, NULL, SW_SHOWNORMAL);
7528 Py_END_ALLOW_THREADS
7529
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00007530 Py_XDECREF(woperation);
Georg Brandlad89dc82006-04-03 12:26:26 +00007531 if (rc <= (HINSTANCE)32) {
7532 PyObject *errval = win32_error_unicode("startfile",
7533 PyUnicode_AS_UNICODE(unipath));
7534 return errval;
7535 }
7536 Py_INCREF(Py_None);
7537 return Py_None;
7538 }
7539#endif
7540
7541normal:
Georg Brandlf4f44152006-02-18 22:29:33 +00007542 if (!PyArg_ParseTuple(args, "et|s:startfile",
7543 Py_FileSystemDefaultEncoding, &filepath,
7544 &operation))
Tim Petersf58a7aa2000-09-22 10:05:54 +00007545 return NULL;
7546 Py_BEGIN_ALLOW_THREADS
Georg Brandlf4f44152006-02-18 22:29:33 +00007547 rc = ShellExecute((HWND)0, operation, filepath,
7548 NULL, NULL, SW_SHOWNORMAL);
Tim Petersf58a7aa2000-09-22 10:05:54 +00007549 Py_END_ALLOW_THREADS
Georg Brandle9f8ec92005-09-25 06:16:40 +00007550 if (rc <= (HINSTANCE)32) {
7551 PyObject *errval = win32_error("startfile", filepath);
7552 PyMem_Free(filepath);
7553 return errval;
7554 }
7555 PyMem_Free(filepath);
Tim Petersf58a7aa2000-09-22 10:05:54 +00007556 Py_INCREF(Py_None);
7557 return Py_None;
7558}
7559#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007560
Martin v. Löwis438b5342002-12-27 10:16:42 +00007561#ifdef HAVE_GETLOADAVG
7562PyDoc_STRVAR(posix_getloadavg__doc__,
7563"getloadavg() -> (float, float, float)\n\n\
7564Return the number of processes in the system run queue averaged over\n\
7565the last 1, 5, and 15 minutes or raises OSError if the load average\n\
7566was unobtainable");
7567
7568static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007569posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00007570{
7571 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00007572 if (getloadavg(loadavg, 3)!=3) {
7573 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
7574 return NULL;
7575 } else
7576 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
7577}
7578#endif
7579
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007580#ifdef MS_WINDOWS
7581
7582PyDoc_STRVAR(win32_urandom__doc__,
7583"urandom(n) -> str\n\n\
7584Return a string of n random bytes suitable for cryptographic use.");
7585
7586typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
7587 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
7588 DWORD dwFlags );
7589typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
7590 BYTE *pbBuffer );
7591
7592static CRYPTGENRANDOM pCryptGenRandom = NULL;
7593static HCRYPTPROV hCryptProv = 0;
7594
Tim Peters4ad82172004-08-30 17:02:04 +00007595static PyObject*
7596win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007597{
Tim Petersd3115382004-08-30 17:36:46 +00007598 int howMany;
7599 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007600
Tim Peters4ad82172004-08-30 17:02:04 +00007601 /* Read arguments */
Tim Peters9b279a82004-08-30 17:10:53 +00007602 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
Tim Peters4ad82172004-08-30 17:02:04 +00007603 return NULL;
Tim Peters51eba612004-08-30 17:08:02 +00007604 if (howMany < 0)
7605 return PyErr_Format(PyExc_ValueError,
7606 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007607
Tim Peters4ad82172004-08-30 17:02:04 +00007608 if (hCryptProv == 0) {
7609 HINSTANCE hAdvAPI32 = NULL;
7610 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007611
Tim Peters4ad82172004-08-30 17:02:04 +00007612 /* Obtain handle to the DLL containing CryptoAPI
7613 This should not fail */
7614 hAdvAPI32 = GetModuleHandle("advapi32.dll");
7615 if(hAdvAPI32 == NULL)
7616 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007617
Tim Peters4ad82172004-08-30 17:02:04 +00007618 /* Obtain pointers to the CryptoAPI functions
7619 This will fail on some early versions of Win95 */
7620 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
7621 hAdvAPI32,
7622 "CryptAcquireContextA");
7623 if (pCryptAcquireContext == NULL)
7624 return PyErr_Format(PyExc_NotImplementedError,
7625 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007626
Tim Peters4ad82172004-08-30 17:02:04 +00007627 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
7628 hAdvAPI32, "CryptGenRandom");
7629 if (pCryptAcquireContext == NULL)
7630 return PyErr_Format(PyExc_NotImplementedError,
7631 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007632
Tim Peters4ad82172004-08-30 17:02:04 +00007633 /* Acquire context */
7634 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
7635 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
7636 return win32_error("CryptAcquireContext", NULL);
7637 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007638
Tim Peters4ad82172004-08-30 17:02:04 +00007639 /* Allocate bytes */
Tim Petersd3115382004-08-30 17:36:46 +00007640 result = PyString_FromStringAndSize(NULL, howMany);
7641 if (result != NULL) {
7642 /* Get random data */
7643 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
7644 PyString_AS_STRING(result))) {
7645 Py_DECREF(result);
7646 return win32_error("CryptGenRandom", NULL);
7647 }
Tim Peters4ad82172004-08-30 17:02:04 +00007648 }
Tim Petersd3115382004-08-30 17:36:46 +00007649 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007650}
7651#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007652
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007653static PyMethodDef posix_methods[] = {
7654 {"access", posix_access, METH_VARARGS, posix_access__doc__},
7655#ifdef HAVE_TTYNAME
7656 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
7657#endif
7658 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
7659 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007660#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007661 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007662#endif /* HAVE_CHOWN */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007663#ifdef HAVE_LCHOWN
7664 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
7665#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00007666#ifdef HAVE_CHROOT
7667 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
7668#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007669#ifdef HAVE_CTERMID
Neal Norwitze241ce82003-02-17 18:17:05 +00007670 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007671#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00007672#ifdef HAVE_GETCWD
Neal Norwitze241ce82003-02-17 18:17:05 +00007673 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Walter Dörwald3b918c32002-11-21 20:18:46 +00007674#ifdef Py_USING_UNICODE
Neal Norwitze241ce82003-02-17 18:17:05 +00007675 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00007676#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00007677#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007678#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007679 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007680#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007681 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
7682 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
7683 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007684#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007685 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007686#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007687#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007688 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007689#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007690 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
7691 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
7692 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007693 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007694#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007695 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007696#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007697#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007698 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007699#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007700 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007701#ifdef HAVE_UNAME
Neal Norwitze241ce82003-02-17 18:17:05 +00007702 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007703#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007704 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
7705 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
7706 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007707#ifdef HAVE_TIMES
Neal Norwitze241ce82003-02-17 18:17:05 +00007708 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007709#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007710 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007711#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007712 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
7713 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007714#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00007715#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007716 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
7717 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00007718#if defined(PYOS_OS2)
7719 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
7720 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
7721#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00007722#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007723#ifdef HAVE_FORK1
Neal Norwitze241ce82003-02-17 18:17:05 +00007724 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007725#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007726#ifdef HAVE_FORK
Neal Norwitze241ce82003-02-17 18:17:05 +00007727 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007728#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007729#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Neal Norwitze241ce82003-02-17 18:17:05 +00007730 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007731#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007732#ifdef HAVE_FORKPTY
Neal Norwitze241ce82003-02-17 18:17:05 +00007733 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00007734#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007735#ifdef HAVE_GETEGID
Neal Norwitze241ce82003-02-17 18:17:05 +00007736 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007737#endif /* HAVE_GETEGID */
7738#ifdef HAVE_GETEUID
Neal Norwitze241ce82003-02-17 18:17:05 +00007739 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007740#endif /* HAVE_GETEUID */
7741#ifdef HAVE_GETGID
Neal Norwitze241ce82003-02-17 18:17:05 +00007742 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007743#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00007744#ifdef HAVE_GETGROUPS
Neal Norwitze241ce82003-02-17 18:17:05 +00007745 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007746#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007747 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007748#ifdef HAVE_GETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00007749 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007750#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007751#ifdef HAVE_GETPPID
Neal Norwitze241ce82003-02-17 18:17:05 +00007752 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007753#endif /* HAVE_GETPPID */
7754#ifdef HAVE_GETUID
Neal Norwitze241ce82003-02-17 18:17:05 +00007755 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007756#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007757#ifdef HAVE_GETLOGIN
Neal Norwitze241ce82003-02-17 18:17:05 +00007758 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00007759#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00007760#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007761 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007762#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007763#ifdef HAVE_KILLPG
7764 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
7765#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00007766#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007767 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00007768#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007769#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007770 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007771#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00007772 {"popen2", win32_popen2, METH_VARARGS},
7773 {"popen3", win32_popen3, METH_VARARGS},
7774 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00007775 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007776#else
7777#if defined(PYOS_OS2) && defined(PYCC_GCC)
7778 {"popen2", os2emx_popen2, METH_VARARGS},
7779 {"popen3", os2emx_popen3, METH_VARARGS},
7780 {"popen4", os2emx_popen4, METH_VARARGS},
7781#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00007782#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007783#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007784#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007785 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007786#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007787#ifdef HAVE_SETEUID
7788 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
7789#endif /* HAVE_SETEUID */
7790#ifdef HAVE_SETEGID
7791 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
7792#endif /* HAVE_SETEGID */
7793#ifdef HAVE_SETREUID
7794 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
7795#endif /* HAVE_SETREUID */
7796#ifdef HAVE_SETREGID
7797 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
7798#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007799#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007800 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007801#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007802#ifdef HAVE_SETGROUPS
7803 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
7804#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00007805#ifdef HAVE_GETPGID
7806 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
7807#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007808#ifdef HAVE_SETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00007809 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007810#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007811#ifdef HAVE_WAIT
Neal Norwitze241ce82003-02-17 18:17:05 +00007812 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007813#endif /* HAVE_WAIT */
Neal Norwitz05a45592006-03-20 06:30:08 +00007814#ifdef HAVE_WAIT3
7815 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
7816#endif /* HAVE_WAIT3 */
7817#ifdef HAVE_WAIT4
7818 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
7819#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00007820#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007821 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007822#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007823#ifdef HAVE_GETSID
7824 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
7825#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007826#ifdef HAVE_SETSID
Neal Norwitze241ce82003-02-17 18:17:05 +00007827 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007828#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007829#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007830 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007831#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007832#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007833 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007834#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007835#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007836 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007837#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007838 {"open", posix_open, METH_VARARGS, posix_open__doc__},
7839 {"close", posix_close, METH_VARARGS, posix_close__doc__},
7840 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
7841 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
7842 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
7843 {"read", posix_read, METH_VARARGS, posix_read__doc__},
7844 {"write", posix_write, METH_VARARGS, posix_write__doc__},
7845 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
7846 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00007847 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007848#ifdef HAVE_PIPE
Neal Norwitze241ce82003-02-17 18:17:05 +00007849 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007850#endif
7851#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007852 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007853#endif
Neal Norwitz11690112002-07-30 01:08:28 +00007854#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007855 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
7856#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007857#ifdef HAVE_DEVICE_MACROS
7858 {"major", posix_major, METH_VARARGS, posix_major__doc__},
7859 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
7860 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
7861#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007862#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007863 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007864#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007865#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007866 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007867#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007868#ifdef HAVE_UNSETENV
7869 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
7870#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00007871#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007872 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00007873#endif
Fred Drake4d1e64b2002-04-15 19:40:07 +00007874#ifdef HAVE_FCHDIR
7875 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
7876#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00007877#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007878 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007879#endif
7880#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007881 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007882#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00007883#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00007884#ifdef WCOREDUMP
7885 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
7886#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007887#ifdef WIFCONTINUED
7888 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
7889#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00007890#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007891 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007892#endif /* WIFSTOPPED */
7893#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007894 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007895#endif /* WIFSIGNALED */
7896#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007897 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007898#endif /* WIFEXITED */
7899#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007900 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007901#endif /* WEXITSTATUS */
7902#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007903 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007904#endif /* WTERMSIG */
7905#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007906 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007907#endif /* WSTOPSIG */
7908#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007909#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007910 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007911#endif
7912#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007913 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007914#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00007915#ifdef HAVE_TMPFILE
Neal Norwitze241ce82003-02-17 18:17:05 +00007916 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007917#endif
7918#ifdef HAVE_TEMPNAM
7919 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
7920#endif
7921#ifdef HAVE_TMPNAM
Neal Norwitze241ce82003-02-17 18:17:05 +00007922 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007923#endif
Fred Drakec9680921999-12-13 16:37:25 +00007924#ifdef HAVE_CONFSTR
7925 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
7926#endif
7927#ifdef HAVE_SYSCONF
7928 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
7929#endif
7930#ifdef HAVE_FPATHCONF
7931 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
7932#endif
7933#ifdef HAVE_PATHCONF
7934 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
7935#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007936 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007937#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00007938 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
7939#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007940#ifdef HAVE_GETLOADAVG
Neal Norwitze241ce82003-02-17 18:17:05 +00007941 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00007942#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007943 #ifdef MS_WINDOWS
7944 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
7945 #endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007946 {NULL, NULL} /* Sentinel */
7947};
7948
7949
Barry Warsaw4a342091996-12-19 23:50:02 +00007950static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007951ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00007952{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007953 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00007954}
7955
Guido van Rossumd48f2521997-12-05 22:19:34 +00007956#if defined(PYOS_OS2)
7957/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007958static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007959{
7960 APIRET rc;
7961 ULONG values[QSV_MAX+1];
7962 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00007963 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00007964
7965 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00007966 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007967 Py_END_ALLOW_THREADS
7968
7969 if (rc != NO_ERROR) {
7970 os2_error(rc);
7971 return -1;
7972 }
7973
Fred Drake4d1e64b2002-04-15 19:40:07 +00007974 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
7975 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
7976 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
7977 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
7978 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
7979 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
7980 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007981
7982 switch (values[QSV_VERSION_MINOR]) {
7983 case 0: ver = "2.00"; break;
7984 case 10: ver = "2.10"; break;
7985 case 11: ver = "2.11"; break;
7986 case 30: ver = "3.00"; break;
7987 case 40: ver = "4.00"; break;
7988 case 50: ver = "5.00"; break;
7989 default:
Tim Peters885d4572001-11-28 20:27:42 +00007990 PyOS_snprintf(tmp, sizeof(tmp),
7991 "%d-%d", values[QSV_VERSION_MAJOR],
7992 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007993 ver = &tmp[0];
7994 }
7995
7996 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007997 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007998 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007999
8000 /* Add Indicator of Which Drive was Used to Boot the System */
8001 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
8002 tmp[1] = ':';
8003 tmp[2] = '\0';
8004
Fred Drake4d1e64b2002-04-15 19:40:07 +00008005 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008006}
8007#endif
8008
Barry Warsaw4a342091996-12-19 23:50:02 +00008009static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008010all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00008011{
Guido van Rossum94f6f721999-01-06 18:42:14 +00008012#ifdef F_OK
8013 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008014#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008015#ifdef R_OK
8016 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008017#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008018#ifdef W_OK
8019 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008020#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008021#ifdef X_OK
8022 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008023#endif
Fred Drakec9680921999-12-13 16:37:25 +00008024#ifdef NGROUPS_MAX
8025 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
8026#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008027#ifdef TMP_MAX
8028 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
8029#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008030#ifdef WCONTINUED
8031 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
8032#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008033#ifdef WNOHANG
8034 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008035#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008036#ifdef WUNTRACED
8037 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
8038#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008039#ifdef O_RDONLY
8040 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
8041#endif
8042#ifdef O_WRONLY
8043 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
8044#endif
8045#ifdef O_RDWR
8046 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
8047#endif
8048#ifdef O_NDELAY
8049 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
8050#endif
8051#ifdef O_NONBLOCK
8052 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
8053#endif
8054#ifdef O_APPEND
8055 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
8056#endif
8057#ifdef O_DSYNC
8058 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
8059#endif
8060#ifdef O_RSYNC
8061 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
8062#endif
8063#ifdef O_SYNC
8064 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
8065#endif
8066#ifdef O_NOCTTY
8067 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
8068#endif
8069#ifdef O_CREAT
8070 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
8071#endif
8072#ifdef O_EXCL
8073 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
8074#endif
8075#ifdef O_TRUNC
8076 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
8077#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00008078#ifdef O_BINARY
8079 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
8080#endif
8081#ifdef O_TEXT
8082 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
8083#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008084#ifdef O_LARGEFILE
8085 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
8086#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00008087#ifdef O_SHLOCK
8088 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
8089#endif
8090#ifdef O_EXLOCK
8091 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
8092#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008093
Tim Peters5aa91602002-01-30 05:46:57 +00008094/* MS Windows */
8095#ifdef O_NOINHERIT
8096 /* Don't inherit in child processes. */
8097 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
8098#endif
8099#ifdef _O_SHORT_LIVED
8100 /* Optimize for short life (keep in memory). */
8101 /* MS forgot to define this one with a non-underscore form too. */
8102 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
8103#endif
8104#ifdef O_TEMPORARY
8105 /* Automatically delete when last handle is closed. */
8106 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
8107#endif
8108#ifdef O_RANDOM
8109 /* Optimize for random access. */
8110 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
8111#endif
8112#ifdef O_SEQUENTIAL
8113 /* Optimize for sequential access. */
8114 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
8115#endif
8116
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008117/* GNU extensions. */
8118#ifdef O_DIRECT
8119 /* Direct disk access. */
8120 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
8121#endif
8122#ifdef O_DIRECTORY
8123 /* Must be a directory. */
8124 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
8125#endif
8126#ifdef O_NOFOLLOW
8127 /* Do not follow links. */
8128 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
8129#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00008130
Barry Warsaw5676bd12003-01-07 20:57:09 +00008131 /* These come from sysexits.h */
8132#ifdef EX_OK
8133 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008134#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008135#ifdef EX_USAGE
8136 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008137#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008138#ifdef EX_DATAERR
8139 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008140#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008141#ifdef EX_NOINPUT
8142 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008143#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008144#ifdef EX_NOUSER
8145 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008146#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008147#ifdef EX_NOHOST
8148 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008149#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008150#ifdef EX_UNAVAILABLE
8151 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008152#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008153#ifdef EX_SOFTWARE
8154 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008155#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008156#ifdef EX_OSERR
8157 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008158#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008159#ifdef EX_OSFILE
8160 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008161#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008162#ifdef EX_CANTCREAT
8163 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008164#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008165#ifdef EX_IOERR
8166 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008167#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008168#ifdef EX_TEMPFAIL
8169 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008170#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008171#ifdef EX_PROTOCOL
8172 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008173#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008174#ifdef EX_NOPERM
8175 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008176#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008177#ifdef EX_CONFIG
8178 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008179#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008180#ifdef EX_NOTFOUND
8181 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008182#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008183
Guido van Rossum246bc171999-02-01 23:54:31 +00008184#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008185#if defined(PYOS_OS2) && defined(PYCC_GCC)
8186 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
8187 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
8188 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
8189 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
8190 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
8191 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
8192 if (ins(d, "P_PM", (long)P_PM)) return -1;
8193 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
8194 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
8195 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
8196 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
8197 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
8198 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
8199 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
8200 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
8201 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
8202 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
8203 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
8204 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
8205 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
8206#else
Guido van Rossum7d385291999-02-16 19:38:04 +00008207 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
8208 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
8209 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
8210 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
8211 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00008212#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008213#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00008214
Guido van Rossumd48f2521997-12-05 22:19:34 +00008215#if defined(PYOS_OS2)
8216 if (insertvalues(d)) return -1;
8217#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008218 return 0;
8219}
8220
8221
Tim Peters5aa91602002-01-30 05:46:57 +00008222#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008223#define INITFUNC initnt
8224#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008225
8226#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008227#define INITFUNC initos2
8228#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008229
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008230#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008231#define INITFUNC initposix
8232#define MODNAME "posix"
8233#endif
8234
Mark Hammondfe51c6d2002-08-02 02:27:13 +00008235PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008236INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00008237{
Fred Drake4d1e64b2002-04-15 19:40:07 +00008238 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00008239
Fred Drake4d1e64b2002-04-15 19:40:07 +00008240 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008241 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00008242 posix__doc__);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00008243 if (m == NULL)
8244 return;
Tim Peters5aa91602002-01-30 05:46:57 +00008245
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008246 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008247 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00008248 Py_XINCREF(v);
8249 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008250 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00008251 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00008252
Fred Drake4d1e64b2002-04-15 19:40:07 +00008253 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00008254 return;
8255
Fred Drake4d1e64b2002-04-15 19:40:07 +00008256 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00008257 return;
8258
Fred Drake4d1e64b2002-04-15 19:40:07 +00008259 Py_INCREF(PyExc_OSError);
8260 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00008261
Guido van Rossumb3d39562000-01-31 18:41:26 +00008262#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00008263 if (posix_putenv_garbage == NULL)
8264 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00008265#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008266
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00008267 if (!initialized) {
8268 stat_result_desc.name = MODNAME ".stat_result";
8269 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
8270 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
8271 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
8272 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
8273 structseq_new = StatResultType.tp_new;
8274 StatResultType.tp_new = statresult_new;
8275
8276 statvfs_result_desc.name = MODNAME ".statvfs_result";
8277 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
8278 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00008279 Py_INCREF((PyObject*) &StatResultType);
8280 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Fred Drake4d1e64b2002-04-15 19:40:07 +00008281 Py_INCREF((PyObject*) &StatVFSResultType);
8282 PyModule_AddObject(m, "statvfs_result",
8283 (PyObject*) &StatVFSResultType);
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00008284 initialized = 1;
Ronald Oussorend06b6f22006-04-23 11:59:25 +00008285
8286#ifdef __APPLE__
8287 /*
8288 * Step 2 of weak-linking support on Mac OS X.
8289 *
8290 * The code below removes functions that are not available on the
8291 * currently active platform.
8292 *
8293 * This block allow one to use a python binary that was build on
8294 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
8295 * OSX 10.4.
8296 */
8297#ifdef HAVE_FSTATVFS
8298 if (fstatvfs == NULL) {
8299 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
8300 return;
8301 }
8302 }
8303#endif /* HAVE_FSTATVFS */
8304
8305#ifdef HAVE_STATVFS
8306 if (statvfs == NULL) {
8307 if (PyObject_DelAttrString(m, "statvfs") == -1) {
8308 return;
8309 }
8310 }
8311#endif /* HAVE_STATVFS */
8312
8313# ifdef HAVE_LCHOWN
8314 if (lchown == NULL) {
8315 if (PyObject_DelAttrString(m, "lchown") == -1) {
8316 return;
8317 }
8318 }
8319#endif /* HAVE_LCHOWN */
8320
8321
8322#endif /* __APPLE__ */
8323
Guido van Rossumb6775db1994-08-01 11:34:53 +00008324}
Anthony Baxterac6bd462006-04-13 02:06:09 +00008325
8326#ifdef __cplusplus
8327}
8328#endif
8329