blob: 4cd220e425afb3f946cfece799ea09677a37da52 [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
Thomas Wouters68bc4f92006-03-01 01:05:10 +000016#define PY_SSIZE_T_CLEAN
17
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000018#include "Python.h"
19#include "structseq.h"
20
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000021#if defined(__VMS)
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000022# include <unixio.h>
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000023#endif /* defined(__VMS) */
24
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000025PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000026"This module provides access to operating system functionality that is\n\
27standardized by the C Standard and the POSIX standard (a thinly\n\
28disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000029corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000030
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000031#ifndef Py_USING_UNICODE
32/* This is used in signatures of functions. */
33#define Py_UNICODE void
34#endif
35
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000036#if defined(PYOS_OS2)
37#define INCL_DOS
38#define INCL_DOSERRORS
39#define INCL_DOSPROCESS
40#define INCL_NOPMAPI
41#include <os2.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000042#if defined(PYCC_GCC)
43#include <ctype.h>
44#include <io.h>
45#include <stdio.h>
46#include <process.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000047#endif
Andrew MacIntyreda4d6cb2004-03-29 11:53:38 +000048#include "osdefs.h"
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000049#endif
50
Guido van Rossumb6775db1994-08-01 11:34:53 +000051#include <sys/types.h>
52#include <sys/stat.h>
Guido van Rossuma6535fd2001-10-18 19:44:10 +000053
Guido van Rossum36bc6801995-06-14 22:54:23 +000054#ifdef HAVE_SYS_WAIT_H
55#include <sys/wait.h> /* For WNOHANG */
56#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000057
Guido van Rossuma376cc51996-12-05 23:43:35 +000058#include <signal.h>
Guido van Rossuma376cc51996-12-05 23:43:35 +000059
Guido van Rossumb6775db1994-08-01 11:34:53 +000060#ifdef HAVE_FCNTL_H
61#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000062#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000063
Guido van Rossuma6535fd2001-10-18 19:44:10 +000064#ifdef HAVE_GRP_H
65#include <grp.h>
66#endif
67
Barry Warsaw5676bd12003-01-07 20:57:09 +000068#ifdef HAVE_SYSEXITS_H
69#include <sysexits.h>
70#endif /* HAVE_SYSEXITS_H */
71
Anthony Baxter8a560de2004-10-13 15:30:56 +000072#ifdef HAVE_SYS_LOADAVG_H
73#include <sys/loadavg.h>
74#endif
75
Guido van Rossuma4916fa1996-05-23 22:58:55 +000076/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +000077/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000078#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000079#include <process.h>
80#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +000081#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000082#define HAVE_GETCWD 1
83#define HAVE_OPENDIR 1
84#define HAVE_SYSTEM 1
85#if defined(__OS2__)
86#define HAVE_EXECV 1
87#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +000088#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000089#include <process.h>
90#else
91#ifdef __BORLANDC__ /* Borland compiler */
92#define HAVE_EXECV 1
93#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +000094#define HAVE_OPENDIR 1
95#define HAVE_PIPE 1
96#define HAVE_POPEN 1
97#define HAVE_SYSTEM 1
98#define HAVE_WAIT 1
99#else
100#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000101#define HAVE_GETCWD 1
Guido van Rossuma1065681999-01-25 23:20:23 +0000102#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000103#define HAVE_EXECV 1
104#define HAVE_PIPE 1
105#define HAVE_POPEN 1
106#define HAVE_SYSTEM 1
Tim Petersab034fa2002-02-01 11:27:43 +0000107#define HAVE_CWAIT 1
Tim Peters11b23062003-04-23 02:39:17 +0000108#define HAVE_FSYNC 1
109#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000110#else
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000111#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
112/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000113#else /* all other compilers */
114/* Unix functions that the configure script doesn't check for */
115#define HAVE_EXECV 1
116#define HAVE_FORK 1
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000117#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
118#define HAVE_FORK1 1
119#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000120#define HAVE_GETCWD 1
121#define HAVE_GETEGID 1
122#define HAVE_GETEUID 1
123#define HAVE_GETGID 1
124#define HAVE_GETPPID 1
125#define HAVE_GETUID 1
126#define HAVE_KILL 1
127#define HAVE_OPENDIR 1
128#define HAVE_PIPE 1
Martin v. Löwis212ede62003-09-20 11:20:30 +0000129#ifndef __rtems__
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000130#define HAVE_POPEN 1
Martin v. Löwis212ede62003-09-20 11:20:30 +0000131#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000132#define HAVE_SYSTEM 1
133#define HAVE_WAIT 1
Guido van Rossumd371ff11999-01-25 16:12:23 +0000134#define HAVE_TTYNAME 1
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000135#endif /* PYOS_OS2 && PYCC_GCC && __VMS */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000136#endif /* _MSC_VER */
137#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000138#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000139#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000140
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000141#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000142
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000143#if defined(__sgi)&&_COMPILER_VERSION>=700
144/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
145 (default) */
146extern char *ctermid_r(char *);
147#endif
148
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000149#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000150#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000151extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000152#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000153#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000154extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000155#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000156extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000157#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000158#endif
159#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000160extern int chdir(char *);
161extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000162#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000163extern int chdir(const char *);
164extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000165#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000166#ifdef __BORLANDC__
167extern int chmod(const char *, int);
168#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000169extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000170#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000171extern int chown(const char *, uid_t, gid_t);
172extern char *getcwd(char *, int);
173extern char *strerror(int);
174extern int link(const char *, const char *);
175extern int rename(const char *, const char *);
176extern int stat(const char *, struct stat *);
177extern int unlink(const char *);
178extern int pclose(FILE *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000179#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000180extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000181#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000182#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000183extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000184#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000185#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000186
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000187#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000188
Guido van Rossumb6775db1994-08-01 11:34:53 +0000189#ifdef HAVE_UTIME_H
190#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000191#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000192
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000193#ifdef HAVE_SYS_UTIME_H
194#include <sys/utime.h>
195#define HAVE_UTIME_H /* pretend we do for the rest of this file */
196#endif /* HAVE_SYS_UTIME_H */
197
Guido van Rossumb6775db1994-08-01 11:34:53 +0000198#ifdef HAVE_SYS_TIMES_H
199#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000200#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000201
202#ifdef HAVE_SYS_PARAM_H
203#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000204#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000205
206#ifdef HAVE_SYS_UTSNAME_H
207#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000208#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000209
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000210#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000211#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000212#define NAMLEN(dirent) strlen((dirent)->d_name)
213#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000214#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000215#include <direct.h>
216#define NAMLEN(dirent) strlen((dirent)->d_name)
217#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000218#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000219#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000220#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000221#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000222#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000223#endif
224#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000225#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000226#endif
227#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000228#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000229#endif
230#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000231
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000232#ifdef _MSC_VER
Guido van Rossumb6775db1994-08-01 11:34:53 +0000233#include <direct.h>
234#include <io.h>
235#include <process.h>
Tim Petersbc2e10e2002-03-03 23:17:02 +0000236#include "osdefs.h"
Martin v. Löwisdc3883f2004-08-29 15:46:35 +0000237#define _WIN32_WINNT 0x0400 /* Needed for CryptoAPI on some systems */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000238#include <windows.h>
Tim Petersee66d0c2002-07-15 16:10:55 +0000239#include <shellapi.h> /* for ShellExecute() */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000240#define popen _popen
Guido van Rossum794d8131994-08-23 13:48:48 +0000241#define pclose _pclose
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000242#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000243
Guido van Rossumd48f2521997-12-05 22:19:34 +0000244#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000245#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000246#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000247
Tim Petersbc2e10e2002-03-03 23:17:02 +0000248#ifndef MAXPATHLEN
249#define MAXPATHLEN 1024
250#endif /* MAXPATHLEN */
251
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000252#ifdef UNION_WAIT
253/* Emulate some macros on systems that have a union instead of macros */
254
255#ifndef WIFEXITED
256#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
257#endif
258
259#ifndef WEXITSTATUS
260#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
261#endif
262
263#ifndef WTERMSIG
264#define WTERMSIG(u_wait) ((u_wait).w_termsig)
265#endif
266
Neal Norwitzd5a37542006-03-20 06:48:34 +0000267#define WAIT_TYPE union wait
268#define WAIT_STATUS_INT(s) (s.w_status)
269
270#else /* !UNION_WAIT */
271#define WAIT_TYPE int
272#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000273#endif /* UNION_WAIT */
274
Greg Wardb48bc172000-03-01 21:51:56 +0000275/* Don't use the "_r" form if we don't need it (also, won't have a
276 prototype for it, at least on Solaris -- maybe others as well?). */
277#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
278#define USE_CTERMID_R
279#endif
280
281#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
282#define USE_TMPNAM_R
283#endif
284
Fred Drake699f3522000-06-29 21:12:41 +0000285/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000286#undef STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000287#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwis14694662006-02-03 12:54:16 +0000288# define STAT win32_stat
289# define FSTAT win32_fstat
290# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000291#else
292# define STAT stat
293# define FSTAT fstat
294# define STRUCT_STAT struct stat
295#endif
296
Tim Peters11b23062003-04-23 02:39:17 +0000297#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000298#include <sys/mkdev.h>
299#else
300#if defined(MAJOR_IN_SYSMACROS)
301#include <sys/sysmacros.h>
302#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000303#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
304#include <sys/mkdev.h>
305#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000306#endif
Fred Drake699f3522000-06-29 21:12:41 +0000307
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000308/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000309#ifdef WITH_NEXT_FRAMEWORK
310/* On Darwin/MacOSX a shared library or framework has no access to
311** environ directly, we must obtain it with _NSGetEnviron().
312*/
313#include <crt_externs.h>
314static char **environ;
315#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000316extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000317#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000318
Barry Warsaw53699e91996-12-10 23:23:01 +0000319static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000320convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000321{
Barry Warsaw53699e91996-12-10 23:23:01 +0000322 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000323 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000324 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000325 if (d == NULL)
326 return NULL;
Jack Jansenea0c3822002-08-01 21:57:49 +0000327#ifdef WITH_NEXT_FRAMEWORK
328 if (environ == NULL)
329 environ = *_NSGetEnviron();
330#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000331 if (environ == NULL)
332 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000333 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000334 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000335 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000336 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000337 char *p = strchr(*e, '=');
338 if (p == NULL)
339 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000340 k = PyString_FromStringAndSize(*e, (int)(p-*e));
341 if (k == NULL) {
342 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000343 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000344 }
345 v = PyString_FromString(p+1);
346 if (v == NULL) {
347 PyErr_Clear();
348 Py_DECREF(k);
349 continue;
350 }
351 if (PyDict_GetItem(d, k) == NULL) {
352 if (PyDict_SetItem(d, k, v) != 0)
353 PyErr_Clear();
354 }
355 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000356 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000357 }
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000358#if defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000359 {
360 APIRET rc;
361 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
362
363 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000364 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000365 PyObject *v = PyString_FromString(buffer);
366 PyDict_SetItemString(d, "BEGINLIBPATH", v);
367 Py_DECREF(v);
368 }
369 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
370 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
371 PyObject *v = PyString_FromString(buffer);
372 PyDict_SetItemString(d, "ENDLIBPATH", v);
373 Py_DECREF(v);
374 }
375 }
376#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000377 return d;
378}
379
380
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000381/* Set a POSIX-specific error from errno, and return NULL */
382
Barry Warsawd58d7641998-07-23 16:14:40 +0000383static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000384posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000385{
Barry Warsawca74da41999-02-09 19:31:45 +0000386 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000387}
Barry Warsawd58d7641998-07-23 16:14:40 +0000388static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000389posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000390{
Barry Warsawca74da41999-02-09 19:31:45 +0000391 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000392}
393
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000394#ifdef Py_WIN_WIDE_FILENAMES
395static PyObject *
396posix_error_with_unicode_filename(Py_UNICODE* name)
397{
398 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
399}
400#endif /* Py_WIN_WIDE_FILENAMES */
401
402
Mark Hammondef8b6542001-05-13 08:04:26 +0000403static PyObject *
404posix_error_with_allocated_filename(char* name)
405{
406 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
407 PyMem_Free(name);
408 return rc;
409}
410
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000411#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000412static PyObject *
413win32_error(char* function, char* filename)
414{
Mark Hammond33a6da92000-08-15 00:46:38 +0000415 /* XXX We should pass the function name along in the future.
416 (_winreg.c also wants to pass the function name.)
Tim Peters5aa91602002-01-30 05:46:57 +0000417 This would however require an additional param to the
Mark Hammond33a6da92000-08-15 00:46:38 +0000418 Windows error object, which is non-trivial.
419 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000420 errno = GetLastError();
421 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000422 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000423 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000424 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000425}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000426
427#ifdef Py_WIN_WIDE_FILENAMES
428static PyObject *
429win32_error_unicode(char* function, Py_UNICODE* filename)
430{
431 /* XXX - see win32_error for comments on 'function' */
432 errno = GetLastError();
433 if (filename)
434 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
435 else
436 return PyErr_SetFromWindowsErr(errno);
437}
438
439static PyObject *_PyUnicode_FromFileSystemEncodedObject(register PyObject *obj)
440{
441 /* XXX Perhaps we should make this API an alias of
442 PyObject_Unicode() instead ?! */
443 if (PyUnicode_CheckExact(obj)) {
444 Py_INCREF(obj);
445 return obj;
446 }
447 if (PyUnicode_Check(obj)) {
448 /* For a Unicode subtype that's not a Unicode object,
449 return a true Unicode object with the same data. */
450 return PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(obj),
451 PyUnicode_GET_SIZE(obj));
452 }
Tim Peters11b23062003-04-23 02:39:17 +0000453 return PyUnicode_FromEncodedObject(obj,
454 Py_FileSystemDefaultEncoding,
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000455 "strict");
456}
457
458#endif /* Py_WIN_WIDE_FILENAMES */
459
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000460#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000461
Guido van Rossumd48f2521997-12-05 22:19:34 +0000462#if defined(PYOS_OS2)
463/**********************************************************************
464 * Helper Function to Trim and Format OS/2 Messages
465 **********************************************************************/
466 static void
467os2_formatmsg(char *msgbuf, int msglen, char *reason)
468{
469 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
470
471 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
472 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
473
Neal Norwitz30b5c5d2005-12-19 06:05:18 +0000474 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
Guido van Rossumd48f2521997-12-05 22:19:34 +0000475 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
476 }
477
478 /* Add Optional Reason Text */
479 if (reason) {
480 strcat(msgbuf, " : ");
481 strcat(msgbuf, reason);
482 }
483}
484
485/**********************************************************************
486 * Decode an OS/2 Operating System Error Code
487 *
488 * A convenience function to lookup an OS/2 error code and return a
489 * text message we can use to raise a Python exception.
490 *
491 * Notes:
492 * The messages for errors returned from the OS/2 kernel reside in
493 * the file OSO001.MSG in the \OS2 directory hierarchy.
494 *
495 **********************************************************************/
496 static char *
497os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
498{
499 APIRET rc;
500 ULONG msglen;
501
502 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
503 Py_BEGIN_ALLOW_THREADS
504 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
505 errorcode, "oso001.msg", &msglen);
506 Py_END_ALLOW_THREADS
507
508 if (rc == NO_ERROR)
509 os2_formatmsg(msgbuf, msglen, reason);
510 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000511 PyOS_snprintf(msgbuf, msgbuflen,
Tim Peters885d4572001-11-28 20:27:42 +0000512 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000513
514 return msgbuf;
515}
516
517/* Set an OS/2-specific error and return NULL. OS/2 kernel
518 errors are not in a global variable e.g. 'errno' nor are
519 they congruent with posix error numbers. */
520
521static PyObject * os2_error(int code)
522{
523 char text[1024];
524 PyObject *v;
525
526 os2_strerror(text, sizeof(text), code, "");
527
528 v = Py_BuildValue("(is)", code, text);
529 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000530 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000531 Py_DECREF(v);
532 }
533 return NULL; /* Signal to Python that an Exception is Pending */
534}
535
536#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000537
538/* POSIX generic methods */
539
Barry Warsaw53699e91996-12-10 23:23:01 +0000540static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000541posix_fildes(PyObject *fdobj, int (*func)(int))
542{
543 int fd;
544 int res;
545 fd = PyObject_AsFileDescriptor(fdobj);
546 if (fd < 0)
547 return NULL;
548 Py_BEGIN_ALLOW_THREADS
549 res = (*func)(fd);
550 Py_END_ALLOW_THREADS
551 if (res < 0)
552 return posix_error();
553 Py_INCREF(Py_None);
554 return Py_None;
555}
Guido van Rossum21142a01999-01-08 21:05:37 +0000556
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000557#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters11b23062003-04-23 02:39:17 +0000558static int
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000559unicode_file_names(void)
560{
561 static int canusewide = -1;
562 if (canusewide == -1) {
Tim Peters11b23062003-04-23 02:39:17 +0000563 /* As per doc for ::GetVersion(), this is the correct test for
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000564 the Windows NT family. */
565 canusewide = (GetVersion() < 0x80000000) ? 1 : 0;
566 }
567 return canusewide;
568}
569#endif
Tim Peters11b23062003-04-23 02:39:17 +0000570
Guido van Rossum21142a01999-01-08 21:05:37 +0000571static PyObject *
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000572posix_1str(PyObject *args, char *format, int (*func)(const char*),
573 char *wformat, int (*wfunc)(const Py_UNICODE*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000574{
Mark Hammondef8b6542001-05-13 08:04:26 +0000575 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000576 int res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000577#ifdef Py_WIN_WIDE_FILENAMES
578 if (unicode_file_names()) {
579 PyUnicodeObject *po;
580 if (PyArg_ParseTuple(args, wformat, &po)) {
581 Py_BEGIN_ALLOW_THREADS
582 /* PyUnicode_AS_UNICODE OK without thread
583 lock as it is a simple dereference. */
584 res = (*wfunc)(PyUnicode_AS_UNICODE(po));
585 Py_END_ALLOW_THREADS
586 if (res < 0)
Mark Hammondd3890362002-10-03 07:24:48 +0000587 return posix_error_with_unicode_filename(PyUnicode_AS_UNICODE(po));
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000588 Py_INCREF(Py_None);
589 return Py_None;
590 }
591 /* Drop the argument parsing error as narrow
592 strings are also valid. */
593 PyErr_Clear();
594 }
595#else
596 /* Platforms that don't support Unicode filenames
597 shouldn't be passing these extra params */
598 assert(wformat==NULL && wfunc == NULL);
599#endif
600
Tim Peters5aa91602002-01-30 05:46:57 +0000601 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000602 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000603 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000604 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000605 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000606 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000607 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000608 return posix_error_with_allocated_filename(path1);
609 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000610 Py_INCREF(Py_None);
611 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000612}
613
Barry Warsaw53699e91996-12-10 23:23:01 +0000614static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000615posix_2str(PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000616 char *format,
617 int (*func)(const char *, const char *),
618 char *wformat,
619 int (*wfunc)(const Py_UNICODE *, const Py_UNICODE *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000620{
Mark Hammondef8b6542001-05-13 08:04:26 +0000621 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000622 int res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000623#ifdef Py_WIN_WIDE_FILENAMES
624 if (unicode_file_names()) {
625 PyObject *po1;
626 PyObject *po2;
627 if (PyArg_ParseTuple(args, wformat, &po1, &po2)) {
628 if (PyUnicode_Check(po1) || PyUnicode_Check(po2)) {
629 PyObject *wpath1;
630 PyObject *wpath2;
631 wpath1 = _PyUnicode_FromFileSystemEncodedObject(po1);
632 wpath2 = _PyUnicode_FromFileSystemEncodedObject(po2);
633 if (!wpath1 || !wpath2) {
634 Py_XDECREF(wpath1);
635 Py_XDECREF(wpath2);
636 return NULL;
637 }
638 Py_BEGIN_ALLOW_THREADS
639 /* PyUnicode_AS_UNICODE OK without thread
640 lock as it is a simple dereference. */
641 res = (*wfunc)(PyUnicode_AS_UNICODE(wpath1),
642 PyUnicode_AS_UNICODE(wpath2));
643 Py_END_ALLOW_THREADS
644 Py_XDECREF(wpath1);
645 Py_XDECREF(wpath2);
646 if (res != 0)
647 return posix_error();
648 Py_INCREF(Py_None);
649 return Py_None;
650 }
651 /* Else flow through as neither is Unicode. */
652 }
653 /* Drop the argument parsing error as narrow
654 strings are also valid. */
655 PyErr_Clear();
656 }
657#else
658 /* Platforms that don't support Unicode filenames
659 shouldn't be passing these extra params */
660 assert(wformat==NULL && wfunc == NULL);
661#endif
662
Mark Hammondef8b6542001-05-13 08:04:26 +0000663 if (!PyArg_ParseTuple(args, format,
Tim Peters5aa91602002-01-30 05:46:57 +0000664 Py_FileSystemDefaultEncoding, &path1,
Mark Hammondef8b6542001-05-13 08:04:26 +0000665 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000666 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000667 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000668 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000669 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000670 PyMem_Free(path1);
671 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000672 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000673 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000674 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000675 Py_INCREF(Py_None);
676 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000677}
678
Martin v. Löwis14694662006-02-03 12:54:16 +0000679#ifdef MS_WINDOWS
680/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
681 - time stamps are restricted to second resolution
682 - file modification times suffer from forth-and-back conversions between
683 UTC and local time
684 Therefore, we implement our own stat, based on the Win32 API directly.
685*/
686#define HAVE_STAT_NSEC 1
687
688struct win32_stat{
689 int st_dev;
690 __int64 st_ino;
691 unsigned short st_mode;
692 int st_nlink;
693 int st_uid;
694 int st_gid;
695 int st_rdev;
696 __int64 st_size;
697 int st_atime;
698 int st_atime_nsec;
699 int st_mtime;
700 int st_mtime_nsec;
701 int st_ctime;
702 int st_ctime_nsec;
703};
704
705static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
706
707static void
708FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, int *time_out, int* nsec_out)
709{
710 /* XXX endianness */
711 __int64 in = *(__int64*)in_ptr;
712 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
713 /* XXX Win32 supports time stamps past 2038; we currently don't */
714 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, int);
715}
716
717/* Below, we *know* that ugo+r is 0444 */
718#if _S_IREAD != 0400
719#error Unsupported C library
720#endif
721static int
722attributes_to_mode(DWORD attr)
723{
724 int m = 0;
725 if (attr & FILE_ATTRIBUTE_DIRECTORY)
726 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
727 else
728 m |= _S_IFREG;
729 if (attr & FILE_ATTRIBUTE_READONLY)
730 m |= 0444;
731 else
732 m |= 0666;
733 return m;
734}
735
736static int
737attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *result)
738{
739 memset(result, 0, sizeof(*result));
740 result->st_mode = attributes_to_mode(info->dwFileAttributes);
741 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
742 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
743 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
744 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
745
746 return 0;
747}
748
749static int
750win32_stat(const char* path, struct win32_stat *result)
751{
752 WIN32_FILE_ATTRIBUTE_DATA info;
753 int code;
754 char *dot;
755 /* XXX not supported on Win95 and NT 3.x */
756 if (!GetFileAttributesExA(path, GetFileExInfoStandard, &info)) {
757 /* Protocol violation: we explicitly clear errno, instead of
758 setting it to a POSIX error. Callers should use GetLastError. */
759 errno = 0;
760 return -1;
761 }
762 code = attribute_data_to_stat(&info, result);
763 if (code != 0)
764 return code;
765 /* Set S_IFEXEC if it is an .exe, .bat, ... */
766 dot = strrchr(path, '.');
767 if (dot) {
768 if (stricmp(dot, ".bat") == 0 ||
769 stricmp(dot, ".cmd") == 0 ||
770 stricmp(dot, ".exe") == 0 ||
771 stricmp(dot, ".com") == 0)
772 result->st_mode |= 0111;
773 }
774 return code;
775}
776
777static int
778win32_wstat(const wchar_t* path, struct win32_stat *result)
779{
780 int code;
781 const wchar_t *dot;
782 WIN32_FILE_ATTRIBUTE_DATA info;
783 /* XXX not supported on Win95 and NT 3.x */
784 if (!GetFileAttributesExW(path, GetFileExInfoStandard, &info)) {
785 /* Protocol violation: we explicitly clear errno, instead of
786 setting it to a POSIX error. Callers should use GetLastError. */
787 errno = 0;
788 return -1;
789 }
790 code = attribute_data_to_stat(&info, result);
791 if (code < 0)
792 return code;
793 /* Set IFEXEC if it is an .exe, .bat, ... */
794 dot = wcsrchr(path, '.');
795 if (dot) {
796 if (_wcsicmp(dot, L".bat") == 0 ||
797 _wcsicmp(dot, L".cmd") == 0 ||
798 _wcsicmp(dot, L".exe") == 0 ||
799 _wcsicmp(dot, L".com") == 0)
800 result->st_mode |= 0111;
801 }
802 return code;
803}
804
805static int
806win32_fstat(int file_number, struct win32_stat *result)
807{
808 BY_HANDLE_FILE_INFORMATION info;
809 HANDLE h;
810 int type;
811
812 h = (HANDLE)_get_osfhandle(file_number);
813
814 /* Protocol violation: we explicitly clear errno, instead of
815 setting it to a POSIX error. Callers should use GetLastError. */
816 errno = 0;
817
818 if (h == INVALID_HANDLE_VALUE) {
819 /* This is really a C library error (invalid file handle).
820 We set the Win32 error to the closes one matching. */
821 SetLastError(ERROR_INVALID_HANDLE);
822 return -1;
823 }
824 memset(result, 0, sizeof(*result));
825
826 type = GetFileType(h);
827 if (type == FILE_TYPE_UNKNOWN) {
828 DWORD error = GetLastError();
829 if (error != 0) {
830 return -1;
831 }
832 /* else: valid but unknown file */
833 }
834
835 if (type != FILE_TYPE_DISK) {
836 if (type == FILE_TYPE_CHAR)
837 result->st_mode = _S_IFCHR;
838 else if (type == FILE_TYPE_PIPE)
839 result->st_mode = _S_IFIFO;
840 return 0;
841 }
842
843 if (!GetFileInformationByHandle(h, &info)) {
844 return -1;
845 }
846
847 /* similar to stat() */
848 result->st_mode = attributes_to_mode(info.dwFileAttributes);
849 result->st_size = (((__int64)info.nFileSizeHigh)<<32) + info.nFileSizeLow;
850 FILE_TIME_to_time_t_nsec(&info.ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
851 FILE_TIME_to_time_t_nsec(&info.ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
852 FILE_TIME_to_time_t_nsec(&info.ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
853 /* specific to fstat() */
854 result->st_nlink = info.nNumberOfLinks;
855 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
856 return 0;
857}
858
859#endif /* MS_WINDOWS */
860
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000861PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000862"stat_result: Result from stat or lstat.\n\n\
863This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +0000864 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000865or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
866\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +0000867Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
868or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000869\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000870See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000871
872static PyStructSequence_Field stat_result_fields[] = {
873 {"st_mode", "protection bits"},
874 {"st_ino", "inode"},
875 {"st_dev", "device"},
876 {"st_nlink", "number of hard links"},
877 {"st_uid", "user ID of owner"},
878 {"st_gid", "group ID of owner"},
879 {"st_size", "total size, in bytes"},
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000880 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
881 {NULL, "integer time of last access"},
882 {NULL, "integer time of last modification"},
883 {NULL, "integer time of last change"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000884 {"st_atime", "time of last access"},
885 {"st_mtime", "time of last modification"},
886 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000887#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000888 {"st_blksize", "blocksize for filesystem I/O"},
889#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000890#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000891 {"st_blocks", "number of blocks allocated"},
892#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000893#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000894 {"st_rdev", "device type (if inode device)"},
895#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +0000896#ifdef HAVE_STRUCT_STAT_ST_FLAGS
897 {"st_flags", "user defined flags for file"},
898#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +0000899#ifdef HAVE_STRUCT_STAT_ST_GEN
900 {"st_gen", "generation number"},
901#endif
902#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
903 {"st_birthtime", "time of creation"},
904#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000905 {0}
906};
907
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000908#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000909#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000910#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000911#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000912#endif
913
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000914#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000915#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
916#else
917#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
918#endif
919
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000920#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000921#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
922#else
923#define ST_RDEV_IDX ST_BLOCKS_IDX
924#endif
925
Hye-Shik Chang5f937a72005-06-02 13:09:30 +0000926#ifdef HAVE_STRUCT_STAT_ST_FLAGS
927#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
928#else
929#define ST_FLAGS_IDX ST_RDEV_IDX
930#endif
931
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +0000932#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +0000933#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +0000934#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +0000935#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +0000936#endif
937
938#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
939#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
940#else
941#define ST_BIRTHTIME_IDX ST_GEN_IDX
942#endif
943
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000944static PyStructSequence_Desc stat_result_desc = {
945 "stat_result", /* name */
946 stat_result__doc__, /* doc */
947 stat_result_fields,
948 10
949};
950
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000951PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000952"statvfs_result: Result from statvfs or fstatvfs.\n\n\
953This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +0000954 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000955or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000956\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000957See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000958
959static PyStructSequence_Field statvfs_result_fields[] = {
960 {"f_bsize", },
961 {"f_frsize", },
962 {"f_blocks", },
963 {"f_bfree", },
964 {"f_bavail", },
965 {"f_files", },
966 {"f_ffree", },
967 {"f_favail", },
968 {"f_flag", },
969 {"f_namemax",},
970 {0}
971};
972
973static PyStructSequence_Desc statvfs_result_desc = {
974 "statvfs_result", /* name */
975 statvfs_result__doc__, /* doc */
976 statvfs_result_fields,
977 10
978};
979
980static PyTypeObject StatResultType;
981static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000982static newfunc structseq_new;
983
984static PyObject *
985statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
986{
987 PyStructSequence *result;
988 int i;
989
990 result = (PyStructSequence*)structseq_new(type, args, kwds);
991 if (!result)
992 return NULL;
993 /* If we have been initialized from a tuple,
994 st_?time might be set to None. Initialize it
995 from the int slots. */
996 for (i = 7; i <= 9; i++) {
997 if (result->ob_item[i+3] == Py_None) {
998 Py_DECREF(Py_None);
999 Py_INCREF(result->ob_item[i]);
1000 result->ob_item[i+3] = result->ob_item[i];
1001 }
1002 }
1003 return (PyObject*)result;
1004}
1005
1006
1007
1008/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001009static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001010
1011PyDoc_STRVAR(stat_float_times__doc__,
1012"stat_float_times([newval]) -> oldval\n\n\
1013Determine whether os.[lf]stat represents time stamps as float objects.\n\
1014If newval is True, future calls to stat() return floats, if it is False,\n\
1015future calls return ints. \n\
1016If newval is omitted, return the current setting.\n");
1017
1018static PyObject*
1019stat_float_times(PyObject* self, PyObject *args)
1020{
1021 int newval = -1;
1022 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1023 return NULL;
1024 if (newval == -1)
1025 /* Return old value */
1026 return PyBool_FromLong(_stat_float_times);
1027 _stat_float_times = newval;
1028 Py_INCREF(Py_None);
1029 return Py_None;
1030}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001031
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001032static void
1033fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1034{
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001035 PyObject *fval,*ival;
1036#if SIZEOF_TIME_T > SIZEOF_LONG
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00001037 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001038#else
1039 ival = PyInt_FromLong((long)sec);
1040#endif
1041 if (_stat_float_times) {
1042 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1043 } else {
1044 fval = ival;
1045 Py_INCREF(fval);
1046 }
1047 PyStructSequence_SET_ITEM(v, index, ival);
1048 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001049}
1050
Tim Peters5aa91602002-01-30 05:46:57 +00001051/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001052 (used by posix_stat() and posix_fstat()) */
1053static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001054_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001055{
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001056 unsigned long ansec, mnsec, cnsec;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001057 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +00001058 if (v == NULL)
1059 return NULL;
1060
Martin v. Löwis14694662006-02-03 12:54:16 +00001061 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001062#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001063 PyStructSequence_SET_ITEM(v, 1,
Martin v. Löwis14694662006-02-03 12:54:16 +00001064 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001065#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001066 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001067#endif
1068#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +00001069 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwis14694662006-02-03 12:54:16 +00001070 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001071#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001072 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001073#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001074 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st->st_nlink));
1075 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st->st_uid));
1076 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001077#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001078 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwis14694662006-02-03 12:54:16 +00001079 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001080#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001081 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001082#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001083
Martin v. Löwis14694662006-02-03 12:54:16 +00001084#if defined(HAVE_STAT_TV_NSEC)
1085 ansec = st->st_atim.tv_nsec;
1086 mnsec = st->st_mtim.tv_nsec;
1087 cnsec = st->st_ctim.tv_nsec;
1088#elif defined(HAVE_STAT_TV_NSEC2)
1089 ansec = st->st_atimespec.tv_nsec;
1090 mnsec = st->st_mtimespec.tv_nsec;
1091 cnsec = st->st_ctimespec.tv_nsec;
1092#elif defined(HAVE_STAT_NSEC)
1093 ansec = st->st_atime_nsec;
1094 mnsec = st->st_mtime_nsec;
1095 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001096#else
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001097 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001098#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001099 fill_time(v, 7, st->st_atime, ansec);
1100 fill_time(v, 8, st->st_mtime, mnsec);
1101 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001102
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001103#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +00001104 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001105 PyInt_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001106#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001107#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +00001108 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001109 PyInt_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001110#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001111#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001112 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001113 PyInt_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001114#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001115#ifdef HAVE_STRUCT_STAT_ST_GEN
1116 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001117 PyInt_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001118#endif
1119#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1120 {
1121 PyObject *val;
1122 unsigned long bsec,bnsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001123 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001124#ifdef HAVE_STAT_TV_NSEC2
Hye-Shik Changd69e0342006-02-19 16:22:22 +00001125 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001126#else
1127 bnsec = 0;
1128#endif
1129 if (_stat_float_times) {
1130 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1131 } else {
1132 val = PyInt_FromLong((long)bsec);
1133 }
1134 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1135 val);
1136 }
1137#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001138#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1139 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001140 PyInt_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001141#endif
Fred Drake699f3522000-06-29 21:12:41 +00001142
1143 if (PyErr_Occurred()) {
1144 Py_DECREF(v);
1145 return NULL;
1146 }
1147
1148 return v;
1149}
1150
Martin v. Löwisd8948722004-06-02 09:57:56 +00001151#ifdef MS_WINDOWS
1152
1153/* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
1154 where / can be used in place of \ and the trailing slash is optional.
1155 Both SERVER and SHARE must have at least one character.
1156*/
1157
1158#define ISSLASHA(c) ((c) == '\\' || (c) == '/')
1159#define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
1160#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
1161
Tim Peters4ad82172004-08-30 17:02:04 +00001162static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001163IsUNCRootA(char *path, int pathlen)
1164{
1165 #define ISSLASH ISSLASHA
1166
1167 int i, share;
1168
1169 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1170 /* minimum UNCRoot is \\x\y */
1171 return FALSE;
1172 for (i = 2; i < pathlen ; i++)
1173 if (ISSLASH(path[i])) break;
1174 if (i == 2 || i == pathlen)
1175 /* do not allow \\\SHARE or \\SERVER */
1176 return FALSE;
1177 share = i+1;
1178 for (i = share; i < pathlen; i++)
1179 if (ISSLASH(path[i])) break;
1180 return (i != share && (i == pathlen || i == pathlen-1));
1181
1182 #undef ISSLASH
1183}
1184
1185#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters4ad82172004-08-30 17:02:04 +00001186static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001187IsUNCRootW(Py_UNICODE *path, int pathlen)
1188{
1189 #define ISSLASH ISSLASHW
1190
1191 int i, share;
1192
1193 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1194 /* minimum UNCRoot is \\x\y */
1195 return FALSE;
1196 for (i = 2; i < pathlen ; i++)
1197 if (ISSLASH(path[i])) break;
1198 if (i == 2 || i == pathlen)
1199 /* do not allow \\\SHARE or \\SERVER */
1200 return FALSE;
1201 share = i+1;
1202 for (i = share; i < pathlen; i++)
1203 if (ISSLASH(path[i])) break;
1204 return (i != share && (i == pathlen || i == pathlen-1));
1205
1206 #undef ISSLASH
1207}
1208#endif /* Py_WIN_WIDE_FILENAMES */
1209#endif /* MS_WINDOWS */
1210
Barry Warsaw53699e91996-12-10 23:23:01 +00001211static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001212posix_do_stat(PyObject *self, PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001213 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001214#ifdef __VMS
1215 int (*statfunc)(const char *, STRUCT_STAT *, ...),
1216#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001217 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001218#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001219 char *wformat,
1220 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001221{
Fred Drake699f3522000-06-29 21:12:41 +00001222 STRUCT_STAT st;
Tim Peters500bd032001-12-19 19:05:01 +00001223 char *path = NULL; /* pass this to stat; do not free() it */
1224 char *pathfree = NULL; /* this memory must be free'd */
Guido van Rossumff4949e1992-08-05 19:58:53 +00001225 int res;
Martin v. Löwis14694662006-02-03 12:54:16 +00001226 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001227
1228#ifdef Py_WIN_WIDE_FILENAMES
1229 /* If on wide-character-capable OS see if argument
1230 is Unicode and if so use wide API. */
1231 if (unicode_file_names()) {
1232 PyUnicodeObject *po;
1233 if (PyArg_ParseTuple(args, wformat, &po)) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001234 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
1235
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001236 Py_BEGIN_ALLOW_THREADS
1237 /* PyUnicode_AS_UNICODE result OK without
1238 thread lock as it is a simple dereference. */
1239 res = wstatfunc(wpath, &st);
1240 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001241
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001242 if (res != 0)
Martin v. Löwis14694662006-02-03 12:54:16 +00001243 return win32_error_unicode("stat", wpath);
1244 return _pystat_fromstructstat(&st);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001245 }
1246 /* Drop the argument parsing error as narrow strings
1247 are also valid. */
1248 PyErr_Clear();
1249 }
1250#endif
1251
Tim Peters5aa91602002-01-30 05:46:57 +00001252 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +00001253 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001254 return NULL;
Tim Peters500bd032001-12-19 19:05:01 +00001255 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +00001256
Barry Warsaw53699e91996-12-10 23:23:01 +00001257 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001258 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00001259 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001260
1261 if (res != 0) {
1262#ifdef MS_WINDOWS
1263 result = win32_error("stat", pathfree);
1264#else
1265 result = posix_error_with_filename(pathfree);
1266#endif
1267 }
1268 else
1269 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001270
Tim Peters500bd032001-12-19 19:05:01 +00001271 PyMem_Free(pathfree);
Martin v. Löwis14694662006-02-03 12:54:16 +00001272 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001273}
1274
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001275/* POSIX methods */
1276
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001277PyDoc_STRVAR(posix_access__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001278"access(path, mode) -> 1 if granted, 0 otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001279Use the real uid/gid to test for access to a path. Note that most\n\
1280operations will use the effective uid/gid, therefore this routine can\n\
1281be used in a suid/sgid environment to test if the invoking user has the\n\
1282specified access to the path. The mode argument can be F_OK to test\n\
1283existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001284
1285static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001286posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001287{
Guido van Rossum015f22a1999-01-06 22:52:38 +00001288 char *path;
1289 int mode;
1290 int res;
1291
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001292#ifdef Py_WIN_WIDE_FILENAMES
1293 if (unicode_file_names()) {
1294 PyUnicodeObject *po;
1295 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1296 Py_BEGIN_ALLOW_THREADS
1297 /* PyUnicode_AS_UNICODE OK without thread lock as
1298 it is a simple dereference. */
1299 res = _waccess(PyUnicode_AS_UNICODE(po), mode);
1300 Py_END_ALLOW_THREADS
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001301 return PyBool_FromLong(res == 0);
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001302 }
1303 /* Drop the argument parsing error as narrow strings
1304 are also valid. */
1305 PyErr_Clear();
1306 }
1307#endif
Martin v. Löwisb60ae992005-03-08 09:10:29 +00001308 if (!PyArg_ParseTuple(args, "eti:access",
1309 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +00001310 return NULL;
1311 Py_BEGIN_ALLOW_THREADS
1312 res = access(path, mode);
1313 Py_END_ALLOW_THREADS
Neal Norwitz24b3c222005-09-19 06:43:44 +00001314 PyMem_Free(path);
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001315 return PyBool_FromLong(res == 0);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001316}
1317
Guido van Rossumd371ff11999-01-25 16:12:23 +00001318#ifndef F_OK
1319#define F_OK 0
1320#endif
1321#ifndef R_OK
1322#define R_OK 4
1323#endif
1324#ifndef W_OK
1325#define W_OK 2
1326#endif
1327#ifndef X_OK
1328#define X_OK 1
1329#endif
1330
1331#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001332PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001333"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001334Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001335
1336static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001337posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001338{
Guido van Rossum94f6f721999-01-06 18:42:14 +00001339 int id;
1340 char *ret;
1341
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001342 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +00001343 return NULL;
1344
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001345#if defined(__VMS)
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +00001346 /* file descriptor 0 only, the default input device (stdin) */
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001347 if (id == 0) {
1348 ret = ttyname();
1349 }
1350 else {
1351 ret = NULL;
1352 }
1353#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00001354 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001355#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001356 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001357 return posix_error();
1358 return PyString_FromString(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001359}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001360#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001361
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001362#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001363PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001364"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001365Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001366
1367static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001368posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001369{
1370 char *ret;
1371 char buffer[L_ctermid];
1372
Greg Wardb48bc172000-03-01 21:51:56 +00001373#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001374 ret = ctermid_r(buffer);
1375#else
1376 ret = ctermid(buffer);
1377#endif
1378 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001379 return posix_error();
1380 return PyString_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001381}
1382#endif
1383
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001384PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001385"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001386Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001387
Barry Warsaw53699e91996-12-10 23:23:01 +00001388static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001389posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001390{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001391#ifdef MS_WINDOWS
1392 return posix_1str(args, "et:chdir", chdir, "U:chdir", _wchdir);
1393#elif defined(PYOS_OS2) && defined(PYCC_GCC)
1394 return posix_1str(args, "et:chdir", _chdir2, NULL, NULL);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001395#elif defined(__VMS)
Tim Peters11b23062003-04-23 02:39:17 +00001396 return posix_1str(args, "et:chdir", (int (*)(const char *))chdir,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001397 NULL, NULL);
1398#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001399 return posix_1str(args, "et:chdir", chdir, NULL, NULL);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001400#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001401}
1402
Fred Drake4d1e64b2002-04-15 19:40:07 +00001403#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001404PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001405"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001406Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001407opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001408
1409static PyObject *
1410posix_fchdir(PyObject *self, PyObject *fdobj)
1411{
1412 return posix_fildes(fdobj, fchdir);
1413}
1414#endif /* HAVE_FCHDIR */
1415
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001416
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001417PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001418"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001419Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001420
Barry Warsaw53699e91996-12-10 23:23:01 +00001421static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001422posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001423{
Mark Hammondef8b6542001-05-13 08:04:26 +00001424 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +00001425 int i;
1426 int res;
Mark Hammond817c9292003-12-03 01:22:38 +00001427#ifdef Py_WIN_WIDE_FILENAMES
1428 if (unicode_file_names()) {
1429 PyUnicodeObject *po;
1430 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1431 Py_BEGIN_ALLOW_THREADS
1432 res = _wchmod(PyUnicode_AS_UNICODE(po), i);
1433 Py_END_ALLOW_THREADS
1434 if (res < 0)
1435 return posix_error_with_unicode_filename(
1436 PyUnicode_AS_UNICODE(po));
1437 Py_INCREF(Py_None);
1438 return Py_None;
1439 }
1440 /* Drop the argument parsing error as narrow strings
1441 are also valid. */
1442 PyErr_Clear();
1443 }
1444#endif /* Py_WIN_WIDE_FILENAMES */
1445 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
Mark Hammondef8b6542001-05-13 08:04:26 +00001446 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +00001447 return NULL;
1448 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +00001449 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001450 Py_END_ALLOW_THREADS
1451 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001452 return posix_error_with_allocated_filename(path);
1453 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001454 Py_INCREF(Py_None);
1455 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001456}
1457
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001458
Martin v. Löwis244edc82001-10-04 22:44:26 +00001459#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001460PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001461"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001462Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00001463
1464static PyObject *
1465posix_chroot(PyObject *self, PyObject *args)
1466{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001467 return posix_1str(args, "et:chroot", chroot, NULL, NULL);
Martin v. Löwis244edc82001-10-04 22:44:26 +00001468}
1469#endif
1470
Guido van Rossum21142a01999-01-08 21:05:37 +00001471#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001472PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001473"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001474force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001475
1476static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001477posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001478{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001479 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001480}
1481#endif /* HAVE_FSYNC */
1482
1483#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00001484
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00001485#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00001486extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1487#endif
1488
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001489PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001490"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00001491force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001492 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001493
1494static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001495posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001496{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001497 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001498}
1499#endif /* HAVE_FDATASYNC */
1500
1501
Fredrik Lundh10723342000-07-10 16:38:09 +00001502#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001503PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001504"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001505Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001506
Barry Warsaw53699e91996-12-10 23:23:01 +00001507static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001508posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001509{
Mark Hammondef8b6542001-05-13 08:04:26 +00001510 char *path = NULL;
Fredrik Lundh44328e62000-07-10 15:59:30 +00001511 int uid, gid;
1512 int res;
Tim Peters5aa91602002-01-30 05:46:57 +00001513 if (!PyArg_ParseTuple(args, "etii:chown",
1514 Py_FileSystemDefaultEncoding, &path,
Mark Hammondef8b6542001-05-13 08:04:26 +00001515 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +00001516 return NULL;
1517 Py_BEGIN_ALLOW_THREADS
1518 res = chown(path, (uid_t) uid, (gid_t) gid);
1519 Py_END_ALLOW_THREADS
1520 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001521 return posix_error_with_allocated_filename(path);
1522 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +00001523 Py_INCREF(Py_None);
1524 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001525}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001526#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001527
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001528#ifdef HAVE_LCHOWN
1529PyDoc_STRVAR(posix_lchown__doc__,
1530"lchown(path, uid, gid)\n\n\
1531Change the owner and group id of path to the numeric uid and gid.\n\
1532This function will not follow symbolic links.");
1533
1534static PyObject *
1535posix_lchown(PyObject *self, PyObject *args)
1536{
1537 char *path = NULL;
1538 int uid, gid;
1539 int res;
1540 if (!PyArg_ParseTuple(args, "etii:lchown",
1541 Py_FileSystemDefaultEncoding, &path,
1542 &uid, &gid))
1543 return NULL;
1544 Py_BEGIN_ALLOW_THREADS
1545 res = lchown(path, (uid_t) uid, (gid_t) gid);
1546 Py_END_ALLOW_THREADS
Tim Peters11b23062003-04-23 02:39:17 +00001547 if (res < 0)
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001548 return posix_error_with_allocated_filename(path);
1549 PyMem_Free(path);
1550 Py_INCREF(Py_None);
1551 return Py_None;
1552}
1553#endif /* HAVE_LCHOWN */
1554
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001555
Guido van Rossum36bc6801995-06-14 22:54:23 +00001556#ifdef HAVE_GETCWD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001557PyDoc_STRVAR(posix_getcwd__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001558"getcwd() -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001559Return a string representing the current working directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001560
Barry Warsaw53699e91996-12-10 23:23:01 +00001561static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001562posix_getcwd(PyObject *self, PyObject *noargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001563{
1564 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +00001565 char *res;
Neal Norwitze241ce82003-02-17 18:17:05 +00001566
Barry Warsaw53699e91996-12-10 23:23:01 +00001567 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001568#if defined(PYOS_OS2) && defined(PYCC_GCC)
1569 res = _getcwd2(buf, sizeof buf);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001570#else
Guido van Rossumff4949e1992-08-05 19:58:53 +00001571 res = getcwd(buf, sizeof buf);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001572#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001573 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001574 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001575 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001576 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001577}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001578
Walter Dörwald3b918c32002-11-21 20:18:46 +00001579#ifdef Py_USING_UNICODE
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001580PyDoc_STRVAR(posix_getcwdu__doc__,
1581"getcwdu() -> path\n\n\
1582Return a unicode string representing the current working directory.");
1583
1584static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001585posix_getcwdu(PyObject *self, PyObject *noargs)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001586{
1587 char buf[1026];
1588 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001589
1590#ifdef Py_WIN_WIDE_FILENAMES
1591 if (unicode_file_names()) {
1592 wchar_t *wres;
1593 wchar_t wbuf[1026];
1594 Py_BEGIN_ALLOW_THREADS
1595 wres = _wgetcwd(wbuf, sizeof wbuf/ sizeof wbuf[0]);
1596 Py_END_ALLOW_THREADS
1597 if (wres == NULL)
1598 return posix_error();
1599 return PyUnicode_FromWideChar(wbuf, wcslen(wbuf));
1600 }
1601#endif
1602
1603 Py_BEGIN_ALLOW_THREADS
1604#if defined(PYOS_OS2) && defined(PYCC_GCC)
1605 res = _getcwd2(buf, sizeof buf);
1606#else
1607 res = getcwd(buf, sizeof buf);
1608#endif
1609 Py_END_ALLOW_THREADS
1610 if (res == NULL)
1611 return posix_error();
1612 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
1613}
Guido van Rossum36bc6801995-06-14 22:54:23 +00001614#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00001615#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001616
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001617
Guido van Rossumb6775db1994-08-01 11:34:53 +00001618#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001619PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001620"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001621Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001622
Barry Warsaw53699e91996-12-10 23:23:01 +00001623static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001624posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001625{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001626 return posix_2str(args, "etet:link", link, NULL, NULL);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001627}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001628#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001629
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001630
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001631PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001632"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001633Return a list containing the names of the entries in the directory.\n\
1634\n\
1635 path: path of directory to list\n\
1636\n\
1637The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001638entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001639
Barry Warsaw53699e91996-12-10 23:23:01 +00001640static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001641posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001642{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001643 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001644 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001645#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001646
Barry Warsaw53699e91996-12-10 23:23:01 +00001647 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001648 HANDLE hFindFile;
Martin v. Löwise920f0d2006-03-07 23:59:33 +00001649 BOOL result;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001650 WIN32_FIND_DATA FileData;
Mark Hammondef8b6542001-05-13 08:04:26 +00001651 /* MAX_PATH characters could mean a bigger encoded string */
1652 char namebuf[MAX_PATH*2+5];
1653 char *bufptr = namebuf;
Martin v. Löwis18e16552006-02-15 17:27:45 +00001654 Py_ssize_t len = sizeof(namebuf)/sizeof(namebuf[0]);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001655
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001656#ifdef Py_WIN_WIDE_FILENAMES
1657 /* If on wide-character-capable OS see if argument
1658 is Unicode and if so use wide API. */
1659 if (unicode_file_names()) {
1660 PyUnicodeObject *po;
1661 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
1662 WIN32_FIND_DATAW wFileData;
1663 Py_UNICODE wnamebuf[MAX_PATH*2+5];
1664 Py_UNICODE wch;
1665 wcsncpy(wnamebuf, PyUnicode_AS_UNICODE(po), MAX_PATH);
1666 wnamebuf[MAX_PATH] = L'\0';
1667 len = wcslen(wnamebuf);
1668 wch = (len > 0) ? wnamebuf[len-1] : L'\0';
1669 if (wch != L'/' && wch != L'\\' && wch != L':')
1670 wnamebuf[len++] = L'/';
1671 wcscpy(wnamebuf + len, L"*.*");
1672 if ((d = PyList_New(0)) == NULL)
1673 return NULL;
1674 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
1675 if (hFindFile == INVALID_HANDLE_VALUE) {
1676 errno = GetLastError();
1677 if (errno == ERROR_FILE_NOT_FOUND) {
1678 return d;
1679 }
1680 Py_DECREF(d);
1681 return win32_error_unicode("FindFirstFileW", wnamebuf);
1682 }
1683 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00001684 /* Skip over . and .. */
1685 if (wcscmp(wFileData.cFileName, L".") != 0 &&
1686 wcscmp(wFileData.cFileName, L"..") != 0) {
1687 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
1688 if (v == NULL) {
1689 Py_DECREF(d);
1690 d = NULL;
1691 break;
1692 }
1693 if (PyList_Append(d, v) != 0) {
1694 Py_DECREF(v);
1695 Py_DECREF(d);
1696 d = NULL;
1697 break;
1698 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001699 Py_DECREF(v);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001700 }
Georg Brandl622927b2006-03-07 12:48:03 +00001701 Py_BEGIN_ALLOW_THREADS
1702 result = FindNextFileW(hFindFile, &wFileData);
1703 Py_END_ALLOW_THREADS
1704 } while (result == TRUE);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001705
1706 if (FindClose(hFindFile) == FALSE) {
1707 Py_DECREF(d);
1708 return win32_error_unicode("FindClose", wnamebuf);
1709 }
1710 return d;
1711 }
1712 /* Drop the argument parsing error as narrow strings
1713 are also valid. */
1714 PyErr_Clear();
1715 }
1716#endif
1717
Tim Peters5aa91602002-01-30 05:46:57 +00001718 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001719 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +00001720 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +00001721 if (len > 0) {
1722 char ch = namebuf[len-1];
1723 if (ch != SEP && ch != ALTSEP && ch != ':')
1724 namebuf[len++] = '/';
1725 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001726 strcpy(namebuf + len, "*.*");
1727
Barry Warsaw53699e91996-12-10 23:23:01 +00001728 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001729 return NULL;
1730
1731 hFindFile = FindFirstFile(namebuf, &FileData);
1732 if (hFindFile == INVALID_HANDLE_VALUE) {
1733 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +00001734 if (errno == ERROR_FILE_NOT_FOUND)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001735 return d;
1736 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00001737 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001738 }
1739 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00001740 /* Skip over . and .. */
1741 if (strcmp(FileData.cFileName, ".") != 0 &&
1742 strcmp(FileData.cFileName, "..") != 0) {
1743 v = PyString_FromString(FileData.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 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001755 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001756 }
Georg Brandl622927b2006-03-07 12:48:03 +00001757 Py_BEGIN_ALLOW_THREADS
1758 result = FindNextFile(hFindFile, &FileData);
1759 Py_END_ALLOW_THREADS
1760 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001761
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001762 if (FindClose(hFindFile) == FALSE) {
1763 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00001764 return win32_error("FindClose", namebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001765 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001766
1767 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001768
Tim Peters0bb44a42000-09-15 07:44:49 +00001769#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001770
1771#ifndef MAX_PATH
1772#define MAX_PATH CCHMAXPATH
1773#endif
1774 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00001775 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001776 PyObject *d, *v;
1777 char namebuf[MAX_PATH+5];
1778 HDIR hdir = 1;
1779 ULONG srchcnt = 1;
1780 FILEFINDBUF3 ep;
1781 APIRET rc;
1782
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001783 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001784 return NULL;
1785 if (len >= MAX_PATH) {
1786 PyErr_SetString(PyExc_ValueError, "path too long");
1787 return NULL;
1788 }
1789 strcpy(namebuf, name);
1790 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001791 if (*pt == ALTSEP)
1792 *pt = SEP;
1793 if (namebuf[len-1] != SEP)
1794 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001795 strcpy(namebuf + len, "*.*");
1796
1797 if ((d = PyList_New(0)) == NULL)
1798 return NULL;
1799
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001800 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
1801 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001802 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001803 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
1804 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
1805 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001806
1807 if (rc != NO_ERROR) {
1808 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001809 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001810 }
1811
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001812 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001813 do {
1814 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001815 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001816 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001817
1818 strcpy(namebuf, ep.achName);
1819
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001820 /* Leave Case of Name Alone -- In Native Form */
1821 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001822
1823 v = PyString_FromString(namebuf);
1824 if (v == NULL) {
1825 Py_DECREF(d);
1826 d = NULL;
1827 break;
1828 }
1829 if (PyList_Append(d, v) != 0) {
1830 Py_DECREF(v);
1831 Py_DECREF(d);
1832 d = NULL;
1833 break;
1834 }
1835 Py_DECREF(v);
1836 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1837 }
1838
1839 return d;
1840#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001841
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001842 char *name = NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001843 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001844 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001845 struct dirent *ep;
Just van Rossum96b1c902003-03-03 17:32:15 +00001846 int arg_is_unicode = 1;
1847
Georg Brandl05e89b82006-04-11 07:04:06 +00001848 errno = 0;
Just van Rossum96b1c902003-03-03 17:32:15 +00001849 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
1850 arg_is_unicode = 0;
1851 PyErr_Clear();
1852 }
1853 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001854 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001855 if ((dirp = opendir(name)) == NULL) {
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001856 return posix_error_with_allocated_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001857 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001858 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001859 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001860 PyMem_Free(name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001861 return NULL;
1862 }
Georg Brandl622927b2006-03-07 12:48:03 +00001863 for (;;) {
1864 Py_BEGIN_ALLOW_THREADS
1865 ep = readdir(dirp);
1866 Py_END_ALLOW_THREADS
1867 if (ep == NULL)
1868 break;
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001869 if (ep->d_name[0] == '.' &&
1870 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001871 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001872 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001873 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001874 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001875 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001876 d = NULL;
1877 break;
1878 }
Just van Rossum46c97842003-02-25 21:42:15 +00001879#ifdef Py_USING_UNICODE
Just van Rossum96b1c902003-03-03 17:32:15 +00001880 if (arg_is_unicode) {
Just van Rossum46c97842003-02-25 21:42:15 +00001881 PyObject *w;
1882
1883 w = PyUnicode_FromEncodedObject(v,
Tim Peters11b23062003-04-23 02:39:17 +00001884 Py_FileSystemDefaultEncoding,
Just van Rossum46c97842003-02-25 21:42:15 +00001885 "strict");
Just van Rossum6a421832003-03-04 19:30:44 +00001886 if (w != NULL) {
1887 Py_DECREF(v);
1888 v = w;
1889 }
1890 else {
1891 /* fall back to the original byte string, as
1892 discussed in patch #683592 */
1893 PyErr_Clear();
Just van Rossum46c97842003-02-25 21:42:15 +00001894 }
Just van Rossum46c97842003-02-25 21:42:15 +00001895 }
1896#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001897 if (PyList_Append(d, v) != 0) {
1898 Py_DECREF(v);
1899 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001900 d = NULL;
1901 break;
1902 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001903 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001904 }
Georg Brandlbbfe4fa2006-04-11 06:47:43 +00001905 if (errno != 0 && d != NULL) {
1906 /* readdir() returned NULL and set errno */
1907 closedir(dirp);
1908 Py_DECREF(d);
1909 return posix_error_with_allocated_filename(name);
1910 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001911 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001912 PyMem_Free(name);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001913
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001914 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001915
Tim Peters0bb44a42000-09-15 07:44:49 +00001916#endif /* which OS */
1917} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001918
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001919#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00001920/* A helper function for abspath on win32 */
1921static PyObject *
1922posix__getfullpathname(PyObject *self, PyObject *args)
1923{
1924 /* assume encoded strings wont more than double no of chars */
1925 char inbuf[MAX_PATH*2];
1926 char *inbufp = inbuf;
Tim Peters67d70eb2006-03-01 04:35:45 +00001927 Py_ssize_t insize = sizeof(inbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00001928 char outbuf[MAX_PATH*2];
1929 char *temp;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001930#ifdef Py_WIN_WIDE_FILENAMES
1931 if (unicode_file_names()) {
1932 PyUnicodeObject *po;
1933 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
1934 Py_UNICODE woutbuf[MAX_PATH*2];
1935 Py_UNICODE *wtemp;
Tim Peters11b23062003-04-23 02:39:17 +00001936 if (!GetFullPathNameW(PyUnicode_AS_UNICODE(po),
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001937 sizeof(woutbuf)/sizeof(woutbuf[0]),
1938 woutbuf, &wtemp))
1939 return win32_error("GetFullPathName", "");
1940 return PyUnicode_FromUnicode(woutbuf, wcslen(woutbuf));
1941 }
1942 /* Drop the argument parsing error as narrow strings
1943 are also valid. */
1944 PyErr_Clear();
1945 }
1946#endif
Tim Peters5aa91602002-01-30 05:46:57 +00001947 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
1948 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00001949 &insize))
1950 return NULL;
1951 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
1952 outbuf, &temp))
1953 return win32_error("GetFullPathName", inbuf);
Martin v. Löwis969297f2004-06-15 18:49:58 +00001954 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
1955 return PyUnicode_Decode(outbuf, strlen(outbuf),
1956 Py_FileSystemDefaultEncoding, NULL);
1957 }
Mark Hammondef8b6542001-05-13 08:04:26 +00001958 return PyString_FromString(outbuf);
1959} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001960#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00001961
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001962PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001963"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001964Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001965
Barry Warsaw53699e91996-12-10 23:23:01 +00001966static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001967posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001968{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001969 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00001970 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001971 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001972
1973#ifdef Py_WIN_WIDE_FILENAMES
1974 if (unicode_file_names()) {
1975 PyUnicodeObject *po;
Mark Hammond05107b62003-02-19 04:08:27 +00001976 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001977 Py_BEGIN_ALLOW_THREADS
1978 /* PyUnicode_AS_UNICODE OK without thread lock as
1979 it is a simple dereference. */
1980 res = _wmkdir(PyUnicode_AS_UNICODE(po));
1981 Py_END_ALLOW_THREADS
1982 if (res < 0)
1983 return posix_error();
1984 Py_INCREF(Py_None);
1985 return Py_None;
1986 }
1987 /* Drop the argument parsing error as narrow strings
1988 are also valid. */
1989 PyErr_Clear();
1990 }
1991#endif
1992
Tim Peters5aa91602002-01-30 05:46:57 +00001993 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001994 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001995 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001996 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001997#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001998 res = mkdir(path);
1999#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00002000 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002001#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002002 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00002003 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00002004 return posix_error_with_allocated_filename(path);
2005 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002006 Py_INCREF(Py_None);
2007 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002008}
2009
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002010
Neal Norwitz1818ed72006-03-26 00:29:48 +00002011/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2012#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002013#include <sys/resource.h>
2014#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002015
Neal Norwitz1818ed72006-03-26 00:29:48 +00002016
2017#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002018PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002019"nice(inc) -> new_priority\n\n\
2020Decrease the priority of process by inc and return the new priority.");
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_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002024{
2025 int increment, value;
2026
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002027 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00002028 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002029
2030 /* There are two flavours of 'nice': one that returns the new
2031 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002032 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2033 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002034
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002035 If we are of the nice family that returns the new priority, we
2036 need to clear errno before the call, and check if errno is filled
2037 before calling posix_error() on a returnvalue of -1, because the
2038 -1 may be the actual new priority! */
2039
2040 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002041 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002042#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002043 if (value == 0)
2044 value = getpriority(PRIO_PROCESS, 0);
2045#endif
2046 if (value == -1 && errno != 0)
2047 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00002048 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002049 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002050}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002051#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002052
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002053
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002054PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002055"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002056Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002057
Barry Warsaw53699e91996-12-10 23:23:01 +00002058static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002059posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002060{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002061#ifdef MS_WINDOWS
2062 return posix_2str(args, "etet:rename", rename, "OO:rename", _wrename);
2063#else
2064 return posix_2str(args, "etet:rename", rename, NULL, NULL);
2065#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002066}
2067
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002068
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002069PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002070"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002071Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002072
Barry Warsaw53699e91996-12-10 23:23:01 +00002073static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002074posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002075{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002076#ifdef MS_WINDOWS
2077 return posix_1str(args, "et:rmdir", rmdir, "U:rmdir", _wrmdir);
2078#else
2079 return posix_1str(args, "et:rmdir", rmdir, NULL, NULL);
2080#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002081}
2082
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002083
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002084PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002085"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002086Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002087
Barry Warsaw53699e91996-12-10 23:23:01 +00002088static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002089posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002090{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002091#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00002092 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002093#else
2094 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
2095#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002096}
2097
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002098
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002099#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002100PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002101"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002102Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002103
Barry Warsaw53699e91996-12-10 23:23:01 +00002104static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002105posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002106{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002107 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002108 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002109 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002110 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002111 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002112 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00002113 Py_END_ALLOW_THREADS
2114 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002115}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002116#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002117
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002118
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002119PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002120"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002121Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002122
Barry Warsaw53699e91996-12-10 23:23:01 +00002123static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002124posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002125{
2126 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002127 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002128 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00002129 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002130 if (i < 0)
2131 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002132 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002133}
2134
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002135
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002136PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002137"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002138Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002139
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002140PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002141"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002142Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002143
Barry Warsaw53699e91996-12-10 23:23:01 +00002144static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002145posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002146{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002147#ifdef MS_WINDOWS
2148 return posix_1str(args, "et:remove", unlink, "U:remove", _wunlink);
2149#else
2150 return posix_1str(args, "et:remove", unlink, NULL, NULL);
2151#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002152}
2153
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002154
Guido van Rossumb6775db1994-08-01 11:34:53 +00002155#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002156PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002157"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002158Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002159
Barry Warsaw53699e91996-12-10 23:23:01 +00002160static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002161posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002162{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002163 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002164 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00002165
Barry Warsaw53699e91996-12-10 23:23:01 +00002166 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002167 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00002168 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002169 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002170 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002171 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00002172 u.sysname,
2173 u.nodename,
2174 u.release,
2175 u.version,
2176 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002177}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002178#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002179
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002180static int
2181extract_time(PyObject *t, long* sec, long* usec)
2182{
2183 long intval;
2184 if (PyFloat_Check(t)) {
2185 double tval = PyFloat_AsDouble(t);
2186 PyObject *intobj = t->ob_type->tp_as_number->nb_int(t);
2187 if (!intobj)
2188 return -1;
2189 intval = PyInt_AsLong(intobj);
2190 Py_DECREF(intobj);
Michael W. Hudsonb8963812005-07-05 15:21:58 +00002191 if (intval == -1 && PyErr_Occurred())
2192 return -1;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002193 *sec = intval;
Tim Peters96940cf2002-09-10 15:37:28 +00002194 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002195 if (*usec < 0)
2196 /* If rounding gave us a negative number,
2197 truncate. */
2198 *usec = 0;
2199 return 0;
2200 }
2201 intval = PyInt_AsLong(t);
2202 if (intval == -1 && PyErr_Occurred())
2203 return -1;
2204 *sec = intval;
2205 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00002206 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002207}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002208
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002209PyDoc_STRVAR(posix_utime__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002210"utime(path, (atime, utime))\n\
2211utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00002212Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002213second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002214
Barry Warsaw53699e91996-12-10 23:23:01 +00002215static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002216posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002217{
Neal Norwitz2adf2102004-06-09 01:46:02 +00002218 char *path = NULL;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002219 long atime, mtime, ausec, musec;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002220 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002221 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002222
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002223#if defined(HAVE_UTIMES)
2224 struct timeval buf[2];
2225#define ATIME buf[0].tv_sec
2226#define MTIME buf[1].tv_sec
2227#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002228/* XXX should define struct utimbuf instead, above */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002229 struct utimbuf buf;
2230#define ATIME buf.actime
2231#define MTIME buf.modtime
2232#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002233#else /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002234 time_t buf[2];
2235#define ATIME buf[0]
2236#define MTIME buf[1]
2237#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002238#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002239
Mark Hammond817c9292003-12-03 01:22:38 +00002240 int have_unicode_filename = 0;
2241#ifdef Py_WIN_WIDE_FILENAMES
2242 PyUnicodeObject *obwpath;
2243 wchar_t *wpath;
2244 if (unicode_file_names()) {
2245 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
2246 wpath = PyUnicode_AS_UNICODE(obwpath);
2247 have_unicode_filename = 1;
2248 } else
2249 /* Drop the argument parsing error as narrow strings
2250 are also valid. */
2251 PyErr_Clear();
2252 }
2253#endif /* Py_WIN_WIDE_FILENAMES */
2254
2255 if (!have_unicode_filename && \
Hye-Shik Chang2b2c9732004-01-04 13:54:25 +00002256 !PyArg_ParseTuple(args, "etO:utime",
2257 Py_FileSystemDefaultEncoding, &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002258 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002259 if (arg == Py_None) {
2260 /* optional time values not given */
2261 Py_BEGIN_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002262#ifdef Py_WIN_WIDE_FILENAMES
2263 if (have_unicode_filename)
2264 res = _wutime(wpath, NULL);
2265 else
2266#endif /* Py_WIN_WIDE_FILENAMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002267 res = utime(path, NULL);
2268 Py_END_ALLOW_THREADS
2269 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002270 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00002271 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002272 "utime() arg 2 must be a tuple (atime, mtime)");
Neal Norwitz96652712004-06-06 20:40:27 +00002273 PyMem_Free(path);
Barry Warsaw3cef8562000-05-01 16:17:24 +00002274 return NULL;
2275 }
2276 else {
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002277 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Neal Norwitz96652712004-06-06 20:40:27 +00002278 &atime, &ausec) == -1) {
2279 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002280 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002281 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002282 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Neal Norwitz96652712004-06-06 20:40:27 +00002283 &mtime, &musec) == -1) {
2284 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002285 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002286 }
Barry Warsaw3cef8562000-05-01 16:17:24 +00002287 ATIME = atime;
2288 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002289#ifdef HAVE_UTIMES
2290 buf[0].tv_usec = ausec;
2291 buf[1].tv_usec = musec;
2292 Py_BEGIN_ALLOW_THREADS
2293 res = utimes(path, buf);
2294 Py_END_ALLOW_THREADS
2295#else
Barry Warsaw3cef8562000-05-01 16:17:24 +00002296 Py_BEGIN_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002297#ifdef Py_WIN_WIDE_FILENAMES
2298 if (have_unicode_filename)
Tim Peters4ad82172004-08-30 17:02:04 +00002299 /* utime is OK with utimbuf, but _wutime insists
2300 on _utimbuf (the msvc headers assert the
Mark Hammond817c9292003-12-03 01:22:38 +00002301 underscore version is ansi) */
2302 res = _wutime(wpath, (struct _utimbuf *)UTIME_ARG);
2303 else
2304#endif /* Py_WIN_WIDE_FILENAMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002305 res = utime(path, UTIME_ARG);
2306 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002307#endif /* HAVE_UTIMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002308 }
Mark Hammond2d5914b2004-05-04 08:10:37 +00002309 if (res < 0) {
2310#ifdef Py_WIN_WIDE_FILENAMES
Neal Norwitz2adf2102004-06-09 01:46:02 +00002311 if (have_unicode_filename)
Mark Hammond2d5914b2004-05-04 08:10:37 +00002312 return posix_error_with_unicode_filename(wpath);
2313#endif /* Py_WIN_WIDE_FILENAMES */
Neal Norwitz96652712004-06-06 20:40:27 +00002314 return posix_error_with_allocated_filename(path);
Mark Hammond2d5914b2004-05-04 08:10:37 +00002315 }
Neal Norwitz96652712004-06-06 20:40:27 +00002316 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002317 Py_INCREF(Py_None);
2318 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002319#undef UTIME_ARG
2320#undef ATIME
2321#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002322}
2323
Guido van Rossum85e3b011991-06-03 12:42:10 +00002324
Guido van Rossum3b066191991-06-04 19:40:25 +00002325/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002326
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002327PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002328"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002329Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002330
Barry Warsaw53699e91996-12-10 23:23:01 +00002331static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002332posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002333{
2334 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002335 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002336 return NULL;
2337 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00002338 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002339}
2340
Martin v. Löwis114619e2002-10-07 06:44:21 +00002341#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
2342static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00002343free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00002344{
Martin v. Löwis725507b2006-03-07 12:08:51 +00002345 Py_ssize_t i;
Martin v. Löwis114619e2002-10-07 06:44:21 +00002346 for (i = 0; i < count; i++)
2347 PyMem_Free(array[i]);
2348 PyMem_DEL(array);
2349}
2350#endif
2351
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002352
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002353#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002354PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002355"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002356Execute an executable path with arguments, replacing current process.\n\
2357\n\
2358 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002359 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002360
Barry Warsaw53699e91996-12-10 23:23:01 +00002361static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002362posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002363{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002364 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002365 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002366 char **argvlist;
Martin v. Löwis725507b2006-03-07 12:08:51 +00002367 Py_ssize_t i, argc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002368 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002369
Guido van Rossum89b33251993-10-22 14:26:06 +00002370 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00002371 argv is a list or tuple of strings. */
2372
Martin v. Löwis114619e2002-10-07 06:44:21 +00002373 if (!PyArg_ParseTuple(args, "etO:execv",
2374 Py_FileSystemDefaultEncoding,
2375 &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002376 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002377 if (PyList_Check(argv)) {
2378 argc = PyList_Size(argv);
2379 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002380 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002381 else if (PyTuple_Check(argv)) {
2382 argc = PyTuple_Size(argv);
2383 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002384 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002385 else {
Fred Drake661ea262000-10-24 19:57:45 +00002386 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002387 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002388 return NULL;
2389 }
2390
Barry Warsaw53699e91996-12-10 23:23:01 +00002391 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002392 if (argvlist == NULL) {
2393 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002394 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002395 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002396 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002397 if (!PyArg_Parse((*getitem)(argv, i), "et",
2398 Py_FileSystemDefaultEncoding,
2399 &argvlist[i])) {
2400 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00002401 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002402 "execv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002403 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002404 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00002405
Guido van Rossum85e3b011991-06-03 12:42:10 +00002406 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002407 }
2408 argvlist[argc] = NULL;
2409
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002410 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002411
Guido van Rossum85e3b011991-06-03 12:42:10 +00002412 /* If we get here it's definitely an error */
2413
Martin v. Löwis114619e2002-10-07 06:44:21 +00002414 free_string_array(argvlist, argc);
2415 PyMem_Free(path);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002416 return posix_error();
2417}
2418
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002419
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002420PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002421"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002422Execute a path with arguments and environment, replacing current process.\n\
2423\n\
2424 path: path of executable file\n\
2425 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002426 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002427
Barry Warsaw53699e91996-12-10 23:23:01 +00002428static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002429posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002430{
2431 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002432 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002433 char **argvlist;
2434 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002435 PyObject *key, *val, *keys=NULL, *vals=NULL;
Martin v. Löwis725507b2006-03-07 12:08:51 +00002436 Py_ssize_t i, pos, argc, envc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002437 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002438 int lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002439
2440 /* execve has three arguments: (path, argv, env), where
2441 argv is a list or tuple of strings and env is a dictionary
2442 like posix.environ. */
2443
Martin v. Löwis114619e2002-10-07 06:44:21 +00002444 if (!PyArg_ParseTuple(args, "etOO:execve",
2445 Py_FileSystemDefaultEncoding,
2446 &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002447 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002448 if (PyList_Check(argv)) {
2449 argc = PyList_Size(argv);
2450 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002451 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002452 else if (PyTuple_Check(argv)) {
2453 argc = PyTuple_Size(argv);
2454 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002455 }
2456 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002457 PyErr_SetString(PyExc_TypeError,
2458 "execve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002459 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002460 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002461 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002462 PyErr_SetString(PyExc_TypeError,
2463 "execve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002464 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002465 }
2466
Barry Warsaw53699e91996-12-10 23:23:01 +00002467 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002468 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002469 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002470 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002471 }
2472 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002473 if (!PyArg_Parse((*getitem)(argv, i),
Martin v. Löwis114619e2002-10-07 06:44:21 +00002474 "et;execve() arg 2 must contain only strings",
Guido van Rossum1e700d22002-10-16 16:52:11 +00002475 Py_FileSystemDefaultEncoding,
Barry Warsaw43d68b81996-12-19 22:10:44 +00002476 &argvlist[i]))
2477 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002478 lastarg = i;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002479 goto fail_1;
2480 }
2481 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002482 lastarg = argc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002483 argvlist[argc] = NULL;
2484
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002485 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002486 if (i < 0)
2487 goto fail_1;
Barry Warsaw53699e91996-12-10 23:23:01 +00002488 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002489 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002490 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002491 goto fail_1;
2492 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002493 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002494 keys = PyMapping_Keys(env);
2495 vals = PyMapping_Values(env);
2496 if (!keys || !vals)
2497 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002498 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2499 PyErr_SetString(PyExc_TypeError,
2500 "execve(): env.keys() or env.values() is not a list");
2501 goto fail_2;
2502 }
Tim Peters5aa91602002-01-30 05:46:57 +00002503
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002504 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002505 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002506 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002507
2508 key = PyList_GetItem(keys, pos);
2509 val = PyList_GetItem(vals, pos);
2510 if (!key || !val)
2511 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002512
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002513 if (!PyArg_Parse(
2514 key,
2515 "s;execve() arg 3 contains a non-string key",
2516 &k) ||
2517 !PyArg_Parse(
2518 val,
2519 "s;execve() arg 3 contains a non-string value",
2520 &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00002521 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002522 goto fail_2;
2523 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00002524
2525#if defined(PYOS_OS2)
2526 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
2527 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
2528#endif
Tim Petersc8996f52001-12-03 20:41:00 +00002529 len = PyString_Size(key) + PyString_Size(val) + 2;
2530 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002531 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002532 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002533 goto fail_2;
2534 }
Tim Petersc8996f52001-12-03 20:41:00 +00002535 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002536 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00002537#if defined(PYOS_OS2)
2538 }
2539#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002540 }
2541 envlist[envc] = 0;
2542
2543 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00002544
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002545 /* If we get here it's definitely an error */
2546
2547 (void) posix_error();
2548
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002549 fail_2:
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002550 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00002551 PyMem_DEL(envlist[envc]);
2552 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002553 fail_1:
2554 free_string_array(argvlist, lastarg);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002555 Py_XDECREF(vals);
2556 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002557 fail_0:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002558 PyMem_Free(path);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002559 return NULL;
2560}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002561#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002562
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002563
Guido van Rossuma1065681999-01-25 23:20:23 +00002564#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002565PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002566"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002567Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002568\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002569 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002570 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002571 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002572
2573static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002574posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002575{
2576 char *path;
2577 PyObject *argv;
2578 char **argvlist;
2579 int mode, i, argc;
Tim Peters79248aa2001-08-29 21:37:10 +00002580 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002581 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00002582
2583 /* spawnv has three arguments: (mode, path, argv), where
2584 argv is a list or tuple of strings. */
2585
Martin v. Löwis114619e2002-10-07 06:44:21 +00002586 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
2587 Py_FileSystemDefaultEncoding,
2588 &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00002589 return NULL;
2590 if (PyList_Check(argv)) {
2591 argc = PyList_Size(argv);
2592 getitem = PyList_GetItem;
2593 }
2594 else if (PyTuple_Check(argv)) {
2595 argc = PyTuple_Size(argv);
2596 getitem = PyTuple_GetItem;
2597 }
2598 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002599 PyErr_SetString(PyExc_TypeError,
2600 "spawnv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002601 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002602 return NULL;
2603 }
2604
2605 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002606 if (argvlist == NULL) {
2607 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002608 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002609 }
Guido van Rossuma1065681999-01-25 23:20:23 +00002610 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002611 if (!PyArg_Parse((*getitem)(argv, i), "et",
2612 Py_FileSystemDefaultEncoding,
2613 &argvlist[i])) {
2614 free_string_array(argvlist, i);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002615 PyErr_SetString(
2616 PyExc_TypeError,
2617 "spawnv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002618 PyMem_Free(path);
Fred Drake137507e2000-06-01 02:02:46 +00002619 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00002620 }
2621 }
2622 argvlist[argc] = NULL;
2623
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002624#if defined(PYOS_OS2) && defined(PYCC_GCC)
2625 Py_BEGIN_ALLOW_THREADS
2626 spawnval = spawnv(mode, path, argvlist);
2627 Py_END_ALLOW_THREADS
2628#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002629 if (mode == _OLD_P_OVERLAY)
2630 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00002631
Tim Peters25059d32001-12-07 20:35:43 +00002632 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002633 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00002634 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002635#endif
Tim Peters5aa91602002-01-30 05:46:57 +00002636
Martin v. Löwis114619e2002-10-07 06:44:21 +00002637 free_string_array(argvlist, argc);
2638 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002639
Fred Drake699f3522000-06-29 21:12:41 +00002640 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002641 return posix_error();
2642 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002643#if SIZEOF_LONG == SIZEOF_VOID_P
2644 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002645#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00002646 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002647#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002648}
2649
2650
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002651PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002652"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002653Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002654\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002655 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002656 path: path of executable file\n\
2657 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002658 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002659
2660static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002661posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002662{
2663 char *path;
2664 PyObject *argv, *env;
2665 char **argvlist;
2666 char **envlist;
2667 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
2668 int mode, i, pos, argc, envc;
Tim Peters79248aa2001-08-29 21:37:10 +00002669 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002670 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002671 int lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002672
2673 /* spawnve has four arguments: (mode, path, argv, env), where
2674 argv is a list or tuple of strings and env is a dictionary
2675 like posix.environ. */
2676
Martin v. Löwis114619e2002-10-07 06:44:21 +00002677 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
2678 Py_FileSystemDefaultEncoding,
2679 &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00002680 return NULL;
2681 if (PyList_Check(argv)) {
2682 argc = PyList_Size(argv);
2683 getitem = PyList_GetItem;
2684 }
2685 else if (PyTuple_Check(argv)) {
2686 argc = PyTuple_Size(argv);
2687 getitem = PyTuple_GetItem;
2688 }
2689 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002690 PyErr_SetString(PyExc_TypeError,
2691 "spawnve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002692 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002693 }
2694 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002695 PyErr_SetString(PyExc_TypeError,
2696 "spawnve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002697 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002698 }
2699
2700 argvlist = PyMem_NEW(char *, argc+1);
2701 if (argvlist == NULL) {
2702 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002703 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002704 }
2705 for (i = 0; i < argc; i++) {
2706 if (!PyArg_Parse((*getitem)(argv, i),
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002707 "et;spawnve() arg 2 must contain only strings",
Martin v. Löwis114619e2002-10-07 06:44:21 +00002708 Py_FileSystemDefaultEncoding,
Guido van Rossuma1065681999-01-25 23:20:23 +00002709 &argvlist[i]))
2710 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002711 lastarg = i;
Guido van Rossuma1065681999-01-25 23:20:23 +00002712 goto fail_1;
2713 }
2714 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002715 lastarg = argc;
Guido van Rossuma1065681999-01-25 23:20:23 +00002716 argvlist[argc] = NULL;
2717
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002718 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002719 if (i < 0)
2720 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00002721 envlist = PyMem_NEW(char *, i + 1);
2722 if (envlist == NULL) {
2723 PyErr_NoMemory();
2724 goto fail_1;
2725 }
2726 envc = 0;
2727 keys = PyMapping_Keys(env);
2728 vals = PyMapping_Values(env);
2729 if (!keys || !vals)
2730 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002731 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2732 PyErr_SetString(PyExc_TypeError,
2733 "spawnve(): env.keys() or env.values() is not a list");
2734 goto fail_2;
2735 }
Tim Peters5aa91602002-01-30 05:46:57 +00002736
Guido van Rossuma1065681999-01-25 23:20:23 +00002737 for (pos = 0; pos < i; pos++) {
2738 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002739 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00002740
2741 key = PyList_GetItem(keys, pos);
2742 val = PyList_GetItem(vals, pos);
2743 if (!key || !val)
2744 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002745
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002746 if (!PyArg_Parse(
2747 key,
2748 "s;spawnve() arg 3 contains a non-string key",
2749 &k) ||
2750 !PyArg_Parse(
2751 val,
2752 "s;spawnve() arg 3 contains a non-string value",
2753 &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00002754 {
2755 goto fail_2;
2756 }
Tim Petersc8996f52001-12-03 20:41:00 +00002757 len = PyString_Size(key) + PyString_Size(val) + 2;
2758 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00002759 if (p == NULL) {
2760 PyErr_NoMemory();
2761 goto fail_2;
2762 }
Tim Petersc8996f52001-12-03 20:41:00 +00002763 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00002764 envlist[envc++] = p;
2765 }
2766 envlist[envc] = 0;
2767
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002768#if defined(PYOS_OS2) && defined(PYCC_GCC)
2769 Py_BEGIN_ALLOW_THREADS
2770 spawnval = spawnve(mode, path, argvlist, envlist);
2771 Py_END_ALLOW_THREADS
2772#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002773 if (mode == _OLD_P_OVERLAY)
2774 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00002775
2776 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002777 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00002778 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002779#endif
Tim Peters25059d32001-12-07 20:35:43 +00002780
Fred Drake699f3522000-06-29 21:12:41 +00002781 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002782 (void) posix_error();
2783 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002784#if SIZEOF_LONG == SIZEOF_VOID_P
2785 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002786#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00002787 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002788#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002789
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002790 fail_2:
Guido van Rossuma1065681999-01-25 23:20:23 +00002791 while (--envc >= 0)
2792 PyMem_DEL(envlist[envc]);
2793 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002794 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002795 free_string_array(argvlist, lastarg);
Guido van Rossuma1065681999-01-25 23:20:23 +00002796 Py_XDECREF(vals);
2797 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002798 fail_0:
2799 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002800 return res;
2801}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00002802
2803/* OS/2 supports spawnvp & spawnvpe natively */
2804#if defined(PYOS_OS2)
2805PyDoc_STRVAR(posix_spawnvp__doc__,
2806"spawnvp(mode, file, args)\n\n\
2807Execute the program 'file' in a new process, using the environment\n\
2808search path to find the file.\n\
2809\n\
2810 mode: mode of process creation\n\
2811 file: executable file name\n\
2812 args: tuple or list of strings");
2813
2814static PyObject *
2815posix_spawnvp(PyObject *self, PyObject *args)
2816{
2817 char *path;
2818 PyObject *argv;
2819 char **argvlist;
2820 int mode, i, argc;
2821 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002822 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00002823
2824 /* spawnvp has three arguments: (mode, path, argv), where
2825 argv is a list or tuple of strings. */
2826
2827 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
2828 Py_FileSystemDefaultEncoding,
2829 &path, &argv))
2830 return NULL;
2831 if (PyList_Check(argv)) {
2832 argc = PyList_Size(argv);
2833 getitem = PyList_GetItem;
2834 }
2835 else if (PyTuple_Check(argv)) {
2836 argc = PyTuple_Size(argv);
2837 getitem = PyTuple_GetItem;
2838 }
2839 else {
2840 PyErr_SetString(PyExc_TypeError,
2841 "spawnvp() arg 2 must be a tuple or list");
2842 PyMem_Free(path);
2843 return NULL;
2844 }
2845
2846 argvlist = PyMem_NEW(char *, argc+1);
2847 if (argvlist == NULL) {
2848 PyMem_Free(path);
2849 return PyErr_NoMemory();
2850 }
2851 for (i = 0; i < argc; i++) {
2852 if (!PyArg_Parse((*getitem)(argv, i), "et",
2853 Py_FileSystemDefaultEncoding,
2854 &argvlist[i])) {
2855 free_string_array(argvlist, i);
2856 PyErr_SetString(
2857 PyExc_TypeError,
2858 "spawnvp() arg 2 must contain only strings");
2859 PyMem_Free(path);
2860 return NULL;
2861 }
2862 }
2863 argvlist[argc] = NULL;
2864
2865 Py_BEGIN_ALLOW_THREADS
2866#if defined(PYCC_GCC)
2867 spawnval = spawnvp(mode, path, argvlist);
2868#else
2869 spawnval = _spawnvp(mode, path, argvlist);
2870#endif
2871 Py_END_ALLOW_THREADS
2872
2873 free_string_array(argvlist, argc);
2874 PyMem_Free(path);
2875
2876 if (spawnval == -1)
2877 return posix_error();
2878 else
2879 return Py_BuildValue("l", (long) spawnval);
2880}
2881
2882
2883PyDoc_STRVAR(posix_spawnvpe__doc__,
2884"spawnvpe(mode, file, args, env)\n\n\
2885Execute the program 'file' in a new process, using the environment\n\
2886search path to find the file.\n\
2887\n\
2888 mode: mode of process creation\n\
2889 file: executable file name\n\
2890 args: tuple or list of arguments\n\
2891 env: dictionary of strings mapping to strings");
2892
2893static PyObject *
2894posix_spawnvpe(PyObject *self, PyObject *args)
2895{
2896 char *path;
2897 PyObject *argv, *env;
2898 char **argvlist;
2899 char **envlist;
2900 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
2901 int mode, i, pos, argc, envc;
2902 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002903 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00002904 int lastarg = 0;
2905
2906 /* spawnvpe has four arguments: (mode, path, argv, env), where
2907 argv is a list or tuple of strings and env is a dictionary
2908 like posix.environ. */
2909
2910 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
2911 Py_FileSystemDefaultEncoding,
2912 &path, &argv, &env))
2913 return NULL;
2914 if (PyList_Check(argv)) {
2915 argc = PyList_Size(argv);
2916 getitem = PyList_GetItem;
2917 }
2918 else if (PyTuple_Check(argv)) {
2919 argc = PyTuple_Size(argv);
2920 getitem = PyTuple_GetItem;
2921 }
2922 else {
2923 PyErr_SetString(PyExc_TypeError,
2924 "spawnvpe() arg 2 must be a tuple or list");
2925 goto fail_0;
2926 }
2927 if (!PyMapping_Check(env)) {
2928 PyErr_SetString(PyExc_TypeError,
2929 "spawnvpe() arg 3 must be a mapping object");
2930 goto fail_0;
2931 }
2932
2933 argvlist = PyMem_NEW(char *, argc+1);
2934 if (argvlist == NULL) {
2935 PyErr_NoMemory();
2936 goto fail_0;
2937 }
2938 for (i = 0; i < argc; i++) {
2939 if (!PyArg_Parse((*getitem)(argv, i),
2940 "et;spawnvpe() arg 2 must contain only strings",
2941 Py_FileSystemDefaultEncoding,
2942 &argvlist[i]))
2943 {
2944 lastarg = i;
2945 goto fail_1;
2946 }
2947 }
2948 lastarg = argc;
2949 argvlist[argc] = NULL;
2950
2951 i = PyMapping_Size(env);
2952 if (i < 0)
2953 goto fail_1;
2954 envlist = PyMem_NEW(char *, i + 1);
2955 if (envlist == NULL) {
2956 PyErr_NoMemory();
2957 goto fail_1;
2958 }
2959 envc = 0;
2960 keys = PyMapping_Keys(env);
2961 vals = PyMapping_Values(env);
2962 if (!keys || !vals)
2963 goto fail_2;
2964 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2965 PyErr_SetString(PyExc_TypeError,
2966 "spawnvpe(): env.keys() or env.values() is not a list");
2967 goto fail_2;
2968 }
2969
2970 for (pos = 0; pos < i; pos++) {
2971 char *p, *k, *v;
2972 size_t len;
2973
2974 key = PyList_GetItem(keys, pos);
2975 val = PyList_GetItem(vals, pos);
2976 if (!key || !val)
2977 goto fail_2;
2978
2979 if (!PyArg_Parse(
2980 key,
2981 "s;spawnvpe() arg 3 contains a non-string key",
2982 &k) ||
2983 !PyArg_Parse(
2984 val,
2985 "s;spawnvpe() arg 3 contains a non-string value",
2986 &v))
2987 {
2988 goto fail_2;
2989 }
2990 len = PyString_Size(key) + PyString_Size(val) + 2;
2991 p = PyMem_NEW(char, len);
2992 if (p == NULL) {
2993 PyErr_NoMemory();
2994 goto fail_2;
2995 }
2996 PyOS_snprintf(p, len, "%s=%s", k, v);
2997 envlist[envc++] = p;
2998 }
2999 envlist[envc] = 0;
3000
3001 Py_BEGIN_ALLOW_THREADS
3002#if defined(PYCC_GCC)
3003 spawnval = spawnve(mode, path, argvlist, envlist);
3004#else
3005 spawnval = _spawnve(mode, path, argvlist, envlist);
3006#endif
3007 Py_END_ALLOW_THREADS
3008
3009 if (spawnval == -1)
3010 (void) posix_error();
3011 else
3012 res = Py_BuildValue("l", (long) spawnval);
3013
3014 fail_2:
3015 while (--envc >= 0)
3016 PyMem_DEL(envlist[envc]);
3017 PyMem_DEL(envlist);
3018 fail_1:
3019 free_string_array(argvlist, lastarg);
3020 Py_XDECREF(vals);
3021 Py_XDECREF(keys);
3022 fail_0:
3023 PyMem_Free(path);
3024 return res;
3025}
3026#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003027#endif /* HAVE_SPAWNV */
3028
3029
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003030#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003031PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003032"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003033Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3034\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003035Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003036
3037static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003038posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003039{
Neal Norwitze241ce82003-02-17 18:17:05 +00003040 int pid = fork1();
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003041 if (pid == -1)
3042 return posix_error();
3043 PyOS_AfterFork();
3044 return PyInt_FromLong((long)pid);
3045}
3046#endif
3047
3048
Guido van Rossumad0ee831995-03-01 10:34:45 +00003049#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003050PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003051"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003052Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003053Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003054
Barry Warsaw53699e91996-12-10 23:23:01 +00003055static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003056posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003057{
Neal Norwitze241ce82003-02-17 18:17:05 +00003058 int pid = fork();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003059 if (pid == -1)
3060 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003061 if (pid == 0)
3062 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00003063 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003064}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003065#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003066
Neal Norwitzb59798b2003-03-21 01:43:31 +00003067/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00003068/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3069#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00003070#define DEV_PTY_FILE "/dev/ptc"
3071#define HAVE_DEV_PTMX
3072#else
3073#define DEV_PTY_FILE "/dev/ptmx"
3074#endif
3075
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003076#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003077#ifdef HAVE_PTY_H
3078#include <pty.h>
3079#else
3080#ifdef HAVE_LIBUTIL_H
3081#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00003082#endif /* HAVE_LIBUTIL_H */
3083#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00003084#ifdef HAVE_STROPTS_H
3085#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003086#endif
3087#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003088
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003089#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003090PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003091"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003092Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003093
3094static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003095posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003096{
3097 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003098#ifndef HAVE_OPENPTY
3099 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003100#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003101#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003102 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003103#ifdef sun
Neal Norwitz84a98e02006-04-10 07:44:23 +00003104 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003105#endif
3106#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00003107
Thomas Wouters70c21a12000-07-14 14:28:33 +00003108#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00003109 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
3110 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003111#elif defined(HAVE__GETPTY)
Thomas Wouters70c21a12000-07-14 14:28:33 +00003112 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
3113 if (slave_name == NULL)
3114 return posix_error();
3115
3116 slave_fd = open(slave_name, O_RDWR);
3117 if (slave_fd < 0)
3118 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003119#else
Neal Norwitzb59798b2003-03-21 01:43:31 +00003120 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003121 if (master_fd < 0)
3122 return posix_error();
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003123 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003124 /* change permission of slave */
3125 if (grantpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003126 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003127 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003128 }
3129 /* unlock slave */
3130 if (unlockpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003131 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003132 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003133 }
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003134 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003135 slave_name = ptsname(master_fd); /* get name of slave */
3136 if (slave_name == NULL)
3137 return posix_error();
3138 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
3139 if (slave_fd < 0)
3140 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003141#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003142 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
3143 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00003144#ifndef __hpux
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003145 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00003146#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003147#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00003148#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00003149
Fred Drake8cef4cf2000-06-28 16:40:38 +00003150 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00003151
Fred Drake8cef4cf2000-06-28 16:40:38 +00003152}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003153#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003154
3155#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003156PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003157"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00003158Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
3159Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003160To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003161
3162static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003163posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003164{
Neal Norwitz24b3c222005-09-19 06:43:44 +00003165 int master_fd = -1, pid;
Tim Peters5aa91602002-01-30 05:46:57 +00003166
Fred Drake8cef4cf2000-06-28 16:40:38 +00003167 pid = forkpty(&master_fd, NULL, NULL, NULL);
3168 if (pid == -1)
3169 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003170 if (pid == 0)
3171 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00003172 return Py_BuildValue("(ii)", pid, master_fd);
3173}
3174#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003175
Guido van Rossumad0ee831995-03-01 10:34:45 +00003176#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003177PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003178"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003179Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003180
Barry Warsaw53699e91996-12-10 23:23:01 +00003181static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003182posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003183{
Barry Warsaw53699e91996-12-10 23:23:01 +00003184 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003185}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003186#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003187
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003188
Guido van Rossumad0ee831995-03-01 10:34:45 +00003189#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003190PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003191"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003192Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003193
Barry Warsaw53699e91996-12-10 23:23:01 +00003194static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003195posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003196{
Barry Warsaw53699e91996-12-10 23:23:01 +00003197 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003198}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003199#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003200
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003201
Guido van Rossumad0ee831995-03-01 10:34:45 +00003202#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003203PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003204"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003205Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003206
Barry Warsaw53699e91996-12-10 23:23:01 +00003207static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003208posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003209{
Barry Warsaw53699e91996-12-10 23:23:01 +00003210 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003211}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003212#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003213
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003214
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003215PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003216"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003217Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003218
Barry Warsaw53699e91996-12-10 23:23:01 +00003219static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003220posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003221{
Barry Warsaw53699e91996-12-10 23:23:01 +00003222 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003223}
3224
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003225
Fred Drakec9680921999-12-13 16:37:25 +00003226#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003227PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003228"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003229Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00003230
3231static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003232posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00003233{
3234 PyObject *result = NULL;
3235
Fred Drakec9680921999-12-13 16:37:25 +00003236#ifdef NGROUPS_MAX
3237#define MAX_GROUPS NGROUPS_MAX
3238#else
3239 /* defined to be 16 on Solaris7, so this should be a small number */
3240#define MAX_GROUPS 64
3241#endif
3242 gid_t grouplist[MAX_GROUPS];
3243 int n;
3244
3245 n = getgroups(MAX_GROUPS, grouplist);
3246 if (n < 0)
3247 posix_error();
3248 else {
3249 result = PyList_New(n);
3250 if (result != NULL) {
Fred Drakec9680921999-12-13 16:37:25 +00003251 int i;
3252 for (i = 0; i < n; ++i) {
Neal Norwitze241ce82003-02-17 18:17:05 +00003253 PyObject *o = PyInt_FromLong((long)grouplist[i]);
Fred Drakec9680921999-12-13 16:37:25 +00003254 if (o == NULL) {
3255 Py_DECREF(result);
3256 result = NULL;
3257 break;
3258 }
3259 PyList_SET_ITEM(result, i, o);
3260 }
3261 }
3262 }
Neal Norwitze241ce82003-02-17 18:17:05 +00003263
Fred Drakec9680921999-12-13 16:37:25 +00003264 return result;
3265}
3266#endif
3267
Martin v. Löwis606edc12002-06-13 21:09:11 +00003268#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003269PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003270"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003271Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00003272
3273static PyObject *
3274posix_getpgid(PyObject *self, PyObject *args)
3275{
3276 int pid, pgid;
3277 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
3278 return NULL;
3279 pgid = getpgid(pid);
3280 if (pgid < 0)
3281 return posix_error();
3282 return PyInt_FromLong((long)pgid);
3283}
3284#endif /* HAVE_GETPGID */
3285
3286
Guido van Rossumb6775db1994-08-01 11:34:53 +00003287#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003288PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003289"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003290Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003291
Barry Warsaw53699e91996-12-10 23:23:01 +00003292static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003293posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00003294{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003295#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00003296 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003297#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00003298 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003299#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00003300}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003301#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00003302
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003303
Guido van Rossumb6775db1994-08-01 11:34:53 +00003304#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003305PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003306"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003307Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003308
Barry Warsaw53699e91996-12-10 23:23:01 +00003309static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003310posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003311{
Guido van Rossum64933891994-10-20 21:56:42 +00003312#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00003313 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003314#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003315 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003316#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00003317 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003318 Py_INCREF(Py_None);
3319 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003320}
3321
Guido van Rossumb6775db1994-08-01 11:34:53 +00003322#endif /* HAVE_SETPGRP */
3323
Guido van Rossumad0ee831995-03-01 10:34:45 +00003324#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003325PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003326"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003327Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003328
Barry Warsaw53699e91996-12-10 23:23:01 +00003329static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003330posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003331{
Barry Warsaw53699e91996-12-10 23:23:01 +00003332 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003333}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003334#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003335
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003336
Fred Drake12c6e2d1999-12-14 21:25:03 +00003337#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003338PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003339"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003340Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00003341
3342static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003343posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00003344{
Neal Norwitze241ce82003-02-17 18:17:05 +00003345 PyObject *result = NULL;
Fred Drakea30680b2000-12-06 21:24:28 +00003346 char *name;
3347 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00003348
Fred Drakea30680b2000-12-06 21:24:28 +00003349 errno = 0;
3350 name = getlogin();
3351 if (name == NULL) {
3352 if (errno)
3353 posix_error();
3354 else
3355 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00003356 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00003357 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00003358 else
3359 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00003360 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00003361
Fred Drake12c6e2d1999-12-14 21:25:03 +00003362 return result;
3363}
3364#endif
3365
Guido van Rossumad0ee831995-03-01 10:34:45 +00003366#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003367PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003368"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003369Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003370
Barry Warsaw53699e91996-12-10 23:23:01 +00003371static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003372posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003373{
Barry Warsaw53699e91996-12-10 23:23:01 +00003374 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003375}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003376#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003377
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003378
Guido van Rossumad0ee831995-03-01 10:34:45 +00003379#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003380PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003381"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003382Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003383
Barry Warsaw53699e91996-12-10 23:23:01 +00003384static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003385posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003386{
3387 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003388 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00003389 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003390#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003391 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
3392 APIRET rc;
3393 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003394 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003395
3396 } else if (sig == XCPT_SIGNAL_KILLPROC) {
3397 APIRET rc;
3398 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003399 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003400
3401 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003402 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003403#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00003404 if (kill(pid, sig) == -1)
3405 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003406#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003407 Py_INCREF(Py_None);
3408 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003409}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003410#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003411
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003412#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003413PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003414"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003415Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003416
3417static PyObject *
3418posix_killpg(PyObject *self, PyObject *args)
3419{
3420 int pgid, sig;
3421 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
3422 return NULL;
3423 if (killpg(pgid, sig) == -1)
3424 return posix_error();
3425 Py_INCREF(Py_None);
3426 return Py_None;
3427}
3428#endif
3429
Guido van Rossumc0125471996-06-28 18:55:32 +00003430#ifdef HAVE_PLOCK
3431
3432#ifdef HAVE_SYS_LOCK_H
3433#include <sys/lock.h>
3434#endif
3435
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003436PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003437"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003438Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003439
Barry Warsaw53699e91996-12-10 23:23:01 +00003440static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003441posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00003442{
3443 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003444 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00003445 return NULL;
3446 if (plock(op) == -1)
3447 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003448 Py_INCREF(Py_None);
3449 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00003450}
3451#endif
3452
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003453
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003454#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003455PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003456"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003457Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003458
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003459#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003460#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003461static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003462async_system(const char *command)
3463{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003464 char errormsg[256], args[1024];
3465 RESULTCODES rcodes;
3466 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003467
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003468 char *shell = getenv("COMSPEC");
3469 if (!shell)
3470 shell = "cmd";
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003471
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003472 /* avoid overflowing the argument buffer */
3473 if (strlen(shell) + 3 + strlen(command) >= 1024)
3474 return ERROR_NOT_ENOUGH_MEMORY
3475
3476 args[0] = '\0';
3477 strcat(args, shell);
3478 strcat(args, "/c ");
3479 strcat(args, command);
3480
3481 /* execute asynchronously, inheriting the environment */
3482 rc = DosExecPgm(errormsg,
3483 sizeof(errormsg),
3484 EXEC_ASYNC,
3485 args,
3486 NULL,
3487 &rcodes,
3488 shell);
3489 return rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003490}
3491
Guido van Rossumd48f2521997-12-05 22:19:34 +00003492static FILE *
3493popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003494{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003495 int oldfd, tgtfd;
3496 HFILE pipeh[2];
3497 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003498
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003499 /* mode determines which of stdin or stdout is reconnected to
3500 * the pipe to the child
3501 */
3502 if (strchr(mode, 'r') != NULL) {
3503 tgt_fd = 1; /* stdout */
3504 } else if (strchr(mode, 'w')) {
3505 tgt_fd = 0; /* stdin */
3506 } else {
3507 *err = ERROR_INVALID_ACCESS;
3508 return NULL;
3509 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003510
Andrew MacIntyrea3be2582004-12-18 09:51:05 +00003511 /* setup the pipe */
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003512 if ((rc = DosCreatePipe(&pipeh[0], &pipeh[1], pipesize)) != NO_ERROR) {
3513 *err = rc;
3514 return NULL;
3515 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003516
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003517 /* prevent other threads accessing stdio */
3518 DosEnterCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003519
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003520 /* reconnect stdio and execute child */
3521 oldfd = dup(tgtfd);
3522 close(tgtfd);
3523 if (dup2(pipeh[tgtfd], tgtfd) == 0) {
3524 DosClose(pipeh[tgtfd]);
3525 rc = async_system(command);
3526 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003527
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003528 /* restore stdio */
3529 dup2(oldfd, tgtfd);
3530 close(oldfd);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003531
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003532 /* allow other threads access to stdio */
3533 DosExitCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003534
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003535 /* if execution of child was successful return file stream */
3536 if (rc == NO_ERROR)
3537 return fdopen(pipeh[1 - tgtfd], mode);
3538 else {
3539 DosClose(pipeh[1 - tgtfd]);
3540 *err = rc;
3541 return NULL;
3542 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003543}
3544
3545static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003546posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003547{
3548 char *name;
3549 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00003550 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003551 FILE *fp;
3552 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003553 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003554 return NULL;
3555 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00003556 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003557 Py_END_ALLOW_THREADS
3558 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003559 return os2_error(err);
3560
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003561 f = PyFile_FromFile(fp, name, mode, fclose);
3562 if (f != NULL)
3563 PyFile_SetBufSize(f, bufsize);
3564 return f;
3565}
3566
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003567#elif defined(PYCC_GCC)
3568
3569/* standard posix version of popen() support */
3570static PyObject *
3571posix_popen(PyObject *self, PyObject *args)
3572{
3573 char *name;
3574 char *mode = "r";
3575 int bufsize = -1;
3576 FILE *fp;
3577 PyObject *f;
3578 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
3579 return NULL;
3580 Py_BEGIN_ALLOW_THREADS
3581 fp = popen(name, mode);
3582 Py_END_ALLOW_THREADS
3583 if (fp == NULL)
3584 return posix_error();
3585 f = PyFile_FromFile(fp, name, mode, pclose);
3586 if (f != NULL)
3587 PyFile_SetBufSize(f, bufsize);
3588 return f;
3589}
3590
3591/* fork() under OS/2 has lots'o'warts
3592 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
3593 * most of this code is a ripoff of the win32 code, but using the
3594 * capabilities of EMX's C library routines
3595 */
3596
3597/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
3598#define POPEN_1 1
3599#define POPEN_2 2
3600#define POPEN_3 3
3601#define POPEN_4 4
3602
3603static PyObject *_PyPopen(char *, int, int, int);
3604static int _PyPclose(FILE *file);
3605
3606/*
3607 * Internal dictionary mapping popen* file pointers to process handles,
3608 * for use when retrieving the process exit code. See _PyPclose() below
3609 * for more information on this dictionary's use.
3610 */
3611static PyObject *_PyPopenProcs = NULL;
3612
3613/* os2emx version of popen2()
3614 *
3615 * The result of this function is a pipe (file) connected to the
3616 * process's stdin, and a pipe connected to the process's stdout.
3617 */
3618
3619static PyObject *
3620os2emx_popen2(PyObject *self, PyObject *args)
3621{
3622 PyObject *f;
3623 int tm=0;
3624
3625 char *cmdstring;
3626 char *mode = "t";
3627 int bufsize = -1;
3628 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
3629 return NULL;
3630
3631 if (*mode == 't')
3632 tm = O_TEXT;
3633 else if (*mode != 'b') {
3634 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3635 return NULL;
3636 } else
3637 tm = O_BINARY;
3638
3639 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
3640
3641 return f;
3642}
3643
3644/*
3645 * Variation on os2emx.popen2
3646 *
3647 * The result of this function is 3 pipes - the process's stdin,
3648 * stdout and stderr
3649 */
3650
3651static PyObject *
3652os2emx_popen3(PyObject *self, PyObject *args)
3653{
3654 PyObject *f;
3655 int tm = 0;
3656
3657 char *cmdstring;
3658 char *mode = "t";
3659 int bufsize = -1;
3660 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
3661 return NULL;
3662
3663 if (*mode == 't')
3664 tm = O_TEXT;
3665 else if (*mode != 'b') {
3666 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3667 return NULL;
3668 } else
3669 tm = O_BINARY;
3670
3671 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
3672
3673 return f;
3674}
3675
3676/*
3677 * Variation on os2emx.popen2
3678 *
Tim Peters11b23062003-04-23 02:39:17 +00003679 * The result of this function is 2 pipes - the processes stdin,
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003680 * and stdout+stderr combined as a single pipe.
3681 */
3682
3683static PyObject *
3684os2emx_popen4(PyObject *self, PyObject *args)
3685{
3686 PyObject *f;
3687 int tm = 0;
3688
3689 char *cmdstring;
3690 char *mode = "t";
3691 int bufsize = -1;
3692 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
3693 return NULL;
3694
3695 if (*mode == 't')
3696 tm = O_TEXT;
3697 else if (*mode != 'b') {
3698 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3699 return NULL;
3700 } else
3701 tm = O_BINARY;
3702
3703 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
3704
3705 return f;
3706}
3707
3708/* a couple of structures for convenient handling of multiple
3709 * file handles and pipes
3710 */
3711struct file_ref
3712{
3713 int handle;
3714 int flags;
3715};
3716
3717struct pipe_ref
3718{
3719 int rd;
3720 int wr;
3721};
3722
3723/* The following code is derived from the win32 code */
3724
3725static PyObject *
3726_PyPopen(char *cmdstring, int mode, int n, int bufsize)
3727{
3728 struct file_ref stdio[3];
3729 struct pipe_ref p_fd[3];
3730 FILE *p_s[3];
3731 int file_count, i, pipe_err, pipe_pid;
3732 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
3733 PyObject *f, *p_f[3];
3734
3735 /* file modes for subsequent fdopen's on pipe handles */
3736 if (mode == O_TEXT)
3737 {
3738 rd_mode = "rt";
3739 wr_mode = "wt";
3740 }
3741 else
3742 {
3743 rd_mode = "rb";
3744 wr_mode = "wb";
3745 }
3746
3747 /* prepare shell references */
3748 if ((shell = getenv("EMXSHELL")) == NULL)
3749 if ((shell = getenv("COMSPEC")) == NULL)
3750 {
3751 errno = ENOENT;
3752 return posix_error();
3753 }
3754
3755 sh_name = _getname(shell);
3756 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
3757 opt = "/c";
3758 else
3759 opt = "-c";
3760
3761 /* save current stdio fds + their flags, and set not inheritable */
3762 i = pipe_err = 0;
3763 while (pipe_err >= 0 && i < 3)
3764 {
3765 pipe_err = stdio[i].handle = dup(i);
3766 stdio[i].flags = fcntl(i, F_GETFD, 0);
3767 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
3768 i++;
3769 }
3770 if (pipe_err < 0)
3771 {
3772 /* didn't get them all saved - clean up and bail out */
3773 int saved_err = errno;
3774 while (i-- > 0)
3775 {
3776 close(stdio[i].handle);
3777 }
3778 errno = saved_err;
3779 return posix_error();
3780 }
3781
3782 /* create pipe ends */
3783 file_count = 2;
3784 if (n == POPEN_3)
3785 file_count = 3;
3786 i = pipe_err = 0;
3787 while ((pipe_err == 0) && (i < file_count))
3788 pipe_err = pipe((int *)&p_fd[i++]);
3789 if (pipe_err < 0)
3790 {
3791 /* didn't get them all made - clean up and bail out */
3792 while (i-- > 0)
3793 {
3794 close(p_fd[i].wr);
3795 close(p_fd[i].rd);
3796 }
3797 errno = EPIPE;
3798 return posix_error();
3799 }
3800
3801 /* change the actual standard IO streams over temporarily,
3802 * making the retained pipe ends non-inheritable
3803 */
3804 pipe_err = 0;
3805
3806 /* - stdin */
3807 if (dup2(p_fd[0].rd, 0) == 0)
3808 {
3809 close(p_fd[0].rd);
3810 i = fcntl(p_fd[0].wr, F_GETFD, 0);
3811 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
3812 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
3813 {
3814 close(p_fd[0].wr);
3815 pipe_err = -1;
3816 }
3817 }
3818 else
3819 {
3820 pipe_err = -1;
3821 }
3822
3823 /* - stdout */
3824 if (pipe_err == 0)
3825 {
3826 if (dup2(p_fd[1].wr, 1) == 1)
3827 {
3828 close(p_fd[1].wr);
3829 i = fcntl(p_fd[1].rd, F_GETFD, 0);
3830 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
3831 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
3832 {
3833 close(p_fd[1].rd);
3834 pipe_err = -1;
3835 }
3836 }
3837 else
3838 {
3839 pipe_err = -1;
3840 }
3841 }
3842
3843 /* - stderr, as required */
3844 if (pipe_err == 0)
3845 switch (n)
3846 {
3847 case POPEN_3:
3848 {
3849 if (dup2(p_fd[2].wr, 2) == 2)
3850 {
3851 close(p_fd[2].wr);
3852 i = fcntl(p_fd[2].rd, F_GETFD, 0);
3853 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
3854 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
3855 {
3856 close(p_fd[2].rd);
3857 pipe_err = -1;
3858 }
3859 }
3860 else
3861 {
3862 pipe_err = -1;
3863 }
3864 break;
3865 }
3866
3867 case POPEN_4:
3868 {
3869 if (dup2(1, 2) != 2)
3870 {
3871 pipe_err = -1;
3872 }
3873 break;
3874 }
3875 }
3876
3877 /* spawn the child process */
3878 if (pipe_err == 0)
3879 {
3880 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
3881 if (pipe_pid == -1)
3882 {
3883 pipe_err = -1;
3884 }
3885 else
3886 {
3887 /* save the PID into the FILE structure
3888 * NOTE: this implementation doesn't actually
3889 * take advantage of this, but do it for
3890 * completeness - AIM Apr01
3891 */
3892 for (i = 0; i < file_count; i++)
3893 p_s[i]->_pid = pipe_pid;
3894 }
3895 }
3896
3897 /* reset standard IO to normal */
3898 for (i = 0; i < 3; i++)
3899 {
3900 dup2(stdio[i].handle, i);
3901 fcntl(i, F_SETFD, stdio[i].flags);
3902 close(stdio[i].handle);
3903 }
3904
3905 /* if any remnant problems, clean up and bail out */
3906 if (pipe_err < 0)
3907 {
3908 for (i = 0; i < 3; i++)
3909 {
3910 close(p_fd[i].rd);
3911 close(p_fd[i].wr);
3912 }
3913 errno = EPIPE;
3914 return posix_error_with_filename(cmdstring);
3915 }
3916
3917 /* build tuple of file objects to return */
3918 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
3919 PyFile_SetBufSize(p_f[0], bufsize);
3920 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
3921 PyFile_SetBufSize(p_f[1], bufsize);
3922 if (n == POPEN_3)
3923 {
3924 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
3925 PyFile_SetBufSize(p_f[0], bufsize);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00003926 f = PyTuple_Pack(3, p_f[0], p_f[1], p_f[2]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003927 }
3928 else
Raymond Hettinger8ae46892003-10-12 19:09:37 +00003929 f = PyTuple_Pack(2, p_f[0], p_f[1]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003930
3931 /*
3932 * Insert the files we've created into the process dictionary
3933 * all referencing the list with the process handle and the
3934 * initial number of files (see description below in _PyPclose).
3935 * Since if _PyPclose later tried to wait on a process when all
3936 * handles weren't closed, it could create a deadlock with the
3937 * child, we spend some energy here to try to ensure that we
3938 * either insert all file handles into the dictionary or none
3939 * at all. It's a little clumsy with the various popen modes
3940 * and variable number of files involved.
3941 */
3942 if (!_PyPopenProcs)
3943 {
3944 _PyPopenProcs = PyDict_New();
3945 }
3946
3947 if (_PyPopenProcs)
3948 {
3949 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
3950 int ins_rc[3];
3951
3952 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
3953 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
3954
3955 procObj = PyList_New(2);
3956 pidObj = PyInt_FromLong((long) pipe_pid);
3957 intObj = PyInt_FromLong((long) file_count);
3958
3959 if (procObj && pidObj && intObj)
3960 {
3961 PyList_SetItem(procObj, 0, pidObj);
3962 PyList_SetItem(procObj, 1, intObj);
3963
3964 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
3965 if (fileObj[0])
3966 {
3967 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
3968 fileObj[0],
3969 procObj);
3970 }
3971 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
3972 if (fileObj[1])
3973 {
3974 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
3975 fileObj[1],
3976 procObj);
3977 }
3978 if (file_count >= 3)
3979 {
3980 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
3981 if (fileObj[2])
3982 {
3983 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
3984 fileObj[2],
3985 procObj);
3986 }
3987 }
3988
3989 if (ins_rc[0] < 0 || !fileObj[0] ||
3990 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
3991 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
3992 {
3993 /* Something failed - remove any dictionary
3994 * entries that did make it.
3995 */
3996 if (!ins_rc[0] && fileObj[0])
3997 {
3998 PyDict_DelItem(_PyPopenProcs,
3999 fileObj[0]);
4000 }
4001 if (!ins_rc[1] && fileObj[1])
4002 {
4003 PyDict_DelItem(_PyPopenProcs,
4004 fileObj[1]);
4005 }
4006 if (!ins_rc[2] && fileObj[2])
4007 {
4008 PyDict_DelItem(_PyPopenProcs,
4009 fileObj[2]);
4010 }
4011 }
4012 }
Tim Peters11b23062003-04-23 02:39:17 +00004013
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004014 /*
4015 * Clean up our localized references for the dictionary keys
4016 * and value since PyDict_SetItem will Py_INCREF any copies
4017 * that got placed in the dictionary.
4018 */
4019 Py_XDECREF(procObj);
4020 Py_XDECREF(fileObj[0]);
4021 Py_XDECREF(fileObj[1]);
4022 Py_XDECREF(fileObj[2]);
4023 }
4024
4025 /* Child is launched. */
4026 return f;
4027}
4028
4029/*
4030 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4031 * exit code for the child process and return as a result of the close.
4032 *
4033 * This function uses the _PyPopenProcs dictionary in order to map the
4034 * input file pointer to information about the process that was
4035 * originally created by the popen* call that created the file pointer.
4036 * The dictionary uses the file pointer as a key (with one entry
4037 * inserted for each file returned by the original popen* call) and a
4038 * single list object as the value for all files from a single call.
4039 * The list object contains the Win32 process handle at [0], and a file
4040 * count at [1], which is initialized to the total number of file
4041 * handles using that list.
4042 *
4043 * This function closes whichever handle it is passed, and decrements
4044 * the file count in the dictionary for the process handle pointed to
4045 * by this file. On the last close (when the file count reaches zero),
4046 * this function will wait for the child process and then return its
4047 * exit code as the result of the close() operation. This permits the
4048 * files to be closed in any order - it is always the close() of the
4049 * final handle that will return the exit code.
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004050 *
4051 * NOTE: This function is currently called with the GIL released.
4052 * hence we use the GILState API to manage our state.
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004053 */
4054
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004055static int _PyPclose(FILE *file)
4056{
4057 int result;
4058 int exit_code;
4059 int pipe_pid;
4060 PyObject *procObj, *pidObj, *intObj, *fileObj;
4061 int file_count;
4062#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004063 PyGILState_STATE state;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004064#endif
4065
4066 /* Close the file handle first, to ensure it can't block the
4067 * child from exiting if it's the last handle.
4068 */
4069 result = fclose(file);
4070
4071#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004072 state = PyGILState_Ensure();
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004073#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004074 if (_PyPopenProcs)
4075 {
4076 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4077 (procObj = PyDict_GetItem(_PyPopenProcs,
4078 fileObj)) != NULL &&
4079 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
4080 (intObj = PyList_GetItem(procObj,1)) != NULL)
4081 {
4082 pipe_pid = (int) PyInt_AsLong(pidObj);
4083 file_count = (int) PyInt_AsLong(intObj);
4084
4085 if (file_count > 1)
4086 {
4087 /* Still other files referencing process */
4088 file_count--;
4089 PyList_SetItem(procObj,1,
4090 PyInt_FromLong((long) file_count));
4091 }
4092 else
4093 {
4094 /* Last file for this process */
4095 if (result != EOF &&
4096 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
4097 {
4098 /* extract exit status */
4099 if (WIFEXITED(exit_code))
4100 {
4101 result = WEXITSTATUS(exit_code);
4102 }
4103 else
4104 {
4105 errno = EPIPE;
4106 result = -1;
4107 }
4108 }
4109 else
4110 {
4111 /* Indicate failure - this will cause the file object
4112 * to raise an I/O error and translate the last
4113 * error code from errno. We do have a problem with
4114 * last errors that overlap the normal errno table,
4115 * but that's a consistent problem with the file object.
4116 */
4117 result = -1;
4118 }
4119 }
4120
4121 /* Remove this file pointer from dictionary */
4122 PyDict_DelItem(_PyPopenProcs, fileObj);
4123
4124 if (PyDict_Size(_PyPopenProcs) == 0)
4125 {
4126 Py_DECREF(_PyPopenProcs);
4127 _PyPopenProcs = NULL;
4128 }
4129
4130 } /* if object retrieval ok */
4131
4132 Py_XDECREF(fileObj);
4133 } /* if _PyPopenProcs */
4134
4135#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004136 PyGILState_Release(state);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004137#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004138 return result;
4139}
4140
4141#endif /* PYCC_??? */
4142
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004143#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004144
4145/*
4146 * Portable 'popen' replacement for Win32.
4147 *
4148 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
4149 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00004150 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004151 */
4152
4153#include <malloc.h>
4154#include <io.h>
4155#include <fcntl.h>
4156
4157/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
4158#define POPEN_1 1
4159#define POPEN_2 2
4160#define POPEN_3 3
4161#define POPEN_4 4
4162
4163static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004164static int _PyPclose(FILE *file);
4165
4166/*
4167 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00004168 * for use when retrieving the process exit code. See _PyPclose() below
4169 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004170 */
4171static PyObject *_PyPopenProcs = NULL;
4172
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004173
4174/* popen that works from a GUI.
4175 *
4176 * The result of this function is a pipe (file) connected to the
4177 * processes stdin or stdout, depending on the requested mode.
4178 */
4179
4180static PyObject *
4181posix_popen(PyObject *self, PyObject *args)
4182{
Raymond Hettingerb5cb6652003-09-01 22:25:41 +00004183 PyObject *f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004184 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004185
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004186 char *cmdstring;
4187 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004188 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004189 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004190 return NULL;
4191
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004192 if (*mode == 'r')
4193 tm = _O_RDONLY;
4194 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00004195 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004196 return NULL;
4197 } else
4198 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00004199
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004200 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004201 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004202 return NULL;
4203 }
4204
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004205 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004206 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004207 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004208 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004209 else
4210 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
4211
4212 return f;
4213}
4214
4215/* Variation on win32pipe.popen
4216 *
4217 * The result of this function is a pipe (file) connected to the
4218 * process's stdin, and a pipe connected to the process's stdout.
4219 */
4220
4221static PyObject *
4222win32_popen2(PyObject *self, PyObject *args)
4223{
4224 PyObject *f;
4225 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00004226
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004227 char *cmdstring;
4228 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004229 int bufsize = -1;
4230 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004231 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004232
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004233 if (*mode == 't')
4234 tm = _O_TEXT;
4235 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004236 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004237 return NULL;
4238 } else
4239 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004240
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004241 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004242 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004243 return NULL;
4244 }
4245
4246 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00004247
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004248 return f;
4249}
4250
4251/*
4252 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004253 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004254 * The result of this function is 3 pipes - the process's stdin,
4255 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004256 */
4257
4258static PyObject *
4259win32_popen3(PyObject *self, PyObject *args)
4260{
4261 PyObject *f;
4262 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004263
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004264 char *cmdstring;
4265 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004266 int bufsize = -1;
4267 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004268 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004269
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004270 if (*mode == 't')
4271 tm = _O_TEXT;
4272 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004273 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004274 return NULL;
4275 } else
4276 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004277
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004278 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004279 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004280 return NULL;
4281 }
4282
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004283 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00004284
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004285 return f;
4286}
4287
4288/*
4289 * Variation on win32pipe.popen
4290 *
Tim Peters5aa91602002-01-30 05:46:57 +00004291 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004292 * and stdout+stderr combined as a single pipe.
4293 */
4294
4295static PyObject *
4296win32_popen4(PyObject *self, PyObject *args)
4297{
4298 PyObject *f;
4299 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004300
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004301 char *cmdstring;
4302 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004303 int bufsize = -1;
4304 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004305 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004306
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004307 if (*mode == 't')
4308 tm = _O_TEXT;
4309 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004310 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004311 return NULL;
4312 } else
4313 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004314
4315 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004316 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004317 return NULL;
4318 }
4319
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004320 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004321
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004322 return f;
4323}
4324
Mark Hammond08501372001-01-31 07:30:29 +00004325static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00004326_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004327 HANDLE hStdin,
4328 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00004329 HANDLE hStderr,
4330 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004331{
4332 PROCESS_INFORMATION piProcInfo;
4333 STARTUPINFO siStartInfo;
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004334 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004335 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00004336 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004337 int i;
Martin v. Löwis18e16552006-02-15 17:27:45 +00004338 Py_ssize_t x;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004339
4340 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00004341 char *comshell;
4342
Tim Peters92e4dd82002-10-05 01:47:34 +00004343 s1 = (char *)alloca(i);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004344 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
Martin v. Löwis18e16552006-02-15 17:27:45 +00004345 /* x < i, so x fits into an integer */
4346 return (int)x;
Tim Peters402d5982001-08-27 06:37:48 +00004347
4348 /* Explicitly check if we are using COMMAND.COM. If we are
4349 * then use the w9xpopen hack.
4350 */
4351 comshell = s1 + x;
4352 while (comshell >= s1 && *comshell != '\\')
4353 --comshell;
4354 ++comshell;
4355
4356 if (GetVersion() < 0x80000000 &&
4357 _stricmp(comshell, "command.com") != 0) {
4358 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004359 x = i + strlen(s3) + strlen(cmdstring) + 1;
Tim Peters92e4dd82002-10-05 01:47:34 +00004360 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004361 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00004362 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004363 }
4364 else {
4365 /*
Tim Peters402d5982001-08-27 06:37:48 +00004366 * Oh gag, we're on Win9x or using COMMAND.COM. Use
4367 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004368 */
Mark Hammond08501372001-01-31 07:30:29 +00004369 char modulepath[_MAX_PATH];
4370 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004371 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
4372 for (i = x = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004373 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004374 x = i+1;
4375 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00004376 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00004377 strncat(modulepath,
4378 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00004379 (sizeof(modulepath)/sizeof(modulepath[0]))
4380 -strlen(modulepath));
4381 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00004382 /* Eeek - file-not-found - possibly an embedding
4383 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00004384 */
Tim Peters5aa91602002-01-30 05:46:57 +00004385 strncpy(modulepath,
4386 Py_GetExecPrefix(),
Mark Hammond08501372001-01-31 07:30:29 +00004387 sizeof(modulepath)/sizeof(modulepath[0]));
4388 if (modulepath[strlen(modulepath)-1] != '\\')
4389 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00004390 strncat(modulepath,
4391 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00004392 (sizeof(modulepath)/sizeof(modulepath[0]))
4393 -strlen(modulepath));
4394 /* No where else to look - raise an easily identifiable
4395 error, rather than leaving Windows to report
4396 "file not found" - as the user is probably blissfully
4397 unaware this shim EXE is used, and it will confuse them.
4398 (well, it confused me for a while ;-)
4399 */
4400 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00004401 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00004402 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00004403 "for popen to work with your shell "
4404 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00004405 szConsoleSpawn);
4406 return FALSE;
4407 }
4408 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004409 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00004410 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004411 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00004412
Tim Peters92e4dd82002-10-05 01:47:34 +00004413 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004414 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004415 /* To maintain correct argument passing semantics,
4416 we pass the command-line as it stands, and allow
4417 quoting to be applied. w9xpopen.exe will then
4418 use its argv vector, and re-quote the necessary
4419 args for the ultimate child process.
4420 */
Tim Peters75cdad52001-11-28 22:07:30 +00004421 PyOS_snprintf(
4422 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004423 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004424 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004425 s1,
4426 s3,
4427 cmdstring);
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004428 /* Not passing CREATE_NEW_CONSOLE has been known to
Tim Peters11b23062003-04-23 02:39:17 +00004429 cause random failures on win9x. Specifically a
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004430 dialog:
4431 "Your program accessed mem currently in use at xxx"
4432 and a hopeful warning about the stability of your
4433 system.
4434 Cost is Ctrl+C wont kill children, but anyone
4435 who cares can have a go!
4436 */
4437 dwProcessFlags |= CREATE_NEW_CONSOLE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004438 }
4439 }
4440
4441 /* Could be an else here to try cmd.exe / command.com in the path
4442 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00004443 else {
Tim Peters402d5982001-08-27 06:37:48 +00004444 PyErr_SetString(PyExc_RuntimeError,
4445 "Cannot locate a COMSPEC environment variable to "
4446 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00004447 return FALSE;
4448 }
Tim Peters5aa91602002-01-30 05:46:57 +00004449
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004450 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
4451 siStartInfo.cb = sizeof(STARTUPINFO);
4452 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
4453 siStartInfo.hStdInput = hStdin;
4454 siStartInfo.hStdOutput = hStdout;
4455 siStartInfo.hStdError = hStderr;
4456 siStartInfo.wShowWindow = SW_HIDE;
4457
4458 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004459 s2,
4460 NULL,
4461 NULL,
4462 TRUE,
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004463 dwProcessFlags,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004464 NULL,
4465 NULL,
4466 &siStartInfo,
4467 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004468 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004469 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004470
Mark Hammondb37a3732000-08-14 04:47:33 +00004471 /* Return process handle */
4472 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004473 return TRUE;
4474 }
Tim Peters402d5982001-08-27 06:37:48 +00004475 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004476 return FALSE;
4477}
4478
4479/* The following code is based off of KB: Q190351 */
4480
4481static PyObject *
4482_PyPopen(char *cmdstring, int mode, int n)
4483{
4484 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
4485 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00004486 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00004487
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004488 SECURITY_ATTRIBUTES saAttr;
4489 BOOL fSuccess;
4490 int fd1, fd2, fd3;
4491 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00004492 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004493 PyObject *f;
4494
4495 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
4496 saAttr.bInheritHandle = TRUE;
4497 saAttr.lpSecurityDescriptor = NULL;
4498
4499 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
4500 return win32_error("CreatePipe", NULL);
4501
4502 /* Create new output read handle and the input write handle. Set
4503 * the inheritance properties to FALSE. Otherwise, the child inherits
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00004504 * these handles; resulting in non-closeable handles to the pipes
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004505 * being created. */
4506 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004507 GetCurrentProcess(), &hChildStdinWrDup, 0,
4508 FALSE,
4509 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004510 if (!fSuccess)
4511 return win32_error("DuplicateHandle", NULL);
4512
4513 /* Close the inheritable version of ChildStdin
4514 that we're using. */
4515 CloseHandle(hChildStdinWr);
4516
4517 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
4518 return win32_error("CreatePipe", NULL);
4519
4520 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004521 GetCurrentProcess(), &hChildStdoutRdDup, 0,
4522 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004523 if (!fSuccess)
4524 return win32_error("DuplicateHandle", NULL);
4525
4526 /* Close the inheritable version of ChildStdout
4527 that we're using. */
4528 CloseHandle(hChildStdoutRd);
4529
4530 if (n != POPEN_4) {
4531 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
4532 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004533 fSuccess = DuplicateHandle(GetCurrentProcess(),
4534 hChildStderrRd,
4535 GetCurrentProcess(),
4536 &hChildStderrRdDup, 0,
4537 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004538 if (!fSuccess)
4539 return win32_error("DuplicateHandle", NULL);
4540 /* Close the inheritable version of ChildStdErr that we're using. */
4541 CloseHandle(hChildStderrRd);
4542 }
Tim Peters5aa91602002-01-30 05:46:57 +00004543
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004544 switch (n) {
4545 case POPEN_1:
4546 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
4547 case _O_WRONLY | _O_TEXT:
4548 /* Case for writing to child Stdin in text mode. */
Martin v. Löwis18e16552006-02-15 17:27:45 +00004549 fd1 = _open_osfhandle((intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004550 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004551 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004552 PyFile_SetBufSize(f, 0);
4553 /* We don't care about these pipes anymore, so close them. */
4554 CloseHandle(hChildStdoutRdDup);
4555 CloseHandle(hChildStderrRdDup);
4556 break;
4557
4558 case _O_RDONLY | _O_TEXT:
4559 /* Case for reading from child Stdout in text mode. */
Martin v. Löwis18e16552006-02-15 17:27:45 +00004560 fd1 = _open_osfhandle((intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004561 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004562 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004563 PyFile_SetBufSize(f, 0);
4564 /* We don't care about these pipes anymore, so close them. */
4565 CloseHandle(hChildStdinWrDup);
4566 CloseHandle(hChildStderrRdDup);
4567 break;
4568
4569 case _O_RDONLY | _O_BINARY:
4570 /* Case for readinig from child Stdout in binary mode. */
Martin v. Löwis18e16552006-02-15 17:27:45 +00004571 fd1 = _open_osfhandle((intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004572 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004573 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004574 PyFile_SetBufSize(f, 0);
4575 /* We don't care about these pipes anymore, so close them. */
4576 CloseHandle(hChildStdinWrDup);
4577 CloseHandle(hChildStderrRdDup);
4578 break;
4579
4580 case _O_WRONLY | _O_BINARY:
4581 /* Case for writing to child Stdin in binary mode. */
Martin v. Löwis18e16552006-02-15 17:27:45 +00004582 fd1 = _open_osfhandle((intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004583 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004584 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004585 PyFile_SetBufSize(f, 0);
4586 /* We don't care about these pipes anymore, so close them. */
4587 CloseHandle(hChildStdoutRdDup);
4588 CloseHandle(hChildStderrRdDup);
4589 break;
4590 }
Mark Hammondb37a3732000-08-14 04:47:33 +00004591 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004592 break;
Tim Peters5aa91602002-01-30 05:46:57 +00004593
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004594 case POPEN_2:
4595 case POPEN_4:
4596 {
4597 char *m1, *m2;
4598 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00004599
Tim Peters7dca21e2002-08-19 00:42:29 +00004600 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004601 m1 = "r";
4602 m2 = "w";
4603 } else {
4604 m1 = "rb";
4605 m2 = "wb";
4606 }
4607
Martin v. Löwis18e16552006-02-15 17:27:45 +00004608 fd1 = _open_osfhandle((intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004609 f1 = _fdopen(fd1, m2);
Martin v. Löwis18e16552006-02-15 17:27:45 +00004610 fd2 = _open_osfhandle((intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004611 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004612 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004613 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00004614 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004615 PyFile_SetBufSize(p2, 0);
4616
4617 if (n != 4)
4618 CloseHandle(hChildStderrRdDup);
4619
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004620 f = PyTuple_Pack(2,p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00004621 Py_XDECREF(p1);
4622 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00004623 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004624 break;
4625 }
Tim Peters5aa91602002-01-30 05:46:57 +00004626
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004627 case POPEN_3:
4628 {
4629 char *m1, *m2;
4630 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00004631
Tim Peters7dca21e2002-08-19 00:42:29 +00004632 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004633 m1 = "r";
4634 m2 = "w";
4635 } else {
4636 m1 = "rb";
4637 m2 = "wb";
4638 }
4639
Martin v. Löwis18e16552006-02-15 17:27:45 +00004640 fd1 = _open_osfhandle((intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004641 f1 = _fdopen(fd1, m2);
Martin v. Löwis18e16552006-02-15 17:27:45 +00004642 fd2 = _open_osfhandle((intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004643 f2 = _fdopen(fd2, m1);
Martin v. Löwis18e16552006-02-15 17:27:45 +00004644 fd3 = _open_osfhandle((intptr_t)hChildStderrRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004645 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004646 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00004647 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
4648 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004649 PyFile_SetBufSize(p1, 0);
4650 PyFile_SetBufSize(p2, 0);
4651 PyFile_SetBufSize(p3, 0);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004652 f = PyTuple_Pack(3,p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00004653 Py_XDECREF(p1);
4654 Py_XDECREF(p2);
4655 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00004656 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004657 break;
4658 }
4659 }
4660
4661 if (n == POPEN_4) {
4662 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004663 hChildStdinRd,
4664 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004665 hChildStdoutWr,
4666 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004667 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004668 }
4669 else {
4670 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004671 hChildStdinRd,
4672 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004673 hChildStderrWr,
4674 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004675 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004676 }
4677
Mark Hammondb37a3732000-08-14 04:47:33 +00004678 /*
4679 * Insert the files we've created into the process dictionary
4680 * all referencing the list with the process handle and the
4681 * initial number of files (see description below in _PyPclose).
4682 * Since if _PyPclose later tried to wait on a process when all
4683 * handles weren't closed, it could create a deadlock with the
4684 * child, we spend some energy here to try to ensure that we
4685 * either insert all file handles into the dictionary or none
4686 * at all. It's a little clumsy with the various popen modes
4687 * and variable number of files involved.
4688 */
4689 if (!_PyPopenProcs) {
4690 _PyPopenProcs = PyDict_New();
4691 }
4692
4693 if (_PyPopenProcs) {
4694 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
4695 int ins_rc[3];
4696
4697 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4698 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4699
4700 procObj = PyList_New(2);
4701 hProcessObj = PyLong_FromVoidPtr(hProcess);
4702 intObj = PyInt_FromLong(file_count);
4703
4704 if (procObj && hProcessObj && intObj) {
4705 PyList_SetItem(procObj,0,hProcessObj);
4706 PyList_SetItem(procObj,1,intObj);
4707
4708 fileObj[0] = PyLong_FromVoidPtr(f1);
4709 if (fileObj[0]) {
4710 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4711 fileObj[0],
4712 procObj);
4713 }
4714 if (file_count >= 2) {
4715 fileObj[1] = PyLong_FromVoidPtr(f2);
4716 if (fileObj[1]) {
4717 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4718 fileObj[1],
4719 procObj);
4720 }
4721 }
4722 if (file_count >= 3) {
4723 fileObj[2] = PyLong_FromVoidPtr(f3);
4724 if (fileObj[2]) {
4725 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4726 fileObj[2],
4727 procObj);
4728 }
4729 }
4730
4731 if (ins_rc[0] < 0 || !fileObj[0] ||
4732 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4733 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
4734 /* Something failed - remove any dictionary
4735 * entries that did make it.
4736 */
4737 if (!ins_rc[0] && fileObj[0]) {
4738 PyDict_DelItem(_PyPopenProcs,
4739 fileObj[0]);
4740 }
4741 if (!ins_rc[1] && fileObj[1]) {
4742 PyDict_DelItem(_PyPopenProcs,
4743 fileObj[1]);
4744 }
4745 if (!ins_rc[2] && fileObj[2]) {
4746 PyDict_DelItem(_PyPopenProcs,
4747 fileObj[2]);
4748 }
4749 }
4750 }
Tim Peters5aa91602002-01-30 05:46:57 +00004751
Mark Hammondb37a3732000-08-14 04:47:33 +00004752 /*
4753 * Clean up our localized references for the dictionary keys
4754 * and value since PyDict_SetItem will Py_INCREF any copies
4755 * that got placed in the dictionary.
4756 */
4757 Py_XDECREF(procObj);
4758 Py_XDECREF(fileObj[0]);
4759 Py_XDECREF(fileObj[1]);
4760 Py_XDECREF(fileObj[2]);
4761 }
4762
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004763 /* Child is launched. Close the parents copy of those pipe
4764 * handles that only the child should have open. You need to
4765 * make sure that no handles to the write end of the output pipe
4766 * are maintained in this process or else the pipe will not close
4767 * when the child process exits and the ReadFile will hang. */
4768
4769 if (!CloseHandle(hChildStdinRd))
4770 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004771
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004772 if (!CloseHandle(hChildStdoutWr))
4773 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004774
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004775 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
4776 return win32_error("CloseHandle", NULL);
4777
4778 return f;
4779}
Fredrik Lundh56055a42000-07-23 19:47:12 +00004780
4781/*
4782 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4783 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00004784 *
4785 * This function uses the _PyPopenProcs dictionary in order to map the
4786 * input file pointer to information about the process that was
4787 * originally created by the popen* call that created the file pointer.
4788 * The dictionary uses the file pointer as a key (with one entry
4789 * inserted for each file returned by the original popen* call) and a
4790 * single list object as the value for all files from a single call.
4791 * The list object contains the Win32 process handle at [0], and a file
4792 * count at [1], which is initialized to the total number of file
4793 * handles using that list.
4794 *
4795 * This function closes whichever handle it is passed, and decrements
4796 * the file count in the dictionary for the process handle pointed to
4797 * by this file. On the last close (when the file count reaches zero),
4798 * this function will wait for the child process and then return its
4799 * exit code as the result of the close() operation. This permits the
4800 * files to be closed in any order - it is always the close() of the
4801 * final handle that will return the exit code.
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004802 *
4803 * NOTE: This function is currently called with the GIL released.
4804 * hence we use the GILState API to manage our state.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004805 */
Tim Peters736aa322000-09-01 06:51:24 +00004806
Fredrik Lundh56055a42000-07-23 19:47:12 +00004807static int _PyPclose(FILE *file)
4808{
Fredrik Lundh20318932000-07-26 17:29:12 +00004809 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004810 DWORD exit_code;
4811 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00004812 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
4813 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00004814#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004815 PyGILState_STATE state;
Tim Peters736aa322000-09-01 06:51:24 +00004816#endif
4817
Fredrik Lundh20318932000-07-26 17:29:12 +00004818 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00004819 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00004820 */
4821 result = fclose(file);
Tim Peters736aa322000-09-01 06:51:24 +00004822#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004823 state = PyGILState_Ensure();
Tim Peters736aa322000-09-01 06:51:24 +00004824#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00004825 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00004826 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4827 (procObj = PyDict_GetItem(_PyPopenProcs,
4828 fileObj)) != NULL &&
4829 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
4830 (intObj = PyList_GetItem(procObj,1)) != NULL) {
4831
4832 hProcess = PyLong_AsVoidPtr(hProcessObj);
4833 file_count = PyInt_AsLong(intObj);
4834
4835 if (file_count > 1) {
4836 /* Still other files referencing process */
4837 file_count--;
4838 PyList_SetItem(procObj,1,
4839 PyInt_FromLong(file_count));
4840 } else {
4841 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00004842 if (result != EOF &&
4843 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
4844 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00004845 /* Possible truncation here in 16-bit environments, but
4846 * real exit codes are just the lower byte in any event.
4847 */
4848 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004849 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00004850 /* Indicate failure - this will cause the file object
4851 * to raise an I/O error and translate the last Win32
4852 * error code from errno. We do have a problem with
4853 * last errors that overlap the normal errno table,
4854 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004855 */
Fredrik Lundh20318932000-07-26 17:29:12 +00004856 if (result != EOF) {
4857 /* If the error wasn't from the fclose(), then
4858 * set errno for the file object error handling.
4859 */
4860 errno = GetLastError();
4861 }
4862 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004863 }
4864
4865 /* Free up the native handle at this point */
4866 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00004867 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00004868
Mark Hammondb37a3732000-08-14 04:47:33 +00004869 /* Remove this file pointer from dictionary */
4870 PyDict_DelItem(_PyPopenProcs, fileObj);
4871
4872 if (PyDict_Size(_PyPopenProcs) == 0) {
4873 Py_DECREF(_PyPopenProcs);
4874 _PyPopenProcs = NULL;
4875 }
4876
4877 } /* if object retrieval ok */
4878
4879 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004880 } /* if _PyPopenProcs */
4881
Tim Peters736aa322000-09-01 06:51:24 +00004882#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004883 PyGILState_Release(state);
Tim Peters736aa322000-09-01 06:51:24 +00004884#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00004885 return result;
4886}
Tim Peters9acdd3a2000-09-01 19:26:36 +00004887
4888#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00004889static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004890posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00004891{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004892 char *name;
4893 char *mode = "r";
4894 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00004895 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00004896 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004897 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00004898 return NULL;
Martin v. Löwis9ad853b2003-10-31 10:01:53 +00004899 /* Strip mode of binary or text modifiers */
4900 if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
4901 mode = "r";
4902 else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
4903 mode = "w";
Barry Warsaw53699e91996-12-10 23:23:01 +00004904 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004905 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004906 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00004907 if (fp == NULL)
4908 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004909 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004910 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00004911 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004912 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00004913}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004914
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004915#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004916#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00004917
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004918
Guido van Rossumb6775db1994-08-01 11:34:53 +00004919#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004920PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004921"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004922Set the current process's user id.");
4923
Barry Warsaw53699e91996-12-10 23:23:01 +00004924static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004925posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004926{
4927 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004928 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004929 return NULL;
4930 if (setuid(uid) < 0)
4931 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004932 Py_INCREF(Py_None);
4933 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004934}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004935#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004936
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004937
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00004938#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004939PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004940"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004941Set the current process's effective user id.");
4942
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00004943static PyObject *
4944posix_seteuid (PyObject *self, PyObject *args)
4945{
4946 int euid;
4947 if (!PyArg_ParseTuple(args, "i", &euid)) {
4948 return NULL;
4949 } else if (seteuid(euid) < 0) {
4950 return posix_error();
4951 } else {
4952 Py_INCREF(Py_None);
4953 return Py_None;
4954 }
4955}
4956#endif /* HAVE_SETEUID */
4957
4958#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004959PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004960"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004961Set the current process's effective group id.");
4962
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00004963static PyObject *
4964posix_setegid (PyObject *self, PyObject *args)
4965{
4966 int egid;
4967 if (!PyArg_ParseTuple(args, "i", &egid)) {
4968 return NULL;
4969 } else if (setegid(egid) < 0) {
4970 return posix_error();
4971 } else {
4972 Py_INCREF(Py_None);
4973 return Py_None;
4974 }
4975}
4976#endif /* HAVE_SETEGID */
4977
4978#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004979PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004980"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004981Set the current process's real and effective user ids.");
4982
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00004983static PyObject *
4984posix_setreuid (PyObject *self, PyObject *args)
4985{
4986 int ruid, euid;
4987 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
4988 return NULL;
4989 } else if (setreuid(ruid, euid) < 0) {
4990 return posix_error();
4991 } else {
4992 Py_INCREF(Py_None);
4993 return Py_None;
4994 }
4995}
4996#endif /* HAVE_SETREUID */
4997
4998#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004999PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005000"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005001Set the current process's real and effective group ids.");
5002
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00005003static PyObject *
5004posix_setregid (PyObject *self, PyObject *args)
5005{
5006 int rgid, egid;
5007 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
5008 return NULL;
5009 } else if (setregid(rgid, egid) < 0) {
5010 return posix_error();
5011 } else {
5012 Py_INCREF(Py_None);
5013 return Py_None;
5014 }
5015}
5016#endif /* HAVE_SETREGID */
5017
Guido van Rossumb6775db1994-08-01 11:34:53 +00005018#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005019PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005020"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005021Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005022
Barry Warsaw53699e91996-12-10 23:23:01 +00005023static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005024posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005025{
5026 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005027 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005028 return NULL;
5029 if (setgid(gid) < 0)
5030 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005031 Py_INCREF(Py_None);
5032 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005033}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005034#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005035
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005036#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005037PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005038"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005039Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005040
5041static PyObject *
5042posix_setgroups(PyObject *self, PyObject *args)
5043{
5044 PyObject *groups;
5045 int i, len;
5046 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00005047
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005048 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
5049 return NULL;
5050 if (!PySequence_Check(groups)) {
5051 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
5052 return NULL;
5053 }
5054 len = PySequence_Size(groups);
5055 if (len > MAX_GROUPS) {
5056 PyErr_SetString(PyExc_ValueError, "too many groups");
5057 return NULL;
5058 }
5059 for(i = 0; i < len; i++) {
5060 PyObject *elem;
5061 elem = PySequence_GetItem(groups, i);
5062 if (!elem)
5063 return NULL;
5064 if (!PyInt_Check(elem)) {
Georg Brandla13c2442005-11-22 19:30:31 +00005065 if (!PyLong_Check(elem)) {
5066 PyErr_SetString(PyExc_TypeError,
5067 "groups must be integers");
5068 Py_DECREF(elem);
5069 return NULL;
5070 } else {
5071 unsigned long x = PyLong_AsUnsignedLong(elem);
5072 if (PyErr_Occurred()) {
5073 PyErr_SetString(PyExc_TypeError,
5074 "group id too big");
5075 Py_DECREF(elem);
5076 return NULL;
5077 }
5078 grouplist[i] = x;
5079 /* read back the value to see if it fitted in gid_t */
5080 if (grouplist[i] != x) {
5081 PyErr_SetString(PyExc_TypeError,
5082 "group id too big");
5083 Py_DECREF(elem);
5084 return NULL;
5085 }
5086 }
5087 } else {
5088 long x = PyInt_AsLong(elem);
5089 grouplist[i] = x;
5090 if (grouplist[i] != x) {
5091 PyErr_SetString(PyExc_TypeError,
5092 "group id too big");
5093 Py_DECREF(elem);
5094 return NULL;
5095 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005096 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005097 Py_DECREF(elem);
5098 }
5099
5100 if (setgroups(len, grouplist) < 0)
5101 return posix_error();
5102 Py_INCREF(Py_None);
5103 return Py_None;
5104}
5105#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005106
Neal Norwitz6c2f9132006-03-20 07:25:26 +00005107#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Neal Norwitz05a45592006-03-20 06:30:08 +00005108static PyObject *
5109wait_helper(int pid, int status, struct rusage *ru)
5110{
5111 PyObject *result;
5112 static PyObject *struct_rusage;
5113
5114 if (pid == -1)
5115 return posix_error();
5116
5117 if (struct_rusage == NULL) {
5118 PyObject *m = PyImport_ImportModule("resource");
5119 if (m == NULL)
5120 return NULL;
5121 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
5122 Py_DECREF(m);
5123 if (struct_rusage == NULL)
5124 return NULL;
5125 }
5126
5127 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
5128 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
5129 if (!result)
5130 return NULL;
5131
5132#ifndef doubletime
5133#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
5134#endif
5135
5136 PyStructSequence_SET_ITEM(result, 0,
5137 PyFloat_FromDouble(doubletime(ru->ru_utime)));
5138 PyStructSequence_SET_ITEM(result, 1,
5139 PyFloat_FromDouble(doubletime(ru->ru_stime)));
5140#define SET_INT(result, index, value)\
5141 PyStructSequence_SET_ITEM(result, index, PyInt_FromLong(value))
5142 SET_INT(result, 2, ru->ru_maxrss);
5143 SET_INT(result, 3, ru->ru_ixrss);
5144 SET_INT(result, 4, ru->ru_idrss);
5145 SET_INT(result, 5, ru->ru_isrss);
5146 SET_INT(result, 6, ru->ru_minflt);
5147 SET_INT(result, 7, ru->ru_majflt);
5148 SET_INT(result, 8, ru->ru_nswap);
5149 SET_INT(result, 9, ru->ru_inblock);
5150 SET_INT(result, 10, ru->ru_oublock);
5151 SET_INT(result, 11, ru->ru_msgsnd);
5152 SET_INT(result, 12, ru->ru_msgrcv);
5153 SET_INT(result, 13, ru->ru_nsignals);
5154 SET_INT(result, 14, ru->ru_nvcsw);
5155 SET_INT(result, 15, ru->ru_nivcsw);
5156#undef SET_INT
5157
5158 if (PyErr_Occurred()) {
5159 Py_DECREF(result);
5160 return NULL;
5161 }
5162
Neal Norwitz9b00a562006-03-20 08:47:12 +00005163 return Py_BuildValue("iiN", pid, status, result);
Neal Norwitz05a45592006-03-20 06:30:08 +00005164}
Neal Norwitz6c2f9132006-03-20 07:25:26 +00005165#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
Neal Norwitz05a45592006-03-20 06:30:08 +00005166
5167#ifdef HAVE_WAIT3
5168PyDoc_STRVAR(posix_wait3__doc__,
5169"wait3(options) -> (pid, status, rusage)\n\n\
5170Wait for completion of a child process.");
5171
5172static PyObject *
5173posix_wait3(PyObject *self, PyObject *args)
5174{
5175 int pid, options;
5176 struct rusage ru;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005177 WAIT_TYPE status;
5178 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00005179
5180 if (!PyArg_ParseTuple(args, "i:wait3", &options))
5181 return NULL;
5182
5183 Py_BEGIN_ALLOW_THREADS
5184 pid = wait3(&status, options, &ru);
5185 Py_END_ALLOW_THREADS
5186
Neal Norwitzd5a37542006-03-20 06:48:34 +00005187 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00005188}
5189#endif /* HAVE_WAIT3 */
5190
5191#ifdef HAVE_WAIT4
5192PyDoc_STRVAR(posix_wait4__doc__,
5193"wait4(pid, options) -> (pid, status, rusage)\n\n\
5194Wait for completion of a given child process.");
5195
5196static PyObject *
5197posix_wait4(PyObject *self, PyObject *args)
5198{
5199 int pid, options;
5200 struct rusage ru;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005201 WAIT_TYPE status;
5202 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00005203
5204 if (!PyArg_ParseTuple(args, "ii:wait4", &pid, &options))
5205 return NULL;
5206
5207 Py_BEGIN_ALLOW_THREADS
5208 pid = wait4(pid, &status, options, &ru);
5209 Py_END_ALLOW_THREADS
5210
Neal Norwitzd5a37542006-03-20 06:48:34 +00005211 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00005212}
5213#endif /* HAVE_WAIT4 */
5214
Guido van Rossumb6775db1994-08-01 11:34:53 +00005215#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005216PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005217"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005218Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005219
Barry Warsaw53699e91996-12-10 23:23:01 +00005220static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005221posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005222{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005223 int pid, options;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005224 WAIT_TYPE status;
5225 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005226
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005227 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00005228 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005229 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00005230 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00005231 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00005232 if (pid == -1)
5233 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00005234
5235 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00005236}
5237
Tim Petersab034fa2002-02-01 11:27:43 +00005238#elif defined(HAVE_CWAIT)
5239
5240/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005241PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005242"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005243"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00005244
5245static PyObject *
5246posix_waitpid(PyObject *self, PyObject *args)
5247{
Martin v. Löwis18e16552006-02-15 17:27:45 +00005248 intptr_t pid;
5249 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00005250
5251 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
5252 return NULL;
5253 Py_BEGIN_ALLOW_THREADS
5254 pid = _cwait(&status, pid, options);
5255 Py_END_ALLOW_THREADS
5256 if (pid == -1)
5257 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00005258
5259 /* shift the status left a byte so this is more like the POSIX waitpid */
5260 return Py_BuildValue("ii", pid, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00005261}
5262#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005263
Guido van Rossumad0ee831995-03-01 10:34:45 +00005264#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005265PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005266"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005267Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005268
Barry Warsaw53699e91996-12-10 23:23:01 +00005269static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005270posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00005271{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005272 int pid;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005273 WAIT_TYPE status;
5274 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00005275
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005276 Py_BEGIN_ALLOW_THREADS
5277 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00005278 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00005279 if (pid == -1)
5280 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00005281
5282 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00005283}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005284#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005285
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005286
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005287PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005288"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005289Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005290
Barry Warsaw53699e91996-12-10 23:23:01 +00005291static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005292posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005293{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005294#ifdef HAVE_LSTAT
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005295 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005296#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005297#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00005298 return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005299#else
5300 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
5301#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005302#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005303}
5304
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005305
Guido van Rossumb6775db1994-08-01 11:34:53 +00005306#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005307PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005308"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005309Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005310
Barry Warsaw53699e91996-12-10 23:23:01 +00005311static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005312posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005313{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005314 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00005315 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005316 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005317 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005318 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005319 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00005320 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00005321 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005322 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00005323 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00005324 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005325}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005326#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005327
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005328
Guido van Rossumb6775db1994-08-01 11:34:53 +00005329#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005330PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005331"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00005332Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005333
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005334static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005335posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005336{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005337 return posix_2str(args, "etet:symlink", symlink, NULL, NULL);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005338}
5339#endif /* HAVE_SYMLINK */
5340
5341
5342#ifdef HAVE_TIMES
5343#ifndef HZ
5344#define HZ 60 /* Universal constant :-) */
5345#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00005346
Guido van Rossumd48f2521997-12-05 22:19:34 +00005347#if defined(PYCC_VACPP) && defined(PYOS_OS2)
5348static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005349system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005350{
5351 ULONG value = 0;
5352
5353 Py_BEGIN_ALLOW_THREADS
5354 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
5355 Py_END_ALLOW_THREADS
5356
5357 return value;
5358}
5359
5360static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005361posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005362{
Guido van Rossumd48f2521997-12-05 22:19:34 +00005363 /* Currently Only Uptime is Provided -- Others Later */
5364 return Py_BuildValue("ddddd",
5365 (double)0 /* t.tms_utime / HZ */,
5366 (double)0 /* t.tms_stime / HZ */,
5367 (double)0 /* t.tms_cutime / HZ */,
5368 (double)0 /* t.tms_cstime / HZ */,
5369 (double)system_uptime() / 1000);
5370}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005371#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00005372static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005373posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00005374{
5375 struct tms t;
5376 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +00005377 errno = 0;
5378 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00005379 if (c == (clock_t) -1)
5380 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005381 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00005382 (double)t.tms_utime / HZ,
5383 (double)t.tms_stime / HZ,
5384 (double)t.tms_cutime / HZ,
5385 (double)t.tms_cstime / HZ,
5386 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00005387}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005388#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005389#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005390
5391
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005392#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005393#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00005394static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005395posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005396{
5397 FILETIME create, exit, kernel, user;
5398 HANDLE hProc;
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005399 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00005400 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
5401 /* The fields of a FILETIME structure are the hi and lo part
5402 of a 64-bit value expressed in 100 nanosecond units.
5403 1e7 is one second in such units; 1e-7 the inverse.
5404 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
5405 */
Barry Warsaw53699e91996-12-10 23:23:01 +00005406 return Py_BuildValue(
5407 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00005408 (double)(kernel.dwHighDateTime*429.4967296 +
5409 kernel.dwLowDateTime*1e-7),
5410 (double)(user.dwHighDateTime*429.4967296 +
5411 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00005412 (double)0,
5413 (double)0,
5414 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005415}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005416#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005417
5418#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005419PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005420"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005421Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005422#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005423
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005424
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00005425#ifdef HAVE_GETSID
5426PyDoc_STRVAR(posix_getsid__doc__,
5427"getsid(pid) -> sid\n\n\
5428Call the system call getsid().");
5429
5430static PyObject *
5431posix_getsid(PyObject *self, PyObject *args)
5432{
5433 int pid, sid;
5434 if (!PyArg_ParseTuple(args, "i:getsid", &pid))
5435 return NULL;
5436 sid = getsid(pid);
5437 if (sid < 0)
5438 return posix_error();
5439 return PyInt_FromLong((long)sid);
5440}
5441#endif /* HAVE_GETSID */
5442
5443
Guido van Rossumb6775db1994-08-01 11:34:53 +00005444#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005445PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005446"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005447Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005448
Barry Warsaw53699e91996-12-10 23:23:01 +00005449static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005450posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005451{
Guido van Rossum687dd131993-05-17 08:34:16 +00005452 if (setsid() < 0)
5453 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005454 Py_INCREF(Py_None);
5455 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005456}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005457#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005458
Guido van Rossumb6775db1994-08-01 11:34:53 +00005459#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005460PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005461"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005462Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005463
Barry Warsaw53699e91996-12-10 23:23:01 +00005464static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005465posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005466{
5467 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005468 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00005469 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005470 if (setpgid(pid, pgrp) < 0)
5471 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005472 Py_INCREF(Py_None);
5473 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005474}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005475#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005476
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005477
Guido van Rossumb6775db1994-08-01 11:34:53 +00005478#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005479PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005480"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005481Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005482
Barry Warsaw53699e91996-12-10 23:23:01 +00005483static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005484posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005485{
5486 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005487 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00005488 return NULL;
5489 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005490 if (pgid < 0)
5491 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005492 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00005493}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005494#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00005495
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005496
Guido van Rossumb6775db1994-08-01 11:34:53 +00005497#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005498PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005499"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005500Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005501
Barry Warsaw53699e91996-12-10 23:23:01 +00005502static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005503posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005504{
5505 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005506 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00005507 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005508 if (tcsetpgrp(fd, pgid) < 0)
5509 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00005510 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00005511 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00005512}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005513#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00005514
Guido van Rossum687dd131993-05-17 08:34:16 +00005515/* Functions acting on file descriptors */
5516
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005517PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005518"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005519Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005520
Barry Warsaw53699e91996-12-10 23:23:01 +00005521static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005522posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005523{
Mark Hammondef8b6542001-05-13 08:04:26 +00005524 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005525 int flag;
5526 int mode = 0777;
5527 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005528
5529#ifdef MS_WINDOWS
5530 if (unicode_file_names()) {
5531 PyUnicodeObject *po;
5532 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
5533 Py_BEGIN_ALLOW_THREADS
5534 /* PyUnicode_AS_UNICODE OK without thread
5535 lock as it is a simple dereference. */
5536 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
5537 Py_END_ALLOW_THREADS
5538 if (fd < 0)
5539 return posix_error();
5540 return PyInt_FromLong((long)fd);
5541 }
5542 /* Drop the argument parsing error as narrow strings
5543 are also valid. */
5544 PyErr_Clear();
5545 }
5546#endif
5547
Tim Peters5aa91602002-01-30 05:46:57 +00005548 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00005549 Py_FileSystemDefaultEncoding, &file,
5550 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00005551 return NULL;
5552
Barry Warsaw53699e91996-12-10 23:23:01 +00005553 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005554 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005555 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005556 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00005557 return posix_error_with_allocated_filename(file);
5558 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00005559 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005560}
5561
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005562
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005563PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005564"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005565Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005566
Barry Warsaw53699e91996-12-10 23:23:01 +00005567static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005568posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005569{
5570 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005571 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005572 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005573 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005574 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00005575 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005576 if (res < 0)
5577 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005578 Py_INCREF(Py_None);
5579 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005580}
5581
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005582
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005583PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005584"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005585Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005586
Barry Warsaw53699e91996-12-10 23:23:01 +00005587static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005588posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005589{
5590 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005591 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005592 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005593 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005594 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00005595 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005596 if (fd < 0)
5597 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005598 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005599}
5600
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005601
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005602PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00005603"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005604Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005605
Barry Warsaw53699e91996-12-10 23:23:01 +00005606static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005607posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005608{
5609 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005610 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00005611 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005612 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005613 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00005614 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005615 if (res < 0)
5616 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005617 Py_INCREF(Py_None);
5618 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005619}
5620
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005621
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005622PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005623"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005624Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005625
Barry Warsaw53699e91996-12-10 23:23:01 +00005626static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005627posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005628{
5629 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005630#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005631 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005632#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00005633 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005634#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005635 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005636 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00005637 return NULL;
5638#ifdef SEEK_SET
5639 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
5640 switch (how) {
5641 case 0: how = SEEK_SET; break;
5642 case 1: how = SEEK_CUR; break;
5643 case 2: how = SEEK_END; break;
5644 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005645#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005646
5647#if !defined(HAVE_LARGEFILE_SUPPORT)
5648 pos = PyInt_AsLong(posobj);
5649#else
5650 pos = PyLong_Check(posobj) ?
5651 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
5652#endif
5653 if (PyErr_Occurred())
5654 return NULL;
5655
Barry Warsaw53699e91996-12-10 23:23:01 +00005656 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005657#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00005658 res = _lseeki64(fd, pos, how);
5659#else
Guido van Rossum687dd131993-05-17 08:34:16 +00005660 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005661#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005662 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005663 if (res < 0)
5664 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00005665
5666#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00005667 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005668#else
5669 return PyLong_FromLongLong(res);
5670#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005671}
5672
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005673
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005674PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005675"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005676Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005677
Barry Warsaw53699e91996-12-10 23:23:01 +00005678static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005679posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005680{
Guido van Rossum8bac5461996-06-11 18:38:48 +00005681 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00005682 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005683 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005684 return NULL;
Michael W. Hudson9867ced2005-01-31 17:01:59 +00005685 if (size < 0) {
5686 errno = EINVAL;
5687 return posix_error();
5688 }
Barry Warsaw53699e91996-12-10 23:23:01 +00005689 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005690 if (buffer == NULL)
5691 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005692 Py_BEGIN_ALLOW_THREADS
5693 n = read(fd, PyString_AsString(buffer), size);
5694 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00005695 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005696 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00005697 return posix_error();
5698 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00005699 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00005700 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00005701 return buffer;
5702}
5703
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005704
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005705PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005706"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005707Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005708
Barry Warsaw53699e91996-12-10 23:23:01 +00005709static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005710posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005711{
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005712 int fd;
5713 Py_ssize_t size;
Guido van Rossum687dd131993-05-17 08:34:16 +00005714 char *buffer;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005715
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005716 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005717 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005718 Py_BEGIN_ALLOW_THREADS
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005719 size = write(fd, buffer, (size_t)size);
Barry Warsaw53699e91996-12-10 23:23:01 +00005720 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005721 if (size < 0)
5722 return posix_error();
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005723 return PyInt_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005724}
5725
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005726
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005727PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005728"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005729Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005730
Barry Warsaw53699e91996-12-10 23:23:01 +00005731static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005732posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005733{
5734 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00005735 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00005736 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005737 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005738 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005739#ifdef __VMS
5740 /* on OpenVMS we must ensure that all bytes are written to the file */
5741 fsync(fd);
5742#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005743 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00005744 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00005745 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00005746 if (res != 0) {
5747#ifdef MS_WINDOWS
5748 return win32_error("fstat", NULL);
5749#else
Guido van Rossum687dd131993-05-17 08:34:16 +00005750 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00005751#endif
5752 }
Tim Peters5aa91602002-01-30 05:46:57 +00005753
Martin v. Löwis14694662006-02-03 12:54:16 +00005754 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00005755}
5756
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005757
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005758PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005759"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005760Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005761
Barry Warsaw53699e91996-12-10 23:23:01 +00005762static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005763posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005764{
Guido van Rossum687dd131993-05-17 08:34:16 +00005765 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005766 char *mode = "r";
5767 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00005768 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00005769 PyObject *f;
5770 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00005771 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00005772
Thomas Heller1f043e22002-11-07 16:00:59 +00005773 if (mode[0] != 'r' && mode[0] != 'w' && mode[0] != 'a') {
5774 PyErr_Format(PyExc_ValueError,
5775 "invalid file mode '%s'", mode);
5776 return NULL;
5777 }
Barry Warsaw53699e91996-12-10 23:23:01 +00005778 Py_BEGIN_ALLOW_THREADS
Georg Brandl644b1e72006-03-31 20:27:22 +00005779#if !defined(MS_WINDOWS) && defined(HAVE_FCNTL_H)
Georg Brandl54a188a2006-03-31 20:00:11 +00005780 if (mode[0] == 'a') {
5781 /* try to make sure the O_APPEND flag is set */
5782 int flags;
5783 flags = fcntl(fd, F_GETFL);
5784 if (flags != -1)
5785 fcntl(fd, F_SETFL, flags | O_APPEND);
5786 fp = fdopen(fd, mode);
Thomas Wouters2a9a6b02006-03-31 22:38:19 +00005787 if (fp == NULL && flags != -1)
Georg Brandl54a188a2006-03-31 20:00:11 +00005788 /* restore old mode if fdopen failed */
5789 fcntl(fd, F_SETFL, flags);
5790 } else {
5791 fp = fdopen(fd, mode);
5792 }
Georg Brandl644b1e72006-03-31 20:27:22 +00005793#else
5794 fp = fdopen(fd, mode);
5795#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005796 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005797 if (fp == NULL)
5798 return posix_error();
Guido van Rossumbd6be7a2002-09-15 18:45:46 +00005799 f = PyFile_FromFile(fp, "<fdopen>", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005800 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00005801 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005802 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00005803}
5804
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005805PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005806"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005807Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005808connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00005809
5810static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00005811posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00005812{
5813 int fd;
5814 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
5815 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005816 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00005817}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005818
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005819#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005820PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005821"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005822Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005823
Barry Warsaw53699e91996-12-10 23:23:01 +00005824static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005825posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00005826{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005827#if defined(PYOS_OS2)
5828 HFILE read, write;
5829 APIRET rc;
5830
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005831 Py_BEGIN_ALLOW_THREADS
5832 rc = DosCreatePipe( &read, &write, 4096);
5833 Py_END_ALLOW_THREADS
5834 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005835 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005836
5837 return Py_BuildValue("(ii)", read, write);
5838#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005839#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00005840 int fds[2];
5841 int res;
Barry Warsaw53699e91996-12-10 23:23:01 +00005842 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005843 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00005844 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005845 if (res != 0)
5846 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005847 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005848#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00005849 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005850 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00005851 BOOL ok;
Barry Warsaw53699e91996-12-10 23:23:01 +00005852 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005853 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00005854 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00005855 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005856 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00005857 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
5858 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005859 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005860#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005861#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005862}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005863#endif /* HAVE_PIPE */
5864
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005865
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005866#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005867PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005868"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005869Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005870
Barry Warsaw53699e91996-12-10 23:23:01 +00005871static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005872posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005873{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005874 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005875 int mode = 0666;
5876 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005877 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005878 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005879 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005880 res = mkfifo(filename, mode);
5881 Py_END_ALLOW_THREADS
5882 if (res < 0)
5883 return posix_error();
5884 Py_INCREF(Py_None);
5885 return Py_None;
5886}
5887#endif
5888
5889
Neal Norwitz11690112002-07-30 01:08:28 +00005890#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005891PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005892"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005893Create a filesystem node (file, device special file or named pipe)\n\
5894named filename. mode specifies both the permissions to use and the\n\
5895type of node to be created, being combined (bitwise OR) with one of\n\
5896S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005897device defines the newly created device special file (probably using\n\
5898os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005899
5900
5901static PyObject *
5902posix_mknod(PyObject *self, PyObject *args)
5903{
5904 char *filename;
5905 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005906 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005907 int res;
Martin v. Löwisd631ebe2002-11-02 17:42:33 +00005908 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005909 return NULL;
5910 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005911 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00005912 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005913 if (res < 0)
5914 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005915 Py_INCREF(Py_None);
5916 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005917}
5918#endif
5919
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005920#ifdef HAVE_DEVICE_MACROS
5921PyDoc_STRVAR(posix_major__doc__,
5922"major(device) -> major number\n\
5923Extracts a device major number from a raw device number.");
5924
5925static PyObject *
5926posix_major(PyObject *self, PyObject *args)
5927{
5928 int device;
5929 if (!PyArg_ParseTuple(args, "i:major", &device))
5930 return NULL;
5931 return PyInt_FromLong((long)major(device));
5932}
5933
5934PyDoc_STRVAR(posix_minor__doc__,
5935"minor(device) -> minor number\n\
5936Extracts a device minor number from a raw device number.");
5937
5938static PyObject *
5939posix_minor(PyObject *self, PyObject *args)
5940{
5941 int device;
5942 if (!PyArg_ParseTuple(args, "i:minor", &device))
5943 return NULL;
5944 return PyInt_FromLong((long)minor(device));
5945}
5946
5947PyDoc_STRVAR(posix_makedev__doc__,
5948"makedev(major, minor) -> device number\n\
5949Composes a raw device number from the major and minor device numbers.");
5950
5951static PyObject *
5952posix_makedev(PyObject *self, PyObject *args)
5953{
5954 int major, minor;
5955 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
5956 return NULL;
5957 return PyInt_FromLong((long)makedev(major, minor));
5958}
5959#endif /* device macros */
5960
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005961
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005962#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005963PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005964"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005965Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005966
Barry Warsaw53699e91996-12-10 23:23:01 +00005967static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005968posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005969{
5970 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005971 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005972 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005973 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005974
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005975 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005976 return NULL;
5977
5978#if !defined(HAVE_LARGEFILE_SUPPORT)
5979 length = PyInt_AsLong(lenobj);
5980#else
5981 length = PyLong_Check(lenobj) ?
5982 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
5983#endif
5984 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005985 return NULL;
5986
Barry Warsaw53699e91996-12-10 23:23:01 +00005987 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005988 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00005989 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005990 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005991 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005992 return NULL;
5993 }
Barry Warsaw53699e91996-12-10 23:23:01 +00005994 Py_INCREF(Py_None);
5995 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005996}
5997#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005998
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005999#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006000PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006001"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006002Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006003
Fred Drake762e2061999-08-26 17:23:54 +00006004/* Save putenv() parameters as values here, so we can collect them when they
6005 * get re-set with another call for the same key. */
6006static PyObject *posix_putenv_garbage;
6007
Tim Peters5aa91602002-01-30 05:46:57 +00006008static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006009posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006010{
6011 char *s1, *s2;
Anthony Baxter64182fe2006-04-11 12:14:09 +00006012 char *newenv;
Fred Drake762e2061999-08-26 17:23:54 +00006013 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00006014 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006015
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006016 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006017 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00006018
6019#if defined(PYOS_OS2)
6020 if (stricmp(s1, "BEGINLIBPATH") == 0) {
6021 APIRET rc;
6022
Guido van Rossumd48f2521997-12-05 22:19:34 +00006023 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
6024 if (rc != NO_ERROR)
6025 return os2_error(rc);
6026
6027 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
6028 APIRET rc;
6029
Guido van Rossumd48f2521997-12-05 22:19:34 +00006030 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
6031 if (rc != NO_ERROR)
6032 return os2_error(rc);
6033 } else {
6034#endif
6035
Fred Drake762e2061999-08-26 17:23:54 +00006036 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00006037 len = strlen(s1) + strlen(s2) + 2;
6038 /* len includes space for a trailing \0; the size arg to
6039 PyString_FromStringAndSize does not count that */
6040 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00006041 if (newstr == NULL)
6042 return PyErr_NoMemory();
Anthony Baxter64182fe2006-04-11 12:14:09 +00006043 newenv = PyString_AS_STRING(newstr);
6044 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
6045 if (putenv(newenv)) {
Neal Norwitz4adc9ab2003-02-10 03:10:43 +00006046 Py_DECREF(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006047 posix_error();
6048 return NULL;
6049 }
Fred Drake762e2061999-08-26 17:23:54 +00006050 /* Install the first arg and newstr in posix_putenv_garbage;
6051 * this will cause previous value to be collected. This has to
6052 * happen after the real putenv() call because the old value
6053 * was still accessible until then. */
6054 if (PyDict_SetItem(posix_putenv_garbage,
6055 PyTuple_GET_ITEM(args, 0), newstr)) {
6056 /* really not much we can do; just leak */
6057 PyErr_Clear();
6058 }
6059 else {
6060 Py_DECREF(newstr);
6061 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00006062
6063#if defined(PYOS_OS2)
6064 }
6065#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006066 Py_INCREF(Py_None);
6067 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006068}
Guido van Rossumb6a47161997-09-15 22:54:34 +00006069#endif /* putenv */
6070
Guido van Rossumc524d952001-10-19 01:31:59 +00006071#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006072PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006073"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006074Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00006075
6076static PyObject *
6077posix_unsetenv(PyObject *self, PyObject *args)
6078{
6079 char *s1;
6080
6081 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
6082 return NULL;
6083
6084 unsetenv(s1);
6085
6086 /* Remove the key from posix_putenv_garbage;
6087 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00006088 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00006089 * old value was still accessible until then.
6090 */
6091 if (PyDict_DelItem(posix_putenv_garbage,
6092 PyTuple_GET_ITEM(args, 0))) {
6093 /* really not much we can do; just leak */
6094 PyErr_Clear();
6095 }
6096
6097 Py_INCREF(Py_None);
6098 return Py_None;
6099}
6100#endif /* unsetenv */
6101
Guido van Rossumb6a47161997-09-15 22:54:34 +00006102#ifdef HAVE_STRERROR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006103PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006104"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006105Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00006106
Guido van Rossumf68d8e52001-04-14 17:55:09 +00006107static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006108posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00006109{
6110 int code;
6111 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006112 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00006113 return NULL;
6114 message = strerror(code);
6115 if (message == NULL) {
6116 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00006117 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00006118 return NULL;
6119 }
6120 return PyString_FromString(message);
6121}
6122#endif /* strerror */
6123
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006124
Guido van Rossumc9641791998-08-04 15:26:23 +00006125#ifdef HAVE_SYS_WAIT_H
6126
Fred Drake106c1a02002-04-23 15:58:02 +00006127#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006128PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006129"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006130Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00006131
6132static PyObject *
6133posix_WCOREDUMP(PyObject *self, PyObject *args)
6134{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006135 WAIT_TYPE status;
6136 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006137
Neal Norwitzd5a37542006-03-20 06:48:34 +00006138 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00006139 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006140
6141 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006142}
6143#endif /* WCOREDUMP */
6144
6145#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006146PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006147"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006148Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006149job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00006150
6151static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006152posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00006153{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006154 WAIT_TYPE status;
6155 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006156
Neal Norwitzd5a37542006-03-20 06:48:34 +00006157 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00006158 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006159
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006160 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006161}
6162#endif /* WIFCONTINUED */
6163
Guido van Rossumc9641791998-08-04 15:26:23 +00006164#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006165PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006166"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006167Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006168
6169static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006170posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006171{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006172 WAIT_TYPE status;
6173 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006174
Neal Norwitzd5a37542006-03-20 06:48:34 +00006175 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006176 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006177
Fred Drake106c1a02002-04-23 15:58:02 +00006178 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006179}
6180#endif /* WIFSTOPPED */
6181
6182#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006183PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006184"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006185Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006186
6187static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006188posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006189{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006190 WAIT_TYPE status;
6191 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006192
Neal Norwitzd5a37542006-03-20 06:48:34 +00006193 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006194 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006195
Fred Drake106c1a02002-04-23 15:58:02 +00006196 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006197}
6198#endif /* WIFSIGNALED */
6199
6200#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006201PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006202"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006203Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006204system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006205
6206static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006207posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006208{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006209 WAIT_TYPE status;
6210 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006211
Neal Norwitzd5a37542006-03-20 06:48:34 +00006212 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006213 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006214
Fred Drake106c1a02002-04-23 15:58:02 +00006215 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006216}
6217#endif /* WIFEXITED */
6218
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006219#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006220PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006221"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006222Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006223
6224static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006225posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006226{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006227 WAIT_TYPE status;
6228 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006229
Neal Norwitzd5a37542006-03-20 06:48:34 +00006230 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006231 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006232
Guido van Rossumc9641791998-08-04 15:26:23 +00006233 return Py_BuildValue("i", WEXITSTATUS(status));
6234}
6235#endif /* WEXITSTATUS */
6236
6237#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006238PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006239"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006240Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006241value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006242
6243static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006244posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006245{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006246 WAIT_TYPE status;
6247 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006248
Neal Norwitzd5a37542006-03-20 06:48:34 +00006249 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006250 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006251
Guido van Rossumc9641791998-08-04 15:26:23 +00006252 return Py_BuildValue("i", WTERMSIG(status));
6253}
6254#endif /* WTERMSIG */
6255
6256#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006257PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006258"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006259Return the signal that stopped the process that provided\n\
6260the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006261
6262static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006263posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006264{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006265 WAIT_TYPE status;
6266 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006267
Neal Norwitzd5a37542006-03-20 06:48:34 +00006268 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006269 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006270
Guido van Rossumc9641791998-08-04 15:26:23 +00006271 return Py_BuildValue("i", WSTOPSIG(status));
6272}
6273#endif /* WSTOPSIG */
6274
6275#endif /* HAVE_SYS_WAIT_H */
6276
6277
Guido van Rossum94f6f721999-01-06 18:42:14 +00006278#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00006279#ifdef _SCO_DS
6280/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
6281 needed definitions in sys/statvfs.h */
6282#define _SVID3
6283#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006284#include <sys/statvfs.h>
6285
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006286static PyObject*
6287_pystatvfs_fromstructstatvfs(struct statvfs st) {
6288 PyObject *v = PyStructSequence_New(&StatVFSResultType);
6289 if (v == NULL)
6290 return NULL;
6291
6292#if !defined(HAVE_LARGEFILE_SUPPORT)
6293 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6294 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
6295 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
6296 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
6297 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
6298 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
6299 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
6300 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
6301 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6302 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6303#else
6304 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6305 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00006306 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006307 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00006308 PyStructSequence_SET_ITEM(v, 3,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006309 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006310 PyStructSequence_SET_ITEM(v, 4,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006311 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00006312 PyStructSequence_SET_ITEM(v, 5,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006313 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00006314 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006315 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00006316 PyStructSequence_SET_ITEM(v, 7,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006317 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006318 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6319 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6320#endif
6321
6322 return v;
6323}
6324
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006325PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006326"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006327Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006328
6329static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006330posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006331{
6332 int fd, res;
6333 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006334
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006335 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006336 return NULL;
6337 Py_BEGIN_ALLOW_THREADS
6338 res = fstatvfs(fd, &st);
6339 Py_END_ALLOW_THREADS
6340 if (res != 0)
6341 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006342
6343 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006344}
6345#endif /* HAVE_FSTATVFS */
6346
6347
6348#if defined(HAVE_STATVFS)
6349#include <sys/statvfs.h>
6350
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006351PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006352"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006353Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006354
6355static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006356posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006357{
6358 char *path;
6359 int res;
6360 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006361 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006362 return NULL;
6363 Py_BEGIN_ALLOW_THREADS
6364 res = statvfs(path, &st);
6365 Py_END_ALLOW_THREADS
6366 if (res != 0)
6367 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006368
6369 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006370}
6371#endif /* HAVE_STATVFS */
6372
6373
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006374#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006375PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006376"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006377Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00006378The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006379or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006380
6381static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006382posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006383{
6384 PyObject *result = NULL;
6385 char *dir = NULL;
6386 char *pfx = NULL;
6387 char *name;
6388
6389 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
6390 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00006391
6392 if (PyErr_Warn(PyExc_RuntimeWarning,
6393 "tempnam is a potential security risk to your program") < 0)
6394 return NULL;
6395
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006396#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00006397 name = _tempnam(dir, pfx);
6398#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006399 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00006400#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006401 if (name == NULL)
6402 return PyErr_NoMemory();
6403 result = PyString_FromString(name);
6404 free(name);
6405 return result;
6406}
Guido van Rossumd371ff11999-01-25 16:12:23 +00006407#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006408
6409
6410#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006411PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006412"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006413Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006414
6415static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006416posix_tmpfile(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006417{
6418 FILE *fp;
6419
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006420 fp = tmpfile();
6421 if (fp == NULL)
6422 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00006423 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006424}
6425#endif
6426
6427
6428#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006429PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006430"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006431Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006432
6433static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006434posix_tmpnam(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006435{
6436 char buffer[L_tmpnam];
6437 char *name;
6438
Skip Montanaro95618b52001-08-18 18:52:10 +00006439 if (PyErr_Warn(PyExc_RuntimeWarning,
6440 "tmpnam is a potential security risk to your program") < 0)
6441 return NULL;
6442
Greg Wardb48bc172000-03-01 21:51:56 +00006443#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006444 name = tmpnam_r(buffer);
6445#else
6446 name = tmpnam(buffer);
6447#endif
6448 if (name == NULL) {
Neal Norwitzd1e0ef62006-03-20 04:08:12 +00006449 PyObject *err = Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00006450#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006451 "unexpected NULL from tmpnam_r"
6452#else
6453 "unexpected NULL from tmpnam"
6454#endif
Neal Norwitzd1e0ef62006-03-20 04:08:12 +00006455 );
6456 PyErr_SetObject(PyExc_OSError, err);
6457 Py_XDECREF(err);
6458 return NULL;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006459 }
6460 return PyString_FromString(buffer);
6461}
6462#endif
6463
6464
Fred Drakec9680921999-12-13 16:37:25 +00006465/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
6466 * It maps strings representing configuration variable names to
6467 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00006468 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00006469 * rarely-used constants. There are three separate tables that use
6470 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00006471 *
6472 * This code is always included, even if none of the interfaces that
6473 * need it are included. The #if hackery needed to avoid it would be
6474 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00006475 */
6476struct constdef {
6477 char *name;
6478 long value;
6479};
6480
Fred Drake12c6e2d1999-12-14 21:25:03 +00006481static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006482conv_confname(PyObject *arg, int *valuep, struct constdef *table,
6483 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006484{
6485 if (PyInt_Check(arg)) {
6486 *valuep = PyInt_AS_LONG(arg);
6487 return 1;
6488 }
6489 if (PyString_Check(arg)) {
6490 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00006491 size_t lo = 0;
6492 size_t mid;
6493 size_t hi = tablesize;
6494 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006495 char *confname = PyString_AS_STRING(arg);
6496 while (lo < hi) {
6497 mid = (lo + hi) / 2;
6498 cmp = strcmp(confname, table[mid].name);
6499 if (cmp < 0)
6500 hi = mid;
6501 else if (cmp > 0)
6502 lo = mid + 1;
6503 else {
6504 *valuep = table[mid].value;
6505 return 1;
6506 }
6507 }
6508 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
6509 }
6510 else
6511 PyErr_SetString(PyExc_TypeError,
6512 "configuration names must be strings or integers");
6513 return 0;
6514}
6515
6516
6517#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
6518static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006519#ifdef _PC_ABI_AIO_XFER_MAX
6520 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
6521#endif
6522#ifdef _PC_ABI_ASYNC_IO
6523 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
6524#endif
Fred Drakec9680921999-12-13 16:37:25 +00006525#ifdef _PC_ASYNC_IO
6526 {"PC_ASYNC_IO", _PC_ASYNC_IO},
6527#endif
6528#ifdef _PC_CHOWN_RESTRICTED
6529 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
6530#endif
6531#ifdef _PC_FILESIZEBITS
6532 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
6533#endif
6534#ifdef _PC_LAST
6535 {"PC_LAST", _PC_LAST},
6536#endif
6537#ifdef _PC_LINK_MAX
6538 {"PC_LINK_MAX", _PC_LINK_MAX},
6539#endif
6540#ifdef _PC_MAX_CANON
6541 {"PC_MAX_CANON", _PC_MAX_CANON},
6542#endif
6543#ifdef _PC_MAX_INPUT
6544 {"PC_MAX_INPUT", _PC_MAX_INPUT},
6545#endif
6546#ifdef _PC_NAME_MAX
6547 {"PC_NAME_MAX", _PC_NAME_MAX},
6548#endif
6549#ifdef _PC_NO_TRUNC
6550 {"PC_NO_TRUNC", _PC_NO_TRUNC},
6551#endif
6552#ifdef _PC_PATH_MAX
6553 {"PC_PATH_MAX", _PC_PATH_MAX},
6554#endif
6555#ifdef _PC_PIPE_BUF
6556 {"PC_PIPE_BUF", _PC_PIPE_BUF},
6557#endif
6558#ifdef _PC_PRIO_IO
6559 {"PC_PRIO_IO", _PC_PRIO_IO},
6560#endif
6561#ifdef _PC_SOCK_MAXBUF
6562 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
6563#endif
6564#ifdef _PC_SYNC_IO
6565 {"PC_SYNC_IO", _PC_SYNC_IO},
6566#endif
6567#ifdef _PC_VDISABLE
6568 {"PC_VDISABLE", _PC_VDISABLE},
6569#endif
6570};
6571
Fred Drakec9680921999-12-13 16:37:25 +00006572static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006573conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006574{
6575 return conv_confname(arg, valuep, posix_constants_pathconf,
6576 sizeof(posix_constants_pathconf)
6577 / sizeof(struct constdef));
6578}
6579#endif
6580
6581#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006582PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006583"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006584Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006585If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006586
6587static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006588posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006589{
6590 PyObject *result = NULL;
6591 int name, fd;
6592
Fred Drake12c6e2d1999-12-14 21:25:03 +00006593 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
6594 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00006595 long limit;
6596
6597 errno = 0;
6598 limit = fpathconf(fd, name);
6599 if (limit == -1 && errno != 0)
6600 posix_error();
6601 else
6602 result = PyInt_FromLong(limit);
6603 }
6604 return result;
6605}
6606#endif
6607
6608
6609#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006610PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006611"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006612Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006613If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006614
6615static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006616posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006617{
6618 PyObject *result = NULL;
6619 int name;
6620 char *path;
6621
6622 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
6623 conv_path_confname, &name)) {
6624 long limit;
6625
6626 errno = 0;
6627 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006628 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00006629 if (errno == EINVAL)
6630 /* could be a path or name problem */
6631 posix_error();
6632 else
6633 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006634 }
Fred Drakec9680921999-12-13 16:37:25 +00006635 else
6636 result = PyInt_FromLong(limit);
6637 }
6638 return result;
6639}
6640#endif
6641
6642#ifdef HAVE_CONFSTR
6643static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006644#ifdef _CS_ARCHITECTURE
6645 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
6646#endif
6647#ifdef _CS_HOSTNAME
6648 {"CS_HOSTNAME", _CS_HOSTNAME},
6649#endif
6650#ifdef _CS_HW_PROVIDER
6651 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
6652#endif
6653#ifdef _CS_HW_SERIAL
6654 {"CS_HW_SERIAL", _CS_HW_SERIAL},
6655#endif
6656#ifdef _CS_INITTAB_NAME
6657 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
6658#endif
Fred Drakec9680921999-12-13 16:37:25 +00006659#ifdef _CS_LFS64_CFLAGS
6660 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
6661#endif
6662#ifdef _CS_LFS64_LDFLAGS
6663 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
6664#endif
6665#ifdef _CS_LFS64_LIBS
6666 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
6667#endif
6668#ifdef _CS_LFS64_LINTFLAGS
6669 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
6670#endif
6671#ifdef _CS_LFS_CFLAGS
6672 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
6673#endif
6674#ifdef _CS_LFS_LDFLAGS
6675 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
6676#endif
6677#ifdef _CS_LFS_LIBS
6678 {"CS_LFS_LIBS", _CS_LFS_LIBS},
6679#endif
6680#ifdef _CS_LFS_LINTFLAGS
6681 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
6682#endif
Fred Draked86ed291999-12-15 15:34:33 +00006683#ifdef _CS_MACHINE
6684 {"CS_MACHINE", _CS_MACHINE},
6685#endif
Fred Drakec9680921999-12-13 16:37:25 +00006686#ifdef _CS_PATH
6687 {"CS_PATH", _CS_PATH},
6688#endif
Fred Draked86ed291999-12-15 15:34:33 +00006689#ifdef _CS_RELEASE
6690 {"CS_RELEASE", _CS_RELEASE},
6691#endif
6692#ifdef _CS_SRPC_DOMAIN
6693 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
6694#endif
6695#ifdef _CS_SYSNAME
6696 {"CS_SYSNAME", _CS_SYSNAME},
6697#endif
6698#ifdef _CS_VERSION
6699 {"CS_VERSION", _CS_VERSION},
6700#endif
Fred Drakec9680921999-12-13 16:37:25 +00006701#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
6702 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
6703#endif
6704#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
6705 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
6706#endif
6707#ifdef _CS_XBS5_ILP32_OFF32_LIBS
6708 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
6709#endif
6710#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
6711 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
6712#endif
6713#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
6714 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
6715#endif
6716#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
6717 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
6718#endif
6719#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
6720 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
6721#endif
6722#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
6723 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
6724#endif
6725#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
6726 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
6727#endif
6728#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
6729 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
6730#endif
6731#ifdef _CS_XBS5_LP64_OFF64_LIBS
6732 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
6733#endif
6734#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
6735 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
6736#endif
6737#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
6738 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
6739#endif
6740#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
6741 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
6742#endif
6743#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
6744 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
6745#endif
6746#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
6747 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
6748#endif
Fred Draked86ed291999-12-15 15:34:33 +00006749#ifdef _MIPS_CS_AVAIL_PROCESSORS
6750 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
6751#endif
6752#ifdef _MIPS_CS_BASE
6753 {"MIPS_CS_BASE", _MIPS_CS_BASE},
6754#endif
6755#ifdef _MIPS_CS_HOSTID
6756 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
6757#endif
6758#ifdef _MIPS_CS_HW_NAME
6759 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
6760#endif
6761#ifdef _MIPS_CS_NUM_PROCESSORS
6762 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
6763#endif
6764#ifdef _MIPS_CS_OSREL_MAJ
6765 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
6766#endif
6767#ifdef _MIPS_CS_OSREL_MIN
6768 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
6769#endif
6770#ifdef _MIPS_CS_OSREL_PATCH
6771 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
6772#endif
6773#ifdef _MIPS_CS_OS_NAME
6774 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
6775#endif
6776#ifdef _MIPS_CS_OS_PROVIDER
6777 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
6778#endif
6779#ifdef _MIPS_CS_PROCESSORS
6780 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
6781#endif
6782#ifdef _MIPS_CS_SERIAL
6783 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
6784#endif
6785#ifdef _MIPS_CS_VENDOR
6786 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
6787#endif
Fred Drakec9680921999-12-13 16:37:25 +00006788};
6789
6790static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006791conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006792{
6793 return conv_confname(arg, valuep, posix_constants_confstr,
6794 sizeof(posix_constants_confstr)
6795 / sizeof(struct constdef));
6796}
6797
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006798PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006799"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006800Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006801
6802static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006803posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006804{
6805 PyObject *result = NULL;
6806 int name;
6807 char buffer[64];
6808
6809 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
6810 int len = confstr(name, buffer, sizeof(buffer));
6811
Fred Drakec9680921999-12-13 16:37:25 +00006812 errno = 0;
6813 if (len == 0) {
6814 if (errno != 0)
6815 posix_error();
6816 else
6817 result = PyString_FromString("");
6818 }
6819 else {
6820 if (len >= sizeof(buffer)) {
6821 result = PyString_FromStringAndSize(NULL, len);
6822 if (result != NULL)
6823 confstr(name, PyString_AS_STRING(result), len+1);
6824 }
6825 else
6826 result = PyString_FromString(buffer);
6827 }
6828 }
6829 return result;
6830}
6831#endif
6832
6833
6834#ifdef HAVE_SYSCONF
6835static struct constdef posix_constants_sysconf[] = {
6836#ifdef _SC_2_CHAR_TERM
6837 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
6838#endif
6839#ifdef _SC_2_C_BIND
6840 {"SC_2_C_BIND", _SC_2_C_BIND},
6841#endif
6842#ifdef _SC_2_C_DEV
6843 {"SC_2_C_DEV", _SC_2_C_DEV},
6844#endif
6845#ifdef _SC_2_C_VERSION
6846 {"SC_2_C_VERSION", _SC_2_C_VERSION},
6847#endif
6848#ifdef _SC_2_FORT_DEV
6849 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
6850#endif
6851#ifdef _SC_2_FORT_RUN
6852 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
6853#endif
6854#ifdef _SC_2_LOCALEDEF
6855 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
6856#endif
6857#ifdef _SC_2_SW_DEV
6858 {"SC_2_SW_DEV", _SC_2_SW_DEV},
6859#endif
6860#ifdef _SC_2_UPE
6861 {"SC_2_UPE", _SC_2_UPE},
6862#endif
6863#ifdef _SC_2_VERSION
6864 {"SC_2_VERSION", _SC_2_VERSION},
6865#endif
Fred Draked86ed291999-12-15 15:34:33 +00006866#ifdef _SC_ABI_ASYNCHRONOUS_IO
6867 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
6868#endif
6869#ifdef _SC_ACL
6870 {"SC_ACL", _SC_ACL},
6871#endif
Fred Drakec9680921999-12-13 16:37:25 +00006872#ifdef _SC_AIO_LISTIO_MAX
6873 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
6874#endif
Fred Drakec9680921999-12-13 16:37:25 +00006875#ifdef _SC_AIO_MAX
6876 {"SC_AIO_MAX", _SC_AIO_MAX},
6877#endif
6878#ifdef _SC_AIO_PRIO_DELTA_MAX
6879 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
6880#endif
6881#ifdef _SC_ARG_MAX
6882 {"SC_ARG_MAX", _SC_ARG_MAX},
6883#endif
6884#ifdef _SC_ASYNCHRONOUS_IO
6885 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
6886#endif
6887#ifdef _SC_ATEXIT_MAX
6888 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
6889#endif
Fred Draked86ed291999-12-15 15:34:33 +00006890#ifdef _SC_AUDIT
6891 {"SC_AUDIT", _SC_AUDIT},
6892#endif
Fred Drakec9680921999-12-13 16:37:25 +00006893#ifdef _SC_AVPHYS_PAGES
6894 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
6895#endif
6896#ifdef _SC_BC_BASE_MAX
6897 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
6898#endif
6899#ifdef _SC_BC_DIM_MAX
6900 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
6901#endif
6902#ifdef _SC_BC_SCALE_MAX
6903 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
6904#endif
6905#ifdef _SC_BC_STRING_MAX
6906 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
6907#endif
Fred Draked86ed291999-12-15 15:34:33 +00006908#ifdef _SC_CAP
6909 {"SC_CAP", _SC_CAP},
6910#endif
Fred Drakec9680921999-12-13 16:37:25 +00006911#ifdef _SC_CHARCLASS_NAME_MAX
6912 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
6913#endif
6914#ifdef _SC_CHAR_BIT
6915 {"SC_CHAR_BIT", _SC_CHAR_BIT},
6916#endif
6917#ifdef _SC_CHAR_MAX
6918 {"SC_CHAR_MAX", _SC_CHAR_MAX},
6919#endif
6920#ifdef _SC_CHAR_MIN
6921 {"SC_CHAR_MIN", _SC_CHAR_MIN},
6922#endif
6923#ifdef _SC_CHILD_MAX
6924 {"SC_CHILD_MAX", _SC_CHILD_MAX},
6925#endif
6926#ifdef _SC_CLK_TCK
6927 {"SC_CLK_TCK", _SC_CLK_TCK},
6928#endif
6929#ifdef _SC_COHER_BLKSZ
6930 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
6931#endif
6932#ifdef _SC_COLL_WEIGHTS_MAX
6933 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
6934#endif
6935#ifdef _SC_DCACHE_ASSOC
6936 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
6937#endif
6938#ifdef _SC_DCACHE_BLKSZ
6939 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
6940#endif
6941#ifdef _SC_DCACHE_LINESZ
6942 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
6943#endif
6944#ifdef _SC_DCACHE_SZ
6945 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
6946#endif
6947#ifdef _SC_DCACHE_TBLKSZ
6948 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
6949#endif
6950#ifdef _SC_DELAYTIMER_MAX
6951 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
6952#endif
6953#ifdef _SC_EQUIV_CLASS_MAX
6954 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
6955#endif
6956#ifdef _SC_EXPR_NEST_MAX
6957 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
6958#endif
6959#ifdef _SC_FSYNC
6960 {"SC_FSYNC", _SC_FSYNC},
6961#endif
6962#ifdef _SC_GETGR_R_SIZE_MAX
6963 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
6964#endif
6965#ifdef _SC_GETPW_R_SIZE_MAX
6966 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
6967#endif
6968#ifdef _SC_ICACHE_ASSOC
6969 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
6970#endif
6971#ifdef _SC_ICACHE_BLKSZ
6972 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
6973#endif
6974#ifdef _SC_ICACHE_LINESZ
6975 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
6976#endif
6977#ifdef _SC_ICACHE_SZ
6978 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
6979#endif
Fred Draked86ed291999-12-15 15:34:33 +00006980#ifdef _SC_INF
6981 {"SC_INF", _SC_INF},
6982#endif
Fred Drakec9680921999-12-13 16:37:25 +00006983#ifdef _SC_INT_MAX
6984 {"SC_INT_MAX", _SC_INT_MAX},
6985#endif
6986#ifdef _SC_INT_MIN
6987 {"SC_INT_MIN", _SC_INT_MIN},
6988#endif
6989#ifdef _SC_IOV_MAX
6990 {"SC_IOV_MAX", _SC_IOV_MAX},
6991#endif
Fred Draked86ed291999-12-15 15:34:33 +00006992#ifdef _SC_IP_SECOPTS
6993 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
6994#endif
Fred Drakec9680921999-12-13 16:37:25 +00006995#ifdef _SC_JOB_CONTROL
6996 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
6997#endif
Fred Draked86ed291999-12-15 15:34:33 +00006998#ifdef _SC_KERN_POINTERS
6999 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
7000#endif
7001#ifdef _SC_KERN_SIM
7002 {"SC_KERN_SIM", _SC_KERN_SIM},
7003#endif
Fred Drakec9680921999-12-13 16:37:25 +00007004#ifdef _SC_LINE_MAX
7005 {"SC_LINE_MAX", _SC_LINE_MAX},
7006#endif
7007#ifdef _SC_LOGIN_NAME_MAX
7008 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
7009#endif
7010#ifdef _SC_LOGNAME_MAX
7011 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
7012#endif
7013#ifdef _SC_LONG_BIT
7014 {"SC_LONG_BIT", _SC_LONG_BIT},
7015#endif
Fred Draked86ed291999-12-15 15:34:33 +00007016#ifdef _SC_MAC
7017 {"SC_MAC", _SC_MAC},
7018#endif
Fred Drakec9680921999-12-13 16:37:25 +00007019#ifdef _SC_MAPPED_FILES
7020 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
7021#endif
7022#ifdef _SC_MAXPID
7023 {"SC_MAXPID", _SC_MAXPID},
7024#endif
7025#ifdef _SC_MB_LEN_MAX
7026 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
7027#endif
7028#ifdef _SC_MEMLOCK
7029 {"SC_MEMLOCK", _SC_MEMLOCK},
7030#endif
7031#ifdef _SC_MEMLOCK_RANGE
7032 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
7033#endif
7034#ifdef _SC_MEMORY_PROTECTION
7035 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
7036#endif
7037#ifdef _SC_MESSAGE_PASSING
7038 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
7039#endif
Fred Draked86ed291999-12-15 15:34:33 +00007040#ifdef _SC_MMAP_FIXED_ALIGNMENT
7041 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
7042#endif
Fred Drakec9680921999-12-13 16:37:25 +00007043#ifdef _SC_MQ_OPEN_MAX
7044 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
7045#endif
7046#ifdef _SC_MQ_PRIO_MAX
7047 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
7048#endif
Fred Draked86ed291999-12-15 15:34:33 +00007049#ifdef _SC_NACLS_MAX
7050 {"SC_NACLS_MAX", _SC_NACLS_MAX},
7051#endif
Fred Drakec9680921999-12-13 16:37:25 +00007052#ifdef _SC_NGROUPS_MAX
7053 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
7054#endif
7055#ifdef _SC_NL_ARGMAX
7056 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
7057#endif
7058#ifdef _SC_NL_LANGMAX
7059 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
7060#endif
7061#ifdef _SC_NL_MSGMAX
7062 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
7063#endif
7064#ifdef _SC_NL_NMAX
7065 {"SC_NL_NMAX", _SC_NL_NMAX},
7066#endif
7067#ifdef _SC_NL_SETMAX
7068 {"SC_NL_SETMAX", _SC_NL_SETMAX},
7069#endif
7070#ifdef _SC_NL_TEXTMAX
7071 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
7072#endif
7073#ifdef _SC_NPROCESSORS_CONF
7074 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
7075#endif
7076#ifdef _SC_NPROCESSORS_ONLN
7077 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
7078#endif
Fred Draked86ed291999-12-15 15:34:33 +00007079#ifdef _SC_NPROC_CONF
7080 {"SC_NPROC_CONF", _SC_NPROC_CONF},
7081#endif
7082#ifdef _SC_NPROC_ONLN
7083 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
7084#endif
Fred Drakec9680921999-12-13 16:37:25 +00007085#ifdef _SC_NZERO
7086 {"SC_NZERO", _SC_NZERO},
7087#endif
7088#ifdef _SC_OPEN_MAX
7089 {"SC_OPEN_MAX", _SC_OPEN_MAX},
7090#endif
7091#ifdef _SC_PAGESIZE
7092 {"SC_PAGESIZE", _SC_PAGESIZE},
7093#endif
7094#ifdef _SC_PAGE_SIZE
7095 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
7096#endif
7097#ifdef _SC_PASS_MAX
7098 {"SC_PASS_MAX", _SC_PASS_MAX},
7099#endif
7100#ifdef _SC_PHYS_PAGES
7101 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
7102#endif
7103#ifdef _SC_PII
7104 {"SC_PII", _SC_PII},
7105#endif
7106#ifdef _SC_PII_INTERNET
7107 {"SC_PII_INTERNET", _SC_PII_INTERNET},
7108#endif
7109#ifdef _SC_PII_INTERNET_DGRAM
7110 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
7111#endif
7112#ifdef _SC_PII_INTERNET_STREAM
7113 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
7114#endif
7115#ifdef _SC_PII_OSI
7116 {"SC_PII_OSI", _SC_PII_OSI},
7117#endif
7118#ifdef _SC_PII_OSI_CLTS
7119 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
7120#endif
7121#ifdef _SC_PII_OSI_COTS
7122 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
7123#endif
7124#ifdef _SC_PII_OSI_M
7125 {"SC_PII_OSI_M", _SC_PII_OSI_M},
7126#endif
7127#ifdef _SC_PII_SOCKET
7128 {"SC_PII_SOCKET", _SC_PII_SOCKET},
7129#endif
7130#ifdef _SC_PII_XTI
7131 {"SC_PII_XTI", _SC_PII_XTI},
7132#endif
7133#ifdef _SC_POLL
7134 {"SC_POLL", _SC_POLL},
7135#endif
7136#ifdef _SC_PRIORITIZED_IO
7137 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
7138#endif
7139#ifdef _SC_PRIORITY_SCHEDULING
7140 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
7141#endif
7142#ifdef _SC_REALTIME_SIGNALS
7143 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
7144#endif
7145#ifdef _SC_RE_DUP_MAX
7146 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
7147#endif
7148#ifdef _SC_RTSIG_MAX
7149 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
7150#endif
7151#ifdef _SC_SAVED_IDS
7152 {"SC_SAVED_IDS", _SC_SAVED_IDS},
7153#endif
7154#ifdef _SC_SCHAR_MAX
7155 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
7156#endif
7157#ifdef _SC_SCHAR_MIN
7158 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
7159#endif
7160#ifdef _SC_SELECT
7161 {"SC_SELECT", _SC_SELECT},
7162#endif
7163#ifdef _SC_SEMAPHORES
7164 {"SC_SEMAPHORES", _SC_SEMAPHORES},
7165#endif
7166#ifdef _SC_SEM_NSEMS_MAX
7167 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
7168#endif
7169#ifdef _SC_SEM_VALUE_MAX
7170 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
7171#endif
7172#ifdef _SC_SHARED_MEMORY_OBJECTS
7173 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
7174#endif
7175#ifdef _SC_SHRT_MAX
7176 {"SC_SHRT_MAX", _SC_SHRT_MAX},
7177#endif
7178#ifdef _SC_SHRT_MIN
7179 {"SC_SHRT_MIN", _SC_SHRT_MIN},
7180#endif
7181#ifdef _SC_SIGQUEUE_MAX
7182 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
7183#endif
7184#ifdef _SC_SIGRT_MAX
7185 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
7186#endif
7187#ifdef _SC_SIGRT_MIN
7188 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
7189#endif
Fred Draked86ed291999-12-15 15:34:33 +00007190#ifdef _SC_SOFTPOWER
7191 {"SC_SOFTPOWER", _SC_SOFTPOWER},
7192#endif
Fred Drakec9680921999-12-13 16:37:25 +00007193#ifdef _SC_SPLIT_CACHE
7194 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
7195#endif
7196#ifdef _SC_SSIZE_MAX
7197 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
7198#endif
7199#ifdef _SC_STACK_PROT
7200 {"SC_STACK_PROT", _SC_STACK_PROT},
7201#endif
7202#ifdef _SC_STREAM_MAX
7203 {"SC_STREAM_MAX", _SC_STREAM_MAX},
7204#endif
7205#ifdef _SC_SYNCHRONIZED_IO
7206 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
7207#endif
7208#ifdef _SC_THREADS
7209 {"SC_THREADS", _SC_THREADS},
7210#endif
7211#ifdef _SC_THREAD_ATTR_STACKADDR
7212 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
7213#endif
7214#ifdef _SC_THREAD_ATTR_STACKSIZE
7215 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
7216#endif
7217#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
7218 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
7219#endif
7220#ifdef _SC_THREAD_KEYS_MAX
7221 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
7222#endif
7223#ifdef _SC_THREAD_PRIORITY_SCHEDULING
7224 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
7225#endif
7226#ifdef _SC_THREAD_PRIO_INHERIT
7227 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
7228#endif
7229#ifdef _SC_THREAD_PRIO_PROTECT
7230 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
7231#endif
7232#ifdef _SC_THREAD_PROCESS_SHARED
7233 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
7234#endif
7235#ifdef _SC_THREAD_SAFE_FUNCTIONS
7236 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
7237#endif
7238#ifdef _SC_THREAD_STACK_MIN
7239 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
7240#endif
7241#ifdef _SC_THREAD_THREADS_MAX
7242 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
7243#endif
7244#ifdef _SC_TIMERS
7245 {"SC_TIMERS", _SC_TIMERS},
7246#endif
7247#ifdef _SC_TIMER_MAX
7248 {"SC_TIMER_MAX", _SC_TIMER_MAX},
7249#endif
7250#ifdef _SC_TTY_NAME_MAX
7251 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
7252#endif
7253#ifdef _SC_TZNAME_MAX
7254 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
7255#endif
7256#ifdef _SC_T_IOV_MAX
7257 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
7258#endif
7259#ifdef _SC_UCHAR_MAX
7260 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
7261#endif
7262#ifdef _SC_UINT_MAX
7263 {"SC_UINT_MAX", _SC_UINT_MAX},
7264#endif
7265#ifdef _SC_UIO_MAXIOV
7266 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
7267#endif
7268#ifdef _SC_ULONG_MAX
7269 {"SC_ULONG_MAX", _SC_ULONG_MAX},
7270#endif
7271#ifdef _SC_USHRT_MAX
7272 {"SC_USHRT_MAX", _SC_USHRT_MAX},
7273#endif
7274#ifdef _SC_VERSION
7275 {"SC_VERSION", _SC_VERSION},
7276#endif
7277#ifdef _SC_WORD_BIT
7278 {"SC_WORD_BIT", _SC_WORD_BIT},
7279#endif
7280#ifdef _SC_XBS5_ILP32_OFF32
7281 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
7282#endif
7283#ifdef _SC_XBS5_ILP32_OFFBIG
7284 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
7285#endif
7286#ifdef _SC_XBS5_LP64_OFF64
7287 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
7288#endif
7289#ifdef _SC_XBS5_LPBIG_OFFBIG
7290 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
7291#endif
7292#ifdef _SC_XOPEN_CRYPT
7293 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
7294#endif
7295#ifdef _SC_XOPEN_ENH_I18N
7296 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
7297#endif
7298#ifdef _SC_XOPEN_LEGACY
7299 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
7300#endif
7301#ifdef _SC_XOPEN_REALTIME
7302 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
7303#endif
7304#ifdef _SC_XOPEN_REALTIME_THREADS
7305 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
7306#endif
7307#ifdef _SC_XOPEN_SHM
7308 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
7309#endif
7310#ifdef _SC_XOPEN_UNIX
7311 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
7312#endif
7313#ifdef _SC_XOPEN_VERSION
7314 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
7315#endif
7316#ifdef _SC_XOPEN_XCU_VERSION
7317 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
7318#endif
7319#ifdef _SC_XOPEN_XPG2
7320 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
7321#endif
7322#ifdef _SC_XOPEN_XPG3
7323 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
7324#endif
7325#ifdef _SC_XOPEN_XPG4
7326 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
7327#endif
7328};
7329
7330static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007331conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007332{
7333 return conv_confname(arg, valuep, posix_constants_sysconf,
7334 sizeof(posix_constants_sysconf)
7335 / sizeof(struct constdef));
7336}
7337
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007338PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007339"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007340Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007341
7342static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007343posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007344{
7345 PyObject *result = NULL;
7346 int name;
7347
7348 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
7349 int value;
7350
7351 errno = 0;
7352 value = sysconf(name);
7353 if (value == -1 && errno != 0)
7354 posix_error();
7355 else
7356 result = PyInt_FromLong(value);
7357 }
7358 return result;
7359}
7360#endif
7361
7362
Fred Drakebec628d1999-12-15 18:31:10 +00007363/* This code is used to ensure that the tables of configuration value names
7364 * are in sorted order as required by conv_confname(), and also to build the
7365 * the exported dictionaries that are used to publish information about the
7366 * names available on the host platform.
7367 *
7368 * Sorting the table at runtime ensures that the table is properly ordered
7369 * when used, even for platforms we're not able to test on. It also makes
7370 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00007371 */
Fred Drakebec628d1999-12-15 18:31:10 +00007372
7373static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007374cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00007375{
7376 const struct constdef *c1 =
7377 (const struct constdef *) v1;
7378 const struct constdef *c2 =
7379 (const struct constdef *) v2;
7380
7381 return strcmp(c1->name, c2->name);
7382}
7383
7384static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007385setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00007386 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007387{
Fred Drakebec628d1999-12-15 18:31:10 +00007388 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00007389 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00007390
7391 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
7392 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00007393 if (d == NULL)
7394 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007395
Barry Warsaw3155db32000-04-13 15:20:40 +00007396 for (i=0; i < tablesize; ++i) {
7397 PyObject *o = PyInt_FromLong(table[i].value);
7398 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
7399 Py_XDECREF(o);
7400 Py_DECREF(d);
7401 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007402 }
Barry Warsaw3155db32000-04-13 15:20:40 +00007403 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00007404 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00007405 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00007406}
7407
Fred Drakebec628d1999-12-15 18:31:10 +00007408/* Return -1 on failure, 0 on success. */
7409static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007410setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007411{
7412#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00007413 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00007414 sizeof(posix_constants_pathconf)
7415 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007416 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007417 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007418#endif
7419#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00007420 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00007421 sizeof(posix_constants_confstr)
7422 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007423 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007424 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007425#endif
7426#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00007427 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00007428 sizeof(posix_constants_sysconf)
7429 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007430 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007431 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007432#endif
Fred Drakebec628d1999-12-15 18:31:10 +00007433 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00007434}
Fred Draked86ed291999-12-15 15:34:33 +00007435
7436
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007437PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007438"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007439Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007440in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007441
7442static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007443posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007444{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007445 abort();
7446 /*NOTREACHED*/
7447 Py_FatalError("abort() called from Python code didn't abort!");
7448 return NULL;
7449}
Fred Drakebec628d1999-12-15 18:31:10 +00007450
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007451#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007452PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00007453"startfile(filepath [, operation]) - Start a file with its associated\n\
7454application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007455\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00007456When \"operation\" is not specified or \"open\", this acts like\n\
7457double-clicking the file in Explorer, or giving the file name as an\n\
7458argument to the DOS \"start\" command: the file is opened with whatever\n\
7459application (if any) its extension is associated.\n\
7460When another \"operation\" is given, it specifies what should be done with\n\
7461the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007462\n\
7463startfile returns as soon as the associated application is launched.\n\
7464There is no option to wait for the application to close, and no way\n\
7465to retrieve the application's exit status.\n\
7466\n\
7467The filepath is relative to the current directory. If you want to use\n\
7468an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007469the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00007470
7471static PyObject *
7472win32_startfile(PyObject *self, PyObject *args)
7473{
7474 char *filepath;
Georg Brandlf4f44152006-02-18 22:29:33 +00007475 char *operation = NULL;
Tim Petersf58a7aa2000-09-22 10:05:54 +00007476 HINSTANCE rc;
Georg Brandlad89dc82006-04-03 12:26:26 +00007477#ifdef Py_WIN_WIDE_FILENAMES
7478 if (unicode_file_names()) {
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00007479 PyObject *unipath, *woperation = NULL;
Georg Brandlad89dc82006-04-03 12:26:26 +00007480 if (!PyArg_ParseTuple(args, "U|s:startfile",
7481 &unipath, &operation)) {
7482 PyErr_Clear();
7483 goto normal;
7484 }
7485
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00007486
7487 if (operation) {
7488 woperation = PyUnicode_DecodeASCII(operation,
7489 strlen(operation), NULL);
7490 if (!woperation) {
7491 PyErr_Clear();
7492 operation = NULL;
7493 goto normal;
7494 }
Georg Brandlad89dc82006-04-03 12:26:26 +00007495 }
7496
7497 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00007498 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
Georg Brandlad89dc82006-04-03 12:26:26 +00007499 PyUnicode_AS_UNICODE(unipath),
Georg Brandlad89dc82006-04-03 12:26:26 +00007500 NULL, NULL, SW_SHOWNORMAL);
7501 Py_END_ALLOW_THREADS
7502
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00007503 Py_XDECREF(woperation);
Georg Brandlad89dc82006-04-03 12:26:26 +00007504 if (rc <= (HINSTANCE)32) {
7505 PyObject *errval = win32_error_unicode("startfile",
7506 PyUnicode_AS_UNICODE(unipath));
7507 return errval;
7508 }
7509 Py_INCREF(Py_None);
7510 return Py_None;
7511 }
7512#endif
7513
7514normal:
Georg Brandlf4f44152006-02-18 22:29:33 +00007515 if (!PyArg_ParseTuple(args, "et|s:startfile",
7516 Py_FileSystemDefaultEncoding, &filepath,
7517 &operation))
Tim Petersf58a7aa2000-09-22 10:05:54 +00007518 return NULL;
7519 Py_BEGIN_ALLOW_THREADS
Georg Brandlf4f44152006-02-18 22:29:33 +00007520 rc = ShellExecute((HWND)0, operation, filepath,
7521 NULL, NULL, SW_SHOWNORMAL);
Tim Petersf58a7aa2000-09-22 10:05:54 +00007522 Py_END_ALLOW_THREADS
Georg Brandle9f8ec92005-09-25 06:16:40 +00007523 if (rc <= (HINSTANCE)32) {
7524 PyObject *errval = win32_error("startfile", filepath);
7525 PyMem_Free(filepath);
7526 return errval;
7527 }
7528 PyMem_Free(filepath);
Tim Petersf58a7aa2000-09-22 10:05:54 +00007529 Py_INCREF(Py_None);
7530 return Py_None;
7531}
7532#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007533
Martin v. Löwis438b5342002-12-27 10:16:42 +00007534#ifdef HAVE_GETLOADAVG
7535PyDoc_STRVAR(posix_getloadavg__doc__,
7536"getloadavg() -> (float, float, float)\n\n\
7537Return the number of processes in the system run queue averaged over\n\
7538the last 1, 5, and 15 minutes or raises OSError if the load average\n\
7539was unobtainable");
7540
7541static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007542posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00007543{
7544 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00007545 if (getloadavg(loadavg, 3)!=3) {
7546 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
7547 return NULL;
7548 } else
7549 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
7550}
7551#endif
7552
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007553#ifdef MS_WINDOWS
7554
7555PyDoc_STRVAR(win32_urandom__doc__,
7556"urandom(n) -> str\n\n\
7557Return a string of n random bytes suitable for cryptographic use.");
7558
7559typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
7560 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
7561 DWORD dwFlags );
7562typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
7563 BYTE *pbBuffer );
7564
7565static CRYPTGENRANDOM pCryptGenRandom = NULL;
7566static HCRYPTPROV hCryptProv = 0;
7567
Tim Peters4ad82172004-08-30 17:02:04 +00007568static PyObject*
7569win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007570{
Tim Petersd3115382004-08-30 17:36:46 +00007571 int howMany;
7572 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007573
Tim Peters4ad82172004-08-30 17:02:04 +00007574 /* Read arguments */
Tim Peters9b279a82004-08-30 17:10:53 +00007575 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
Tim Peters4ad82172004-08-30 17:02:04 +00007576 return NULL;
Tim Peters51eba612004-08-30 17:08:02 +00007577 if (howMany < 0)
7578 return PyErr_Format(PyExc_ValueError,
7579 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007580
Tim Peters4ad82172004-08-30 17:02:04 +00007581 if (hCryptProv == 0) {
7582 HINSTANCE hAdvAPI32 = NULL;
7583 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007584
Tim Peters4ad82172004-08-30 17:02:04 +00007585 /* Obtain handle to the DLL containing CryptoAPI
7586 This should not fail */
7587 hAdvAPI32 = GetModuleHandle("advapi32.dll");
7588 if(hAdvAPI32 == NULL)
7589 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007590
Tim Peters4ad82172004-08-30 17:02:04 +00007591 /* Obtain pointers to the CryptoAPI functions
7592 This will fail on some early versions of Win95 */
7593 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
7594 hAdvAPI32,
7595 "CryptAcquireContextA");
7596 if (pCryptAcquireContext == NULL)
7597 return PyErr_Format(PyExc_NotImplementedError,
7598 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007599
Tim Peters4ad82172004-08-30 17:02:04 +00007600 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
7601 hAdvAPI32, "CryptGenRandom");
7602 if (pCryptAcquireContext == NULL)
7603 return PyErr_Format(PyExc_NotImplementedError,
7604 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007605
Tim Peters4ad82172004-08-30 17:02:04 +00007606 /* Acquire context */
7607 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
7608 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
7609 return win32_error("CryptAcquireContext", NULL);
7610 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007611
Tim Peters4ad82172004-08-30 17:02:04 +00007612 /* Allocate bytes */
Tim Petersd3115382004-08-30 17:36:46 +00007613 result = PyString_FromStringAndSize(NULL, howMany);
7614 if (result != NULL) {
7615 /* Get random data */
7616 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
7617 PyString_AS_STRING(result))) {
7618 Py_DECREF(result);
7619 return win32_error("CryptGenRandom", NULL);
7620 }
Tim Peters4ad82172004-08-30 17:02:04 +00007621 }
Tim Petersd3115382004-08-30 17:36:46 +00007622 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007623}
7624#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007625
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007626static PyMethodDef posix_methods[] = {
7627 {"access", posix_access, METH_VARARGS, posix_access__doc__},
7628#ifdef HAVE_TTYNAME
7629 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
7630#endif
7631 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
7632 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007633#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007634 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007635#endif /* HAVE_CHOWN */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007636#ifdef HAVE_LCHOWN
7637 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
7638#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00007639#ifdef HAVE_CHROOT
7640 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
7641#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007642#ifdef HAVE_CTERMID
Neal Norwitze241ce82003-02-17 18:17:05 +00007643 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007644#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00007645#ifdef HAVE_GETCWD
Neal Norwitze241ce82003-02-17 18:17:05 +00007646 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Walter Dörwald3b918c32002-11-21 20:18:46 +00007647#ifdef Py_USING_UNICODE
Neal Norwitze241ce82003-02-17 18:17:05 +00007648 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00007649#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00007650#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007651#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007652 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007653#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007654 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
7655 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
7656 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007657#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007658 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007659#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007660#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007661 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007662#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007663 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
7664 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
7665 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007666 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007667#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007668 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007669#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007670#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007671 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007672#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007673 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007674#ifdef HAVE_UNAME
Neal Norwitze241ce82003-02-17 18:17:05 +00007675 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007676#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007677 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
7678 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
7679 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007680#ifdef HAVE_TIMES
Neal Norwitze241ce82003-02-17 18:17:05 +00007681 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007682#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007683 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007684#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007685 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
7686 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007687#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00007688#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007689 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
7690 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00007691#if defined(PYOS_OS2)
7692 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
7693 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
7694#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00007695#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007696#ifdef HAVE_FORK1
Neal Norwitze241ce82003-02-17 18:17:05 +00007697 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007698#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007699#ifdef HAVE_FORK
Neal Norwitze241ce82003-02-17 18:17:05 +00007700 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007701#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007702#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Neal Norwitze241ce82003-02-17 18:17:05 +00007703 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007704#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007705#ifdef HAVE_FORKPTY
Neal Norwitze241ce82003-02-17 18:17:05 +00007706 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00007707#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007708#ifdef HAVE_GETEGID
Neal Norwitze241ce82003-02-17 18:17:05 +00007709 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007710#endif /* HAVE_GETEGID */
7711#ifdef HAVE_GETEUID
Neal Norwitze241ce82003-02-17 18:17:05 +00007712 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007713#endif /* HAVE_GETEUID */
7714#ifdef HAVE_GETGID
Neal Norwitze241ce82003-02-17 18:17:05 +00007715 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007716#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00007717#ifdef HAVE_GETGROUPS
Neal Norwitze241ce82003-02-17 18:17:05 +00007718 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007719#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007720 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007721#ifdef HAVE_GETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00007722 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007723#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007724#ifdef HAVE_GETPPID
Neal Norwitze241ce82003-02-17 18:17:05 +00007725 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007726#endif /* HAVE_GETPPID */
7727#ifdef HAVE_GETUID
Neal Norwitze241ce82003-02-17 18:17:05 +00007728 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007729#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007730#ifdef HAVE_GETLOGIN
Neal Norwitze241ce82003-02-17 18:17:05 +00007731 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00007732#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00007733#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007734 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007735#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007736#ifdef HAVE_KILLPG
7737 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
7738#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00007739#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007740 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00007741#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007742#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007743 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007744#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00007745 {"popen2", win32_popen2, METH_VARARGS},
7746 {"popen3", win32_popen3, METH_VARARGS},
7747 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00007748 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007749#else
7750#if defined(PYOS_OS2) && defined(PYCC_GCC)
7751 {"popen2", os2emx_popen2, METH_VARARGS},
7752 {"popen3", os2emx_popen3, METH_VARARGS},
7753 {"popen4", os2emx_popen4, METH_VARARGS},
7754#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00007755#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007756#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007757#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007758 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007759#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00007760#ifdef HAVE_SETEUID
7761 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
7762#endif /* HAVE_SETEUID */
7763#ifdef HAVE_SETEGID
7764 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
7765#endif /* HAVE_SETEGID */
7766#ifdef HAVE_SETREUID
7767 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
7768#endif /* HAVE_SETREUID */
7769#ifdef HAVE_SETREGID
7770 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
7771#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007772#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007773 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007774#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007775#ifdef HAVE_SETGROUPS
7776 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
7777#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00007778#ifdef HAVE_GETPGID
7779 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
7780#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007781#ifdef HAVE_SETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00007782 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007783#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007784#ifdef HAVE_WAIT
Neal Norwitze241ce82003-02-17 18:17:05 +00007785 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007786#endif /* HAVE_WAIT */
Neal Norwitz05a45592006-03-20 06:30:08 +00007787#ifdef HAVE_WAIT3
7788 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
7789#endif /* HAVE_WAIT3 */
7790#ifdef HAVE_WAIT4
7791 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
7792#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00007793#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007794 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007795#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007796#ifdef HAVE_GETSID
7797 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
7798#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007799#ifdef HAVE_SETSID
Neal Norwitze241ce82003-02-17 18:17:05 +00007800 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007801#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007802#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007803 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007804#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007805#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007806 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007807#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007808#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007809 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007810#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007811 {"open", posix_open, METH_VARARGS, posix_open__doc__},
7812 {"close", posix_close, METH_VARARGS, posix_close__doc__},
7813 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
7814 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
7815 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
7816 {"read", posix_read, METH_VARARGS, posix_read__doc__},
7817 {"write", posix_write, METH_VARARGS, posix_write__doc__},
7818 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
7819 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00007820 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007821#ifdef HAVE_PIPE
Neal Norwitze241ce82003-02-17 18:17:05 +00007822 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007823#endif
7824#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007825 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007826#endif
Neal Norwitz11690112002-07-30 01:08:28 +00007827#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007828 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
7829#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007830#ifdef HAVE_DEVICE_MACROS
7831 {"major", posix_major, METH_VARARGS, posix_major__doc__},
7832 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
7833 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
7834#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007835#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007836 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007837#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007838#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007839 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007840#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007841#ifdef HAVE_UNSETENV
7842 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
7843#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00007844#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007845 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00007846#endif
Fred Drake4d1e64b2002-04-15 19:40:07 +00007847#ifdef HAVE_FCHDIR
7848 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
7849#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00007850#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007851 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007852#endif
7853#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007854 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007855#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00007856#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00007857#ifdef WCOREDUMP
7858 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
7859#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007860#ifdef WIFCONTINUED
7861 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
7862#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00007863#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007864 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007865#endif /* WIFSTOPPED */
7866#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007867 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007868#endif /* WIFSIGNALED */
7869#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007870 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007871#endif /* WIFEXITED */
7872#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007873 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007874#endif /* WEXITSTATUS */
7875#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007876 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007877#endif /* WTERMSIG */
7878#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007879 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007880#endif /* WSTOPSIG */
7881#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007882#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007883 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007884#endif
7885#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007886 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007887#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00007888#ifdef HAVE_TMPFILE
Neal Norwitze241ce82003-02-17 18:17:05 +00007889 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007890#endif
7891#ifdef HAVE_TEMPNAM
7892 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
7893#endif
7894#ifdef HAVE_TMPNAM
Neal Norwitze241ce82003-02-17 18:17:05 +00007895 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007896#endif
Fred Drakec9680921999-12-13 16:37:25 +00007897#ifdef HAVE_CONFSTR
7898 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
7899#endif
7900#ifdef HAVE_SYSCONF
7901 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
7902#endif
7903#ifdef HAVE_FPATHCONF
7904 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
7905#endif
7906#ifdef HAVE_PATHCONF
7907 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
7908#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007909 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007910#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00007911 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
7912#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007913#ifdef HAVE_GETLOADAVG
Neal Norwitze241ce82003-02-17 18:17:05 +00007914 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00007915#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007916 #ifdef MS_WINDOWS
7917 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
7918 #endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007919 {NULL, NULL} /* Sentinel */
7920};
7921
7922
Barry Warsaw4a342091996-12-19 23:50:02 +00007923static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007924ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00007925{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007926 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00007927}
7928
Guido van Rossumd48f2521997-12-05 22:19:34 +00007929#if defined(PYOS_OS2)
7930/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007931static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007932{
7933 APIRET rc;
7934 ULONG values[QSV_MAX+1];
7935 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00007936 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00007937
7938 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00007939 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007940 Py_END_ALLOW_THREADS
7941
7942 if (rc != NO_ERROR) {
7943 os2_error(rc);
7944 return -1;
7945 }
7946
Fred Drake4d1e64b2002-04-15 19:40:07 +00007947 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
7948 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
7949 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
7950 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
7951 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
7952 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
7953 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007954
7955 switch (values[QSV_VERSION_MINOR]) {
7956 case 0: ver = "2.00"; break;
7957 case 10: ver = "2.10"; break;
7958 case 11: ver = "2.11"; break;
7959 case 30: ver = "3.00"; break;
7960 case 40: ver = "4.00"; break;
7961 case 50: ver = "5.00"; break;
7962 default:
Tim Peters885d4572001-11-28 20:27:42 +00007963 PyOS_snprintf(tmp, sizeof(tmp),
7964 "%d-%d", values[QSV_VERSION_MAJOR],
7965 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007966 ver = &tmp[0];
7967 }
7968
7969 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007970 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007971 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007972
7973 /* Add Indicator of Which Drive was Used to Boot the System */
7974 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
7975 tmp[1] = ':';
7976 tmp[2] = '\0';
7977
Fred Drake4d1e64b2002-04-15 19:40:07 +00007978 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007979}
7980#endif
7981
Barry Warsaw4a342091996-12-19 23:50:02 +00007982static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007983all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00007984{
Guido van Rossum94f6f721999-01-06 18:42:14 +00007985#ifdef F_OK
7986 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007987#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007988#ifdef R_OK
7989 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007990#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007991#ifdef W_OK
7992 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007993#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007994#ifdef X_OK
7995 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007996#endif
Fred Drakec9680921999-12-13 16:37:25 +00007997#ifdef NGROUPS_MAX
7998 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
7999#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008000#ifdef TMP_MAX
8001 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
8002#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008003#ifdef WCONTINUED
8004 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
8005#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008006#ifdef WNOHANG
8007 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008008#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008009#ifdef WUNTRACED
8010 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
8011#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008012#ifdef O_RDONLY
8013 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
8014#endif
8015#ifdef O_WRONLY
8016 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
8017#endif
8018#ifdef O_RDWR
8019 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
8020#endif
8021#ifdef O_NDELAY
8022 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
8023#endif
8024#ifdef O_NONBLOCK
8025 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
8026#endif
8027#ifdef O_APPEND
8028 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
8029#endif
8030#ifdef O_DSYNC
8031 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
8032#endif
8033#ifdef O_RSYNC
8034 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
8035#endif
8036#ifdef O_SYNC
8037 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
8038#endif
8039#ifdef O_NOCTTY
8040 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
8041#endif
8042#ifdef O_CREAT
8043 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
8044#endif
8045#ifdef O_EXCL
8046 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
8047#endif
8048#ifdef O_TRUNC
8049 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
8050#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00008051#ifdef O_BINARY
8052 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
8053#endif
8054#ifdef O_TEXT
8055 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
8056#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008057#ifdef O_LARGEFILE
8058 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
8059#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00008060#ifdef O_SHLOCK
8061 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
8062#endif
8063#ifdef O_EXLOCK
8064 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
8065#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008066
Tim Peters5aa91602002-01-30 05:46:57 +00008067/* MS Windows */
8068#ifdef O_NOINHERIT
8069 /* Don't inherit in child processes. */
8070 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
8071#endif
8072#ifdef _O_SHORT_LIVED
8073 /* Optimize for short life (keep in memory). */
8074 /* MS forgot to define this one with a non-underscore form too. */
8075 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
8076#endif
8077#ifdef O_TEMPORARY
8078 /* Automatically delete when last handle is closed. */
8079 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
8080#endif
8081#ifdef O_RANDOM
8082 /* Optimize for random access. */
8083 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
8084#endif
8085#ifdef O_SEQUENTIAL
8086 /* Optimize for sequential access. */
8087 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
8088#endif
8089
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008090/* GNU extensions. */
8091#ifdef O_DIRECT
8092 /* Direct disk access. */
8093 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
8094#endif
8095#ifdef O_DIRECTORY
8096 /* Must be a directory. */
8097 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
8098#endif
8099#ifdef O_NOFOLLOW
8100 /* Do not follow links. */
8101 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
8102#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00008103
Barry Warsaw5676bd12003-01-07 20:57:09 +00008104 /* These come from sysexits.h */
8105#ifdef EX_OK
8106 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008107#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008108#ifdef EX_USAGE
8109 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008110#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008111#ifdef EX_DATAERR
8112 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008113#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008114#ifdef EX_NOINPUT
8115 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008116#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008117#ifdef EX_NOUSER
8118 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008119#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008120#ifdef EX_NOHOST
8121 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008122#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008123#ifdef EX_UNAVAILABLE
8124 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008125#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008126#ifdef EX_SOFTWARE
8127 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008128#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008129#ifdef EX_OSERR
8130 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008131#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008132#ifdef EX_OSFILE
8133 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008134#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008135#ifdef EX_CANTCREAT
8136 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008137#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008138#ifdef EX_IOERR
8139 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008140#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008141#ifdef EX_TEMPFAIL
8142 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008143#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008144#ifdef EX_PROTOCOL
8145 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008146#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008147#ifdef EX_NOPERM
8148 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008149#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008150#ifdef EX_CONFIG
8151 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008152#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008153#ifdef EX_NOTFOUND
8154 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008155#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008156
Guido van Rossum246bc171999-02-01 23:54:31 +00008157#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008158#if defined(PYOS_OS2) && defined(PYCC_GCC)
8159 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
8160 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
8161 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
8162 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
8163 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
8164 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
8165 if (ins(d, "P_PM", (long)P_PM)) return -1;
8166 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
8167 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
8168 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
8169 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
8170 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
8171 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
8172 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
8173 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
8174 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
8175 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
8176 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
8177 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
8178 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
8179#else
Guido van Rossum7d385291999-02-16 19:38:04 +00008180 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
8181 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
8182 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
8183 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
8184 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00008185#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008186#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00008187
Guido van Rossumd48f2521997-12-05 22:19:34 +00008188#if defined(PYOS_OS2)
8189 if (insertvalues(d)) return -1;
8190#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008191 return 0;
8192}
8193
8194
Tim Peters5aa91602002-01-30 05:46:57 +00008195#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008196#define INITFUNC initnt
8197#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008198
8199#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008200#define INITFUNC initos2
8201#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008202
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008203#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008204#define INITFUNC initposix
8205#define MODNAME "posix"
8206#endif
8207
Mark Hammondfe51c6d2002-08-02 02:27:13 +00008208PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008209INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00008210{
Fred Drake4d1e64b2002-04-15 19:40:07 +00008211 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00008212
Fred Drake4d1e64b2002-04-15 19:40:07 +00008213 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008214 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00008215 posix__doc__);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00008216 if (m == NULL)
8217 return;
Tim Peters5aa91602002-01-30 05:46:57 +00008218
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008219 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008220 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00008221 Py_XINCREF(v);
8222 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008223 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00008224 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00008225
Fred Drake4d1e64b2002-04-15 19:40:07 +00008226 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00008227 return;
8228
Fred Drake4d1e64b2002-04-15 19:40:07 +00008229 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00008230 return;
8231
Fred Drake4d1e64b2002-04-15 19:40:07 +00008232 Py_INCREF(PyExc_OSError);
8233 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00008234
Guido van Rossumb3d39562000-01-31 18:41:26 +00008235#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00008236 if (posix_putenv_garbage == NULL)
8237 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00008238#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008239
Guido van Rossum14648392001-12-08 18:02:58 +00008240 stat_result_desc.name = MODNAME ".stat_result";
Martin v. Löwisf607bda2002-10-16 18:27:39 +00008241 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
8242 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
8243 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008244 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00008245 structseq_new = StatResultType.tp_new;
8246 StatResultType.tp_new = statresult_new;
Fred Drake4d1e64b2002-04-15 19:40:07 +00008247 Py_INCREF((PyObject*) &StatResultType);
8248 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008249
Guido van Rossum14648392001-12-08 18:02:58 +00008250 statvfs_result_desc.name = MODNAME ".statvfs_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008251 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Fred Drake4d1e64b2002-04-15 19:40:07 +00008252 Py_INCREF((PyObject*) &StatVFSResultType);
8253 PyModule_AddObject(m, "statvfs_result",
8254 (PyObject*) &StatVFSResultType);
Guido van Rossumb6775db1994-08-01 11:34:53 +00008255}