blob: e0c2b7f4f99671c98d7185e75aeabae6e4bd85ff [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
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000016#include "Python.h"
17#include "structseq.h"
18
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000019#if defined(__VMS)
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000020# include <unixio.h>
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000021#endif /* defined(__VMS) */
22
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000023PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000024"This module provides access to operating system functionality that is\n\
25standardized by the C Standard and the POSIX standard (a thinly\n\
26disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000027corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000028
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000029#ifndef Py_USING_UNICODE
30/* This is used in signatures of functions. */
31#define Py_UNICODE void
32#endif
33
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000034#if defined(PYOS_OS2)
35#define INCL_DOS
36#define INCL_DOSERRORS
37#define INCL_DOSPROCESS
38#define INCL_NOPMAPI
39#include <os2.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000040#if defined(PYCC_GCC)
41#include <ctype.h>
42#include <io.h>
43#include <stdio.h>
44#include <process.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000045#endif
Andrew MacIntyreda4d6cb2004-03-29 11:53:38 +000046#include "osdefs.h"
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000047#endif
48
Guido van Rossumb6775db1994-08-01 11:34:53 +000049#include <sys/types.h>
50#include <sys/stat.h>
Guido van Rossuma6535fd2001-10-18 19:44:10 +000051
Guido van Rossum36bc6801995-06-14 22:54:23 +000052#ifdef HAVE_SYS_WAIT_H
53#include <sys/wait.h> /* For WNOHANG */
54#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000055
Guido van Rossuma376cc51996-12-05 23:43:35 +000056#include <signal.h>
Guido van Rossuma376cc51996-12-05 23:43:35 +000057
Guido van Rossumb6775db1994-08-01 11:34:53 +000058#ifdef HAVE_FCNTL_H
59#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000060#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000061
Guido van Rossuma6535fd2001-10-18 19:44:10 +000062#ifdef HAVE_GRP_H
63#include <grp.h>
64#endif
65
Barry Warsaw5676bd12003-01-07 20:57:09 +000066#ifdef HAVE_SYSEXITS_H
67#include <sysexits.h>
68#endif /* HAVE_SYSEXITS_H */
69
Anthony Baxter8a560de2004-10-13 15:30:56 +000070#ifdef HAVE_SYS_LOADAVG_H
71#include <sys/loadavg.h>
72#endif
73
Guido van Rossuma4916fa1996-05-23 22:58:55 +000074/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +000075/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000076#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000077#include <process.h>
78#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +000079#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000080#define HAVE_GETCWD 1
81#define HAVE_OPENDIR 1
82#define HAVE_SYSTEM 1
83#if defined(__OS2__)
84#define HAVE_EXECV 1
85#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +000086#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000087#include <process.h>
88#else
89#ifdef __BORLANDC__ /* Borland compiler */
90#define HAVE_EXECV 1
91#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +000092#define HAVE_OPENDIR 1
93#define HAVE_PIPE 1
94#define HAVE_POPEN 1
95#define HAVE_SYSTEM 1
96#define HAVE_WAIT 1
97#else
98#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +000099#define HAVE_GETCWD 1
Guido van Rossuma1065681999-01-25 23:20:23 +0000100#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000101#define HAVE_EXECV 1
102#define HAVE_PIPE 1
103#define HAVE_POPEN 1
104#define HAVE_SYSTEM 1
Tim Petersab034fa2002-02-01 11:27:43 +0000105#define HAVE_CWAIT 1
Tim Peters11b23062003-04-23 02:39:17 +0000106#define HAVE_FSYNC 1
107#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000108#else
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000109#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
110/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000111#else /* all other compilers */
112/* Unix functions that the configure script doesn't check for */
113#define HAVE_EXECV 1
114#define HAVE_FORK 1
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000115#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
116#define HAVE_FORK1 1
117#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000118#define HAVE_GETCWD 1
119#define HAVE_GETEGID 1
120#define HAVE_GETEUID 1
121#define HAVE_GETGID 1
122#define HAVE_GETPPID 1
123#define HAVE_GETUID 1
124#define HAVE_KILL 1
125#define HAVE_OPENDIR 1
126#define HAVE_PIPE 1
Martin v. Löwis212ede62003-09-20 11:20:30 +0000127#ifndef __rtems__
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000128#define HAVE_POPEN 1
Martin v. Löwis212ede62003-09-20 11:20:30 +0000129#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000130#define HAVE_SYSTEM 1
131#define HAVE_WAIT 1
Guido van Rossumd371ff11999-01-25 16:12:23 +0000132#define HAVE_TTYNAME 1
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000133#endif /* PYOS_OS2 && PYCC_GCC && __VMS */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000134#endif /* _MSC_VER */
135#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000136#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000137#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000138
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000139#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000140
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000141#if defined(__sgi)&&_COMPILER_VERSION>=700
142/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
143 (default) */
144extern char *ctermid_r(char *);
145#endif
146
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000147#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000148#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000149extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000150#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000151#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000152extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000153#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000154extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000155#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000156#endif
157#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000158extern int chdir(char *);
159extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000160#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000161extern int chdir(const char *);
162extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000163#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000164#ifdef __BORLANDC__
165extern int chmod(const char *, int);
166#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000167extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000168#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000169extern int chown(const char *, uid_t, gid_t);
170extern char *getcwd(char *, int);
171extern char *strerror(int);
172extern int link(const char *, const char *);
173extern int rename(const char *, const char *);
174extern int stat(const char *, struct stat *);
175extern int unlink(const char *);
176extern int pclose(FILE *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000177#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000178extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000179#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000180#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000181extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000182#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000183#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000184
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000185#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000186
Guido van Rossumb6775db1994-08-01 11:34:53 +0000187#ifdef HAVE_UTIME_H
188#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000189#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000190
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000191#ifdef HAVE_SYS_UTIME_H
192#include <sys/utime.h>
193#define HAVE_UTIME_H /* pretend we do for the rest of this file */
194#endif /* HAVE_SYS_UTIME_H */
195
Guido van Rossumb6775db1994-08-01 11:34:53 +0000196#ifdef HAVE_SYS_TIMES_H
197#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000198#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000199
200#ifdef HAVE_SYS_PARAM_H
201#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000202#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000203
204#ifdef HAVE_SYS_UTSNAME_H
205#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000206#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000207
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000208#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000209#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000210#define NAMLEN(dirent) strlen((dirent)->d_name)
211#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000212#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000213#include <direct.h>
214#define NAMLEN(dirent) strlen((dirent)->d_name)
215#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000216#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000217#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000218#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000219#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000220#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000221#endif
222#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000223#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000224#endif
225#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000226#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000227#endif
228#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000229
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000230#ifdef _MSC_VER
Guido van Rossumb6775db1994-08-01 11:34:53 +0000231#include <direct.h>
232#include <io.h>
233#include <process.h>
Tim Petersbc2e10e2002-03-03 23:17:02 +0000234#include "osdefs.h"
Martin v. Löwisdc3883f2004-08-29 15:46:35 +0000235#define _WIN32_WINNT 0x0400 /* Needed for CryptoAPI on some systems */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000236#include <windows.h>
Tim Petersee66d0c2002-07-15 16:10:55 +0000237#include <shellapi.h> /* for ShellExecute() */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000238#define popen _popen
Guido van Rossum794d8131994-08-23 13:48:48 +0000239#define pclose _pclose
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000240#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000241
Guido van Rossumd48f2521997-12-05 22:19:34 +0000242#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000243#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000244#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000245
Tim Petersbc2e10e2002-03-03 23:17:02 +0000246#ifndef MAXPATHLEN
247#define MAXPATHLEN 1024
248#endif /* MAXPATHLEN */
249
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000250#ifdef UNION_WAIT
251/* Emulate some macros on systems that have a union instead of macros */
252
253#ifndef WIFEXITED
254#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
255#endif
256
257#ifndef WEXITSTATUS
258#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
259#endif
260
261#ifndef WTERMSIG
262#define WTERMSIG(u_wait) ((u_wait).w_termsig)
263#endif
264
265#endif /* UNION_WAIT */
266
Greg Wardb48bc172000-03-01 21:51:56 +0000267/* Don't use the "_r" form if we don't need it (also, won't have a
268 prototype for it, at least on Solaris -- maybe others as well?). */
269#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
270#define USE_CTERMID_R
271#endif
272
273#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
274#define USE_TMPNAM_R
275#endif
276
Fred Drake699f3522000-06-29 21:12:41 +0000277/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000278#undef STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000279#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +0000280# define STAT _stati64
281# define FSTAT _fstati64
282# define STRUCT_STAT struct _stati64
283#else
284# define STAT stat
285# define FSTAT fstat
286# define STRUCT_STAT struct stat
287#endif
288
Tim Peters11b23062003-04-23 02:39:17 +0000289#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000290#include <sys/mkdev.h>
291#else
292#if defined(MAJOR_IN_SYSMACROS)
293#include <sys/sysmacros.h>
294#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000295#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
296#include <sys/mkdev.h>
297#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000298#endif
Fred Drake699f3522000-06-29 21:12:41 +0000299
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000300/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000301#ifdef WITH_NEXT_FRAMEWORK
302/* On Darwin/MacOSX a shared library or framework has no access to
303** environ directly, we must obtain it with _NSGetEnviron().
304*/
305#include <crt_externs.h>
306static char **environ;
307#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000308extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000309#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000310
Barry Warsaw53699e91996-12-10 23:23:01 +0000311static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000312convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000313{
Barry Warsaw53699e91996-12-10 23:23:01 +0000314 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000315 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000316 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000317 if (d == NULL)
318 return NULL;
Jack Jansenea0c3822002-08-01 21:57:49 +0000319#ifdef WITH_NEXT_FRAMEWORK
320 if (environ == NULL)
321 environ = *_NSGetEnviron();
322#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000323 if (environ == NULL)
324 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000325 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000326 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000327 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000328 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000329 char *p = strchr(*e, '=');
330 if (p == NULL)
331 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000332 k = PyString_FromStringAndSize(*e, (int)(p-*e));
333 if (k == NULL) {
334 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000335 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000336 }
337 v = PyString_FromString(p+1);
338 if (v == NULL) {
339 PyErr_Clear();
340 Py_DECREF(k);
341 continue;
342 }
343 if (PyDict_GetItem(d, k) == NULL) {
344 if (PyDict_SetItem(d, k, v) != 0)
345 PyErr_Clear();
346 }
347 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000348 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000349 }
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000350#if defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000351 {
352 APIRET rc;
353 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
354
355 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000356 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000357 PyObject *v = PyString_FromString(buffer);
358 PyDict_SetItemString(d, "BEGINLIBPATH", v);
359 Py_DECREF(v);
360 }
361 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
362 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
363 PyObject *v = PyString_FromString(buffer);
364 PyDict_SetItemString(d, "ENDLIBPATH", v);
365 Py_DECREF(v);
366 }
367 }
368#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000369 return d;
370}
371
372
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000373/* Set a POSIX-specific error from errno, and return NULL */
374
Barry Warsawd58d7641998-07-23 16:14:40 +0000375static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000376posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000377{
Barry Warsawca74da41999-02-09 19:31:45 +0000378 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000379}
Barry Warsawd58d7641998-07-23 16:14:40 +0000380static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000381posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000382{
Barry Warsawca74da41999-02-09 19:31:45 +0000383 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000384}
385
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000386#ifdef Py_WIN_WIDE_FILENAMES
387static PyObject *
388posix_error_with_unicode_filename(Py_UNICODE* name)
389{
390 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
391}
392#endif /* Py_WIN_WIDE_FILENAMES */
393
394
Mark Hammondef8b6542001-05-13 08:04:26 +0000395static PyObject *
396posix_error_with_allocated_filename(char* name)
397{
398 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
399 PyMem_Free(name);
400 return rc;
401}
402
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000403#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000404static PyObject *
405win32_error(char* function, char* filename)
406{
Mark Hammond33a6da92000-08-15 00:46:38 +0000407 /* XXX We should pass the function name along in the future.
408 (_winreg.c also wants to pass the function name.)
Tim Peters5aa91602002-01-30 05:46:57 +0000409 This would however require an additional param to the
Mark Hammond33a6da92000-08-15 00:46:38 +0000410 Windows error object, which is non-trivial.
411 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000412 errno = GetLastError();
413 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000414 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000415 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000416 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000417}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000418
419#ifdef Py_WIN_WIDE_FILENAMES
420static PyObject *
421win32_error_unicode(char* function, Py_UNICODE* filename)
422{
423 /* XXX - see win32_error for comments on 'function' */
424 errno = GetLastError();
425 if (filename)
426 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
427 else
428 return PyErr_SetFromWindowsErr(errno);
429}
430
431static PyObject *_PyUnicode_FromFileSystemEncodedObject(register PyObject *obj)
432{
433 /* XXX Perhaps we should make this API an alias of
434 PyObject_Unicode() instead ?! */
435 if (PyUnicode_CheckExact(obj)) {
436 Py_INCREF(obj);
437 return obj;
438 }
439 if (PyUnicode_Check(obj)) {
440 /* For a Unicode subtype that's not a Unicode object,
441 return a true Unicode object with the same data. */
442 return PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(obj),
443 PyUnicode_GET_SIZE(obj));
444 }
Tim Peters11b23062003-04-23 02:39:17 +0000445 return PyUnicode_FromEncodedObject(obj,
446 Py_FileSystemDefaultEncoding,
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000447 "strict");
448}
449
450#endif /* Py_WIN_WIDE_FILENAMES */
451
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000452#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000453
Guido van Rossumd48f2521997-12-05 22:19:34 +0000454#if defined(PYOS_OS2)
455/**********************************************************************
456 * Helper Function to Trim and Format OS/2 Messages
457 **********************************************************************/
458 static void
459os2_formatmsg(char *msgbuf, int msglen, char *reason)
460{
461 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
462
463 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
464 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
465
466 while (lastc > msgbuf && isspace(*lastc))
467 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
468 }
469
470 /* Add Optional Reason Text */
471 if (reason) {
472 strcat(msgbuf, " : ");
473 strcat(msgbuf, reason);
474 }
475}
476
477/**********************************************************************
478 * Decode an OS/2 Operating System Error Code
479 *
480 * A convenience function to lookup an OS/2 error code and return a
481 * text message we can use to raise a Python exception.
482 *
483 * Notes:
484 * The messages for errors returned from the OS/2 kernel reside in
485 * the file OSO001.MSG in the \OS2 directory hierarchy.
486 *
487 **********************************************************************/
488 static char *
489os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
490{
491 APIRET rc;
492 ULONG msglen;
493
494 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
495 Py_BEGIN_ALLOW_THREADS
496 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
497 errorcode, "oso001.msg", &msglen);
498 Py_END_ALLOW_THREADS
499
500 if (rc == NO_ERROR)
501 os2_formatmsg(msgbuf, msglen, reason);
502 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000503 PyOS_snprintf(msgbuf, msgbuflen,
Tim Peters885d4572001-11-28 20:27:42 +0000504 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000505
506 return msgbuf;
507}
508
509/* Set an OS/2-specific error and return NULL. OS/2 kernel
510 errors are not in a global variable e.g. 'errno' nor are
511 they congruent with posix error numbers. */
512
513static PyObject * os2_error(int code)
514{
515 char text[1024];
516 PyObject *v;
517
518 os2_strerror(text, sizeof(text), code, "");
519
520 v = Py_BuildValue("(is)", code, text);
521 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000522 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000523 Py_DECREF(v);
524 }
525 return NULL; /* Signal to Python that an Exception is Pending */
526}
527
528#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000529
530/* POSIX generic methods */
531
Barry Warsaw53699e91996-12-10 23:23:01 +0000532static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000533posix_fildes(PyObject *fdobj, int (*func)(int))
534{
535 int fd;
536 int res;
537 fd = PyObject_AsFileDescriptor(fdobj);
538 if (fd < 0)
539 return NULL;
540 Py_BEGIN_ALLOW_THREADS
541 res = (*func)(fd);
542 Py_END_ALLOW_THREADS
543 if (res < 0)
544 return posix_error();
545 Py_INCREF(Py_None);
546 return Py_None;
547}
Guido van Rossum21142a01999-01-08 21:05:37 +0000548
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000549#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters11b23062003-04-23 02:39:17 +0000550static int
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000551unicode_file_names(void)
552{
553 static int canusewide = -1;
554 if (canusewide == -1) {
Tim Peters11b23062003-04-23 02:39:17 +0000555 /* As per doc for ::GetVersion(), this is the correct test for
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000556 the Windows NT family. */
557 canusewide = (GetVersion() < 0x80000000) ? 1 : 0;
558 }
559 return canusewide;
560}
561#endif
Tim Peters11b23062003-04-23 02:39:17 +0000562
Guido van Rossum21142a01999-01-08 21:05:37 +0000563static PyObject *
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000564posix_1str(PyObject *args, char *format, int (*func)(const char*),
565 char *wformat, int (*wfunc)(const Py_UNICODE*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000566{
Mark Hammondef8b6542001-05-13 08:04:26 +0000567 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000568 int res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000569#ifdef Py_WIN_WIDE_FILENAMES
570 if (unicode_file_names()) {
571 PyUnicodeObject *po;
572 if (PyArg_ParseTuple(args, wformat, &po)) {
573 Py_BEGIN_ALLOW_THREADS
574 /* PyUnicode_AS_UNICODE OK without thread
575 lock as it is a simple dereference. */
576 res = (*wfunc)(PyUnicode_AS_UNICODE(po));
577 Py_END_ALLOW_THREADS
578 if (res < 0)
Mark Hammondd3890362002-10-03 07:24:48 +0000579 return posix_error_with_unicode_filename(PyUnicode_AS_UNICODE(po));
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000580 Py_INCREF(Py_None);
581 return Py_None;
582 }
583 /* Drop the argument parsing error as narrow
584 strings are also valid. */
585 PyErr_Clear();
586 }
587#else
588 /* Platforms that don't support Unicode filenames
589 shouldn't be passing these extra params */
590 assert(wformat==NULL && wfunc == NULL);
591#endif
592
Tim Peters5aa91602002-01-30 05:46:57 +0000593 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000594 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000595 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000596 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000597 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000598 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000599 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000600 return posix_error_with_allocated_filename(path1);
601 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000602 Py_INCREF(Py_None);
603 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000604}
605
Barry Warsaw53699e91996-12-10 23:23:01 +0000606static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000607posix_2str(PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000608 char *format,
609 int (*func)(const char *, const char *),
610 char *wformat,
611 int (*wfunc)(const Py_UNICODE *, const Py_UNICODE *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000612{
Mark Hammondef8b6542001-05-13 08:04:26 +0000613 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000614 int res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000615#ifdef Py_WIN_WIDE_FILENAMES
616 if (unicode_file_names()) {
617 PyObject *po1;
618 PyObject *po2;
619 if (PyArg_ParseTuple(args, wformat, &po1, &po2)) {
620 if (PyUnicode_Check(po1) || PyUnicode_Check(po2)) {
621 PyObject *wpath1;
622 PyObject *wpath2;
623 wpath1 = _PyUnicode_FromFileSystemEncodedObject(po1);
624 wpath2 = _PyUnicode_FromFileSystemEncodedObject(po2);
625 if (!wpath1 || !wpath2) {
626 Py_XDECREF(wpath1);
627 Py_XDECREF(wpath2);
628 return NULL;
629 }
630 Py_BEGIN_ALLOW_THREADS
631 /* PyUnicode_AS_UNICODE OK without thread
632 lock as it is a simple dereference. */
633 res = (*wfunc)(PyUnicode_AS_UNICODE(wpath1),
634 PyUnicode_AS_UNICODE(wpath2));
635 Py_END_ALLOW_THREADS
636 Py_XDECREF(wpath1);
637 Py_XDECREF(wpath2);
638 if (res != 0)
639 return posix_error();
640 Py_INCREF(Py_None);
641 return Py_None;
642 }
643 /* Else flow through as neither is Unicode. */
644 }
645 /* Drop the argument parsing error as narrow
646 strings are also valid. */
647 PyErr_Clear();
648 }
649#else
650 /* Platforms that don't support Unicode filenames
651 shouldn't be passing these extra params */
652 assert(wformat==NULL && wfunc == NULL);
653#endif
654
Mark Hammondef8b6542001-05-13 08:04:26 +0000655 if (!PyArg_ParseTuple(args, format,
Tim Peters5aa91602002-01-30 05:46:57 +0000656 Py_FileSystemDefaultEncoding, &path1,
Mark Hammondef8b6542001-05-13 08:04:26 +0000657 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000658 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000659 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000660 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000661 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000662 PyMem_Free(path1);
663 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000664 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000665 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000666 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000667 Py_INCREF(Py_None);
668 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000669}
670
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000671PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000672"stat_result: Result from stat or lstat.\n\n\
673This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +0000674 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000675or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
676\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +0000677Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
678or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000679\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000680See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000681
682static PyStructSequence_Field stat_result_fields[] = {
683 {"st_mode", "protection bits"},
684 {"st_ino", "inode"},
685 {"st_dev", "device"},
686 {"st_nlink", "number of hard links"},
687 {"st_uid", "user ID of owner"},
688 {"st_gid", "group ID of owner"},
689 {"st_size", "total size, in bytes"},
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000690 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
691 {NULL, "integer time of last access"},
692 {NULL, "integer time of last modification"},
693 {NULL, "integer time of last change"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000694 {"st_atime", "time of last access"},
695 {"st_mtime", "time of last modification"},
696 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000697#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000698 {"st_blksize", "blocksize for filesystem I/O"},
699#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000700#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000701 {"st_blocks", "number of blocks allocated"},
702#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000703#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000704 {"st_rdev", "device type (if inode device)"},
705#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +0000706#ifdef HAVE_STRUCT_STAT_ST_FLAGS
707 {"st_flags", "user defined flags for file"},
708#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000709 {0}
710};
711
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000712#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000713#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000714#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000715#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000716#endif
717
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000718#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000719#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
720#else
721#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
722#endif
723
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000724#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000725#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
726#else
727#define ST_RDEV_IDX ST_BLOCKS_IDX
728#endif
729
Hye-Shik Chang5f937a72005-06-02 13:09:30 +0000730#ifdef HAVE_STRUCT_STAT_ST_FLAGS
731#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
732#else
733#define ST_FLAGS_IDX ST_RDEV_IDX
734#endif
735
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000736static PyStructSequence_Desc stat_result_desc = {
737 "stat_result", /* name */
738 stat_result__doc__, /* doc */
739 stat_result_fields,
740 10
741};
742
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000743PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000744"statvfs_result: Result from statvfs or fstatvfs.\n\n\
745This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +0000746 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000747or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000748\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000749See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000750
751static PyStructSequence_Field statvfs_result_fields[] = {
752 {"f_bsize", },
753 {"f_frsize", },
754 {"f_blocks", },
755 {"f_bfree", },
756 {"f_bavail", },
757 {"f_files", },
758 {"f_ffree", },
759 {"f_favail", },
760 {"f_flag", },
761 {"f_namemax",},
762 {0}
763};
764
765static PyStructSequence_Desc statvfs_result_desc = {
766 "statvfs_result", /* name */
767 statvfs_result__doc__, /* doc */
768 statvfs_result_fields,
769 10
770};
771
772static PyTypeObject StatResultType;
773static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000774static newfunc structseq_new;
775
776static PyObject *
777statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
778{
779 PyStructSequence *result;
780 int i;
781
782 result = (PyStructSequence*)structseq_new(type, args, kwds);
783 if (!result)
784 return NULL;
785 /* If we have been initialized from a tuple,
786 st_?time might be set to None. Initialize it
787 from the int slots. */
788 for (i = 7; i <= 9; i++) {
789 if (result->ob_item[i+3] == Py_None) {
790 Py_DECREF(Py_None);
791 Py_INCREF(result->ob_item[i]);
792 result->ob_item[i+3] = result->ob_item[i];
793 }
794 }
795 return (PyObject*)result;
796}
797
798
799
800/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +0000801static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000802
803PyDoc_STRVAR(stat_float_times__doc__,
804"stat_float_times([newval]) -> oldval\n\n\
805Determine whether os.[lf]stat represents time stamps as float objects.\n\
806If newval is True, future calls to stat() return floats, if it is False,\n\
807future calls return ints. \n\
808If newval is omitted, return the current setting.\n");
809
810static PyObject*
811stat_float_times(PyObject* self, PyObject *args)
812{
813 int newval = -1;
814 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
815 return NULL;
816 if (newval == -1)
817 /* Return old value */
818 return PyBool_FromLong(_stat_float_times);
819 _stat_float_times = newval;
820 Py_INCREF(Py_None);
821 return Py_None;
822}
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000823
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000824static void
825fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
826{
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000827 PyObject *fval,*ival;
828#if SIZEOF_TIME_T > SIZEOF_LONG
Martin v. Löwisb9a0f912003-03-29 10:06:18 +0000829 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000830#else
831 ival = PyInt_FromLong((long)sec);
832#endif
833 if (_stat_float_times) {
834 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
835 } else {
836 fval = ival;
837 Py_INCREF(fval);
838 }
839 PyStructSequence_SET_ITEM(v, index, ival);
840 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000841}
842
Tim Peters5aa91602002-01-30 05:46:57 +0000843/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +0000844 (used by posix_stat() and posix_fstat()) */
845static PyObject*
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000846_pystat_fromstructstat(STRUCT_STAT st)
Fred Drake699f3522000-06-29 21:12:41 +0000847{
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000848 unsigned long ansec, mnsec, cnsec;
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000849 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +0000850 if (v == NULL)
851 return NULL;
852
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000853 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st.st_mode));
Fred Drake699f3522000-06-29 21:12:41 +0000854#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +0000855 PyStructSequence_SET_ITEM(v, 1,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +0000856 PyLong_FromLongLong((PY_LONG_LONG)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +0000857#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000858 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +0000859#endif
860#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +0000861 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +0000862 PyLong_FromLongLong((PY_LONG_LONG)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +0000863#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000864 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +0000865#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000866 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st.st_nlink));
867 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st.st_uid));
868 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st.st_gid));
Fred Drake699f3522000-06-29 21:12:41 +0000869#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +0000870 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +0000871 PyLong_FromLongLong((PY_LONG_LONG)st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +0000872#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000873 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +0000874#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000875
876#ifdef HAVE_STAT_TV_NSEC
877 ansec = st.st_atim.tv_nsec;
878 mnsec = st.st_mtim.tv_nsec;
879 cnsec = st.st_ctim.tv_nsec;
Fred Drake699f3522000-06-29 21:12:41 +0000880#else
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000881 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000882#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000883 fill_time(v, 7, st.st_atime, ansec);
884 fill_time(v, 8, st.st_mtime, mnsec);
885 fill_time(v, 9, st.st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000886
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000887#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +0000888 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000889 PyInt_FromLong((long)st.st_blksize));
890#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000891#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +0000892 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000893 PyInt_FromLong((long)st.st_blocks));
894#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000895#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000896 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
897 PyInt_FromLong((long)st.st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +0000898#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +0000899#ifdef HAVE_STRUCT_STAT_ST_FLAGS
900 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
901 PyInt_FromLong((long)st.st_flags));
902#endif
Fred Drake699f3522000-06-29 21:12:41 +0000903
904 if (PyErr_Occurred()) {
905 Py_DECREF(v);
906 return NULL;
907 }
908
909 return v;
910}
911
Martin v. Löwisd8948722004-06-02 09:57:56 +0000912#ifdef MS_WINDOWS
913
914/* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
915 where / can be used in place of \ and the trailing slash is optional.
916 Both SERVER and SHARE must have at least one character.
917*/
918
919#define ISSLASHA(c) ((c) == '\\' || (c) == '/')
920#define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
921#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
922
Tim Peters4ad82172004-08-30 17:02:04 +0000923static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +0000924IsUNCRootA(char *path, int pathlen)
925{
926 #define ISSLASH ISSLASHA
927
928 int i, share;
929
930 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
931 /* minimum UNCRoot is \\x\y */
932 return FALSE;
933 for (i = 2; i < pathlen ; i++)
934 if (ISSLASH(path[i])) break;
935 if (i == 2 || i == pathlen)
936 /* do not allow \\\SHARE or \\SERVER */
937 return FALSE;
938 share = i+1;
939 for (i = share; i < pathlen; i++)
940 if (ISSLASH(path[i])) break;
941 return (i != share && (i == pathlen || i == pathlen-1));
942
943 #undef ISSLASH
944}
945
946#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters4ad82172004-08-30 17:02:04 +0000947static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +0000948IsUNCRootW(Py_UNICODE *path, int pathlen)
949{
950 #define ISSLASH ISSLASHW
951
952 int i, share;
953
954 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
955 /* minimum UNCRoot is \\x\y */
956 return FALSE;
957 for (i = 2; i < pathlen ; i++)
958 if (ISSLASH(path[i])) break;
959 if (i == 2 || i == pathlen)
960 /* do not allow \\\SHARE or \\SERVER */
961 return FALSE;
962 share = i+1;
963 for (i = share; i < pathlen; i++)
964 if (ISSLASH(path[i])) break;
965 return (i != share && (i == pathlen || i == pathlen-1));
966
967 #undef ISSLASH
968}
969#endif /* Py_WIN_WIDE_FILENAMES */
970#endif /* MS_WINDOWS */
971
Barry Warsaw53699e91996-12-10 23:23:01 +0000972static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000973posix_do_stat(PyObject *self, PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000974 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000975#ifdef __VMS
976 int (*statfunc)(const char *, STRUCT_STAT *, ...),
977#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000978 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000979#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000980 char *wformat,
981 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000982{
Fred Drake699f3522000-06-29 21:12:41 +0000983 STRUCT_STAT st;
Tim Peters500bd032001-12-19 19:05:01 +0000984 char *path = NULL; /* pass this to stat; do not free() it */
985 char *pathfree = NULL; /* this memory must be free'd */
Guido van Rossumff4949e1992-08-05 19:58:53 +0000986 int res;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000987
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000988#ifdef MS_WINDOWS
Tim Peters500bd032001-12-19 19:05:01 +0000989 int pathlen;
990 char pathcopy[MAX_PATH];
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000991#endif /* MS_WINDOWS */
Guido van Rossumace88ae2000-04-21 18:54:45 +0000992
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000993
994#ifdef Py_WIN_WIDE_FILENAMES
995 /* If on wide-character-capable OS see if argument
996 is Unicode and if so use wide API. */
997 if (unicode_file_names()) {
998 PyUnicodeObject *po;
999 if (PyArg_ParseTuple(args, wformat, &po)) {
1000 Py_UNICODE wpath[MAX_PATH+1];
1001 pathlen = wcslen(PyUnicode_AS_UNICODE(po));
1002 /* the library call can blow up if the file name is too long! */
1003 if (pathlen > MAX_PATH) {
1004 errno = ENAMETOOLONG;
1005 return posix_error();
1006 }
1007 wcscpy(wpath, PyUnicode_AS_UNICODE(po));
1008 /* Remove trailing slash or backslash, unless it's the current
1009 drive root (/ or \) or a specific drive's root (like c:\ or c:/).
1010 */
Martin v. Löwisd8948722004-06-02 09:57:56 +00001011 if (pathlen > 0) {
1012 if (ISSLASHW(wpath[pathlen-1])) {
1013 /* It does end with a slash -- exempt the root drive cases. */
Tim Peters4ad82172004-08-30 17:02:04 +00001014 if (pathlen == 1 || (pathlen == 3 && wpath[1] == L':') ||
Martin v. Löwisd8948722004-06-02 09:57:56 +00001015 IsUNCRootW(wpath, pathlen))
1016 /* leave it alone */;
1017 else {
1018 /* nuke the trailing backslash */
1019 wpath[pathlen-1] = L'\0';
1020 }
1021 }
Tim Peters4ad82172004-08-30 17:02:04 +00001022 else if (ISSLASHW(wpath[1]) && pathlen < ARRAYSIZE(wpath)-1 &&
Martin v. Löwisd8948722004-06-02 09:57:56 +00001023 IsUNCRootW(wpath, pathlen)) {
1024 /* UNC root w/o trailing slash: add one when there's room */
1025 wpath[pathlen++] = L'\\';
1026 wpath[pathlen] = L'\0';
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001027 }
1028 }
1029 Py_BEGIN_ALLOW_THREADS
1030 /* PyUnicode_AS_UNICODE result OK without
1031 thread lock as it is a simple dereference. */
1032 res = wstatfunc(wpath, &st);
1033 Py_END_ALLOW_THREADS
1034 if (res != 0)
1035 return posix_error_with_unicode_filename(wpath);
1036 return _pystat_fromstructstat(st);
1037 }
1038 /* Drop the argument parsing error as narrow strings
1039 are also valid. */
1040 PyErr_Clear();
1041 }
1042#endif
1043
Tim Peters5aa91602002-01-30 05:46:57 +00001044 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +00001045 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001046 return NULL;
Tim Peters500bd032001-12-19 19:05:01 +00001047 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +00001048
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001049#ifdef MS_WINDOWS
Guido van Rossumace88ae2000-04-21 18:54:45 +00001050 pathlen = strlen(path);
1051 /* the library call can blow up if the file name is too long! */
1052 if (pathlen > MAX_PATH) {
Tim Peters500bd032001-12-19 19:05:01 +00001053 PyMem_Free(pathfree);
Guido van Rossumace88ae2000-04-21 18:54:45 +00001054 errno = ENAMETOOLONG;
1055 return posix_error();
1056 }
1057
Tim Peters500bd032001-12-19 19:05:01 +00001058 /* Remove trailing slash or backslash, unless it's the current
1059 drive root (/ or \) or a specific drive's root (like c:\ or c:/).
1060 */
Martin v. Löwisd8948722004-06-02 09:57:56 +00001061 if (pathlen > 0) {
1062 if (ISSLASHA(path[pathlen-1])) {
1063 /* It does end with a slash -- exempt the root drive cases. */
Tim Peters4ad82172004-08-30 17:02:04 +00001064 if (pathlen == 1 || (pathlen == 3 && path[1] == ':') ||
Martin v. Löwisd8948722004-06-02 09:57:56 +00001065 IsUNCRootA(path, pathlen))
1066 /* leave it alone */;
1067 else {
1068 /* nuke the trailing backslash */
1069 strncpy(pathcopy, path, pathlen);
1070 pathcopy[pathlen-1] = '\0';
1071 path = pathcopy;
1072 }
1073 }
Tim Peters4ad82172004-08-30 17:02:04 +00001074 else if (ISSLASHA(path[1]) && pathlen < ARRAYSIZE(pathcopy)-1 &&
Martin v. Löwisd8948722004-06-02 09:57:56 +00001075 IsUNCRootA(path, pathlen)) {
1076 /* UNC root w/o trailing slash: add one when there's room */
Guido van Rossumace88ae2000-04-21 18:54:45 +00001077 strncpy(pathcopy, path, pathlen);
Martin v. Löwisd8948722004-06-02 09:57:56 +00001078 pathcopy[pathlen++] = '\\';
1079 pathcopy[pathlen] = '\0';
Guido van Rossumace88ae2000-04-21 18:54:45 +00001080 path = pathcopy;
1081 }
1082 }
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001083#endif /* MS_WINDOWS */
Guido van Rossumace88ae2000-04-21 18:54:45 +00001084
Barry Warsaw53699e91996-12-10 23:23:01 +00001085 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001086 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00001087 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001088 if (res != 0)
Tim Peters500bd032001-12-19 19:05:01 +00001089 return posix_error_with_allocated_filename(pathfree);
Fred Drake699f3522000-06-29 21:12:41 +00001090
Tim Peters500bd032001-12-19 19:05:01 +00001091 PyMem_Free(pathfree);
Fred Drake699f3522000-06-29 21:12:41 +00001092 return _pystat_fromstructstat(st);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001093}
1094
1095
1096/* POSIX methods */
1097
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001098PyDoc_STRVAR(posix_access__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001099"access(path, mode) -> 1 if granted, 0 otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001100Use the real uid/gid to test for access to a path. Note that most\n\
1101operations will use the effective uid/gid, therefore this routine can\n\
1102be used in a suid/sgid environment to test if the invoking user has the\n\
1103specified access to the path. The mode argument can be F_OK to test\n\
1104existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001105
1106static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001107posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001108{
Guido van Rossum015f22a1999-01-06 22:52:38 +00001109 char *path;
1110 int mode;
1111 int res;
1112
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001113#ifdef Py_WIN_WIDE_FILENAMES
1114 if (unicode_file_names()) {
1115 PyUnicodeObject *po;
1116 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1117 Py_BEGIN_ALLOW_THREADS
1118 /* PyUnicode_AS_UNICODE OK without thread lock as
1119 it is a simple dereference. */
1120 res = _waccess(PyUnicode_AS_UNICODE(po), mode);
1121 Py_END_ALLOW_THREADS
1122 return(PyBool_FromLong(res == 0));
1123 }
1124 /* Drop the argument parsing error as narrow strings
1125 are also valid. */
1126 PyErr_Clear();
1127 }
1128#endif
Martin v. Löwisb60ae992005-03-08 09:10:29 +00001129 if (!PyArg_ParseTuple(args, "eti:access",
1130 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +00001131 return NULL;
1132 Py_BEGIN_ALLOW_THREADS
1133 res = access(path, mode);
1134 Py_END_ALLOW_THREADS
Guido van Rossum674deb22002-09-01 15:06:28 +00001135 return(PyBool_FromLong(res == 0));
Guido van Rossum94f6f721999-01-06 18:42:14 +00001136}
1137
Guido van Rossumd371ff11999-01-25 16:12:23 +00001138#ifndef F_OK
1139#define F_OK 0
1140#endif
1141#ifndef R_OK
1142#define R_OK 4
1143#endif
1144#ifndef W_OK
1145#define W_OK 2
1146#endif
1147#ifndef X_OK
1148#define X_OK 1
1149#endif
1150
1151#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001152PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001153"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001154Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001155
1156static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001157posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001158{
Guido van Rossum94f6f721999-01-06 18:42:14 +00001159 int id;
1160 char *ret;
1161
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001162 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +00001163 return NULL;
1164
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001165#if defined(__VMS)
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +00001166 /* file descriptor 0 only, the default input device (stdin) */
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001167 if (id == 0) {
1168 ret = ttyname();
1169 }
1170 else {
1171 ret = NULL;
1172 }
1173#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00001174 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001175#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001176 if (ret == NULL)
1177 return(posix_error());
1178 return(PyString_FromString(ret));
1179}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001180#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001181
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001182#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001183PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001184"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001185Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001186
1187static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001188posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001189{
1190 char *ret;
1191 char buffer[L_ctermid];
1192
Greg Wardb48bc172000-03-01 21:51:56 +00001193#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001194 ret = ctermid_r(buffer);
1195#else
1196 ret = ctermid(buffer);
1197#endif
1198 if (ret == NULL)
1199 return(posix_error());
1200 return(PyString_FromString(buffer));
1201}
1202#endif
1203
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001204PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001205"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001206Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001207
Barry Warsaw53699e91996-12-10 23:23:01 +00001208static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001209posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001210{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001211#ifdef MS_WINDOWS
1212 return posix_1str(args, "et:chdir", chdir, "U:chdir", _wchdir);
1213#elif defined(PYOS_OS2) && defined(PYCC_GCC)
1214 return posix_1str(args, "et:chdir", _chdir2, NULL, NULL);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001215#elif defined(__VMS)
Tim Peters11b23062003-04-23 02:39:17 +00001216 return posix_1str(args, "et:chdir", (int (*)(const char *))chdir,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001217 NULL, NULL);
1218#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001219 return posix_1str(args, "et:chdir", chdir, NULL, NULL);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001220#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001221}
1222
Fred Drake4d1e64b2002-04-15 19:40:07 +00001223#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001224PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001225"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001226Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001227opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001228
1229static PyObject *
1230posix_fchdir(PyObject *self, PyObject *fdobj)
1231{
1232 return posix_fildes(fdobj, fchdir);
1233}
1234#endif /* HAVE_FCHDIR */
1235
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001236
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001237PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001238"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001239Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001240
Barry Warsaw53699e91996-12-10 23:23:01 +00001241static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001242posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001243{
Mark Hammondef8b6542001-05-13 08:04:26 +00001244 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +00001245 int i;
1246 int res;
Mark Hammond817c9292003-12-03 01:22:38 +00001247#ifdef Py_WIN_WIDE_FILENAMES
1248 if (unicode_file_names()) {
1249 PyUnicodeObject *po;
1250 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1251 Py_BEGIN_ALLOW_THREADS
1252 res = _wchmod(PyUnicode_AS_UNICODE(po), i);
1253 Py_END_ALLOW_THREADS
1254 if (res < 0)
1255 return posix_error_with_unicode_filename(
1256 PyUnicode_AS_UNICODE(po));
1257 Py_INCREF(Py_None);
1258 return Py_None;
1259 }
1260 /* Drop the argument parsing error as narrow strings
1261 are also valid. */
1262 PyErr_Clear();
1263 }
1264#endif /* Py_WIN_WIDE_FILENAMES */
1265 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
Mark Hammondef8b6542001-05-13 08:04:26 +00001266 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +00001267 return NULL;
1268 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +00001269 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001270 Py_END_ALLOW_THREADS
1271 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001272 return posix_error_with_allocated_filename(path);
1273 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001274 Py_INCREF(Py_None);
1275 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001276}
1277
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001278
Martin v. Löwis244edc82001-10-04 22:44:26 +00001279#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001280PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001281"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001282Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00001283
1284static PyObject *
1285posix_chroot(PyObject *self, PyObject *args)
1286{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001287 return posix_1str(args, "et:chroot", chroot, NULL, NULL);
Martin v. Löwis244edc82001-10-04 22:44:26 +00001288}
1289#endif
1290
Guido van Rossum21142a01999-01-08 21:05:37 +00001291#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001292PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001293"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001294force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001295
1296static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001297posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001298{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001299 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001300}
1301#endif /* HAVE_FSYNC */
1302
1303#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00001304
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00001305#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00001306extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1307#endif
1308
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001309PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001310"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00001311force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001312 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001313
1314static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001315posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001316{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001317 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001318}
1319#endif /* HAVE_FDATASYNC */
1320
1321
Fredrik Lundh10723342000-07-10 16:38:09 +00001322#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001323PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001324"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001325Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001326
Barry Warsaw53699e91996-12-10 23:23:01 +00001327static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001328posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001329{
Mark Hammondef8b6542001-05-13 08:04:26 +00001330 char *path = NULL;
Fredrik Lundh44328e62000-07-10 15:59:30 +00001331 int uid, gid;
1332 int res;
Tim Peters5aa91602002-01-30 05:46:57 +00001333 if (!PyArg_ParseTuple(args, "etii:chown",
1334 Py_FileSystemDefaultEncoding, &path,
Mark Hammondef8b6542001-05-13 08:04:26 +00001335 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +00001336 return NULL;
1337 Py_BEGIN_ALLOW_THREADS
1338 res = chown(path, (uid_t) uid, (gid_t) gid);
1339 Py_END_ALLOW_THREADS
1340 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001341 return posix_error_with_allocated_filename(path);
1342 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +00001343 Py_INCREF(Py_None);
1344 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001345}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001346#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001347
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001348#ifdef HAVE_LCHOWN
1349PyDoc_STRVAR(posix_lchown__doc__,
1350"lchown(path, uid, gid)\n\n\
1351Change the owner and group id of path to the numeric uid and gid.\n\
1352This function will not follow symbolic links.");
1353
1354static PyObject *
1355posix_lchown(PyObject *self, PyObject *args)
1356{
1357 char *path = NULL;
1358 int uid, gid;
1359 int res;
1360 if (!PyArg_ParseTuple(args, "etii:lchown",
1361 Py_FileSystemDefaultEncoding, &path,
1362 &uid, &gid))
1363 return NULL;
1364 Py_BEGIN_ALLOW_THREADS
1365 res = lchown(path, (uid_t) uid, (gid_t) gid);
1366 Py_END_ALLOW_THREADS
Tim Peters11b23062003-04-23 02:39:17 +00001367 if (res < 0)
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001368 return posix_error_with_allocated_filename(path);
1369 PyMem_Free(path);
1370 Py_INCREF(Py_None);
1371 return Py_None;
1372}
1373#endif /* HAVE_LCHOWN */
1374
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001375
Guido van Rossum36bc6801995-06-14 22:54:23 +00001376#ifdef HAVE_GETCWD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001377PyDoc_STRVAR(posix_getcwd__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001378"getcwd() -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001379Return a string representing the current working directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001380
Barry Warsaw53699e91996-12-10 23:23:01 +00001381static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001382posix_getcwd(PyObject *self, PyObject *noargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001383{
1384 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +00001385 char *res;
Neal Norwitze241ce82003-02-17 18:17:05 +00001386
Barry Warsaw53699e91996-12-10 23:23:01 +00001387 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001388#if defined(PYOS_OS2) && defined(PYCC_GCC)
1389 res = _getcwd2(buf, sizeof buf);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001390#else
Guido van Rossumff4949e1992-08-05 19:58:53 +00001391 res = getcwd(buf, sizeof buf);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001392#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001393 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001394 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001395 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001396 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001397}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001398
Walter Dörwald3b918c32002-11-21 20:18:46 +00001399#ifdef Py_USING_UNICODE
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001400PyDoc_STRVAR(posix_getcwdu__doc__,
1401"getcwdu() -> path\n\n\
1402Return a unicode string representing the current working directory.");
1403
1404static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001405posix_getcwdu(PyObject *self, PyObject *noargs)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001406{
1407 char buf[1026];
1408 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001409
1410#ifdef Py_WIN_WIDE_FILENAMES
1411 if (unicode_file_names()) {
1412 wchar_t *wres;
1413 wchar_t wbuf[1026];
1414 Py_BEGIN_ALLOW_THREADS
1415 wres = _wgetcwd(wbuf, sizeof wbuf/ sizeof wbuf[0]);
1416 Py_END_ALLOW_THREADS
1417 if (wres == NULL)
1418 return posix_error();
1419 return PyUnicode_FromWideChar(wbuf, wcslen(wbuf));
1420 }
1421#endif
1422
1423 Py_BEGIN_ALLOW_THREADS
1424#if defined(PYOS_OS2) && defined(PYCC_GCC)
1425 res = _getcwd2(buf, sizeof buf);
1426#else
1427 res = getcwd(buf, sizeof buf);
1428#endif
1429 Py_END_ALLOW_THREADS
1430 if (res == NULL)
1431 return posix_error();
1432 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
1433}
Guido van Rossum36bc6801995-06-14 22:54:23 +00001434#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00001435#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001436
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001437
Guido van Rossumb6775db1994-08-01 11:34:53 +00001438#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001439PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001440"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001441Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001442
Barry Warsaw53699e91996-12-10 23:23:01 +00001443static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001444posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001445{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001446 return posix_2str(args, "etet:link", link, NULL, NULL);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001447}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001448#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001449
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001450
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001451PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001452"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001453Return a list containing the names of the entries in the directory.\n\
1454\n\
1455 path: path of directory to list\n\
1456\n\
1457The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001458entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001459
Barry Warsaw53699e91996-12-10 23:23:01 +00001460static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001461posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001462{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001463 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001464 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001465#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001466
Barry Warsaw53699e91996-12-10 23:23:01 +00001467 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001468 HANDLE hFindFile;
1469 WIN32_FIND_DATA FileData;
Mark Hammondef8b6542001-05-13 08:04:26 +00001470 /* MAX_PATH characters could mean a bigger encoded string */
1471 char namebuf[MAX_PATH*2+5];
1472 char *bufptr = namebuf;
1473 int len = sizeof(namebuf)/sizeof(namebuf[0]);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001474
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001475#ifdef Py_WIN_WIDE_FILENAMES
1476 /* If on wide-character-capable OS see if argument
1477 is Unicode and if so use wide API. */
1478 if (unicode_file_names()) {
1479 PyUnicodeObject *po;
1480 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
1481 WIN32_FIND_DATAW wFileData;
1482 Py_UNICODE wnamebuf[MAX_PATH*2+5];
1483 Py_UNICODE wch;
1484 wcsncpy(wnamebuf, PyUnicode_AS_UNICODE(po), MAX_PATH);
1485 wnamebuf[MAX_PATH] = L'\0';
1486 len = wcslen(wnamebuf);
1487 wch = (len > 0) ? wnamebuf[len-1] : L'\0';
1488 if (wch != L'/' && wch != L'\\' && wch != L':')
1489 wnamebuf[len++] = L'/';
1490 wcscpy(wnamebuf + len, L"*.*");
1491 if ((d = PyList_New(0)) == NULL)
1492 return NULL;
1493 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
1494 if (hFindFile == INVALID_HANDLE_VALUE) {
1495 errno = GetLastError();
1496 if (errno == ERROR_FILE_NOT_FOUND) {
1497 return d;
1498 }
1499 Py_DECREF(d);
1500 return win32_error_unicode("FindFirstFileW", wnamebuf);
1501 }
1502 do {
1503 if (wFileData.cFileName[0] == L'.' &&
1504 (wFileData.cFileName[1] == L'\0' ||
1505 wFileData.cFileName[1] == L'.' &&
1506 wFileData.cFileName[2] == L'\0'))
1507 continue;
1508 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
1509 if (v == NULL) {
1510 Py_DECREF(d);
1511 d = NULL;
1512 break;
1513 }
1514 if (PyList_Append(d, v) != 0) {
1515 Py_DECREF(v);
1516 Py_DECREF(d);
1517 d = NULL;
1518 break;
1519 }
1520 Py_DECREF(v);
1521 } while (FindNextFileW(hFindFile, &wFileData) == TRUE);
1522
1523 if (FindClose(hFindFile) == FALSE) {
1524 Py_DECREF(d);
1525 return win32_error_unicode("FindClose", wnamebuf);
1526 }
1527 return d;
1528 }
1529 /* Drop the argument parsing error as narrow strings
1530 are also valid. */
1531 PyErr_Clear();
1532 }
1533#endif
1534
Tim Peters5aa91602002-01-30 05:46:57 +00001535 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001536 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +00001537 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +00001538 if (len > 0) {
1539 char ch = namebuf[len-1];
1540 if (ch != SEP && ch != ALTSEP && ch != ':')
1541 namebuf[len++] = '/';
1542 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001543 strcpy(namebuf + len, "*.*");
1544
Barry Warsaw53699e91996-12-10 23:23:01 +00001545 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001546 return NULL;
1547
1548 hFindFile = FindFirstFile(namebuf, &FileData);
1549 if (hFindFile == INVALID_HANDLE_VALUE) {
1550 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +00001551 if (errno == ERROR_FILE_NOT_FOUND)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001552 return d;
1553 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00001554 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001555 }
1556 do {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001557 if (FileData.cFileName[0] == '.' &&
1558 (FileData.cFileName[1] == '\0' ||
1559 FileData.cFileName[1] == '.' &&
1560 FileData.cFileName[2] == '\0'))
1561 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001562 v = PyString_FromString(FileData.cFileName);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001563 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001564 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001565 d = NULL;
1566 break;
1567 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001568 if (PyList_Append(d, v) != 0) {
1569 Py_DECREF(v);
1570 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001571 d = NULL;
1572 break;
1573 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001574 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001575 } while (FindNextFile(hFindFile, &FileData) == TRUE);
1576
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001577 if (FindClose(hFindFile) == FALSE) {
1578 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00001579 return win32_error("FindClose", namebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001580 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001581
1582 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001583
Tim Peters0bb44a42000-09-15 07:44:49 +00001584#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001585
1586#ifndef MAX_PATH
1587#define MAX_PATH CCHMAXPATH
1588#endif
1589 char *name, *pt;
1590 int len;
1591 PyObject *d, *v;
1592 char namebuf[MAX_PATH+5];
1593 HDIR hdir = 1;
1594 ULONG srchcnt = 1;
1595 FILEFINDBUF3 ep;
1596 APIRET rc;
1597
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001598 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001599 return NULL;
1600 if (len >= MAX_PATH) {
1601 PyErr_SetString(PyExc_ValueError, "path too long");
1602 return NULL;
1603 }
1604 strcpy(namebuf, name);
1605 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001606 if (*pt == ALTSEP)
1607 *pt = SEP;
1608 if (namebuf[len-1] != SEP)
1609 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001610 strcpy(namebuf + len, "*.*");
1611
1612 if ((d = PyList_New(0)) == NULL)
1613 return NULL;
1614
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001615 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
1616 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001617 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001618 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
1619 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
1620 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001621
1622 if (rc != NO_ERROR) {
1623 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001624 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001625 }
1626
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001627 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001628 do {
1629 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001630 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001631 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001632
1633 strcpy(namebuf, ep.achName);
1634
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001635 /* Leave Case of Name Alone -- In Native Form */
1636 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001637
1638 v = PyString_FromString(namebuf);
1639 if (v == NULL) {
1640 Py_DECREF(d);
1641 d = NULL;
1642 break;
1643 }
1644 if (PyList_Append(d, v) != 0) {
1645 Py_DECREF(v);
1646 Py_DECREF(d);
1647 d = NULL;
1648 break;
1649 }
1650 Py_DECREF(v);
1651 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1652 }
1653
1654 return d;
1655#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001656
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001657 char *name = NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001658 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001659 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001660 struct dirent *ep;
Just van Rossum96b1c902003-03-03 17:32:15 +00001661 int arg_is_unicode = 1;
1662
1663 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
1664 arg_is_unicode = 0;
1665 PyErr_Clear();
1666 }
1667 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001668 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001669 if ((dirp = opendir(name)) == NULL) {
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001670 return posix_error_with_allocated_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001671 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001672 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001673 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001674 PyMem_Free(name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001675 return NULL;
1676 }
1677 while ((ep = readdir(dirp)) != NULL) {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001678 if (ep->d_name[0] == '.' &&
1679 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001680 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001681 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001682 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001683 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001684 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001685 d = NULL;
1686 break;
1687 }
Just van Rossum46c97842003-02-25 21:42:15 +00001688#ifdef Py_USING_UNICODE
Just van Rossum96b1c902003-03-03 17:32:15 +00001689 if (arg_is_unicode) {
Just van Rossum46c97842003-02-25 21:42:15 +00001690 PyObject *w;
1691
1692 w = PyUnicode_FromEncodedObject(v,
Tim Peters11b23062003-04-23 02:39:17 +00001693 Py_FileSystemDefaultEncoding,
Just van Rossum46c97842003-02-25 21:42:15 +00001694 "strict");
Just van Rossum6a421832003-03-04 19:30:44 +00001695 if (w != NULL) {
1696 Py_DECREF(v);
1697 v = w;
1698 }
1699 else {
1700 /* fall back to the original byte string, as
1701 discussed in patch #683592 */
1702 PyErr_Clear();
Just van Rossum46c97842003-02-25 21:42:15 +00001703 }
Just van Rossum46c97842003-02-25 21:42:15 +00001704 }
1705#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001706 if (PyList_Append(d, v) != 0) {
1707 Py_DECREF(v);
1708 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001709 d = NULL;
1710 break;
1711 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001712 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001713 }
1714 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001715 PyMem_Free(name);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001716
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001717 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001718
Tim Peters0bb44a42000-09-15 07:44:49 +00001719#endif /* which OS */
1720} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001721
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001722#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00001723/* A helper function for abspath on win32 */
1724static PyObject *
1725posix__getfullpathname(PyObject *self, PyObject *args)
1726{
1727 /* assume encoded strings wont more than double no of chars */
1728 char inbuf[MAX_PATH*2];
1729 char *inbufp = inbuf;
1730 int insize = sizeof(inbuf)/sizeof(inbuf[0]);
1731 char outbuf[MAX_PATH*2];
1732 char *temp;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001733#ifdef Py_WIN_WIDE_FILENAMES
1734 if (unicode_file_names()) {
1735 PyUnicodeObject *po;
1736 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
1737 Py_UNICODE woutbuf[MAX_PATH*2];
1738 Py_UNICODE *wtemp;
Tim Peters11b23062003-04-23 02:39:17 +00001739 if (!GetFullPathNameW(PyUnicode_AS_UNICODE(po),
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001740 sizeof(woutbuf)/sizeof(woutbuf[0]),
1741 woutbuf, &wtemp))
1742 return win32_error("GetFullPathName", "");
1743 return PyUnicode_FromUnicode(woutbuf, wcslen(woutbuf));
1744 }
1745 /* Drop the argument parsing error as narrow strings
1746 are also valid. */
1747 PyErr_Clear();
1748 }
1749#endif
Tim Peters5aa91602002-01-30 05:46:57 +00001750 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
1751 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00001752 &insize))
1753 return NULL;
1754 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
1755 outbuf, &temp))
1756 return win32_error("GetFullPathName", inbuf);
Martin v. Löwis969297f2004-06-15 18:49:58 +00001757 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
1758 return PyUnicode_Decode(outbuf, strlen(outbuf),
1759 Py_FileSystemDefaultEncoding, NULL);
1760 }
Mark Hammondef8b6542001-05-13 08:04:26 +00001761 return PyString_FromString(outbuf);
1762} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001763#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00001764
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001765PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001766"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001767Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001768
Barry Warsaw53699e91996-12-10 23:23:01 +00001769static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001770posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001771{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001772 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00001773 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001774 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001775
1776#ifdef Py_WIN_WIDE_FILENAMES
1777 if (unicode_file_names()) {
1778 PyUnicodeObject *po;
Mark Hammond05107b62003-02-19 04:08:27 +00001779 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001780 Py_BEGIN_ALLOW_THREADS
1781 /* PyUnicode_AS_UNICODE OK without thread lock as
1782 it is a simple dereference. */
1783 res = _wmkdir(PyUnicode_AS_UNICODE(po));
1784 Py_END_ALLOW_THREADS
1785 if (res < 0)
1786 return posix_error();
1787 Py_INCREF(Py_None);
1788 return Py_None;
1789 }
1790 /* Drop the argument parsing error as narrow strings
1791 are also valid. */
1792 PyErr_Clear();
1793 }
1794#endif
1795
Tim Peters5aa91602002-01-30 05:46:57 +00001796 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001797 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001798 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001799 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001800#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001801 res = mkdir(path);
1802#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001803 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001804#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001805 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001806 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001807 return posix_error_with_allocated_filename(path);
1808 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001809 Py_INCREF(Py_None);
1810 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001811}
1812
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001813
Guido van Rossumb6775db1994-08-01 11:34:53 +00001814#ifdef HAVE_NICE
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001815#if defined(HAVE_BROKEN_NICE) && defined(HAVE_SYS_RESOURCE_H)
1816#if defined(HAVE_GETPRIORITY) && !defined(PRIO_PROCESS)
1817#include <sys/resource.h>
1818#endif
1819#endif
1820
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001821PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001822"nice(inc) -> new_priority\n\n\
1823Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001824
Barry Warsaw53699e91996-12-10 23:23:01 +00001825static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001826posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00001827{
1828 int increment, value;
1829
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001830 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00001831 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001832
1833 /* There are two flavours of 'nice': one that returns the new
1834 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001835 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
1836 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00001837
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001838 If we are of the nice family that returns the new priority, we
1839 need to clear errno before the call, and check if errno is filled
1840 before calling posix_error() on a returnvalue of -1, because the
1841 -1 may be the actual new priority! */
1842
1843 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00001844 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001845#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001846 if (value == 0)
1847 value = getpriority(PRIO_PROCESS, 0);
1848#endif
1849 if (value == -1 && errno != 0)
1850 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00001851 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001852 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00001853}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001854#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001855
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001856
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001857PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001858"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001859Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001860
Barry Warsaw53699e91996-12-10 23:23:01 +00001861static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001862posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001863{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001864#ifdef MS_WINDOWS
1865 return posix_2str(args, "etet:rename", rename, "OO:rename", _wrename);
1866#else
1867 return posix_2str(args, "etet:rename", rename, NULL, NULL);
1868#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001869}
1870
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001871
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001872PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001873"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001874Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001875
Barry Warsaw53699e91996-12-10 23:23:01 +00001876static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001877posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001878{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001879#ifdef MS_WINDOWS
1880 return posix_1str(args, "et:rmdir", rmdir, "U:rmdir", _wrmdir);
1881#else
1882 return posix_1str(args, "et:rmdir", rmdir, NULL, NULL);
1883#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001884}
1885
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001886
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001887PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001888"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001889Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001890
Barry Warsaw53699e91996-12-10 23:23:01 +00001891static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001892posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001893{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001894#ifdef MS_WINDOWS
1895 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", _wstati64);
1896#else
1897 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
1898#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001899}
1900
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001901
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001902#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001903PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001904"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001905Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001906
Barry Warsaw53699e91996-12-10 23:23:01 +00001907static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001908posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001909{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001910 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001911 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001912 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001913 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001914 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001915 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00001916 Py_END_ALLOW_THREADS
1917 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001918}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001919#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001920
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001921
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001922PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001923"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001924Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001925
Barry Warsaw53699e91996-12-10 23:23:01 +00001926static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001927posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001928{
1929 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001930 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001931 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00001932 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001933 if (i < 0)
1934 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001935 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001936}
1937
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001938
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001939PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001940"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001941Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001942
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001943PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001944"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001945Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001946
Barry Warsaw53699e91996-12-10 23:23:01 +00001947static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001948posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001949{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001950#ifdef MS_WINDOWS
1951 return posix_1str(args, "et:remove", unlink, "U:remove", _wunlink);
1952#else
1953 return posix_1str(args, "et:remove", unlink, NULL, NULL);
1954#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001955}
1956
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001957
Guido van Rossumb6775db1994-08-01 11:34:53 +00001958#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001959PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001960"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001961Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001962
Barry Warsaw53699e91996-12-10 23:23:01 +00001963static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001964posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001965{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001966 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001967 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00001968
Barry Warsaw53699e91996-12-10 23:23:01 +00001969 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001970 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00001971 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001972 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001973 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001974 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001975 u.sysname,
1976 u.nodename,
1977 u.release,
1978 u.version,
1979 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001980}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001981#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001982
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001983static int
1984extract_time(PyObject *t, long* sec, long* usec)
1985{
1986 long intval;
1987 if (PyFloat_Check(t)) {
1988 double tval = PyFloat_AsDouble(t);
1989 PyObject *intobj = t->ob_type->tp_as_number->nb_int(t);
1990 if (!intobj)
1991 return -1;
1992 intval = PyInt_AsLong(intobj);
1993 Py_DECREF(intobj);
Michael W. Hudsonb8963812005-07-05 15:21:58 +00001994 if (intval == -1 && PyErr_Occurred())
1995 return -1;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001996 *sec = intval;
Tim Peters96940cf2002-09-10 15:37:28 +00001997 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001998 if (*usec < 0)
1999 /* If rounding gave us a negative number,
2000 truncate. */
2001 *usec = 0;
2002 return 0;
2003 }
2004 intval = PyInt_AsLong(t);
2005 if (intval == -1 && PyErr_Occurred())
2006 return -1;
2007 *sec = intval;
2008 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00002009 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002010}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002011
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002012PyDoc_STRVAR(posix_utime__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002013"utime(path, (atime, utime))\n\
2014utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00002015Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002016second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002017
Barry Warsaw53699e91996-12-10 23:23:01 +00002018static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002019posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002020{
Neal Norwitz2adf2102004-06-09 01:46:02 +00002021 char *path = NULL;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002022 long atime, mtime, ausec, musec;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002023 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002024 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002025
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002026#if defined(HAVE_UTIMES)
2027 struct timeval buf[2];
2028#define ATIME buf[0].tv_sec
2029#define MTIME buf[1].tv_sec
2030#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002031/* XXX should define struct utimbuf instead, above */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002032 struct utimbuf buf;
2033#define ATIME buf.actime
2034#define MTIME buf.modtime
2035#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002036#else /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002037 time_t buf[2];
2038#define ATIME buf[0]
2039#define MTIME buf[1]
2040#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002041#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002042
Mark Hammond817c9292003-12-03 01:22:38 +00002043 int have_unicode_filename = 0;
2044#ifdef Py_WIN_WIDE_FILENAMES
2045 PyUnicodeObject *obwpath;
2046 wchar_t *wpath;
2047 if (unicode_file_names()) {
2048 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
2049 wpath = PyUnicode_AS_UNICODE(obwpath);
2050 have_unicode_filename = 1;
2051 } else
2052 /* Drop the argument parsing error as narrow strings
2053 are also valid. */
2054 PyErr_Clear();
2055 }
2056#endif /* Py_WIN_WIDE_FILENAMES */
2057
2058 if (!have_unicode_filename && \
Hye-Shik Chang2b2c9732004-01-04 13:54:25 +00002059 !PyArg_ParseTuple(args, "etO:utime",
2060 Py_FileSystemDefaultEncoding, &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002061 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002062 if (arg == Py_None) {
2063 /* optional time values not given */
2064 Py_BEGIN_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002065#ifdef Py_WIN_WIDE_FILENAMES
2066 if (have_unicode_filename)
2067 res = _wutime(wpath, NULL);
2068 else
2069#endif /* Py_WIN_WIDE_FILENAMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002070 res = utime(path, NULL);
2071 Py_END_ALLOW_THREADS
2072 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002073 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00002074 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002075 "utime() arg 2 must be a tuple (atime, mtime)");
Neal Norwitz96652712004-06-06 20:40:27 +00002076 PyMem_Free(path);
Barry Warsaw3cef8562000-05-01 16:17:24 +00002077 return NULL;
2078 }
2079 else {
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002080 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Neal Norwitz96652712004-06-06 20:40:27 +00002081 &atime, &ausec) == -1) {
2082 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002083 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002084 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002085 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Neal Norwitz96652712004-06-06 20:40:27 +00002086 &mtime, &musec) == -1) {
2087 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002088 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002089 }
Barry Warsaw3cef8562000-05-01 16:17:24 +00002090 ATIME = atime;
2091 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002092#ifdef HAVE_UTIMES
2093 buf[0].tv_usec = ausec;
2094 buf[1].tv_usec = musec;
2095 Py_BEGIN_ALLOW_THREADS
2096 res = utimes(path, buf);
2097 Py_END_ALLOW_THREADS
2098#else
Barry Warsaw3cef8562000-05-01 16:17:24 +00002099 Py_BEGIN_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002100#ifdef Py_WIN_WIDE_FILENAMES
2101 if (have_unicode_filename)
Tim Peters4ad82172004-08-30 17:02:04 +00002102 /* utime is OK with utimbuf, but _wutime insists
2103 on _utimbuf (the msvc headers assert the
Mark Hammond817c9292003-12-03 01:22:38 +00002104 underscore version is ansi) */
2105 res = _wutime(wpath, (struct _utimbuf *)UTIME_ARG);
2106 else
2107#endif /* Py_WIN_WIDE_FILENAMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002108 res = utime(path, UTIME_ARG);
2109 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002110#endif /* HAVE_UTIMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002111 }
Mark Hammond2d5914b2004-05-04 08:10:37 +00002112 if (res < 0) {
2113#ifdef Py_WIN_WIDE_FILENAMES
Neal Norwitz2adf2102004-06-09 01:46:02 +00002114 if (have_unicode_filename)
Mark Hammond2d5914b2004-05-04 08:10:37 +00002115 return posix_error_with_unicode_filename(wpath);
2116#endif /* Py_WIN_WIDE_FILENAMES */
Neal Norwitz96652712004-06-06 20:40:27 +00002117 return posix_error_with_allocated_filename(path);
Mark Hammond2d5914b2004-05-04 08:10:37 +00002118 }
Neal Norwitz96652712004-06-06 20:40:27 +00002119 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002120 Py_INCREF(Py_None);
2121 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002122#undef UTIME_ARG
2123#undef ATIME
2124#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002125}
2126
Guido van Rossum85e3b011991-06-03 12:42:10 +00002127
Guido van Rossum3b066191991-06-04 19:40:25 +00002128/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002129
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002130PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002131"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002132Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002133
Barry Warsaw53699e91996-12-10 23:23:01 +00002134static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002135posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002136{
2137 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002138 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002139 return NULL;
2140 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00002141 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002142}
2143
Martin v. Löwis114619e2002-10-07 06:44:21 +00002144#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
2145static void
2146free_string_array(char **array, int count)
2147{
2148 int i;
2149 for (i = 0; i < count; i++)
2150 PyMem_Free(array[i]);
2151 PyMem_DEL(array);
2152}
2153#endif
2154
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002155
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002156#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002157PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002158"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002159Execute an executable path with arguments, replacing current process.\n\
2160\n\
2161 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002162 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002163
Barry Warsaw53699e91996-12-10 23:23:01 +00002164static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002165posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002166{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002167 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002168 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002169 char **argvlist;
2170 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002171 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002172
Guido van Rossum89b33251993-10-22 14:26:06 +00002173 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00002174 argv is a list or tuple of strings. */
2175
Martin v. Löwis114619e2002-10-07 06:44:21 +00002176 if (!PyArg_ParseTuple(args, "etO:execv",
2177 Py_FileSystemDefaultEncoding,
2178 &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002179 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002180 if (PyList_Check(argv)) {
2181 argc = PyList_Size(argv);
2182 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002183 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002184 else if (PyTuple_Check(argv)) {
2185 argc = PyTuple_Size(argv);
2186 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002187 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002188 else {
Fred Drake661ea262000-10-24 19:57:45 +00002189 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002190 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002191 return NULL;
2192 }
2193
Barry Warsaw53699e91996-12-10 23:23:01 +00002194 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002195 if (argvlist == NULL) {
2196 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002197 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002198 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002199 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002200 if (!PyArg_Parse((*getitem)(argv, i), "et",
2201 Py_FileSystemDefaultEncoding,
2202 &argvlist[i])) {
2203 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00002204 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002205 "execv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002206 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002207 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00002208
Guido van Rossum85e3b011991-06-03 12:42:10 +00002209 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002210 }
2211 argvlist[argc] = NULL;
2212
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002213 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002214
Guido van Rossum85e3b011991-06-03 12:42:10 +00002215 /* If we get here it's definitely an error */
2216
Martin v. Löwis114619e2002-10-07 06:44:21 +00002217 free_string_array(argvlist, argc);
2218 PyMem_Free(path);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002219 return posix_error();
2220}
2221
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002222
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002223PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002224"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002225Execute a path with arguments and environment, replacing current process.\n\
2226\n\
2227 path: path of executable file\n\
2228 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002229 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002230
Barry Warsaw53699e91996-12-10 23:23:01 +00002231static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002232posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002233{
2234 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002235 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002236 char **argvlist;
2237 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002238 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002239 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002240 PyObject *(*getitem)(PyObject *, int);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002241 int lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002242
2243 /* execve has three arguments: (path, argv, env), where
2244 argv is a list or tuple of strings and env is a dictionary
2245 like posix.environ. */
2246
Martin v. Löwis114619e2002-10-07 06:44:21 +00002247 if (!PyArg_ParseTuple(args, "etOO:execve",
2248 Py_FileSystemDefaultEncoding,
2249 &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002250 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002251 if (PyList_Check(argv)) {
2252 argc = PyList_Size(argv);
2253 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002254 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002255 else if (PyTuple_Check(argv)) {
2256 argc = PyTuple_Size(argv);
2257 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002258 }
2259 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002260 PyErr_SetString(PyExc_TypeError,
2261 "execve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002262 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002263 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002264 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002265 PyErr_SetString(PyExc_TypeError,
2266 "execve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002267 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002268 }
2269
Barry Warsaw53699e91996-12-10 23:23:01 +00002270 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002271 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002272 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002273 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002274 }
2275 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002276 if (!PyArg_Parse((*getitem)(argv, i),
Martin v. Löwis114619e2002-10-07 06:44:21 +00002277 "et;execve() arg 2 must contain only strings",
Guido van Rossum1e700d22002-10-16 16:52:11 +00002278 Py_FileSystemDefaultEncoding,
Barry Warsaw43d68b81996-12-19 22:10:44 +00002279 &argvlist[i]))
2280 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002281 lastarg = i;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002282 goto fail_1;
2283 }
2284 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002285 lastarg = argc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002286 argvlist[argc] = NULL;
2287
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002288 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002289 if (i < 0)
2290 goto fail_1;
Barry Warsaw53699e91996-12-10 23:23:01 +00002291 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002292 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002293 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002294 goto fail_1;
2295 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002296 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002297 keys = PyMapping_Keys(env);
2298 vals = PyMapping_Values(env);
2299 if (!keys || !vals)
2300 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002301 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2302 PyErr_SetString(PyExc_TypeError,
2303 "execve(): env.keys() or env.values() is not a list");
2304 goto fail_2;
2305 }
Tim Peters5aa91602002-01-30 05:46:57 +00002306
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002307 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002308 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002309 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002310
2311 key = PyList_GetItem(keys, pos);
2312 val = PyList_GetItem(vals, pos);
2313 if (!key || !val)
2314 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002315
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002316 if (!PyArg_Parse(
2317 key,
2318 "s;execve() arg 3 contains a non-string key",
2319 &k) ||
2320 !PyArg_Parse(
2321 val,
2322 "s;execve() arg 3 contains a non-string value",
2323 &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00002324 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002325 goto fail_2;
2326 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00002327
2328#if defined(PYOS_OS2)
2329 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
2330 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
2331#endif
Tim Petersc8996f52001-12-03 20:41:00 +00002332 len = PyString_Size(key) + PyString_Size(val) + 2;
2333 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002334 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002335 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002336 goto fail_2;
2337 }
Tim Petersc8996f52001-12-03 20:41:00 +00002338 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002339 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00002340#if defined(PYOS_OS2)
2341 }
2342#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002343 }
2344 envlist[envc] = 0;
2345
2346 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00002347
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002348 /* If we get here it's definitely an error */
2349
2350 (void) posix_error();
2351
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002352 fail_2:
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002353 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00002354 PyMem_DEL(envlist[envc]);
2355 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002356 fail_1:
2357 free_string_array(argvlist, lastarg);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002358 Py_XDECREF(vals);
2359 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002360 fail_0:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002361 PyMem_Free(path);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002362 return NULL;
2363}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002364#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002365
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002366
Guido van Rossuma1065681999-01-25 23:20:23 +00002367#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002368PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002369"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002370Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002371\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002372 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002373 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002374 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002375
2376static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002377posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002378{
2379 char *path;
2380 PyObject *argv;
2381 char **argvlist;
2382 int mode, i, argc;
Tim Peters79248aa2001-08-29 21:37:10 +00002383 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002384 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00002385
2386 /* spawnv has three arguments: (mode, path, argv), where
2387 argv is a list or tuple of strings. */
2388
Martin v. Löwis114619e2002-10-07 06:44:21 +00002389 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
2390 Py_FileSystemDefaultEncoding,
2391 &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00002392 return NULL;
2393 if (PyList_Check(argv)) {
2394 argc = PyList_Size(argv);
2395 getitem = PyList_GetItem;
2396 }
2397 else if (PyTuple_Check(argv)) {
2398 argc = PyTuple_Size(argv);
2399 getitem = PyTuple_GetItem;
2400 }
2401 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002402 PyErr_SetString(PyExc_TypeError,
2403 "spawnv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002404 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002405 return NULL;
2406 }
2407
2408 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002409 if (argvlist == NULL) {
2410 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002411 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002412 }
Guido van Rossuma1065681999-01-25 23:20:23 +00002413 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002414 if (!PyArg_Parse((*getitem)(argv, i), "et",
2415 Py_FileSystemDefaultEncoding,
2416 &argvlist[i])) {
2417 free_string_array(argvlist, i);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002418 PyErr_SetString(
2419 PyExc_TypeError,
2420 "spawnv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002421 PyMem_Free(path);
Fred Drake137507e2000-06-01 02:02:46 +00002422 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00002423 }
2424 }
2425 argvlist[argc] = NULL;
2426
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002427#if defined(PYOS_OS2) && defined(PYCC_GCC)
2428 Py_BEGIN_ALLOW_THREADS
2429 spawnval = spawnv(mode, path, argvlist);
2430 Py_END_ALLOW_THREADS
2431#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002432 if (mode == _OLD_P_OVERLAY)
2433 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00002434
Tim Peters25059d32001-12-07 20:35:43 +00002435 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002436 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00002437 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002438#endif
Tim Peters5aa91602002-01-30 05:46:57 +00002439
Martin v. Löwis114619e2002-10-07 06:44:21 +00002440 free_string_array(argvlist, argc);
2441 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002442
Fred Drake699f3522000-06-29 21:12:41 +00002443 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002444 return posix_error();
2445 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002446#if SIZEOF_LONG == SIZEOF_VOID_P
2447 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002448#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00002449 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002450#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002451}
2452
2453
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002454PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002455"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002456Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002457\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002458 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002459 path: path of executable file\n\
2460 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002461 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002462
2463static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002464posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002465{
2466 char *path;
2467 PyObject *argv, *env;
2468 char **argvlist;
2469 char **envlist;
2470 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
2471 int mode, i, pos, argc, envc;
Tim Peters79248aa2001-08-29 21:37:10 +00002472 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002473 PyObject *(*getitem)(PyObject *, int);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002474 int lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002475
2476 /* spawnve has four arguments: (mode, path, argv, env), where
2477 argv is a list or tuple of strings and env is a dictionary
2478 like posix.environ. */
2479
Martin v. Löwis114619e2002-10-07 06:44:21 +00002480 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
2481 Py_FileSystemDefaultEncoding,
2482 &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00002483 return NULL;
2484 if (PyList_Check(argv)) {
2485 argc = PyList_Size(argv);
2486 getitem = PyList_GetItem;
2487 }
2488 else if (PyTuple_Check(argv)) {
2489 argc = PyTuple_Size(argv);
2490 getitem = PyTuple_GetItem;
2491 }
2492 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002493 PyErr_SetString(PyExc_TypeError,
2494 "spawnve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002495 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002496 }
2497 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002498 PyErr_SetString(PyExc_TypeError,
2499 "spawnve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002500 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002501 }
2502
2503 argvlist = PyMem_NEW(char *, argc+1);
2504 if (argvlist == NULL) {
2505 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002506 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002507 }
2508 for (i = 0; i < argc; i++) {
2509 if (!PyArg_Parse((*getitem)(argv, i),
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002510 "et;spawnve() arg 2 must contain only strings",
Martin v. Löwis114619e2002-10-07 06:44:21 +00002511 Py_FileSystemDefaultEncoding,
Guido van Rossuma1065681999-01-25 23:20:23 +00002512 &argvlist[i]))
2513 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002514 lastarg = i;
Guido van Rossuma1065681999-01-25 23:20:23 +00002515 goto fail_1;
2516 }
2517 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002518 lastarg = argc;
Guido van Rossuma1065681999-01-25 23:20:23 +00002519 argvlist[argc] = NULL;
2520
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002521 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002522 if (i < 0)
2523 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00002524 envlist = PyMem_NEW(char *, i + 1);
2525 if (envlist == NULL) {
2526 PyErr_NoMemory();
2527 goto fail_1;
2528 }
2529 envc = 0;
2530 keys = PyMapping_Keys(env);
2531 vals = PyMapping_Values(env);
2532 if (!keys || !vals)
2533 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002534 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2535 PyErr_SetString(PyExc_TypeError,
2536 "spawnve(): env.keys() or env.values() is not a list");
2537 goto fail_2;
2538 }
Tim Peters5aa91602002-01-30 05:46:57 +00002539
Guido van Rossuma1065681999-01-25 23:20:23 +00002540 for (pos = 0; pos < i; pos++) {
2541 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002542 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00002543
2544 key = PyList_GetItem(keys, pos);
2545 val = PyList_GetItem(vals, pos);
2546 if (!key || !val)
2547 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002548
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002549 if (!PyArg_Parse(
2550 key,
2551 "s;spawnve() arg 3 contains a non-string key",
2552 &k) ||
2553 !PyArg_Parse(
2554 val,
2555 "s;spawnve() arg 3 contains a non-string value",
2556 &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00002557 {
2558 goto fail_2;
2559 }
Tim Petersc8996f52001-12-03 20:41:00 +00002560 len = PyString_Size(key) + PyString_Size(val) + 2;
2561 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00002562 if (p == NULL) {
2563 PyErr_NoMemory();
2564 goto fail_2;
2565 }
Tim Petersc8996f52001-12-03 20:41:00 +00002566 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00002567 envlist[envc++] = p;
2568 }
2569 envlist[envc] = 0;
2570
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002571#if defined(PYOS_OS2) && defined(PYCC_GCC)
2572 Py_BEGIN_ALLOW_THREADS
2573 spawnval = spawnve(mode, path, argvlist, envlist);
2574 Py_END_ALLOW_THREADS
2575#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002576 if (mode == _OLD_P_OVERLAY)
2577 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00002578
2579 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002580 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00002581 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002582#endif
Tim Peters25059d32001-12-07 20:35:43 +00002583
Fred Drake699f3522000-06-29 21:12:41 +00002584 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002585 (void) posix_error();
2586 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002587#if SIZEOF_LONG == SIZEOF_VOID_P
2588 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002589#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00002590 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002591#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002592
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002593 fail_2:
Guido van Rossuma1065681999-01-25 23:20:23 +00002594 while (--envc >= 0)
2595 PyMem_DEL(envlist[envc]);
2596 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002597 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002598 free_string_array(argvlist, lastarg);
Guido van Rossuma1065681999-01-25 23:20:23 +00002599 Py_XDECREF(vals);
2600 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002601 fail_0:
2602 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002603 return res;
2604}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00002605
2606/* OS/2 supports spawnvp & spawnvpe natively */
2607#if defined(PYOS_OS2)
2608PyDoc_STRVAR(posix_spawnvp__doc__,
2609"spawnvp(mode, file, args)\n\n\
2610Execute the program 'file' in a new process, using the environment\n\
2611search path to find the file.\n\
2612\n\
2613 mode: mode of process creation\n\
2614 file: executable file name\n\
2615 args: tuple or list of strings");
2616
2617static PyObject *
2618posix_spawnvp(PyObject *self, PyObject *args)
2619{
2620 char *path;
2621 PyObject *argv;
2622 char **argvlist;
2623 int mode, i, argc;
2624 Py_intptr_t spawnval;
2625 PyObject *(*getitem)(PyObject *, int);
2626
2627 /* spawnvp has three arguments: (mode, path, argv), where
2628 argv is a list or tuple of strings. */
2629
2630 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
2631 Py_FileSystemDefaultEncoding,
2632 &path, &argv))
2633 return NULL;
2634 if (PyList_Check(argv)) {
2635 argc = PyList_Size(argv);
2636 getitem = PyList_GetItem;
2637 }
2638 else if (PyTuple_Check(argv)) {
2639 argc = PyTuple_Size(argv);
2640 getitem = PyTuple_GetItem;
2641 }
2642 else {
2643 PyErr_SetString(PyExc_TypeError,
2644 "spawnvp() arg 2 must be a tuple or list");
2645 PyMem_Free(path);
2646 return NULL;
2647 }
2648
2649 argvlist = PyMem_NEW(char *, argc+1);
2650 if (argvlist == NULL) {
2651 PyMem_Free(path);
2652 return PyErr_NoMemory();
2653 }
2654 for (i = 0; i < argc; i++) {
2655 if (!PyArg_Parse((*getitem)(argv, i), "et",
2656 Py_FileSystemDefaultEncoding,
2657 &argvlist[i])) {
2658 free_string_array(argvlist, i);
2659 PyErr_SetString(
2660 PyExc_TypeError,
2661 "spawnvp() arg 2 must contain only strings");
2662 PyMem_Free(path);
2663 return NULL;
2664 }
2665 }
2666 argvlist[argc] = NULL;
2667
2668 Py_BEGIN_ALLOW_THREADS
2669#if defined(PYCC_GCC)
2670 spawnval = spawnvp(mode, path, argvlist);
2671#else
2672 spawnval = _spawnvp(mode, path, argvlist);
2673#endif
2674 Py_END_ALLOW_THREADS
2675
2676 free_string_array(argvlist, argc);
2677 PyMem_Free(path);
2678
2679 if (spawnval == -1)
2680 return posix_error();
2681 else
2682 return Py_BuildValue("l", (long) spawnval);
2683}
2684
2685
2686PyDoc_STRVAR(posix_spawnvpe__doc__,
2687"spawnvpe(mode, file, args, env)\n\n\
2688Execute the program 'file' in a new process, using the environment\n\
2689search path to find the file.\n\
2690\n\
2691 mode: mode of process creation\n\
2692 file: executable file name\n\
2693 args: tuple or list of arguments\n\
2694 env: dictionary of strings mapping to strings");
2695
2696static PyObject *
2697posix_spawnvpe(PyObject *self, PyObject *args)
2698{
2699 char *path;
2700 PyObject *argv, *env;
2701 char **argvlist;
2702 char **envlist;
2703 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
2704 int mode, i, pos, argc, envc;
2705 Py_intptr_t spawnval;
2706 PyObject *(*getitem)(PyObject *, int);
2707 int lastarg = 0;
2708
2709 /* spawnvpe has four arguments: (mode, path, argv, env), where
2710 argv is a list or tuple of strings and env is a dictionary
2711 like posix.environ. */
2712
2713 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
2714 Py_FileSystemDefaultEncoding,
2715 &path, &argv, &env))
2716 return NULL;
2717 if (PyList_Check(argv)) {
2718 argc = PyList_Size(argv);
2719 getitem = PyList_GetItem;
2720 }
2721 else if (PyTuple_Check(argv)) {
2722 argc = PyTuple_Size(argv);
2723 getitem = PyTuple_GetItem;
2724 }
2725 else {
2726 PyErr_SetString(PyExc_TypeError,
2727 "spawnvpe() arg 2 must be a tuple or list");
2728 goto fail_0;
2729 }
2730 if (!PyMapping_Check(env)) {
2731 PyErr_SetString(PyExc_TypeError,
2732 "spawnvpe() arg 3 must be a mapping object");
2733 goto fail_0;
2734 }
2735
2736 argvlist = PyMem_NEW(char *, argc+1);
2737 if (argvlist == NULL) {
2738 PyErr_NoMemory();
2739 goto fail_0;
2740 }
2741 for (i = 0; i < argc; i++) {
2742 if (!PyArg_Parse((*getitem)(argv, i),
2743 "et;spawnvpe() arg 2 must contain only strings",
2744 Py_FileSystemDefaultEncoding,
2745 &argvlist[i]))
2746 {
2747 lastarg = i;
2748 goto fail_1;
2749 }
2750 }
2751 lastarg = argc;
2752 argvlist[argc] = NULL;
2753
2754 i = PyMapping_Size(env);
2755 if (i < 0)
2756 goto fail_1;
2757 envlist = PyMem_NEW(char *, i + 1);
2758 if (envlist == NULL) {
2759 PyErr_NoMemory();
2760 goto fail_1;
2761 }
2762 envc = 0;
2763 keys = PyMapping_Keys(env);
2764 vals = PyMapping_Values(env);
2765 if (!keys || !vals)
2766 goto fail_2;
2767 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2768 PyErr_SetString(PyExc_TypeError,
2769 "spawnvpe(): env.keys() or env.values() is not a list");
2770 goto fail_2;
2771 }
2772
2773 for (pos = 0; pos < i; pos++) {
2774 char *p, *k, *v;
2775 size_t len;
2776
2777 key = PyList_GetItem(keys, pos);
2778 val = PyList_GetItem(vals, pos);
2779 if (!key || !val)
2780 goto fail_2;
2781
2782 if (!PyArg_Parse(
2783 key,
2784 "s;spawnvpe() arg 3 contains a non-string key",
2785 &k) ||
2786 !PyArg_Parse(
2787 val,
2788 "s;spawnvpe() arg 3 contains a non-string value",
2789 &v))
2790 {
2791 goto fail_2;
2792 }
2793 len = PyString_Size(key) + PyString_Size(val) + 2;
2794 p = PyMem_NEW(char, len);
2795 if (p == NULL) {
2796 PyErr_NoMemory();
2797 goto fail_2;
2798 }
2799 PyOS_snprintf(p, len, "%s=%s", k, v);
2800 envlist[envc++] = p;
2801 }
2802 envlist[envc] = 0;
2803
2804 Py_BEGIN_ALLOW_THREADS
2805#if defined(PYCC_GCC)
2806 spawnval = spawnve(mode, path, argvlist, envlist);
2807#else
2808 spawnval = _spawnve(mode, path, argvlist, envlist);
2809#endif
2810 Py_END_ALLOW_THREADS
2811
2812 if (spawnval == -1)
2813 (void) posix_error();
2814 else
2815 res = Py_BuildValue("l", (long) spawnval);
2816
2817 fail_2:
2818 while (--envc >= 0)
2819 PyMem_DEL(envlist[envc]);
2820 PyMem_DEL(envlist);
2821 fail_1:
2822 free_string_array(argvlist, lastarg);
2823 Py_XDECREF(vals);
2824 Py_XDECREF(keys);
2825 fail_0:
2826 PyMem_Free(path);
2827 return res;
2828}
2829#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00002830#endif /* HAVE_SPAWNV */
2831
2832
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002833#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002834PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002835"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002836Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
2837\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002838Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002839
2840static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002841posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002842{
Neal Norwitze241ce82003-02-17 18:17:05 +00002843 int pid = fork1();
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002844 if (pid == -1)
2845 return posix_error();
2846 PyOS_AfterFork();
2847 return PyInt_FromLong((long)pid);
2848}
2849#endif
2850
2851
Guido van Rossumad0ee831995-03-01 10:34:45 +00002852#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002853PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002854"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002855Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002856Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002857
Barry Warsaw53699e91996-12-10 23:23:01 +00002858static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002859posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002860{
Neal Norwitze241ce82003-02-17 18:17:05 +00002861 int pid = fork();
Guido van Rossum85e3b011991-06-03 12:42:10 +00002862 if (pid == -1)
2863 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00002864 if (pid == 0)
2865 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00002866 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002867}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002868#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002869
Neal Norwitzb59798b2003-03-21 01:43:31 +00002870/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00002871/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
2872#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00002873#define DEV_PTY_FILE "/dev/ptc"
2874#define HAVE_DEV_PTMX
2875#else
2876#define DEV_PTY_FILE "/dev/ptmx"
2877#endif
2878
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002879#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002880#ifdef HAVE_PTY_H
2881#include <pty.h>
2882#else
2883#ifdef HAVE_LIBUTIL_H
2884#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00002885#endif /* HAVE_LIBUTIL_H */
2886#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00002887#ifdef HAVE_STROPTS_H
2888#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002889#endif
2890#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00002891
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002892#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002893PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002894"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002895Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00002896
2897static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002898posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002899{
2900 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00002901#ifndef HAVE_OPENPTY
2902 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00002903#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002904#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00002905 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002906#ifdef sun
2907 extern char *ptsname();
2908#endif
2909#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00002910
Thomas Wouters70c21a12000-07-14 14:28:33 +00002911#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00002912 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
2913 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00002914#elif defined(HAVE__GETPTY)
Thomas Wouters70c21a12000-07-14 14:28:33 +00002915 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
2916 if (slave_name == NULL)
2917 return posix_error();
2918
2919 slave_fd = open(slave_name, O_RDWR);
2920 if (slave_fd < 0)
2921 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002922#else
Neal Norwitzb59798b2003-03-21 01:43:31 +00002923 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002924 if (master_fd < 0)
2925 return posix_error();
Anthony Baxter9ceaa722004-10-13 14:48:50 +00002926 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00002927 /* change permission of slave */
2928 if (grantpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00002929 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002930 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00002931 }
2932 /* unlock slave */
2933 if (unlockpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00002934 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002935 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00002936 }
Anthony Baxter9ceaa722004-10-13 14:48:50 +00002937 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002938 slave_name = ptsname(master_fd); /* get name of slave */
2939 if (slave_name == NULL)
2940 return posix_error();
2941 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
2942 if (slave_fd < 0)
2943 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00002944#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002945 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
2946 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00002947#ifndef __hpux
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002948 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00002949#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002950#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00002951#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00002952
Fred Drake8cef4cf2000-06-28 16:40:38 +00002953 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00002954
Fred Drake8cef4cf2000-06-28 16:40:38 +00002955}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002956#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00002957
2958#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002959PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002960"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00002961Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
2962Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002963To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00002964
2965static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002966posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002967{
2968 int master_fd, pid;
Tim Peters5aa91602002-01-30 05:46:57 +00002969
Fred Drake8cef4cf2000-06-28 16:40:38 +00002970 pid = forkpty(&master_fd, NULL, NULL, NULL);
2971 if (pid == -1)
2972 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00002973 if (pid == 0)
2974 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00002975 return Py_BuildValue("(ii)", pid, master_fd);
2976}
2977#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002978
Guido van Rossumad0ee831995-03-01 10:34:45 +00002979#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002980PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002981"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002982Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002983
Barry Warsaw53699e91996-12-10 23:23:01 +00002984static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002985posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002986{
Barry Warsaw53699e91996-12-10 23:23:01 +00002987 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002988}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002989#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002990
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002991
Guido van Rossumad0ee831995-03-01 10:34:45 +00002992#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002993PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002994"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002995Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002996
Barry Warsaw53699e91996-12-10 23:23:01 +00002997static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002998posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002999{
Barry Warsaw53699e91996-12-10 23:23:01 +00003000 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003001}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003002#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003003
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003004
Guido van Rossumad0ee831995-03-01 10:34:45 +00003005#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003006PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003007"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003008Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003009
Barry Warsaw53699e91996-12-10 23:23:01 +00003010static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003011posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003012{
Barry Warsaw53699e91996-12-10 23:23:01 +00003013 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003014}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003015#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003016
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003017
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003018PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003019"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003020Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003021
Barry Warsaw53699e91996-12-10 23:23:01 +00003022static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003023posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003024{
Barry Warsaw53699e91996-12-10 23:23:01 +00003025 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003026}
3027
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003028
Fred Drakec9680921999-12-13 16:37:25 +00003029#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003030PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003031"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003032Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00003033
3034static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003035posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00003036{
3037 PyObject *result = NULL;
3038
Fred Drakec9680921999-12-13 16:37:25 +00003039#ifdef NGROUPS_MAX
3040#define MAX_GROUPS NGROUPS_MAX
3041#else
3042 /* defined to be 16 on Solaris7, so this should be a small number */
3043#define MAX_GROUPS 64
3044#endif
3045 gid_t grouplist[MAX_GROUPS];
3046 int n;
3047
3048 n = getgroups(MAX_GROUPS, grouplist);
3049 if (n < 0)
3050 posix_error();
3051 else {
3052 result = PyList_New(n);
3053 if (result != NULL) {
Fred Drakec9680921999-12-13 16:37:25 +00003054 int i;
3055 for (i = 0; i < n; ++i) {
Neal Norwitze241ce82003-02-17 18:17:05 +00003056 PyObject *o = PyInt_FromLong((long)grouplist[i]);
Fred Drakec9680921999-12-13 16:37:25 +00003057 if (o == NULL) {
3058 Py_DECREF(result);
3059 result = NULL;
3060 break;
3061 }
3062 PyList_SET_ITEM(result, i, o);
3063 }
3064 }
3065 }
Neal Norwitze241ce82003-02-17 18:17:05 +00003066
Fred Drakec9680921999-12-13 16:37:25 +00003067 return result;
3068}
3069#endif
3070
Martin v. Löwis606edc12002-06-13 21:09:11 +00003071#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003072PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003073"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003074Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00003075
3076static PyObject *
3077posix_getpgid(PyObject *self, PyObject *args)
3078{
3079 int pid, pgid;
3080 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
3081 return NULL;
3082 pgid = getpgid(pid);
3083 if (pgid < 0)
3084 return posix_error();
3085 return PyInt_FromLong((long)pgid);
3086}
3087#endif /* HAVE_GETPGID */
3088
3089
Guido van Rossumb6775db1994-08-01 11:34:53 +00003090#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003091PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003092"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003093Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003094
Barry Warsaw53699e91996-12-10 23:23:01 +00003095static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003096posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00003097{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003098#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00003099 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003100#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00003101 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003102#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00003103}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003104#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00003105
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003106
Guido van Rossumb6775db1994-08-01 11:34:53 +00003107#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003108PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003109"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003110Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003111
Barry Warsaw53699e91996-12-10 23:23:01 +00003112static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003113posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003114{
Guido van Rossum64933891994-10-20 21:56:42 +00003115#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00003116 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003117#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003118 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003119#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00003120 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003121 Py_INCREF(Py_None);
3122 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003123}
3124
Guido van Rossumb6775db1994-08-01 11:34:53 +00003125#endif /* HAVE_SETPGRP */
3126
Guido van Rossumad0ee831995-03-01 10:34:45 +00003127#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003128PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003129"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003130Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003131
Barry Warsaw53699e91996-12-10 23:23:01 +00003132static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003133posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003134{
Barry Warsaw53699e91996-12-10 23:23:01 +00003135 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003136}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003137#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003138
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003139
Fred Drake12c6e2d1999-12-14 21:25:03 +00003140#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003141PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003142"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003143Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00003144
3145static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003146posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00003147{
Neal Norwitze241ce82003-02-17 18:17:05 +00003148 PyObject *result = NULL;
Fred Drakea30680b2000-12-06 21:24:28 +00003149 char *name;
3150 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00003151
Fred Drakea30680b2000-12-06 21:24:28 +00003152 errno = 0;
3153 name = getlogin();
3154 if (name == NULL) {
3155 if (errno)
3156 posix_error();
3157 else
3158 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00003159 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00003160 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00003161 else
3162 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00003163 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00003164
Fred Drake12c6e2d1999-12-14 21:25:03 +00003165 return result;
3166}
3167#endif
3168
Guido van Rossumad0ee831995-03-01 10:34:45 +00003169#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003170PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003171"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003172Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003173
Barry Warsaw53699e91996-12-10 23:23:01 +00003174static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003175posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003176{
Barry Warsaw53699e91996-12-10 23:23:01 +00003177 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003178}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003179#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003180
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003181
Guido van Rossumad0ee831995-03-01 10:34:45 +00003182#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003183PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003184"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003185Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003186
Barry Warsaw53699e91996-12-10 23:23:01 +00003187static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003188posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003189{
3190 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003191 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00003192 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003193#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003194 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
3195 APIRET rc;
3196 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003197 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003198
3199 } else if (sig == XCPT_SIGNAL_KILLPROC) {
3200 APIRET rc;
3201 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003202 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003203
3204 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003205 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003206#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00003207 if (kill(pid, sig) == -1)
3208 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003209#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003210 Py_INCREF(Py_None);
3211 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003212}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003213#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003214
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003215#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003216PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003217"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003218Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003219
3220static PyObject *
3221posix_killpg(PyObject *self, PyObject *args)
3222{
3223 int pgid, sig;
3224 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
3225 return NULL;
3226 if (killpg(pgid, sig) == -1)
3227 return posix_error();
3228 Py_INCREF(Py_None);
3229 return Py_None;
3230}
3231#endif
3232
Guido van Rossumc0125471996-06-28 18:55:32 +00003233#ifdef HAVE_PLOCK
3234
3235#ifdef HAVE_SYS_LOCK_H
3236#include <sys/lock.h>
3237#endif
3238
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003239PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003240"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003241Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003242
Barry Warsaw53699e91996-12-10 23:23:01 +00003243static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003244posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00003245{
3246 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003247 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00003248 return NULL;
3249 if (plock(op) == -1)
3250 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003251 Py_INCREF(Py_None);
3252 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00003253}
3254#endif
3255
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003256
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003257#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003258PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003259"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003260Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003261
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003262#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003263#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003264static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003265async_system(const char *command)
3266{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003267 char errormsg[256], args[1024];
3268 RESULTCODES rcodes;
3269 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003270
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003271 char *shell = getenv("COMSPEC");
3272 if (!shell)
3273 shell = "cmd";
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003274
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003275 /* avoid overflowing the argument buffer */
3276 if (strlen(shell) + 3 + strlen(command) >= 1024)
3277 return ERROR_NOT_ENOUGH_MEMORY
3278
3279 args[0] = '\0';
3280 strcat(args, shell);
3281 strcat(args, "/c ");
3282 strcat(args, command);
3283
3284 /* execute asynchronously, inheriting the environment */
3285 rc = DosExecPgm(errormsg,
3286 sizeof(errormsg),
3287 EXEC_ASYNC,
3288 args,
3289 NULL,
3290 &rcodes,
3291 shell);
3292 return rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003293}
3294
Guido van Rossumd48f2521997-12-05 22:19:34 +00003295static FILE *
3296popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003297{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003298 int oldfd, tgtfd;
3299 HFILE pipeh[2];
3300 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003301
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003302 /* mode determines which of stdin or stdout is reconnected to
3303 * the pipe to the child
3304 */
3305 if (strchr(mode, 'r') != NULL) {
3306 tgt_fd = 1; /* stdout */
3307 } else if (strchr(mode, 'w')) {
3308 tgt_fd = 0; /* stdin */
3309 } else {
3310 *err = ERROR_INVALID_ACCESS;
3311 return NULL;
3312 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003313
Andrew MacIntyrea3be2582004-12-18 09:51:05 +00003314 /* setup the pipe */
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003315 if ((rc = DosCreatePipe(&pipeh[0], &pipeh[1], pipesize)) != NO_ERROR) {
3316 *err = rc;
3317 return NULL;
3318 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003319
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003320 /* prevent other threads accessing stdio */
3321 DosEnterCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003322
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003323 /* reconnect stdio and execute child */
3324 oldfd = dup(tgtfd);
3325 close(tgtfd);
3326 if (dup2(pipeh[tgtfd], tgtfd) == 0) {
3327 DosClose(pipeh[tgtfd]);
3328 rc = async_system(command);
3329 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003330
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003331 /* restore stdio */
3332 dup2(oldfd, tgtfd);
3333 close(oldfd);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003334
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003335 /* allow other threads access to stdio */
3336 DosExitCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003337
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003338 /* if execution of child was successful return file stream */
3339 if (rc == NO_ERROR)
3340 return fdopen(pipeh[1 - tgtfd], mode);
3341 else {
3342 DosClose(pipeh[1 - tgtfd]);
3343 *err = rc;
3344 return NULL;
3345 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003346}
3347
3348static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003349posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003350{
3351 char *name;
3352 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00003353 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003354 FILE *fp;
3355 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003356 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003357 return NULL;
3358 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00003359 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003360 Py_END_ALLOW_THREADS
3361 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003362 return os2_error(err);
3363
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003364 f = PyFile_FromFile(fp, name, mode, fclose);
3365 if (f != NULL)
3366 PyFile_SetBufSize(f, bufsize);
3367 return f;
3368}
3369
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003370#elif defined(PYCC_GCC)
3371
3372/* standard posix version of popen() support */
3373static PyObject *
3374posix_popen(PyObject *self, PyObject *args)
3375{
3376 char *name;
3377 char *mode = "r";
3378 int bufsize = -1;
3379 FILE *fp;
3380 PyObject *f;
3381 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
3382 return NULL;
3383 Py_BEGIN_ALLOW_THREADS
3384 fp = popen(name, mode);
3385 Py_END_ALLOW_THREADS
3386 if (fp == NULL)
3387 return posix_error();
3388 f = PyFile_FromFile(fp, name, mode, pclose);
3389 if (f != NULL)
3390 PyFile_SetBufSize(f, bufsize);
3391 return f;
3392}
3393
3394/* fork() under OS/2 has lots'o'warts
3395 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
3396 * most of this code is a ripoff of the win32 code, but using the
3397 * capabilities of EMX's C library routines
3398 */
3399
3400/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
3401#define POPEN_1 1
3402#define POPEN_2 2
3403#define POPEN_3 3
3404#define POPEN_4 4
3405
3406static PyObject *_PyPopen(char *, int, int, int);
3407static int _PyPclose(FILE *file);
3408
3409/*
3410 * Internal dictionary mapping popen* file pointers to process handles,
3411 * for use when retrieving the process exit code. See _PyPclose() below
3412 * for more information on this dictionary's use.
3413 */
3414static PyObject *_PyPopenProcs = NULL;
3415
3416/* os2emx version of popen2()
3417 *
3418 * The result of this function is a pipe (file) connected to the
3419 * process's stdin, and a pipe connected to the process's stdout.
3420 */
3421
3422static PyObject *
3423os2emx_popen2(PyObject *self, PyObject *args)
3424{
3425 PyObject *f;
3426 int tm=0;
3427
3428 char *cmdstring;
3429 char *mode = "t";
3430 int bufsize = -1;
3431 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
3432 return NULL;
3433
3434 if (*mode == 't')
3435 tm = O_TEXT;
3436 else if (*mode != 'b') {
3437 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3438 return NULL;
3439 } else
3440 tm = O_BINARY;
3441
3442 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
3443
3444 return f;
3445}
3446
3447/*
3448 * Variation on os2emx.popen2
3449 *
3450 * The result of this function is 3 pipes - the process's stdin,
3451 * stdout and stderr
3452 */
3453
3454static PyObject *
3455os2emx_popen3(PyObject *self, PyObject *args)
3456{
3457 PyObject *f;
3458 int tm = 0;
3459
3460 char *cmdstring;
3461 char *mode = "t";
3462 int bufsize = -1;
3463 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
3464 return NULL;
3465
3466 if (*mode == 't')
3467 tm = O_TEXT;
3468 else if (*mode != 'b') {
3469 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3470 return NULL;
3471 } else
3472 tm = O_BINARY;
3473
3474 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
3475
3476 return f;
3477}
3478
3479/*
3480 * Variation on os2emx.popen2
3481 *
Tim Peters11b23062003-04-23 02:39:17 +00003482 * The result of this function is 2 pipes - the processes stdin,
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003483 * and stdout+stderr combined as a single pipe.
3484 */
3485
3486static PyObject *
3487os2emx_popen4(PyObject *self, PyObject *args)
3488{
3489 PyObject *f;
3490 int tm = 0;
3491
3492 char *cmdstring;
3493 char *mode = "t";
3494 int bufsize = -1;
3495 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
3496 return NULL;
3497
3498 if (*mode == 't')
3499 tm = O_TEXT;
3500 else if (*mode != 'b') {
3501 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3502 return NULL;
3503 } else
3504 tm = O_BINARY;
3505
3506 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
3507
3508 return f;
3509}
3510
3511/* a couple of structures for convenient handling of multiple
3512 * file handles and pipes
3513 */
3514struct file_ref
3515{
3516 int handle;
3517 int flags;
3518};
3519
3520struct pipe_ref
3521{
3522 int rd;
3523 int wr;
3524};
3525
3526/* The following code is derived from the win32 code */
3527
3528static PyObject *
3529_PyPopen(char *cmdstring, int mode, int n, int bufsize)
3530{
3531 struct file_ref stdio[3];
3532 struct pipe_ref p_fd[3];
3533 FILE *p_s[3];
3534 int file_count, i, pipe_err, pipe_pid;
3535 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
3536 PyObject *f, *p_f[3];
3537
3538 /* file modes for subsequent fdopen's on pipe handles */
3539 if (mode == O_TEXT)
3540 {
3541 rd_mode = "rt";
3542 wr_mode = "wt";
3543 }
3544 else
3545 {
3546 rd_mode = "rb";
3547 wr_mode = "wb";
3548 }
3549
3550 /* prepare shell references */
3551 if ((shell = getenv("EMXSHELL")) == NULL)
3552 if ((shell = getenv("COMSPEC")) == NULL)
3553 {
3554 errno = ENOENT;
3555 return posix_error();
3556 }
3557
3558 sh_name = _getname(shell);
3559 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
3560 opt = "/c";
3561 else
3562 opt = "-c";
3563
3564 /* save current stdio fds + their flags, and set not inheritable */
3565 i = pipe_err = 0;
3566 while (pipe_err >= 0 && i < 3)
3567 {
3568 pipe_err = stdio[i].handle = dup(i);
3569 stdio[i].flags = fcntl(i, F_GETFD, 0);
3570 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
3571 i++;
3572 }
3573 if (pipe_err < 0)
3574 {
3575 /* didn't get them all saved - clean up and bail out */
3576 int saved_err = errno;
3577 while (i-- > 0)
3578 {
3579 close(stdio[i].handle);
3580 }
3581 errno = saved_err;
3582 return posix_error();
3583 }
3584
3585 /* create pipe ends */
3586 file_count = 2;
3587 if (n == POPEN_3)
3588 file_count = 3;
3589 i = pipe_err = 0;
3590 while ((pipe_err == 0) && (i < file_count))
3591 pipe_err = pipe((int *)&p_fd[i++]);
3592 if (pipe_err < 0)
3593 {
3594 /* didn't get them all made - clean up and bail out */
3595 while (i-- > 0)
3596 {
3597 close(p_fd[i].wr);
3598 close(p_fd[i].rd);
3599 }
3600 errno = EPIPE;
3601 return posix_error();
3602 }
3603
3604 /* change the actual standard IO streams over temporarily,
3605 * making the retained pipe ends non-inheritable
3606 */
3607 pipe_err = 0;
3608
3609 /* - stdin */
3610 if (dup2(p_fd[0].rd, 0) == 0)
3611 {
3612 close(p_fd[0].rd);
3613 i = fcntl(p_fd[0].wr, F_GETFD, 0);
3614 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
3615 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
3616 {
3617 close(p_fd[0].wr);
3618 pipe_err = -1;
3619 }
3620 }
3621 else
3622 {
3623 pipe_err = -1;
3624 }
3625
3626 /* - stdout */
3627 if (pipe_err == 0)
3628 {
3629 if (dup2(p_fd[1].wr, 1) == 1)
3630 {
3631 close(p_fd[1].wr);
3632 i = fcntl(p_fd[1].rd, F_GETFD, 0);
3633 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
3634 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
3635 {
3636 close(p_fd[1].rd);
3637 pipe_err = -1;
3638 }
3639 }
3640 else
3641 {
3642 pipe_err = -1;
3643 }
3644 }
3645
3646 /* - stderr, as required */
3647 if (pipe_err == 0)
3648 switch (n)
3649 {
3650 case POPEN_3:
3651 {
3652 if (dup2(p_fd[2].wr, 2) == 2)
3653 {
3654 close(p_fd[2].wr);
3655 i = fcntl(p_fd[2].rd, F_GETFD, 0);
3656 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
3657 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
3658 {
3659 close(p_fd[2].rd);
3660 pipe_err = -1;
3661 }
3662 }
3663 else
3664 {
3665 pipe_err = -1;
3666 }
3667 break;
3668 }
3669
3670 case POPEN_4:
3671 {
3672 if (dup2(1, 2) != 2)
3673 {
3674 pipe_err = -1;
3675 }
3676 break;
3677 }
3678 }
3679
3680 /* spawn the child process */
3681 if (pipe_err == 0)
3682 {
3683 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
3684 if (pipe_pid == -1)
3685 {
3686 pipe_err = -1;
3687 }
3688 else
3689 {
3690 /* save the PID into the FILE structure
3691 * NOTE: this implementation doesn't actually
3692 * take advantage of this, but do it for
3693 * completeness - AIM Apr01
3694 */
3695 for (i = 0; i < file_count; i++)
3696 p_s[i]->_pid = pipe_pid;
3697 }
3698 }
3699
3700 /* reset standard IO to normal */
3701 for (i = 0; i < 3; i++)
3702 {
3703 dup2(stdio[i].handle, i);
3704 fcntl(i, F_SETFD, stdio[i].flags);
3705 close(stdio[i].handle);
3706 }
3707
3708 /* if any remnant problems, clean up and bail out */
3709 if (pipe_err < 0)
3710 {
3711 for (i = 0; i < 3; i++)
3712 {
3713 close(p_fd[i].rd);
3714 close(p_fd[i].wr);
3715 }
3716 errno = EPIPE;
3717 return posix_error_with_filename(cmdstring);
3718 }
3719
3720 /* build tuple of file objects to return */
3721 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
3722 PyFile_SetBufSize(p_f[0], bufsize);
3723 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
3724 PyFile_SetBufSize(p_f[1], bufsize);
3725 if (n == POPEN_3)
3726 {
3727 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
3728 PyFile_SetBufSize(p_f[0], bufsize);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00003729 f = PyTuple_Pack(3, p_f[0], p_f[1], p_f[2]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003730 }
3731 else
Raymond Hettinger8ae46892003-10-12 19:09:37 +00003732 f = PyTuple_Pack(2, p_f[0], p_f[1]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003733
3734 /*
3735 * Insert the files we've created into the process dictionary
3736 * all referencing the list with the process handle and the
3737 * initial number of files (see description below in _PyPclose).
3738 * Since if _PyPclose later tried to wait on a process when all
3739 * handles weren't closed, it could create a deadlock with the
3740 * child, we spend some energy here to try to ensure that we
3741 * either insert all file handles into the dictionary or none
3742 * at all. It's a little clumsy with the various popen modes
3743 * and variable number of files involved.
3744 */
3745 if (!_PyPopenProcs)
3746 {
3747 _PyPopenProcs = PyDict_New();
3748 }
3749
3750 if (_PyPopenProcs)
3751 {
3752 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
3753 int ins_rc[3];
3754
3755 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
3756 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
3757
3758 procObj = PyList_New(2);
3759 pidObj = PyInt_FromLong((long) pipe_pid);
3760 intObj = PyInt_FromLong((long) file_count);
3761
3762 if (procObj && pidObj && intObj)
3763 {
3764 PyList_SetItem(procObj, 0, pidObj);
3765 PyList_SetItem(procObj, 1, intObj);
3766
3767 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
3768 if (fileObj[0])
3769 {
3770 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
3771 fileObj[0],
3772 procObj);
3773 }
3774 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
3775 if (fileObj[1])
3776 {
3777 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
3778 fileObj[1],
3779 procObj);
3780 }
3781 if (file_count >= 3)
3782 {
3783 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
3784 if (fileObj[2])
3785 {
3786 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
3787 fileObj[2],
3788 procObj);
3789 }
3790 }
3791
3792 if (ins_rc[0] < 0 || !fileObj[0] ||
3793 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
3794 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
3795 {
3796 /* Something failed - remove any dictionary
3797 * entries that did make it.
3798 */
3799 if (!ins_rc[0] && fileObj[0])
3800 {
3801 PyDict_DelItem(_PyPopenProcs,
3802 fileObj[0]);
3803 }
3804 if (!ins_rc[1] && fileObj[1])
3805 {
3806 PyDict_DelItem(_PyPopenProcs,
3807 fileObj[1]);
3808 }
3809 if (!ins_rc[2] && fileObj[2])
3810 {
3811 PyDict_DelItem(_PyPopenProcs,
3812 fileObj[2]);
3813 }
3814 }
3815 }
Tim Peters11b23062003-04-23 02:39:17 +00003816
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003817 /*
3818 * Clean up our localized references for the dictionary keys
3819 * and value since PyDict_SetItem will Py_INCREF any copies
3820 * that got placed in the dictionary.
3821 */
3822 Py_XDECREF(procObj);
3823 Py_XDECREF(fileObj[0]);
3824 Py_XDECREF(fileObj[1]);
3825 Py_XDECREF(fileObj[2]);
3826 }
3827
3828 /* Child is launched. */
3829 return f;
3830}
3831
3832/*
3833 * Wrapper for fclose() to use for popen* files, so we can retrieve the
3834 * exit code for the child process and return as a result of the close.
3835 *
3836 * This function uses the _PyPopenProcs dictionary in order to map the
3837 * input file pointer to information about the process that was
3838 * originally created by the popen* call that created the file pointer.
3839 * The dictionary uses the file pointer as a key (with one entry
3840 * inserted for each file returned by the original popen* call) and a
3841 * single list object as the value for all files from a single call.
3842 * The list object contains the Win32 process handle at [0], and a file
3843 * count at [1], which is initialized to the total number of file
3844 * handles using that list.
3845 *
3846 * This function closes whichever handle it is passed, and decrements
3847 * the file count in the dictionary for the process handle pointed to
3848 * by this file. On the last close (when the file count reaches zero),
3849 * this function will wait for the child process and then return its
3850 * exit code as the result of the close() operation. This permits the
3851 * files to be closed in any order - it is always the close() of the
3852 * final handle that will return the exit code.
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00003853 *
3854 * NOTE: This function is currently called with the GIL released.
3855 * hence we use the GILState API to manage our state.
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003856 */
3857
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003858static int _PyPclose(FILE *file)
3859{
3860 int result;
3861 int exit_code;
3862 int pipe_pid;
3863 PyObject *procObj, *pidObj, *intObj, *fileObj;
3864 int file_count;
3865#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00003866 PyGILState_STATE state;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003867#endif
3868
3869 /* Close the file handle first, to ensure it can't block the
3870 * child from exiting if it's the last handle.
3871 */
3872 result = fclose(file);
3873
3874#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00003875 state = PyGILState_Ensure();
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003876#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003877 if (_PyPopenProcs)
3878 {
3879 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
3880 (procObj = PyDict_GetItem(_PyPopenProcs,
3881 fileObj)) != NULL &&
3882 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
3883 (intObj = PyList_GetItem(procObj,1)) != NULL)
3884 {
3885 pipe_pid = (int) PyInt_AsLong(pidObj);
3886 file_count = (int) PyInt_AsLong(intObj);
3887
3888 if (file_count > 1)
3889 {
3890 /* Still other files referencing process */
3891 file_count--;
3892 PyList_SetItem(procObj,1,
3893 PyInt_FromLong((long) file_count));
3894 }
3895 else
3896 {
3897 /* Last file for this process */
3898 if (result != EOF &&
3899 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
3900 {
3901 /* extract exit status */
3902 if (WIFEXITED(exit_code))
3903 {
3904 result = WEXITSTATUS(exit_code);
3905 }
3906 else
3907 {
3908 errno = EPIPE;
3909 result = -1;
3910 }
3911 }
3912 else
3913 {
3914 /* Indicate failure - this will cause the file object
3915 * to raise an I/O error and translate the last
3916 * error code from errno. We do have a problem with
3917 * last errors that overlap the normal errno table,
3918 * but that's a consistent problem with the file object.
3919 */
3920 result = -1;
3921 }
3922 }
3923
3924 /* Remove this file pointer from dictionary */
3925 PyDict_DelItem(_PyPopenProcs, fileObj);
3926
3927 if (PyDict_Size(_PyPopenProcs) == 0)
3928 {
3929 Py_DECREF(_PyPopenProcs);
3930 _PyPopenProcs = NULL;
3931 }
3932
3933 } /* if object retrieval ok */
3934
3935 Py_XDECREF(fileObj);
3936 } /* if _PyPopenProcs */
3937
3938#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00003939 PyGILState_Release(state);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003940#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003941 return result;
3942}
3943
3944#endif /* PYCC_??? */
3945
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003946#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003947
3948/*
3949 * Portable 'popen' replacement for Win32.
3950 *
3951 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
3952 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00003953 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003954 */
3955
3956#include <malloc.h>
3957#include <io.h>
3958#include <fcntl.h>
3959
3960/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
3961#define POPEN_1 1
3962#define POPEN_2 2
3963#define POPEN_3 3
3964#define POPEN_4 4
3965
3966static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003967static int _PyPclose(FILE *file);
3968
3969/*
3970 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00003971 * for use when retrieving the process exit code. See _PyPclose() below
3972 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003973 */
3974static PyObject *_PyPopenProcs = NULL;
3975
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003976
3977/* popen that works from a GUI.
3978 *
3979 * The result of this function is a pipe (file) connected to the
3980 * processes stdin or stdout, depending on the requested mode.
3981 */
3982
3983static PyObject *
3984posix_popen(PyObject *self, PyObject *args)
3985{
Raymond Hettingerb5cb6652003-09-01 22:25:41 +00003986 PyObject *f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003987 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003988
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003989 char *cmdstring;
3990 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003991 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003992 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003993 return NULL;
3994
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003995 if (*mode == 'r')
3996 tm = _O_RDONLY;
3997 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00003998 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003999 return NULL;
4000 } else
4001 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00004002
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004003 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004004 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004005 return NULL;
4006 }
4007
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004008 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004009 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004010 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004011 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004012 else
4013 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
4014
4015 return f;
4016}
4017
4018/* Variation on win32pipe.popen
4019 *
4020 * The result of this function is a pipe (file) connected to the
4021 * process's stdin, and a pipe connected to the process's stdout.
4022 */
4023
4024static PyObject *
4025win32_popen2(PyObject *self, PyObject *args)
4026{
4027 PyObject *f;
4028 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00004029
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004030 char *cmdstring;
4031 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004032 int bufsize = -1;
4033 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004034 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004035
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004036 if (*mode == 't')
4037 tm = _O_TEXT;
4038 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004039 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004040 return NULL;
4041 } else
4042 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004043
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004044 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004045 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004046 return NULL;
4047 }
4048
4049 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00004050
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004051 return f;
4052}
4053
4054/*
4055 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004056 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004057 * The result of this function is 3 pipes - the process's stdin,
4058 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004059 */
4060
4061static PyObject *
4062win32_popen3(PyObject *self, PyObject *args)
4063{
4064 PyObject *f;
4065 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004066
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004067 char *cmdstring;
4068 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004069 int bufsize = -1;
4070 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004071 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004072
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004073 if (*mode == 't')
4074 tm = _O_TEXT;
4075 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004076 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004077 return NULL;
4078 } else
4079 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004080
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004081 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004082 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004083 return NULL;
4084 }
4085
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004086 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00004087
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004088 return f;
4089}
4090
4091/*
4092 * Variation on win32pipe.popen
4093 *
Tim Peters5aa91602002-01-30 05:46:57 +00004094 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004095 * and stdout+stderr combined as a single pipe.
4096 */
4097
4098static PyObject *
4099win32_popen4(PyObject *self, PyObject *args)
4100{
4101 PyObject *f;
4102 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004103
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004104 char *cmdstring;
4105 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004106 int bufsize = -1;
4107 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004108 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004109
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004110 if (*mode == 't')
4111 tm = _O_TEXT;
4112 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004113 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004114 return NULL;
4115 } else
4116 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004117
4118 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004119 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004120 return NULL;
4121 }
4122
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004123 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004124
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004125 return f;
4126}
4127
Mark Hammond08501372001-01-31 07:30:29 +00004128static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00004129_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004130 HANDLE hStdin,
4131 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00004132 HANDLE hStderr,
4133 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004134{
4135 PROCESS_INFORMATION piProcInfo;
4136 STARTUPINFO siStartInfo;
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004137 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004138 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00004139 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004140 int i;
4141 int x;
4142
4143 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00004144 char *comshell;
4145
Tim Peters92e4dd82002-10-05 01:47:34 +00004146 s1 = (char *)alloca(i);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004147 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
4148 return x;
Tim Peters402d5982001-08-27 06:37:48 +00004149
4150 /* Explicitly check if we are using COMMAND.COM. If we are
4151 * then use the w9xpopen hack.
4152 */
4153 comshell = s1 + x;
4154 while (comshell >= s1 && *comshell != '\\')
4155 --comshell;
4156 ++comshell;
4157
4158 if (GetVersion() < 0x80000000 &&
4159 _stricmp(comshell, "command.com") != 0) {
4160 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004161 x = i + strlen(s3) + strlen(cmdstring) + 1;
Tim Peters92e4dd82002-10-05 01:47:34 +00004162 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004163 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00004164 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004165 }
4166 else {
4167 /*
Tim Peters402d5982001-08-27 06:37:48 +00004168 * Oh gag, we're on Win9x or using COMMAND.COM. Use
4169 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004170 */
Mark Hammond08501372001-01-31 07:30:29 +00004171 char modulepath[_MAX_PATH];
4172 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004173 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
4174 for (i = x = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004175 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004176 x = i+1;
4177 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00004178 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00004179 strncat(modulepath,
4180 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00004181 (sizeof(modulepath)/sizeof(modulepath[0]))
4182 -strlen(modulepath));
4183 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00004184 /* Eeek - file-not-found - possibly an embedding
4185 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00004186 */
Tim Peters5aa91602002-01-30 05:46:57 +00004187 strncpy(modulepath,
4188 Py_GetExecPrefix(),
Mark Hammond08501372001-01-31 07:30:29 +00004189 sizeof(modulepath)/sizeof(modulepath[0]));
4190 if (modulepath[strlen(modulepath)-1] != '\\')
4191 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00004192 strncat(modulepath,
4193 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00004194 (sizeof(modulepath)/sizeof(modulepath[0]))
4195 -strlen(modulepath));
4196 /* No where else to look - raise an easily identifiable
4197 error, rather than leaving Windows to report
4198 "file not found" - as the user is probably blissfully
4199 unaware this shim EXE is used, and it will confuse them.
4200 (well, it confused me for a while ;-)
4201 */
4202 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00004203 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00004204 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00004205 "for popen to work with your shell "
4206 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00004207 szConsoleSpawn);
4208 return FALSE;
4209 }
4210 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004211 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00004212 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004213 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00004214
Tim Peters92e4dd82002-10-05 01:47:34 +00004215 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004216 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004217 /* To maintain correct argument passing semantics,
4218 we pass the command-line as it stands, and allow
4219 quoting to be applied. w9xpopen.exe will then
4220 use its argv vector, and re-quote the necessary
4221 args for the ultimate child process.
4222 */
Tim Peters75cdad52001-11-28 22:07:30 +00004223 PyOS_snprintf(
4224 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004225 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004226 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004227 s1,
4228 s3,
4229 cmdstring);
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004230 /* Not passing CREATE_NEW_CONSOLE has been known to
Tim Peters11b23062003-04-23 02:39:17 +00004231 cause random failures on win9x. Specifically a
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004232 dialog:
4233 "Your program accessed mem currently in use at xxx"
4234 and a hopeful warning about the stability of your
4235 system.
4236 Cost is Ctrl+C wont kill children, but anyone
4237 who cares can have a go!
4238 */
4239 dwProcessFlags |= CREATE_NEW_CONSOLE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004240 }
4241 }
4242
4243 /* Could be an else here to try cmd.exe / command.com in the path
4244 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00004245 else {
Tim Peters402d5982001-08-27 06:37:48 +00004246 PyErr_SetString(PyExc_RuntimeError,
4247 "Cannot locate a COMSPEC environment variable to "
4248 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00004249 return FALSE;
4250 }
Tim Peters5aa91602002-01-30 05:46:57 +00004251
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004252 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
4253 siStartInfo.cb = sizeof(STARTUPINFO);
4254 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
4255 siStartInfo.hStdInput = hStdin;
4256 siStartInfo.hStdOutput = hStdout;
4257 siStartInfo.hStdError = hStderr;
4258 siStartInfo.wShowWindow = SW_HIDE;
4259
4260 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004261 s2,
4262 NULL,
4263 NULL,
4264 TRUE,
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004265 dwProcessFlags,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004266 NULL,
4267 NULL,
4268 &siStartInfo,
4269 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004270 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004271 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004272
Mark Hammondb37a3732000-08-14 04:47:33 +00004273 /* Return process handle */
4274 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004275 return TRUE;
4276 }
Tim Peters402d5982001-08-27 06:37:48 +00004277 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004278 return FALSE;
4279}
4280
4281/* The following code is based off of KB: Q190351 */
4282
4283static PyObject *
4284_PyPopen(char *cmdstring, int mode, int n)
4285{
4286 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
4287 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00004288 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00004289
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004290 SECURITY_ATTRIBUTES saAttr;
4291 BOOL fSuccess;
4292 int fd1, fd2, fd3;
4293 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00004294 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004295 PyObject *f;
4296
4297 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
4298 saAttr.bInheritHandle = TRUE;
4299 saAttr.lpSecurityDescriptor = NULL;
4300
4301 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
4302 return win32_error("CreatePipe", NULL);
4303
4304 /* Create new output read handle and the input write handle. Set
4305 * the inheritance properties to FALSE. Otherwise, the child inherits
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00004306 * these handles; resulting in non-closeable handles to the pipes
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004307 * being created. */
4308 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004309 GetCurrentProcess(), &hChildStdinWrDup, 0,
4310 FALSE,
4311 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004312 if (!fSuccess)
4313 return win32_error("DuplicateHandle", NULL);
4314
4315 /* Close the inheritable version of ChildStdin
4316 that we're using. */
4317 CloseHandle(hChildStdinWr);
4318
4319 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
4320 return win32_error("CreatePipe", NULL);
4321
4322 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004323 GetCurrentProcess(), &hChildStdoutRdDup, 0,
4324 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004325 if (!fSuccess)
4326 return win32_error("DuplicateHandle", NULL);
4327
4328 /* Close the inheritable version of ChildStdout
4329 that we're using. */
4330 CloseHandle(hChildStdoutRd);
4331
4332 if (n != POPEN_4) {
4333 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
4334 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004335 fSuccess = DuplicateHandle(GetCurrentProcess(),
4336 hChildStderrRd,
4337 GetCurrentProcess(),
4338 &hChildStderrRdDup, 0,
4339 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004340 if (!fSuccess)
4341 return win32_error("DuplicateHandle", NULL);
4342 /* Close the inheritable version of ChildStdErr that we're using. */
4343 CloseHandle(hChildStderrRd);
4344 }
Tim Peters5aa91602002-01-30 05:46:57 +00004345
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004346 switch (n) {
4347 case POPEN_1:
4348 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
4349 case _O_WRONLY | _O_TEXT:
4350 /* Case for writing to child Stdin in text mode. */
4351 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4352 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004353 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004354 PyFile_SetBufSize(f, 0);
4355 /* We don't care about these pipes anymore, so close them. */
4356 CloseHandle(hChildStdoutRdDup);
4357 CloseHandle(hChildStderrRdDup);
4358 break;
4359
4360 case _O_RDONLY | _O_TEXT:
4361 /* Case for reading from child Stdout in text mode. */
4362 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4363 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004364 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004365 PyFile_SetBufSize(f, 0);
4366 /* We don't care about these pipes anymore, so close them. */
4367 CloseHandle(hChildStdinWrDup);
4368 CloseHandle(hChildStderrRdDup);
4369 break;
4370
4371 case _O_RDONLY | _O_BINARY:
4372 /* Case for readinig from child Stdout in binary mode. */
4373 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4374 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004375 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004376 PyFile_SetBufSize(f, 0);
4377 /* We don't care about these pipes anymore, so close them. */
4378 CloseHandle(hChildStdinWrDup);
4379 CloseHandle(hChildStderrRdDup);
4380 break;
4381
4382 case _O_WRONLY | _O_BINARY:
4383 /* Case for writing to child Stdin in binary mode. */
4384 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4385 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004386 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004387 PyFile_SetBufSize(f, 0);
4388 /* We don't care about these pipes anymore, so close them. */
4389 CloseHandle(hChildStdoutRdDup);
4390 CloseHandle(hChildStderrRdDup);
4391 break;
4392 }
Mark Hammondb37a3732000-08-14 04:47:33 +00004393 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004394 break;
Tim Peters5aa91602002-01-30 05:46:57 +00004395
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004396 case POPEN_2:
4397 case POPEN_4:
4398 {
4399 char *m1, *m2;
4400 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00004401
Tim Peters7dca21e2002-08-19 00:42:29 +00004402 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004403 m1 = "r";
4404 m2 = "w";
4405 } else {
4406 m1 = "rb";
4407 m2 = "wb";
4408 }
4409
4410 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4411 f1 = _fdopen(fd1, m2);
4412 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4413 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004414 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004415 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00004416 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004417 PyFile_SetBufSize(p2, 0);
4418
4419 if (n != 4)
4420 CloseHandle(hChildStderrRdDup);
4421
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004422 f = PyTuple_Pack(2,p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00004423 Py_XDECREF(p1);
4424 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00004425 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004426 break;
4427 }
Tim Peters5aa91602002-01-30 05:46:57 +00004428
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004429 case POPEN_3:
4430 {
4431 char *m1, *m2;
4432 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00004433
Tim Peters7dca21e2002-08-19 00:42:29 +00004434 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004435 m1 = "r";
4436 m2 = "w";
4437 } else {
4438 m1 = "rb";
4439 m2 = "wb";
4440 }
4441
4442 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4443 f1 = _fdopen(fd1, m2);
4444 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4445 f2 = _fdopen(fd2, m1);
4446 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
4447 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004448 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00004449 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
4450 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004451 PyFile_SetBufSize(p1, 0);
4452 PyFile_SetBufSize(p2, 0);
4453 PyFile_SetBufSize(p3, 0);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004454 f = PyTuple_Pack(3,p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00004455 Py_XDECREF(p1);
4456 Py_XDECREF(p2);
4457 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00004458 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004459 break;
4460 }
4461 }
4462
4463 if (n == POPEN_4) {
4464 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004465 hChildStdinRd,
4466 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004467 hChildStdoutWr,
4468 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004469 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004470 }
4471 else {
4472 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004473 hChildStdinRd,
4474 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004475 hChildStderrWr,
4476 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004477 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004478 }
4479
Mark Hammondb37a3732000-08-14 04:47:33 +00004480 /*
4481 * Insert the files we've created into the process dictionary
4482 * all referencing the list with the process handle and the
4483 * initial number of files (see description below in _PyPclose).
4484 * Since if _PyPclose later tried to wait on a process when all
4485 * handles weren't closed, it could create a deadlock with the
4486 * child, we spend some energy here to try to ensure that we
4487 * either insert all file handles into the dictionary or none
4488 * at all. It's a little clumsy with the various popen modes
4489 * and variable number of files involved.
4490 */
4491 if (!_PyPopenProcs) {
4492 _PyPopenProcs = PyDict_New();
4493 }
4494
4495 if (_PyPopenProcs) {
4496 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
4497 int ins_rc[3];
4498
4499 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4500 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4501
4502 procObj = PyList_New(2);
4503 hProcessObj = PyLong_FromVoidPtr(hProcess);
4504 intObj = PyInt_FromLong(file_count);
4505
4506 if (procObj && hProcessObj && intObj) {
4507 PyList_SetItem(procObj,0,hProcessObj);
4508 PyList_SetItem(procObj,1,intObj);
4509
4510 fileObj[0] = PyLong_FromVoidPtr(f1);
4511 if (fileObj[0]) {
4512 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4513 fileObj[0],
4514 procObj);
4515 }
4516 if (file_count >= 2) {
4517 fileObj[1] = PyLong_FromVoidPtr(f2);
4518 if (fileObj[1]) {
4519 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4520 fileObj[1],
4521 procObj);
4522 }
4523 }
4524 if (file_count >= 3) {
4525 fileObj[2] = PyLong_FromVoidPtr(f3);
4526 if (fileObj[2]) {
4527 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4528 fileObj[2],
4529 procObj);
4530 }
4531 }
4532
4533 if (ins_rc[0] < 0 || !fileObj[0] ||
4534 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4535 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
4536 /* Something failed - remove any dictionary
4537 * entries that did make it.
4538 */
4539 if (!ins_rc[0] && fileObj[0]) {
4540 PyDict_DelItem(_PyPopenProcs,
4541 fileObj[0]);
4542 }
4543 if (!ins_rc[1] && fileObj[1]) {
4544 PyDict_DelItem(_PyPopenProcs,
4545 fileObj[1]);
4546 }
4547 if (!ins_rc[2] && fileObj[2]) {
4548 PyDict_DelItem(_PyPopenProcs,
4549 fileObj[2]);
4550 }
4551 }
4552 }
Tim Peters5aa91602002-01-30 05:46:57 +00004553
Mark Hammondb37a3732000-08-14 04:47:33 +00004554 /*
4555 * Clean up our localized references for the dictionary keys
4556 * and value since PyDict_SetItem will Py_INCREF any copies
4557 * that got placed in the dictionary.
4558 */
4559 Py_XDECREF(procObj);
4560 Py_XDECREF(fileObj[0]);
4561 Py_XDECREF(fileObj[1]);
4562 Py_XDECREF(fileObj[2]);
4563 }
4564
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004565 /* Child is launched. Close the parents copy of those pipe
4566 * handles that only the child should have open. You need to
4567 * make sure that no handles to the write end of the output pipe
4568 * are maintained in this process or else the pipe will not close
4569 * when the child process exits and the ReadFile will hang. */
4570
4571 if (!CloseHandle(hChildStdinRd))
4572 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004573
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004574 if (!CloseHandle(hChildStdoutWr))
4575 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004576
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004577 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
4578 return win32_error("CloseHandle", NULL);
4579
4580 return f;
4581}
Fredrik Lundh56055a42000-07-23 19:47:12 +00004582
4583/*
4584 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4585 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00004586 *
4587 * This function uses the _PyPopenProcs dictionary in order to map the
4588 * input file pointer to information about the process that was
4589 * originally created by the popen* call that created the file pointer.
4590 * The dictionary uses the file pointer as a key (with one entry
4591 * inserted for each file returned by the original popen* call) and a
4592 * single list object as the value for all files from a single call.
4593 * The list object contains the Win32 process handle at [0], and a file
4594 * count at [1], which is initialized to the total number of file
4595 * handles using that list.
4596 *
4597 * This function closes whichever handle it is passed, and decrements
4598 * the file count in the dictionary for the process handle pointed to
4599 * by this file. On the last close (when the file count reaches zero),
4600 * this function will wait for the child process and then return its
4601 * exit code as the result of the close() operation. This permits the
4602 * files to be closed in any order - it is always the close() of the
4603 * final handle that will return the exit code.
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004604 *
4605 * NOTE: This function is currently called with the GIL released.
4606 * hence we use the GILState API to manage our state.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004607 */
Tim Peters736aa322000-09-01 06:51:24 +00004608
Fredrik Lundh56055a42000-07-23 19:47:12 +00004609static int _PyPclose(FILE *file)
4610{
Fredrik Lundh20318932000-07-26 17:29:12 +00004611 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004612 DWORD exit_code;
4613 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00004614 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
4615 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00004616#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004617 PyGILState_STATE state;
Tim Peters736aa322000-09-01 06:51:24 +00004618#endif
4619
Fredrik Lundh20318932000-07-26 17:29:12 +00004620 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00004621 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00004622 */
4623 result = fclose(file);
Tim Peters736aa322000-09-01 06:51:24 +00004624#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004625 state = PyGILState_Ensure();
Tim Peters736aa322000-09-01 06:51:24 +00004626#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00004627 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00004628 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4629 (procObj = PyDict_GetItem(_PyPopenProcs,
4630 fileObj)) != NULL &&
4631 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
4632 (intObj = PyList_GetItem(procObj,1)) != NULL) {
4633
4634 hProcess = PyLong_AsVoidPtr(hProcessObj);
4635 file_count = PyInt_AsLong(intObj);
4636
4637 if (file_count > 1) {
4638 /* Still other files referencing process */
4639 file_count--;
4640 PyList_SetItem(procObj,1,
4641 PyInt_FromLong(file_count));
4642 } else {
4643 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00004644 if (result != EOF &&
4645 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
4646 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00004647 /* Possible truncation here in 16-bit environments, but
4648 * real exit codes are just the lower byte in any event.
4649 */
4650 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004651 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00004652 /* Indicate failure - this will cause the file object
4653 * to raise an I/O error and translate the last Win32
4654 * error code from errno. We do have a problem with
4655 * last errors that overlap the normal errno table,
4656 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004657 */
Fredrik Lundh20318932000-07-26 17:29:12 +00004658 if (result != EOF) {
4659 /* If the error wasn't from the fclose(), then
4660 * set errno for the file object error handling.
4661 */
4662 errno = GetLastError();
4663 }
4664 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004665 }
4666
4667 /* Free up the native handle at this point */
4668 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00004669 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00004670
Mark Hammondb37a3732000-08-14 04:47:33 +00004671 /* Remove this file pointer from dictionary */
4672 PyDict_DelItem(_PyPopenProcs, fileObj);
4673
4674 if (PyDict_Size(_PyPopenProcs) == 0) {
4675 Py_DECREF(_PyPopenProcs);
4676 _PyPopenProcs = NULL;
4677 }
4678
4679 } /* if object retrieval ok */
4680
4681 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004682 } /* if _PyPopenProcs */
4683
Tim Peters736aa322000-09-01 06:51:24 +00004684#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004685 PyGILState_Release(state);
Tim Peters736aa322000-09-01 06:51:24 +00004686#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00004687 return result;
4688}
Tim Peters9acdd3a2000-09-01 19:26:36 +00004689
4690#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00004691static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004692posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00004693{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004694 char *name;
4695 char *mode = "r";
4696 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00004697 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00004698 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004699 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00004700 return NULL;
Martin v. Löwis9ad853b2003-10-31 10:01:53 +00004701 /* Strip mode of binary or text modifiers */
4702 if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
4703 mode = "r";
4704 else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
4705 mode = "w";
Barry Warsaw53699e91996-12-10 23:23:01 +00004706 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004707 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004708 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00004709 if (fp == NULL)
4710 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004711 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004712 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00004713 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004714 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00004715}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004716
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004717#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004718#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00004719
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004720
Guido van Rossumb6775db1994-08-01 11:34:53 +00004721#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004722PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004723"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004724Set the current process's user id.");
4725
Barry Warsaw53699e91996-12-10 23:23:01 +00004726static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004727posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004728{
4729 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004730 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004731 return NULL;
4732 if (setuid(uid) < 0)
4733 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004734 Py_INCREF(Py_None);
4735 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004736}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004737#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004738
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004739
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004740#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004741PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004742"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004743Set the current process's effective user id.");
4744
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004745static PyObject *
4746posix_seteuid (PyObject *self, PyObject *args)
4747{
4748 int euid;
4749 if (!PyArg_ParseTuple(args, "i", &euid)) {
4750 return NULL;
4751 } else if (seteuid(euid) < 0) {
4752 return posix_error();
4753 } else {
4754 Py_INCREF(Py_None);
4755 return Py_None;
4756 }
4757}
4758#endif /* HAVE_SETEUID */
4759
4760#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004761PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004762"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004763Set the current process's effective group id.");
4764
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004765static PyObject *
4766posix_setegid (PyObject *self, PyObject *args)
4767{
4768 int egid;
4769 if (!PyArg_ParseTuple(args, "i", &egid)) {
4770 return NULL;
4771 } else if (setegid(egid) < 0) {
4772 return posix_error();
4773 } else {
4774 Py_INCREF(Py_None);
4775 return Py_None;
4776 }
4777}
4778#endif /* HAVE_SETEGID */
4779
4780#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004781PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004782"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004783Set the current process's real and effective user ids.");
4784
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004785static PyObject *
4786posix_setreuid (PyObject *self, PyObject *args)
4787{
4788 int ruid, euid;
4789 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
4790 return NULL;
4791 } else if (setreuid(ruid, euid) < 0) {
4792 return posix_error();
4793 } else {
4794 Py_INCREF(Py_None);
4795 return Py_None;
4796 }
4797}
4798#endif /* HAVE_SETREUID */
4799
4800#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004801PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004802"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004803Set the current process's real and effective group ids.");
4804
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004805static PyObject *
4806posix_setregid (PyObject *self, PyObject *args)
4807{
4808 int rgid, egid;
4809 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
4810 return NULL;
4811 } else if (setregid(rgid, egid) < 0) {
4812 return posix_error();
4813 } else {
4814 Py_INCREF(Py_None);
4815 return Py_None;
4816 }
4817}
4818#endif /* HAVE_SETREGID */
4819
Guido van Rossumb6775db1994-08-01 11:34:53 +00004820#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004821PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004822"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004823Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004824
Barry Warsaw53699e91996-12-10 23:23:01 +00004825static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004826posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004827{
4828 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004829 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004830 return NULL;
4831 if (setgid(gid) < 0)
4832 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004833 Py_INCREF(Py_None);
4834 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004835}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004836#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004837
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004838#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004839PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004840"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004841Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004842
4843static PyObject *
4844posix_setgroups(PyObject *self, PyObject *args)
4845{
4846 PyObject *groups;
4847 int i, len;
4848 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00004849
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004850 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
4851 return NULL;
4852 if (!PySequence_Check(groups)) {
4853 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
4854 return NULL;
4855 }
4856 len = PySequence_Size(groups);
4857 if (len > MAX_GROUPS) {
4858 PyErr_SetString(PyExc_ValueError, "too many groups");
4859 return NULL;
4860 }
4861 for(i = 0; i < len; i++) {
4862 PyObject *elem;
4863 elem = PySequence_GetItem(groups, i);
4864 if (!elem)
4865 return NULL;
4866 if (!PyInt_Check(elem)) {
4867 PyErr_SetString(PyExc_TypeError,
4868 "groups must be integers");
4869 Py_DECREF(elem);
4870 return NULL;
4871 }
4872 /* XXX: check that value fits into gid_t. */
4873 grouplist[i] = PyInt_AsLong(elem);
4874 Py_DECREF(elem);
4875 }
4876
4877 if (setgroups(len, grouplist) < 0)
4878 return posix_error();
4879 Py_INCREF(Py_None);
4880 return Py_None;
4881}
4882#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004883
Guido van Rossumb6775db1994-08-01 11:34:53 +00004884#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004885PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004886"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004887Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004888
Barry Warsaw53699e91996-12-10 23:23:01 +00004889static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004890posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004891{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004892 int pid, options;
4893#ifdef UNION_WAIT
4894 union wait status;
4895#define status_i (status.w_status)
4896#else
4897 int status;
4898#define status_i status
4899#endif
4900 status_i = 0;
4901
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004902 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00004903 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004904 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00004905 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00004906 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00004907 if (pid == -1)
4908 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00004909 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004910 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00004911}
4912
Tim Petersab034fa2002-02-01 11:27:43 +00004913#elif defined(HAVE_CWAIT)
4914
4915/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004916PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004917"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004918"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00004919
4920static PyObject *
4921posix_waitpid(PyObject *self, PyObject *args)
4922{
4923 int pid, options;
4924 int status;
4925
4926 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
4927 return NULL;
4928 Py_BEGIN_ALLOW_THREADS
4929 pid = _cwait(&status, pid, options);
4930 Py_END_ALLOW_THREADS
4931 if (pid == -1)
4932 return posix_error();
4933 else
4934 /* shift the status left a byte so this is more like the
4935 POSIX waitpid */
4936 return Py_BuildValue("ii", pid, status << 8);
4937}
4938#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004939
Guido van Rossumad0ee831995-03-01 10:34:45 +00004940#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004941PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004942"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004943Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004944
Barry Warsaw53699e91996-12-10 23:23:01 +00004945static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004946posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00004947{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004948 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004949#ifdef UNION_WAIT
4950 union wait status;
4951#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004952#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004953 int status;
4954#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004955#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00004956
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004957 status_i = 0;
4958 Py_BEGIN_ALLOW_THREADS
4959 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00004960 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00004961 if (pid == -1)
4962 return posix_error();
4963 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004964 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004965#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00004966}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004967#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004968
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004969
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004970PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004971"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004972Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004973
Barry Warsaw53699e91996-12-10 23:23:01 +00004974static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004975posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004976{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004977#ifdef HAVE_LSTAT
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004978 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004979#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004980#ifdef MS_WINDOWS
Mark Hammond7edd0a92003-08-06 02:46:58 +00004981 return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", _wstati64);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004982#else
4983 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
4984#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00004985#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004986}
4987
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004988
Guido van Rossumb6775db1994-08-01 11:34:53 +00004989#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004990PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004991"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004992Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004993
Barry Warsaw53699e91996-12-10 23:23:01 +00004994static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004995posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004996{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004997 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004998 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004999 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005000 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005001 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005002 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00005003 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00005004 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005005 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00005006 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00005007 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005008}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005009#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005010
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005011
Guido van Rossumb6775db1994-08-01 11:34:53 +00005012#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005013PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005014"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00005015Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005016
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005017static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005018posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005019{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005020 return posix_2str(args, "etet:symlink", symlink, NULL, NULL);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005021}
5022#endif /* HAVE_SYMLINK */
5023
5024
5025#ifdef HAVE_TIMES
5026#ifndef HZ
5027#define HZ 60 /* Universal constant :-) */
5028#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00005029
Guido van Rossumd48f2521997-12-05 22:19:34 +00005030#if defined(PYCC_VACPP) && defined(PYOS_OS2)
5031static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005032system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005033{
5034 ULONG value = 0;
5035
5036 Py_BEGIN_ALLOW_THREADS
5037 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
5038 Py_END_ALLOW_THREADS
5039
5040 return value;
5041}
5042
5043static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005044posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005045{
Guido van Rossumd48f2521997-12-05 22:19:34 +00005046 /* Currently Only Uptime is Provided -- Others Later */
5047 return Py_BuildValue("ddddd",
5048 (double)0 /* t.tms_utime / HZ */,
5049 (double)0 /* t.tms_stime / HZ */,
5050 (double)0 /* t.tms_cutime / HZ */,
5051 (double)0 /* t.tms_cstime / HZ */,
5052 (double)system_uptime() / 1000);
5053}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005054#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00005055static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005056posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00005057{
5058 struct tms t;
5059 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +00005060 errno = 0;
5061 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00005062 if (c == (clock_t) -1)
5063 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005064 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00005065 (double)t.tms_utime / HZ,
5066 (double)t.tms_stime / HZ,
5067 (double)t.tms_cutime / HZ,
5068 (double)t.tms_cstime / HZ,
5069 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00005070}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005071#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005072#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005073
5074
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005075#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005076#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00005077static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005078posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005079{
5080 FILETIME create, exit, kernel, user;
5081 HANDLE hProc;
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005082 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00005083 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
5084 /* The fields of a FILETIME structure are the hi and lo part
5085 of a 64-bit value expressed in 100 nanosecond units.
5086 1e7 is one second in such units; 1e-7 the inverse.
5087 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
5088 */
Barry Warsaw53699e91996-12-10 23:23:01 +00005089 return Py_BuildValue(
5090 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00005091 (double)(kernel.dwHighDateTime*429.4967296 +
5092 kernel.dwLowDateTime*1e-7),
5093 (double)(user.dwHighDateTime*429.4967296 +
5094 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00005095 (double)0,
5096 (double)0,
5097 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005098}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005099#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005100
5101#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005102PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005103"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005104Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005105#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005106
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005107
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00005108#ifdef HAVE_GETSID
5109PyDoc_STRVAR(posix_getsid__doc__,
5110"getsid(pid) -> sid\n\n\
5111Call the system call getsid().");
5112
5113static PyObject *
5114posix_getsid(PyObject *self, PyObject *args)
5115{
5116 int pid, sid;
5117 if (!PyArg_ParseTuple(args, "i:getsid", &pid))
5118 return NULL;
5119 sid = getsid(pid);
5120 if (sid < 0)
5121 return posix_error();
5122 return PyInt_FromLong((long)sid);
5123}
5124#endif /* HAVE_GETSID */
5125
5126
Guido van Rossumb6775db1994-08-01 11:34:53 +00005127#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005128PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005129"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005130Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005131
Barry Warsaw53699e91996-12-10 23:23:01 +00005132static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005133posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005134{
Guido van Rossum687dd131993-05-17 08:34:16 +00005135 if (setsid() < 0)
5136 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005137 Py_INCREF(Py_None);
5138 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005139}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005140#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005141
Guido van Rossumb6775db1994-08-01 11:34:53 +00005142#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005143PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005144"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005145Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005146
Barry Warsaw53699e91996-12-10 23:23:01 +00005147static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005148posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005149{
5150 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005151 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00005152 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005153 if (setpgid(pid, pgrp) < 0)
5154 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005155 Py_INCREF(Py_None);
5156 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005157}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005158#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005159
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005160
Guido van Rossumb6775db1994-08-01 11:34:53 +00005161#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005162PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005163"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005164Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005165
Barry Warsaw53699e91996-12-10 23:23:01 +00005166static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005167posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005168{
5169 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005170 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00005171 return NULL;
5172 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005173 if (pgid < 0)
5174 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005175 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00005176}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005177#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00005178
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005179
Guido van Rossumb6775db1994-08-01 11:34:53 +00005180#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005181PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005182"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005183Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005184
Barry Warsaw53699e91996-12-10 23:23:01 +00005185static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005186posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005187{
5188 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005189 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00005190 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005191 if (tcsetpgrp(fd, pgid) < 0)
5192 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00005193 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00005194 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00005195}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005196#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00005197
Guido van Rossum687dd131993-05-17 08:34:16 +00005198/* Functions acting on file descriptors */
5199
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005200PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005201"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005202Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005203
Barry Warsaw53699e91996-12-10 23:23:01 +00005204static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005205posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005206{
Mark Hammondef8b6542001-05-13 08:04:26 +00005207 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005208 int flag;
5209 int mode = 0777;
5210 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005211
5212#ifdef MS_WINDOWS
5213 if (unicode_file_names()) {
5214 PyUnicodeObject *po;
5215 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
5216 Py_BEGIN_ALLOW_THREADS
5217 /* PyUnicode_AS_UNICODE OK without thread
5218 lock as it is a simple dereference. */
5219 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
5220 Py_END_ALLOW_THREADS
5221 if (fd < 0)
5222 return posix_error();
5223 return PyInt_FromLong((long)fd);
5224 }
5225 /* Drop the argument parsing error as narrow strings
5226 are also valid. */
5227 PyErr_Clear();
5228 }
5229#endif
5230
Tim Peters5aa91602002-01-30 05:46:57 +00005231 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00005232 Py_FileSystemDefaultEncoding, &file,
5233 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00005234 return NULL;
5235
Barry Warsaw53699e91996-12-10 23:23:01 +00005236 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005237 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005238 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005239 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00005240 return posix_error_with_allocated_filename(file);
5241 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00005242 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005243}
5244
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005245
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005246PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005247"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005248Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005249
Barry Warsaw53699e91996-12-10 23:23:01 +00005250static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005251posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005252{
5253 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005254 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005255 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005256 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005257 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00005258 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005259 if (res < 0)
5260 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005261 Py_INCREF(Py_None);
5262 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005263}
5264
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005265
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005266PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005267"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005268Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005269
Barry Warsaw53699e91996-12-10 23:23:01 +00005270static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005271posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005272{
5273 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005274 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005275 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005276 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005277 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00005278 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005279 if (fd < 0)
5280 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005281 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005282}
5283
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005284
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005285PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00005286"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005287Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005288
Barry Warsaw53699e91996-12-10 23:23:01 +00005289static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005290posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005291{
5292 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005293 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00005294 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005295 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005296 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00005297 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005298 if (res < 0)
5299 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005300 Py_INCREF(Py_None);
5301 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005302}
5303
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005304
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005305PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005306"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005307Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005308
Barry Warsaw53699e91996-12-10 23:23:01 +00005309static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005310posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005311{
5312 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005313#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005314 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005315#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00005316 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005317#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005318 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005319 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00005320 return NULL;
5321#ifdef SEEK_SET
5322 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
5323 switch (how) {
5324 case 0: how = SEEK_SET; break;
5325 case 1: how = SEEK_CUR; break;
5326 case 2: how = SEEK_END; break;
5327 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005328#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005329
5330#if !defined(HAVE_LARGEFILE_SUPPORT)
5331 pos = PyInt_AsLong(posobj);
5332#else
5333 pos = PyLong_Check(posobj) ?
5334 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
5335#endif
5336 if (PyErr_Occurred())
5337 return NULL;
5338
Barry Warsaw53699e91996-12-10 23:23:01 +00005339 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005340#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00005341 res = _lseeki64(fd, pos, how);
5342#else
Guido van Rossum687dd131993-05-17 08:34:16 +00005343 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005344#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005345 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005346 if (res < 0)
5347 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00005348
5349#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00005350 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005351#else
5352 return PyLong_FromLongLong(res);
5353#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005354}
5355
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005356
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005357PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005358"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005359Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005360
Barry Warsaw53699e91996-12-10 23:23:01 +00005361static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005362posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005363{
Guido van Rossum8bac5461996-06-11 18:38:48 +00005364 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00005365 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005366 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005367 return NULL;
Michael W. Hudson9867ced2005-01-31 17:01:59 +00005368 if (size < 0) {
5369 errno = EINVAL;
5370 return posix_error();
5371 }
Barry Warsaw53699e91996-12-10 23:23:01 +00005372 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005373 if (buffer == NULL)
5374 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005375 Py_BEGIN_ALLOW_THREADS
5376 n = read(fd, PyString_AsString(buffer), size);
5377 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00005378 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005379 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00005380 return posix_error();
5381 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00005382 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00005383 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00005384 return buffer;
5385}
5386
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005387
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005388PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005389"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005390Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005391
Barry Warsaw53699e91996-12-10 23:23:01 +00005392static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005393posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005394{
5395 int fd, size;
5396 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005397 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005398 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005399 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005400 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00005401 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005402 if (size < 0)
5403 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005404 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005405}
5406
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005407
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005408PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005409"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005410Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005411
Barry Warsaw53699e91996-12-10 23:23:01 +00005412static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005413posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005414{
5415 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00005416 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00005417 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005418 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005419 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005420#ifdef __VMS
5421 /* on OpenVMS we must ensure that all bytes are written to the file */
5422 fsync(fd);
5423#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005424 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00005425 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00005426 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005427 if (res != 0)
5428 return posix_error();
Tim Peters5aa91602002-01-30 05:46:57 +00005429
Fred Drake699f3522000-06-29 21:12:41 +00005430 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00005431}
5432
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005433
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005434PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005435"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005436Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005437
Barry Warsaw53699e91996-12-10 23:23:01 +00005438static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005439posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005440{
Guido van Rossum687dd131993-05-17 08:34:16 +00005441 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005442 char *mode = "r";
5443 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00005444 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00005445 PyObject *f;
5446 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00005447 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00005448
Thomas Heller1f043e22002-11-07 16:00:59 +00005449 if (mode[0] != 'r' && mode[0] != 'w' && mode[0] != 'a') {
5450 PyErr_Format(PyExc_ValueError,
5451 "invalid file mode '%s'", mode);
5452 return NULL;
5453 }
5454
Barry Warsaw53699e91996-12-10 23:23:01 +00005455 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005456 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005457 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005458 if (fp == NULL)
5459 return posix_error();
Guido van Rossumbd6be7a2002-09-15 18:45:46 +00005460 f = PyFile_FromFile(fp, "<fdopen>", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005461 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00005462 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005463 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00005464}
5465
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005466PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005467"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005468Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005469connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00005470
5471static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00005472posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00005473{
5474 int fd;
5475 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
5476 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005477 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00005478}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005479
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005480#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005481PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005482"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005483Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005484
Barry Warsaw53699e91996-12-10 23:23:01 +00005485static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005486posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00005487{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005488#if defined(PYOS_OS2)
5489 HFILE read, write;
5490 APIRET rc;
5491
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005492 Py_BEGIN_ALLOW_THREADS
5493 rc = DosCreatePipe( &read, &write, 4096);
5494 Py_END_ALLOW_THREADS
5495 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005496 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005497
5498 return Py_BuildValue("(ii)", read, write);
5499#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005500#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00005501 int fds[2];
5502 int res;
Barry Warsaw53699e91996-12-10 23:23:01 +00005503 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005504 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00005505 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005506 if (res != 0)
5507 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005508 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005509#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00005510 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005511 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00005512 BOOL ok;
Barry Warsaw53699e91996-12-10 23:23:01 +00005513 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005514 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00005515 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00005516 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005517 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00005518 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
5519 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005520 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005521#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005522#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005523}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005524#endif /* HAVE_PIPE */
5525
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005526
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005527#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005528PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005529"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005530Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005531
Barry Warsaw53699e91996-12-10 23:23:01 +00005532static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005533posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005534{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005535 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005536 int mode = 0666;
5537 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005538 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005539 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005540 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005541 res = mkfifo(filename, mode);
5542 Py_END_ALLOW_THREADS
5543 if (res < 0)
5544 return posix_error();
5545 Py_INCREF(Py_None);
5546 return Py_None;
5547}
5548#endif
5549
5550
Neal Norwitz11690112002-07-30 01:08:28 +00005551#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005552PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005553"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005554Create a filesystem node (file, device special file or named pipe)\n\
5555named filename. mode specifies both the permissions to use and the\n\
5556type of node to be created, being combined (bitwise OR) with one of\n\
5557S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005558device defines the newly created device special file (probably using\n\
5559os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005560
5561
5562static PyObject *
5563posix_mknod(PyObject *self, PyObject *args)
5564{
5565 char *filename;
5566 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005567 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005568 int res;
Martin v. Löwisd631ebe2002-11-02 17:42:33 +00005569 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005570 return NULL;
5571 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005572 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00005573 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005574 if (res < 0)
5575 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005576 Py_INCREF(Py_None);
5577 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005578}
5579#endif
5580
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005581#ifdef HAVE_DEVICE_MACROS
5582PyDoc_STRVAR(posix_major__doc__,
5583"major(device) -> major number\n\
5584Extracts a device major number from a raw device number.");
5585
5586static PyObject *
5587posix_major(PyObject *self, PyObject *args)
5588{
5589 int device;
5590 if (!PyArg_ParseTuple(args, "i:major", &device))
5591 return NULL;
5592 return PyInt_FromLong((long)major(device));
5593}
5594
5595PyDoc_STRVAR(posix_minor__doc__,
5596"minor(device) -> minor number\n\
5597Extracts a device minor number from a raw device number.");
5598
5599static PyObject *
5600posix_minor(PyObject *self, PyObject *args)
5601{
5602 int device;
5603 if (!PyArg_ParseTuple(args, "i:minor", &device))
5604 return NULL;
5605 return PyInt_FromLong((long)minor(device));
5606}
5607
5608PyDoc_STRVAR(posix_makedev__doc__,
5609"makedev(major, minor) -> device number\n\
5610Composes a raw device number from the major and minor device numbers.");
5611
5612static PyObject *
5613posix_makedev(PyObject *self, PyObject *args)
5614{
5615 int major, minor;
5616 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
5617 return NULL;
5618 return PyInt_FromLong((long)makedev(major, minor));
5619}
5620#endif /* device macros */
5621
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005622
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005623#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005624PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005625"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005626Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005627
Barry Warsaw53699e91996-12-10 23:23:01 +00005628static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005629posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005630{
5631 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005632 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005633 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005634 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005635
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005636 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005637 return NULL;
5638
5639#if !defined(HAVE_LARGEFILE_SUPPORT)
5640 length = PyInt_AsLong(lenobj);
5641#else
5642 length = PyLong_Check(lenobj) ?
5643 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
5644#endif
5645 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005646 return NULL;
5647
Barry Warsaw53699e91996-12-10 23:23:01 +00005648 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005649 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00005650 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005651 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005652 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005653 return NULL;
5654 }
Barry Warsaw53699e91996-12-10 23:23:01 +00005655 Py_INCREF(Py_None);
5656 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005657}
5658#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005659
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005660#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005661PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005662"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005663Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005664
Fred Drake762e2061999-08-26 17:23:54 +00005665/* Save putenv() parameters as values here, so we can collect them when they
5666 * get re-set with another call for the same key. */
5667static PyObject *posix_putenv_garbage;
5668
Tim Peters5aa91602002-01-30 05:46:57 +00005669static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005670posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005671{
5672 char *s1, *s2;
5673 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00005674 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00005675 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005676
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005677 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005678 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00005679
5680#if defined(PYOS_OS2)
5681 if (stricmp(s1, "BEGINLIBPATH") == 0) {
5682 APIRET rc;
5683
Guido van Rossumd48f2521997-12-05 22:19:34 +00005684 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
5685 if (rc != NO_ERROR)
5686 return os2_error(rc);
5687
5688 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
5689 APIRET rc;
5690
Guido van Rossumd48f2521997-12-05 22:19:34 +00005691 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
5692 if (rc != NO_ERROR)
5693 return os2_error(rc);
5694 } else {
5695#endif
5696
Fred Drake762e2061999-08-26 17:23:54 +00005697 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00005698 len = strlen(s1) + strlen(s2) + 2;
5699 /* len includes space for a trailing \0; the size arg to
5700 PyString_FromStringAndSize does not count that */
5701 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00005702 if (newstr == NULL)
5703 return PyErr_NoMemory();
5704 new = PyString_AS_STRING(newstr);
Tim Petersc8996f52001-12-03 20:41:00 +00005705 PyOS_snprintf(new, len, "%s=%s", s1, s2);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005706 if (putenv(new)) {
Neal Norwitz4adc9ab2003-02-10 03:10:43 +00005707 Py_DECREF(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005708 posix_error();
5709 return NULL;
5710 }
Fred Drake762e2061999-08-26 17:23:54 +00005711 /* Install the first arg and newstr in posix_putenv_garbage;
5712 * this will cause previous value to be collected. This has to
5713 * happen after the real putenv() call because the old value
5714 * was still accessible until then. */
5715 if (PyDict_SetItem(posix_putenv_garbage,
5716 PyTuple_GET_ITEM(args, 0), newstr)) {
5717 /* really not much we can do; just leak */
5718 PyErr_Clear();
5719 }
5720 else {
5721 Py_DECREF(newstr);
5722 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005723
5724#if defined(PYOS_OS2)
5725 }
5726#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005727 Py_INCREF(Py_None);
5728 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005729}
Guido van Rossumb6a47161997-09-15 22:54:34 +00005730#endif /* putenv */
5731
Guido van Rossumc524d952001-10-19 01:31:59 +00005732#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005733PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005734"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005735Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00005736
5737static PyObject *
5738posix_unsetenv(PyObject *self, PyObject *args)
5739{
5740 char *s1;
5741
5742 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
5743 return NULL;
5744
5745 unsetenv(s1);
5746
5747 /* Remove the key from posix_putenv_garbage;
5748 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00005749 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00005750 * old value was still accessible until then.
5751 */
5752 if (PyDict_DelItem(posix_putenv_garbage,
5753 PyTuple_GET_ITEM(args, 0))) {
5754 /* really not much we can do; just leak */
5755 PyErr_Clear();
5756 }
5757
5758 Py_INCREF(Py_None);
5759 return Py_None;
5760}
5761#endif /* unsetenv */
5762
Guido van Rossumb6a47161997-09-15 22:54:34 +00005763#ifdef HAVE_STRERROR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005764PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005765"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005766Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005767
Guido van Rossumf68d8e52001-04-14 17:55:09 +00005768static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005769posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00005770{
5771 int code;
5772 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005773 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00005774 return NULL;
5775 message = strerror(code);
5776 if (message == NULL) {
5777 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00005778 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005779 return NULL;
5780 }
5781 return PyString_FromString(message);
5782}
5783#endif /* strerror */
5784
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005785
Guido van Rossumc9641791998-08-04 15:26:23 +00005786#ifdef HAVE_SYS_WAIT_H
5787
Fred Drake106c1a02002-04-23 15:58:02 +00005788#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005789PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005790"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005791Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00005792
5793static PyObject *
5794posix_WCOREDUMP(PyObject *self, PyObject *args)
5795{
5796#ifdef UNION_WAIT
5797 union wait status;
5798#define status_i (status.w_status)
5799#else
5800 int status;
5801#define status_i status
5802#endif
5803 status_i = 0;
5804
5805 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &status_i))
5806 {
5807 return NULL;
5808 }
5809
5810 return PyBool_FromLong(WCOREDUMP(status));
5811#undef status_i
5812}
5813#endif /* WCOREDUMP */
5814
5815#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005816PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005817"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005818Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005819job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00005820
5821static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005822posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00005823{
5824#ifdef UNION_WAIT
5825 union wait status;
5826#define status_i (status.w_status)
5827#else
5828 int status;
5829#define status_i status
5830#endif
5831 status_i = 0;
5832
5833 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &status_i))
5834 {
5835 return NULL;
5836 }
5837
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005838 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00005839#undef status_i
5840}
5841#endif /* WIFCONTINUED */
5842
Guido van Rossumc9641791998-08-04 15:26:23 +00005843#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005844PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005845"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005846Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005847
5848static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005849posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005850{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005851#ifdef UNION_WAIT
5852 union wait status;
5853#define status_i (status.w_status)
5854#else
5855 int status;
5856#define status_i status
5857#endif
5858 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005859
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005860 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005861 {
5862 return NULL;
5863 }
Tim Peters5aa91602002-01-30 05:46:57 +00005864
Fred Drake106c1a02002-04-23 15:58:02 +00005865 return PyBool_FromLong(WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005866#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005867}
5868#endif /* WIFSTOPPED */
5869
5870#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005871PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005872"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005873Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005874
5875static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005876posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005877{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005878#ifdef UNION_WAIT
5879 union wait status;
5880#define status_i (status.w_status)
5881#else
5882 int status;
5883#define status_i status
5884#endif
5885 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005886
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005887 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005888 {
5889 return NULL;
5890 }
Tim Peters5aa91602002-01-30 05:46:57 +00005891
Fred Drake106c1a02002-04-23 15:58:02 +00005892 return PyBool_FromLong(WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005893#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005894}
5895#endif /* WIFSIGNALED */
5896
5897#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005898PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005899"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005900Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005901system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005902
5903static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005904posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005905{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005906#ifdef UNION_WAIT
5907 union wait status;
5908#define status_i (status.w_status)
5909#else
5910 int status;
5911#define status_i status
5912#endif
5913 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005914
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005915 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005916 {
5917 return NULL;
5918 }
Tim Peters5aa91602002-01-30 05:46:57 +00005919
Fred Drake106c1a02002-04-23 15:58:02 +00005920 return PyBool_FromLong(WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005921#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005922}
5923#endif /* WIFEXITED */
5924
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005925#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005926PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005927"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005928Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005929
5930static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005931posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005932{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005933#ifdef UNION_WAIT
5934 union wait status;
5935#define status_i (status.w_status)
5936#else
5937 int status;
5938#define status_i status
5939#endif
5940 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005941
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005942 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005943 {
5944 return NULL;
5945 }
Tim Peters5aa91602002-01-30 05:46:57 +00005946
Guido van Rossumc9641791998-08-04 15:26:23 +00005947 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005948#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005949}
5950#endif /* WEXITSTATUS */
5951
5952#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005953PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005954"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005955Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005956value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005957
5958static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005959posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005960{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005961#ifdef UNION_WAIT
5962 union wait status;
5963#define status_i (status.w_status)
5964#else
5965 int status;
5966#define status_i status
5967#endif
5968 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005969
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005970 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005971 {
5972 return NULL;
5973 }
Tim Peters5aa91602002-01-30 05:46:57 +00005974
Guido van Rossumc9641791998-08-04 15:26:23 +00005975 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005976#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005977}
5978#endif /* WTERMSIG */
5979
5980#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005981PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005982"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005983Return the signal that stopped the process that provided\n\
5984the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005985
5986static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005987posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005988{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005989#ifdef UNION_WAIT
5990 union wait status;
5991#define status_i (status.w_status)
5992#else
5993 int status;
5994#define status_i status
5995#endif
5996 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005997
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005998 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005999 {
6000 return NULL;
6001 }
Tim Peters5aa91602002-01-30 05:46:57 +00006002
Guido van Rossumc9641791998-08-04 15:26:23 +00006003 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006004#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00006005}
6006#endif /* WSTOPSIG */
6007
6008#endif /* HAVE_SYS_WAIT_H */
6009
6010
Guido van Rossum94f6f721999-01-06 18:42:14 +00006011#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00006012#ifdef _SCO_DS
6013/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
6014 needed definitions in sys/statvfs.h */
6015#define _SVID3
6016#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006017#include <sys/statvfs.h>
6018
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006019static PyObject*
6020_pystatvfs_fromstructstatvfs(struct statvfs st) {
6021 PyObject *v = PyStructSequence_New(&StatVFSResultType);
6022 if (v == NULL)
6023 return NULL;
6024
6025#if !defined(HAVE_LARGEFILE_SUPPORT)
6026 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6027 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
6028 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
6029 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
6030 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
6031 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
6032 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
6033 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
6034 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6035 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6036#else
6037 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6038 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00006039 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006040 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00006041 PyStructSequence_SET_ITEM(v, 3,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006042 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006043 PyStructSequence_SET_ITEM(v, 4,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006044 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00006045 PyStructSequence_SET_ITEM(v, 5,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006046 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00006047 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006048 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00006049 PyStructSequence_SET_ITEM(v, 7,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006050 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006051 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6052 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6053#endif
6054
6055 return v;
6056}
6057
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006058PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006059"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006060Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006061
6062static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006063posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006064{
6065 int fd, res;
6066 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006067
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006068 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006069 return NULL;
6070 Py_BEGIN_ALLOW_THREADS
6071 res = fstatvfs(fd, &st);
6072 Py_END_ALLOW_THREADS
6073 if (res != 0)
6074 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006075
6076 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006077}
6078#endif /* HAVE_FSTATVFS */
6079
6080
6081#if defined(HAVE_STATVFS)
6082#include <sys/statvfs.h>
6083
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006084PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006085"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006086Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006087
6088static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006089posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006090{
6091 char *path;
6092 int res;
6093 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006094 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006095 return NULL;
6096 Py_BEGIN_ALLOW_THREADS
6097 res = statvfs(path, &st);
6098 Py_END_ALLOW_THREADS
6099 if (res != 0)
6100 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006101
6102 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006103}
6104#endif /* HAVE_STATVFS */
6105
6106
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006107#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006108PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006109"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006110Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00006111The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006112or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006113
6114static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006115posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006116{
6117 PyObject *result = NULL;
6118 char *dir = NULL;
6119 char *pfx = NULL;
6120 char *name;
6121
6122 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
6123 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00006124
6125 if (PyErr_Warn(PyExc_RuntimeWarning,
6126 "tempnam is a potential security risk to your program") < 0)
6127 return NULL;
6128
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006129#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00006130 name = _tempnam(dir, pfx);
6131#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006132 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00006133#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006134 if (name == NULL)
6135 return PyErr_NoMemory();
6136 result = PyString_FromString(name);
6137 free(name);
6138 return result;
6139}
Guido van Rossumd371ff11999-01-25 16:12:23 +00006140#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006141
6142
6143#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006144PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006145"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006146Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006147
6148static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006149posix_tmpfile(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006150{
6151 FILE *fp;
6152
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006153 fp = tmpfile();
6154 if (fp == NULL)
6155 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00006156 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006157}
6158#endif
6159
6160
6161#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006162PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006163"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006164Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006165
6166static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006167posix_tmpnam(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006168{
6169 char buffer[L_tmpnam];
6170 char *name;
6171
Skip Montanaro95618b52001-08-18 18:52:10 +00006172 if (PyErr_Warn(PyExc_RuntimeWarning,
6173 "tmpnam is a potential security risk to your program") < 0)
6174 return NULL;
6175
Greg Wardb48bc172000-03-01 21:51:56 +00006176#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006177 name = tmpnam_r(buffer);
6178#else
6179 name = tmpnam(buffer);
6180#endif
6181 if (name == NULL) {
6182 PyErr_SetObject(PyExc_OSError,
6183 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00006184#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006185 "unexpected NULL from tmpnam_r"
6186#else
6187 "unexpected NULL from tmpnam"
6188#endif
6189 ));
6190 return NULL;
6191 }
6192 return PyString_FromString(buffer);
6193}
6194#endif
6195
6196
Fred Drakec9680921999-12-13 16:37:25 +00006197/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
6198 * It maps strings representing configuration variable names to
6199 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00006200 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00006201 * rarely-used constants. There are three separate tables that use
6202 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00006203 *
6204 * This code is always included, even if none of the interfaces that
6205 * need it are included. The #if hackery needed to avoid it would be
6206 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00006207 */
6208struct constdef {
6209 char *name;
6210 long value;
6211};
6212
Fred Drake12c6e2d1999-12-14 21:25:03 +00006213static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006214conv_confname(PyObject *arg, int *valuep, struct constdef *table,
6215 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006216{
6217 if (PyInt_Check(arg)) {
6218 *valuep = PyInt_AS_LONG(arg);
6219 return 1;
6220 }
6221 if (PyString_Check(arg)) {
6222 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00006223 size_t lo = 0;
6224 size_t mid;
6225 size_t hi = tablesize;
6226 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006227 char *confname = PyString_AS_STRING(arg);
6228 while (lo < hi) {
6229 mid = (lo + hi) / 2;
6230 cmp = strcmp(confname, table[mid].name);
6231 if (cmp < 0)
6232 hi = mid;
6233 else if (cmp > 0)
6234 lo = mid + 1;
6235 else {
6236 *valuep = table[mid].value;
6237 return 1;
6238 }
6239 }
6240 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
6241 }
6242 else
6243 PyErr_SetString(PyExc_TypeError,
6244 "configuration names must be strings or integers");
6245 return 0;
6246}
6247
6248
6249#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
6250static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006251#ifdef _PC_ABI_AIO_XFER_MAX
6252 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
6253#endif
6254#ifdef _PC_ABI_ASYNC_IO
6255 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
6256#endif
Fred Drakec9680921999-12-13 16:37:25 +00006257#ifdef _PC_ASYNC_IO
6258 {"PC_ASYNC_IO", _PC_ASYNC_IO},
6259#endif
6260#ifdef _PC_CHOWN_RESTRICTED
6261 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
6262#endif
6263#ifdef _PC_FILESIZEBITS
6264 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
6265#endif
6266#ifdef _PC_LAST
6267 {"PC_LAST", _PC_LAST},
6268#endif
6269#ifdef _PC_LINK_MAX
6270 {"PC_LINK_MAX", _PC_LINK_MAX},
6271#endif
6272#ifdef _PC_MAX_CANON
6273 {"PC_MAX_CANON", _PC_MAX_CANON},
6274#endif
6275#ifdef _PC_MAX_INPUT
6276 {"PC_MAX_INPUT", _PC_MAX_INPUT},
6277#endif
6278#ifdef _PC_NAME_MAX
6279 {"PC_NAME_MAX", _PC_NAME_MAX},
6280#endif
6281#ifdef _PC_NO_TRUNC
6282 {"PC_NO_TRUNC", _PC_NO_TRUNC},
6283#endif
6284#ifdef _PC_PATH_MAX
6285 {"PC_PATH_MAX", _PC_PATH_MAX},
6286#endif
6287#ifdef _PC_PIPE_BUF
6288 {"PC_PIPE_BUF", _PC_PIPE_BUF},
6289#endif
6290#ifdef _PC_PRIO_IO
6291 {"PC_PRIO_IO", _PC_PRIO_IO},
6292#endif
6293#ifdef _PC_SOCK_MAXBUF
6294 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
6295#endif
6296#ifdef _PC_SYNC_IO
6297 {"PC_SYNC_IO", _PC_SYNC_IO},
6298#endif
6299#ifdef _PC_VDISABLE
6300 {"PC_VDISABLE", _PC_VDISABLE},
6301#endif
6302};
6303
Fred Drakec9680921999-12-13 16:37:25 +00006304static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006305conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006306{
6307 return conv_confname(arg, valuep, posix_constants_pathconf,
6308 sizeof(posix_constants_pathconf)
6309 / sizeof(struct constdef));
6310}
6311#endif
6312
6313#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006314PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006315"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006316Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006317If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006318
6319static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006320posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006321{
6322 PyObject *result = NULL;
6323 int name, fd;
6324
Fred Drake12c6e2d1999-12-14 21:25:03 +00006325 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
6326 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00006327 long limit;
6328
6329 errno = 0;
6330 limit = fpathconf(fd, name);
6331 if (limit == -1 && errno != 0)
6332 posix_error();
6333 else
6334 result = PyInt_FromLong(limit);
6335 }
6336 return result;
6337}
6338#endif
6339
6340
6341#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006342PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006343"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006344Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006345If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006346
6347static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006348posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006349{
6350 PyObject *result = NULL;
6351 int name;
6352 char *path;
6353
6354 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
6355 conv_path_confname, &name)) {
6356 long limit;
6357
6358 errno = 0;
6359 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006360 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00006361 if (errno == EINVAL)
6362 /* could be a path or name problem */
6363 posix_error();
6364 else
6365 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006366 }
Fred Drakec9680921999-12-13 16:37:25 +00006367 else
6368 result = PyInt_FromLong(limit);
6369 }
6370 return result;
6371}
6372#endif
6373
6374#ifdef HAVE_CONFSTR
6375static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006376#ifdef _CS_ARCHITECTURE
6377 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
6378#endif
6379#ifdef _CS_HOSTNAME
6380 {"CS_HOSTNAME", _CS_HOSTNAME},
6381#endif
6382#ifdef _CS_HW_PROVIDER
6383 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
6384#endif
6385#ifdef _CS_HW_SERIAL
6386 {"CS_HW_SERIAL", _CS_HW_SERIAL},
6387#endif
6388#ifdef _CS_INITTAB_NAME
6389 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
6390#endif
Fred Drakec9680921999-12-13 16:37:25 +00006391#ifdef _CS_LFS64_CFLAGS
6392 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
6393#endif
6394#ifdef _CS_LFS64_LDFLAGS
6395 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
6396#endif
6397#ifdef _CS_LFS64_LIBS
6398 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
6399#endif
6400#ifdef _CS_LFS64_LINTFLAGS
6401 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
6402#endif
6403#ifdef _CS_LFS_CFLAGS
6404 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
6405#endif
6406#ifdef _CS_LFS_LDFLAGS
6407 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
6408#endif
6409#ifdef _CS_LFS_LIBS
6410 {"CS_LFS_LIBS", _CS_LFS_LIBS},
6411#endif
6412#ifdef _CS_LFS_LINTFLAGS
6413 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
6414#endif
Fred Draked86ed291999-12-15 15:34:33 +00006415#ifdef _CS_MACHINE
6416 {"CS_MACHINE", _CS_MACHINE},
6417#endif
Fred Drakec9680921999-12-13 16:37:25 +00006418#ifdef _CS_PATH
6419 {"CS_PATH", _CS_PATH},
6420#endif
Fred Draked86ed291999-12-15 15:34:33 +00006421#ifdef _CS_RELEASE
6422 {"CS_RELEASE", _CS_RELEASE},
6423#endif
6424#ifdef _CS_SRPC_DOMAIN
6425 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
6426#endif
6427#ifdef _CS_SYSNAME
6428 {"CS_SYSNAME", _CS_SYSNAME},
6429#endif
6430#ifdef _CS_VERSION
6431 {"CS_VERSION", _CS_VERSION},
6432#endif
Fred Drakec9680921999-12-13 16:37:25 +00006433#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
6434 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
6435#endif
6436#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
6437 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
6438#endif
6439#ifdef _CS_XBS5_ILP32_OFF32_LIBS
6440 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
6441#endif
6442#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
6443 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
6444#endif
6445#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
6446 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
6447#endif
6448#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
6449 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
6450#endif
6451#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
6452 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
6453#endif
6454#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
6455 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
6456#endif
6457#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
6458 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
6459#endif
6460#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
6461 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
6462#endif
6463#ifdef _CS_XBS5_LP64_OFF64_LIBS
6464 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
6465#endif
6466#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
6467 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
6468#endif
6469#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
6470 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
6471#endif
6472#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
6473 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
6474#endif
6475#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
6476 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
6477#endif
6478#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
6479 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
6480#endif
Fred Draked86ed291999-12-15 15:34:33 +00006481#ifdef _MIPS_CS_AVAIL_PROCESSORS
6482 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
6483#endif
6484#ifdef _MIPS_CS_BASE
6485 {"MIPS_CS_BASE", _MIPS_CS_BASE},
6486#endif
6487#ifdef _MIPS_CS_HOSTID
6488 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
6489#endif
6490#ifdef _MIPS_CS_HW_NAME
6491 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
6492#endif
6493#ifdef _MIPS_CS_NUM_PROCESSORS
6494 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
6495#endif
6496#ifdef _MIPS_CS_OSREL_MAJ
6497 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
6498#endif
6499#ifdef _MIPS_CS_OSREL_MIN
6500 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
6501#endif
6502#ifdef _MIPS_CS_OSREL_PATCH
6503 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
6504#endif
6505#ifdef _MIPS_CS_OS_NAME
6506 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
6507#endif
6508#ifdef _MIPS_CS_OS_PROVIDER
6509 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
6510#endif
6511#ifdef _MIPS_CS_PROCESSORS
6512 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
6513#endif
6514#ifdef _MIPS_CS_SERIAL
6515 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
6516#endif
6517#ifdef _MIPS_CS_VENDOR
6518 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
6519#endif
Fred Drakec9680921999-12-13 16:37:25 +00006520};
6521
6522static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006523conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006524{
6525 return conv_confname(arg, valuep, posix_constants_confstr,
6526 sizeof(posix_constants_confstr)
6527 / sizeof(struct constdef));
6528}
6529
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006530PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006531"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006532Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006533
6534static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006535posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006536{
6537 PyObject *result = NULL;
6538 int name;
6539 char buffer[64];
6540
6541 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
6542 int len = confstr(name, buffer, sizeof(buffer));
6543
Fred Drakec9680921999-12-13 16:37:25 +00006544 errno = 0;
6545 if (len == 0) {
6546 if (errno != 0)
6547 posix_error();
6548 else
6549 result = PyString_FromString("");
6550 }
6551 else {
6552 if (len >= sizeof(buffer)) {
6553 result = PyString_FromStringAndSize(NULL, len);
6554 if (result != NULL)
6555 confstr(name, PyString_AS_STRING(result), len+1);
6556 }
6557 else
6558 result = PyString_FromString(buffer);
6559 }
6560 }
6561 return result;
6562}
6563#endif
6564
6565
6566#ifdef HAVE_SYSCONF
6567static struct constdef posix_constants_sysconf[] = {
6568#ifdef _SC_2_CHAR_TERM
6569 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
6570#endif
6571#ifdef _SC_2_C_BIND
6572 {"SC_2_C_BIND", _SC_2_C_BIND},
6573#endif
6574#ifdef _SC_2_C_DEV
6575 {"SC_2_C_DEV", _SC_2_C_DEV},
6576#endif
6577#ifdef _SC_2_C_VERSION
6578 {"SC_2_C_VERSION", _SC_2_C_VERSION},
6579#endif
6580#ifdef _SC_2_FORT_DEV
6581 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
6582#endif
6583#ifdef _SC_2_FORT_RUN
6584 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
6585#endif
6586#ifdef _SC_2_LOCALEDEF
6587 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
6588#endif
6589#ifdef _SC_2_SW_DEV
6590 {"SC_2_SW_DEV", _SC_2_SW_DEV},
6591#endif
6592#ifdef _SC_2_UPE
6593 {"SC_2_UPE", _SC_2_UPE},
6594#endif
6595#ifdef _SC_2_VERSION
6596 {"SC_2_VERSION", _SC_2_VERSION},
6597#endif
Fred Draked86ed291999-12-15 15:34:33 +00006598#ifdef _SC_ABI_ASYNCHRONOUS_IO
6599 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
6600#endif
6601#ifdef _SC_ACL
6602 {"SC_ACL", _SC_ACL},
6603#endif
Fred Drakec9680921999-12-13 16:37:25 +00006604#ifdef _SC_AIO_LISTIO_MAX
6605 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
6606#endif
Fred Drakec9680921999-12-13 16:37:25 +00006607#ifdef _SC_AIO_MAX
6608 {"SC_AIO_MAX", _SC_AIO_MAX},
6609#endif
6610#ifdef _SC_AIO_PRIO_DELTA_MAX
6611 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
6612#endif
6613#ifdef _SC_ARG_MAX
6614 {"SC_ARG_MAX", _SC_ARG_MAX},
6615#endif
6616#ifdef _SC_ASYNCHRONOUS_IO
6617 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
6618#endif
6619#ifdef _SC_ATEXIT_MAX
6620 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
6621#endif
Fred Draked86ed291999-12-15 15:34:33 +00006622#ifdef _SC_AUDIT
6623 {"SC_AUDIT", _SC_AUDIT},
6624#endif
Fred Drakec9680921999-12-13 16:37:25 +00006625#ifdef _SC_AVPHYS_PAGES
6626 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
6627#endif
6628#ifdef _SC_BC_BASE_MAX
6629 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
6630#endif
6631#ifdef _SC_BC_DIM_MAX
6632 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
6633#endif
6634#ifdef _SC_BC_SCALE_MAX
6635 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
6636#endif
6637#ifdef _SC_BC_STRING_MAX
6638 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
6639#endif
Fred Draked86ed291999-12-15 15:34:33 +00006640#ifdef _SC_CAP
6641 {"SC_CAP", _SC_CAP},
6642#endif
Fred Drakec9680921999-12-13 16:37:25 +00006643#ifdef _SC_CHARCLASS_NAME_MAX
6644 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
6645#endif
6646#ifdef _SC_CHAR_BIT
6647 {"SC_CHAR_BIT", _SC_CHAR_BIT},
6648#endif
6649#ifdef _SC_CHAR_MAX
6650 {"SC_CHAR_MAX", _SC_CHAR_MAX},
6651#endif
6652#ifdef _SC_CHAR_MIN
6653 {"SC_CHAR_MIN", _SC_CHAR_MIN},
6654#endif
6655#ifdef _SC_CHILD_MAX
6656 {"SC_CHILD_MAX", _SC_CHILD_MAX},
6657#endif
6658#ifdef _SC_CLK_TCK
6659 {"SC_CLK_TCK", _SC_CLK_TCK},
6660#endif
6661#ifdef _SC_COHER_BLKSZ
6662 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
6663#endif
6664#ifdef _SC_COLL_WEIGHTS_MAX
6665 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
6666#endif
6667#ifdef _SC_DCACHE_ASSOC
6668 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
6669#endif
6670#ifdef _SC_DCACHE_BLKSZ
6671 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
6672#endif
6673#ifdef _SC_DCACHE_LINESZ
6674 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
6675#endif
6676#ifdef _SC_DCACHE_SZ
6677 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
6678#endif
6679#ifdef _SC_DCACHE_TBLKSZ
6680 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
6681#endif
6682#ifdef _SC_DELAYTIMER_MAX
6683 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
6684#endif
6685#ifdef _SC_EQUIV_CLASS_MAX
6686 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
6687#endif
6688#ifdef _SC_EXPR_NEST_MAX
6689 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
6690#endif
6691#ifdef _SC_FSYNC
6692 {"SC_FSYNC", _SC_FSYNC},
6693#endif
6694#ifdef _SC_GETGR_R_SIZE_MAX
6695 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
6696#endif
6697#ifdef _SC_GETPW_R_SIZE_MAX
6698 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
6699#endif
6700#ifdef _SC_ICACHE_ASSOC
6701 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
6702#endif
6703#ifdef _SC_ICACHE_BLKSZ
6704 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
6705#endif
6706#ifdef _SC_ICACHE_LINESZ
6707 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
6708#endif
6709#ifdef _SC_ICACHE_SZ
6710 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
6711#endif
Fred Draked86ed291999-12-15 15:34:33 +00006712#ifdef _SC_INF
6713 {"SC_INF", _SC_INF},
6714#endif
Fred Drakec9680921999-12-13 16:37:25 +00006715#ifdef _SC_INT_MAX
6716 {"SC_INT_MAX", _SC_INT_MAX},
6717#endif
6718#ifdef _SC_INT_MIN
6719 {"SC_INT_MIN", _SC_INT_MIN},
6720#endif
6721#ifdef _SC_IOV_MAX
6722 {"SC_IOV_MAX", _SC_IOV_MAX},
6723#endif
Fred Draked86ed291999-12-15 15:34:33 +00006724#ifdef _SC_IP_SECOPTS
6725 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
6726#endif
Fred Drakec9680921999-12-13 16:37:25 +00006727#ifdef _SC_JOB_CONTROL
6728 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
6729#endif
Fred Draked86ed291999-12-15 15:34:33 +00006730#ifdef _SC_KERN_POINTERS
6731 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
6732#endif
6733#ifdef _SC_KERN_SIM
6734 {"SC_KERN_SIM", _SC_KERN_SIM},
6735#endif
Fred Drakec9680921999-12-13 16:37:25 +00006736#ifdef _SC_LINE_MAX
6737 {"SC_LINE_MAX", _SC_LINE_MAX},
6738#endif
6739#ifdef _SC_LOGIN_NAME_MAX
6740 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
6741#endif
6742#ifdef _SC_LOGNAME_MAX
6743 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
6744#endif
6745#ifdef _SC_LONG_BIT
6746 {"SC_LONG_BIT", _SC_LONG_BIT},
6747#endif
Fred Draked86ed291999-12-15 15:34:33 +00006748#ifdef _SC_MAC
6749 {"SC_MAC", _SC_MAC},
6750#endif
Fred Drakec9680921999-12-13 16:37:25 +00006751#ifdef _SC_MAPPED_FILES
6752 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
6753#endif
6754#ifdef _SC_MAXPID
6755 {"SC_MAXPID", _SC_MAXPID},
6756#endif
6757#ifdef _SC_MB_LEN_MAX
6758 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
6759#endif
6760#ifdef _SC_MEMLOCK
6761 {"SC_MEMLOCK", _SC_MEMLOCK},
6762#endif
6763#ifdef _SC_MEMLOCK_RANGE
6764 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
6765#endif
6766#ifdef _SC_MEMORY_PROTECTION
6767 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
6768#endif
6769#ifdef _SC_MESSAGE_PASSING
6770 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
6771#endif
Fred Draked86ed291999-12-15 15:34:33 +00006772#ifdef _SC_MMAP_FIXED_ALIGNMENT
6773 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
6774#endif
Fred Drakec9680921999-12-13 16:37:25 +00006775#ifdef _SC_MQ_OPEN_MAX
6776 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
6777#endif
6778#ifdef _SC_MQ_PRIO_MAX
6779 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
6780#endif
Fred Draked86ed291999-12-15 15:34:33 +00006781#ifdef _SC_NACLS_MAX
6782 {"SC_NACLS_MAX", _SC_NACLS_MAX},
6783#endif
Fred Drakec9680921999-12-13 16:37:25 +00006784#ifdef _SC_NGROUPS_MAX
6785 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
6786#endif
6787#ifdef _SC_NL_ARGMAX
6788 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
6789#endif
6790#ifdef _SC_NL_LANGMAX
6791 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
6792#endif
6793#ifdef _SC_NL_MSGMAX
6794 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
6795#endif
6796#ifdef _SC_NL_NMAX
6797 {"SC_NL_NMAX", _SC_NL_NMAX},
6798#endif
6799#ifdef _SC_NL_SETMAX
6800 {"SC_NL_SETMAX", _SC_NL_SETMAX},
6801#endif
6802#ifdef _SC_NL_TEXTMAX
6803 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
6804#endif
6805#ifdef _SC_NPROCESSORS_CONF
6806 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
6807#endif
6808#ifdef _SC_NPROCESSORS_ONLN
6809 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
6810#endif
Fred Draked86ed291999-12-15 15:34:33 +00006811#ifdef _SC_NPROC_CONF
6812 {"SC_NPROC_CONF", _SC_NPROC_CONF},
6813#endif
6814#ifdef _SC_NPROC_ONLN
6815 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
6816#endif
Fred Drakec9680921999-12-13 16:37:25 +00006817#ifdef _SC_NZERO
6818 {"SC_NZERO", _SC_NZERO},
6819#endif
6820#ifdef _SC_OPEN_MAX
6821 {"SC_OPEN_MAX", _SC_OPEN_MAX},
6822#endif
6823#ifdef _SC_PAGESIZE
6824 {"SC_PAGESIZE", _SC_PAGESIZE},
6825#endif
6826#ifdef _SC_PAGE_SIZE
6827 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
6828#endif
6829#ifdef _SC_PASS_MAX
6830 {"SC_PASS_MAX", _SC_PASS_MAX},
6831#endif
6832#ifdef _SC_PHYS_PAGES
6833 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
6834#endif
6835#ifdef _SC_PII
6836 {"SC_PII", _SC_PII},
6837#endif
6838#ifdef _SC_PII_INTERNET
6839 {"SC_PII_INTERNET", _SC_PII_INTERNET},
6840#endif
6841#ifdef _SC_PII_INTERNET_DGRAM
6842 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
6843#endif
6844#ifdef _SC_PII_INTERNET_STREAM
6845 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
6846#endif
6847#ifdef _SC_PII_OSI
6848 {"SC_PII_OSI", _SC_PII_OSI},
6849#endif
6850#ifdef _SC_PII_OSI_CLTS
6851 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
6852#endif
6853#ifdef _SC_PII_OSI_COTS
6854 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
6855#endif
6856#ifdef _SC_PII_OSI_M
6857 {"SC_PII_OSI_M", _SC_PII_OSI_M},
6858#endif
6859#ifdef _SC_PII_SOCKET
6860 {"SC_PII_SOCKET", _SC_PII_SOCKET},
6861#endif
6862#ifdef _SC_PII_XTI
6863 {"SC_PII_XTI", _SC_PII_XTI},
6864#endif
6865#ifdef _SC_POLL
6866 {"SC_POLL", _SC_POLL},
6867#endif
6868#ifdef _SC_PRIORITIZED_IO
6869 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
6870#endif
6871#ifdef _SC_PRIORITY_SCHEDULING
6872 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
6873#endif
6874#ifdef _SC_REALTIME_SIGNALS
6875 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
6876#endif
6877#ifdef _SC_RE_DUP_MAX
6878 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
6879#endif
6880#ifdef _SC_RTSIG_MAX
6881 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
6882#endif
6883#ifdef _SC_SAVED_IDS
6884 {"SC_SAVED_IDS", _SC_SAVED_IDS},
6885#endif
6886#ifdef _SC_SCHAR_MAX
6887 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
6888#endif
6889#ifdef _SC_SCHAR_MIN
6890 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
6891#endif
6892#ifdef _SC_SELECT
6893 {"SC_SELECT", _SC_SELECT},
6894#endif
6895#ifdef _SC_SEMAPHORES
6896 {"SC_SEMAPHORES", _SC_SEMAPHORES},
6897#endif
6898#ifdef _SC_SEM_NSEMS_MAX
6899 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
6900#endif
6901#ifdef _SC_SEM_VALUE_MAX
6902 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
6903#endif
6904#ifdef _SC_SHARED_MEMORY_OBJECTS
6905 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
6906#endif
6907#ifdef _SC_SHRT_MAX
6908 {"SC_SHRT_MAX", _SC_SHRT_MAX},
6909#endif
6910#ifdef _SC_SHRT_MIN
6911 {"SC_SHRT_MIN", _SC_SHRT_MIN},
6912#endif
6913#ifdef _SC_SIGQUEUE_MAX
6914 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
6915#endif
6916#ifdef _SC_SIGRT_MAX
6917 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
6918#endif
6919#ifdef _SC_SIGRT_MIN
6920 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
6921#endif
Fred Draked86ed291999-12-15 15:34:33 +00006922#ifdef _SC_SOFTPOWER
6923 {"SC_SOFTPOWER", _SC_SOFTPOWER},
6924#endif
Fred Drakec9680921999-12-13 16:37:25 +00006925#ifdef _SC_SPLIT_CACHE
6926 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
6927#endif
6928#ifdef _SC_SSIZE_MAX
6929 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
6930#endif
6931#ifdef _SC_STACK_PROT
6932 {"SC_STACK_PROT", _SC_STACK_PROT},
6933#endif
6934#ifdef _SC_STREAM_MAX
6935 {"SC_STREAM_MAX", _SC_STREAM_MAX},
6936#endif
6937#ifdef _SC_SYNCHRONIZED_IO
6938 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
6939#endif
6940#ifdef _SC_THREADS
6941 {"SC_THREADS", _SC_THREADS},
6942#endif
6943#ifdef _SC_THREAD_ATTR_STACKADDR
6944 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
6945#endif
6946#ifdef _SC_THREAD_ATTR_STACKSIZE
6947 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
6948#endif
6949#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
6950 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
6951#endif
6952#ifdef _SC_THREAD_KEYS_MAX
6953 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
6954#endif
6955#ifdef _SC_THREAD_PRIORITY_SCHEDULING
6956 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
6957#endif
6958#ifdef _SC_THREAD_PRIO_INHERIT
6959 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
6960#endif
6961#ifdef _SC_THREAD_PRIO_PROTECT
6962 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
6963#endif
6964#ifdef _SC_THREAD_PROCESS_SHARED
6965 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
6966#endif
6967#ifdef _SC_THREAD_SAFE_FUNCTIONS
6968 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
6969#endif
6970#ifdef _SC_THREAD_STACK_MIN
6971 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
6972#endif
6973#ifdef _SC_THREAD_THREADS_MAX
6974 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
6975#endif
6976#ifdef _SC_TIMERS
6977 {"SC_TIMERS", _SC_TIMERS},
6978#endif
6979#ifdef _SC_TIMER_MAX
6980 {"SC_TIMER_MAX", _SC_TIMER_MAX},
6981#endif
6982#ifdef _SC_TTY_NAME_MAX
6983 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
6984#endif
6985#ifdef _SC_TZNAME_MAX
6986 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
6987#endif
6988#ifdef _SC_T_IOV_MAX
6989 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
6990#endif
6991#ifdef _SC_UCHAR_MAX
6992 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
6993#endif
6994#ifdef _SC_UINT_MAX
6995 {"SC_UINT_MAX", _SC_UINT_MAX},
6996#endif
6997#ifdef _SC_UIO_MAXIOV
6998 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
6999#endif
7000#ifdef _SC_ULONG_MAX
7001 {"SC_ULONG_MAX", _SC_ULONG_MAX},
7002#endif
7003#ifdef _SC_USHRT_MAX
7004 {"SC_USHRT_MAX", _SC_USHRT_MAX},
7005#endif
7006#ifdef _SC_VERSION
7007 {"SC_VERSION", _SC_VERSION},
7008#endif
7009#ifdef _SC_WORD_BIT
7010 {"SC_WORD_BIT", _SC_WORD_BIT},
7011#endif
7012#ifdef _SC_XBS5_ILP32_OFF32
7013 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
7014#endif
7015#ifdef _SC_XBS5_ILP32_OFFBIG
7016 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
7017#endif
7018#ifdef _SC_XBS5_LP64_OFF64
7019 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
7020#endif
7021#ifdef _SC_XBS5_LPBIG_OFFBIG
7022 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
7023#endif
7024#ifdef _SC_XOPEN_CRYPT
7025 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
7026#endif
7027#ifdef _SC_XOPEN_ENH_I18N
7028 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
7029#endif
7030#ifdef _SC_XOPEN_LEGACY
7031 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
7032#endif
7033#ifdef _SC_XOPEN_REALTIME
7034 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
7035#endif
7036#ifdef _SC_XOPEN_REALTIME_THREADS
7037 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
7038#endif
7039#ifdef _SC_XOPEN_SHM
7040 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
7041#endif
7042#ifdef _SC_XOPEN_UNIX
7043 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
7044#endif
7045#ifdef _SC_XOPEN_VERSION
7046 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
7047#endif
7048#ifdef _SC_XOPEN_XCU_VERSION
7049 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
7050#endif
7051#ifdef _SC_XOPEN_XPG2
7052 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
7053#endif
7054#ifdef _SC_XOPEN_XPG3
7055 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
7056#endif
7057#ifdef _SC_XOPEN_XPG4
7058 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
7059#endif
7060};
7061
7062static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007063conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007064{
7065 return conv_confname(arg, valuep, posix_constants_sysconf,
7066 sizeof(posix_constants_sysconf)
7067 / sizeof(struct constdef));
7068}
7069
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007070PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007071"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007072Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007073
7074static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007075posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007076{
7077 PyObject *result = NULL;
7078 int name;
7079
7080 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
7081 int value;
7082
7083 errno = 0;
7084 value = sysconf(name);
7085 if (value == -1 && errno != 0)
7086 posix_error();
7087 else
7088 result = PyInt_FromLong(value);
7089 }
7090 return result;
7091}
7092#endif
7093
7094
Fred Drakebec628d1999-12-15 18:31:10 +00007095/* This code is used to ensure that the tables of configuration value names
7096 * are in sorted order as required by conv_confname(), and also to build the
7097 * the exported dictionaries that are used to publish information about the
7098 * names available on the host platform.
7099 *
7100 * Sorting the table at runtime ensures that the table is properly ordered
7101 * when used, even for platforms we're not able to test on. It also makes
7102 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00007103 */
Fred Drakebec628d1999-12-15 18:31:10 +00007104
7105static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007106cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00007107{
7108 const struct constdef *c1 =
7109 (const struct constdef *) v1;
7110 const struct constdef *c2 =
7111 (const struct constdef *) v2;
7112
7113 return strcmp(c1->name, c2->name);
7114}
7115
7116static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007117setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00007118 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007119{
Fred Drakebec628d1999-12-15 18:31:10 +00007120 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00007121 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00007122
7123 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
7124 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00007125 if (d == NULL)
7126 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007127
Barry Warsaw3155db32000-04-13 15:20:40 +00007128 for (i=0; i < tablesize; ++i) {
7129 PyObject *o = PyInt_FromLong(table[i].value);
7130 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
7131 Py_XDECREF(o);
7132 Py_DECREF(d);
7133 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007134 }
Barry Warsaw3155db32000-04-13 15:20:40 +00007135 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00007136 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00007137 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00007138}
7139
Fred Drakebec628d1999-12-15 18:31:10 +00007140/* Return -1 on failure, 0 on success. */
7141static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007142setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007143{
7144#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00007145 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00007146 sizeof(posix_constants_pathconf)
7147 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007148 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007149 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007150#endif
7151#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00007152 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00007153 sizeof(posix_constants_confstr)
7154 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007155 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007156 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007157#endif
7158#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00007159 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00007160 sizeof(posix_constants_sysconf)
7161 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007162 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007163 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007164#endif
Fred Drakebec628d1999-12-15 18:31:10 +00007165 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00007166}
Fred Draked86ed291999-12-15 15:34:33 +00007167
7168
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007169PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007170"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007171Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007172in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007173
7174static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007175posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007176{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007177 abort();
7178 /*NOTREACHED*/
7179 Py_FatalError("abort() called from Python code didn't abort!");
7180 return NULL;
7181}
Fred Drakebec628d1999-12-15 18:31:10 +00007182
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007183#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007184PyDoc_STRVAR(win32_startfile__doc__,
7185"startfile(filepath) - Start a file with its associated application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007186\n\
7187This acts like double-clicking the file in Explorer, or giving the file\n\
7188name as an argument to the DOS \"start\" command: the file is opened\n\
7189with whatever application (if any) its extension is associated.\n\
7190\n\
7191startfile returns as soon as the associated application is launched.\n\
7192There is no option to wait for the application to close, and no way\n\
7193to retrieve the application's exit status.\n\
7194\n\
7195The filepath is relative to the current directory. If you want to use\n\
7196an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007197the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00007198
7199static PyObject *
7200win32_startfile(PyObject *self, PyObject *args)
7201{
7202 char *filepath;
7203 HINSTANCE rc;
7204 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
7205 return NULL;
7206 Py_BEGIN_ALLOW_THREADS
7207 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
7208 Py_END_ALLOW_THREADS
7209 if (rc <= (HINSTANCE)32)
7210 return win32_error("startfile", filepath);
7211 Py_INCREF(Py_None);
7212 return Py_None;
7213}
7214#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007215
Martin v. Löwis438b5342002-12-27 10:16:42 +00007216#ifdef HAVE_GETLOADAVG
7217PyDoc_STRVAR(posix_getloadavg__doc__,
7218"getloadavg() -> (float, float, float)\n\n\
7219Return the number of processes in the system run queue averaged over\n\
7220the last 1, 5, and 15 minutes or raises OSError if the load average\n\
7221was unobtainable");
7222
7223static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007224posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00007225{
7226 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00007227 if (getloadavg(loadavg, 3)!=3) {
7228 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
7229 return NULL;
7230 } else
7231 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
7232}
7233#endif
7234
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007235#ifdef MS_WINDOWS
7236
7237PyDoc_STRVAR(win32_urandom__doc__,
7238"urandom(n) -> str\n\n\
7239Return a string of n random bytes suitable for cryptographic use.");
7240
7241typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
7242 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
7243 DWORD dwFlags );
7244typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
7245 BYTE *pbBuffer );
7246
7247static CRYPTGENRANDOM pCryptGenRandom = NULL;
7248static HCRYPTPROV hCryptProv = 0;
7249
Tim Peters4ad82172004-08-30 17:02:04 +00007250static PyObject*
7251win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007252{
Tim Petersd3115382004-08-30 17:36:46 +00007253 int howMany;
7254 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007255
Tim Peters4ad82172004-08-30 17:02:04 +00007256 /* Read arguments */
Tim Peters9b279a82004-08-30 17:10:53 +00007257 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
Tim Peters4ad82172004-08-30 17:02:04 +00007258 return NULL;
Tim Peters51eba612004-08-30 17:08:02 +00007259 if (howMany < 0)
7260 return PyErr_Format(PyExc_ValueError,
7261 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007262
Tim Peters4ad82172004-08-30 17:02:04 +00007263 if (hCryptProv == 0) {
7264 HINSTANCE hAdvAPI32 = NULL;
7265 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007266
Tim Peters4ad82172004-08-30 17:02:04 +00007267 /* Obtain handle to the DLL containing CryptoAPI
7268 This should not fail */
7269 hAdvAPI32 = GetModuleHandle("advapi32.dll");
7270 if(hAdvAPI32 == NULL)
7271 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007272
Tim Peters4ad82172004-08-30 17:02:04 +00007273 /* Obtain pointers to the CryptoAPI functions
7274 This will fail on some early versions of Win95 */
7275 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
7276 hAdvAPI32,
7277 "CryptAcquireContextA");
7278 if (pCryptAcquireContext == NULL)
7279 return PyErr_Format(PyExc_NotImplementedError,
7280 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007281
Tim Peters4ad82172004-08-30 17:02:04 +00007282 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
7283 hAdvAPI32, "CryptGenRandom");
7284 if (pCryptAcquireContext == NULL)
7285 return PyErr_Format(PyExc_NotImplementedError,
7286 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007287
Tim Peters4ad82172004-08-30 17:02:04 +00007288 /* Acquire context */
7289 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
7290 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
7291 return win32_error("CryptAcquireContext", NULL);
7292 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007293
Tim Peters4ad82172004-08-30 17:02:04 +00007294 /* Allocate bytes */
Tim Petersd3115382004-08-30 17:36:46 +00007295 result = PyString_FromStringAndSize(NULL, howMany);
7296 if (result != NULL) {
7297 /* Get random data */
7298 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
7299 PyString_AS_STRING(result))) {
7300 Py_DECREF(result);
7301 return win32_error("CryptGenRandom", NULL);
7302 }
Tim Peters4ad82172004-08-30 17:02:04 +00007303 }
Tim Petersd3115382004-08-30 17:36:46 +00007304 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007305}
7306#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007307
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007308static PyMethodDef posix_methods[] = {
7309 {"access", posix_access, METH_VARARGS, posix_access__doc__},
7310#ifdef HAVE_TTYNAME
7311 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
7312#endif
7313 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
7314 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007315#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007316 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007317#endif /* HAVE_CHOWN */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007318#ifdef HAVE_LCHOWN
7319 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
7320#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00007321#ifdef HAVE_CHROOT
7322 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
7323#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007324#ifdef HAVE_CTERMID
Neal Norwitze241ce82003-02-17 18:17:05 +00007325 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007326#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00007327#ifdef HAVE_GETCWD
Neal Norwitze241ce82003-02-17 18:17:05 +00007328 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Walter Dörwald3b918c32002-11-21 20:18:46 +00007329#ifdef Py_USING_UNICODE
Neal Norwitze241ce82003-02-17 18:17:05 +00007330 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00007331#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00007332#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007333#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007334 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007335#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007336 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
7337 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
7338 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007339#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007340 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007341#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007342#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007343 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007344#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007345 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
7346 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
7347 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007348 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007349#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007350 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007351#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007352#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007353 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007354#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007355 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007356#ifdef HAVE_UNAME
Neal Norwitze241ce82003-02-17 18:17:05 +00007357 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007358#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007359 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
7360 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
7361 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007362#ifdef HAVE_TIMES
Neal Norwitze241ce82003-02-17 18:17:05 +00007363 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007364#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007365 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007366#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007367 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
7368 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007369#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00007370#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007371 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
7372 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00007373#if defined(PYOS_OS2)
7374 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
7375 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
7376#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00007377#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007378#ifdef HAVE_FORK1
Neal Norwitze241ce82003-02-17 18:17:05 +00007379 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007380#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007381#ifdef HAVE_FORK
Neal Norwitze241ce82003-02-17 18:17:05 +00007382 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007383#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007384#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Neal Norwitze241ce82003-02-17 18:17:05 +00007385 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007386#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007387#ifdef HAVE_FORKPTY
Neal Norwitze241ce82003-02-17 18:17:05 +00007388 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00007389#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007390#ifdef HAVE_GETEGID
Neal Norwitze241ce82003-02-17 18:17:05 +00007391 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007392#endif /* HAVE_GETEGID */
7393#ifdef HAVE_GETEUID
Neal Norwitze241ce82003-02-17 18:17:05 +00007394 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007395#endif /* HAVE_GETEUID */
7396#ifdef HAVE_GETGID
Neal Norwitze241ce82003-02-17 18:17:05 +00007397 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007398#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00007399#ifdef HAVE_GETGROUPS
Neal Norwitze241ce82003-02-17 18:17:05 +00007400 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007401#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007402 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007403#ifdef HAVE_GETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00007404 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007405#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007406#ifdef HAVE_GETPPID
Neal Norwitze241ce82003-02-17 18:17:05 +00007407 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007408#endif /* HAVE_GETPPID */
7409#ifdef HAVE_GETUID
Neal Norwitze241ce82003-02-17 18:17:05 +00007410 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007411#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007412#ifdef HAVE_GETLOGIN
Neal Norwitze241ce82003-02-17 18:17:05 +00007413 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00007414#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00007415#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007416 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007417#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007418#ifdef HAVE_KILLPG
7419 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
7420#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00007421#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007422 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00007423#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007424#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007425 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007426#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00007427 {"popen2", win32_popen2, METH_VARARGS},
7428 {"popen3", win32_popen3, METH_VARARGS},
7429 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00007430 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007431#else
7432#if defined(PYOS_OS2) && defined(PYCC_GCC)
7433 {"popen2", os2emx_popen2, METH_VARARGS},
7434 {"popen3", os2emx_popen3, METH_VARARGS},
7435 {"popen4", os2emx_popen4, METH_VARARGS},
7436#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00007437#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007438#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007439#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007440 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007441#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007442#ifdef HAVE_SETEUID
7443 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
7444#endif /* HAVE_SETEUID */
7445#ifdef HAVE_SETEGID
7446 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
7447#endif /* HAVE_SETEGID */
7448#ifdef HAVE_SETREUID
7449 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
7450#endif /* HAVE_SETREUID */
7451#ifdef HAVE_SETREGID
7452 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
7453#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007454#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007455 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007456#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007457#ifdef HAVE_SETGROUPS
7458 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
7459#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00007460#ifdef HAVE_GETPGID
7461 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
7462#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007463#ifdef HAVE_SETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00007464 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007465#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007466#ifdef HAVE_WAIT
Neal Norwitze241ce82003-02-17 18:17:05 +00007467 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007468#endif /* HAVE_WAIT */
Tim Petersab034fa2002-02-01 11:27:43 +00007469#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007470 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007471#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007472#ifdef HAVE_GETSID
7473 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
7474#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007475#ifdef HAVE_SETSID
Neal Norwitze241ce82003-02-17 18:17:05 +00007476 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007477#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007478#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007479 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007480#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007481#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007482 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007483#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007484#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007485 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007486#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007487 {"open", posix_open, METH_VARARGS, posix_open__doc__},
7488 {"close", posix_close, METH_VARARGS, posix_close__doc__},
7489 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
7490 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
7491 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
7492 {"read", posix_read, METH_VARARGS, posix_read__doc__},
7493 {"write", posix_write, METH_VARARGS, posix_write__doc__},
7494 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
7495 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00007496 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007497#ifdef HAVE_PIPE
Neal Norwitze241ce82003-02-17 18:17:05 +00007498 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007499#endif
7500#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007501 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007502#endif
Neal Norwitz11690112002-07-30 01:08:28 +00007503#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007504 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
7505#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007506#ifdef HAVE_DEVICE_MACROS
7507 {"major", posix_major, METH_VARARGS, posix_major__doc__},
7508 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
7509 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
7510#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007511#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007512 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007513#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007514#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007515 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007516#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007517#ifdef HAVE_UNSETENV
7518 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
7519#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00007520#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007521 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00007522#endif
Fred Drake4d1e64b2002-04-15 19:40:07 +00007523#ifdef HAVE_FCHDIR
7524 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
7525#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00007526#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007527 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007528#endif
7529#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007530 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007531#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00007532#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00007533#ifdef WCOREDUMP
7534 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
7535#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007536#ifdef WIFCONTINUED
7537 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
7538#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00007539#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007540 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007541#endif /* WIFSTOPPED */
7542#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007543 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007544#endif /* WIFSIGNALED */
7545#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007546 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007547#endif /* WIFEXITED */
7548#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007549 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007550#endif /* WEXITSTATUS */
7551#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007552 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007553#endif /* WTERMSIG */
7554#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007555 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007556#endif /* WSTOPSIG */
7557#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007558#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007559 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007560#endif
7561#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007562 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007563#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00007564#ifdef HAVE_TMPFILE
Neal Norwitze241ce82003-02-17 18:17:05 +00007565 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007566#endif
7567#ifdef HAVE_TEMPNAM
7568 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
7569#endif
7570#ifdef HAVE_TMPNAM
Neal Norwitze241ce82003-02-17 18:17:05 +00007571 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007572#endif
Fred Drakec9680921999-12-13 16:37:25 +00007573#ifdef HAVE_CONFSTR
7574 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
7575#endif
7576#ifdef HAVE_SYSCONF
7577 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
7578#endif
7579#ifdef HAVE_FPATHCONF
7580 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
7581#endif
7582#ifdef HAVE_PATHCONF
7583 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
7584#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007585 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007586#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00007587 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
7588#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007589#ifdef HAVE_GETLOADAVG
Neal Norwitze241ce82003-02-17 18:17:05 +00007590 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00007591#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007592 #ifdef MS_WINDOWS
7593 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
7594 #endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007595 {NULL, NULL} /* Sentinel */
7596};
7597
7598
Barry Warsaw4a342091996-12-19 23:50:02 +00007599static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007600ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00007601{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007602 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00007603}
7604
Guido van Rossumd48f2521997-12-05 22:19:34 +00007605#if defined(PYOS_OS2)
7606/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007607static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007608{
7609 APIRET rc;
7610 ULONG values[QSV_MAX+1];
7611 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00007612 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00007613
7614 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00007615 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007616 Py_END_ALLOW_THREADS
7617
7618 if (rc != NO_ERROR) {
7619 os2_error(rc);
7620 return -1;
7621 }
7622
Fred Drake4d1e64b2002-04-15 19:40:07 +00007623 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
7624 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
7625 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
7626 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
7627 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
7628 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
7629 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007630
7631 switch (values[QSV_VERSION_MINOR]) {
7632 case 0: ver = "2.00"; break;
7633 case 10: ver = "2.10"; break;
7634 case 11: ver = "2.11"; break;
7635 case 30: ver = "3.00"; break;
7636 case 40: ver = "4.00"; break;
7637 case 50: ver = "5.00"; break;
7638 default:
Tim Peters885d4572001-11-28 20:27:42 +00007639 PyOS_snprintf(tmp, sizeof(tmp),
7640 "%d-%d", values[QSV_VERSION_MAJOR],
7641 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007642 ver = &tmp[0];
7643 }
7644
7645 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007646 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007647 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007648
7649 /* Add Indicator of Which Drive was Used to Boot the System */
7650 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
7651 tmp[1] = ':';
7652 tmp[2] = '\0';
7653
Fred Drake4d1e64b2002-04-15 19:40:07 +00007654 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007655}
7656#endif
7657
Barry Warsaw4a342091996-12-19 23:50:02 +00007658static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007659all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00007660{
Guido van Rossum94f6f721999-01-06 18:42:14 +00007661#ifdef F_OK
7662 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007663#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007664#ifdef R_OK
7665 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007666#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007667#ifdef W_OK
7668 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007669#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007670#ifdef X_OK
7671 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007672#endif
Fred Drakec9680921999-12-13 16:37:25 +00007673#ifdef NGROUPS_MAX
7674 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
7675#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007676#ifdef TMP_MAX
7677 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
7678#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007679#ifdef WCONTINUED
7680 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
7681#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007682#ifdef WNOHANG
7683 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007684#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007685#ifdef WUNTRACED
7686 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
7687#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007688#ifdef O_RDONLY
7689 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
7690#endif
7691#ifdef O_WRONLY
7692 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
7693#endif
7694#ifdef O_RDWR
7695 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
7696#endif
7697#ifdef O_NDELAY
7698 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
7699#endif
7700#ifdef O_NONBLOCK
7701 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
7702#endif
7703#ifdef O_APPEND
7704 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
7705#endif
7706#ifdef O_DSYNC
7707 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
7708#endif
7709#ifdef O_RSYNC
7710 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
7711#endif
7712#ifdef O_SYNC
7713 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
7714#endif
7715#ifdef O_NOCTTY
7716 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
7717#endif
7718#ifdef O_CREAT
7719 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
7720#endif
7721#ifdef O_EXCL
7722 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
7723#endif
7724#ifdef O_TRUNC
7725 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
7726#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00007727#ifdef O_BINARY
7728 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
7729#endif
7730#ifdef O_TEXT
7731 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
7732#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007733#ifdef O_LARGEFILE
7734 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
7735#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00007736#ifdef O_SHLOCK
7737 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
7738#endif
7739#ifdef O_EXLOCK
7740 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
7741#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007742
Tim Peters5aa91602002-01-30 05:46:57 +00007743/* MS Windows */
7744#ifdef O_NOINHERIT
7745 /* Don't inherit in child processes. */
7746 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
7747#endif
7748#ifdef _O_SHORT_LIVED
7749 /* Optimize for short life (keep in memory). */
7750 /* MS forgot to define this one with a non-underscore form too. */
7751 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
7752#endif
7753#ifdef O_TEMPORARY
7754 /* Automatically delete when last handle is closed. */
7755 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
7756#endif
7757#ifdef O_RANDOM
7758 /* Optimize for random access. */
7759 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
7760#endif
7761#ifdef O_SEQUENTIAL
7762 /* Optimize for sequential access. */
7763 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
7764#endif
7765
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007766/* GNU extensions. */
7767#ifdef O_DIRECT
7768 /* Direct disk access. */
7769 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
7770#endif
7771#ifdef O_DIRECTORY
7772 /* Must be a directory. */
7773 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
7774#endif
7775#ifdef O_NOFOLLOW
7776 /* Do not follow links. */
7777 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
7778#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00007779
Barry Warsaw5676bd12003-01-07 20:57:09 +00007780 /* These come from sysexits.h */
7781#ifdef EX_OK
7782 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007783#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007784#ifdef EX_USAGE
7785 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007786#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007787#ifdef EX_DATAERR
7788 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007789#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007790#ifdef EX_NOINPUT
7791 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007792#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007793#ifdef EX_NOUSER
7794 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007795#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007796#ifdef EX_NOHOST
7797 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007798#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007799#ifdef EX_UNAVAILABLE
7800 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007801#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007802#ifdef EX_SOFTWARE
7803 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007804#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007805#ifdef EX_OSERR
7806 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007807#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007808#ifdef EX_OSFILE
7809 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007810#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007811#ifdef EX_CANTCREAT
7812 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007813#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007814#ifdef EX_IOERR
7815 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007816#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007817#ifdef EX_TEMPFAIL
7818 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007819#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007820#ifdef EX_PROTOCOL
7821 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007822#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007823#ifdef EX_NOPERM
7824 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007825#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007826#ifdef EX_CONFIG
7827 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007828#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007829#ifdef EX_NOTFOUND
7830 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007831#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007832
Guido van Rossum246bc171999-02-01 23:54:31 +00007833#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007834#if defined(PYOS_OS2) && defined(PYCC_GCC)
7835 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
7836 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
7837 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
7838 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
7839 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
7840 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
7841 if (ins(d, "P_PM", (long)P_PM)) return -1;
7842 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
7843 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
7844 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
7845 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
7846 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
7847 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
7848 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
7849 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
7850 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
7851 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
7852 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
7853 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
7854 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
7855#else
Guido van Rossum7d385291999-02-16 19:38:04 +00007856 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
7857 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
7858 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
7859 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
7860 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00007861#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007862#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00007863
Guido van Rossumd48f2521997-12-05 22:19:34 +00007864#if defined(PYOS_OS2)
7865 if (insertvalues(d)) return -1;
7866#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007867 return 0;
7868}
7869
7870
Tim Peters5aa91602002-01-30 05:46:57 +00007871#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007872#define INITFUNC initnt
7873#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007874
7875#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007876#define INITFUNC initos2
7877#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007878
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007879#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007880#define INITFUNC initposix
7881#define MODNAME "posix"
7882#endif
7883
Mark Hammondfe51c6d2002-08-02 02:27:13 +00007884PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007885INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00007886{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007887 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00007888
Fred Drake4d1e64b2002-04-15 19:40:07 +00007889 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007890 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00007891 posix__doc__);
Tim Peters5aa91602002-01-30 05:46:57 +00007892
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007893 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007894 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00007895 Py_XINCREF(v);
7896 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007897 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00007898 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00007899
Fred Drake4d1e64b2002-04-15 19:40:07 +00007900 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00007901 return;
7902
Fred Drake4d1e64b2002-04-15 19:40:07 +00007903 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00007904 return;
7905
Fred Drake4d1e64b2002-04-15 19:40:07 +00007906 Py_INCREF(PyExc_OSError);
7907 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00007908
Guido van Rossumb3d39562000-01-31 18:41:26 +00007909#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00007910 if (posix_putenv_garbage == NULL)
7911 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00007912#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007913
Guido van Rossum14648392001-12-08 18:02:58 +00007914 stat_result_desc.name = MODNAME ".stat_result";
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007915 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
7916 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
7917 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007918 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007919 structseq_new = StatResultType.tp_new;
7920 StatResultType.tp_new = statresult_new;
Fred Drake4d1e64b2002-04-15 19:40:07 +00007921 Py_INCREF((PyObject*) &StatResultType);
7922 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007923
Guido van Rossum14648392001-12-08 18:02:58 +00007924 statvfs_result_desc.name = MODNAME ".statvfs_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007925 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Fred Drake4d1e64b2002-04-15 19:40:07 +00007926 Py_INCREF((PyObject*) &StatVFSResultType);
7927 PyModule_AddObject(m, "statvfs_result",
7928 (PyObject*) &StatVFSResultType);
Guido van Rossumb6775db1994-08-01 11:34:53 +00007929}