blob: bb4c6ed6a4477859e236309369b085ebbaac1929 [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{
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000461}
462
463/* Function suitable for O& conversion */
464static int
465convert_to_unicode(PyObject *arg, void* _param)
466{
467 PyObject **param = (PyObject**)_param;
468 if (PyUnicode_CheckExact(arg)) {
469 Py_INCREF(arg);
470 *param = arg;
471 }
472 else if (PyUnicode_Check(arg)) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000473 /* For a Unicode subtype that's not a Unicode object,
474 return a true Unicode object with the same data. */
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000475 *param = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(arg),
476 PyUnicode_GET_SIZE(arg));
477 return *param != NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000478 }
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000479 else
480 *param = PyUnicode_FromEncodedObject(arg,
481 Py_FileSystemDefaultEncoding,
482 "strict");
483 return (*param) != NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000484}
485
486#endif /* Py_WIN_WIDE_FILENAMES */
487
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000488#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000489
Guido van Rossumd48f2521997-12-05 22:19:34 +0000490#if defined(PYOS_OS2)
491/**********************************************************************
492 * Helper Function to Trim and Format OS/2 Messages
493 **********************************************************************/
494 static void
495os2_formatmsg(char *msgbuf, int msglen, char *reason)
496{
497 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
498
499 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
500 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
501
Neal Norwitz30b5c5d2005-12-19 06:05:18 +0000502 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
Guido van Rossumd48f2521997-12-05 22:19:34 +0000503 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
504 }
505
506 /* Add Optional Reason Text */
507 if (reason) {
508 strcat(msgbuf, " : ");
509 strcat(msgbuf, reason);
510 }
511}
512
513/**********************************************************************
514 * Decode an OS/2 Operating System Error Code
515 *
516 * A convenience function to lookup an OS/2 error code and return a
517 * text message we can use to raise a Python exception.
518 *
519 * Notes:
520 * The messages for errors returned from the OS/2 kernel reside in
521 * the file OSO001.MSG in the \OS2 directory hierarchy.
522 *
523 **********************************************************************/
524 static char *
525os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
526{
527 APIRET rc;
528 ULONG msglen;
529
530 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
531 Py_BEGIN_ALLOW_THREADS
532 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
533 errorcode, "oso001.msg", &msglen);
534 Py_END_ALLOW_THREADS
535
536 if (rc == NO_ERROR)
537 os2_formatmsg(msgbuf, msglen, reason);
538 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000539 PyOS_snprintf(msgbuf, msgbuflen,
Tim Peters885d4572001-11-28 20:27:42 +0000540 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000541
542 return msgbuf;
543}
544
545/* Set an OS/2-specific error and return NULL. OS/2 kernel
546 errors are not in a global variable e.g. 'errno' nor are
547 they congruent with posix error numbers. */
548
549static PyObject * os2_error(int code)
550{
551 char text[1024];
552 PyObject *v;
553
554 os2_strerror(text, sizeof(text), code, "");
555
556 v = Py_BuildValue("(is)", code, text);
557 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000558 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000559 Py_DECREF(v);
560 }
561 return NULL; /* Signal to Python that an Exception is Pending */
562}
563
564#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000565
566/* POSIX generic methods */
567
Barry Warsaw53699e91996-12-10 23:23:01 +0000568static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000569posix_fildes(PyObject *fdobj, int (*func)(int))
570{
571 int fd;
572 int res;
573 fd = PyObject_AsFileDescriptor(fdobj);
574 if (fd < 0)
575 return NULL;
576 Py_BEGIN_ALLOW_THREADS
577 res = (*func)(fd);
578 Py_END_ALLOW_THREADS
579 if (res < 0)
580 return posix_error();
581 Py_INCREF(Py_None);
582 return Py_None;
583}
Guido van Rossum21142a01999-01-08 21:05:37 +0000584
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000585#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters11b23062003-04-23 02:39:17 +0000586static int
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000587unicode_file_names(void)
588{
589 static int canusewide = -1;
590 if (canusewide == -1) {
Tim Peters11b23062003-04-23 02:39:17 +0000591 /* As per doc for ::GetVersion(), this is the correct test for
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000592 the Windows NT family. */
593 canusewide = (GetVersion() < 0x80000000) ? 1 : 0;
594 }
595 return canusewide;
596}
597#endif
Tim Peters11b23062003-04-23 02:39:17 +0000598
Guido van Rossum21142a01999-01-08 21:05:37 +0000599static PyObject *
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000600posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000601{
Mark Hammondef8b6542001-05-13 08:04:26 +0000602 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000603 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000604 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000605 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000606 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000607 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000608 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000609 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000610 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000611 return posix_error_with_allocated_filename(path1);
612 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000613 Py_INCREF(Py_None);
614 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000615}
616
Barry Warsaw53699e91996-12-10 23:23:01 +0000617static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000618posix_2str(PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000619 char *format,
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000620 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000621{
Mark Hammondef8b6542001-05-13 08:04:26 +0000622 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000623 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000624 if (!PyArg_ParseTuple(args, format,
Tim Peters5aa91602002-01-30 05:46:57 +0000625 Py_FileSystemDefaultEncoding, &path1,
Mark Hammondef8b6542001-05-13 08:04:26 +0000626 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000627 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000628 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000629 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000630 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000631 PyMem_Free(path1);
632 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000633 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000634 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000635 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000636 Py_INCREF(Py_None);
637 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000638}
639
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000640#ifdef Py_WIN_WIDE_FILENAMES
641static PyObject*
642win32_1str(PyObject* args, char* func,
643 char* format, BOOL (__stdcall *funcA)(LPCSTR),
644 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
645{
646 PyObject *uni;
647 char *ansi;
648 BOOL result;
649 if (unicode_file_names()) {
650 if (!PyArg_ParseTuple(args, wformat, &uni))
651 PyErr_Clear();
652 else {
653 Py_BEGIN_ALLOW_THREADS
654 result = funcW(PyUnicode_AsUnicode(uni));
655 Py_END_ALLOW_THREADS
656 if (!result)
657 return win32_error_unicode(func, PyUnicode_AsUnicode(uni));
658 Py_INCREF(Py_None);
659 return Py_None;
660 }
661 }
662 if (!PyArg_ParseTuple(args, format, &ansi))
663 return NULL;
664 Py_BEGIN_ALLOW_THREADS
665 result = funcA(ansi);
666 Py_END_ALLOW_THREADS
667 if (!result)
668 return win32_error(func, ansi);
669 Py_INCREF(Py_None);
670 return Py_None;
671
672}
673
674/* This is a reimplementation of the C library's chdir function,
675 but one that produces Win32 errors instead of DOS error codes.
676 chdir is essentially a wrapper around SetCurrentDirectory; however,
677 it also needs to set "magic" environment variables indicating
678 the per-drive current directory, which are of the form =<drive>: */
679BOOL __stdcall
680win32_chdir(LPCSTR path)
681{
682 char new_path[MAX_PATH+1];
683 int result;
684 char env[4] = "=x:";
685
686 if(!SetCurrentDirectoryA(path))
687 return FALSE;
688 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
689 if (!result)
690 return FALSE;
691 /* In the ANSI API, there should not be any paths longer
692 than MAX_PATH. */
693 assert(result <= MAX_PATH+1);
694 if (strncmp(new_path, "\\\\", 2) == 0 ||
695 strncmp(new_path, "//", 2) == 0)
696 /* UNC path, nothing to do. */
697 return TRUE;
698 env[1] = new_path[0];
699 return SetEnvironmentVariableA(env, new_path);
700}
701
702/* The Unicode version differs from the ANSI version
703 since the current directory might exceed MAX_PATH characters */
704BOOL __stdcall
705win32_wchdir(LPCWSTR path)
706{
707 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
708 int result;
709 wchar_t env[4] = L"=x:";
710
711 if(!SetCurrentDirectoryW(path))
712 return FALSE;
713 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
714 if (!result)
715 return FALSE;
716 if (result > MAX_PATH+1) {
717 new_path = malloc(result);
718 if (!new_path) {
719 SetLastError(ERROR_OUTOFMEMORY);
720 return FALSE;
721 }
722 }
723 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
724 wcsncmp(new_path, L"//", 2) == 0)
725 /* UNC path, nothing to do. */
726 return TRUE;
727 env[1] = new_path[0];
728 result = SetEnvironmentVariableW(env, new_path);
729 if (new_path != _new_path)
730 free(new_path);
731 return result;
732}
733#endif
734
Martin v. Löwis14694662006-02-03 12:54:16 +0000735#ifdef MS_WINDOWS
736/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
737 - time stamps are restricted to second resolution
738 - file modification times suffer from forth-and-back conversions between
739 UTC and local time
740 Therefore, we implement our own stat, based on the Win32 API directly.
741*/
742#define HAVE_STAT_NSEC 1
743
744struct win32_stat{
745 int st_dev;
746 __int64 st_ino;
747 unsigned short st_mode;
748 int st_nlink;
749 int st_uid;
750 int st_gid;
751 int st_rdev;
752 __int64 st_size;
753 int st_atime;
754 int st_atime_nsec;
755 int st_mtime;
756 int st_mtime_nsec;
757 int st_ctime;
758 int st_ctime_nsec;
759};
760
761static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
762
763static void
764FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, int *time_out, int* nsec_out)
765{
766 /* XXX endianness */
767 __int64 in = *(__int64*)in_ptr;
768 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
769 /* XXX Win32 supports time stamps past 2038; we currently don't */
770 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, int);
771}
772
773/* Below, we *know* that ugo+r is 0444 */
774#if _S_IREAD != 0400
775#error Unsupported C library
776#endif
777static int
778attributes_to_mode(DWORD attr)
779{
780 int m = 0;
781 if (attr & FILE_ATTRIBUTE_DIRECTORY)
782 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
783 else
784 m |= _S_IFREG;
785 if (attr & FILE_ATTRIBUTE_READONLY)
786 m |= 0444;
787 else
788 m |= 0666;
789 return m;
790}
791
792static int
793attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *result)
794{
795 memset(result, 0, sizeof(*result));
796 result->st_mode = attributes_to_mode(info->dwFileAttributes);
797 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
798 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
799 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
800 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
801
802 return 0;
803}
804
805static int
806win32_stat(const char* path, struct win32_stat *result)
807{
808 WIN32_FILE_ATTRIBUTE_DATA info;
809 int code;
810 char *dot;
811 /* XXX not supported on Win95 and NT 3.x */
812 if (!GetFileAttributesExA(path, GetFileExInfoStandard, &info)) {
813 /* Protocol violation: we explicitly clear errno, instead of
814 setting it to a POSIX error. Callers should use GetLastError. */
815 errno = 0;
816 return -1;
817 }
818 code = attribute_data_to_stat(&info, result);
819 if (code != 0)
820 return code;
821 /* Set S_IFEXEC if it is an .exe, .bat, ... */
822 dot = strrchr(path, '.');
823 if (dot) {
824 if (stricmp(dot, ".bat") == 0 ||
825 stricmp(dot, ".cmd") == 0 ||
826 stricmp(dot, ".exe") == 0 ||
827 stricmp(dot, ".com") == 0)
828 result->st_mode |= 0111;
829 }
830 return code;
831}
832
833static int
834win32_wstat(const wchar_t* path, struct win32_stat *result)
835{
836 int code;
837 const wchar_t *dot;
838 WIN32_FILE_ATTRIBUTE_DATA info;
839 /* XXX not supported on Win95 and NT 3.x */
840 if (!GetFileAttributesExW(path, GetFileExInfoStandard, &info)) {
841 /* Protocol violation: we explicitly clear errno, instead of
842 setting it to a POSIX error. Callers should use GetLastError. */
843 errno = 0;
844 return -1;
845 }
846 code = attribute_data_to_stat(&info, result);
847 if (code < 0)
848 return code;
849 /* Set IFEXEC if it is an .exe, .bat, ... */
850 dot = wcsrchr(path, '.');
851 if (dot) {
852 if (_wcsicmp(dot, L".bat") == 0 ||
853 _wcsicmp(dot, L".cmd") == 0 ||
854 _wcsicmp(dot, L".exe") == 0 ||
855 _wcsicmp(dot, L".com") == 0)
856 result->st_mode |= 0111;
857 }
858 return code;
859}
860
861static int
862win32_fstat(int file_number, struct win32_stat *result)
863{
864 BY_HANDLE_FILE_INFORMATION info;
865 HANDLE h;
866 int type;
867
868 h = (HANDLE)_get_osfhandle(file_number);
869
870 /* Protocol violation: we explicitly clear errno, instead of
871 setting it to a POSIX error. Callers should use GetLastError. */
872 errno = 0;
873
874 if (h == INVALID_HANDLE_VALUE) {
875 /* This is really a C library error (invalid file handle).
876 We set the Win32 error to the closes one matching. */
877 SetLastError(ERROR_INVALID_HANDLE);
878 return -1;
879 }
880 memset(result, 0, sizeof(*result));
881
882 type = GetFileType(h);
883 if (type == FILE_TYPE_UNKNOWN) {
884 DWORD error = GetLastError();
885 if (error != 0) {
886 return -1;
887 }
888 /* else: valid but unknown file */
889 }
890
891 if (type != FILE_TYPE_DISK) {
892 if (type == FILE_TYPE_CHAR)
893 result->st_mode = _S_IFCHR;
894 else if (type == FILE_TYPE_PIPE)
895 result->st_mode = _S_IFIFO;
896 return 0;
897 }
898
899 if (!GetFileInformationByHandle(h, &info)) {
900 return -1;
901 }
902
903 /* similar to stat() */
904 result->st_mode = attributes_to_mode(info.dwFileAttributes);
905 result->st_size = (((__int64)info.nFileSizeHigh)<<32) + info.nFileSizeLow;
906 FILE_TIME_to_time_t_nsec(&info.ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
907 FILE_TIME_to_time_t_nsec(&info.ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
908 FILE_TIME_to_time_t_nsec(&info.ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
909 /* specific to fstat() */
910 result->st_nlink = info.nNumberOfLinks;
911 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
912 return 0;
913}
914
915#endif /* MS_WINDOWS */
916
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000917PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000918"stat_result: Result from stat or lstat.\n\n\
919This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +0000920 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000921or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
922\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +0000923Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
924or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000925\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000926See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000927
928static PyStructSequence_Field stat_result_fields[] = {
929 {"st_mode", "protection bits"},
930 {"st_ino", "inode"},
931 {"st_dev", "device"},
932 {"st_nlink", "number of hard links"},
933 {"st_uid", "user ID of owner"},
934 {"st_gid", "group ID of owner"},
935 {"st_size", "total size, in bytes"},
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000936 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
937 {NULL, "integer time of last access"},
938 {NULL, "integer time of last modification"},
939 {NULL, "integer time of last change"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000940 {"st_atime", "time of last access"},
941 {"st_mtime", "time of last modification"},
942 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000943#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000944 {"st_blksize", "blocksize for filesystem I/O"},
945#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000946#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000947 {"st_blocks", "number of blocks allocated"},
948#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000949#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000950 {"st_rdev", "device type (if inode device)"},
951#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +0000952#ifdef HAVE_STRUCT_STAT_ST_FLAGS
953 {"st_flags", "user defined flags for file"},
954#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +0000955#ifdef HAVE_STRUCT_STAT_ST_GEN
956 {"st_gen", "generation number"},
957#endif
958#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
959 {"st_birthtime", "time of creation"},
960#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000961 {0}
962};
963
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000964#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000965#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000966#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000967#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000968#endif
969
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000970#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000971#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
972#else
973#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
974#endif
975
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000976#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000977#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
978#else
979#define ST_RDEV_IDX ST_BLOCKS_IDX
980#endif
981
Hye-Shik Chang5f937a72005-06-02 13:09:30 +0000982#ifdef HAVE_STRUCT_STAT_ST_FLAGS
983#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
984#else
985#define ST_FLAGS_IDX ST_RDEV_IDX
986#endif
987
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +0000988#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +0000989#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +0000990#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +0000991#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +0000992#endif
993
994#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
995#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
996#else
997#define ST_BIRTHTIME_IDX ST_GEN_IDX
998#endif
999
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001000static PyStructSequence_Desc stat_result_desc = {
1001 "stat_result", /* name */
1002 stat_result__doc__, /* doc */
1003 stat_result_fields,
1004 10
1005};
1006
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001007PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001008"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1009This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001010 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001011or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001012\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001013See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001014
1015static PyStructSequence_Field statvfs_result_fields[] = {
1016 {"f_bsize", },
1017 {"f_frsize", },
1018 {"f_blocks", },
1019 {"f_bfree", },
1020 {"f_bavail", },
1021 {"f_files", },
1022 {"f_ffree", },
1023 {"f_favail", },
1024 {"f_flag", },
1025 {"f_namemax",},
1026 {0}
1027};
1028
1029static PyStructSequence_Desc statvfs_result_desc = {
1030 "statvfs_result", /* name */
1031 statvfs_result__doc__, /* doc */
1032 statvfs_result_fields,
1033 10
1034};
1035
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00001036static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001037static PyTypeObject StatResultType;
1038static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001039static newfunc structseq_new;
1040
1041static PyObject *
1042statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1043{
1044 PyStructSequence *result;
1045 int i;
1046
1047 result = (PyStructSequence*)structseq_new(type, args, kwds);
1048 if (!result)
1049 return NULL;
1050 /* If we have been initialized from a tuple,
1051 st_?time might be set to None. Initialize it
1052 from the int slots. */
1053 for (i = 7; i <= 9; i++) {
1054 if (result->ob_item[i+3] == Py_None) {
1055 Py_DECREF(Py_None);
1056 Py_INCREF(result->ob_item[i]);
1057 result->ob_item[i+3] = result->ob_item[i];
1058 }
1059 }
1060 return (PyObject*)result;
1061}
1062
1063
1064
1065/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001066static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001067
1068PyDoc_STRVAR(stat_float_times__doc__,
1069"stat_float_times([newval]) -> oldval\n\n\
1070Determine whether os.[lf]stat represents time stamps as float objects.\n\
1071If newval is True, future calls to stat() return floats, if it is False,\n\
1072future calls return ints. \n\
1073If newval is omitted, return the current setting.\n");
1074
1075static PyObject*
1076stat_float_times(PyObject* self, PyObject *args)
1077{
1078 int newval = -1;
1079 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1080 return NULL;
1081 if (newval == -1)
1082 /* Return old value */
1083 return PyBool_FromLong(_stat_float_times);
1084 _stat_float_times = newval;
1085 Py_INCREF(Py_None);
1086 return Py_None;
1087}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001088
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001089static void
1090fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1091{
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001092 PyObject *fval,*ival;
1093#if SIZEOF_TIME_T > SIZEOF_LONG
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00001094 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001095#else
1096 ival = PyInt_FromLong((long)sec);
1097#endif
1098 if (_stat_float_times) {
1099 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1100 } else {
1101 fval = ival;
1102 Py_INCREF(fval);
1103 }
1104 PyStructSequence_SET_ITEM(v, index, ival);
1105 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001106}
1107
Tim Peters5aa91602002-01-30 05:46:57 +00001108/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001109 (used by posix_stat() and posix_fstat()) */
1110static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001111_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001112{
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001113 unsigned long ansec, mnsec, cnsec;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001114 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +00001115 if (v == NULL)
1116 return NULL;
1117
Martin v. Löwis14694662006-02-03 12:54:16 +00001118 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001119#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001120 PyStructSequence_SET_ITEM(v, 1,
Martin v. Löwis14694662006-02-03 12:54:16 +00001121 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001122#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001123 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001124#endif
1125#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +00001126 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwis14694662006-02-03 12:54:16 +00001127 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001128#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001129 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001130#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001131 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st->st_nlink));
1132 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st->st_uid));
1133 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001134#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001135 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwis14694662006-02-03 12:54:16 +00001136 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001137#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001138 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001139#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001140
Martin v. Löwis14694662006-02-03 12:54:16 +00001141#if defined(HAVE_STAT_TV_NSEC)
1142 ansec = st->st_atim.tv_nsec;
1143 mnsec = st->st_mtim.tv_nsec;
1144 cnsec = st->st_ctim.tv_nsec;
1145#elif defined(HAVE_STAT_TV_NSEC2)
1146 ansec = st->st_atimespec.tv_nsec;
1147 mnsec = st->st_mtimespec.tv_nsec;
1148 cnsec = st->st_ctimespec.tv_nsec;
1149#elif defined(HAVE_STAT_NSEC)
1150 ansec = st->st_atime_nsec;
1151 mnsec = st->st_mtime_nsec;
1152 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001153#else
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001154 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001155#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001156 fill_time(v, 7, st->st_atime, ansec);
1157 fill_time(v, 8, st->st_mtime, mnsec);
1158 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001159
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001160#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +00001161 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001162 PyInt_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001163#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001164#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +00001165 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001166 PyInt_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001167#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001168#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001169 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001170 PyInt_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001171#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001172#ifdef HAVE_STRUCT_STAT_ST_GEN
1173 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001174 PyInt_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001175#endif
1176#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1177 {
1178 PyObject *val;
1179 unsigned long bsec,bnsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001180 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001181#ifdef HAVE_STAT_TV_NSEC2
Hye-Shik Changd69e0342006-02-19 16:22:22 +00001182 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001183#else
1184 bnsec = 0;
1185#endif
1186 if (_stat_float_times) {
1187 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1188 } else {
1189 val = PyInt_FromLong((long)bsec);
1190 }
1191 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1192 val);
1193 }
1194#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001195#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1196 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001197 PyInt_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001198#endif
Fred Drake699f3522000-06-29 21:12:41 +00001199
1200 if (PyErr_Occurred()) {
1201 Py_DECREF(v);
1202 return NULL;
1203 }
1204
1205 return v;
1206}
1207
Martin v. Löwisd8948722004-06-02 09:57:56 +00001208#ifdef MS_WINDOWS
1209
1210/* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
1211 where / can be used in place of \ and the trailing slash is optional.
1212 Both SERVER and SHARE must have at least one character.
1213*/
1214
1215#define ISSLASHA(c) ((c) == '\\' || (c) == '/')
1216#define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
1217#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
1218
Tim Peters4ad82172004-08-30 17:02:04 +00001219static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001220IsUNCRootA(char *path, int pathlen)
1221{
1222 #define ISSLASH ISSLASHA
1223
1224 int i, share;
1225
1226 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1227 /* minimum UNCRoot is \\x\y */
1228 return FALSE;
1229 for (i = 2; i < pathlen ; i++)
1230 if (ISSLASH(path[i])) break;
1231 if (i == 2 || i == pathlen)
1232 /* do not allow \\\SHARE or \\SERVER */
1233 return FALSE;
1234 share = i+1;
1235 for (i = share; i < pathlen; i++)
1236 if (ISSLASH(path[i])) break;
1237 return (i != share && (i == pathlen || i == pathlen-1));
1238
1239 #undef ISSLASH
1240}
1241
1242#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters4ad82172004-08-30 17:02:04 +00001243static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001244IsUNCRootW(Py_UNICODE *path, int pathlen)
1245{
1246 #define ISSLASH ISSLASHW
1247
1248 int i, share;
1249
1250 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1251 /* minimum UNCRoot is \\x\y */
1252 return FALSE;
1253 for (i = 2; i < pathlen ; i++)
1254 if (ISSLASH(path[i])) break;
1255 if (i == 2 || i == pathlen)
1256 /* do not allow \\\SHARE or \\SERVER */
1257 return FALSE;
1258 share = i+1;
1259 for (i = share; i < pathlen; i++)
1260 if (ISSLASH(path[i])) break;
1261 return (i != share && (i == pathlen || i == pathlen-1));
1262
1263 #undef ISSLASH
1264}
1265#endif /* Py_WIN_WIDE_FILENAMES */
1266#endif /* MS_WINDOWS */
1267
Barry Warsaw53699e91996-12-10 23:23:01 +00001268static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001269posix_do_stat(PyObject *self, PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001270 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001271#ifdef __VMS
1272 int (*statfunc)(const char *, STRUCT_STAT *, ...),
1273#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001274 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001275#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001276 char *wformat,
1277 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001278{
Fred Drake699f3522000-06-29 21:12:41 +00001279 STRUCT_STAT st;
Tim Peters500bd032001-12-19 19:05:01 +00001280 char *path = NULL; /* pass this to stat; do not free() it */
1281 char *pathfree = NULL; /* this memory must be free'd */
Guido van Rossumff4949e1992-08-05 19:58:53 +00001282 int res;
Martin v. Löwis14694662006-02-03 12:54:16 +00001283 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001284
1285#ifdef Py_WIN_WIDE_FILENAMES
1286 /* If on wide-character-capable OS see if argument
1287 is Unicode and if so use wide API. */
1288 if (unicode_file_names()) {
1289 PyUnicodeObject *po;
1290 if (PyArg_ParseTuple(args, wformat, &po)) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001291 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
1292
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001293 Py_BEGIN_ALLOW_THREADS
1294 /* PyUnicode_AS_UNICODE result OK without
1295 thread lock as it is a simple dereference. */
1296 res = wstatfunc(wpath, &st);
1297 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001298
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001299 if (res != 0)
Martin v. Löwis14694662006-02-03 12:54:16 +00001300 return win32_error_unicode("stat", wpath);
1301 return _pystat_fromstructstat(&st);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001302 }
1303 /* Drop the argument parsing error as narrow strings
1304 are also valid. */
1305 PyErr_Clear();
1306 }
1307#endif
1308
Tim Peters5aa91602002-01-30 05:46:57 +00001309 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +00001310 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001311 return NULL;
Tim Peters500bd032001-12-19 19:05:01 +00001312 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +00001313
Barry Warsaw53699e91996-12-10 23:23:01 +00001314 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001315 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00001316 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001317
1318 if (res != 0) {
1319#ifdef MS_WINDOWS
1320 result = win32_error("stat", pathfree);
1321#else
1322 result = posix_error_with_filename(pathfree);
1323#endif
1324 }
1325 else
1326 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001327
Tim Peters500bd032001-12-19 19:05:01 +00001328 PyMem_Free(pathfree);
Martin v. Löwis14694662006-02-03 12:54:16 +00001329 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001330}
1331
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001332/* POSIX methods */
1333
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001334PyDoc_STRVAR(posix_access__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001335"access(path, mode) -> 1 if granted, 0 otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001336Use the real uid/gid to test for access to a path. Note that most\n\
1337operations will use the effective uid/gid, therefore this routine can\n\
1338be used in a suid/sgid environment to test if the invoking user has the\n\
1339specified access to the path. The mode argument can be F_OK to test\n\
1340existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001341
1342static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001343posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001344{
Guido van Rossum015f22a1999-01-06 22:52:38 +00001345 char *path;
1346 int mode;
1347 int res;
1348
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001349#ifdef Py_WIN_WIDE_FILENAMES
1350 if (unicode_file_names()) {
1351 PyUnicodeObject *po;
1352 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1353 Py_BEGIN_ALLOW_THREADS
1354 /* PyUnicode_AS_UNICODE OK without thread lock as
1355 it is a simple dereference. */
1356 res = _waccess(PyUnicode_AS_UNICODE(po), mode);
1357 Py_END_ALLOW_THREADS
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001358 return PyBool_FromLong(res == 0);
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001359 }
1360 /* Drop the argument parsing error as narrow strings
1361 are also valid. */
1362 PyErr_Clear();
1363 }
1364#endif
Martin v. Löwisb60ae992005-03-08 09:10:29 +00001365 if (!PyArg_ParseTuple(args, "eti:access",
1366 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +00001367 return NULL;
1368 Py_BEGIN_ALLOW_THREADS
1369 res = access(path, mode);
1370 Py_END_ALLOW_THREADS
Neal Norwitz24b3c222005-09-19 06:43:44 +00001371 PyMem_Free(path);
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001372 return PyBool_FromLong(res == 0);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001373}
1374
Guido van Rossumd371ff11999-01-25 16:12:23 +00001375#ifndef F_OK
1376#define F_OK 0
1377#endif
1378#ifndef R_OK
1379#define R_OK 4
1380#endif
1381#ifndef W_OK
1382#define W_OK 2
1383#endif
1384#ifndef X_OK
1385#define X_OK 1
1386#endif
1387
1388#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001389PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001390"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001391Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001392
1393static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001394posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001395{
Guido van Rossum94f6f721999-01-06 18:42:14 +00001396 int id;
1397 char *ret;
1398
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001399 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +00001400 return NULL;
1401
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001402#if defined(__VMS)
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +00001403 /* file descriptor 0 only, the default input device (stdin) */
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001404 if (id == 0) {
1405 ret = ttyname();
1406 }
1407 else {
1408 ret = NULL;
1409 }
1410#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00001411 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001412#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001413 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001414 return posix_error();
1415 return PyString_FromString(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001416}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001417#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001418
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001419#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001420PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001421"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001422Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001423
1424static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001425posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001426{
1427 char *ret;
1428 char buffer[L_ctermid];
1429
Greg Wardb48bc172000-03-01 21:51:56 +00001430#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001431 ret = ctermid_r(buffer);
1432#else
1433 ret = ctermid(buffer);
1434#endif
1435 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001436 return posix_error();
1437 return PyString_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001438}
1439#endif
1440
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001441PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001442"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001443Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001444
Barry Warsaw53699e91996-12-10 23:23:01 +00001445static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001446posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001447{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001448#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001449 return win32_1str(args, "chdir", "s:chdir", win32_chdir, "U:chdir", win32_wchdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001450#elif defined(PYOS_OS2) && defined(PYCC_GCC)
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001451 return posix_1str(args, "et:chdir", _chdir2);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001452#elif defined(__VMS)
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001453 return posix_1str(args, "et:chdir", (int (*)(const char *))chdir);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001454#else
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001455 return posix_1str(args, "et:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001456#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001457}
1458
Fred Drake4d1e64b2002-04-15 19:40:07 +00001459#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001460PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001461"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001462Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001463opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001464
1465static PyObject *
1466posix_fchdir(PyObject *self, PyObject *fdobj)
1467{
1468 return posix_fildes(fdobj, fchdir);
1469}
1470#endif /* HAVE_FCHDIR */
1471
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001472
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001473PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001474"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001475Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001476
Barry Warsaw53699e91996-12-10 23:23:01 +00001477static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001478posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001479{
Mark Hammondef8b6542001-05-13 08:04:26 +00001480 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +00001481 int i;
1482 int res;
Mark Hammond817c9292003-12-03 01:22:38 +00001483#ifdef Py_WIN_WIDE_FILENAMES
1484 if (unicode_file_names()) {
1485 PyUnicodeObject *po;
1486 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1487 Py_BEGIN_ALLOW_THREADS
1488 res = _wchmod(PyUnicode_AS_UNICODE(po), i);
1489 Py_END_ALLOW_THREADS
1490 if (res < 0)
1491 return posix_error_with_unicode_filename(
1492 PyUnicode_AS_UNICODE(po));
1493 Py_INCREF(Py_None);
1494 return Py_None;
1495 }
1496 /* Drop the argument parsing error as narrow strings
1497 are also valid. */
1498 PyErr_Clear();
1499 }
1500#endif /* Py_WIN_WIDE_FILENAMES */
1501 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
Mark Hammondef8b6542001-05-13 08:04:26 +00001502 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +00001503 return NULL;
1504 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +00001505 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001506 Py_END_ALLOW_THREADS
1507 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001508 return posix_error_with_allocated_filename(path);
1509 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001510 Py_INCREF(Py_None);
1511 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001512}
1513
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001514
Martin v. Löwis244edc82001-10-04 22:44:26 +00001515#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001516PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001517"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001518Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00001519
1520static PyObject *
1521posix_chroot(PyObject *self, PyObject *args)
1522{
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001523 return posix_1str(args, "et:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00001524}
1525#endif
1526
Guido van Rossum21142a01999-01-08 21:05:37 +00001527#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001528PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001529"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001530force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001531
1532static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001533posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001534{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001535 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001536}
1537#endif /* HAVE_FSYNC */
1538
1539#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00001540
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00001541#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00001542extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1543#endif
1544
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001545PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001546"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00001547force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001548 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001549
1550static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001551posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001552{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001553 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001554}
1555#endif /* HAVE_FDATASYNC */
1556
1557
Fredrik Lundh10723342000-07-10 16:38:09 +00001558#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001559PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001560"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001561Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001562
Barry Warsaw53699e91996-12-10 23:23:01 +00001563static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001564posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001565{
Mark Hammondef8b6542001-05-13 08:04:26 +00001566 char *path = NULL;
Fredrik Lundh44328e62000-07-10 15:59:30 +00001567 int uid, gid;
1568 int res;
Tim Peters5aa91602002-01-30 05:46:57 +00001569 if (!PyArg_ParseTuple(args, "etii:chown",
1570 Py_FileSystemDefaultEncoding, &path,
Mark Hammondef8b6542001-05-13 08:04:26 +00001571 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +00001572 return NULL;
1573 Py_BEGIN_ALLOW_THREADS
1574 res = chown(path, (uid_t) uid, (gid_t) gid);
1575 Py_END_ALLOW_THREADS
1576 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001577 return posix_error_with_allocated_filename(path);
1578 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +00001579 Py_INCREF(Py_None);
1580 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001581}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001582#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001583
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001584#ifdef HAVE_LCHOWN
1585PyDoc_STRVAR(posix_lchown__doc__,
1586"lchown(path, uid, gid)\n\n\
1587Change the owner and group id of path to the numeric uid and gid.\n\
1588This function will not follow symbolic links.");
1589
1590static PyObject *
1591posix_lchown(PyObject *self, PyObject *args)
1592{
1593 char *path = NULL;
1594 int uid, gid;
1595 int res;
1596 if (!PyArg_ParseTuple(args, "etii:lchown",
1597 Py_FileSystemDefaultEncoding, &path,
1598 &uid, &gid))
1599 return NULL;
1600 Py_BEGIN_ALLOW_THREADS
1601 res = lchown(path, (uid_t) uid, (gid_t) gid);
1602 Py_END_ALLOW_THREADS
Tim Peters11b23062003-04-23 02:39:17 +00001603 if (res < 0)
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001604 return posix_error_with_allocated_filename(path);
1605 PyMem_Free(path);
1606 Py_INCREF(Py_None);
1607 return Py_None;
1608}
1609#endif /* HAVE_LCHOWN */
1610
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001611
Guido van Rossum36bc6801995-06-14 22:54:23 +00001612#ifdef HAVE_GETCWD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001613PyDoc_STRVAR(posix_getcwd__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001614"getcwd() -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001615Return a string representing the current working directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001616
Barry Warsaw53699e91996-12-10 23:23:01 +00001617static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001618posix_getcwd(PyObject *self, PyObject *noargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001619{
1620 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +00001621 char *res;
Neal Norwitze241ce82003-02-17 18:17:05 +00001622
Barry Warsaw53699e91996-12-10 23:23:01 +00001623 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001624#if defined(PYOS_OS2) && defined(PYCC_GCC)
1625 res = _getcwd2(buf, sizeof buf);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001626#else
Guido van Rossumff4949e1992-08-05 19:58:53 +00001627 res = getcwd(buf, sizeof buf);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001628#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001629 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001630 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001631 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001632 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001633}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001634
Walter Dörwald3b918c32002-11-21 20:18:46 +00001635#ifdef Py_USING_UNICODE
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001636PyDoc_STRVAR(posix_getcwdu__doc__,
1637"getcwdu() -> path\n\n\
1638Return a unicode string representing the current working directory.");
1639
1640static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001641posix_getcwdu(PyObject *self, PyObject *noargs)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001642{
1643 char buf[1026];
1644 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001645
1646#ifdef Py_WIN_WIDE_FILENAMES
1647 if (unicode_file_names()) {
1648 wchar_t *wres;
1649 wchar_t wbuf[1026];
1650 Py_BEGIN_ALLOW_THREADS
1651 wres = _wgetcwd(wbuf, sizeof wbuf/ sizeof wbuf[0]);
1652 Py_END_ALLOW_THREADS
1653 if (wres == NULL)
1654 return posix_error();
1655 return PyUnicode_FromWideChar(wbuf, wcslen(wbuf));
1656 }
1657#endif
1658
1659 Py_BEGIN_ALLOW_THREADS
1660#if defined(PYOS_OS2) && defined(PYCC_GCC)
1661 res = _getcwd2(buf, sizeof buf);
1662#else
1663 res = getcwd(buf, sizeof buf);
1664#endif
1665 Py_END_ALLOW_THREADS
1666 if (res == NULL)
1667 return posix_error();
1668 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
1669}
Guido van Rossum36bc6801995-06-14 22:54:23 +00001670#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00001671#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001672
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001673
Guido van Rossumb6775db1994-08-01 11:34:53 +00001674#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001675PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001676"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001677Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001678
Barry Warsaw53699e91996-12-10 23:23:01 +00001679static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001680posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001681{
Martin v. Löwis4fc2bda2006-05-04 12:04:27 +00001682 return posix_2str(args, "etet:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001683}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001684#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001685
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001686
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001687PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001688"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001689Return a list containing the names of the entries in the directory.\n\
1690\n\
1691 path: path of directory to list\n\
1692\n\
1693The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001694entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001695
Barry Warsaw53699e91996-12-10 23:23:01 +00001696static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001697posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001698{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001699 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001700 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001701#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001702
Barry Warsaw53699e91996-12-10 23:23:01 +00001703 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001704 HANDLE hFindFile;
Martin v. Löwise920f0d2006-03-07 23:59:33 +00001705 BOOL result;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001706 WIN32_FIND_DATA FileData;
Mark Hammondef8b6542001-05-13 08:04:26 +00001707 /* MAX_PATH characters could mean a bigger encoded string */
1708 char namebuf[MAX_PATH*2+5];
1709 char *bufptr = namebuf;
Martin v. Löwis18e16552006-02-15 17:27:45 +00001710 Py_ssize_t len = sizeof(namebuf)/sizeof(namebuf[0]);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001711
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001712#ifdef Py_WIN_WIDE_FILENAMES
1713 /* If on wide-character-capable OS see if argument
1714 is Unicode and if so use wide API. */
1715 if (unicode_file_names()) {
1716 PyUnicodeObject *po;
1717 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
1718 WIN32_FIND_DATAW wFileData;
1719 Py_UNICODE wnamebuf[MAX_PATH*2+5];
1720 Py_UNICODE wch;
1721 wcsncpy(wnamebuf, PyUnicode_AS_UNICODE(po), MAX_PATH);
1722 wnamebuf[MAX_PATH] = L'\0';
1723 len = wcslen(wnamebuf);
1724 wch = (len > 0) ? wnamebuf[len-1] : L'\0';
1725 if (wch != L'/' && wch != L'\\' && wch != L':')
1726 wnamebuf[len++] = L'/';
1727 wcscpy(wnamebuf + len, L"*.*");
1728 if ((d = PyList_New(0)) == NULL)
1729 return NULL;
1730 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
1731 if (hFindFile == INVALID_HANDLE_VALUE) {
1732 errno = GetLastError();
1733 if (errno == ERROR_FILE_NOT_FOUND) {
1734 return d;
1735 }
1736 Py_DECREF(d);
1737 return win32_error_unicode("FindFirstFileW", wnamebuf);
1738 }
1739 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00001740 /* Skip over . and .. */
1741 if (wcscmp(wFileData.cFileName, L".") != 0 &&
1742 wcscmp(wFileData.cFileName, L"..") != 0) {
1743 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
1744 if (v == NULL) {
1745 Py_DECREF(d);
1746 d = NULL;
1747 break;
1748 }
1749 if (PyList_Append(d, v) != 0) {
1750 Py_DECREF(v);
1751 Py_DECREF(d);
1752 d = NULL;
1753 break;
1754 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001755 Py_DECREF(v);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001756 }
Georg Brandl622927b2006-03-07 12:48:03 +00001757 Py_BEGIN_ALLOW_THREADS
1758 result = FindNextFileW(hFindFile, &wFileData);
1759 Py_END_ALLOW_THREADS
1760 } while (result == TRUE);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001761
1762 if (FindClose(hFindFile) == FALSE) {
1763 Py_DECREF(d);
1764 return win32_error_unicode("FindClose", wnamebuf);
1765 }
1766 return d;
1767 }
1768 /* Drop the argument parsing error as narrow strings
1769 are also valid. */
1770 PyErr_Clear();
1771 }
1772#endif
1773
Tim Peters5aa91602002-01-30 05:46:57 +00001774 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001775 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +00001776 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +00001777 if (len > 0) {
1778 char ch = namebuf[len-1];
1779 if (ch != SEP && ch != ALTSEP && ch != ':')
1780 namebuf[len++] = '/';
1781 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001782 strcpy(namebuf + len, "*.*");
1783
Barry Warsaw53699e91996-12-10 23:23:01 +00001784 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001785 return NULL;
1786
1787 hFindFile = FindFirstFile(namebuf, &FileData);
1788 if (hFindFile == INVALID_HANDLE_VALUE) {
1789 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +00001790 if (errno == ERROR_FILE_NOT_FOUND)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001791 return d;
1792 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00001793 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001794 }
1795 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00001796 /* Skip over . and .. */
1797 if (strcmp(FileData.cFileName, ".") != 0 &&
1798 strcmp(FileData.cFileName, "..") != 0) {
1799 v = PyString_FromString(FileData.cFileName);
1800 if (v == NULL) {
1801 Py_DECREF(d);
1802 d = NULL;
1803 break;
1804 }
1805 if (PyList_Append(d, v) != 0) {
1806 Py_DECREF(v);
1807 Py_DECREF(d);
1808 d = NULL;
1809 break;
1810 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001811 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001812 }
Georg Brandl622927b2006-03-07 12:48:03 +00001813 Py_BEGIN_ALLOW_THREADS
1814 result = FindNextFile(hFindFile, &FileData);
1815 Py_END_ALLOW_THREADS
1816 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001817
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001818 if (FindClose(hFindFile) == FALSE) {
1819 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00001820 return win32_error("FindClose", namebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001821 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001822
1823 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001824
Tim Peters0bb44a42000-09-15 07:44:49 +00001825#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001826
1827#ifndef MAX_PATH
1828#define MAX_PATH CCHMAXPATH
1829#endif
1830 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00001831 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001832 PyObject *d, *v;
1833 char namebuf[MAX_PATH+5];
1834 HDIR hdir = 1;
1835 ULONG srchcnt = 1;
1836 FILEFINDBUF3 ep;
1837 APIRET rc;
1838
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001839 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001840 return NULL;
1841 if (len >= MAX_PATH) {
1842 PyErr_SetString(PyExc_ValueError, "path too long");
1843 return NULL;
1844 }
1845 strcpy(namebuf, name);
1846 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001847 if (*pt == ALTSEP)
1848 *pt = SEP;
1849 if (namebuf[len-1] != SEP)
1850 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001851 strcpy(namebuf + len, "*.*");
1852
1853 if ((d = PyList_New(0)) == NULL)
1854 return NULL;
1855
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001856 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
1857 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001858 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001859 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
1860 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
1861 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001862
1863 if (rc != NO_ERROR) {
1864 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001865 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001866 }
1867
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001868 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001869 do {
1870 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001871 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001872 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001873
1874 strcpy(namebuf, ep.achName);
1875
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001876 /* Leave Case of Name Alone -- In Native Form */
1877 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001878
1879 v = PyString_FromString(namebuf);
1880 if (v == NULL) {
1881 Py_DECREF(d);
1882 d = NULL;
1883 break;
1884 }
1885 if (PyList_Append(d, v) != 0) {
1886 Py_DECREF(v);
1887 Py_DECREF(d);
1888 d = NULL;
1889 break;
1890 }
1891 Py_DECREF(v);
1892 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1893 }
1894
1895 return d;
1896#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001897
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001898 char *name = NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001899 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001900 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001901 struct dirent *ep;
Just van Rossum96b1c902003-03-03 17:32:15 +00001902 int arg_is_unicode = 1;
1903
Georg Brandl05e89b82006-04-11 07:04:06 +00001904 errno = 0;
Just van Rossum96b1c902003-03-03 17:32:15 +00001905 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
1906 arg_is_unicode = 0;
1907 PyErr_Clear();
1908 }
1909 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001910 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001911 if ((dirp = opendir(name)) == NULL) {
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001912 return posix_error_with_allocated_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001913 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001914 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001915 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001916 PyMem_Free(name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001917 return NULL;
1918 }
Georg Brandl622927b2006-03-07 12:48:03 +00001919 for (;;) {
1920 Py_BEGIN_ALLOW_THREADS
1921 ep = readdir(dirp);
1922 Py_END_ALLOW_THREADS
1923 if (ep == NULL)
1924 break;
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001925 if (ep->d_name[0] == '.' &&
1926 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001927 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001928 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001929 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001930 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001931 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001932 d = NULL;
1933 break;
1934 }
Just van Rossum46c97842003-02-25 21:42:15 +00001935#ifdef Py_USING_UNICODE
Just van Rossum96b1c902003-03-03 17:32:15 +00001936 if (arg_is_unicode) {
Just van Rossum46c97842003-02-25 21:42:15 +00001937 PyObject *w;
1938
1939 w = PyUnicode_FromEncodedObject(v,
Tim Peters11b23062003-04-23 02:39:17 +00001940 Py_FileSystemDefaultEncoding,
Just van Rossum46c97842003-02-25 21:42:15 +00001941 "strict");
Just van Rossum6a421832003-03-04 19:30:44 +00001942 if (w != NULL) {
1943 Py_DECREF(v);
1944 v = w;
1945 }
1946 else {
1947 /* fall back to the original byte string, as
1948 discussed in patch #683592 */
1949 PyErr_Clear();
Just van Rossum46c97842003-02-25 21:42:15 +00001950 }
Just van Rossum46c97842003-02-25 21:42:15 +00001951 }
1952#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001953 if (PyList_Append(d, v) != 0) {
1954 Py_DECREF(v);
1955 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001956 d = NULL;
1957 break;
1958 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001959 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001960 }
Georg Brandlbbfe4fa2006-04-11 06:47:43 +00001961 if (errno != 0 && d != NULL) {
1962 /* readdir() returned NULL and set errno */
1963 closedir(dirp);
1964 Py_DECREF(d);
1965 return posix_error_with_allocated_filename(name);
1966 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001967 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001968 PyMem_Free(name);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001969
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001970 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001971
Tim Peters0bb44a42000-09-15 07:44:49 +00001972#endif /* which OS */
1973} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001974
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001975#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00001976/* A helper function for abspath on win32 */
1977static PyObject *
1978posix__getfullpathname(PyObject *self, PyObject *args)
1979{
1980 /* assume encoded strings wont more than double no of chars */
1981 char inbuf[MAX_PATH*2];
1982 char *inbufp = inbuf;
Tim Peters67d70eb2006-03-01 04:35:45 +00001983 Py_ssize_t insize = sizeof(inbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00001984 char outbuf[MAX_PATH*2];
1985 char *temp;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001986#ifdef Py_WIN_WIDE_FILENAMES
1987 if (unicode_file_names()) {
1988 PyUnicodeObject *po;
1989 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
1990 Py_UNICODE woutbuf[MAX_PATH*2];
1991 Py_UNICODE *wtemp;
Tim Peters11b23062003-04-23 02:39:17 +00001992 if (!GetFullPathNameW(PyUnicode_AS_UNICODE(po),
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001993 sizeof(woutbuf)/sizeof(woutbuf[0]),
1994 woutbuf, &wtemp))
1995 return win32_error("GetFullPathName", "");
1996 return PyUnicode_FromUnicode(woutbuf, wcslen(woutbuf));
1997 }
1998 /* Drop the argument parsing error as narrow strings
1999 are also valid. */
2000 PyErr_Clear();
2001 }
2002#endif
Tim Peters5aa91602002-01-30 05:46:57 +00002003 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
2004 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00002005 &insize))
2006 return NULL;
2007 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
2008 outbuf, &temp))
2009 return win32_error("GetFullPathName", inbuf);
Martin v. Löwis969297f2004-06-15 18:49:58 +00002010 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2011 return PyUnicode_Decode(outbuf, strlen(outbuf),
2012 Py_FileSystemDefaultEncoding, NULL);
2013 }
Mark Hammondef8b6542001-05-13 08:04:26 +00002014 return PyString_FromString(outbuf);
2015} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002016#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00002017
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002018PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002019"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002020Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002021
Barry Warsaw53699e91996-12-10 23:23:01 +00002022static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002023posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002024{
Guido van Rossumb0824db1996-02-25 04:50:32 +00002025 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00002026 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002027 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002028
2029#ifdef Py_WIN_WIDE_FILENAMES
2030 if (unicode_file_names()) {
2031 PyUnicodeObject *po;
Mark Hammond05107b62003-02-19 04:08:27 +00002032 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002033 Py_BEGIN_ALLOW_THREADS
2034 /* PyUnicode_AS_UNICODE OK without thread lock as
2035 it is a simple dereference. */
2036 res = _wmkdir(PyUnicode_AS_UNICODE(po));
2037 Py_END_ALLOW_THREADS
2038 if (res < 0)
2039 return posix_error();
2040 Py_INCREF(Py_None);
2041 return Py_None;
2042 }
2043 /* Drop the argument parsing error as narrow strings
2044 are also valid. */
2045 PyErr_Clear();
2046 }
2047#endif
2048
Tim Peters5aa91602002-01-30 05:46:57 +00002049 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00002050 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00002051 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002052 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002053#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002054 res = mkdir(path);
2055#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00002056 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002057#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002058 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00002059 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00002060 return posix_error_with_allocated_filename(path);
2061 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002062 Py_INCREF(Py_None);
2063 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002064}
2065
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002066
Neal Norwitz1818ed72006-03-26 00:29:48 +00002067/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2068#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002069#include <sys/resource.h>
2070#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002071
Neal Norwitz1818ed72006-03-26 00:29:48 +00002072
2073#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002074PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002075"nice(inc) -> new_priority\n\n\
2076Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002077
Barry Warsaw53699e91996-12-10 23:23:01 +00002078static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002079posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002080{
2081 int increment, value;
2082
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002083 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00002084 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002085
2086 /* There are two flavours of 'nice': one that returns the new
2087 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002088 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2089 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002090
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002091 If we are of the nice family that returns the new priority, we
2092 need to clear errno before the call, and check if errno is filled
2093 before calling posix_error() on a returnvalue of -1, because the
2094 -1 may be the actual new priority! */
2095
2096 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002097 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002098#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002099 if (value == 0)
2100 value = getpriority(PRIO_PROCESS, 0);
2101#endif
2102 if (value == -1 && errno != 0)
2103 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00002104 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002105 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002106}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002107#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002108
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002109PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002110"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002111Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002112
Barry Warsaw53699e91996-12-10 23:23:01 +00002113static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002114posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002115{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002116#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002117 PyObject *o1, *o2;
2118 char *p1, *p2;
2119 BOOL result;
2120 if (unicode_file_names()) {
2121 if (!PyArg_ParseTuple(args, "O&O&:rename",
2122 convert_to_unicode, &o1,
2123 convert_to_unicode, &o2))
2124 PyErr_Clear();
2125 else {
2126 Py_BEGIN_ALLOW_THREADS
2127 result = MoveFileW(PyUnicode_AsUnicode(o1),
2128 PyUnicode_AsUnicode(o2));
2129 Py_END_ALLOW_THREADS
2130 Py_DECREF(o1);
2131 Py_DECREF(o2);
2132 if (!result)
2133 return win32_error("rename", NULL);
2134 Py_INCREF(Py_None);
2135 return Py_None;
2136 }
2137 }
2138 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
2139 return NULL;
2140 Py_BEGIN_ALLOW_THREADS
2141 result = MoveFileA(p1, p2);
2142 Py_END_ALLOW_THREADS
2143 if (!result)
2144 return win32_error("rename", NULL);
2145 Py_INCREF(Py_None);
2146 return Py_None;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002147#else
Martin v. Löwis4fc2bda2006-05-04 12:04:27 +00002148 return posix_2str(args, "etet:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002149#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002150}
2151
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002152
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002153PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002154"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002155Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002156
Barry Warsaw53699e91996-12-10 23:23:01 +00002157static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002158posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002159{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002160#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002161 return win32_1str(args, "rmdir", "s:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002162#else
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002163 return posix_1str(args, "et:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002164#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002165}
2166
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002167
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002168PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002169"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002170Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002171
Barry Warsaw53699e91996-12-10 23:23:01 +00002172static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002173posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002174{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002175#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00002176 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002177#else
2178 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
2179#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002180}
2181
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002182
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002183#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002184PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002185"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002186Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002187
Barry Warsaw53699e91996-12-10 23:23:01 +00002188static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002189posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002190{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002191 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002192 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002193 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002194 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002195 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002196 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00002197 Py_END_ALLOW_THREADS
2198 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002199}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002200#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002201
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002202
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002203PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002204"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002205Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002206
Barry Warsaw53699e91996-12-10 23:23:01 +00002207static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002208posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002209{
2210 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002211 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002212 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00002213 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002214 if (i < 0)
2215 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002216 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002217}
2218
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002219
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002220PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002221"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002222Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002223
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002224PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002225"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002226Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002227
Barry Warsaw53699e91996-12-10 23:23:01 +00002228static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002229posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002230{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002231#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002232 return win32_1str(args, "remove", "s:remove", DeleteFileA, "U:remove", DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002233#else
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002234 return posix_1str(args, "et:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002235#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002236}
2237
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002238
Guido van Rossumb6775db1994-08-01 11:34:53 +00002239#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002240PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002241"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002242Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002243
Barry Warsaw53699e91996-12-10 23:23:01 +00002244static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002245posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002246{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002247 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002248 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00002249
Barry Warsaw53699e91996-12-10 23:23:01 +00002250 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002251 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00002252 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002253 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002254 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002255 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00002256 u.sysname,
2257 u.nodename,
2258 u.release,
2259 u.version,
2260 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002261}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002262#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002263
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002264static int
2265extract_time(PyObject *t, long* sec, long* usec)
2266{
2267 long intval;
2268 if (PyFloat_Check(t)) {
2269 double tval = PyFloat_AsDouble(t);
2270 PyObject *intobj = t->ob_type->tp_as_number->nb_int(t);
2271 if (!intobj)
2272 return -1;
2273 intval = PyInt_AsLong(intobj);
2274 Py_DECREF(intobj);
Michael W. Hudsonb8963812005-07-05 15:21:58 +00002275 if (intval == -1 && PyErr_Occurred())
2276 return -1;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002277 *sec = intval;
Tim Peters96940cf2002-09-10 15:37:28 +00002278 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002279 if (*usec < 0)
2280 /* If rounding gave us a negative number,
2281 truncate. */
2282 *usec = 0;
2283 return 0;
2284 }
2285 intval = PyInt_AsLong(t);
2286 if (intval == -1 && PyErr_Occurred())
2287 return -1;
2288 *sec = intval;
2289 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00002290 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002291}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002292
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002293PyDoc_STRVAR(posix_utime__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002294"utime(path, (atime, utime))\n\
2295utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00002296Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002297second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002298
Barry Warsaw53699e91996-12-10 23:23:01 +00002299static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002300posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002301{
Neal Norwitz2adf2102004-06-09 01:46:02 +00002302 char *path = NULL;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002303 long atime, mtime, ausec, musec;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002304 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002305 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002306
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002307#if defined(HAVE_UTIMES)
2308 struct timeval buf[2];
2309#define ATIME buf[0].tv_sec
2310#define MTIME buf[1].tv_sec
2311#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002312/* XXX should define struct utimbuf instead, above */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002313 struct utimbuf buf;
2314#define ATIME buf.actime
2315#define MTIME buf.modtime
2316#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002317#else /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002318 time_t buf[2];
2319#define ATIME buf[0]
2320#define MTIME buf[1]
2321#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002322#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002323
Mark Hammond817c9292003-12-03 01:22:38 +00002324 int have_unicode_filename = 0;
2325#ifdef Py_WIN_WIDE_FILENAMES
2326 PyUnicodeObject *obwpath;
2327 wchar_t *wpath;
2328 if (unicode_file_names()) {
2329 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
2330 wpath = PyUnicode_AS_UNICODE(obwpath);
2331 have_unicode_filename = 1;
2332 } else
2333 /* Drop the argument parsing error as narrow strings
2334 are also valid. */
2335 PyErr_Clear();
2336 }
2337#endif /* Py_WIN_WIDE_FILENAMES */
2338
2339 if (!have_unicode_filename && \
Hye-Shik Chang2b2c9732004-01-04 13:54:25 +00002340 !PyArg_ParseTuple(args, "etO:utime",
2341 Py_FileSystemDefaultEncoding, &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002342 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002343 if (arg == Py_None) {
2344 /* optional time values not given */
2345 Py_BEGIN_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002346#ifdef Py_WIN_WIDE_FILENAMES
2347 if (have_unicode_filename)
2348 res = _wutime(wpath, NULL);
2349 else
2350#endif /* Py_WIN_WIDE_FILENAMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002351 res = utime(path, NULL);
2352 Py_END_ALLOW_THREADS
2353 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002354 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00002355 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002356 "utime() arg 2 must be a tuple (atime, mtime)");
Neal Norwitz96652712004-06-06 20:40:27 +00002357 PyMem_Free(path);
Barry Warsaw3cef8562000-05-01 16:17:24 +00002358 return NULL;
2359 }
2360 else {
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002361 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Neal Norwitz96652712004-06-06 20:40:27 +00002362 &atime, &ausec) == -1) {
2363 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002364 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002365 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002366 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Neal Norwitz96652712004-06-06 20:40:27 +00002367 &mtime, &musec) == -1) {
2368 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002369 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002370 }
Barry Warsaw3cef8562000-05-01 16:17:24 +00002371 ATIME = atime;
2372 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002373#ifdef HAVE_UTIMES
2374 buf[0].tv_usec = ausec;
2375 buf[1].tv_usec = musec;
2376 Py_BEGIN_ALLOW_THREADS
2377 res = utimes(path, buf);
2378 Py_END_ALLOW_THREADS
2379#else
Barry Warsaw3cef8562000-05-01 16:17:24 +00002380 Py_BEGIN_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002381#ifdef Py_WIN_WIDE_FILENAMES
2382 if (have_unicode_filename)
Tim Peters4ad82172004-08-30 17:02:04 +00002383 /* utime is OK with utimbuf, but _wutime insists
2384 on _utimbuf (the msvc headers assert the
Mark Hammond817c9292003-12-03 01:22:38 +00002385 underscore version is ansi) */
2386 res = _wutime(wpath, (struct _utimbuf *)UTIME_ARG);
2387 else
2388#endif /* Py_WIN_WIDE_FILENAMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002389 res = utime(path, UTIME_ARG);
2390 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002391#endif /* HAVE_UTIMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002392 }
Mark Hammond2d5914b2004-05-04 08:10:37 +00002393 if (res < 0) {
2394#ifdef Py_WIN_WIDE_FILENAMES
Neal Norwitz2adf2102004-06-09 01:46:02 +00002395 if (have_unicode_filename)
Mark Hammond2d5914b2004-05-04 08:10:37 +00002396 return posix_error_with_unicode_filename(wpath);
2397#endif /* Py_WIN_WIDE_FILENAMES */
Neal Norwitz96652712004-06-06 20:40:27 +00002398 return posix_error_with_allocated_filename(path);
Mark Hammond2d5914b2004-05-04 08:10:37 +00002399 }
Neal Norwitz96652712004-06-06 20:40:27 +00002400 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002401 Py_INCREF(Py_None);
2402 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002403#undef UTIME_ARG
2404#undef ATIME
2405#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002406}
2407
Guido van Rossum85e3b011991-06-03 12:42:10 +00002408
Guido van Rossum3b066191991-06-04 19:40:25 +00002409/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002410
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002411PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002412"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002413Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002414
Barry Warsaw53699e91996-12-10 23:23:01 +00002415static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002416posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002417{
2418 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002419 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002420 return NULL;
2421 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00002422 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002423}
2424
Martin v. Löwis114619e2002-10-07 06:44:21 +00002425#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
2426static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00002427free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00002428{
Martin v. Löwis725507b2006-03-07 12:08:51 +00002429 Py_ssize_t i;
Martin v. Löwis114619e2002-10-07 06:44:21 +00002430 for (i = 0; i < count; i++)
2431 PyMem_Free(array[i]);
2432 PyMem_DEL(array);
2433}
2434#endif
2435
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002436
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002437#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002438PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002439"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002440Execute an executable path with arguments, replacing current process.\n\
2441\n\
2442 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002443 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002444
Barry Warsaw53699e91996-12-10 23:23:01 +00002445static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002446posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002447{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002448 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002449 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002450 char **argvlist;
Martin v. Löwis725507b2006-03-07 12:08:51 +00002451 Py_ssize_t i, argc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002452 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002453
Guido van Rossum89b33251993-10-22 14:26:06 +00002454 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00002455 argv is a list or tuple of strings. */
2456
Martin v. Löwis114619e2002-10-07 06:44:21 +00002457 if (!PyArg_ParseTuple(args, "etO:execv",
2458 Py_FileSystemDefaultEncoding,
2459 &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002460 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002461 if (PyList_Check(argv)) {
2462 argc = PyList_Size(argv);
2463 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002464 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002465 else if (PyTuple_Check(argv)) {
2466 argc = PyTuple_Size(argv);
2467 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002468 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002469 else {
Fred Drake661ea262000-10-24 19:57:45 +00002470 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002471 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002472 return NULL;
2473 }
2474
Barry Warsaw53699e91996-12-10 23:23:01 +00002475 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002476 if (argvlist == NULL) {
2477 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002478 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002479 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002480 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002481 if (!PyArg_Parse((*getitem)(argv, i), "et",
2482 Py_FileSystemDefaultEncoding,
2483 &argvlist[i])) {
2484 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00002485 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002486 "execv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002487 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002488 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00002489
Guido van Rossum85e3b011991-06-03 12:42:10 +00002490 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002491 }
2492 argvlist[argc] = NULL;
2493
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002494 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002495
Guido van Rossum85e3b011991-06-03 12:42:10 +00002496 /* If we get here it's definitely an error */
2497
Martin v. Löwis114619e2002-10-07 06:44:21 +00002498 free_string_array(argvlist, argc);
2499 PyMem_Free(path);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002500 return posix_error();
2501}
2502
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002503
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002504PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002505"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002506Execute a path with arguments and environment, replacing current process.\n\
2507\n\
2508 path: path of executable file\n\
2509 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002510 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002511
Barry Warsaw53699e91996-12-10 23:23:01 +00002512static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002513posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002514{
2515 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002516 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002517 char **argvlist;
2518 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002519 PyObject *key, *val, *keys=NULL, *vals=NULL;
Martin v. Löwis725507b2006-03-07 12:08:51 +00002520 Py_ssize_t i, pos, argc, envc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002521 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Martin v. Löwis26fd9602006-04-22 11:15:41 +00002522 Py_ssize_t lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002523
2524 /* execve has three arguments: (path, argv, env), where
2525 argv is a list or tuple of strings and env is a dictionary
2526 like posix.environ. */
2527
Martin v. Löwis114619e2002-10-07 06:44:21 +00002528 if (!PyArg_ParseTuple(args, "etOO:execve",
2529 Py_FileSystemDefaultEncoding,
2530 &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002531 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002532 if (PyList_Check(argv)) {
2533 argc = PyList_Size(argv);
2534 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002535 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002536 else if (PyTuple_Check(argv)) {
2537 argc = PyTuple_Size(argv);
2538 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002539 }
2540 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002541 PyErr_SetString(PyExc_TypeError,
2542 "execve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002543 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002544 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002545 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002546 PyErr_SetString(PyExc_TypeError,
2547 "execve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002548 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002549 }
2550
Barry Warsaw53699e91996-12-10 23:23:01 +00002551 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002552 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002553 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002554 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002555 }
2556 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002557 if (!PyArg_Parse((*getitem)(argv, i),
Martin v. Löwis114619e2002-10-07 06:44:21 +00002558 "et;execve() arg 2 must contain only strings",
Guido van Rossum1e700d22002-10-16 16:52:11 +00002559 Py_FileSystemDefaultEncoding,
Barry Warsaw43d68b81996-12-19 22:10:44 +00002560 &argvlist[i]))
2561 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002562 lastarg = i;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002563 goto fail_1;
2564 }
2565 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002566 lastarg = argc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002567 argvlist[argc] = NULL;
2568
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002569 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002570 if (i < 0)
2571 goto fail_1;
Barry Warsaw53699e91996-12-10 23:23:01 +00002572 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002573 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002574 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002575 goto fail_1;
2576 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002577 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002578 keys = PyMapping_Keys(env);
2579 vals = PyMapping_Values(env);
2580 if (!keys || !vals)
2581 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002582 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2583 PyErr_SetString(PyExc_TypeError,
2584 "execve(): env.keys() or env.values() is not a list");
2585 goto fail_2;
2586 }
Tim Peters5aa91602002-01-30 05:46:57 +00002587
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002588 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002589 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002590 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002591
2592 key = PyList_GetItem(keys, pos);
2593 val = PyList_GetItem(vals, pos);
2594 if (!key || !val)
2595 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002596
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002597 if (!PyArg_Parse(
2598 key,
2599 "s;execve() arg 3 contains a non-string key",
2600 &k) ||
2601 !PyArg_Parse(
2602 val,
2603 "s;execve() arg 3 contains a non-string value",
2604 &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00002605 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002606 goto fail_2;
2607 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00002608
2609#if defined(PYOS_OS2)
2610 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
2611 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
2612#endif
Tim Petersc8996f52001-12-03 20:41:00 +00002613 len = PyString_Size(key) + PyString_Size(val) + 2;
2614 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002615 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002616 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002617 goto fail_2;
2618 }
Tim Petersc8996f52001-12-03 20:41:00 +00002619 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002620 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00002621#if defined(PYOS_OS2)
2622 }
2623#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002624 }
2625 envlist[envc] = 0;
2626
2627 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00002628
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002629 /* If we get here it's definitely an error */
2630
2631 (void) posix_error();
2632
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002633 fail_2:
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002634 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00002635 PyMem_DEL(envlist[envc]);
2636 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002637 fail_1:
2638 free_string_array(argvlist, lastarg);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002639 Py_XDECREF(vals);
2640 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002641 fail_0:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002642 PyMem_Free(path);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002643 return NULL;
2644}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002645#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002646
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002647
Guido van Rossuma1065681999-01-25 23:20:23 +00002648#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002649PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002650"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002651Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002652\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002653 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002654 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002655 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002656
2657static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002658posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002659{
2660 char *path;
2661 PyObject *argv;
2662 char **argvlist;
Martin v. Löwis26fd9602006-04-22 11:15:41 +00002663 int mode, i;
2664 Py_ssize_t argc;
Tim Peters79248aa2001-08-29 21:37:10 +00002665 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002666 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00002667
2668 /* spawnv has three arguments: (mode, path, argv), where
2669 argv is a list or tuple of strings. */
2670
Martin v. Löwis114619e2002-10-07 06:44:21 +00002671 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
2672 Py_FileSystemDefaultEncoding,
2673 &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00002674 return NULL;
2675 if (PyList_Check(argv)) {
2676 argc = PyList_Size(argv);
2677 getitem = PyList_GetItem;
2678 }
2679 else if (PyTuple_Check(argv)) {
2680 argc = PyTuple_Size(argv);
2681 getitem = PyTuple_GetItem;
2682 }
2683 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002684 PyErr_SetString(PyExc_TypeError,
2685 "spawnv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002686 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002687 return NULL;
2688 }
2689
2690 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002691 if (argvlist == NULL) {
2692 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002693 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002694 }
Guido van Rossuma1065681999-01-25 23:20:23 +00002695 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002696 if (!PyArg_Parse((*getitem)(argv, i), "et",
2697 Py_FileSystemDefaultEncoding,
2698 &argvlist[i])) {
2699 free_string_array(argvlist, i);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002700 PyErr_SetString(
2701 PyExc_TypeError,
2702 "spawnv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002703 PyMem_Free(path);
Fred Drake137507e2000-06-01 02:02:46 +00002704 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00002705 }
2706 }
2707 argvlist[argc] = NULL;
2708
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002709#if defined(PYOS_OS2) && defined(PYCC_GCC)
2710 Py_BEGIN_ALLOW_THREADS
2711 spawnval = spawnv(mode, path, argvlist);
2712 Py_END_ALLOW_THREADS
2713#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002714 if (mode == _OLD_P_OVERLAY)
2715 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00002716
Tim Peters25059d32001-12-07 20:35:43 +00002717 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002718 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00002719 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002720#endif
Tim Peters5aa91602002-01-30 05:46:57 +00002721
Martin v. Löwis114619e2002-10-07 06:44:21 +00002722 free_string_array(argvlist, argc);
2723 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002724
Fred Drake699f3522000-06-29 21:12:41 +00002725 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002726 return posix_error();
2727 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002728#if SIZEOF_LONG == SIZEOF_VOID_P
2729 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002730#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00002731 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002732#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002733}
2734
2735
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002736PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002737"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002738Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002739\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002740 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002741 path: path of executable file\n\
2742 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002743 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002744
2745static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002746posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002747{
2748 char *path;
2749 PyObject *argv, *env;
2750 char **argvlist;
2751 char **envlist;
2752 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
Martin v. Löwis26fd9602006-04-22 11:15:41 +00002753 int mode, pos, envc;
2754 Py_ssize_t argc, i;
Tim Peters79248aa2001-08-29 21:37:10 +00002755 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002756 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Martin v. Löwis26fd9602006-04-22 11:15:41 +00002757 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002758
2759 /* spawnve has four arguments: (mode, path, argv, env), where
2760 argv is a list or tuple of strings and env is a dictionary
2761 like posix.environ. */
2762
Martin v. Löwis114619e2002-10-07 06:44:21 +00002763 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
2764 Py_FileSystemDefaultEncoding,
2765 &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00002766 return NULL;
2767 if (PyList_Check(argv)) {
2768 argc = PyList_Size(argv);
2769 getitem = PyList_GetItem;
2770 }
2771 else if (PyTuple_Check(argv)) {
2772 argc = PyTuple_Size(argv);
2773 getitem = PyTuple_GetItem;
2774 }
2775 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002776 PyErr_SetString(PyExc_TypeError,
2777 "spawnve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002778 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002779 }
2780 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002781 PyErr_SetString(PyExc_TypeError,
2782 "spawnve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002783 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002784 }
2785
2786 argvlist = PyMem_NEW(char *, argc+1);
2787 if (argvlist == NULL) {
2788 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002789 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002790 }
2791 for (i = 0; i < argc; i++) {
2792 if (!PyArg_Parse((*getitem)(argv, i),
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002793 "et;spawnve() arg 2 must contain only strings",
Martin v. Löwis114619e2002-10-07 06:44:21 +00002794 Py_FileSystemDefaultEncoding,
Guido van Rossuma1065681999-01-25 23:20:23 +00002795 &argvlist[i]))
2796 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002797 lastarg = i;
Guido van Rossuma1065681999-01-25 23:20:23 +00002798 goto fail_1;
2799 }
2800 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002801 lastarg = argc;
Guido van Rossuma1065681999-01-25 23:20:23 +00002802 argvlist[argc] = NULL;
2803
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002804 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002805 if (i < 0)
2806 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00002807 envlist = PyMem_NEW(char *, i + 1);
2808 if (envlist == NULL) {
2809 PyErr_NoMemory();
2810 goto fail_1;
2811 }
2812 envc = 0;
2813 keys = PyMapping_Keys(env);
2814 vals = PyMapping_Values(env);
2815 if (!keys || !vals)
2816 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002817 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2818 PyErr_SetString(PyExc_TypeError,
2819 "spawnve(): env.keys() or env.values() is not a list");
2820 goto fail_2;
2821 }
Tim Peters5aa91602002-01-30 05:46:57 +00002822
Guido van Rossuma1065681999-01-25 23:20:23 +00002823 for (pos = 0; pos < i; pos++) {
2824 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002825 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00002826
2827 key = PyList_GetItem(keys, pos);
2828 val = PyList_GetItem(vals, pos);
2829 if (!key || !val)
2830 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002831
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002832 if (!PyArg_Parse(
2833 key,
2834 "s;spawnve() arg 3 contains a non-string key",
2835 &k) ||
2836 !PyArg_Parse(
2837 val,
2838 "s;spawnve() arg 3 contains a non-string value",
2839 &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00002840 {
2841 goto fail_2;
2842 }
Tim Petersc8996f52001-12-03 20:41:00 +00002843 len = PyString_Size(key) + PyString_Size(val) + 2;
2844 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00002845 if (p == NULL) {
2846 PyErr_NoMemory();
2847 goto fail_2;
2848 }
Tim Petersc8996f52001-12-03 20:41:00 +00002849 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00002850 envlist[envc++] = p;
2851 }
2852 envlist[envc] = 0;
2853
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002854#if defined(PYOS_OS2) && defined(PYCC_GCC)
2855 Py_BEGIN_ALLOW_THREADS
2856 spawnval = spawnve(mode, path, argvlist, envlist);
2857 Py_END_ALLOW_THREADS
2858#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002859 if (mode == _OLD_P_OVERLAY)
2860 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00002861
2862 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002863 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00002864 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002865#endif
Tim Peters25059d32001-12-07 20:35:43 +00002866
Fred Drake699f3522000-06-29 21:12:41 +00002867 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002868 (void) posix_error();
2869 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002870#if SIZEOF_LONG == SIZEOF_VOID_P
2871 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002872#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00002873 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002874#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002875
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002876 fail_2:
Guido van Rossuma1065681999-01-25 23:20:23 +00002877 while (--envc >= 0)
2878 PyMem_DEL(envlist[envc]);
2879 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002880 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002881 free_string_array(argvlist, lastarg);
Guido van Rossuma1065681999-01-25 23:20:23 +00002882 Py_XDECREF(vals);
2883 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002884 fail_0:
2885 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002886 return res;
2887}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00002888
2889/* OS/2 supports spawnvp & spawnvpe natively */
2890#if defined(PYOS_OS2)
2891PyDoc_STRVAR(posix_spawnvp__doc__,
2892"spawnvp(mode, file, args)\n\n\
2893Execute the program 'file' in a new process, using the environment\n\
2894search path to find the file.\n\
2895\n\
2896 mode: mode of process creation\n\
2897 file: executable file name\n\
2898 args: tuple or list of strings");
2899
2900static PyObject *
2901posix_spawnvp(PyObject *self, PyObject *args)
2902{
2903 char *path;
2904 PyObject *argv;
2905 char **argvlist;
2906 int mode, i, argc;
2907 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002908 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00002909
2910 /* spawnvp has three arguments: (mode, path, argv), where
2911 argv is a list or tuple of strings. */
2912
2913 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
2914 Py_FileSystemDefaultEncoding,
2915 &path, &argv))
2916 return NULL;
2917 if (PyList_Check(argv)) {
2918 argc = PyList_Size(argv);
2919 getitem = PyList_GetItem;
2920 }
2921 else if (PyTuple_Check(argv)) {
2922 argc = PyTuple_Size(argv);
2923 getitem = PyTuple_GetItem;
2924 }
2925 else {
2926 PyErr_SetString(PyExc_TypeError,
2927 "spawnvp() arg 2 must be a tuple or list");
2928 PyMem_Free(path);
2929 return NULL;
2930 }
2931
2932 argvlist = PyMem_NEW(char *, argc+1);
2933 if (argvlist == NULL) {
2934 PyMem_Free(path);
2935 return PyErr_NoMemory();
2936 }
2937 for (i = 0; i < argc; i++) {
2938 if (!PyArg_Parse((*getitem)(argv, i), "et",
2939 Py_FileSystemDefaultEncoding,
2940 &argvlist[i])) {
2941 free_string_array(argvlist, i);
2942 PyErr_SetString(
2943 PyExc_TypeError,
2944 "spawnvp() arg 2 must contain only strings");
2945 PyMem_Free(path);
2946 return NULL;
2947 }
2948 }
2949 argvlist[argc] = NULL;
2950
2951 Py_BEGIN_ALLOW_THREADS
2952#if defined(PYCC_GCC)
2953 spawnval = spawnvp(mode, path, argvlist);
2954#else
2955 spawnval = _spawnvp(mode, path, argvlist);
2956#endif
2957 Py_END_ALLOW_THREADS
2958
2959 free_string_array(argvlist, argc);
2960 PyMem_Free(path);
2961
2962 if (spawnval == -1)
2963 return posix_error();
2964 else
2965 return Py_BuildValue("l", (long) spawnval);
2966}
2967
2968
2969PyDoc_STRVAR(posix_spawnvpe__doc__,
2970"spawnvpe(mode, file, args, env)\n\n\
2971Execute the program 'file' in a new process, using the environment\n\
2972search path to find the file.\n\
2973\n\
2974 mode: mode of process creation\n\
2975 file: executable file name\n\
2976 args: tuple or list of arguments\n\
2977 env: dictionary of strings mapping to strings");
2978
2979static PyObject *
2980posix_spawnvpe(PyObject *self, PyObject *args)
2981{
2982 char *path;
2983 PyObject *argv, *env;
2984 char **argvlist;
2985 char **envlist;
2986 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
2987 int mode, i, pos, argc, envc;
2988 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002989 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00002990 int lastarg = 0;
2991
2992 /* spawnvpe has four arguments: (mode, path, argv, env), where
2993 argv is a list or tuple of strings and env is a dictionary
2994 like posix.environ. */
2995
2996 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
2997 Py_FileSystemDefaultEncoding,
2998 &path, &argv, &env))
2999 return NULL;
3000 if (PyList_Check(argv)) {
3001 argc = PyList_Size(argv);
3002 getitem = PyList_GetItem;
3003 }
3004 else if (PyTuple_Check(argv)) {
3005 argc = PyTuple_Size(argv);
3006 getitem = PyTuple_GetItem;
3007 }
3008 else {
3009 PyErr_SetString(PyExc_TypeError,
3010 "spawnvpe() arg 2 must be a tuple or list");
3011 goto fail_0;
3012 }
3013 if (!PyMapping_Check(env)) {
3014 PyErr_SetString(PyExc_TypeError,
3015 "spawnvpe() arg 3 must be a mapping object");
3016 goto fail_0;
3017 }
3018
3019 argvlist = PyMem_NEW(char *, argc+1);
3020 if (argvlist == NULL) {
3021 PyErr_NoMemory();
3022 goto fail_0;
3023 }
3024 for (i = 0; i < argc; i++) {
3025 if (!PyArg_Parse((*getitem)(argv, i),
3026 "et;spawnvpe() arg 2 must contain only strings",
3027 Py_FileSystemDefaultEncoding,
3028 &argvlist[i]))
3029 {
3030 lastarg = i;
3031 goto fail_1;
3032 }
3033 }
3034 lastarg = argc;
3035 argvlist[argc] = NULL;
3036
3037 i = PyMapping_Size(env);
3038 if (i < 0)
3039 goto fail_1;
3040 envlist = PyMem_NEW(char *, i + 1);
3041 if (envlist == NULL) {
3042 PyErr_NoMemory();
3043 goto fail_1;
3044 }
3045 envc = 0;
3046 keys = PyMapping_Keys(env);
3047 vals = PyMapping_Values(env);
3048 if (!keys || !vals)
3049 goto fail_2;
3050 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3051 PyErr_SetString(PyExc_TypeError,
3052 "spawnvpe(): env.keys() or env.values() is not a list");
3053 goto fail_2;
3054 }
3055
3056 for (pos = 0; pos < i; pos++) {
3057 char *p, *k, *v;
3058 size_t len;
3059
3060 key = PyList_GetItem(keys, pos);
3061 val = PyList_GetItem(vals, pos);
3062 if (!key || !val)
3063 goto fail_2;
3064
3065 if (!PyArg_Parse(
3066 key,
3067 "s;spawnvpe() arg 3 contains a non-string key",
3068 &k) ||
3069 !PyArg_Parse(
3070 val,
3071 "s;spawnvpe() arg 3 contains a non-string value",
3072 &v))
3073 {
3074 goto fail_2;
3075 }
3076 len = PyString_Size(key) + PyString_Size(val) + 2;
3077 p = PyMem_NEW(char, len);
3078 if (p == NULL) {
3079 PyErr_NoMemory();
3080 goto fail_2;
3081 }
3082 PyOS_snprintf(p, len, "%s=%s", k, v);
3083 envlist[envc++] = p;
3084 }
3085 envlist[envc] = 0;
3086
3087 Py_BEGIN_ALLOW_THREADS
3088#if defined(PYCC_GCC)
3089 spawnval = spawnve(mode, path, argvlist, envlist);
3090#else
3091 spawnval = _spawnve(mode, path, argvlist, envlist);
3092#endif
3093 Py_END_ALLOW_THREADS
3094
3095 if (spawnval == -1)
3096 (void) posix_error();
3097 else
3098 res = Py_BuildValue("l", (long) spawnval);
3099
3100 fail_2:
3101 while (--envc >= 0)
3102 PyMem_DEL(envlist[envc]);
3103 PyMem_DEL(envlist);
3104 fail_1:
3105 free_string_array(argvlist, lastarg);
3106 Py_XDECREF(vals);
3107 Py_XDECREF(keys);
3108 fail_0:
3109 PyMem_Free(path);
3110 return res;
3111}
3112#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003113#endif /* HAVE_SPAWNV */
3114
3115
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003116#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003117PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003118"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003119Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3120\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003121Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003122
3123static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003124posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003125{
Neal Norwitze241ce82003-02-17 18:17:05 +00003126 int pid = fork1();
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003127 if (pid == -1)
3128 return posix_error();
3129 PyOS_AfterFork();
3130 return PyInt_FromLong((long)pid);
3131}
3132#endif
3133
3134
Guido van Rossumad0ee831995-03-01 10:34:45 +00003135#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003136PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003137"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003138Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003139Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003140
Barry Warsaw53699e91996-12-10 23:23:01 +00003141static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003142posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003143{
Neal Norwitze241ce82003-02-17 18:17:05 +00003144 int pid = fork();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003145 if (pid == -1)
3146 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003147 if (pid == 0)
3148 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00003149 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003150}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003151#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003152
Neal Norwitzb59798b2003-03-21 01:43:31 +00003153/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00003154/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3155#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00003156#define DEV_PTY_FILE "/dev/ptc"
3157#define HAVE_DEV_PTMX
3158#else
3159#define DEV_PTY_FILE "/dev/ptmx"
3160#endif
3161
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003162#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003163#ifdef HAVE_PTY_H
3164#include <pty.h>
3165#else
3166#ifdef HAVE_LIBUTIL_H
3167#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00003168#endif /* HAVE_LIBUTIL_H */
3169#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00003170#ifdef HAVE_STROPTS_H
3171#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003172#endif
3173#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003174
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003175#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003176PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003177"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003178Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003179
3180static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003181posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003182{
3183 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003184#ifndef HAVE_OPENPTY
3185 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003186#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003187#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003188 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003189#ifdef sun
Neal Norwitz84a98e02006-04-10 07:44:23 +00003190 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003191#endif
3192#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00003193
Thomas Wouters70c21a12000-07-14 14:28:33 +00003194#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00003195 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
3196 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003197#elif defined(HAVE__GETPTY)
Thomas Wouters70c21a12000-07-14 14:28:33 +00003198 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
3199 if (slave_name == NULL)
3200 return posix_error();
3201
3202 slave_fd = open(slave_name, O_RDWR);
3203 if (slave_fd < 0)
3204 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003205#else
Neal Norwitzb59798b2003-03-21 01:43:31 +00003206 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003207 if (master_fd < 0)
3208 return posix_error();
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003209 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003210 /* change permission of slave */
3211 if (grantpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003212 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003213 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003214 }
3215 /* unlock slave */
3216 if (unlockpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003217 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003218 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003219 }
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003220 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003221 slave_name = ptsname(master_fd); /* get name of slave */
3222 if (slave_name == NULL)
3223 return posix_error();
3224 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
3225 if (slave_fd < 0)
3226 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003227#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003228 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
3229 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00003230#ifndef __hpux
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003231 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00003232#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003233#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00003234#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00003235
Fred Drake8cef4cf2000-06-28 16:40:38 +00003236 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00003237
Fred Drake8cef4cf2000-06-28 16:40:38 +00003238}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003239#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003240
3241#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003242PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003243"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00003244Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
3245Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003246To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003247
3248static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003249posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003250{
Neal Norwitz24b3c222005-09-19 06:43:44 +00003251 int master_fd = -1, pid;
Tim Peters5aa91602002-01-30 05:46:57 +00003252
Fred Drake8cef4cf2000-06-28 16:40:38 +00003253 pid = forkpty(&master_fd, NULL, NULL, NULL);
3254 if (pid == -1)
3255 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003256 if (pid == 0)
3257 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00003258 return Py_BuildValue("(ii)", pid, master_fd);
3259}
3260#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003261
Guido van Rossumad0ee831995-03-01 10:34:45 +00003262#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003263PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003264"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003265Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003266
Barry Warsaw53699e91996-12-10 23:23:01 +00003267static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003268posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003269{
Barry Warsaw53699e91996-12-10 23:23:01 +00003270 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003271}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003272#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003273
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003274
Guido van Rossumad0ee831995-03-01 10:34:45 +00003275#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003276PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003277"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003278Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003279
Barry Warsaw53699e91996-12-10 23:23:01 +00003280static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003281posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003282{
Barry Warsaw53699e91996-12-10 23:23:01 +00003283 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003284}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003285#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003286
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003287
Guido van Rossumad0ee831995-03-01 10:34:45 +00003288#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003289PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003290"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003291Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003292
Barry Warsaw53699e91996-12-10 23:23:01 +00003293static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003294posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003295{
Barry Warsaw53699e91996-12-10 23:23:01 +00003296 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003297}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003298#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003299
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003300
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003301PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003302"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003303Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003304
Barry Warsaw53699e91996-12-10 23:23:01 +00003305static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003306posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003307{
Barry Warsaw53699e91996-12-10 23:23:01 +00003308 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003309}
3310
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003311
Fred Drakec9680921999-12-13 16:37:25 +00003312#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003313PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003314"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003315Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00003316
3317static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003318posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00003319{
3320 PyObject *result = NULL;
3321
Fred Drakec9680921999-12-13 16:37:25 +00003322#ifdef NGROUPS_MAX
3323#define MAX_GROUPS NGROUPS_MAX
3324#else
3325 /* defined to be 16 on Solaris7, so this should be a small number */
3326#define MAX_GROUPS 64
3327#endif
3328 gid_t grouplist[MAX_GROUPS];
3329 int n;
3330
3331 n = getgroups(MAX_GROUPS, grouplist);
3332 if (n < 0)
3333 posix_error();
3334 else {
3335 result = PyList_New(n);
3336 if (result != NULL) {
Fred Drakec9680921999-12-13 16:37:25 +00003337 int i;
3338 for (i = 0; i < n; ++i) {
Neal Norwitze241ce82003-02-17 18:17:05 +00003339 PyObject *o = PyInt_FromLong((long)grouplist[i]);
Fred Drakec9680921999-12-13 16:37:25 +00003340 if (o == NULL) {
3341 Py_DECREF(result);
3342 result = NULL;
3343 break;
3344 }
3345 PyList_SET_ITEM(result, i, o);
3346 }
3347 }
3348 }
Neal Norwitze241ce82003-02-17 18:17:05 +00003349
Fred Drakec9680921999-12-13 16:37:25 +00003350 return result;
3351}
3352#endif
3353
Martin v. Löwis606edc12002-06-13 21:09:11 +00003354#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003355PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003356"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003357Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00003358
3359static PyObject *
3360posix_getpgid(PyObject *self, PyObject *args)
3361{
3362 int pid, pgid;
3363 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
3364 return NULL;
3365 pgid = getpgid(pid);
3366 if (pgid < 0)
3367 return posix_error();
3368 return PyInt_FromLong((long)pgid);
3369}
3370#endif /* HAVE_GETPGID */
3371
3372
Guido van Rossumb6775db1994-08-01 11:34:53 +00003373#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003374PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003375"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003376Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003377
Barry Warsaw53699e91996-12-10 23:23:01 +00003378static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003379posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00003380{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003381#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00003382 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003383#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00003384 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003385#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00003386}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003387#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00003388
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003389
Guido van Rossumb6775db1994-08-01 11:34:53 +00003390#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003391PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003392"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003393Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003394
Barry Warsaw53699e91996-12-10 23:23:01 +00003395static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003396posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003397{
Guido van Rossum64933891994-10-20 21:56:42 +00003398#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00003399 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003400#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003401 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003402#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00003403 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003404 Py_INCREF(Py_None);
3405 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003406}
3407
Guido van Rossumb6775db1994-08-01 11:34:53 +00003408#endif /* HAVE_SETPGRP */
3409
Guido van Rossumad0ee831995-03-01 10:34:45 +00003410#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003411PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003412"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003413Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003414
Barry Warsaw53699e91996-12-10 23:23:01 +00003415static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003416posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003417{
Barry Warsaw53699e91996-12-10 23:23:01 +00003418 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003419}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003420#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003421
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003422
Fred Drake12c6e2d1999-12-14 21:25:03 +00003423#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003424PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003425"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003426Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00003427
3428static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003429posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00003430{
Neal Norwitze241ce82003-02-17 18:17:05 +00003431 PyObject *result = NULL;
Fred Drakea30680b2000-12-06 21:24:28 +00003432 char *name;
3433 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00003434
Fred Drakea30680b2000-12-06 21:24:28 +00003435 errno = 0;
3436 name = getlogin();
3437 if (name == NULL) {
3438 if (errno)
3439 posix_error();
3440 else
3441 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00003442 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00003443 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00003444 else
3445 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00003446 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00003447
Fred Drake12c6e2d1999-12-14 21:25:03 +00003448 return result;
3449}
3450#endif
3451
Guido van Rossumad0ee831995-03-01 10:34:45 +00003452#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003453PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003454"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003455Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003456
Barry Warsaw53699e91996-12-10 23:23:01 +00003457static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003458posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003459{
Barry Warsaw53699e91996-12-10 23:23:01 +00003460 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003461}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003462#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003463
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003464
Guido van Rossumad0ee831995-03-01 10:34:45 +00003465#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003466PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003467"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003468Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003469
Barry Warsaw53699e91996-12-10 23:23:01 +00003470static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003471posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003472{
3473 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003474 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00003475 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003476#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003477 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
3478 APIRET rc;
3479 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003480 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003481
3482 } else if (sig == XCPT_SIGNAL_KILLPROC) {
3483 APIRET rc;
3484 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003485 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003486
3487 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003488 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003489#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00003490 if (kill(pid, sig) == -1)
3491 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003492#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003493 Py_INCREF(Py_None);
3494 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003495}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003496#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003497
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003498#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003499PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003500"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003501Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003502
3503static PyObject *
3504posix_killpg(PyObject *self, PyObject *args)
3505{
3506 int pgid, sig;
3507 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
3508 return NULL;
3509 if (killpg(pgid, sig) == -1)
3510 return posix_error();
3511 Py_INCREF(Py_None);
3512 return Py_None;
3513}
3514#endif
3515
Guido van Rossumc0125471996-06-28 18:55:32 +00003516#ifdef HAVE_PLOCK
3517
3518#ifdef HAVE_SYS_LOCK_H
3519#include <sys/lock.h>
3520#endif
3521
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003522PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003523"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003524Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003525
Barry Warsaw53699e91996-12-10 23:23:01 +00003526static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003527posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00003528{
3529 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003530 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00003531 return NULL;
3532 if (plock(op) == -1)
3533 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003534 Py_INCREF(Py_None);
3535 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00003536}
3537#endif
3538
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003539
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003540#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003541PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003542"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003543Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003544
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003545#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003546#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003547static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003548async_system(const char *command)
3549{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003550 char errormsg[256], args[1024];
3551 RESULTCODES rcodes;
3552 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003553
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003554 char *shell = getenv("COMSPEC");
3555 if (!shell)
3556 shell = "cmd";
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003557
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003558 /* avoid overflowing the argument buffer */
3559 if (strlen(shell) + 3 + strlen(command) >= 1024)
3560 return ERROR_NOT_ENOUGH_MEMORY
3561
3562 args[0] = '\0';
3563 strcat(args, shell);
3564 strcat(args, "/c ");
3565 strcat(args, command);
3566
3567 /* execute asynchronously, inheriting the environment */
3568 rc = DosExecPgm(errormsg,
3569 sizeof(errormsg),
3570 EXEC_ASYNC,
3571 args,
3572 NULL,
3573 &rcodes,
3574 shell);
3575 return rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003576}
3577
Guido van Rossumd48f2521997-12-05 22:19:34 +00003578static FILE *
3579popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003580{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003581 int oldfd, tgtfd;
3582 HFILE pipeh[2];
3583 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003584
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003585 /* mode determines which of stdin or stdout is reconnected to
3586 * the pipe to the child
3587 */
3588 if (strchr(mode, 'r') != NULL) {
3589 tgt_fd = 1; /* stdout */
3590 } else if (strchr(mode, 'w')) {
3591 tgt_fd = 0; /* stdin */
3592 } else {
3593 *err = ERROR_INVALID_ACCESS;
3594 return NULL;
3595 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003596
Andrew MacIntyrea3be2582004-12-18 09:51:05 +00003597 /* setup the pipe */
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003598 if ((rc = DosCreatePipe(&pipeh[0], &pipeh[1], pipesize)) != NO_ERROR) {
3599 *err = rc;
3600 return NULL;
3601 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003602
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003603 /* prevent other threads accessing stdio */
3604 DosEnterCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003605
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003606 /* reconnect stdio and execute child */
3607 oldfd = dup(tgtfd);
3608 close(tgtfd);
3609 if (dup2(pipeh[tgtfd], tgtfd) == 0) {
3610 DosClose(pipeh[tgtfd]);
3611 rc = async_system(command);
3612 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003613
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003614 /* restore stdio */
3615 dup2(oldfd, tgtfd);
3616 close(oldfd);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003617
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003618 /* allow other threads access to stdio */
3619 DosExitCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003620
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003621 /* if execution of child was successful return file stream */
3622 if (rc == NO_ERROR)
3623 return fdopen(pipeh[1 - tgtfd], mode);
3624 else {
3625 DosClose(pipeh[1 - tgtfd]);
3626 *err = rc;
3627 return NULL;
3628 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003629}
3630
3631static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003632posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003633{
3634 char *name;
3635 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00003636 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003637 FILE *fp;
3638 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003639 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003640 return NULL;
3641 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00003642 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003643 Py_END_ALLOW_THREADS
3644 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003645 return os2_error(err);
3646
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003647 f = PyFile_FromFile(fp, name, mode, fclose);
3648 if (f != NULL)
3649 PyFile_SetBufSize(f, bufsize);
3650 return f;
3651}
3652
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003653#elif defined(PYCC_GCC)
3654
3655/* standard posix version of popen() support */
3656static PyObject *
3657posix_popen(PyObject *self, PyObject *args)
3658{
3659 char *name;
3660 char *mode = "r";
3661 int bufsize = -1;
3662 FILE *fp;
3663 PyObject *f;
3664 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
3665 return NULL;
3666 Py_BEGIN_ALLOW_THREADS
3667 fp = popen(name, mode);
3668 Py_END_ALLOW_THREADS
3669 if (fp == NULL)
3670 return posix_error();
3671 f = PyFile_FromFile(fp, name, mode, pclose);
3672 if (f != NULL)
3673 PyFile_SetBufSize(f, bufsize);
3674 return f;
3675}
3676
3677/* fork() under OS/2 has lots'o'warts
3678 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
3679 * most of this code is a ripoff of the win32 code, but using the
3680 * capabilities of EMX's C library routines
3681 */
3682
3683/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
3684#define POPEN_1 1
3685#define POPEN_2 2
3686#define POPEN_3 3
3687#define POPEN_4 4
3688
3689static PyObject *_PyPopen(char *, int, int, int);
3690static int _PyPclose(FILE *file);
3691
3692/*
3693 * Internal dictionary mapping popen* file pointers to process handles,
3694 * for use when retrieving the process exit code. See _PyPclose() below
3695 * for more information on this dictionary's use.
3696 */
3697static PyObject *_PyPopenProcs = NULL;
3698
3699/* os2emx version of popen2()
3700 *
3701 * The result of this function is a pipe (file) connected to the
3702 * process's stdin, and a pipe connected to the process's stdout.
3703 */
3704
3705static PyObject *
3706os2emx_popen2(PyObject *self, PyObject *args)
3707{
3708 PyObject *f;
3709 int tm=0;
3710
3711 char *cmdstring;
3712 char *mode = "t";
3713 int bufsize = -1;
3714 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
3715 return NULL;
3716
3717 if (*mode == 't')
3718 tm = O_TEXT;
3719 else if (*mode != 'b') {
3720 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3721 return NULL;
3722 } else
3723 tm = O_BINARY;
3724
3725 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
3726
3727 return f;
3728}
3729
3730/*
3731 * Variation on os2emx.popen2
3732 *
3733 * The result of this function is 3 pipes - the process's stdin,
3734 * stdout and stderr
3735 */
3736
3737static PyObject *
3738os2emx_popen3(PyObject *self, PyObject *args)
3739{
3740 PyObject *f;
3741 int tm = 0;
3742
3743 char *cmdstring;
3744 char *mode = "t";
3745 int bufsize = -1;
3746 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
3747 return NULL;
3748
3749 if (*mode == 't')
3750 tm = O_TEXT;
3751 else if (*mode != 'b') {
3752 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3753 return NULL;
3754 } else
3755 tm = O_BINARY;
3756
3757 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
3758
3759 return f;
3760}
3761
3762/*
3763 * Variation on os2emx.popen2
3764 *
Tim Peters11b23062003-04-23 02:39:17 +00003765 * The result of this function is 2 pipes - the processes stdin,
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003766 * and stdout+stderr combined as a single pipe.
3767 */
3768
3769static PyObject *
3770os2emx_popen4(PyObject *self, PyObject *args)
3771{
3772 PyObject *f;
3773 int tm = 0;
3774
3775 char *cmdstring;
3776 char *mode = "t";
3777 int bufsize = -1;
3778 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
3779 return NULL;
3780
3781 if (*mode == 't')
3782 tm = O_TEXT;
3783 else if (*mode != 'b') {
3784 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3785 return NULL;
3786 } else
3787 tm = O_BINARY;
3788
3789 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
3790
3791 return f;
3792}
3793
3794/* a couple of structures for convenient handling of multiple
3795 * file handles and pipes
3796 */
3797struct file_ref
3798{
3799 int handle;
3800 int flags;
3801};
3802
3803struct pipe_ref
3804{
3805 int rd;
3806 int wr;
3807};
3808
3809/* The following code is derived from the win32 code */
3810
3811static PyObject *
3812_PyPopen(char *cmdstring, int mode, int n, int bufsize)
3813{
3814 struct file_ref stdio[3];
3815 struct pipe_ref p_fd[3];
3816 FILE *p_s[3];
3817 int file_count, i, pipe_err, pipe_pid;
3818 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
3819 PyObject *f, *p_f[3];
3820
3821 /* file modes for subsequent fdopen's on pipe handles */
3822 if (mode == O_TEXT)
3823 {
3824 rd_mode = "rt";
3825 wr_mode = "wt";
3826 }
3827 else
3828 {
3829 rd_mode = "rb";
3830 wr_mode = "wb";
3831 }
3832
3833 /* prepare shell references */
3834 if ((shell = getenv("EMXSHELL")) == NULL)
3835 if ((shell = getenv("COMSPEC")) == NULL)
3836 {
3837 errno = ENOENT;
3838 return posix_error();
3839 }
3840
3841 sh_name = _getname(shell);
3842 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
3843 opt = "/c";
3844 else
3845 opt = "-c";
3846
3847 /* save current stdio fds + their flags, and set not inheritable */
3848 i = pipe_err = 0;
3849 while (pipe_err >= 0 && i < 3)
3850 {
3851 pipe_err = stdio[i].handle = dup(i);
3852 stdio[i].flags = fcntl(i, F_GETFD, 0);
3853 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
3854 i++;
3855 }
3856 if (pipe_err < 0)
3857 {
3858 /* didn't get them all saved - clean up and bail out */
3859 int saved_err = errno;
3860 while (i-- > 0)
3861 {
3862 close(stdio[i].handle);
3863 }
3864 errno = saved_err;
3865 return posix_error();
3866 }
3867
3868 /* create pipe ends */
3869 file_count = 2;
3870 if (n == POPEN_3)
3871 file_count = 3;
3872 i = pipe_err = 0;
3873 while ((pipe_err == 0) && (i < file_count))
3874 pipe_err = pipe((int *)&p_fd[i++]);
3875 if (pipe_err < 0)
3876 {
3877 /* didn't get them all made - clean up and bail out */
3878 while (i-- > 0)
3879 {
3880 close(p_fd[i].wr);
3881 close(p_fd[i].rd);
3882 }
3883 errno = EPIPE;
3884 return posix_error();
3885 }
3886
3887 /* change the actual standard IO streams over temporarily,
3888 * making the retained pipe ends non-inheritable
3889 */
3890 pipe_err = 0;
3891
3892 /* - stdin */
3893 if (dup2(p_fd[0].rd, 0) == 0)
3894 {
3895 close(p_fd[0].rd);
3896 i = fcntl(p_fd[0].wr, F_GETFD, 0);
3897 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
3898 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
3899 {
3900 close(p_fd[0].wr);
3901 pipe_err = -1;
3902 }
3903 }
3904 else
3905 {
3906 pipe_err = -1;
3907 }
3908
3909 /* - stdout */
3910 if (pipe_err == 0)
3911 {
3912 if (dup2(p_fd[1].wr, 1) == 1)
3913 {
3914 close(p_fd[1].wr);
3915 i = fcntl(p_fd[1].rd, F_GETFD, 0);
3916 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
3917 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
3918 {
3919 close(p_fd[1].rd);
3920 pipe_err = -1;
3921 }
3922 }
3923 else
3924 {
3925 pipe_err = -1;
3926 }
3927 }
3928
3929 /* - stderr, as required */
3930 if (pipe_err == 0)
3931 switch (n)
3932 {
3933 case POPEN_3:
3934 {
3935 if (dup2(p_fd[2].wr, 2) == 2)
3936 {
3937 close(p_fd[2].wr);
3938 i = fcntl(p_fd[2].rd, F_GETFD, 0);
3939 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
3940 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
3941 {
3942 close(p_fd[2].rd);
3943 pipe_err = -1;
3944 }
3945 }
3946 else
3947 {
3948 pipe_err = -1;
3949 }
3950 break;
3951 }
3952
3953 case POPEN_4:
3954 {
3955 if (dup2(1, 2) != 2)
3956 {
3957 pipe_err = -1;
3958 }
3959 break;
3960 }
3961 }
3962
3963 /* spawn the child process */
3964 if (pipe_err == 0)
3965 {
3966 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
3967 if (pipe_pid == -1)
3968 {
3969 pipe_err = -1;
3970 }
3971 else
3972 {
3973 /* save the PID into the FILE structure
3974 * NOTE: this implementation doesn't actually
3975 * take advantage of this, but do it for
3976 * completeness - AIM Apr01
3977 */
3978 for (i = 0; i < file_count; i++)
3979 p_s[i]->_pid = pipe_pid;
3980 }
3981 }
3982
3983 /* reset standard IO to normal */
3984 for (i = 0; i < 3; i++)
3985 {
3986 dup2(stdio[i].handle, i);
3987 fcntl(i, F_SETFD, stdio[i].flags);
3988 close(stdio[i].handle);
3989 }
3990
3991 /* if any remnant problems, clean up and bail out */
3992 if (pipe_err < 0)
3993 {
3994 for (i = 0; i < 3; i++)
3995 {
3996 close(p_fd[i].rd);
3997 close(p_fd[i].wr);
3998 }
3999 errno = EPIPE;
4000 return posix_error_with_filename(cmdstring);
4001 }
4002
4003 /* build tuple of file objects to return */
4004 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
4005 PyFile_SetBufSize(p_f[0], bufsize);
4006 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
4007 PyFile_SetBufSize(p_f[1], bufsize);
4008 if (n == POPEN_3)
4009 {
4010 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
4011 PyFile_SetBufSize(p_f[0], bufsize);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004012 f = PyTuple_Pack(3, p_f[0], p_f[1], p_f[2]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004013 }
4014 else
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004015 f = PyTuple_Pack(2, p_f[0], p_f[1]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004016
4017 /*
4018 * Insert the files we've created into the process dictionary
4019 * all referencing the list with the process handle and the
4020 * initial number of files (see description below in _PyPclose).
4021 * Since if _PyPclose later tried to wait on a process when all
4022 * handles weren't closed, it could create a deadlock with the
4023 * child, we spend some energy here to try to ensure that we
4024 * either insert all file handles into the dictionary or none
4025 * at all. It's a little clumsy with the various popen modes
4026 * and variable number of files involved.
4027 */
4028 if (!_PyPopenProcs)
4029 {
4030 _PyPopenProcs = PyDict_New();
4031 }
4032
4033 if (_PyPopenProcs)
4034 {
4035 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
4036 int ins_rc[3];
4037
4038 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4039 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4040
4041 procObj = PyList_New(2);
4042 pidObj = PyInt_FromLong((long) pipe_pid);
4043 intObj = PyInt_FromLong((long) file_count);
4044
4045 if (procObj && pidObj && intObj)
4046 {
4047 PyList_SetItem(procObj, 0, pidObj);
4048 PyList_SetItem(procObj, 1, intObj);
4049
4050 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
4051 if (fileObj[0])
4052 {
4053 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4054 fileObj[0],
4055 procObj);
4056 }
4057 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
4058 if (fileObj[1])
4059 {
4060 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4061 fileObj[1],
4062 procObj);
4063 }
4064 if (file_count >= 3)
4065 {
4066 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
4067 if (fileObj[2])
4068 {
4069 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4070 fileObj[2],
4071 procObj);
4072 }
4073 }
4074
4075 if (ins_rc[0] < 0 || !fileObj[0] ||
4076 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4077 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
4078 {
4079 /* Something failed - remove any dictionary
4080 * entries that did make it.
4081 */
4082 if (!ins_rc[0] && fileObj[0])
4083 {
4084 PyDict_DelItem(_PyPopenProcs,
4085 fileObj[0]);
4086 }
4087 if (!ins_rc[1] && fileObj[1])
4088 {
4089 PyDict_DelItem(_PyPopenProcs,
4090 fileObj[1]);
4091 }
4092 if (!ins_rc[2] && fileObj[2])
4093 {
4094 PyDict_DelItem(_PyPopenProcs,
4095 fileObj[2]);
4096 }
4097 }
4098 }
Tim Peters11b23062003-04-23 02:39:17 +00004099
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004100 /*
4101 * Clean up our localized references for the dictionary keys
4102 * and value since PyDict_SetItem will Py_INCREF any copies
4103 * that got placed in the dictionary.
4104 */
4105 Py_XDECREF(procObj);
4106 Py_XDECREF(fileObj[0]);
4107 Py_XDECREF(fileObj[1]);
4108 Py_XDECREF(fileObj[2]);
4109 }
4110
4111 /* Child is launched. */
4112 return f;
4113}
4114
4115/*
4116 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4117 * exit code for the child process and return as a result of the close.
4118 *
4119 * This function uses the _PyPopenProcs dictionary in order to map the
4120 * input file pointer to information about the process that was
4121 * originally created by the popen* call that created the file pointer.
4122 * The dictionary uses the file pointer as a key (with one entry
4123 * inserted for each file returned by the original popen* call) and a
4124 * single list object as the value for all files from a single call.
4125 * The list object contains the Win32 process handle at [0], and a file
4126 * count at [1], which is initialized to the total number of file
4127 * handles using that list.
4128 *
4129 * This function closes whichever handle it is passed, and decrements
4130 * the file count in the dictionary for the process handle pointed to
4131 * by this file. On the last close (when the file count reaches zero),
4132 * this function will wait for the child process and then return its
4133 * exit code as the result of the close() operation. This permits the
4134 * files to be closed in any order - it is always the close() of the
4135 * final handle that will return the exit code.
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004136 *
4137 * NOTE: This function is currently called with the GIL released.
4138 * hence we use the GILState API to manage our state.
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004139 */
4140
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004141static int _PyPclose(FILE *file)
4142{
4143 int result;
4144 int exit_code;
4145 int pipe_pid;
4146 PyObject *procObj, *pidObj, *intObj, *fileObj;
4147 int file_count;
4148#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004149 PyGILState_STATE state;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004150#endif
4151
4152 /* Close the file handle first, to ensure it can't block the
4153 * child from exiting if it's the last handle.
4154 */
4155 result = fclose(file);
4156
4157#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004158 state = PyGILState_Ensure();
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004159#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004160 if (_PyPopenProcs)
4161 {
4162 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4163 (procObj = PyDict_GetItem(_PyPopenProcs,
4164 fileObj)) != NULL &&
4165 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
4166 (intObj = PyList_GetItem(procObj,1)) != NULL)
4167 {
4168 pipe_pid = (int) PyInt_AsLong(pidObj);
4169 file_count = (int) PyInt_AsLong(intObj);
4170
4171 if (file_count > 1)
4172 {
4173 /* Still other files referencing process */
4174 file_count--;
4175 PyList_SetItem(procObj,1,
4176 PyInt_FromLong((long) file_count));
4177 }
4178 else
4179 {
4180 /* Last file for this process */
4181 if (result != EOF &&
4182 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
4183 {
4184 /* extract exit status */
4185 if (WIFEXITED(exit_code))
4186 {
4187 result = WEXITSTATUS(exit_code);
4188 }
4189 else
4190 {
4191 errno = EPIPE;
4192 result = -1;
4193 }
4194 }
4195 else
4196 {
4197 /* Indicate failure - this will cause the file object
4198 * to raise an I/O error and translate the last
4199 * error code from errno. We do have a problem with
4200 * last errors that overlap the normal errno table,
4201 * but that's a consistent problem with the file object.
4202 */
4203 result = -1;
4204 }
4205 }
4206
4207 /* Remove this file pointer from dictionary */
4208 PyDict_DelItem(_PyPopenProcs, fileObj);
4209
4210 if (PyDict_Size(_PyPopenProcs) == 0)
4211 {
4212 Py_DECREF(_PyPopenProcs);
4213 _PyPopenProcs = NULL;
4214 }
4215
4216 } /* if object retrieval ok */
4217
4218 Py_XDECREF(fileObj);
4219 } /* if _PyPopenProcs */
4220
4221#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004222 PyGILState_Release(state);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004223#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004224 return result;
4225}
4226
4227#endif /* PYCC_??? */
4228
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004229#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004230
4231/*
4232 * Portable 'popen' replacement for Win32.
4233 *
4234 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
4235 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00004236 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004237 */
4238
4239#include <malloc.h>
4240#include <io.h>
4241#include <fcntl.h>
4242
4243/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
4244#define POPEN_1 1
4245#define POPEN_2 2
4246#define POPEN_3 3
4247#define POPEN_4 4
4248
4249static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004250static int _PyPclose(FILE *file);
4251
4252/*
4253 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00004254 * for use when retrieving the process exit code. See _PyPclose() below
4255 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004256 */
4257static PyObject *_PyPopenProcs = NULL;
4258
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004259
4260/* popen that works from a GUI.
4261 *
4262 * The result of this function is a pipe (file) connected to the
4263 * processes stdin or stdout, depending on the requested mode.
4264 */
4265
4266static PyObject *
4267posix_popen(PyObject *self, PyObject *args)
4268{
Raymond Hettingerb5cb6652003-09-01 22:25:41 +00004269 PyObject *f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004270 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004271
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004272 char *cmdstring;
4273 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004274 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004275 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004276 return NULL;
4277
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004278 if (*mode == 'r')
4279 tm = _O_RDONLY;
4280 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00004281 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004282 return NULL;
4283 } else
4284 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00004285
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004286 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004287 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004288 return NULL;
4289 }
4290
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004291 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004292 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004293 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004294 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004295 else
4296 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
4297
4298 return f;
4299}
4300
4301/* Variation on win32pipe.popen
4302 *
4303 * The result of this function is a pipe (file) connected to the
4304 * process's stdin, and a pipe connected to the process's stdout.
4305 */
4306
4307static PyObject *
4308win32_popen2(PyObject *self, PyObject *args)
4309{
4310 PyObject *f;
4311 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00004312
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004313 char *cmdstring;
4314 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004315 int bufsize = -1;
4316 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004317 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004318
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004319 if (*mode == 't')
4320 tm = _O_TEXT;
4321 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004322 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004323 return NULL;
4324 } else
4325 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004326
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004327 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004328 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004329 return NULL;
4330 }
4331
4332 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00004333
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004334 return f;
4335}
4336
4337/*
4338 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004339 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004340 * The result of this function is 3 pipes - the process's stdin,
4341 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004342 */
4343
4344static PyObject *
4345win32_popen3(PyObject *self, PyObject *args)
4346{
4347 PyObject *f;
4348 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004349
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004350 char *cmdstring;
4351 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004352 int bufsize = -1;
4353 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004354 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004355
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004356 if (*mode == 't')
4357 tm = _O_TEXT;
4358 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004359 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004360 return NULL;
4361 } else
4362 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004363
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004364 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004365 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004366 return NULL;
4367 }
4368
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004369 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00004370
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004371 return f;
4372}
4373
4374/*
4375 * Variation on win32pipe.popen
4376 *
Tim Peters5aa91602002-01-30 05:46:57 +00004377 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004378 * and stdout+stderr combined as a single pipe.
4379 */
4380
4381static PyObject *
4382win32_popen4(PyObject *self, PyObject *args)
4383{
4384 PyObject *f;
4385 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004386
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004387 char *cmdstring;
4388 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004389 int bufsize = -1;
4390 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004391 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004392
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004393 if (*mode == 't')
4394 tm = _O_TEXT;
4395 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004396 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004397 return NULL;
4398 } else
4399 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004400
4401 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004402 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004403 return NULL;
4404 }
4405
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004406 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004407
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004408 return f;
4409}
4410
Mark Hammond08501372001-01-31 07:30:29 +00004411static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00004412_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004413 HANDLE hStdin,
4414 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00004415 HANDLE hStderr,
4416 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004417{
4418 PROCESS_INFORMATION piProcInfo;
4419 STARTUPINFO siStartInfo;
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004420 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004421 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00004422 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004423 int i;
Martin v. Löwis18e16552006-02-15 17:27:45 +00004424 Py_ssize_t x;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004425
4426 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00004427 char *comshell;
4428
Tim Peters92e4dd82002-10-05 01:47:34 +00004429 s1 = (char *)alloca(i);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004430 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
Martin v. Löwis18e16552006-02-15 17:27:45 +00004431 /* x < i, so x fits into an integer */
4432 return (int)x;
Tim Peters402d5982001-08-27 06:37:48 +00004433
4434 /* Explicitly check if we are using COMMAND.COM. If we are
4435 * then use the w9xpopen hack.
4436 */
4437 comshell = s1 + x;
4438 while (comshell >= s1 && *comshell != '\\')
4439 --comshell;
4440 ++comshell;
4441
4442 if (GetVersion() < 0x80000000 &&
4443 _stricmp(comshell, "command.com") != 0) {
4444 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004445 x = i + strlen(s3) + strlen(cmdstring) + 1;
Tim Peters92e4dd82002-10-05 01:47:34 +00004446 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004447 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00004448 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004449 }
4450 else {
4451 /*
Tim Peters402d5982001-08-27 06:37:48 +00004452 * Oh gag, we're on Win9x or using COMMAND.COM. Use
4453 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004454 */
Mark Hammond08501372001-01-31 07:30:29 +00004455 char modulepath[_MAX_PATH];
4456 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004457 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
Martin v. Löwis26fd9602006-04-22 11:15:41 +00004458 for (x = i = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004459 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004460 x = i+1;
4461 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00004462 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00004463 strncat(modulepath,
4464 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00004465 (sizeof(modulepath)/sizeof(modulepath[0]))
4466 -strlen(modulepath));
4467 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00004468 /* Eeek - file-not-found - possibly an embedding
4469 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00004470 */
Tim Peters5aa91602002-01-30 05:46:57 +00004471 strncpy(modulepath,
4472 Py_GetExecPrefix(),
Mark Hammond08501372001-01-31 07:30:29 +00004473 sizeof(modulepath)/sizeof(modulepath[0]));
4474 if (modulepath[strlen(modulepath)-1] != '\\')
4475 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00004476 strncat(modulepath,
4477 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00004478 (sizeof(modulepath)/sizeof(modulepath[0]))
4479 -strlen(modulepath));
4480 /* No where else to look - raise an easily identifiable
4481 error, rather than leaving Windows to report
4482 "file not found" - as the user is probably blissfully
4483 unaware this shim EXE is used, and it will confuse them.
4484 (well, it confused me for a while ;-)
4485 */
4486 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00004487 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00004488 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00004489 "for popen to work with your shell "
4490 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00004491 szConsoleSpawn);
4492 return FALSE;
4493 }
4494 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004495 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00004496 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004497 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00004498
Tim Peters92e4dd82002-10-05 01:47:34 +00004499 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004500 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004501 /* To maintain correct argument passing semantics,
4502 we pass the command-line as it stands, and allow
4503 quoting to be applied. w9xpopen.exe will then
4504 use its argv vector, and re-quote the necessary
4505 args for the ultimate child process.
4506 */
Tim Peters75cdad52001-11-28 22:07:30 +00004507 PyOS_snprintf(
4508 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004509 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004510 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004511 s1,
4512 s3,
4513 cmdstring);
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004514 /* Not passing CREATE_NEW_CONSOLE has been known to
Tim Peters11b23062003-04-23 02:39:17 +00004515 cause random failures on win9x. Specifically a
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004516 dialog:
4517 "Your program accessed mem currently in use at xxx"
4518 and a hopeful warning about the stability of your
4519 system.
4520 Cost is Ctrl+C wont kill children, but anyone
4521 who cares can have a go!
4522 */
4523 dwProcessFlags |= CREATE_NEW_CONSOLE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004524 }
4525 }
4526
4527 /* Could be an else here to try cmd.exe / command.com in the path
4528 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00004529 else {
Tim Peters402d5982001-08-27 06:37:48 +00004530 PyErr_SetString(PyExc_RuntimeError,
4531 "Cannot locate a COMSPEC environment variable to "
4532 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00004533 return FALSE;
4534 }
Tim Peters5aa91602002-01-30 05:46:57 +00004535
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004536 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
4537 siStartInfo.cb = sizeof(STARTUPINFO);
4538 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
4539 siStartInfo.hStdInput = hStdin;
4540 siStartInfo.hStdOutput = hStdout;
4541 siStartInfo.hStdError = hStderr;
4542 siStartInfo.wShowWindow = SW_HIDE;
4543
4544 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004545 s2,
4546 NULL,
4547 NULL,
4548 TRUE,
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004549 dwProcessFlags,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004550 NULL,
4551 NULL,
4552 &siStartInfo,
4553 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004554 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004555 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004556
Mark Hammondb37a3732000-08-14 04:47:33 +00004557 /* Return process handle */
4558 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004559 return TRUE;
4560 }
Tim Peters402d5982001-08-27 06:37:48 +00004561 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004562 return FALSE;
4563}
4564
4565/* The following code is based off of KB: Q190351 */
4566
4567static PyObject *
4568_PyPopen(char *cmdstring, int mode, int n)
4569{
4570 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
4571 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00004572 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00004573
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004574 SECURITY_ATTRIBUTES saAttr;
4575 BOOL fSuccess;
4576 int fd1, fd2, fd3;
4577 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00004578 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004579 PyObject *f;
4580
4581 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
4582 saAttr.bInheritHandle = TRUE;
4583 saAttr.lpSecurityDescriptor = NULL;
4584
4585 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
4586 return win32_error("CreatePipe", NULL);
4587
4588 /* Create new output read handle and the input write handle. Set
4589 * the inheritance properties to FALSE. Otherwise, the child inherits
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00004590 * these handles; resulting in non-closeable handles to the pipes
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004591 * being created. */
4592 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004593 GetCurrentProcess(), &hChildStdinWrDup, 0,
4594 FALSE,
4595 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004596 if (!fSuccess)
4597 return win32_error("DuplicateHandle", NULL);
4598
4599 /* Close the inheritable version of ChildStdin
4600 that we're using. */
4601 CloseHandle(hChildStdinWr);
4602
4603 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
4604 return win32_error("CreatePipe", NULL);
4605
4606 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004607 GetCurrentProcess(), &hChildStdoutRdDup, 0,
4608 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004609 if (!fSuccess)
4610 return win32_error("DuplicateHandle", NULL);
4611
4612 /* Close the inheritable version of ChildStdout
4613 that we're using. */
4614 CloseHandle(hChildStdoutRd);
4615
4616 if (n != POPEN_4) {
4617 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
4618 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004619 fSuccess = DuplicateHandle(GetCurrentProcess(),
4620 hChildStderrRd,
4621 GetCurrentProcess(),
4622 &hChildStderrRdDup, 0,
4623 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004624 if (!fSuccess)
4625 return win32_error("DuplicateHandle", NULL);
4626 /* Close the inheritable version of ChildStdErr that we're using. */
4627 CloseHandle(hChildStderrRd);
4628 }
Tim Peters5aa91602002-01-30 05:46:57 +00004629
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004630 switch (n) {
4631 case POPEN_1:
4632 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
4633 case _O_WRONLY | _O_TEXT:
4634 /* Case for writing to child Stdin in text mode. */
Martin v. Löwis18e16552006-02-15 17:27:45 +00004635 fd1 = _open_osfhandle((intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004636 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004637 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004638 PyFile_SetBufSize(f, 0);
4639 /* We don't care about these pipes anymore, so close them. */
4640 CloseHandle(hChildStdoutRdDup);
4641 CloseHandle(hChildStderrRdDup);
4642 break;
4643
4644 case _O_RDONLY | _O_TEXT:
4645 /* Case for reading from child Stdout in text mode. */
Martin v. Löwis18e16552006-02-15 17:27:45 +00004646 fd1 = _open_osfhandle((intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004647 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004648 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004649 PyFile_SetBufSize(f, 0);
4650 /* We don't care about these pipes anymore, so close them. */
4651 CloseHandle(hChildStdinWrDup);
4652 CloseHandle(hChildStderrRdDup);
4653 break;
4654
4655 case _O_RDONLY | _O_BINARY:
4656 /* Case for readinig from child Stdout in binary mode. */
Martin v. Löwis18e16552006-02-15 17:27:45 +00004657 fd1 = _open_osfhandle((intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004658 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004659 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004660 PyFile_SetBufSize(f, 0);
4661 /* We don't care about these pipes anymore, so close them. */
4662 CloseHandle(hChildStdinWrDup);
4663 CloseHandle(hChildStderrRdDup);
4664 break;
4665
4666 case _O_WRONLY | _O_BINARY:
4667 /* Case for writing to child Stdin in binary mode. */
Martin v. Löwis18e16552006-02-15 17:27:45 +00004668 fd1 = _open_osfhandle((intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004669 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004670 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004671 PyFile_SetBufSize(f, 0);
4672 /* We don't care about these pipes anymore, so close them. */
4673 CloseHandle(hChildStdoutRdDup);
4674 CloseHandle(hChildStderrRdDup);
4675 break;
4676 }
Mark Hammondb37a3732000-08-14 04:47:33 +00004677 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004678 break;
Tim Peters5aa91602002-01-30 05:46:57 +00004679
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004680 case POPEN_2:
4681 case POPEN_4:
4682 {
4683 char *m1, *m2;
4684 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00004685
Tim Peters7dca21e2002-08-19 00:42:29 +00004686 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004687 m1 = "r";
4688 m2 = "w";
4689 } else {
4690 m1 = "rb";
4691 m2 = "wb";
4692 }
4693
Martin v. Löwis18e16552006-02-15 17:27:45 +00004694 fd1 = _open_osfhandle((intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004695 f1 = _fdopen(fd1, m2);
Martin v. Löwis18e16552006-02-15 17:27:45 +00004696 fd2 = _open_osfhandle((intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004697 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004698 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004699 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00004700 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004701 PyFile_SetBufSize(p2, 0);
4702
4703 if (n != 4)
4704 CloseHandle(hChildStderrRdDup);
4705
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004706 f = PyTuple_Pack(2,p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00004707 Py_XDECREF(p1);
4708 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00004709 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004710 break;
4711 }
Tim Peters5aa91602002-01-30 05:46:57 +00004712
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004713 case POPEN_3:
4714 {
4715 char *m1, *m2;
4716 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00004717
Tim Peters7dca21e2002-08-19 00:42:29 +00004718 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004719 m1 = "r";
4720 m2 = "w";
4721 } else {
4722 m1 = "rb";
4723 m2 = "wb";
4724 }
4725
Martin v. Löwis18e16552006-02-15 17:27:45 +00004726 fd1 = _open_osfhandle((intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004727 f1 = _fdopen(fd1, m2);
Martin v. Löwis18e16552006-02-15 17:27:45 +00004728 fd2 = _open_osfhandle((intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004729 f2 = _fdopen(fd2, m1);
Martin v. Löwis18e16552006-02-15 17:27:45 +00004730 fd3 = _open_osfhandle((intptr_t)hChildStderrRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004731 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004732 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00004733 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
4734 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004735 PyFile_SetBufSize(p1, 0);
4736 PyFile_SetBufSize(p2, 0);
4737 PyFile_SetBufSize(p3, 0);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004738 f = PyTuple_Pack(3,p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00004739 Py_XDECREF(p1);
4740 Py_XDECREF(p2);
4741 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00004742 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004743 break;
4744 }
4745 }
4746
4747 if (n == POPEN_4) {
4748 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004749 hChildStdinRd,
4750 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004751 hChildStdoutWr,
4752 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004753 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004754 }
4755 else {
4756 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004757 hChildStdinRd,
4758 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004759 hChildStderrWr,
4760 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004761 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004762 }
4763
Mark Hammondb37a3732000-08-14 04:47:33 +00004764 /*
4765 * Insert the files we've created into the process dictionary
4766 * all referencing the list with the process handle and the
4767 * initial number of files (see description below in _PyPclose).
4768 * Since if _PyPclose later tried to wait on a process when all
4769 * handles weren't closed, it could create a deadlock with the
4770 * child, we spend some energy here to try to ensure that we
4771 * either insert all file handles into the dictionary or none
4772 * at all. It's a little clumsy with the various popen modes
4773 * and variable number of files involved.
4774 */
4775 if (!_PyPopenProcs) {
4776 _PyPopenProcs = PyDict_New();
4777 }
4778
4779 if (_PyPopenProcs) {
4780 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
4781 int ins_rc[3];
4782
4783 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4784 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4785
4786 procObj = PyList_New(2);
4787 hProcessObj = PyLong_FromVoidPtr(hProcess);
4788 intObj = PyInt_FromLong(file_count);
4789
4790 if (procObj && hProcessObj && intObj) {
4791 PyList_SetItem(procObj,0,hProcessObj);
4792 PyList_SetItem(procObj,1,intObj);
4793
4794 fileObj[0] = PyLong_FromVoidPtr(f1);
4795 if (fileObj[0]) {
4796 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4797 fileObj[0],
4798 procObj);
4799 }
4800 if (file_count >= 2) {
4801 fileObj[1] = PyLong_FromVoidPtr(f2);
4802 if (fileObj[1]) {
4803 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4804 fileObj[1],
4805 procObj);
4806 }
4807 }
4808 if (file_count >= 3) {
4809 fileObj[2] = PyLong_FromVoidPtr(f3);
4810 if (fileObj[2]) {
4811 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4812 fileObj[2],
4813 procObj);
4814 }
4815 }
4816
4817 if (ins_rc[0] < 0 || !fileObj[0] ||
4818 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4819 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
4820 /* Something failed - remove any dictionary
4821 * entries that did make it.
4822 */
4823 if (!ins_rc[0] && fileObj[0]) {
4824 PyDict_DelItem(_PyPopenProcs,
4825 fileObj[0]);
4826 }
4827 if (!ins_rc[1] && fileObj[1]) {
4828 PyDict_DelItem(_PyPopenProcs,
4829 fileObj[1]);
4830 }
4831 if (!ins_rc[2] && fileObj[2]) {
4832 PyDict_DelItem(_PyPopenProcs,
4833 fileObj[2]);
4834 }
4835 }
4836 }
Tim Peters5aa91602002-01-30 05:46:57 +00004837
Mark Hammondb37a3732000-08-14 04:47:33 +00004838 /*
4839 * Clean up our localized references for the dictionary keys
4840 * and value since PyDict_SetItem will Py_INCREF any copies
4841 * that got placed in the dictionary.
4842 */
4843 Py_XDECREF(procObj);
4844 Py_XDECREF(fileObj[0]);
4845 Py_XDECREF(fileObj[1]);
4846 Py_XDECREF(fileObj[2]);
4847 }
4848
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004849 /* Child is launched. Close the parents copy of those pipe
4850 * handles that only the child should have open. You need to
4851 * make sure that no handles to the write end of the output pipe
4852 * are maintained in this process or else the pipe will not close
4853 * when the child process exits and the ReadFile will hang. */
4854
4855 if (!CloseHandle(hChildStdinRd))
4856 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004857
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004858 if (!CloseHandle(hChildStdoutWr))
4859 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004860
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004861 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
4862 return win32_error("CloseHandle", NULL);
4863
4864 return f;
4865}
Fredrik Lundh56055a42000-07-23 19:47:12 +00004866
4867/*
4868 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4869 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00004870 *
4871 * This function uses the _PyPopenProcs dictionary in order to map the
4872 * input file pointer to information about the process that was
4873 * originally created by the popen* call that created the file pointer.
4874 * The dictionary uses the file pointer as a key (with one entry
4875 * inserted for each file returned by the original popen* call) and a
4876 * single list object as the value for all files from a single call.
4877 * The list object contains the Win32 process handle at [0], and a file
4878 * count at [1], which is initialized to the total number of file
4879 * handles using that list.
4880 *
4881 * This function closes whichever handle it is passed, and decrements
4882 * the file count in the dictionary for the process handle pointed to
4883 * by this file. On the last close (when the file count reaches zero),
4884 * this function will wait for the child process and then return its
4885 * exit code as the result of the close() operation. This permits the
4886 * files to be closed in any order - it is always the close() of the
4887 * final handle that will return the exit code.
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004888 *
4889 * NOTE: This function is currently called with the GIL released.
4890 * hence we use the GILState API to manage our state.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004891 */
Tim Peters736aa322000-09-01 06:51:24 +00004892
Fredrik Lundh56055a42000-07-23 19:47:12 +00004893static int _PyPclose(FILE *file)
4894{
Fredrik Lundh20318932000-07-26 17:29:12 +00004895 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004896 DWORD exit_code;
4897 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00004898 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
4899 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00004900#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004901 PyGILState_STATE state;
Tim Peters736aa322000-09-01 06:51:24 +00004902#endif
4903
Fredrik Lundh20318932000-07-26 17:29:12 +00004904 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00004905 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00004906 */
4907 result = fclose(file);
Tim Peters736aa322000-09-01 06:51:24 +00004908#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004909 state = PyGILState_Ensure();
Tim Peters736aa322000-09-01 06:51:24 +00004910#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00004911 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00004912 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4913 (procObj = PyDict_GetItem(_PyPopenProcs,
4914 fileObj)) != NULL &&
4915 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
4916 (intObj = PyList_GetItem(procObj,1)) != NULL) {
4917
4918 hProcess = PyLong_AsVoidPtr(hProcessObj);
4919 file_count = PyInt_AsLong(intObj);
4920
4921 if (file_count > 1) {
4922 /* Still other files referencing process */
4923 file_count--;
4924 PyList_SetItem(procObj,1,
4925 PyInt_FromLong(file_count));
4926 } else {
4927 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00004928 if (result != EOF &&
4929 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
4930 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00004931 /* Possible truncation here in 16-bit environments, but
4932 * real exit codes are just the lower byte in any event.
4933 */
4934 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004935 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00004936 /* Indicate failure - this will cause the file object
4937 * to raise an I/O error and translate the last Win32
4938 * error code from errno. We do have a problem with
4939 * last errors that overlap the normal errno table,
4940 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004941 */
Fredrik Lundh20318932000-07-26 17:29:12 +00004942 if (result != EOF) {
4943 /* If the error wasn't from the fclose(), then
4944 * set errno for the file object error handling.
4945 */
4946 errno = GetLastError();
4947 }
4948 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004949 }
4950
4951 /* Free up the native handle at this point */
4952 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00004953 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00004954
Mark Hammondb37a3732000-08-14 04:47:33 +00004955 /* Remove this file pointer from dictionary */
4956 PyDict_DelItem(_PyPopenProcs, fileObj);
4957
4958 if (PyDict_Size(_PyPopenProcs) == 0) {
4959 Py_DECREF(_PyPopenProcs);
4960 _PyPopenProcs = NULL;
4961 }
4962
4963 } /* if object retrieval ok */
4964
4965 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004966 } /* if _PyPopenProcs */
4967
Tim Peters736aa322000-09-01 06:51:24 +00004968#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004969 PyGILState_Release(state);
Tim Peters736aa322000-09-01 06:51:24 +00004970#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00004971 return result;
4972}
Tim Peters9acdd3a2000-09-01 19:26:36 +00004973
4974#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00004975static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004976posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00004977{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004978 char *name;
4979 char *mode = "r";
4980 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00004981 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00004982 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004983 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00004984 return NULL;
Martin v. Löwis9ad853b2003-10-31 10:01:53 +00004985 /* Strip mode of binary or text modifiers */
4986 if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
4987 mode = "r";
4988 else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
4989 mode = "w";
Barry Warsaw53699e91996-12-10 23:23:01 +00004990 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004991 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004992 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00004993 if (fp == NULL)
4994 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004995 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004996 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00004997 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004998 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00004999}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005000
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005001#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005002#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00005003
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005004
Guido van Rossumb6775db1994-08-01 11:34:53 +00005005#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005006PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005007"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005008Set the current process's user id.");
5009
Barry Warsaw53699e91996-12-10 23:23:01 +00005010static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005011posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005012{
5013 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005014 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005015 return NULL;
5016 if (setuid(uid) < 0)
5017 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005018 Py_INCREF(Py_None);
5019 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005020}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005021#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005022
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005023
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005024#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005025PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005026"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005027Set the current process's effective user id.");
5028
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005029static PyObject *
5030posix_seteuid (PyObject *self, PyObject *args)
5031{
5032 int euid;
5033 if (!PyArg_ParseTuple(args, "i", &euid)) {
5034 return NULL;
5035 } else if (seteuid(euid) < 0) {
5036 return posix_error();
5037 } else {
5038 Py_INCREF(Py_None);
5039 return Py_None;
5040 }
5041}
5042#endif /* HAVE_SETEUID */
5043
5044#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005045PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005046"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005047Set the current process's effective group id.");
5048
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005049static PyObject *
5050posix_setegid (PyObject *self, PyObject *args)
5051{
5052 int egid;
5053 if (!PyArg_ParseTuple(args, "i", &egid)) {
5054 return NULL;
5055 } else if (setegid(egid) < 0) {
5056 return posix_error();
5057 } else {
5058 Py_INCREF(Py_None);
5059 return Py_None;
5060 }
5061}
5062#endif /* HAVE_SETEGID */
5063
5064#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005065PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005066"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005067Set the current process's real and effective user ids.");
5068
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005069static PyObject *
5070posix_setreuid (PyObject *self, PyObject *args)
5071{
5072 int ruid, euid;
5073 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
5074 return NULL;
5075 } else if (setreuid(ruid, euid) < 0) {
5076 return posix_error();
5077 } else {
5078 Py_INCREF(Py_None);
5079 return Py_None;
5080 }
5081}
5082#endif /* HAVE_SETREUID */
5083
5084#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005085PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005086"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005087Set the current process's real and effective group ids.");
5088
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005089static PyObject *
5090posix_setregid (PyObject *self, PyObject *args)
5091{
5092 int rgid, egid;
5093 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
5094 return NULL;
5095 } else if (setregid(rgid, egid) < 0) {
5096 return posix_error();
5097 } else {
5098 Py_INCREF(Py_None);
5099 return Py_None;
5100 }
5101}
5102#endif /* HAVE_SETREGID */
5103
Guido van Rossumb6775db1994-08-01 11:34:53 +00005104#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005105PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005106"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005107Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005108
Barry Warsaw53699e91996-12-10 23:23:01 +00005109static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005110posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005111{
5112 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005113 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005114 return NULL;
5115 if (setgid(gid) < 0)
5116 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005117 Py_INCREF(Py_None);
5118 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005119}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005120#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005121
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005122#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005123PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005124"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005125Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005126
5127static PyObject *
5128posix_setgroups(PyObject *self, PyObject *args)
5129{
5130 PyObject *groups;
5131 int i, len;
5132 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00005133
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005134 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
5135 return NULL;
5136 if (!PySequence_Check(groups)) {
5137 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
5138 return NULL;
5139 }
5140 len = PySequence_Size(groups);
5141 if (len > MAX_GROUPS) {
5142 PyErr_SetString(PyExc_ValueError, "too many groups");
5143 return NULL;
5144 }
5145 for(i = 0; i < len; i++) {
5146 PyObject *elem;
5147 elem = PySequence_GetItem(groups, i);
5148 if (!elem)
5149 return NULL;
5150 if (!PyInt_Check(elem)) {
Georg Brandla13c2442005-11-22 19:30:31 +00005151 if (!PyLong_Check(elem)) {
5152 PyErr_SetString(PyExc_TypeError,
5153 "groups must be integers");
5154 Py_DECREF(elem);
5155 return NULL;
5156 } else {
5157 unsigned long x = PyLong_AsUnsignedLong(elem);
5158 if (PyErr_Occurred()) {
5159 PyErr_SetString(PyExc_TypeError,
5160 "group id too big");
5161 Py_DECREF(elem);
5162 return NULL;
5163 }
5164 grouplist[i] = x;
5165 /* read back the value to see if it fitted in gid_t */
5166 if (grouplist[i] != x) {
5167 PyErr_SetString(PyExc_TypeError,
5168 "group id too big");
5169 Py_DECREF(elem);
5170 return NULL;
5171 }
5172 }
5173 } else {
5174 long x = PyInt_AsLong(elem);
5175 grouplist[i] = x;
5176 if (grouplist[i] != x) {
5177 PyErr_SetString(PyExc_TypeError,
5178 "group id too big");
5179 Py_DECREF(elem);
5180 return NULL;
5181 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005182 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005183 Py_DECREF(elem);
5184 }
5185
5186 if (setgroups(len, grouplist) < 0)
5187 return posix_error();
5188 Py_INCREF(Py_None);
5189 return Py_None;
5190}
5191#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005192
Neal Norwitz6c2f9132006-03-20 07:25:26 +00005193#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Neal Norwitz05a45592006-03-20 06:30:08 +00005194static PyObject *
5195wait_helper(int pid, int status, struct rusage *ru)
5196{
5197 PyObject *result;
5198 static PyObject *struct_rusage;
5199
5200 if (pid == -1)
5201 return posix_error();
5202
5203 if (struct_rusage == NULL) {
5204 PyObject *m = PyImport_ImportModule("resource");
5205 if (m == NULL)
5206 return NULL;
5207 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
5208 Py_DECREF(m);
5209 if (struct_rusage == NULL)
5210 return NULL;
5211 }
5212
5213 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
5214 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
5215 if (!result)
5216 return NULL;
5217
5218#ifndef doubletime
5219#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
5220#endif
5221
5222 PyStructSequence_SET_ITEM(result, 0,
5223 PyFloat_FromDouble(doubletime(ru->ru_utime)));
5224 PyStructSequence_SET_ITEM(result, 1,
5225 PyFloat_FromDouble(doubletime(ru->ru_stime)));
5226#define SET_INT(result, index, value)\
5227 PyStructSequence_SET_ITEM(result, index, PyInt_FromLong(value))
5228 SET_INT(result, 2, ru->ru_maxrss);
5229 SET_INT(result, 3, ru->ru_ixrss);
5230 SET_INT(result, 4, ru->ru_idrss);
5231 SET_INT(result, 5, ru->ru_isrss);
5232 SET_INT(result, 6, ru->ru_minflt);
5233 SET_INT(result, 7, ru->ru_majflt);
5234 SET_INT(result, 8, ru->ru_nswap);
5235 SET_INT(result, 9, ru->ru_inblock);
5236 SET_INT(result, 10, ru->ru_oublock);
5237 SET_INT(result, 11, ru->ru_msgsnd);
5238 SET_INT(result, 12, ru->ru_msgrcv);
5239 SET_INT(result, 13, ru->ru_nsignals);
5240 SET_INT(result, 14, ru->ru_nvcsw);
5241 SET_INT(result, 15, ru->ru_nivcsw);
5242#undef SET_INT
5243
5244 if (PyErr_Occurred()) {
5245 Py_DECREF(result);
5246 return NULL;
5247 }
5248
Neal Norwitz9b00a562006-03-20 08:47:12 +00005249 return Py_BuildValue("iiN", pid, status, result);
Neal Norwitz05a45592006-03-20 06:30:08 +00005250}
Neal Norwitz6c2f9132006-03-20 07:25:26 +00005251#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
Neal Norwitz05a45592006-03-20 06:30:08 +00005252
5253#ifdef HAVE_WAIT3
5254PyDoc_STRVAR(posix_wait3__doc__,
5255"wait3(options) -> (pid, status, rusage)\n\n\
5256Wait for completion of a child process.");
5257
5258static PyObject *
5259posix_wait3(PyObject *self, PyObject *args)
5260{
5261 int pid, options;
5262 struct rusage ru;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005263 WAIT_TYPE status;
5264 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00005265
5266 if (!PyArg_ParseTuple(args, "i:wait3", &options))
5267 return NULL;
5268
5269 Py_BEGIN_ALLOW_THREADS
5270 pid = wait3(&status, options, &ru);
5271 Py_END_ALLOW_THREADS
5272
Neal Norwitzd5a37542006-03-20 06:48:34 +00005273 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00005274}
5275#endif /* HAVE_WAIT3 */
5276
5277#ifdef HAVE_WAIT4
5278PyDoc_STRVAR(posix_wait4__doc__,
5279"wait4(pid, options) -> (pid, status, rusage)\n\n\
5280Wait for completion of a given child process.");
5281
5282static PyObject *
5283posix_wait4(PyObject *self, PyObject *args)
5284{
5285 int pid, options;
5286 struct rusage ru;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005287 WAIT_TYPE status;
5288 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00005289
5290 if (!PyArg_ParseTuple(args, "ii:wait4", &pid, &options))
5291 return NULL;
5292
5293 Py_BEGIN_ALLOW_THREADS
5294 pid = wait4(pid, &status, options, &ru);
5295 Py_END_ALLOW_THREADS
5296
Neal Norwitzd5a37542006-03-20 06:48:34 +00005297 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00005298}
5299#endif /* HAVE_WAIT4 */
5300
Guido van Rossumb6775db1994-08-01 11:34:53 +00005301#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005302PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005303"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005304Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005305
Barry Warsaw53699e91996-12-10 23:23:01 +00005306static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005307posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005308{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005309 int pid, options;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005310 WAIT_TYPE status;
5311 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005312
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005313 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00005314 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005315 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00005316 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00005317 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00005318 if (pid == -1)
5319 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00005320
5321 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00005322}
5323
Tim Petersab034fa2002-02-01 11:27:43 +00005324#elif defined(HAVE_CWAIT)
5325
5326/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005327PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005328"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005329"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00005330
5331static PyObject *
5332posix_waitpid(PyObject *self, PyObject *args)
5333{
Martin v. Löwis18e16552006-02-15 17:27:45 +00005334 intptr_t pid;
5335 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00005336
5337 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
5338 return NULL;
5339 Py_BEGIN_ALLOW_THREADS
5340 pid = _cwait(&status, pid, options);
5341 Py_END_ALLOW_THREADS
5342 if (pid == -1)
5343 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00005344
5345 /* shift the status left a byte so this is more like the POSIX waitpid */
5346 return Py_BuildValue("ii", pid, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00005347}
5348#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005349
Guido van Rossumad0ee831995-03-01 10:34:45 +00005350#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005351PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005352"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005353Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005354
Barry Warsaw53699e91996-12-10 23:23:01 +00005355static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005356posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00005357{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005358 int pid;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005359 WAIT_TYPE status;
5360 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00005361
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005362 Py_BEGIN_ALLOW_THREADS
5363 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00005364 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00005365 if (pid == -1)
5366 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00005367
5368 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00005369}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005370#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005371
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005372
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005373PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005374"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005375Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005376
Barry Warsaw53699e91996-12-10 23:23:01 +00005377static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005378posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005379{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005380#ifdef HAVE_LSTAT
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005381 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005382#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005383#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00005384 return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005385#else
5386 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
5387#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005388#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005389}
5390
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005391
Guido van Rossumb6775db1994-08-01 11:34:53 +00005392#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005393PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005394"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005395Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005396
Barry Warsaw53699e91996-12-10 23:23:01 +00005397static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005398posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005399{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005400 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00005401 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005402 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005403 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005404 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005405 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00005406 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00005407 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005408 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00005409 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00005410 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005411}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005412#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005413
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005414
Guido van Rossumb6775db1994-08-01 11:34:53 +00005415#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005416PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005417"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00005418Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005419
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005420static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005421posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005422{
Martin v. Löwis4fc2bda2006-05-04 12:04:27 +00005423 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005424}
5425#endif /* HAVE_SYMLINK */
5426
5427
5428#ifdef HAVE_TIMES
5429#ifndef HZ
5430#define HZ 60 /* Universal constant :-) */
5431#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00005432
Guido van Rossumd48f2521997-12-05 22:19:34 +00005433#if defined(PYCC_VACPP) && defined(PYOS_OS2)
5434static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005435system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005436{
5437 ULONG value = 0;
5438
5439 Py_BEGIN_ALLOW_THREADS
5440 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
5441 Py_END_ALLOW_THREADS
5442
5443 return value;
5444}
5445
5446static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005447posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005448{
Guido van Rossumd48f2521997-12-05 22:19:34 +00005449 /* Currently Only Uptime is Provided -- Others Later */
5450 return Py_BuildValue("ddddd",
5451 (double)0 /* t.tms_utime / HZ */,
5452 (double)0 /* t.tms_stime / HZ */,
5453 (double)0 /* t.tms_cutime / HZ */,
5454 (double)0 /* t.tms_cstime / HZ */,
5455 (double)system_uptime() / 1000);
5456}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005457#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00005458static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005459posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00005460{
5461 struct tms t;
5462 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +00005463 errno = 0;
5464 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00005465 if (c == (clock_t) -1)
5466 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005467 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00005468 (double)t.tms_utime / HZ,
5469 (double)t.tms_stime / HZ,
5470 (double)t.tms_cutime / HZ,
5471 (double)t.tms_cstime / HZ,
5472 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00005473}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005474#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005475#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005476
5477
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005478#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005479#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00005480static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005481posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005482{
5483 FILETIME create, exit, kernel, user;
5484 HANDLE hProc;
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005485 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00005486 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
5487 /* The fields of a FILETIME structure are the hi and lo part
5488 of a 64-bit value expressed in 100 nanosecond units.
5489 1e7 is one second in such units; 1e-7 the inverse.
5490 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
5491 */
Barry Warsaw53699e91996-12-10 23:23:01 +00005492 return Py_BuildValue(
5493 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00005494 (double)(kernel.dwHighDateTime*429.4967296 +
5495 kernel.dwLowDateTime*1e-7),
5496 (double)(user.dwHighDateTime*429.4967296 +
5497 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00005498 (double)0,
5499 (double)0,
5500 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005501}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005502#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005503
5504#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005505PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005506"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005507Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005508#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005509
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005510
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00005511#ifdef HAVE_GETSID
5512PyDoc_STRVAR(posix_getsid__doc__,
5513"getsid(pid) -> sid\n\n\
5514Call the system call getsid().");
5515
5516static PyObject *
5517posix_getsid(PyObject *self, PyObject *args)
5518{
5519 int pid, sid;
5520 if (!PyArg_ParseTuple(args, "i:getsid", &pid))
5521 return NULL;
5522 sid = getsid(pid);
5523 if (sid < 0)
5524 return posix_error();
5525 return PyInt_FromLong((long)sid);
5526}
5527#endif /* HAVE_GETSID */
5528
5529
Guido van Rossumb6775db1994-08-01 11:34:53 +00005530#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005531PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005532"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005533Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005534
Barry Warsaw53699e91996-12-10 23:23:01 +00005535static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005536posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005537{
Guido van Rossum687dd131993-05-17 08:34:16 +00005538 if (setsid() < 0)
5539 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005540 Py_INCREF(Py_None);
5541 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005542}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005543#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005544
Guido van Rossumb6775db1994-08-01 11:34:53 +00005545#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005546PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005547"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005548Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005549
Barry Warsaw53699e91996-12-10 23:23:01 +00005550static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005551posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005552{
5553 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005554 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00005555 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005556 if (setpgid(pid, pgrp) < 0)
5557 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005558 Py_INCREF(Py_None);
5559 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005560}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005561#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005562
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005563
Guido van Rossumb6775db1994-08-01 11:34:53 +00005564#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005565PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005566"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005567Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005568
Barry Warsaw53699e91996-12-10 23:23:01 +00005569static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005570posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005571{
5572 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005573 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00005574 return NULL;
5575 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005576 if (pgid < 0)
5577 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005578 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00005579}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005580#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00005581
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005582
Guido van Rossumb6775db1994-08-01 11:34:53 +00005583#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005584PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005585"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005586Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005587
Barry Warsaw53699e91996-12-10 23:23:01 +00005588static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005589posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005590{
5591 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005592 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00005593 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005594 if (tcsetpgrp(fd, pgid) < 0)
5595 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00005596 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00005597 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00005598}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005599#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00005600
Guido van Rossum687dd131993-05-17 08:34:16 +00005601/* Functions acting on file descriptors */
5602
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005603PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005604"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005605Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005606
Barry Warsaw53699e91996-12-10 23:23:01 +00005607static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005608posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005609{
Mark Hammondef8b6542001-05-13 08:04:26 +00005610 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005611 int flag;
5612 int mode = 0777;
5613 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005614
5615#ifdef MS_WINDOWS
5616 if (unicode_file_names()) {
5617 PyUnicodeObject *po;
5618 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
5619 Py_BEGIN_ALLOW_THREADS
5620 /* PyUnicode_AS_UNICODE OK without thread
5621 lock as it is a simple dereference. */
5622 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
5623 Py_END_ALLOW_THREADS
5624 if (fd < 0)
5625 return posix_error();
5626 return PyInt_FromLong((long)fd);
5627 }
5628 /* Drop the argument parsing error as narrow strings
5629 are also valid. */
5630 PyErr_Clear();
5631 }
5632#endif
5633
Tim Peters5aa91602002-01-30 05:46:57 +00005634 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00005635 Py_FileSystemDefaultEncoding, &file,
5636 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00005637 return NULL;
5638
Barry Warsaw53699e91996-12-10 23:23:01 +00005639 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005640 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005641 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005642 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00005643 return posix_error_with_allocated_filename(file);
5644 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00005645 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005646}
5647
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005648
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005649PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005650"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005651Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005652
Barry Warsaw53699e91996-12-10 23:23:01 +00005653static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005654posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005655{
5656 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005657 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005658 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005659 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005660 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00005661 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005662 if (res < 0)
5663 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005664 Py_INCREF(Py_None);
5665 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005666}
5667
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005668
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005669PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005670"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005671Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005672
Barry Warsaw53699e91996-12-10 23:23:01 +00005673static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005674posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005675{
5676 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005677 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005678 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005679 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005680 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00005681 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005682 if (fd < 0)
5683 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005684 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005685}
5686
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005687
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005688PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00005689"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005690Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005691
Barry Warsaw53699e91996-12-10 23:23:01 +00005692static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005693posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005694{
5695 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005696 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00005697 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005698 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005699 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00005700 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005701 if (res < 0)
5702 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005703 Py_INCREF(Py_None);
5704 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005705}
5706
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005707
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005708PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005709"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005710Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005711
Barry Warsaw53699e91996-12-10 23:23:01 +00005712static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005713posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005714{
5715 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005716#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005717 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005718#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00005719 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005720#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005721 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005722 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00005723 return NULL;
5724#ifdef SEEK_SET
5725 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
5726 switch (how) {
5727 case 0: how = SEEK_SET; break;
5728 case 1: how = SEEK_CUR; break;
5729 case 2: how = SEEK_END; break;
5730 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005731#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005732
5733#if !defined(HAVE_LARGEFILE_SUPPORT)
5734 pos = PyInt_AsLong(posobj);
5735#else
5736 pos = PyLong_Check(posobj) ?
5737 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
5738#endif
5739 if (PyErr_Occurred())
5740 return NULL;
5741
Barry Warsaw53699e91996-12-10 23:23:01 +00005742 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005743#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00005744 res = _lseeki64(fd, pos, how);
5745#else
Guido van Rossum687dd131993-05-17 08:34:16 +00005746 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005747#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005748 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005749 if (res < 0)
5750 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00005751
5752#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00005753 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005754#else
5755 return PyLong_FromLongLong(res);
5756#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005757}
5758
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005759
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005760PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005761"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005762Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005763
Barry Warsaw53699e91996-12-10 23:23:01 +00005764static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005765posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005766{
Guido van Rossum8bac5461996-06-11 18:38:48 +00005767 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00005768 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005769 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005770 return NULL;
Michael W. Hudson9867ced2005-01-31 17:01:59 +00005771 if (size < 0) {
5772 errno = EINVAL;
5773 return posix_error();
5774 }
Barry Warsaw53699e91996-12-10 23:23:01 +00005775 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005776 if (buffer == NULL)
5777 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005778 Py_BEGIN_ALLOW_THREADS
5779 n = read(fd, PyString_AsString(buffer), size);
5780 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00005781 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005782 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00005783 return posix_error();
5784 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00005785 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00005786 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00005787 return buffer;
5788}
5789
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005790
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005791PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005792"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005793Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005794
Barry Warsaw53699e91996-12-10 23:23:01 +00005795static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005796posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005797{
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005798 int fd;
5799 Py_ssize_t size;
Guido van Rossum687dd131993-05-17 08:34:16 +00005800 char *buffer;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005801
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005802 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005803 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005804 Py_BEGIN_ALLOW_THREADS
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005805 size = write(fd, buffer, (size_t)size);
Barry Warsaw53699e91996-12-10 23:23:01 +00005806 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005807 if (size < 0)
5808 return posix_error();
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005809 return PyInt_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005810}
5811
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005812
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005813PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005814"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005815Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005816
Barry Warsaw53699e91996-12-10 23:23:01 +00005817static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005818posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005819{
5820 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00005821 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00005822 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005823 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005824 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005825#ifdef __VMS
5826 /* on OpenVMS we must ensure that all bytes are written to the file */
5827 fsync(fd);
5828#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005829 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00005830 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00005831 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00005832 if (res != 0) {
5833#ifdef MS_WINDOWS
5834 return win32_error("fstat", NULL);
5835#else
Guido van Rossum687dd131993-05-17 08:34:16 +00005836 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00005837#endif
5838 }
Tim Peters5aa91602002-01-30 05:46:57 +00005839
Martin v. Löwis14694662006-02-03 12:54:16 +00005840 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00005841}
5842
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005843
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005844PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005845"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005846Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005847
Barry Warsaw53699e91996-12-10 23:23:01 +00005848static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005849posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005850{
Guido van Rossum687dd131993-05-17 08:34:16 +00005851 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005852 char *mode = "r";
5853 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00005854 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00005855 PyObject *f;
5856 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00005857 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00005858
Thomas Heller1f043e22002-11-07 16:00:59 +00005859 if (mode[0] != 'r' && mode[0] != 'w' && mode[0] != 'a') {
5860 PyErr_Format(PyExc_ValueError,
5861 "invalid file mode '%s'", mode);
5862 return NULL;
5863 }
Barry Warsaw53699e91996-12-10 23:23:01 +00005864 Py_BEGIN_ALLOW_THREADS
Georg Brandl644b1e72006-03-31 20:27:22 +00005865#if !defined(MS_WINDOWS) && defined(HAVE_FCNTL_H)
Georg Brandl54a188a2006-03-31 20:00:11 +00005866 if (mode[0] == 'a') {
5867 /* try to make sure the O_APPEND flag is set */
5868 int flags;
5869 flags = fcntl(fd, F_GETFL);
5870 if (flags != -1)
5871 fcntl(fd, F_SETFL, flags | O_APPEND);
5872 fp = fdopen(fd, mode);
Thomas Wouters2a9a6b02006-03-31 22:38:19 +00005873 if (fp == NULL && flags != -1)
Georg Brandl54a188a2006-03-31 20:00:11 +00005874 /* restore old mode if fdopen failed */
5875 fcntl(fd, F_SETFL, flags);
5876 } else {
5877 fp = fdopen(fd, mode);
5878 }
Georg Brandl644b1e72006-03-31 20:27:22 +00005879#else
5880 fp = fdopen(fd, mode);
5881#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005882 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005883 if (fp == NULL)
5884 return posix_error();
Guido van Rossumbd6be7a2002-09-15 18:45:46 +00005885 f = PyFile_FromFile(fp, "<fdopen>", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005886 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00005887 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005888 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00005889}
5890
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005891PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005892"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005893Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005894connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00005895
5896static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00005897posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00005898{
5899 int fd;
5900 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
5901 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005902 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00005903}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005904
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005905#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005906PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005907"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005908Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005909
Barry Warsaw53699e91996-12-10 23:23:01 +00005910static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005911posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00005912{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005913#if defined(PYOS_OS2)
5914 HFILE read, write;
5915 APIRET rc;
5916
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005917 Py_BEGIN_ALLOW_THREADS
5918 rc = DosCreatePipe( &read, &write, 4096);
5919 Py_END_ALLOW_THREADS
5920 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005921 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005922
5923 return Py_BuildValue("(ii)", read, write);
5924#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005925#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00005926 int fds[2];
5927 int res;
Barry Warsaw53699e91996-12-10 23:23:01 +00005928 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005929 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00005930 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005931 if (res != 0)
5932 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005933 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005934#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00005935 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005936 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00005937 BOOL ok;
Barry Warsaw53699e91996-12-10 23:23:01 +00005938 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005939 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00005940 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00005941 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005942 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00005943 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
5944 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005945 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005946#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005947#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005948}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005949#endif /* HAVE_PIPE */
5950
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005951
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005952#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005953PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005954"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005955Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005956
Barry Warsaw53699e91996-12-10 23:23:01 +00005957static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005958posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005959{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005960 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005961 int mode = 0666;
5962 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005963 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005964 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005965 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005966 res = mkfifo(filename, mode);
5967 Py_END_ALLOW_THREADS
5968 if (res < 0)
5969 return posix_error();
5970 Py_INCREF(Py_None);
5971 return Py_None;
5972}
5973#endif
5974
5975
Neal Norwitz11690112002-07-30 01:08:28 +00005976#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005977PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005978"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005979Create a filesystem node (file, device special file or named pipe)\n\
5980named filename. mode specifies both the permissions to use and the\n\
5981type of node to be created, being combined (bitwise OR) with one of\n\
5982S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005983device defines the newly created device special file (probably using\n\
5984os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005985
5986
5987static PyObject *
5988posix_mknod(PyObject *self, PyObject *args)
5989{
5990 char *filename;
5991 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005992 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005993 int res;
Martin v. Löwisd631ebe2002-11-02 17:42:33 +00005994 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005995 return NULL;
5996 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005997 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00005998 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005999 if (res < 0)
6000 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006001 Py_INCREF(Py_None);
6002 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006003}
6004#endif
6005
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006006#ifdef HAVE_DEVICE_MACROS
6007PyDoc_STRVAR(posix_major__doc__,
6008"major(device) -> major number\n\
6009Extracts a device major number from a raw device number.");
6010
6011static PyObject *
6012posix_major(PyObject *self, PyObject *args)
6013{
6014 int device;
6015 if (!PyArg_ParseTuple(args, "i:major", &device))
6016 return NULL;
6017 return PyInt_FromLong((long)major(device));
6018}
6019
6020PyDoc_STRVAR(posix_minor__doc__,
6021"minor(device) -> minor number\n\
6022Extracts a device minor number from a raw device number.");
6023
6024static PyObject *
6025posix_minor(PyObject *self, PyObject *args)
6026{
6027 int device;
6028 if (!PyArg_ParseTuple(args, "i:minor", &device))
6029 return NULL;
6030 return PyInt_FromLong((long)minor(device));
6031}
6032
6033PyDoc_STRVAR(posix_makedev__doc__,
6034"makedev(major, minor) -> device number\n\
6035Composes a raw device number from the major and minor device numbers.");
6036
6037static PyObject *
6038posix_makedev(PyObject *self, PyObject *args)
6039{
6040 int major, minor;
6041 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
6042 return NULL;
6043 return PyInt_FromLong((long)makedev(major, minor));
6044}
6045#endif /* device macros */
6046
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006047
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006048#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006049PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006050"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006051Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006052
Barry Warsaw53699e91996-12-10 23:23:01 +00006053static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006054posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006055{
6056 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006057 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006058 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006059 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006060
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006061 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006062 return NULL;
6063
6064#if !defined(HAVE_LARGEFILE_SUPPORT)
6065 length = PyInt_AsLong(lenobj);
6066#else
6067 length = PyLong_Check(lenobj) ?
6068 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
6069#endif
6070 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006071 return NULL;
6072
Barry Warsaw53699e91996-12-10 23:23:01 +00006073 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006074 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00006075 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006076 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00006077 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006078 return NULL;
6079 }
Barry Warsaw53699e91996-12-10 23:23:01 +00006080 Py_INCREF(Py_None);
6081 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006082}
6083#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006084
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006085#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006086PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006087"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006088Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006089
Fred Drake762e2061999-08-26 17:23:54 +00006090/* Save putenv() parameters as values here, so we can collect them when they
6091 * get re-set with another call for the same key. */
6092static PyObject *posix_putenv_garbage;
6093
Tim Peters5aa91602002-01-30 05:46:57 +00006094static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006095posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006096{
6097 char *s1, *s2;
Anthony Baxter64182fe2006-04-11 12:14:09 +00006098 char *newenv;
Fred Drake762e2061999-08-26 17:23:54 +00006099 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00006100 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006101
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006102 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006103 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00006104
6105#if defined(PYOS_OS2)
6106 if (stricmp(s1, "BEGINLIBPATH") == 0) {
6107 APIRET rc;
6108
Guido van Rossumd48f2521997-12-05 22:19:34 +00006109 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
6110 if (rc != NO_ERROR)
6111 return os2_error(rc);
6112
6113 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
6114 APIRET rc;
6115
Guido van Rossumd48f2521997-12-05 22:19:34 +00006116 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
6117 if (rc != NO_ERROR)
6118 return os2_error(rc);
6119 } else {
6120#endif
6121
Fred Drake762e2061999-08-26 17:23:54 +00006122 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00006123 len = strlen(s1) + strlen(s2) + 2;
6124 /* len includes space for a trailing \0; the size arg to
6125 PyString_FromStringAndSize does not count that */
6126 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00006127 if (newstr == NULL)
6128 return PyErr_NoMemory();
Anthony Baxter64182fe2006-04-11 12:14:09 +00006129 newenv = PyString_AS_STRING(newstr);
6130 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
6131 if (putenv(newenv)) {
Neal Norwitz4adc9ab2003-02-10 03:10:43 +00006132 Py_DECREF(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006133 posix_error();
6134 return NULL;
6135 }
Fred Drake762e2061999-08-26 17:23:54 +00006136 /* Install the first arg and newstr in posix_putenv_garbage;
6137 * this will cause previous value to be collected. This has to
6138 * happen after the real putenv() call because the old value
6139 * was still accessible until then. */
6140 if (PyDict_SetItem(posix_putenv_garbage,
6141 PyTuple_GET_ITEM(args, 0), newstr)) {
6142 /* really not much we can do; just leak */
6143 PyErr_Clear();
6144 }
6145 else {
6146 Py_DECREF(newstr);
6147 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00006148
6149#if defined(PYOS_OS2)
6150 }
6151#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006152 Py_INCREF(Py_None);
6153 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006154}
Guido van Rossumb6a47161997-09-15 22:54:34 +00006155#endif /* putenv */
6156
Guido van Rossumc524d952001-10-19 01:31:59 +00006157#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006158PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006159"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006160Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00006161
6162static PyObject *
6163posix_unsetenv(PyObject *self, PyObject *args)
6164{
6165 char *s1;
6166
6167 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
6168 return NULL;
6169
6170 unsetenv(s1);
6171
6172 /* Remove the key from posix_putenv_garbage;
6173 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00006174 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00006175 * old value was still accessible until then.
6176 */
6177 if (PyDict_DelItem(posix_putenv_garbage,
6178 PyTuple_GET_ITEM(args, 0))) {
6179 /* really not much we can do; just leak */
6180 PyErr_Clear();
6181 }
6182
6183 Py_INCREF(Py_None);
6184 return Py_None;
6185}
6186#endif /* unsetenv */
6187
Guido van Rossumb6a47161997-09-15 22:54:34 +00006188#ifdef HAVE_STRERROR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006189PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006190"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006191Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00006192
Guido van Rossumf68d8e52001-04-14 17:55:09 +00006193static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006194posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00006195{
6196 int code;
6197 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006198 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00006199 return NULL;
6200 message = strerror(code);
6201 if (message == NULL) {
6202 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00006203 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00006204 return NULL;
6205 }
6206 return PyString_FromString(message);
6207}
6208#endif /* strerror */
6209
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006210
Guido van Rossumc9641791998-08-04 15:26:23 +00006211#ifdef HAVE_SYS_WAIT_H
6212
Fred Drake106c1a02002-04-23 15:58:02 +00006213#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006214PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006215"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006216Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00006217
6218static PyObject *
6219posix_WCOREDUMP(PyObject *self, PyObject *args)
6220{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006221 WAIT_TYPE status;
6222 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006223
Neal Norwitzd5a37542006-03-20 06:48:34 +00006224 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00006225 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006226
6227 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006228}
6229#endif /* WCOREDUMP */
6230
6231#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006232PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006233"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006234Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006235job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00006236
6237static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006238posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00006239{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006240 WAIT_TYPE status;
6241 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006242
Neal Norwitzd5a37542006-03-20 06:48:34 +00006243 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00006244 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006245
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006246 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006247}
6248#endif /* WIFCONTINUED */
6249
Guido van Rossumc9641791998-08-04 15:26:23 +00006250#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006251PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006252"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006253Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006254
6255static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006256posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006257{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006258 WAIT_TYPE status;
6259 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006260
Neal Norwitzd5a37542006-03-20 06:48:34 +00006261 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006262 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006263
Fred Drake106c1a02002-04-23 15:58:02 +00006264 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006265}
6266#endif /* WIFSTOPPED */
6267
6268#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006269PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006270"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006271Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006272
6273static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006274posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006275{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006276 WAIT_TYPE status;
6277 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006278
Neal Norwitzd5a37542006-03-20 06:48:34 +00006279 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006280 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006281
Fred Drake106c1a02002-04-23 15:58:02 +00006282 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006283}
6284#endif /* WIFSIGNALED */
6285
6286#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006287PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006288"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006289Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006290system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006291
6292static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006293posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006294{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006295 WAIT_TYPE status;
6296 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006297
Neal Norwitzd5a37542006-03-20 06:48:34 +00006298 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006299 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006300
Fred Drake106c1a02002-04-23 15:58:02 +00006301 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006302}
6303#endif /* WIFEXITED */
6304
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006305#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006306PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006307"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006308Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006309
6310static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006311posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006312{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006313 WAIT_TYPE status;
6314 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006315
Neal Norwitzd5a37542006-03-20 06:48:34 +00006316 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006317 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006318
Guido van Rossumc9641791998-08-04 15:26:23 +00006319 return Py_BuildValue("i", WEXITSTATUS(status));
6320}
6321#endif /* WEXITSTATUS */
6322
6323#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006324PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006325"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006326Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006327value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006328
6329static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006330posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006331{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006332 WAIT_TYPE status;
6333 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006334
Neal Norwitzd5a37542006-03-20 06:48:34 +00006335 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006336 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006337
Guido van Rossumc9641791998-08-04 15:26:23 +00006338 return Py_BuildValue("i", WTERMSIG(status));
6339}
6340#endif /* WTERMSIG */
6341
6342#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006343PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006344"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006345Return the signal that stopped the process that provided\n\
6346the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006347
6348static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006349posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006350{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006351 WAIT_TYPE status;
6352 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006353
Neal Norwitzd5a37542006-03-20 06:48:34 +00006354 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006355 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006356
Guido van Rossumc9641791998-08-04 15:26:23 +00006357 return Py_BuildValue("i", WSTOPSIG(status));
6358}
6359#endif /* WSTOPSIG */
6360
6361#endif /* HAVE_SYS_WAIT_H */
6362
6363
Guido van Rossum94f6f721999-01-06 18:42:14 +00006364#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00006365#ifdef _SCO_DS
6366/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
6367 needed definitions in sys/statvfs.h */
6368#define _SVID3
6369#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006370#include <sys/statvfs.h>
6371
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006372static PyObject*
6373_pystatvfs_fromstructstatvfs(struct statvfs st) {
6374 PyObject *v = PyStructSequence_New(&StatVFSResultType);
6375 if (v == NULL)
6376 return NULL;
6377
6378#if !defined(HAVE_LARGEFILE_SUPPORT)
6379 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6380 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
6381 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
6382 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
6383 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
6384 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
6385 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
6386 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
6387 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6388 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6389#else
6390 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6391 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00006392 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006393 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00006394 PyStructSequence_SET_ITEM(v, 3,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006395 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006396 PyStructSequence_SET_ITEM(v, 4,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006397 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00006398 PyStructSequence_SET_ITEM(v, 5,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006399 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00006400 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006401 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00006402 PyStructSequence_SET_ITEM(v, 7,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006403 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006404 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6405 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6406#endif
6407
6408 return v;
6409}
6410
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006411PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006412"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006413Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006414
6415static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006416posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006417{
6418 int fd, res;
6419 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006420
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006421 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006422 return NULL;
6423 Py_BEGIN_ALLOW_THREADS
6424 res = fstatvfs(fd, &st);
6425 Py_END_ALLOW_THREADS
6426 if (res != 0)
6427 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006428
6429 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006430}
6431#endif /* HAVE_FSTATVFS */
6432
6433
6434#if defined(HAVE_STATVFS)
6435#include <sys/statvfs.h>
6436
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006437PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006438"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006439Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006440
6441static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006442posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006443{
6444 char *path;
6445 int res;
6446 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006447 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006448 return NULL;
6449 Py_BEGIN_ALLOW_THREADS
6450 res = statvfs(path, &st);
6451 Py_END_ALLOW_THREADS
6452 if (res != 0)
6453 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006454
6455 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006456}
6457#endif /* HAVE_STATVFS */
6458
6459
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006460#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006461PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006462"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006463Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00006464The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006465or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006466
6467static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006468posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006469{
6470 PyObject *result = NULL;
6471 char *dir = NULL;
6472 char *pfx = NULL;
6473 char *name;
6474
6475 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
6476 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00006477
6478 if (PyErr_Warn(PyExc_RuntimeWarning,
6479 "tempnam is a potential security risk to your program") < 0)
6480 return NULL;
6481
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006482#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00006483 name = _tempnam(dir, pfx);
6484#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006485 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00006486#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006487 if (name == NULL)
6488 return PyErr_NoMemory();
6489 result = PyString_FromString(name);
6490 free(name);
6491 return result;
6492}
Guido van Rossumd371ff11999-01-25 16:12:23 +00006493#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006494
6495
6496#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006497PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006498"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006499Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006500
6501static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006502posix_tmpfile(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006503{
6504 FILE *fp;
6505
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006506 fp = tmpfile();
6507 if (fp == NULL)
6508 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00006509 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006510}
6511#endif
6512
6513
6514#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006515PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006516"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006517Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006518
6519static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006520posix_tmpnam(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006521{
6522 char buffer[L_tmpnam];
6523 char *name;
6524
Skip Montanaro95618b52001-08-18 18:52:10 +00006525 if (PyErr_Warn(PyExc_RuntimeWarning,
6526 "tmpnam is a potential security risk to your program") < 0)
6527 return NULL;
6528
Greg Wardb48bc172000-03-01 21:51:56 +00006529#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006530 name = tmpnam_r(buffer);
6531#else
6532 name = tmpnam(buffer);
6533#endif
6534 if (name == NULL) {
Neal Norwitzd1e0ef62006-03-20 04:08:12 +00006535 PyObject *err = Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00006536#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006537 "unexpected NULL from tmpnam_r"
6538#else
6539 "unexpected NULL from tmpnam"
6540#endif
Neal Norwitzd1e0ef62006-03-20 04:08:12 +00006541 );
6542 PyErr_SetObject(PyExc_OSError, err);
6543 Py_XDECREF(err);
6544 return NULL;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006545 }
6546 return PyString_FromString(buffer);
6547}
6548#endif
6549
6550
Fred Drakec9680921999-12-13 16:37:25 +00006551/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
6552 * It maps strings representing configuration variable names to
6553 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00006554 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00006555 * rarely-used constants. There are three separate tables that use
6556 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00006557 *
6558 * This code is always included, even if none of the interfaces that
6559 * need it are included. The #if hackery needed to avoid it would be
6560 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00006561 */
6562struct constdef {
6563 char *name;
6564 long value;
6565};
6566
Fred Drake12c6e2d1999-12-14 21:25:03 +00006567static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006568conv_confname(PyObject *arg, int *valuep, struct constdef *table,
6569 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006570{
6571 if (PyInt_Check(arg)) {
6572 *valuep = PyInt_AS_LONG(arg);
6573 return 1;
6574 }
6575 if (PyString_Check(arg)) {
6576 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00006577 size_t lo = 0;
6578 size_t mid;
6579 size_t hi = tablesize;
6580 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006581 char *confname = PyString_AS_STRING(arg);
6582 while (lo < hi) {
6583 mid = (lo + hi) / 2;
6584 cmp = strcmp(confname, table[mid].name);
6585 if (cmp < 0)
6586 hi = mid;
6587 else if (cmp > 0)
6588 lo = mid + 1;
6589 else {
6590 *valuep = table[mid].value;
6591 return 1;
6592 }
6593 }
6594 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
6595 }
6596 else
6597 PyErr_SetString(PyExc_TypeError,
6598 "configuration names must be strings or integers");
6599 return 0;
6600}
6601
6602
6603#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
6604static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006605#ifdef _PC_ABI_AIO_XFER_MAX
6606 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
6607#endif
6608#ifdef _PC_ABI_ASYNC_IO
6609 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
6610#endif
Fred Drakec9680921999-12-13 16:37:25 +00006611#ifdef _PC_ASYNC_IO
6612 {"PC_ASYNC_IO", _PC_ASYNC_IO},
6613#endif
6614#ifdef _PC_CHOWN_RESTRICTED
6615 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
6616#endif
6617#ifdef _PC_FILESIZEBITS
6618 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
6619#endif
6620#ifdef _PC_LAST
6621 {"PC_LAST", _PC_LAST},
6622#endif
6623#ifdef _PC_LINK_MAX
6624 {"PC_LINK_MAX", _PC_LINK_MAX},
6625#endif
6626#ifdef _PC_MAX_CANON
6627 {"PC_MAX_CANON", _PC_MAX_CANON},
6628#endif
6629#ifdef _PC_MAX_INPUT
6630 {"PC_MAX_INPUT", _PC_MAX_INPUT},
6631#endif
6632#ifdef _PC_NAME_MAX
6633 {"PC_NAME_MAX", _PC_NAME_MAX},
6634#endif
6635#ifdef _PC_NO_TRUNC
6636 {"PC_NO_TRUNC", _PC_NO_TRUNC},
6637#endif
6638#ifdef _PC_PATH_MAX
6639 {"PC_PATH_MAX", _PC_PATH_MAX},
6640#endif
6641#ifdef _PC_PIPE_BUF
6642 {"PC_PIPE_BUF", _PC_PIPE_BUF},
6643#endif
6644#ifdef _PC_PRIO_IO
6645 {"PC_PRIO_IO", _PC_PRIO_IO},
6646#endif
6647#ifdef _PC_SOCK_MAXBUF
6648 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
6649#endif
6650#ifdef _PC_SYNC_IO
6651 {"PC_SYNC_IO", _PC_SYNC_IO},
6652#endif
6653#ifdef _PC_VDISABLE
6654 {"PC_VDISABLE", _PC_VDISABLE},
6655#endif
6656};
6657
Fred Drakec9680921999-12-13 16:37:25 +00006658static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006659conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006660{
6661 return conv_confname(arg, valuep, posix_constants_pathconf,
6662 sizeof(posix_constants_pathconf)
6663 / sizeof(struct constdef));
6664}
6665#endif
6666
6667#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006668PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006669"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006670Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006671If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006672
6673static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006674posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006675{
6676 PyObject *result = NULL;
6677 int name, fd;
6678
Fred Drake12c6e2d1999-12-14 21:25:03 +00006679 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
6680 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00006681 long limit;
6682
6683 errno = 0;
6684 limit = fpathconf(fd, name);
6685 if (limit == -1 && errno != 0)
6686 posix_error();
6687 else
6688 result = PyInt_FromLong(limit);
6689 }
6690 return result;
6691}
6692#endif
6693
6694
6695#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006696PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006697"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006698Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006699If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006700
6701static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006702posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006703{
6704 PyObject *result = NULL;
6705 int name;
6706 char *path;
6707
6708 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
6709 conv_path_confname, &name)) {
6710 long limit;
6711
6712 errno = 0;
6713 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006714 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00006715 if (errno == EINVAL)
6716 /* could be a path or name problem */
6717 posix_error();
6718 else
6719 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006720 }
Fred Drakec9680921999-12-13 16:37:25 +00006721 else
6722 result = PyInt_FromLong(limit);
6723 }
6724 return result;
6725}
6726#endif
6727
6728#ifdef HAVE_CONFSTR
6729static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006730#ifdef _CS_ARCHITECTURE
6731 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
6732#endif
6733#ifdef _CS_HOSTNAME
6734 {"CS_HOSTNAME", _CS_HOSTNAME},
6735#endif
6736#ifdef _CS_HW_PROVIDER
6737 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
6738#endif
6739#ifdef _CS_HW_SERIAL
6740 {"CS_HW_SERIAL", _CS_HW_SERIAL},
6741#endif
6742#ifdef _CS_INITTAB_NAME
6743 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
6744#endif
Fred Drakec9680921999-12-13 16:37:25 +00006745#ifdef _CS_LFS64_CFLAGS
6746 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
6747#endif
6748#ifdef _CS_LFS64_LDFLAGS
6749 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
6750#endif
6751#ifdef _CS_LFS64_LIBS
6752 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
6753#endif
6754#ifdef _CS_LFS64_LINTFLAGS
6755 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
6756#endif
6757#ifdef _CS_LFS_CFLAGS
6758 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
6759#endif
6760#ifdef _CS_LFS_LDFLAGS
6761 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
6762#endif
6763#ifdef _CS_LFS_LIBS
6764 {"CS_LFS_LIBS", _CS_LFS_LIBS},
6765#endif
6766#ifdef _CS_LFS_LINTFLAGS
6767 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
6768#endif
Fred Draked86ed291999-12-15 15:34:33 +00006769#ifdef _CS_MACHINE
6770 {"CS_MACHINE", _CS_MACHINE},
6771#endif
Fred Drakec9680921999-12-13 16:37:25 +00006772#ifdef _CS_PATH
6773 {"CS_PATH", _CS_PATH},
6774#endif
Fred Draked86ed291999-12-15 15:34:33 +00006775#ifdef _CS_RELEASE
6776 {"CS_RELEASE", _CS_RELEASE},
6777#endif
6778#ifdef _CS_SRPC_DOMAIN
6779 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
6780#endif
6781#ifdef _CS_SYSNAME
6782 {"CS_SYSNAME", _CS_SYSNAME},
6783#endif
6784#ifdef _CS_VERSION
6785 {"CS_VERSION", _CS_VERSION},
6786#endif
Fred Drakec9680921999-12-13 16:37:25 +00006787#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
6788 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
6789#endif
6790#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
6791 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
6792#endif
6793#ifdef _CS_XBS5_ILP32_OFF32_LIBS
6794 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
6795#endif
6796#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
6797 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
6798#endif
6799#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
6800 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
6801#endif
6802#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
6803 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
6804#endif
6805#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
6806 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
6807#endif
6808#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
6809 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
6810#endif
6811#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
6812 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
6813#endif
6814#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
6815 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
6816#endif
6817#ifdef _CS_XBS5_LP64_OFF64_LIBS
6818 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
6819#endif
6820#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
6821 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
6822#endif
6823#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
6824 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
6825#endif
6826#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
6827 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
6828#endif
6829#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
6830 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
6831#endif
6832#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
6833 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
6834#endif
Fred Draked86ed291999-12-15 15:34:33 +00006835#ifdef _MIPS_CS_AVAIL_PROCESSORS
6836 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
6837#endif
6838#ifdef _MIPS_CS_BASE
6839 {"MIPS_CS_BASE", _MIPS_CS_BASE},
6840#endif
6841#ifdef _MIPS_CS_HOSTID
6842 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
6843#endif
6844#ifdef _MIPS_CS_HW_NAME
6845 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
6846#endif
6847#ifdef _MIPS_CS_NUM_PROCESSORS
6848 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
6849#endif
6850#ifdef _MIPS_CS_OSREL_MAJ
6851 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
6852#endif
6853#ifdef _MIPS_CS_OSREL_MIN
6854 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
6855#endif
6856#ifdef _MIPS_CS_OSREL_PATCH
6857 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
6858#endif
6859#ifdef _MIPS_CS_OS_NAME
6860 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
6861#endif
6862#ifdef _MIPS_CS_OS_PROVIDER
6863 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
6864#endif
6865#ifdef _MIPS_CS_PROCESSORS
6866 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
6867#endif
6868#ifdef _MIPS_CS_SERIAL
6869 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
6870#endif
6871#ifdef _MIPS_CS_VENDOR
6872 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
6873#endif
Fred Drakec9680921999-12-13 16:37:25 +00006874};
6875
6876static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006877conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006878{
6879 return conv_confname(arg, valuep, posix_constants_confstr,
6880 sizeof(posix_constants_confstr)
6881 / sizeof(struct constdef));
6882}
6883
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006884PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006885"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006886Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006887
6888static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006889posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006890{
6891 PyObject *result = NULL;
6892 int name;
Neal Norwitz449b24e2006-04-20 06:56:05 +00006893 char buffer[256];
Fred Drakec9680921999-12-13 16:37:25 +00006894
6895 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
Skip Montanarodd527fc2006-04-18 00:49:49 +00006896 int len;
Fred Drakec9680921999-12-13 16:37:25 +00006897
Fred Drakec9680921999-12-13 16:37:25 +00006898 errno = 0;
Skip Montanarodd527fc2006-04-18 00:49:49 +00006899 len = confstr(name, buffer, sizeof(buffer));
Skip Montanaro94785ef2006-04-20 01:29:48 +00006900 if (len == 0) {
6901 if (errno) {
6902 posix_error();
6903 }
6904 else {
6905 result = Py_None;
6906 Py_INCREF(Py_None);
6907 }
Fred Drakec9680921999-12-13 16:37:25 +00006908 }
6909 else {
Neal Norwitz0d21b1e2006-04-20 06:44:42 +00006910 if ((unsigned int)len >= sizeof(buffer)) {
Neal Norwitz449b24e2006-04-20 06:56:05 +00006911 result = PyString_FromStringAndSize(NULL, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00006912 if (result != NULL)
Neal Norwitz449b24e2006-04-20 06:56:05 +00006913 confstr(name, PyString_AS_STRING(result), len);
Fred Drakec9680921999-12-13 16:37:25 +00006914 }
6915 else
Neal Norwitz449b24e2006-04-20 06:56:05 +00006916 result = PyString_FromStringAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00006917 }
6918 }
6919 return result;
6920}
6921#endif
6922
6923
6924#ifdef HAVE_SYSCONF
6925static struct constdef posix_constants_sysconf[] = {
6926#ifdef _SC_2_CHAR_TERM
6927 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
6928#endif
6929#ifdef _SC_2_C_BIND
6930 {"SC_2_C_BIND", _SC_2_C_BIND},
6931#endif
6932#ifdef _SC_2_C_DEV
6933 {"SC_2_C_DEV", _SC_2_C_DEV},
6934#endif
6935#ifdef _SC_2_C_VERSION
6936 {"SC_2_C_VERSION", _SC_2_C_VERSION},
6937#endif
6938#ifdef _SC_2_FORT_DEV
6939 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
6940#endif
6941#ifdef _SC_2_FORT_RUN
6942 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
6943#endif
6944#ifdef _SC_2_LOCALEDEF
6945 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
6946#endif
6947#ifdef _SC_2_SW_DEV
6948 {"SC_2_SW_DEV", _SC_2_SW_DEV},
6949#endif
6950#ifdef _SC_2_UPE
6951 {"SC_2_UPE", _SC_2_UPE},
6952#endif
6953#ifdef _SC_2_VERSION
6954 {"SC_2_VERSION", _SC_2_VERSION},
6955#endif
Fred Draked86ed291999-12-15 15:34:33 +00006956#ifdef _SC_ABI_ASYNCHRONOUS_IO
6957 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
6958#endif
6959#ifdef _SC_ACL
6960 {"SC_ACL", _SC_ACL},
6961#endif
Fred Drakec9680921999-12-13 16:37:25 +00006962#ifdef _SC_AIO_LISTIO_MAX
6963 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
6964#endif
Fred Drakec9680921999-12-13 16:37:25 +00006965#ifdef _SC_AIO_MAX
6966 {"SC_AIO_MAX", _SC_AIO_MAX},
6967#endif
6968#ifdef _SC_AIO_PRIO_DELTA_MAX
6969 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
6970#endif
6971#ifdef _SC_ARG_MAX
6972 {"SC_ARG_MAX", _SC_ARG_MAX},
6973#endif
6974#ifdef _SC_ASYNCHRONOUS_IO
6975 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
6976#endif
6977#ifdef _SC_ATEXIT_MAX
6978 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
6979#endif
Fred Draked86ed291999-12-15 15:34:33 +00006980#ifdef _SC_AUDIT
6981 {"SC_AUDIT", _SC_AUDIT},
6982#endif
Fred Drakec9680921999-12-13 16:37:25 +00006983#ifdef _SC_AVPHYS_PAGES
6984 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
6985#endif
6986#ifdef _SC_BC_BASE_MAX
6987 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
6988#endif
6989#ifdef _SC_BC_DIM_MAX
6990 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
6991#endif
6992#ifdef _SC_BC_SCALE_MAX
6993 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
6994#endif
6995#ifdef _SC_BC_STRING_MAX
6996 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
6997#endif
Fred Draked86ed291999-12-15 15:34:33 +00006998#ifdef _SC_CAP
6999 {"SC_CAP", _SC_CAP},
7000#endif
Fred Drakec9680921999-12-13 16:37:25 +00007001#ifdef _SC_CHARCLASS_NAME_MAX
7002 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
7003#endif
7004#ifdef _SC_CHAR_BIT
7005 {"SC_CHAR_BIT", _SC_CHAR_BIT},
7006#endif
7007#ifdef _SC_CHAR_MAX
7008 {"SC_CHAR_MAX", _SC_CHAR_MAX},
7009#endif
7010#ifdef _SC_CHAR_MIN
7011 {"SC_CHAR_MIN", _SC_CHAR_MIN},
7012#endif
7013#ifdef _SC_CHILD_MAX
7014 {"SC_CHILD_MAX", _SC_CHILD_MAX},
7015#endif
7016#ifdef _SC_CLK_TCK
7017 {"SC_CLK_TCK", _SC_CLK_TCK},
7018#endif
7019#ifdef _SC_COHER_BLKSZ
7020 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
7021#endif
7022#ifdef _SC_COLL_WEIGHTS_MAX
7023 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
7024#endif
7025#ifdef _SC_DCACHE_ASSOC
7026 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
7027#endif
7028#ifdef _SC_DCACHE_BLKSZ
7029 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
7030#endif
7031#ifdef _SC_DCACHE_LINESZ
7032 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
7033#endif
7034#ifdef _SC_DCACHE_SZ
7035 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
7036#endif
7037#ifdef _SC_DCACHE_TBLKSZ
7038 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
7039#endif
7040#ifdef _SC_DELAYTIMER_MAX
7041 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
7042#endif
7043#ifdef _SC_EQUIV_CLASS_MAX
7044 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
7045#endif
7046#ifdef _SC_EXPR_NEST_MAX
7047 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
7048#endif
7049#ifdef _SC_FSYNC
7050 {"SC_FSYNC", _SC_FSYNC},
7051#endif
7052#ifdef _SC_GETGR_R_SIZE_MAX
7053 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
7054#endif
7055#ifdef _SC_GETPW_R_SIZE_MAX
7056 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
7057#endif
7058#ifdef _SC_ICACHE_ASSOC
7059 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
7060#endif
7061#ifdef _SC_ICACHE_BLKSZ
7062 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
7063#endif
7064#ifdef _SC_ICACHE_LINESZ
7065 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
7066#endif
7067#ifdef _SC_ICACHE_SZ
7068 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
7069#endif
Fred Draked86ed291999-12-15 15:34:33 +00007070#ifdef _SC_INF
7071 {"SC_INF", _SC_INF},
7072#endif
Fred Drakec9680921999-12-13 16:37:25 +00007073#ifdef _SC_INT_MAX
7074 {"SC_INT_MAX", _SC_INT_MAX},
7075#endif
7076#ifdef _SC_INT_MIN
7077 {"SC_INT_MIN", _SC_INT_MIN},
7078#endif
7079#ifdef _SC_IOV_MAX
7080 {"SC_IOV_MAX", _SC_IOV_MAX},
7081#endif
Fred Draked86ed291999-12-15 15:34:33 +00007082#ifdef _SC_IP_SECOPTS
7083 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
7084#endif
Fred Drakec9680921999-12-13 16:37:25 +00007085#ifdef _SC_JOB_CONTROL
7086 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
7087#endif
Fred Draked86ed291999-12-15 15:34:33 +00007088#ifdef _SC_KERN_POINTERS
7089 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
7090#endif
7091#ifdef _SC_KERN_SIM
7092 {"SC_KERN_SIM", _SC_KERN_SIM},
7093#endif
Fred Drakec9680921999-12-13 16:37:25 +00007094#ifdef _SC_LINE_MAX
7095 {"SC_LINE_MAX", _SC_LINE_MAX},
7096#endif
7097#ifdef _SC_LOGIN_NAME_MAX
7098 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
7099#endif
7100#ifdef _SC_LOGNAME_MAX
7101 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
7102#endif
7103#ifdef _SC_LONG_BIT
7104 {"SC_LONG_BIT", _SC_LONG_BIT},
7105#endif
Fred Draked86ed291999-12-15 15:34:33 +00007106#ifdef _SC_MAC
7107 {"SC_MAC", _SC_MAC},
7108#endif
Fred Drakec9680921999-12-13 16:37:25 +00007109#ifdef _SC_MAPPED_FILES
7110 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
7111#endif
7112#ifdef _SC_MAXPID
7113 {"SC_MAXPID", _SC_MAXPID},
7114#endif
7115#ifdef _SC_MB_LEN_MAX
7116 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
7117#endif
7118#ifdef _SC_MEMLOCK
7119 {"SC_MEMLOCK", _SC_MEMLOCK},
7120#endif
7121#ifdef _SC_MEMLOCK_RANGE
7122 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
7123#endif
7124#ifdef _SC_MEMORY_PROTECTION
7125 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
7126#endif
7127#ifdef _SC_MESSAGE_PASSING
7128 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
7129#endif
Fred Draked86ed291999-12-15 15:34:33 +00007130#ifdef _SC_MMAP_FIXED_ALIGNMENT
7131 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
7132#endif
Fred Drakec9680921999-12-13 16:37:25 +00007133#ifdef _SC_MQ_OPEN_MAX
7134 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
7135#endif
7136#ifdef _SC_MQ_PRIO_MAX
7137 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
7138#endif
Fred Draked86ed291999-12-15 15:34:33 +00007139#ifdef _SC_NACLS_MAX
7140 {"SC_NACLS_MAX", _SC_NACLS_MAX},
7141#endif
Fred Drakec9680921999-12-13 16:37:25 +00007142#ifdef _SC_NGROUPS_MAX
7143 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
7144#endif
7145#ifdef _SC_NL_ARGMAX
7146 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
7147#endif
7148#ifdef _SC_NL_LANGMAX
7149 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
7150#endif
7151#ifdef _SC_NL_MSGMAX
7152 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
7153#endif
7154#ifdef _SC_NL_NMAX
7155 {"SC_NL_NMAX", _SC_NL_NMAX},
7156#endif
7157#ifdef _SC_NL_SETMAX
7158 {"SC_NL_SETMAX", _SC_NL_SETMAX},
7159#endif
7160#ifdef _SC_NL_TEXTMAX
7161 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
7162#endif
7163#ifdef _SC_NPROCESSORS_CONF
7164 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
7165#endif
7166#ifdef _SC_NPROCESSORS_ONLN
7167 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
7168#endif
Fred Draked86ed291999-12-15 15:34:33 +00007169#ifdef _SC_NPROC_CONF
7170 {"SC_NPROC_CONF", _SC_NPROC_CONF},
7171#endif
7172#ifdef _SC_NPROC_ONLN
7173 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
7174#endif
Fred Drakec9680921999-12-13 16:37:25 +00007175#ifdef _SC_NZERO
7176 {"SC_NZERO", _SC_NZERO},
7177#endif
7178#ifdef _SC_OPEN_MAX
7179 {"SC_OPEN_MAX", _SC_OPEN_MAX},
7180#endif
7181#ifdef _SC_PAGESIZE
7182 {"SC_PAGESIZE", _SC_PAGESIZE},
7183#endif
7184#ifdef _SC_PAGE_SIZE
7185 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
7186#endif
7187#ifdef _SC_PASS_MAX
7188 {"SC_PASS_MAX", _SC_PASS_MAX},
7189#endif
7190#ifdef _SC_PHYS_PAGES
7191 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
7192#endif
7193#ifdef _SC_PII
7194 {"SC_PII", _SC_PII},
7195#endif
7196#ifdef _SC_PII_INTERNET
7197 {"SC_PII_INTERNET", _SC_PII_INTERNET},
7198#endif
7199#ifdef _SC_PII_INTERNET_DGRAM
7200 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
7201#endif
7202#ifdef _SC_PII_INTERNET_STREAM
7203 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
7204#endif
7205#ifdef _SC_PII_OSI
7206 {"SC_PII_OSI", _SC_PII_OSI},
7207#endif
7208#ifdef _SC_PII_OSI_CLTS
7209 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
7210#endif
7211#ifdef _SC_PII_OSI_COTS
7212 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
7213#endif
7214#ifdef _SC_PII_OSI_M
7215 {"SC_PII_OSI_M", _SC_PII_OSI_M},
7216#endif
7217#ifdef _SC_PII_SOCKET
7218 {"SC_PII_SOCKET", _SC_PII_SOCKET},
7219#endif
7220#ifdef _SC_PII_XTI
7221 {"SC_PII_XTI", _SC_PII_XTI},
7222#endif
7223#ifdef _SC_POLL
7224 {"SC_POLL", _SC_POLL},
7225#endif
7226#ifdef _SC_PRIORITIZED_IO
7227 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
7228#endif
7229#ifdef _SC_PRIORITY_SCHEDULING
7230 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
7231#endif
7232#ifdef _SC_REALTIME_SIGNALS
7233 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
7234#endif
7235#ifdef _SC_RE_DUP_MAX
7236 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
7237#endif
7238#ifdef _SC_RTSIG_MAX
7239 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
7240#endif
7241#ifdef _SC_SAVED_IDS
7242 {"SC_SAVED_IDS", _SC_SAVED_IDS},
7243#endif
7244#ifdef _SC_SCHAR_MAX
7245 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
7246#endif
7247#ifdef _SC_SCHAR_MIN
7248 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
7249#endif
7250#ifdef _SC_SELECT
7251 {"SC_SELECT", _SC_SELECT},
7252#endif
7253#ifdef _SC_SEMAPHORES
7254 {"SC_SEMAPHORES", _SC_SEMAPHORES},
7255#endif
7256#ifdef _SC_SEM_NSEMS_MAX
7257 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
7258#endif
7259#ifdef _SC_SEM_VALUE_MAX
7260 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
7261#endif
7262#ifdef _SC_SHARED_MEMORY_OBJECTS
7263 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
7264#endif
7265#ifdef _SC_SHRT_MAX
7266 {"SC_SHRT_MAX", _SC_SHRT_MAX},
7267#endif
7268#ifdef _SC_SHRT_MIN
7269 {"SC_SHRT_MIN", _SC_SHRT_MIN},
7270#endif
7271#ifdef _SC_SIGQUEUE_MAX
7272 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
7273#endif
7274#ifdef _SC_SIGRT_MAX
7275 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
7276#endif
7277#ifdef _SC_SIGRT_MIN
7278 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
7279#endif
Fred Draked86ed291999-12-15 15:34:33 +00007280#ifdef _SC_SOFTPOWER
7281 {"SC_SOFTPOWER", _SC_SOFTPOWER},
7282#endif
Fred Drakec9680921999-12-13 16:37:25 +00007283#ifdef _SC_SPLIT_CACHE
7284 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
7285#endif
7286#ifdef _SC_SSIZE_MAX
7287 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
7288#endif
7289#ifdef _SC_STACK_PROT
7290 {"SC_STACK_PROT", _SC_STACK_PROT},
7291#endif
7292#ifdef _SC_STREAM_MAX
7293 {"SC_STREAM_MAX", _SC_STREAM_MAX},
7294#endif
7295#ifdef _SC_SYNCHRONIZED_IO
7296 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
7297#endif
7298#ifdef _SC_THREADS
7299 {"SC_THREADS", _SC_THREADS},
7300#endif
7301#ifdef _SC_THREAD_ATTR_STACKADDR
7302 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
7303#endif
7304#ifdef _SC_THREAD_ATTR_STACKSIZE
7305 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
7306#endif
7307#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
7308 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
7309#endif
7310#ifdef _SC_THREAD_KEYS_MAX
7311 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
7312#endif
7313#ifdef _SC_THREAD_PRIORITY_SCHEDULING
7314 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
7315#endif
7316#ifdef _SC_THREAD_PRIO_INHERIT
7317 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
7318#endif
7319#ifdef _SC_THREAD_PRIO_PROTECT
7320 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
7321#endif
7322#ifdef _SC_THREAD_PROCESS_SHARED
7323 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
7324#endif
7325#ifdef _SC_THREAD_SAFE_FUNCTIONS
7326 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
7327#endif
7328#ifdef _SC_THREAD_STACK_MIN
7329 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
7330#endif
7331#ifdef _SC_THREAD_THREADS_MAX
7332 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
7333#endif
7334#ifdef _SC_TIMERS
7335 {"SC_TIMERS", _SC_TIMERS},
7336#endif
7337#ifdef _SC_TIMER_MAX
7338 {"SC_TIMER_MAX", _SC_TIMER_MAX},
7339#endif
7340#ifdef _SC_TTY_NAME_MAX
7341 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
7342#endif
7343#ifdef _SC_TZNAME_MAX
7344 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
7345#endif
7346#ifdef _SC_T_IOV_MAX
7347 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
7348#endif
7349#ifdef _SC_UCHAR_MAX
7350 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
7351#endif
7352#ifdef _SC_UINT_MAX
7353 {"SC_UINT_MAX", _SC_UINT_MAX},
7354#endif
7355#ifdef _SC_UIO_MAXIOV
7356 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
7357#endif
7358#ifdef _SC_ULONG_MAX
7359 {"SC_ULONG_MAX", _SC_ULONG_MAX},
7360#endif
7361#ifdef _SC_USHRT_MAX
7362 {"SC_USHRT_MAX", _SC_USHRT_MAX},
7363#endif
7364#ifdef _SC_VERSION
7365 {"SC_VERSION", _SC_VERSION},
7366#endif
7367#ifdef _SC_WORD_BIT
7368 {"SC_WORD_BIT", _SC_WORD_BIT},
7369#endif
7370#ifdef _SC_XBS5_ILP32_OFF32
7371 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
7372#endif
7373#ifdef _SC_XBS5_ILP32_OFFBIG
7374 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
7375#endif
7376#ifdef _SC_XBS5_LP64_OFF64
7377 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
7378#endif
7379#ifdef _SC_XBS5_LPBIG_OFFBIG
7380 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
7381#endif
7382#ifdef _SC_XOPEN_CRYPT
7383 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
7384#endif
7385#ifdef _SC_XOPEN_ENH_I18N
7386 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
7387#endif
7388#ifdef _SC_XOPEN_LEGACY
7389 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
7390#endif
7391#ifdef _SC_XOPEN_REALTIME
7392 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
7393#endif
7394#ifdef _SC_XOPEN_REALTIME_THREADS
7395 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
7396#endif
7397#ifdef _SC_XOPEN_SHM
7398 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
7399#endif
7400#ifdef _SC_XOPEN_UNIX
7401 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
7402#endif
7403#ifdef _SC_XOPEN_VERSION
7404 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
7405#endif
7406#ifdef _SC_XOPEN_XCU_VERSION
7407 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
7408#endif
7409#ifdef _SC_XOPEN_XPG2
7410 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
7411#endif
7412#ifdef _SC_XOPEN_XPG3
7413 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
7414#endif
7415#ifdef _SC_XOPEN_XPG4
7416 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
7417#endif
7418};
7419
7420static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007421conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007422{
7423 return conv_confname(arg, valuep, posix_constants_sysconf,
7424 sizeof(posix_constants_sysconf)
7425 / sizeof(struct constdef));
7426}
7427
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007428PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007429"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007430Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007431
7432static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007433posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007434{
7435 PyObject *result = NULL;
7436 int name;
7437
7438 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
7439 int value;
7440
7441 errno = 0;
7442 value = sysconf(name);
7443 if (value == -1 && errno != 0)
7444 posix_error();
7445 else
7446 result = PyInt_FromLong(value);
7447 }
7448 return result;
7449}
7450#endif
7451
7452
Fred Drakebec628d1999-12-15 18:31:10 +00007453/* This code is used to ensure that the tables of configuration value names
7454 * are in sorted order as required by conv_confname(), and also to build the
7455 * the exported dictionaries that are used to publish information about the
7456 * names available on the host platform.
7457 *
7458 * Sorting the table at runtime ensures that the table is properly ordered
7459 * when used, even for platforms we're not able to test on. It also makes
7460 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00007461 */
Fred Drakebec628d1999-12-15 18:31:10 +00007462
7463static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007464cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00007465{
7466 const struct constdef *c1 =
7467 (const struct constdef *) v1;
7468 const struct constdef *c2 =
7469 (const struct constdef *) v2;
7470
7471 return strcmp(c1->name, c2->name);
7472}
7473
7474static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007475setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00007476 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007477{
Fred Drakebec628d1999-12-15 18:31:10 +00007478 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00007479 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00007480
7481 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
7482 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00007483 if (d == NULL)
7484 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007485
Barry Warsaw3155db32000-04-13 15:20:40 +00007486 for (i=0; i < tablesize; ++i) {
7487 PyObject *o = PyInt_FromLong(table[i].value);
7488 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
7489 Py_XDECREF(o);
7490 Py_DECREF(d);
7491 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007492 }
Barry Warsaw3155db32000-04-13 15:20:40 +00007493 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00007494 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00007495 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00007496}
7497
Fred Drakebec628d1999-12-15 18:31:10 +00007498/* Return -1 on failure, 0 on success. */
7499static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007500setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007501{
7502#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00007503 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00007504 sizeof(posix_constants_pathconf)
7505 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007506 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007507 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007508#endif
7509#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00007510 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00007511 sizeof(posix_constants_confstr)
7512 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007513 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007514 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007515#endif
7516#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00007517 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00007518 sizeof(posix_constants_sysconf)
7519 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007520 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007521 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007522#endif
Fred Drakebec628d1999-12-15 18:31:10 +00007523 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00007524}
Fred Draked86ed291999-12-15 15:34:33 +00007525
7526
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007527PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007528"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007529Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007530in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007531
7532static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007533posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007534{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007535 abort();
7536 /*NOTREACHED*/
7537 Py_FatalError("abort() called from Python code didn't abort!");
7538 return NULL;
7539}
Fred Drakebec628d1999-12-15 18:31:10 +00007540
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007541#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007542PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00007543"startfile(filepath [, operation]) - Start a file with its associated\n\
7544application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007545\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00007546When \"operation\" is not specified or \"open\", this acts like\n\
7547double-clicking the file in Explorer, or giving the file name as an\n\
7548argument to the DOS \"start\" command: the file is opened with whatever\n\
7549application (if any) its extension is associated.\n\
7550When another \"operation\" is given, it specifies what should be done with\n\
7551the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007552\n\
7553startfile returns as soon as the associated application is launched.\n\
7554There is no option to wait for the application to close, and no way\n\
7555to retrieve the application's exit status.\n\
7556\n\
7557The filepath is relative to the current directory. If you want to use\n\
7558an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007559the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00007560
7561static PyObject *
7562win32_startfile(PyObject *self, PyObject *args)
7563{
7564 char *filepath;
Georg Brandlf4f44152006-02-18 22:29:33 +00007565 char *operation = NULL;
Tim Petersf58a7aa2000-09-22 10:05:54 +00007566 HINSTANCE rc;
Georg Brandlad89dc82006-04-03 12:26:26 +00007567#ifdef Py_WIN_WIDE_FILENAMES
7568 if (unicode_file_names()) {
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00007569 PyObject *unipath, *woperation = NULL;
Georg Brandlad89dc82006-04-03 12:26:26 +00007570 if (!PyArg_ParseTuple(args, "U|s:startfile",
7571 &unipath, &operation)) {
7572 PyErr_Clear();
7573 goto normal;
7574 }
7575
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00007576
7577 if (operation) {
7578 woperation = PyUnicode_DecodeASCII(operation,
7579 strlen(operation), NULL);
7580 if (!woperation) {
7581 PyErr_Clear();
7582 operation = NULL;
7583 goto normal;
7584 }
Georg Brandlad89dc82006-04-03 12:26:26 +00007585 }
7586
7587 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00007588 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
Georg Brandlad89dc82006-04-03 12:26:26 +00007589 PyUnicode_AS_UNICODE(unipath),
Georg Brandlad89dc82006-04-03 12:26:26 +00007590 NULL, NULL, SW_SHOWNORMAL);
7591 Py_END_ALLOW_THREADS
7592
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00007593 Py_XDECREF(woperation);
Georg Brandlad89dc82006-04-03 12:26:26 +00007594 if (rc <= (HINSTANCE)32) {
7595 PyObject *errval = win32_error_unicode("startfile",
7596 PyUnicode_AS_UNICODE(unipath));
7597 return errval;
7598 }
7599 Py_INCREF(Py_None);
7600 return Py_None;
7601 }
7602#endif
7603
7604normal:
Georg Brandlf4f44152006-02-18 22:29:33 +00007605 if (!PyArg_ParseTuple(args, "et|s:startfile",
7606 Py_FileSystemDefaultEncoding, &filepath,
7607 &operation))
Tim Petersf58a7aa2000-09-22 10:05:54 +00007608 return NULL;
7609 Py_BEGIN_ALLOW_THREADS
Georg Brandlf4f44152006-02-18 22:29:33 +00007610 rc = ShellExecute((HWND)0, operation, filepath,
7611 NULL, NULL, SW_SHOWNORMAL);
Tim Petersf58a7aa2000-09-22 10:05:54 +00007612 Py_END_ALLOW_THREADS
Georg Brandle9f8ec92005-09-25 06:16:40 +00007613 if (rc <= (HINSTANCE)32) {
7614 PyObject *errval = win32_error("startfile", filepath);
7615 PyMem_Free(filepath);
7616 return errval;
7617 }
7618 PyMem_Free(filepath);
Tim Petersf58a7aa2000-09-22 10:05:54 +00007619 Py_INCREF(Py_None);
7620 return Py_None;
7621}
7622#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007623
Martin v. Löwis438b5342002-12-27 10:16:42 +00007624#ifdef HAVE_GETLOADAVG
7625PyDoc_STRVAR(posix_getloadavg__doc__,
7626"getloadavg() -> (float, float, float)\n\n\
7627Return the number of processes in the system run queue averaged over\n\
7628the last 1, 5, and 15 minutes or raises OSError if the load average\n\
7629was unobtainable");
7630
7631static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007632posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00007633{
7634 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00007635 if (getloadavg(loadavg, 3)!=3) {
7636 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
7637 return NULL;
7638 } else
7639 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
7640}
7641#endif
7642
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007643#ifdef MS_WINDOWS
7644
7645PyDoc_STRVAR(win32_urandom__doc__,
7646"urandom(n) -> str\n\n\
7647Return a string of n random bytes suitable for cryptographic use.");
7648
7649typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
7650 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
7651 DWORD dwFlags );
7652typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
7653 BYTE *pbBuffer );
7654
7655static CRYPTGENRANDOM pCryptGenRandom = NULL;
7656static HCRYPTPROV hCryptProv = 0;
7657
Tim Peters4ad82172004-08-30 17:02:04 +00007658static PyObject*
7659win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007660{
Tim Petersd3115382004-08-30 17:36:46 +00007661 int howMany;
7662 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007663
Tim Peters4ad82172004-08-30 17:02:04 +00007664 /* Read arguments */
Tim Peters9b279a82004-08-30 17:10:53 +00007665 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
Tim Peters4ad82172004-08-30 17:02:04 +00007666 return NULL;
Tim Peters51eba612004-08-30 17:08:02 +00007667 if (howMany < 0)
7668 return PyErr_Format(PyExc_ValueError,
7669 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007670
Tim Peters4ad82172004-08-30 17:02:04 +00007671 if (hCryptProv == 0) {
7672 HINSTANCE hAdvAPI32 = NULL;
7673 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007674
Tim Peters4ad82172004-08-30 17:02:04 +00007675 /* Obtain handle to the DLL containing CryptoAPI
7676 This should not fail */
7677 hAdvAPI32 = GetModuleHandle("advapi32.dll");
7678 if(hAdvAPI32 == NULL)
7679 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007680
Tim Peters4ad82172004-08-30 17:02:04 +00007681 /* Obtain pointers to the CryptoAPI functions
7682 This will fail on some early versions of Win95 */
7683 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
7684 hAdvAPI32,
7685 "CryptAcquireContextA");
7686 if (pCryptAcquireContext == NULL)
7687 return PyErr_Format(PyExc_NotImplementedError,
7688 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007689
Tim Peters4ad82172004-08-30 17:02:04 +00007690 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
7691 hAdvAPI32, "CryptGenRandom");
7692 if (pCryptAcquireContext == NULL)
7693 return PyErr_Format(PyExc_NotImplementedError,
7694 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007695
Tim Peters4ad82172004-08-30 17:02:04 +00007696 /* Acquire context */
7697 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
7698 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
7699 return win32_error("CryptAcquireContext", NULL);
7700 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007701
Tim Peters4ad82172004-08-30 17:02:04 +00007702 /* Allocate bytes */
Tim Petersd3115382004-08-30 17:36:46 +00007703 result = PyString_FromStringAndSize(NULL, howMany);
7704 if (result != NULL) {
7705 /* Get random data */
7706 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
7707 PyString_AS_STRING(result))) {
7708 Py_DECREF(result);
7709 return win32_error("CryptGenRandom", NULL);
7710 }
Tim Peters4ad82172004-08-30 17:02:04 +00007711 }
Tim Petersd3115382004-08-30 17:36:46 +00007712 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007713}
7714#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007715
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007716static PyMethodDef posix_methods[] = {
7717 {"access", posix_access, METH_VARARGS, posix_access__doc__},
7718#ifdef HAVE_TTYNAME
7719 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
7720#endif
7721 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
7722 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007723#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007724 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007725#endif /* HAVE_CHOWN */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007726#ifdef HAVE_LCHOWN
7727 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
7728#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00007729#ifdef HAVE_CHROOT
7730 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
7731#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007732#ifdef HAVE_CTERMID
Neal Norwitze241ce82003-02-17 18:17:05 +00007733 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007734#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00007735#ifdef HAVE_GETCWD
Neal Norwitze241ce82003-02-17 18:17:05 +00007736 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Walter Dörwald3b918c32002-11-21 20:18:46 +00007737#ifdef Py_USING_UNICODE
Neal Norwitze241ce82003-02-17 18:17:05 +00007738 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00007739#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00007740#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007741#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007742 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007743#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007744 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
7745 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
7746 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007747#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007748 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007749#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007750#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007751 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007752#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007753 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
7754 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
7755 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007756 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007757#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007758 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007759#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007760#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007761 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007762#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007763 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007764#ifdef HAVE_UNAME
Neal Norwitze241ce82003-02-17 18:17:05 +00007765 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007766#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007767 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
7768 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
7769 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007770#ifdef HAVE_TIMES
Neal Norwitze241ce82003-02-17 18:17:05 +00007771 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007772#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007773 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007774#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007775 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
7776 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007777#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00007778#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007779 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
7780 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00007781#if defined(PYOS_OS2)
7782 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
7783 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
7784#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00007785#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007786#ifdef HAVE_FORK1
Neal Norwitze241ce82003-02-17 18:17:05 +00007787 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007788#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007789#ifdef HAVE_FORK
Neal Norwitze241ce82003-02-17 18:17:05 +00007790 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007791#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007792#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Neal Norwitze241ce82003-02-17 18:17:05 +00007793 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007794#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007795#ifdef HAVE_FORKPTY
Neal Norwitze241ce82003-02-17 18:17:05 +00007796 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00007797#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007798#ifdef HAVE_GETEGID
Neal Norwitze241ce82003-02-17 18:17:05 +00007799 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007800#endif /* HAVE_GETEGID */
7801#ifdef HAVE_GETEUID
Neal Norwitze241ce82003-02-17 18:17:05 +00007802 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007803#endif /* HAVE_GETEUID */
7804#ifdef HAVE_GETGID
Neal Norwitze241ce82003-02-17 18:17:05 +00007805 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007806#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00007807#ifdef HAVE_GETGROUPS
Neal Norwitze241ce82003-02-17 18:17:05 +00007808 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007809#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007810 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007811#ifdef HAVE_GETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00007812 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007813#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007814#ifdef HAVE_GETPPID
Neal Norwitze241ce82003-02-17 18:17:05 +00007815 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007816#endif /* HAVE_GETPPID */
7817#ifdef HAVE_GETUID
Neal Norwitze241ce82003-02-17 18:17:05 +00007818 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007819#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007820#ifdef HAVE_GETLOGIN
Neal Norwitze241ce82003-02-17 18:17:05 +00007821 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00007822#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00007823#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007824 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007825#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007826#ifdef HAVE_KILLPG
7827 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
7828#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00007829#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007830 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00007831#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007832#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007833 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007834#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00007835 {"popen2", win32_popen2, METH_VARARGS},
7836 {"popen3", win32_popen3, METH_VARARGS},
7837 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00007838 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007839#else
7840#if defined(PYOS_OS2) && defined(PYCC_GCC)
7841 {"popen2", os2emx_popen2, METH_VARARGS},
7842 {"popen3", os2emx_popen3, METH_VARARGS},
7843 {"popen4", os2emx_popen4, METH_VARARGS},
7844#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00007845#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007846#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007847#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007848 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007849#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007850#ifdef HAVE_SETEUID
7851 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
7852#endif /* HAVE_SETEUID */
7853#ifdef HAVE_SETEGID
7854 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
7855#endif /* HAVE_SETEGID */
7856#ifdef HAVE_SETREUID
7857 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
7858#endif /* HAVE_SETREUID */
7859#ifdef HAVE_SETREGID
7860 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
7861#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007862#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007863 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007864#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007865#ifdef HAVE_SETGROUPS
7866 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
7867#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00007868#ifdef HAVE_GETPGID
7869 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
7870#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007871#ifdef HAVE_SETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00007872 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007873#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007874#ifdef HAVE_WAIT
Neal Norwitze241ce82003-02-17 18:17:05 +00007875 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007876#endif /* HAVE_WAIT */
Neal Norwitz05a45592006-03-20 06:30:08 +00007877#ifdef HAVE_WAIT3
7878 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
7879#endif /* HAVE_WAIT3 */
7880#ifdef HAVE_WAIT4
7881 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
7882#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00007883#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007884 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007885#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007886#ifdef HAVE_GETSID
7887 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
7888#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007889#ifdef HAVE_SETSID
Neal Norwitze241ce82003-02-17 18:17:05 +00007890 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007891#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007892#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007893 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007894#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007895#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007896 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007897#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007898#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007899 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007900#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007901 {"open", posix_open, METH_VARARGS, posix_open__doc__},
7902 {"close", posix_close, METH_VARARGS, posix_close__doc__},
7903 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
7904 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
7905 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
7906 {"read", posix_read, METH_VARARGS, posix_read__doc__},
7907 {"write", posix_write, METH_VARARGS, posix_write__doc__},
7908 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
7909 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00007910 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007911#ifdef HAVE_PIPE
Neal Norwitze241ce82003-02-17 18:17:05 +00007912 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007913#endif
7914#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007915 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007916#endif
Neal Norwitz11690112002-07-30 01:08:28 +00007917#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007918 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
7919#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007920#ifdef HAVE_DEVICE_MACROS
7921 {"major", posix_major, METH_VARARGS, posix_major__doc__},
7922 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
7923 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
7924#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007925#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007926 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007927#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007928#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007929 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007930#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007931#ifdef HAVE_UNSETENV
7932 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
7933#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00007934#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007935 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00007936#endif
Fred Drake4d1e64b2002-04-15 19:40:07 +00007937#ifdef HAVE_FCHDIR
7938 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
7939#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00007940#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007941 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007942#endif
7943#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007944 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007945#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00007946#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00007947#ifdef WCOREDUMP
7948 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
7949#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007950#ifdef WIFCONTINUED
7951 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
7952#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00007953#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007954 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007955#endif /* WIFSTOPPED */
7956#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007957 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007958#endif /* WIFSIGNALED */
7959#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007960 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007961#endif /* WIFEXITED */
7962#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007963 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007964#endif /* WEXITSTATUS */
7965#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007966 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007967#endif /* WTERMSIG */
7968#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007969 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007970#endif /* WSTOPSIG */
7971#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007972#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007973 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007974#endif
7975#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007976 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007977#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00007978#ifdef HAVE_TMPFILE
Neal Norwitze241ce82003-02-17 18:17:05 +00007979 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007980#endif
7981#ifdef HAVE_TEMPNAM
7982 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
7983#endif
7984#ifdef HAVE_TMPNAM
Neal Norwitze241ce82003-02-17 18:17:05 +00007985 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007986#endif
Fred Drakec9680921999-12-13 16:37:25 +00007987#ifdef HAVE_CONFSTR
7988 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
7989#endif
7990#ifdef HAVE_SYSCONF
7991 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
7992#endif
7993#ifdef HAVE_FPATHCONF
7994 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
7995#endif
7996#ifdef HAVE_PATHCONF
7997 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
7998#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007999 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008000#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00008001 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
8002#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00008003#ifdef HAVE_GETLOADAVG
Neal Norwitze241ce82003-02-17 18:17:05 +00008004 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00008005#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008006 #ifdef MS_WINDOWS
8007 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
8008 #endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008009 {NULL, NULL} /* Sentinel */
8010};
8011
8012
Barry Warsaw4a342091996-12-19 23:50:02 +00008013static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00008014ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00008015{
Fred Drake4d1e64b2002-04-15 19:40:07 +00008016 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00008017}
8018
Guido van Rossumd48f2521997-12-05 22:19:34 +00008019#if defined(PYOS_OS2)
8020/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008021static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008022{
8023 APIRET rc;
8024 ULONG values[QSV_MAX+1];
8025 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00008026 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00008027
8028 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00008029 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008030 Py_END_ALLOW_THREADS
8031
8032 if (rc != NO_ERROR) {
8033 os2_error(rc);
8034 return -1;
8035 }
8036
Fred Drake4d1e64b2002-04-15 19:40:07 +00008037 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
8038 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
8039 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
8040 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
8041 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
8042 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
8043 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008044
8045 switch (values[QSV_VERSION_MINOR]) {
8046 case 0: ver = "2.00"; break;
8047 case 10: ver = "2.10"; break;
8048 case 11: ver = "2.11"; break;
8049 case 30: ver = "3.00"; break;
8050 case 40: ver = "4.00"; break;
8051 case 50: ver = "5.00"; break;
8052 default:
Tim Peters885d4572001-11-28 20:27:42 +00008053 PyOS_snprintf(tmp, sizeof(tmp),
8054 "%d-%d", values[QSV_VERSION_MAJOR],
8055 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008056 ver = &tmp[0];
8057 }
8058
8059 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008060 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008061 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008062
8063 /* Add Indicator of Which Drive was Used to Boot the System */
8064 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
8065 tmp[1] = ':';
8066 tmp[2] = '\0';
8067
Fred Drake4d1e64b2002-04-15 19:40:07 +00008068 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008069}
8070#endif
8071
Barry Warsaw4a342091996-12-19 23:50:02 +00008072static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008073all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00008074{
Guido van Rossum94f6f721999-01-06 18:42:14 +00008075#ifdef F_OK
8076 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008077#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008078#ifdef R_OK
8079 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008080#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008081#ifdef W_OK
8082 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008083#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008084#ifdef X_OK
8085 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008086#endif
Fred Drakec9680921999-12-13 16:37:25 +00008087#ifdef NGROUPS_MAX
8088 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
8089#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008090#ifdef TMP_MAX
8091 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
8092#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008093#ifdef WCONTINUED
8094 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
8095#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008096#ifdef WNOHANG
8097 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008098#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008099#ifdef WUNTRACED
8100 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
8101#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008102#ifdef O_RDONLY
8103 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
8104#endif
8105#ifdef O_WRONLY
8106 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
8107#endif
8108#ifdef O_RDWR
8109 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
8110#endif
8111#ifdef O_NDELAY
8112 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
8113#endif
8114#ifdef O_NONBLOCK
8115 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
8116#endif
8117#ifdef O_APPEND
8118 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
8119#endif
8120#ifdef O_DSYNC
8121 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
8122#endif
8123#ifdef O_RSYNC
8124 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
8125#endif
8126#ifdef O_SYNC
8127 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
8128#endif
8129#ifdef O_NOCTTY
8130 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
8131#endif
8132#ifdef O_CREAT
8133 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
8134#endif
8135#ifdef O_EXCL
8136 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
8137#endif
8138#ifdef O_TRUNC
8139 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
8140#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00008141#ifdef O_BINARY
8142 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
8143#endif
8144#ifdef O_TEXT
8145 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
8146#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008147#ifdef O_LARGEFILE
8148 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
8149#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00008150#ifdef O_SHLOCK
8151 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
8152#endif
8153#ifdef O_EXLOCK
8154 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
8155#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008156
Tim Peters5aa91602002-01-30 05:46:57 +00008157/* MS Windows */
8158#ifdef O_NOINHERIT
8159 /* Don't inherit in child processes. */
8160 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
8161#endif
8162#ifdef _O_SHORT_LIVED
8163 /* Optimize for short life (keep in memory). */
8164 /* MS forgot to define this one with a non-underscore form too. */
8165 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
8166#endif
8167#ifdef O_TEMPORARY
8168 /* Automatically delete when last handle is closed. */
8169 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
8170#endif
8171#ifdef O_RANDOM
8172 /* Optimize for random access. */
8173 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
8174#endif
8175#ifdef O_SEQUENTIAL
8176 /* Optimize for sequential access. */
8177 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
8178#endif
8179
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008180/* GNU extensions. */
8181#ifdef O_DIRECT
8182 /* Direct disk access. */
8183 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
8184#endif
8185#ifdef O_DIRECTORY
8186 /* Must be a directory. */
8187 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
8188#endif
8189#ifdef O_NOFOLLOW
8190 /* Do not follow links. */
8191 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
8192#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00008193
Barry Warsaw5676bd12003-01-07 20:57:09 +00008194 /* These come from sysexits.h */
8195#ifdef EX_OK
8196 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008197#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008198#ifdef EX_USAGE
8199 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008200#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008201#ifdef EX_DATAERR
8202 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008203#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008204#ifdef EX_NOINPUT
8205 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008206#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008207#ifdef EX_NOUSER
8208 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008209#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008210#ifdef EX_NOHOST
8211 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008212#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008213#ifdef EX_UNAVAILABLE
8214 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008215#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008216#ifdef EX_SOFTWARE
8217 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008218#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008219#ifdef EX_OSERR
8220 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008221#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008222#ifdef EX_OSFILE
8223 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008224#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008225#ifdef EX_CANTCREAT
8226 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008227#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008228#ifdef EX_IOERR
8229 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008230#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008231#ifdef EX_TEMPFAIL
8232 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008233#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008234#ifdef EX_PROTOCOL
8235 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008236#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008237#ifdef EX_NOPERM
8238 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008239#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008240#ifdef EX_CONFIG
8241 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008242#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008243#ifdef EX_NOTFOUND
8244 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008245#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008246
Guido van Rossum246bc171999-02-01 23:54:31 +00008247#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008248#if defined(PYOS_OS2) && defined(PYCC_GCC)
8249 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
8250 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
8251 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
8252 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
8253 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
8254 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
8255 if (ins(d, "P_PM", (long)P_PM)) return -1;
8256 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
8257 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
8258 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
8259 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
8260 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
8261 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
8262 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
8263 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
8264 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
8265 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
8266 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
8267 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
8268 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
8269#else
Guido van Rossum7d385291999-02-16 19:38:04 +00008270 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
8271 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
8272 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
8273 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
8274 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00008275#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008276#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00008277
Guido van Rossumd48f2521997-12-05 22:19:34 +00008278#if defined(PYOS_OS2)
8279 if (insertvalues(d)) return -1;
8280#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008281 return 0;
8282}
8283
8284
Tim Peters5aa91602002-01-30 05:46:57 +00008285#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008286#define INITFUNC initnt
8287#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008288
8289#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008290#define INITFUNC initos2
8291#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008292
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008293#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008294#define INITFUNC initposix
8295#define MODNAME "posix"
8296#endif
8297
Mark Hammondfe51c6d2002-08-02 02:27:13 +00008298PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008299INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00008300{
Fred Drake4d1e64b2002-04-15 19:40:07 +00008301 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00008302
Fred Drake4d1e64b2002-04-15 19:40:07 +00008303 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008304 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00008305 posix__doc__);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00008306 if (m == NULL)
8307 return;
Tim Peters5aa91602002-01-30 05:46:57 +00008308
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008309 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008310 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00008311 Py_XINCREF(v);
8312 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008313 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00008314 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00008315
Fred Drake4d1e64b2002-04-15 19:40:07 +00008316 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00008317 return;
8318
Fred Drake4d1e64b2002-04-15 19:40:07 +00008319 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00008320 return;
8321
Fred Drake4d1e64b2002-04-15 19:40:07 +00008322 Py_INCREF(PyExc_OSError);
8323 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00008324
Guido van Rossumb3d39562000-01-31 18:41:26 +00008325#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00008326 if (posix_putenv_garbage == NULL)
8327 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00008328#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008329
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00008330 if (!initialized) {
8331 stat_result_desc.name = MODNAME ".stat_result";
8332 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
8333 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
8334 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
8335 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
8336 structseq_new = StatResultType.tp_new;
8337 StatResultType.tp_new = statresult_new;
8338
8339 statvfs_result_desc.name = MODNAME ".statvfs_result";
8340 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
8341 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00008342 Py_INCREF((PyObject*) &StatResultType);
8343 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Fred Drake4d1e64b2002-04-15 19:40:07 +00008344 Py_INCREF((PyObject*) &StatVFSResultType);
8345 PyModule_AddObject(m, "statvfs_result",
8346 (PyObject*) &StatVFSResultType);
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00008347 initialized = 1;
Ronald Oussorend06b6f22006-04-23 11:59:25 +00008348
8349#ifdef __APPLE__
8350 /*
8351 * Step 2 of weak-linking support on Mac OS X.
8352 *
8353 * The code below removes functions that are not available on the
8354 * currently active platform.
8355 *
8356 * This block allow one to use a python binary that was build on
8357 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
8358 * OSX 10.4.
8359 */
8360#ifdef HAVE_FSTATVFS
8361 if (fstatvfs == NULL) {
8362 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
8363 return;
8364 }
8365 }
8366#endif /* HAVE_FSTATVFS */
8367
8368#ifdef HAVE_STATVFS
8369 if (statvfs == NULL) {
8370 if (PyObject_DelAttrString(m, "statvfs") == -1) {
8371 return;
8372 }
8373 }
8374#endif /* HAVE_STATVFS */
8375
8376# ifdef HAVE_LCHOWN
8377 if (lchown == NULL) {
8378 if (PyObject_DelAttrString(m, "lchown") == -1) {
8379 return;
8380 }
8381 }
8382#endif /* HAVE_LCHOWN */
8383
8384
8385#endif /* __APPLE__ */
8386
Guido van Rossumb6775db1994-08-01 11:34:53 +00008387}
Anthony Baxterac6bd462006-04-13 02:06:09 +00008388
8389#ifdef __cplusplus
8390}
8391#endif
8392