blob: e4a0200f046628be1908b8c5df19a81874610be0 [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);
1994 *sec = intval;
Tim Peters96940cf2002-09-10 15:37:28 +00001995 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001996 if (*usec < 0)
1997 /* If rounding gave us a negative number,
1998 truncate. */
1999 *usec = 0;
2000 return 0;
2001 }
2002 intval = PyInt_AsLong(t);
2003 if (intval == -1 && PyErr_Occurred())
2004 return -1;
2005 *sec = intval;
2006 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00002007 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002008}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002009
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002010PyDoc_STRVAR(posix_utime__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002011"utime(path, (atime, utime))\n\
2012utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00002013Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002014second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002015
Barry Warsaw53699e91996-12-10 23:23:01 +00002016static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002017posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002018{
Neal Norwitz2adf2102004-06-09 01:46:02 +00002019 char *path = NULL;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002020 long atime, mtime, ausec, musec;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002021 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002022 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002023
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002024#if defined(HAVE_UTIMES)
2025 struct timeval buf[2];
2026#define ATIME buf[0].tv_sec
2027#define MTIME buf[1].tv_sec
2028#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002029/* XXX should define struct utimbuf instead, above */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002030 struct utimbuf buf;
2031#define ATIME buf.actime
2032#define MTIME buf.modtime
2033#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002034#else /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002035 time_t buf[2];
2036#define ATIME buf[0]
2037#define MTIME buf[1]
2038#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002039#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002040
Mark Hammond817c9292003-12-03 01:22:38 +00002041 int have_unicode_filename = 0;
2042#ifdef Py_WIN_WIDE_FILENAMES
2043 PyUnicodeObject *obwpath;
2044 wchar_t *wpath;
2045 if (unicode_file_names()) {
2046 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
2047 wpath = PyUnicode_AS_UNICODE(obwpath);
2048 have_unicode_filename = 1;
2049 } else
2050 /* Drop the argument parsing error as narrow strings
2051 are also valid. */
2052 PyErr_Clear();
2053 }
2054#endif /* Py_WIN_WIDE_FILENAMES */
2055
2056 if (!have_unicode_filename && \
Hye-Shik Chang2b2c9732004-01-04 13:54:25 +00002057 !PyArg_ParseTuple(args, "etO:utime",
2058 Py_FileSystemDefaultEncoding, &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002059 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002060 if (arg == Py_None) {
2061 /* optional time values not given */
2062 Py_BEGIN_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002063#ifdef Py_WIN_WIDE_FILENAMES
2064 if (have_unicode_filename)
2065 res = _wutime(wpath, NULL);
2066 else
2067#endif /* Py_WIN_WIDE_FILENAMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002068 res = utime(path, NULL);
2069 Py_END_ALLOW_THREADS
2070 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002071 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00002072 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002073 "utime() arg 2 must be a tuple (atime, mtime)");
Neal Norwitz96652712004-06-06 20:40:27 +00002074 PyMem_Free(path);
Barry Warsaw3cef8562000-05-01 16:17:24 +00002075 return NULL;
2076 }
2077 else {
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002078 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Neal Norwitz96652712004-06-06 20:40:27 +00002079 &atime, &ausec) == -1) {
2080 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002081 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002082 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002083 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Neal Norwitz96652712004-06-06 20:40:27 +00002084 &mtime, &musec) == -1) {
2085 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002086 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002087 }
Barry Warsaw3cef8562000-05-01 16:17:24 +00002088 ATIME = atime;
2089 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002090#ifdef HAVE_UTIMES
2091 buf[0].tv_usec = ausec;
2092 buf[1].tv_usec = musec;
2093 Py_BEGIN_ALLOW_THREADS
2094 res = utimes(path, buf);
2095 Py_END_ALLOW_THREADS
2096#else
Barry Warsaw3cef8562000-05-01 16:17:24 +00002097 Py_BEGIN_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002098#ifdef Py_WIN_WIDE_FILENAMES
2099 if (have_unicode_filename)
Tim Peters4ad82172004-08-30 17:02:04 +00002100 /* utime is OK with utimbuf, but _wutime insists
2101 on _utimbuf (the msvc headers assert the
Mark Hammond817c9292003-12-03 01:22:38 +00002102 underscore version is ansi) */
2103 res = _wutime(wpath, (struct _utimbuf *)UTIME_ARG);
2104 else
2105#endif /* Py_WIN_WIDE_FILENAMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002106 res = utime(path, UTIME_ARG);
2107 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002108#endif /* HAVE_UTIMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002109 }
Mark Hammond2d5914b2004-05-04 08:10:37 +00002110 if (res < 0) {
2111#ifdef Py_WIN_WIDE_FILENAMES
Neal Norwitz2adf2102004-06-09 01:46:02 +00002112 if (have_unicode_filename)
Mark Hammond2d5914b2004-05-04 08:10:37 +00002113 return posix_error_with_unicode_filename(wpath);
2114#endif /* Py_WIN_WIDE_FILENAMES */
Neal Norwitz96652712004-06-06 20:40:27 +00002115 return posix_error_with_allocated_filename(path);
Mark Hammond2d5914b2004-05-04 08:10:37 +00002116 }
Neal Norwitz96652712004-06-06 20:40:27 +00002117 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002118 Py_INCREF(Py_None);
2119 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002120#undef UTIME_ARG
2121#undef ATIME
2122#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002123}
2124
Guido van Rossum85e3b011991-06-03 12:42:10 +00002125
Guido van Rossum3b066191991-06-04 19:40:25 +00002126/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002127
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002128PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002129"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002130Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002131
Barry Warsaw53699e91996-12-10 23:23:01 +00002132static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002133posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002134{
2135 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002136 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002137 return NULL;
2138 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00002139 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002140}
2141
Martin v. Löwis114619e2002-10-07 06:44:21 +00002142#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
2143static void
2144free_string_array(char **array, int count)
2145{
2146 int i;
2147 for (i = 0; i < count; i++)
2148 PyMem_Free(array[i]);
2149 PyMem_DEL(array);
2150}
2151#endif
2152
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002153
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002154#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002155PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002156"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002157Execute an executable path with arguments, replacing current process.\n\
2158\n\
2159 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002160 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002161
Barry Warsaw53699e91996-12-10 23:23:01 +00002162static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002163posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002164{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002165 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002166 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002167 char **argvlist;
2168 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002169 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002170
Guido van Rossum89b33251993-10-22 14:26:06 +00002171 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00002172 argv is a list or tuple of strings. */
2173
Martin v. Löwis114619e2002-10-07 06:44:21 +00002174 if (!PyArg_ParseTuple(args, "etO:execv",
2175 Py_FileSystemDefaultEncoding,
2176 &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002177 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002178 if (PyList_Check(argv)) {
2179 argc = PyList_Size(argv);
2180 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002181 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002182 else if (PyTuple_Check(argv)) {
2183 argc = PyTuple_Size(argv);
2184 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002185 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002186 else {
Fred Drake661ea262000-10-24 19:57:45 +00002187 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002188 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002189 return NULL;
2190 }
2191
Barry Warsaw53699e91996-12-10 23:23:01 +00002192 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002193 if (argvlist == NULL) {
2194 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002195 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002196 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002197 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002198 if (!PyArg_Parse((*getitem)(argv, i), "et",
2199 Py_FileSystemDefaultEncoding,
2200 &argvlist[i])) {
2201 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00002202 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002203 "execv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002204 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002205 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00002206
Guido van Rossum85e3b011991-06-03 12:42:10 +00002207 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002208 }
2209 argvlist[argc] = NULL;
2210
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002211 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002212
Guido van Rossum85e3b011991-06-03 12:42:10 +00002213 /* If we get here it's definitely an error */
2214
Martin v. Löwis114619e2002-10-07 06:44:21 +00002215 free_string_array(argvlist, argc);
2216 PyMem_Free(path);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002217 return posix_error();
2218}
2219
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002220
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002221PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002222"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002223Execute a path with arguments and environment, replacing current process.\n\
2224\n\
2225 path: path of executable file\n\
2226 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002227 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002228
Barry Warsaw53699e91996-12-10 23:23:01 +00002229static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002230posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002231{
2232 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002233 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002234 char **argvlist;
2235 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002236 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002237 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002238 PyObject *(*getitem)(PyObject *, int);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002239 int lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002240
2241 /* execve has three arguments: (path, argv, env), where
2242 argv is a list or tuple of strings and env is a dictionary
2243 like posix.environ. */
2244
Martin v. Löwis114619e2002-10-07 06:44:21 +00002245 if (!PyArg_ParseTuple(args, "etOO:execve",
2246 Py_FileSystemDefaultEncoding,
2247 &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002248 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002249 if (PyList_Check(argv)) {
2250 argc = PyList_Size(argv);
2251 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002252 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002253 else if (PyTuple_Check(argv)) {
2254 argc = PyTuple_Size(argv);
2255 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002256 }
2257 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002258 PyErr_SetString(PyExc_TypeError,
2259 "execve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002260 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002261 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002262 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002263 PyErr_SetString(PyExc_TypeError,
2264 "execve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002265 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002266 }
2267
Barry Warsaw53699e91996-12-10 23:23:01 +00002268 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002269 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002270 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002271 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002272 }
2273 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002274 if (!PyArg_Parse((*getitem)(argv, i),
Martin v. Löwis114619e2002-10-07 06:44:21 +00002275 "et;execve() arg 2 must contain only strings",
Guido van Rossum1e700d22002-10-16 16:52:11 +00002276 Py_FileSystemDefaultEncoding,
Barry Warsaw43d68b81996-12-19 22:10:44 +00002277 &argvlist[i]))
2278 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002279 lastarg = i;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002280 goto fail_1;
2281 }
2282 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002283 lastarg = argc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002284 argvlist[argc] = NULL;
2285
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002286 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002287 if (i < 0)
2288 goto fail_1;
Barry Warsaw53699e91996-12-10 23:23:01 +00002289 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002290 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002291 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002292 goto fail_1;
2293 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002294 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002295 keys = PyMapping_Keys(env);
2296 vals = PyMapping_Values(env);
2297 if (!keys || !vals)
2298 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002299 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2300 PyErr_SetString(PyExc_TypeError,
2301 "execve(): env.keys() or env.values() is not a list");
2302 goto fail_2;
2303 }
Tim Peters5aa91602002-01-30 05:46:57 +00002304
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002305 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002306 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002307 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002308
2309 key = PyList_GetItem(keys, pos);
2310 val = PyList_GetItem(vals, pos);
2311 if (!key || !val)
2312 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002313
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002314 if (!PyArg_Parse(
2315 key,
2316 "s;execve() arg 3 contains a non-string key",
2317 &k) ||
2318 !PyArg_Parse(
2319 val,
2320 "s;execve() arg 3 contains a non-string value",
2321 &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00002322 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002323 goto fail_2;
2324 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00002325
2326#if defined(PYOS_OS2)
2327 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
2328 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
2329#endif
Tim Petersc8996f52001-12-03 20:41:00 +00002330 len = PyString_Size(key) + PyString_Size(val) + 2;
2331 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002332 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002333 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002334 goto fail_2;
2335 }
Tim Petersc8996f52001-12-03 20:41:00 +00002336 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002337 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00002338#if defined(PYOS_OS2)
2339 }
2340#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002341 }
2342 envlist[envc] = 0;
2343
2344 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00002345
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002346 /* If we get here it's definitely an error */
2347
2348 (void) posix_error();
2349
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002350 fail_2:
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002351 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00002352 PyMem_DEL(envlist[envc]);
2353 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002354 fail_1:
2355 free_string_array(argvlist, lastarg);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002356 Py_XDECREF(vals);
2357 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002358 fail_0:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002359 PyMem_Free(path);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002360 return NULL;
2361}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002362#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002363
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002364
Guido van Rossuma1065681999-01-25 23:20:23 +00002365#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002366PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002367"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002368Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002369\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002370 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002371 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002372 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002373
2374static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002375posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002376{
2377 char *path;
2378 PyObject *argv;
2379 char **argvlist;
2380 int mode, i, argc;
Tim Peters79248aa2001-08-29 21:37:10 +00002381 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002382 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00002383
2384 /* spawnv has three arguments: (mode, path, argv), where
2385 argv is a list or tuple of strings. */
2386
Martin v. Löwis114619e2002-10-07 06:44:21 +00002387 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
2388 Py_FileSystemDefaultEncoding,
2389 &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00002390 return NULL;
2391 if (PyList_Check(argv)) {
2392 argc = PyList_Size(argv);
2393 getitem = PyList_GetItem;
2394 }
2395 else if (PyTuple_Check(argv)) {
2396 argc = PyTuple_Size(argv);
2397 getitem = PyTuple_GetItem;
2398 }
2399 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002400 PyErr_SetString(PyExc_TypeError,
2401 "spawnv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002402 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002403 return NULL;
2404 }
2405
2406 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002407 if (argvlist == NULL) {
2408 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002409 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002410 }
Guido van Rossuma1065681999-01-25 23:20:23 +00002411 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002412 if (!PyArg_Parse((*getitem)(argv, i), "et",
2413 Py_FileSystemDefaultEncoding,
2414 &argvlist[i])) {
2415 free_string_array(argvlist, i);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002416 PyErr_SetString(
2417 PyExc_TypeError,
2418 "spawnv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002419 PyMem_Free(path);
Fred Drake137507e2000-06-01 02:02:46 +00002420 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00002421 }
2422 }
2423 argvlist[argc] = NULL;
2424
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002425#if defined(PYOS_OS2) && defined(PYCC_GCC)
2426 Py_BEGIN_ALLOW_THREADS
2427 spawnval = spawnv(mode, path, argvlist);
2428 Py_END_ALLOW_THREADS
2429#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002430 if (mode == _OLD_P_OVERLAY)
2431 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00002432
Tim Peters25059d32001-12-07 20:35:43 +00002433 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002434 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00002435 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002436#endif
Tim Peters5aa91602002-01-30 05:46:57 +00002437
Martin v. Löwis114619e2002-10-07 06:44:21 +00002438 free_string_array(argvlist, argc);
2439 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002440
Fred Drake699f3522000-06-29 21:12:41 +00002441 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002442 return posix_error();
2443 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002444#if SIZEOF_LONG == SIZEOF_VOID_P
2445 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002446#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00002447 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002448#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002449}
2450
2451
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002452PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002453"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002454Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002455\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002456 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002457 path: path of executable file\n\
2458 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002459 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002460
2461static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002462posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002463{
2464 char *path;
2465 PyObject *argv, *env;
2466 char **argvlist;
2467 char **envlist;
2468 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
2469 int mode, i, pos, argc, envc;
Tim Peters79248aa2001-08-29 21:37:10 +00002470 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002471 PyObject *(*getitem)(PyObject *, int);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002472 int lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002473
2474 /* spawnve has four arguments: (mode, path, argv, env), where
2475 argv is a list or tuple of strings and env is a dictionary
2476 like posix.environ. */
2477
Martin v. Löwis114619e2002-10-07 06:44:21 +00002478 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
2479 Py_FileSystemDefaultEncoding,
2480 &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00002481 return NULL;
2482 if (PyList_Check(argv)) {
2483 argc = PyList_Size(argv);
2484 getitem = PyList_GetItem;
2485 }
2486 else if (PyTuple_Check(argv)) {
2487 argc = PyTuple_Size(argv);
2488 getitem = PyTuple_GetItem;
2489 }
2490 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002491 PyErr_SetString(PyExc_TypeError,
2492 "spawnve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002493 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002494 }
2495 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002496 PyErr_SetString(PyExc_TypeError,
2497 "spawnve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002498 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002499 }
2500
2501 argvlist = PyMem_NEW(char *, argc+1);
2502 if (argvlist == NULL) {
2503 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002504 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002505 }
2506 for (i = 0; i < argc; i++) {
2507 if (!PyArg_Parse((*getitem)(argv, i),
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002508 "et;spawnve() arg 2 must contain only strings",
Martin v. Löwis114619e2002-10-07 06:44:21 +00002509 Py_FileSystemDefaultEncoding,
Guido van Rossuma1065681999-01-25 23:20:23 +00002510 &argvlist[i]))
2511 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002512 lastarg = i;
Guido van Rossuma1065681999-01-25 23:20:23 +00002513 goto fail_1;
2514 }
2515 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002516 lastarg = argc;
Guido van Rossuma1065681999-01-25 23:20:23 +00002517 argvlist[argc] = NULL;
2518
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002519 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002520 if (i < 0)
2521 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00002522 envlist = PyMem_NEW(char *, i + 1);
2523 if (envlist == NULL) {
2524 PyErr_NoMemory();
2525 goto fail_1;
2526 }
2527 envc = 0;
2528 keys = PyMapping_Keys(env);
2529 vals = PyMapping_Values(env);
2530 if (!keys || !vals)
2531 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002532 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2533 PyErr_SetString(PyExc_TypeError,
2534 "spawnve(): env.keys() or env.values() is not a list");
2535 goto fail_2;
2536 }
Tim Peters5aa91602002-01-30 05:46:57 +00002537
Guido van Rossuma1065681999-01-25 23:20:23 +00002538 for (pos = 0; pos < i; pos++) {
2539 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002540 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00002541
2542 key = PyList_GetItem(keys, pos);
2543 val = PyList_GetItem(vals, pos);
2544 if (!key || !val)
2545 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002546
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002547 if (!PyArg_Parse(
2548 key,
2549 "s;spawnve() arg 3 contains a non-string key",
2550 &k) ||
2551 !PyArg_Parse(
2552 val,
2553 "s;spawnve() arg 3 contains a non-string value",
2554 &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00002555 {
2556 goto fail_2;
2557 }
Tim Petersc8996f52001-12-03 20:41:00 +00002558 len = PyString_Size(key) + PyString_Size(val) + 2;
2559 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00002560 if (p == NULL) {
2561 PyErr_NoMemory();
2562 goto fail_2;
2563 }
Tim Petersc8996f52001-12-03 20:41:00 +00002564 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00002565 envlist[envc++] = p;
2566 }
2567 envlist[envc] = 0;
2568
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002569#if defined(PYOS_OS2) && defined(PYCC_GCC)
2570 Py_BEGIN_ALLOW_THREADS
2571 spawnval = spawnve(mode, path, argvlist, envlist);
2572 Py_END_ALLOW_THREADS
2573#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002574 if (mode == _OLD_P_OVERLAY)
2575 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00002576
2577 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002578 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00002579 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002580#endif
Tim Peters25059d32001-12-07 20:35:43 +00002581
Fred Drake699f3522000-06-29 21:12:41 +00002582 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002583 (void) posix_error();
2584 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002585#if SIZEOF_LONG == SIZEOF_VOID_P
2586 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002587#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00002588 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002589#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002590
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002591 fail_2:
Guido van Rossuma1065681999-01-25 23:20:23 +00002592 while (--envc >= 0)
2593 PyMem_DEL(envlist[envc]);
2594 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002595 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002596 free_string_array(argvlist, lastarg);
Guido van Rossuma1065681999-01-25 23:20:23 +00002597 Py_XDECREF(vals);
2598 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002599 fail_0:
2600 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002601 return res;
2602}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00002603
2604/* OS/2 supports spawnvp & spawnvpe natively */
2605#if defined(PYOS_OS2)
2606PyDoc_STRVAR(posix_spawnvp__doc__,
2607"spawnvp(mode, file, args)\n\n\
2608Execute the program 'file' in a new process, using the environment\n\
2609search path to find the file.\n\
2610\n\
2611 mode: mode of process creation\n\
2612 file: executable file name\n\
2613 args: tuple or list of strings");
2614
2615static PyObject *
2616posix_spawnvp(PyObject *self, PyObject *args)
2617{
2618 char *path;
2619 PyObject *argv;
2620 char **argvlist;
2621 int mode, i, argc;
2622 Py_intptr_t spawnval;
2623 PyObject *(*getitem)(PyObject *, int);
2624
2625 /* spawnvp has three arguments: (mode, path, argv), where
2626 argv is a list or tuple of strings. */
2627
2628 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
2629 Py_FileSystemDefaultEncoding,
2630 &path, &argv))
2631 return NULL;
2632 if (PyList_Check(argv)) {
2633 argc = PyList_Size(argv);
2634 getitem = PyList_GetItem;
2635 }
2636 else if (PyTuple_Check(argv)) {
2637 argc = PyTuple_Size(argv);
2638 getitem = PyTuple_GetItem;
2639 }
2640 else {
2641 PyErr_SetString(PyExc_TypeError,
2642 "spawnvp() arg 2 must be a tuple or list");
2643 PyMem_Free(path);
2644 return NULL;
2645 }
2646
2647 argvlist = PyMem_NEW(char *, argc+1);
2648 if (argvlist == NULL) {
2649 PyMem_Free(path);
2650 return PyErr_NoMemory();
2651 }
2652 for (i = 0; i < argc; i++) {
2653 if (!PyArg_Parse((*getitem)(argv, i), "et",
2654 Py_FileSystemDefaultEncoding,
2655 &argvlist[i])) {
2656 free_string_array(argvlist, i);
2657 PyErr_SetString(
2658 PyExc_TypeError,
2659 "spawnvp() arg 2 must contain only strings");
2660 PyMem_Free(path);
2661 return NULL;
2662 }
2663 }
2664 argvlist[argc] = NULL;
2665
2666 Py_BEGIN_ALLOW_THREADS
2667#if defined(PYCC_GCC)
2668 spawnval = spawnvp(mode, path, argvlist);
2669#else
2670 spawnval = _spawnvp(mode, path, argvlist);
2671#endif
2672 Py_END_ALLOW_THREADS
2673
2674 free_string_array(argvlist, argc);
2675 PyMem_Free(path);
2676
2677 if (spawnval == -1)
2678 return posix_error();
2679 else
2680 return Py_BuildValue("l", (long) spawnval);
2681}
2682
2683
2684PyDoc_STRVAR(posix_spawnvpe__doc__,
2685"spawnvpe(mode, file, args, env)\n\n\
2686Execute the program 'file' in a new process, using the environment\n\
2687search path to find the file.\n\
2688\n\
2689 mode: mode of process creation\n\
2690 file: executable file name\n\
2691 args: tuple or list of arguments\n\
2692 env: dictionary of strings mapping to strings");
2693
2694static PyObject *
2695posix_spawnvpe(PyObject *self, PyObject *args)
2696{
2697 char *path;
2698 PyObject *argv, *env;
2699 char **argvlist;
2700 char **envlist;
2701 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
2702 int mode, i, pos, argc, envc;
2703 Py_intptr_t spawnval;
2704 PyObject *(*getitem)(PyObject *, int);
2705 int lastarg = 0;
2706
2707 /* spawnvpe has four arguments: (mode, path, argv, env), where
2708 argv is a list or tuple of strings and env is a dictionary
2709 like posix.environ. */
2710
2711 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
2712 Py_FileSystemDefaultEncoding,
2713 &path, &argv, &env))
2714 return NULL;
2715 if (PyList_Check(argv)) {
2716 argc = PyList_Size(argv);
2717 getitem = PyList_GetItem;
2718 }
2719 else if (PyTuple_Check(argv)) {
2720 argc = PyTuple_Size(argv);
2721 getitem = PyTuple_GetItem;
2722 }
2723 else {
2724 PyErr_SetString(PyExc_TypeError,
2725 "spawnvpe() arg 2 must be a tuple or list");
2726 goto fail_0;
2727 }
2728 if (!PyMapping_Check(env)) {
2729 PyErr_SetString(PyExc_TypeError,
2730 "spawnvpe() arg 3 must be a mapping object");
2731 goto fail_0;
2732 }
2733
2734 argvlist = PyMem_NEW(char *, argc+1);
2735 if (argvlist == NULL) {
2736 PyErr_NoMemory();
2737 goto fail_0;
2738 }
2739 for (i = 0; i < argc; i++) {
2740 if (!PyArg_Parse((*getitem)(argv, i),
2741 "et;spawnvpe() arg 2 must contain only strings",
2742 Py_FileSystemDefaultEncoding,
2743 &argvlist[i]))
2744 {
2745 lastarg = i;
2746 goto fail_1;
2747 }
2748 }
2749 lastarg = argc;
2750 argvlist[argc] = NULL;
2751
2752 i = PyMapping_Size(env);
2753 if (i < 0)
2754 goto fail_1;
2755 envlist = PyMem_NEW(char *, i + 1);
2756 if (envlist == NULL) {
2757 PyErr_NoMemory();
2758 goto fail_1;
2759 }
2760 envc = 0;
2761 keys = PyMapping_Keys(env);
2762 vals = PyMapping_Values(env);
2763 if (!keys || !vals)
2764 goto fail_2;
2765 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2766 PyErr_SetString(PyExc_TypeError,
2767 "spawnvpe(): env.keys() or env.values() is not a list");
2768 goto fail_2;
2769 }
2770
2771 for (pos = 0; pos < i; pos++) {
2772 char *p, *k, *v;
2773 size_t len;
2774
2775 key = PyList_GetItem(keys, pos);
2776 val = PyList_GetItem(vals, pos);
2777 if (!key || !val)
2778 goto fail_2;
2779
2780 if (!PyArg_Parse(
2781 key,
2782 "s;spawnvpe() arg 3 contains a non-string key",
2783 &k) ||
2784 !PyArg_Parse(
2785 val,
2786 "s;spawnvpe() arg 3 contains a non-string value",
2787 &v))
2788 {
2789 goto fail_2;
2790 }
2791 len = PyString_Size(key) + PyString_Size(val) + 2;
2792 p = PyMem_NEW(char, len);
2793 if (p == NULL) {
2794 PyErr_NoMemory();
2795 goto fail_2;
2796 }
2797 PyOS_snprintf(p, len, "%s=%s", k, v);
2798 envlist[envc++] = p;
2799 }
2800 envlist[envc] = 0;
2801
2802 Py_BEGIN_ALLOW_THREADS
2803#if defined(PYCC_GCC)
2804 spawnval = spawnve(mode, path, argvlist, envlist);
2805#else
2806 spawnval = _spawnve(mode, path, argvlist, envlist);
2807#endif
2808 Py_END_ALLOW_THREADS
2809
2810 if (spawnval == -1)
2811 (void) posix_error();
2812 else
2813 res = Py_BuildValue("l", (long) spawnval);
2814
2815 fail_2:
2816 while (--envc >= 0)
2817 PyMem_DEL(envlist[envc]);
2818 PyMem_DEL(envlist);
2819 fail_1:
2820 free_string_array(argvlist, lastarg);
2821 Py_XDECREF(vals);
2822 Py_XDECREF(keys);
2823 fail_0:
2824 PyMem_Free(path);
2825 return res;
2826}
2827#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00002828#endif /* HAVE_SPAWNV */
2829
2830
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002831#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002832PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002833"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002834Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
2835\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002836Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002837
2838static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002839posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002840{
Neal Norwitze241ce82003-02-17 18:17:05 +00002841 int pid = fork1();
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002842 if (pid == -1)
2843 return posix_error();
2844 PyOS_AfterFork();
2845 return PyInt_FromLong((long)pid);
2846}
2847#endif
2848
2849
Guido van Rossumad0ee831995-03-01 10:34:45 +00002850#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002851PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002852"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002853Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002854Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002855
Barry Warsaw53699e91996-12-10 23:23:01 +00002856static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002857posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002858{
Neal Norwitze241ce82003-02-17 18:17:05 +00002859 int pid = fork();
Guido van Rossum85e3b011991-06-03 12:42:10 +00002860 if (pid == -1)
2861 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00002862 if (pid == 0)
2863 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00002864 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002865}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002866#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002867
Neal Norwitzb59798b2003-03-21 01:43:31 +00002868/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00002869/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
2870#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00002871#define DEV_PTY_FILE "/dev/ptc"
2872#define HAVE_DEV_PTMX
2873#else
2874#define DEV_PTY_FILE "/dev/ptmx"
2875#endif
2876
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002877#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002878#ifdef HAVE_PTY_H
2879#include <pty.h>
2880#else
2881#ifdef HAVE_LIBUTIL_H
2882#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00002883#endif /* HAVE_LIBUTIL_H */
2884#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00002885#ifdef HAVE_STROPTS_H
2886#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002887#endif
2888#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00002889
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002890#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002891PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002892"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002893Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00002894
2895static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002896posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002897{
2898 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00002899#ifndef HAVE_OPENPTY
2900 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00002901#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002902#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00002903 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002904#ifdef sun
2905 extern char *ptsname();
2906#endif
2907#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00002908
Thomas Wouters70c21a12000-07-14 14:28:33 +00002909#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00002910 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
2911 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00002912#elif defined(HAVE__GETPTY)
Thomas Wouters70c21a12000-07-14 14:28:33 +00002913 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
2914 if (slave_name == NULL)
2915 return posix_error();
2916
2917 slave_fd = open(slave_name, O_RDWR);
2918 if (slave_fd < 0)
2919 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002920#else
Neal Norwitzb59798b2003-03-21 01:43:31 +00002921 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002922 if (master_fd < 0)
2923 return posix_error();
Anthony Baxter9ceaa722004-10-13 14:48:50 +00002924 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00002925 /* change permission of slave */
2926 if (grantpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00002927 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002928 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00002929 }
2930 /* unlock slave */
2931 if (unlockpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00002932 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002933 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00002934 }
Anthony Baxter9ceaa722004-10-13 14:48:50 +00002935 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002936 slave_name = ptsname(master_fd); /* get name of slave */
2937 if (slave_name == NULL)
2938 return posix_error();
2939 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
2940 if (slave_fd < 0)
2941 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00002942#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002943 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
2944 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00002945#ifndef __hpux
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002946 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00002947#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002948#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00002949#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00002950
Fred Drake8cef4cf2000-06-28 16:40:38 +00002951 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00002952
Fred Drake8cef4cf2000-06-28 16:40:38 +00002953}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002954#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00002955
2956#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002957PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002958"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00002959Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
2960Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002961To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00002962
2963static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002964posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002965{
2966 int master_fd, pid;
Tim Peters5aa91602002-01-30 05:46:57 +00002967
Fred Drake8cef4cf2000-06-28 16:40:38 +00002968 pid = forkpty(&master_fd, NULL, NULL, NULL);
2969 if (pid == -1)
2970 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00002971 if (pid == 0)
2972 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00002973 return Py_BuildValue("(ii)", pid, master_fd);
2974}
2975#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002976
Guido van Rossumad0ee831995-03-01 10:34:45 +00002977#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002978PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002979"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002980Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002981
Barry Warsaw53699e91996-12-10 23:23:01 +00002982static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002983posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002984{
Barry Warsaw53699e91996-12-10 23:23:01 +00002985 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002986}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002987#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002988
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002989
Guido van Rossumad0ee831995-03-01 10:34:45 +00002990#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002991PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002992"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002993Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002994
Barry Warsaw53699e91996-12-10 23:23:01 +00002995static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002996posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002997{
Barry Warsaw53699e91996-12-10 23:23:01 +00002998 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002999}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003000#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003001
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003002
Guido van Rossumad0ee831995-03-01 10:34:45 +00003003#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003004PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003005"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003006Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003007
Barry Warsaw53699e91996-12-10 23:23:01 +00003008static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003009posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003010{
Barry Warsaw53699e91996-12-10 23:23:01 +00003011 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003012}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003013#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003014
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003015
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003016PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003017"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003018Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003019
Barry Warsaw53699e91996-12-10 23:23:01 +00003020static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003021posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003022{
Barry Warsaw53699e91996-12-10 23:23:01 +00003023 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003024}
3025
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003026
Fred Drakec9680921999-12-13 16:37:25 +00003027#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003028PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003029"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003030Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00003031
3032static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003033posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00003034{
3035 PyObject *result = NULL;
3036
Fred Drakec9680921999-12-13 16:37:25 +00003037#ifdef NGROUPS_MAX
3038#define MAX_GROUPS NGROUPS_MAX
3039#else
3040 /* defined to be 16 on Solaris7, so this should be a small number */
3041#define MAX_GROUPS 64
3042#endif
3043 gid_t grouplist[MAX_GROUPS];
3044 int n;
3045
3046 n = getgroups(MAX_GROUPS, grouplist);
3047 if (n < 0)
3048 posix_error();
3049 else {
3050 result = PyList_New(n);
3051 if (result != NULL) {
Fred Drakec9680921999-12-13 16:37:25 +00003052 int i;
3053 for (i = 0; i < n; ++i) {
Neal Norwitze241ce82003-02-17 18:17:05 +00003054 PyObject *o = PyInt_FromLong((long)grouplist[i]);
Fred Drakec9680921999-12-13 16:37:25 +00003055 if (o == NULL) {
3056 Py_DECREF(result);
3057 result = NULL;
3058 break;
3059 }
3060 PyList_SET_ITEM(result, i, o);
3061 }
3062 }
3063 }
Neal Norwitze241ce82003-02-17 18:17:05 +00003064
Fred Drakec9680921999-12-13 16:37:25 +00003065 return result;
3066}
3067#endif
3068
Martin v. Löwis606edc12002-06-13 21:09:11 +00003069#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003070PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003071"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003072Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00003073
3074static PyObject *
3075posix_getpgid(PyObject *self, PyObject *args)
3076{
3077 int pid, pgid;
3078 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
3079 return NULL;
3080 pgid = getpgid(pid);
3081 if (pgid < 0)
3082 return posix_error();
3083 return PyInt_FromLong((long)pgid);
3084}
3085#endif /* HAVE_GETPGID */
3086
3087
Guido van Rossumb6775db1994-08-01 11:34:53 +00003088#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003089PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003090"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003091Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003092
Barry Warsaw53699e91996-12-10 23:23:01 +00003093static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003094posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00003095{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003096#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00003097 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003098#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00003099 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003100#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00003101}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003102#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00003103
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003104
Guido van Rossumb6775db1994-08-01 11:34:53 +00003105#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003106PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003107"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003108Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003109
Barry Warsaw53699e91996-12-10 23:23:01 +00003110static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003111posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003112{
Guido van Rossum64933891994-10-20 21:56:42 +00003113#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00003114 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003115#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003116 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003117#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00003118 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003119 Py_INCREF(Py_None);
3120 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003121}
3122
Guido van Rossumb6775db1994-08-01 11:34:53 +00003123#endif /* HAVE_SETPGRP */
3124
Guido van Rossumad0ee831995-03-01 10:34:45 +00003125#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003126PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003127"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003128Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003129
Barry Warsaw53699e91996-12-10 23:23:01 +00003130static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003131posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003132{
Barry Warsaw53699e91996-12-10 23:23:01 +00003133 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003134}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003135#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003136
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003137
Fred Drake12c6e2d1999-12-14 21:25:03 +00003138#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003139PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003140"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003141Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00003142
3143static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003144posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00003145{
Neal Norwitze241ce82003-02-17 18:17:05 +00003146 PyObject *result = NULL;
Fred Drakea30680b2000-12-06 21:24:28 +00003147 char *name;
3148 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00003149
Fred Drakea30680b2000-12-06 21:24:28 +00003150 errno = 0;
3151 name = getlogin();
3152 if (name == NULL) {
3153 if (errno)
3154 posix_error();
3155 else
3156 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00003157 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00003158 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00003159 else
3160 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00003161 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00003162
Fred Drake12c6e2d1999-12-14 21:25:03 +00003163 return result;
3164}
3165#endif
3166
Guido van Rossumad0ee831995-03-01 10:34:45 +00003167#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003168PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003169"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003170Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003171
Barry Warsaw53699e91996-12-10 23:23:01 +00003172static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003173posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003174{
Barry Warsaw53699e91996-12-10 23:23:01 +00003175 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003176}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003177#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003178
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003179
Guido van Rossumad0ee831995-03-01 10:34:45 +00003180#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003181PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003182"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003183Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003184
Barry Warsaw53699e91996-12-10 23:23:01 +00003185static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003186posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003187{
3188 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003189 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00003190 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003191#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003192 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
3193 APIRET rc;
3194 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003195 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003196
3197 } else if (sig == XCPT_SIGNAL_KILLPROC) {
3198 APIRET rc;
3199 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003200 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003201
3202 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003203 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003204#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00003205 if (kill(pid, sig) == -1)
3206 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003207#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003208 Py_INCREF(Py_None);
3209 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003210}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003211#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003212
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003213#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003214PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003215"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003216Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003217
3218static PyObject *
3219posix_killpg(PyObject *self, PyObject *args)
3220{
3221 int pgid, sig;
3222 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
3223 return NULL;
3224 if (killpg(pgid, sig) == -1)
3225 return posix_error();
3226 Py_INCREF(Py_None);
3227 return Py_None;
3228}
3229#endif
3230
Guido van Rossumc0125471996-06-28 18:55:32 +00003231#ifdef HAVE_PLOCK
3232
3233#ifdef HAVE_SYS_LOCK_H
3234#include <sys/lock.h>
3235#endif
3236
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003237PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003238"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003239Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003240
Barry Warsaw53699e91996-12-10 23:23:01 +00003241static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003242posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00003243{
3244 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003245 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00003246 return NULL;
3247 if (plock(op) == -1)
3248 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003249 Py_INCREF(Py_None);
3250 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00003251}
3252#endif
3253
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003254
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003255#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003256PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003257"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003258Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003259
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003260#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003261#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003262static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003263async_system(const char *command)
3264{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003265 char errormsg[256], args[1024];
3266 RESULTCODES rcodes;
3267 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003268
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003269 char *shell = getenv("COMSPEC");
3270 if (!shell)
3271 shell = "cmd";
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003272
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003273 /* avoid overflowing the argument buffer */
3274 if (strlen(shell) + 3 + strlen(command) >= 1024)
3275 return ERROR_NOT_ENOUGH_MEMORY
3276
3277 args[0] = '\0';
3278 strcat(args, shell);
3279 strcat(args, "/c ");
3280 strcat(args, command);
3281
3282 /* execute asynchronously, inheriting the environment */
3283 rc = DosExecPgm(errormsg,
3284 sizeof(errormsg),
3285 EXEC_ASYNC,
3286 args,
3287 NULL,
3288 &rcodes,
3289 shell);
3290 return rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003291}
3292
Guido van Rossumd48f2521997-12-05 22:19:34 +00003293static FILE *
3294popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003295{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003296 int oldfd, tgtfd;
3297 HFILE pipeh[2];
3298 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003299
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003300 /* mode determines which of stdin or stdout is reconnected to
3301 * the pipe to the child
3302 */
3303 if (strchr(mode, 'r') != NULL) {
3304 tgt_fd = 1; /* stdout */
3305 } else if (strchr(mode, 'w')) {
3306 tgt_fd = 0; /* stdin */
3307 } else {
3308 *err = ERROR_INVALID_ACCESS;
3309 return NULL;
3310 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003311
Andrew MacIntyrea3be2582004-12-18 09:51:05 +00003312 /* setup the pipe */
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003313 if ((rc = DosCreatePipe(&pipeh[0], &pipeh[1], pipesize)) != NO_ERROR) {
3314 *err = rc;
3315 return NULL;
3316 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003317
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003318 /* prevent other threads accessing stdio */
3319 DosEnterCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003320
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003321 /* reconnect stdio and execute child */
3322 oldfd = dup(tgtfd);
3323 close(tgtfd);
3324 if (dup2(pipeh[tgtfd], tgtfd) == 0) {
3325 DosClose(pipeh[tgtfd]);
3326 rc = async_system(command);
3327 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003328
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003329 /* restore stdio */
3330 dup2(oldfd, tgtfd);
3331 close(oldfd);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003332
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003333 /* allow other threads access to stdio */
3334 DosExitCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003335
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003336 /* if execution of child was successful return file stream */
3337 if (rc == NO_ERROR)
3338 return fdopen(pipeh[1 - tgtfd], mode);
3339 else {
3340 DosClose(pipeh[1 - tgtfd]);
3341 *err = rc;
3342 return NULL;
3343 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003344}
3345
3346static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003347posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003348{
3349 char *name;
3350 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00003351 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003352 FILE *fp;
3353 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003354 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003355 return NULL;
3356 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00003357 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003358 Py_END_ALLOW_THREADS
3359 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003360 return os2_error(err);
3361
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003362 f = PyFile_FromFile(fp, name, mode, fclose);
3363 if (f != NULL)
3364 PyFile_SetBufSize(f, bufsize);
3365 return f;
3366}
3367
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003368#elif defined(PYCC_GCC)
3369
3370/* standard posix version of popen() support */
3371static PyObject *
3372posix_popen(PyObject *self, PyObject *args)
3373{
3374 char *name;
3375 char *mode = "r";
3376 int bufsize = -1;
3377 FILE *fp;
3378 PyObject *f;
3379 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
3380 return NULL;
3381 Py_BEGIN_ALLOW_THREADS
3382 fp = popen(name, mode);
3383 Py_END_ALLOW_THREADS
3384 if (fp == NULL)
3385 return posix_error();
3386 f = PyFile_FromFile(fp, name, mode, pclose);
3387 if (f != NULL)
3388 PyFile_SetBufSize(f, bufsize);
3389 return f;
3390}
3391
3392/* fork() under OS/2 has lots'o'warts
3393 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
3394 * most of this code is a ripoff of the win32 code, but using the
3395 * capabilities of EMX's C library routines
3396 */
3397
3398/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
3399#define POPEN_1 1
3400#define POPEN_2 2
3401#define POPEN_3 3
3402#define POPEN_4 4
3403
3404static PyObject *_PyPopen(char *, int, int, int);
3405static int _PyPclose(FILE *file);
3406
3407/*
3408 * Internal dictionary mapping popen* file pointers to process handles,
3409 * for use when retrieving the process exit code. See _PyPclose() below
3410 * for more information on this dictionary's use.
3411 */
3412static PyObject *_PyPopenProcs = NULL;
3413
3414/* os2emx version of popen2()
3415 *
3416 * The result of this function is a pipe (file) connected to the
3417 * process's stdin, and a pipe connected to the process's stdout.
3418 */
3419
3420static PyObject *
3421os2emx_popen2(PyObject *self, PyObject *args)
3422{
3423 PyObject *f;
3424 int tm=0;
3425
3426 char *cmdstring;
3427 char *mode = "t";
3428 int bufsize = -1;
3429 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
3430 return NULL;
3431
3432 if (*mode == 't')
3433 tm = O_TEXT;
3434 else if (*mode != 'b') {
3435 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3436 return NULL;
3437 } else
3438 tm = O_BINARY;
3439
3440 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
3441
3442 return f;
3443}
3444
3445/*
3446 * Variation on os2emx.popen2
3447 *
3448 * The result of this function is 3 pipes - the process's stdin,
3449 * stdout and stderr
3450 */
3451
3452static PyObject *
3453os2emx_popen3(PyObject *self, PyObject *args)
3454{
3455 PyObject *f;
3456 int tm = 0;
3457
3458 char *cmdstring;
3459 char *mode = "t";
3460 int bufsize = -1;
3461 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
3462 return NULL;
3463
3464 if (*mode == 't')
3465 tm = O_TEXT;
3466 else if (*mode != 'b') {
3467 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3468 return NULL;
3469 } else
3470 tm = O_BINARY;
3471
3472 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
3473
3474 return f;
3475}
3476
3477/*
3478 * Variation on os2emx.popen2
3479 *
Tim Peters11b23062003-04-23 02:39:17 +00003480 * The result of this function is 2 pipes - the processes stdin,
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003481 * and stdout+stderr combined as a single pipe.
3482 */
3483
3484static PyObject *
3485os2emx_popen4(PyObject *self, PyObject *args)
3486{
3487 PyObject *f;
3488 int tm = 0;
3489
3490 char *cmdstring;
3491 char *mode = "t";
3492 int bufsize = -1;
3493 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
3494 return NULL;
3495
3496 if (*mode == 't')
3497 tm = O_TEXT;
3498 else if (*mode != 'b') {
3499 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3500 return NULL;
3501 } else
3502 tm = O_BINARY;
3503
3504 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
3505
3506 return f;
3507}
3508
3509/* a couple of structures for convenient handling of multiple
3510 * file handles and pipes
3511 */
3512struct file_ref
3513{
3514 int handle;
3515 int flags;
3516};
3517
3518struct pipe_ref
3519{
3520 int rd;
3521 int wr;
3522};
3523
3524/* The following code is derived from the win32 code */
3525
3526static PyObject *
3527_PyPopen(char *cmdstring, int mode, int n, int bufsize)
3528{
3529 struct file_ref stdio[3];
3530 struct pipe_ref p_fd[3];
3531 FILE *p_s[3];
3532 int file_count, i, pipe_err, pipe_pid;
3533 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
3534 PyObject *f, *p_f[3];
3535
3536 /* file modes for subsequent fdopen's on pipe handles */
3537 if (mode == O_TEXT)
3538 {
3539 rd_mode = "rt";
3540 wr_mode = "wt";
3541 }
3542 else
3543 {
3544 rd_mode = "rb";
3545 wr_mode = "wb";
3546 }
3547
3548 /* prepare shell references */
3549 if ((shell = getenv("EMXSHELL")) == NULL)
3550 if ((shell = getenv("COMSPEC")) == NULL)
3551 {
3552 errno = ENOENT;
3553 return posix_error();
3554 }
3555
3556 sh_name = _getname(shell);
3557 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
3558 opt = "/c";
3559 else
3560 opt = "-c";
3561
3562 /* save current stdio fds + their flags, and set not inheritable */
3563 i = pipe_err = 0;
3564 while (pipe_err >= 0 && i < 3)
3565 {
3566 pipe_err = stdio[i].handle = dup(i);
3567 stdio[i].flags = fcntl(i, F_GETFD, 0);
3568 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
3569 i++;
3570 }
3571 if (pipe_err < 0)
3572 {
3573 /* didn't get them all saved - clean up and bail out */
3574 int saved_err = errno;
3575 while (i-- > 0)
3576 {
3577 close(stdio[i].handle);
3578 }
3579 errno = saved_err;
3580 return posix_error();
3581 }
3582
3583 /* create pipe ends */
3584 file_count = 2;
3585 if (n == POPEN_3)
3586 file_count = 3;
3587 i = pipe_err = 0;
3588 while ((pipe_err == 0) && (i < file_count))
3589 pipe_err = pipe((int *)&p_fd[i++]);
3590 if (pipe_err < 0)
3591 {
3592 /* didn't get them all made - clean up and bail out */
3593 while (i-- > 0)
3594 {
3595 close(p_fd[i].wr);
3596 close(p_fd[i].rd);
3597 }
3598 errno = EPIPE;
3599 return posix_error();
3600 }
3601
3602 /* change the actual standard IO streams over temporarily,
3603 * making the retained pipe ends non-inheritable
3604 */
3605 pipe_err = 0;
3606
3607 /* - stdin */
3608 if (dup2(p_fd[0].rd, 0) == 0)
3609 {
3610 close(p_fd[0].rd);
3611 i = fcntl(p_fd[0].wr, F_GETFD, 0);
3612 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
3613 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
3614 {
3615 close(p_fd[0].wr);
3616 pipe_err = -1;
3617 }
3618 }
3619 else
3620 {
3621 pipe_err = -1;
3622 }
3623
3624 /* - stdout */
3625 if (pipe_err == 0)
3626 {
3627 if (dup2(p_fd[1].wr, 1) == 1)
3628 {
3629 close(p_fd[1].wr);
3630 i = fcntl(p_fd[1].rd, F_GETFD, 0);
3631 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
3632 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
3633 {
3634 close(p_fd[1].rd);
3635 pipe_err = -1;
3636 }
3637 }
3638 else
3639 {
3640 pipe_err = -1;
3641 }
3642 }
3643
3644 /* - stderr, as required */
3645 if (pipe_err == 0)
3646 switch (n)
3647 {
3648 case POPEN_3:
3649 {
3650 if (dup2(p_fd[2].wr, 2) == 2)
3651 {
3652 close(p_fd[2].wr);
3653 i = fcntl(p_fd[2].rd, F_GETFD, 0);
3654 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
3655 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
3656 {
3657 close(p_fd[2].rd);
3658 pipe_err = -1;
3659 }
3660 }
3661 else
3662 {
3663 pipe_err = -1;
3664 }
3665 break;
3666 }
3667
3668 case POPEN_4:
3669 {
3670 if (dup2(1, 2) != 2)
3671 {
3672 pipe_err = -1;
3673 }
3674 break;
3675 }
3676 }
3677
3678 /* spawn the child process */
3679 if (pipe_err == 0)
3680 {
3681 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
3682 if (pipe_pid == -1)
3683 {
3684 pipe_err = -1;
3685 }
3686 else
3687 {
3688 /* save the PID into the FILE structure
3689 * NOTE: this implementation doesn't actually
3690 * take advantage of this, but do it for
3691 * completeness - AIM Apr01
3692 */
3693 for (i = 0; i < file_count; i++)
3694 p_s[i]->_pid = pipe_pid;
3695 }
3696 }
3697
3698 /* reset standard IO to normal */
3699 for (i = 0; i < 3; i++)
3700 {
3701 dup2(stdio[i].handle, i);
3702 fcntl(i, F_SETFD, stdio[i].flags);
3703 close(stdio[i].handle);
3704 }
3705
3706 /* if any remnant problems, clean up and bail out */
3707 if (pipe_err < 0)
3708 {
3709 for (i = 0; i < 3; i++)
3710 {
3711 close(p_fd[i].rd);
3712 close(p_fd[i].wr);
3713 }
3714 errno = EPIPE;
3715 return posix_error_with_filename(cmdstring);
3716 }
3717
3718 /* build tuple of file objects to return */
3719 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
3720 PyFile_SetBufSize(p_f[0], bufsize);
3721 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
3722 PyFile_SetBufSize(p_f[1], bufsize);
3723 if (n == POPEN_3)
3724 {
3725 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
3726 PyFile_SetBufSize(p_f[0], bufsize);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00003727 f = PyTuple_Pack(3, p_f[0], p_f[1], p_f[2]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003728 }
3729 else
Raymond Hettinger8ae46892003-10-12 19:09:37 +00003730 f = PyTuple_Pack(2, p_f[0], p_f[1]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003731
3732 /*
3733 * Insert the files we've created into the process dictionary
3734 * all referencing the list with the process handle and the
3735 * initial number of files (see description below in _PyPclose).
3736 * Since if _PyPclose later tried to wait on a process when all
3737 * handles weren't closed, it could create a deadlock with the
3738 * child, we spend some energy here to try to ensure that we
3739 * either insert all file handles into the dictionary or none
3740 * at all. It's a little clumsy with the various popen modes
3741 * and variable number of files involved.
3742 */
3743 if (!_PyPopenProcs)
3744 {
3745 _PyPopenProcs = PyDict_New();
3746 }
3747
3748 if (_PyPopenProcs)
3749 {
3750 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
3751 int ins_rc[3];
3752
3753 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
3754 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
3755
3756 procObj = PyList_New(2);
3757 pidObj = PyInt_FromLong((long) pipe_pid);
3758 intObj = PyInt_FromLong((long) file_count);
3759
3760 if (procObj && pidObj && intObj)
3761 {
3762 PyList_SetItem(procObj, 0, pidObj);
3763 PyList_SetItem(procObj, 1, intObj);
3764
3765 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
3766 if (fileObj[0])
3767 {
3768 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
3769 fileObj[0],
3770 procObj);
3771 }
3772 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
3773 if (fileObj[1])
3774 {
3775 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
3776 fileObj[1],
3777 procObj);
3778 }
3779 if (file_count >= 3)
3780 {
3781 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
3782 if (fileObj[2])
3783 {
3784 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
3785 fileObj[2],
3786 procObj);
3787 }
3788 }
3789
3790 if (ins_rc[0] < 0 || !fileObj[0] ||
3791 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
3792 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
3793 {
3794 /* Something failed - remove any dictionary
3795 * entries that did make it.
3796 */
3797 if (!ins_rc[0] && fileObj[0])
3798 {
3799 PyDict_DelItem(_PyPopenProcs,
3800 fileObj[0]);
3801 }
3802 if (!ins_rc[1] && fileObj[1])
3803 {
3804 PyDict_DelItem(_PyPopenProcs,
3805 fileObj[1]);
3806 }
3807 if (!ins_rc[2] && fileObj[2])
3808 {
3809 PyDict_DelItem(_PyPopenProcs,
3810 fileObj[2]);
3811 }
3812 }
3813 }
Tim Peters11b23062003-04-23 02:39:17 +00003814
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003815 /*
3816 * Clean up our localized references for the dictionary keys
3817 * and value since PyDict_SetItem will Py_INCREF any copies
3818 * that got placed in the dictionary.
3819 */
3820 Py_XDECREF(procObj);
3821 Py_XDECREF(fileObj[0]);
3822 Py_XDECREF(fileObj[1]);
3823 Py_XDECREF(fileObj[2]);
3824 }
3825
3826 /* Child is launched. */
3827 return f;
3828}
3829
3830/*
3831 * Wrapper for fclose() to use for popen* files, so we can retrieve the
3832 * exit code for the child process and return as a result of the close.
3833 *
3834 * This function uses the _PyPopenProcs dictionary in order to map the
3835 * input file pointer to information about the process that was
3836 * originally created by the popen* call that created the file pointer.
3837 * The dictionary uses the file pointer as a key (with one entry
3838 * inserted for each file returned by the original popen* call) and a
3839 * single list object as the value for all files from a single call.
3840 * The list object contains the Win32 process handle at [0], and a file
3841 * count at [1], which is initialized to the total number of file
3842 * handles using that list.
3843 *
3844 * This function closes whichever handle it is passed, and decrements
3845 * the file count in the dictionary for the process handle pointed to
3846 * by this file. On the last close (when the file count reaches zero),
3847 * this function will wait for the child process and then return its
3848 * exit code as the result of the close() operation. This permits the
3849 * files to be closed in any order - it is always the close() of the
3850 * final handle that will return the exit code.
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00003851 *
3852 * NOTE: This function is currently called with the GIL released.
3853 * hence we use the GILState API to manage our state.
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003854 */
3855
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003856static int _PyPclose(FILE *file)
3857{
3858 int result;
3859 int exit_code;
3860 int pipe_pid;
3861 PyObject *procObj, *pidObj, *intObj, *fileObj;
3862 int file_count;
3863#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00003864 PyGILState_STATE state;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003865#endif
3866
3867 /* Close the file handle first, to ensure it can't block the
3868 * child from exiting if it's the last handle.
3869 */
3870 result = fclose(file);
3871
3872#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00003873 state = PyGILState_Ensure();
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003874#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003875 if (_PyPopenProcs)
3876 {
3877 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
3878 (procObj = PyDict_GetItem(_PyPopenProcs,
3879 fileObj)) != NULL &&
3880 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
3881 (intObj = PyList_GetItem(procObj,1)) != NULL)
3882 {
3883 pipe_pid = (int) PyInt_AsLong(pidObj);
3884 file_count = (int) PyInt_AsLong(intObj);
3885
3886 if (file_count > 1)
3887 {
3888 /* Still other files referencing process */
3889 file_count--;
3890 PyList_SetItem(procObj,1,
3891 PyInt_FromLong((long) file_count));
3892 }
3893 else
3894 {
3895 /* Last file for this process */
3896 if (result != EOF &&
3897 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
3898 {
3899 /* extract exit status */
3900 if (WIFEXITED(exit_code))
3901 {
3902 result = WEXITSTATUS(exit_code);
3903 }
3904 else
3905 {
3906 errno = EPIPE;
3907 result = -1;
3908 }
3909 }
3910 else
3911 {
3912 /* Indicate failure - this will cause the file object
3913 * to raise an I/O error and translate the last
3914 * error code from errno. We do have a problem with
3915 * last errors that overlap the normal errno table,
3916 * but that's a consistent problem with the file object.
3917 */
3918 result = -1;
3919 }
3920 }
3921
3922 /* Remove this file pointer from dictionary */
3923 PyDict_DelItem(_PyPopenProcs, fileObj);
3924
3925 if (PyDict_Size(_PyPopenProcs) == 0)
3926 {
3927 Py_DECREF(_PyPopenProcs);
3928 _PyPopenProcs = NULL;
3929 }
3930
3931 } /* if object retrieval ok */
3932
3933 Py_XDECREF(fileObj);
3934 } /* if _PyPopenProcs */
3935
3936#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00003937 PyGILState_Release(state);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003938#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003939 return result;
3940}
3941
3942#endif /* PYCC_??? */
3943
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003944#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003945
3946/*
3947 * Portable 'popen' replacement for Win32.
3948 *
3949 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
3950 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00003951 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003952 */
3953
3954#include <malloc.h>
3955#include <io.h>
3956#include <fcntl.h>
3957
3958/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
3959#define POPEN_1 1
3960#define POPEN_2 2
3961#define POPEN_3 3
3962#define POPEN_4 4
3963
3964static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003965static int _PyPclose(FILE *file);
3966
3967/*
3968 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00003969 * for use when retrieving the process exit code. See _PyPclose() below
3970 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003971 */
3972static PyObject *_PyPopenProcs = NULL;
3973
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003974
3975/* popen that works from a GUI.
3976 *
3977 * The result of this function is a pipe (file) connected to the
3978 * processes stdin or stdout, depending on the requested mode.
3979 */
3980
3981static PyObject *
3982posix_popen(PyObject *self, PyObject *args)
3983{
Raymond Hettingerb5cb6652003-09-01 22:25:41 +00003984 PyObject *f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003985 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003986
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003987 char *cmdstring;
3988 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003989 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003990 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003991 return NULL;
3992
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003993 if (*mode == 'r')
3994 tm = _O_RDONLY;
3995 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00003996 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003997 return NULL;
3998 } else
3999 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00004000
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004001 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004002 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004003 return NULL;
4004 }
4005
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004006 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004007 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004008 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004009 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004010 else
4011 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
4012
4013 return f;
4014}
4015
4016/* Variation on win32pipe.popen
4017 *
4018 * The result of this function is a pipe (file) connected to the
4019 * process's stdin, and a pipe connected to the process's stdout.
4020 */
4021
4022static PyObject *
4023win32_popen2(PyObject *self, PyObject *args)
4024{
4025 PyObject *f;
4026 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00004027
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004028 char *cmdstring;
4029 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004030 int bufsize = -1;
4031 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004032 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004033
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004034 if (*mode == 't')
4035 tm = _O_TEXT;
4036 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004037 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004038 return NULL;
4039 } else
4040 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004041
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004042 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004043 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004044 return NULL;
4045 }
4046
4047 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00004048
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004049 return f;
4050}
4051
4052/*
4053 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004054 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004055 * The result of this function is 3 pipes - the process's stdin,
4056 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004057 */
4058
4059static PyObject *
4060win32_popen3(PyObject *self, PyObject *args)
4061{
4062 PyObject *f;
4063 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004064
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004065 char *cmdstring;
4066 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004067 int bufsize = -1;
4068 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004069 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004070
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004071 if (*mode == 't')
4072 tm = _O_TEXT;
4073 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004074 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004075 return NULL;
4076 } else
4077 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004078
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004079 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004080 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004081 return NULL;
4082 }
4083
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004084 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00004085
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004086 return f;
4087}
4088
4089/*
4090 * Variation on win32pipe.popen
4091 *
Tim Peters5aa91602002-01-30 05:46:57 +00004092 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004093 * and stdout+stderr combined as a single pipe.
4094 */
4095
4096static PyObject *
4097win32_popen4(PyObject *self, PyObject *args)
4098{
4099 PyObject *f;
4100 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004101
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004102 char *cmdstring;
4103 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004104 int bufsize = -1;
4105 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004106 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004107
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004108 if (*mode == 't')
4109 tm = _O_TEXT;
4110 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004111 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004112 return NULL;
4113 } else
4114 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004115
4116 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004117 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004118 return NULL;
4119 }
4120
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004121 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004122
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004123 return f;
4124}
4125
Mark Hammond08501372001-01-31 07:30:29 +00004126static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00004127_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004128 HANDLE hStdin,
4129 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00004130 HANDLE hStderr,
4131 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004132{
4133 PROCESS_INFORMATION piProcInfo;
4134 STARTUPINFO siStartInfo;
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004135 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004136 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00004137 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004138 int i;
4139 int x;
4140
4141 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00004142 char *comshell;
4143
Tim Peters92e4dd82002-10-05 01:47:34 +00004144 s1 = (char *)alloca(i);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004145 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
4146 return x;
Tim Peters402d5982001-08-27 06:37:48 +00004147
4148 /* Explicitly check if we are using COMMAND.COM. If we are
4149 * then use the w9xpopen hack.
4150 */
4151 comshell = s1 + x;
4152 while (comshell >= s1 && *comshell != '\\')
4153 --comshell;
4154 ++comshell;
4155
4156 if (GetVersion() < 0x80000000 &&
4157 _stricmp(comshell, "command.com") != 0) {
4158 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004159 x = i + strlen(s3) + strlen(cmdstring) + 1;
Tim Peters92e4dd82002-10-05 01:47:34 +00004160 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004161 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00004162 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004163 }
4164 else {
4165 /*
Tim Peters402d5982001-08-27 06:37:48 +00004166 * Oh gag, we're on Win9x or using COMMAND.COM. Use
4167 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004168 */
Mark Hammond08501372001-01-31 07:30:29 +00004169 char modulepath[_MAX_PATH];
4170 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004171 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
4172 for (i = x = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004173 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004174 x = i+1;
4175 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00004176 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00004177 strncat(modulepath,
4178 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00004179 (sizeof(modulepath)/sizeof(modulepath[0]))
4180 -strlen(modulepath));
4181 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00004182 /* Eeek - file-not-found - possibly an embedding
4183 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00004184 */
Tim Peters5aa91602002-01-30 05:46:57 +00004185 strncpy(modulepath,
4186 Py_GetExecPrefix(),
Mark Hammond08501372001-01-31 07:30:29 +00004187 sizeof(modulepath)/sizeof(modulepath[0]));
4188 if (modulepath[strlen(modulepath)-1] != '\\')
4189 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00004190 strncat(modulepath,
4191 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00004192 (sizeof(modulepath)/sizeof(modulepath[0]))
4193 -strlen(modulepath));
4194 /* No where else to look - raise an easily identifiable
4195 error, rather than leaving Windows to report
4196 "file not found" - as the user is probably blissfully
4197 unaware this shim EXE is used, and it will confuse them.
4198 (well, it confused me for a while ;-)
4199 */
4200 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00004201 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00004202 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00004203 "for popen to work with your shell "
4204 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00004205 szConsoleSpawn);
4206 return FALSE;
4207 }
4208 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004209 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00004210 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004211 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00004212
Tim Peters92e4dd82002-10-05 01:47:34 +00004213 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004214 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004215 /* To maintain correct argument passing semantics,
4216 we pass the command-line as it stands, and allow
4217 quoting to be applied. w9xpopen.exe will then
4218 use its argv vector, and re-quote the necessary
4219 args for the ultimate child process.
4220 */
Tim Peters75cdad52001-11-28 22:07:30 +00004221 PyOS_snprintf(
4222 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004223 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004224 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004225 s1,
4226 s3,
4227 cmdstring);
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004228 /* Not passing CREATE_NEW_CONSOLE has been known to
Tim Peters11b23062003-04-23 02:39:17 +00004229 cause random failures on win9x. Specifically a
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004230 dialog:
4231 "Your program accessed mem currently in use at xxx"
4232 and a hopeful warning about the stability of your
4233 system.
4234 Cost is Ctrl+C wont kill children, but anyone
4235 who cares can have a go!
4236 */
4237 dwProcessFlags |= CREATE_NEW_CONSOLE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004238 }
4239 }
4240
4241 /* Could be an else here to try cmd.exe / command.com in the path
4242 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00004243 else {
Tim Peters402d5982001-08-27 06:37:48 +00004244 PyErr_SetString(PyExc_RuntimeError,
4245 "Cannot locate a COMSPEC environment variable to "
4246 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00004247 return FALSE;
4248 }
Tim Peters5aa91602002-01-30 05:46:57 +00004249
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004250 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
4251 siStartInfo.cb = sizeof(STARTUPINFO);
4252 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
4253 siStartInfo.hStdInput = hStdin;
4254 siStartInfo.hStdOutput = hStdout;
4255 siStartInfo.hStdError = hStderr;
4256 siStartInfo.wShowWindow = SW_HIDE;
4257
4258 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004259 s2,
4260 NULL,
4261 NULL,
4262 TRUE,
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004263 dwProcessFlags,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004264 NULL,
4265 NULL,
4266 &siStartInfo,
4267 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004268 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004269 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004270
Mark Hammondb37a3732000-08-14 04:47:33 +00004271 /* Return process handle */
4272 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004273 return TRUE;
4274 }
Tim Peters402d5982001-08-27 06:37:48 +00004275 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004276 return FALSE;
4277}
4278
4279/* The following code is based off of KB: Q190351 */
4280
4281static PyObject *
4282_PyPopen(char *cmdstring, int mode, int n)
4283{
4284 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
4285 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00004286 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00004287
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004288 SECURITY_ATTRIBUTES saAttr;
4289 BOOL fSuccess;
4290 int fd1, fd2, fd3;
4291 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00004292 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004293 PyObject *f;
4294
4295 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
4296 saAttr.bInheritHandle = TRUE;
4297 saAttr.lpSecurityDescriptor = NULL;
4298
4299 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
4300 return win32_error("CreatePipe", NULL);
4301
4302 /* Create new output read handle and the input write handle. Set
4303 * the inheritance properties to FALSE. Otherwise, the child inherits
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00004304 * these handles; resulting in non-closeable handles to the pipes
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004305 * being created. */
4306 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004307 GetCurrentProcess(), &hChildStdinWrDup, 0,
4308 FALSE,
4309 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004310 if (!fSuccess)
4311 return win32_error("DuplicateHandle", NULL);
4312
4313 /* Close the inheritable version of ChildStdin
4314 that we're using. */
4315 CloseHandle(hChildStdinWr);
4316
4317 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
4318 return win32_error("CreatePipe", NULL);
4319
4320 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004321 GetCurrentProcess(), &hChildStdoutRdDup, 0,
4322 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004323 if (!fSuccess)
4324 return win32_error("DuplicateHandle", NULL);
4325
4326 /* Close the inheritable version of ChildStdout
4327 that we're using. */
4328 CloseHandle(hChildStdoutRd);
4329
4330 if (n != POPEN_4) {
4331 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
4332 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004333 fSuccess = DuplicateHandle(GetCurrentProcess(),
4334 hChildStderrRd,
4335 GetCurrentProcess(),
4336 &hChildStderrRdDup, 0,
4337 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004338 if (!fSuccess)
4339 return win32_error("DuplicateHandle", NULL);
4340 /* Close the inheritable version of ChildStdErr that we're using. */
4341 CloseHandle(hChildStderrRd);
4342 }
Tim Peters5aa91602002-01-30 05:46:57 +00004343
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004344 switch (n) {
4345 case POPEN_1:
4346 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
4347 case _O_WRONLY | _O_TEXT:
4348 /* Case for writing to child Stdin in text mode. */
4349 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4350 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004351 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004352 PyFile_SetBufSize(f, 0);
4353 /* We don't care about these pipes anymore, so close them. */
4354 CloseHandle(hChildStdoutRdDup);
4355 CloseHandle(hChildStderrRdDup);
4356 break;
4357
4358 case _O_RDONLY | _O_TEXT:
4359 /* Case for reading from child Stdout in text mode. */
4360 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4361 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004362 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004363 PyFile_SetBufSize(f, 0);
4364 /* We don't care about these pipes anymore, so close them. */
4365 CloseHandle(hChildStdinWrDup);
4366 CloseHandle(hChildStderrRdDup);
4367 break;
4368
4369 case _O_RDONLY | _O_BINARY:
4370 /* Case for readinig from child Stdout in binary mode. */
4371 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4372 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004373 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004374 PyFile_SetBufSize(f, 0);
4375 /* We don't care about these pipes anymore, so close them. */
4376 CloseHandle(hChildStdinWrDup);
4377 CloseHandle(hChildStderrRdDup);
4378 break;
4379
4380 case _O_WRONLY | _O_BINARY:
4381 /* Case for writing to child Stdin in binary mode. */
4382 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4383 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004384 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004385 PyFile_SetBufSize(f, 0);
4386 /* We don't care about these pipes anymore, so close them. */
4387 CloseHandle(hChildStdoutRdDup);
4388 CloseHandle(hChildStderrRdDup);
4389 break;
4390 }
Mark Hammondb37a3732000-08-14 04:47:33 +00004391 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004392 break;
Tim Peters5aa91602002-01-30 05:46:57 +00004393
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004394 case POPEN_2:
4395 case POPEN_4:
4396 {
4397 char *m1, *m2;
4398 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00004399
Tim Peters7dca21e2002-08-19 00:42:29 +00004400 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004401 m1 = "r";
4402 m2 = "w";
4403 } else {
4404 m1 = "rb";
4405 m2 = "wb";
4406 }
4407
4408 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4409 f1 = _fdopen(fd1, m2);
4410 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4411 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004412 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004413 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00004414 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004415 PyFile_SetBufSize(p2, 0);
4416
4417 if (n != 4)
4418 CloseHandle(hChildStderrRdDup);
4419
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004420 f = PyTuple_Pack(2,p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00004421 Py_XDECREF(p1);
4422 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00004423 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004424 break;
4425 }
Tim Peters5aa91602002-01-30 05:46:57 +00004426
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004427 case POPEN_3:
4428 {
4429 char *m1, *m2;
4430 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00004431
Tim Peters7dca21e2002-08-19 00:42:29 +00004432 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004433 m1 = "r";
4434 m2 = "w";
4435 } else {
4436 m1 = "rb";
4437 m2 = "wb";
4438 }
4439
4440 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4441 f1 = _fdopen(fd1, m2);
4442 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4443 f2 = _fdopen(fd2, m1);
4444 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
4445 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004446 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00004447 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
4448 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004449 PyFile_SetBufSize(p1, 0);
4450 PyFile_SetBufSize(p2, 0);
4451 PyFile_SetBufSize(p3, 0);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004452 f = PyTuple_Pack(3,p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00004453 Py_XDECREF(p1);
4454 Py_XDECREF(p2);
4455 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00004456 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004457 break;
4458 }
4459 }
4460
4461 if (n == POPEN_4) {
4462 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004463 hChildStdinRd,
4464 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004465 hChildStdoutWr,
4466 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004467 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004468 }
4469 else {
4470 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004471 hChildStdinRd,
4472 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004473 hChildStderrWr,
4474 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004475 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004476 }
4477
Mark Hammondb37a3732000-08-14 04:47:33 +00004478 /*
4479 * Insert the files we've created into the process dictionary
4480 * all referencing the list with the process handle and the
4481 * initial number of files (see description below in _PyPclose).
4482 * Since if _PyPclose later tried to wait on a process when all
4483 * handles weren't closed, it could create a deadlock with the
4484 * child, we spend some energy here to try to ensure that we
4485 * either insert all file handles into the dictionary or none
4486 * at all. It's a little clumsy with the various popen modes
4487 * and variable number of files involved.
4488 */
4489 if (!_PyPopenProcs) {
4490 _PyPopenProcs = PyDict_New();
4491 }
4492
4493 if (_PyPopenProcs) {
4494 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
4495 int ins_rc[3];
4496
4497 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4498 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4499
4500 procObj = PyList_New(2);
4501 hProcessObj = PyLong_FromVoidPtr(hProcess);
4502 intObj = PyInt_FromLong(file_count);
4503
4504 if (procObj && hProcessObj && intObj) {
4505 PyList_SetItem(procObj,0,hProcessObj);
4506 PyList_SetItem(procObj,1,intObj);
4507
4508 fileObj[0] = PyLong_FromVoidPtr(f1);
4509 if (fileObj[0]) {
4510 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4511 fileObj[0],
4512 procObj);
4513 }
4514 if (file_count >= 2) {
4515 fileObj[1] = PyLong_FromVoidPtr(f2);
4516 if (fileObj[1]) {
4517 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4518 fileObj[1],
4519 procObj);
4520 }
4521 }
4522 if (file_count >= 3) {
4523 fileObj[2] = PyLong_FromVoidPtr(f3);
4524 if (fileObj[2]) {
4525 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4526 fileObj[2],
4527 procObj);
4528 }
4529 }
4530
4531 if (ins_rc[0] < 0 || !fileObj[0] ||
4532 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4533 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
4534 /* Something failed - remove any dictionary
4535 * entries that did make it.
4536 */
4537 if (!ins_rc[0] && fileObj[0]) {
4538 PyDict_DelItem(_PyPopenProcs,
4539 fileObj[0]);
4540 }
4541 if (!ins_rc[1] && fileObj[1]) {
4542 PyDict_DelItem(_PyPopenProcs,
4543 fileObj[1]);
4544 }
4545 if (!ins_rc[2] && fileObj[2]) {
4546 PyDict_DelItem(_PyPopenProcs,
4547 fileObj[2]);
4548 }
4549 }
4550 }
Tim Peters5aa91602002-01-30 05:46:57 +00004551
Mark Hammondb37a3732000-08-14 04:47:33 +00004552 /*
4553 * Clean up our localized references for the dictionary keys
4554 * and value since PyDict_SetItem will Py_INCREF any copies
4555 * that got placed in the dictionary.
4556 */
4557 Py_XDECREF(procObj);
4558 Py_XDECREF(fileObj[0]);
4559 Py_XDECREF(fileObj[1]);
4560 Py_XDECREF(fileObj[2]);
4561 }
4562
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004563 /* Child is launched. Close the parents copy of those pipe
4564 * handles that only the child should have open. You need to
4565 * make sure that no handles to the write end of the output pipe
4566 * are maintained in this process or else the pipe will not close
4567 * when the child process exits and the ReadFile will hang. */
4568
4569 if (!CloseHandle(hChildStdinRd))
4570 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004571
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004572 if (!CloseHandle(hChildStdoutWr))
4573 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004574
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004575 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
4576 return win32_error("CloseHandle", NULL);
4577
4578 return f;
4579}
Fredrik Lundh56055a42000-07-23 19:47:12 +00004580
4581/*
4582 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4583 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00004584 *
4585 * This function uses the _PyPopenProcs dictionary in order to map the
4586 * input file pointer to information about the process that was
4587 * originally created by the popen* call that created the file pointer.
4588 * The dictionary uses the file pointer as a key (with one entry
4589 * inserted for each file returned by the original popen* call) and a
4590 * single list object as the value for all files from a single call.
4591 * The list object contains the Win32 process handle at [0], and a file
4592 * count at [1], which is initialized to the total number of file
4593 * handles using that list.
4594 *
4595 * This function closes whichever handle it is passed, and decrements
4596 * the file count in the dictionary for the process handle pointed to
4597 * by this file. On the last close (when the file count reaches zero),
4598 * this function will wait for the child process and then return its
4599 * exit code as the result of the close() operation. This permits the
4600 * files to be closed in any order - it is always the close() of the
4601 * final handle that will return the exit code.
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004602 *
4603 * NOTE: This function is currently called with the GIL released.
4604 * hence we use the GILState API to manage our state.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004605 */
Tim Peters736aa322000-09-01 06:51:24 +00004606
Fredrik Lundh56055a42000-07-23 19:47:12 +00004607static int _PyPclose(FILE *file)
4608{
Fredrik Lundh20318932000-07-26 17:29:12 +00004609 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004610 DWORD exit_code;
4611 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00004612 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
4613 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00004614#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004615 PyGILState_STATE state;
Tim Peters736aa322000-09-01 06:51:24 +00004616#endif
4617
Fredrik Lundh20318932000-07-26 17:29:12 +00004618 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00004619 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00004620 */
4621 result = fclose(file);
Tim Peters736aa322000-09-01 06:51:24 +00004622#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004623 state = PyGILState_Ensure();
Tim Peters736aa322000-09-01 06:51:24 +00004624#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00004625 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00004626 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4627 (procObj = PyDict_GetItem(_PyPopenProcs,
4628 fileObj)) != NULL &&
4629 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
4630 (intObj = PyList_GetItem(procObj,1)) != NULL) {
4631
4632 hProcess = PyLong_AsVoidPtr(hProcessObj);
4633 file_count = PyInt_AsLong(intObj);
4634
4635 if (file_count > 1) {
4636 /* Still other files referencing process */
4637 file_count--;
4638 PyList_SetItem(procObj,1,
4639 PyInt_FromLong(file_count));
4640 } else {
4641 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00004642 if (result != EOF &&
4643 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
4644 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00004645 /* Possible truncation here in 16-bit environments, but
4646 * real exit codes are just the lower byte in any event.
4647 */
4648 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004649 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00004650 /* Indicate failure - this will cause the file object
4651 * to raise an I/O error and translate the last Win32
4652 * error code from errno. We do have a problem with
4653 * last errors that overlap the normal errno table,
4654 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004655 */
Fredrik Lundh20318932000-07-26 17:29:12 +00004656 if (result != EOF) {
4657 /* If the error wasn't from the fclose(), then
4658 * set errno for the file object error handling.
4659 */
4660 errno = GetLastError();
4661 }
4662 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004663 }
4664
4665 /* Free up the native handle at this point */
4666 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00004667 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00004668
Mark Hammondb37a3732000-08-14 04:47:33 +00004669 /* Remove this file pointer from dictionary */
4670 PyDict_DelItem(_PyPopenProcs, fileObj);
4671
4672 if (PyDict_Size(_PyPopenProcs) == 0) {
4673 Py_DECREF(_PyPopenProcs);
4674 _PyPopenProcs = NULL;
4675 }
4676
4677 } /* if object retrieval ok */
4678
4679 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004680 } /* if _PyPopenProcs */
4681
Tim Peters736aa322000-09-01 06:51:24 +00004682#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004683 PyGILState_Release(state);
Tim Peters736aa322000-09-01 06:51:24 +00004684#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00004685 return result;
4686}
Tim Peters9acdd3a2000-09-01 19:26:36 +00004687
4688#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00004689static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004690posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00004691{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004692 char *name;
4693 char *mode = "r";
4694 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00004695 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00004696 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004697 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00004698 return NULL;
Martin v. Löwis9ad853b2003-10-31 10:01:53 +00004699 /* Strip mode of binary or text modifiers */
4700 if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
4701 mode = "r";
4702 else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
4703 mode = "w";
Barry Warsaw53699e91996-12-10 23:23:01 +00004704 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004705 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004706 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00004707 if (fp == NULL)
4708 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004709 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004710 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00004711 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004712 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00004713}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004714
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004715#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004716#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00004717
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004718
Guido van Rossumb6775db1994-08-01 11:34:53 +00004719#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004720PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004721"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004722Set the current process's user id.");
4723
Barry Warsaw53699e91996-12-10 23:23:01 +00004724static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004725posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004726{
4727 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004728 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004729 return NULL;
4730 if (setuid(uid) < 0)
4731 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004732 Py_INCREF(Py_None);
4733 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004734}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004735#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004736
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004737
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004738#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004739PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004740"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004741Set the current process's effective user id.");
4742
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004743static PyObject *
4744posix_seteuid (PyObject *self, PyObject *args)
4745{
4746 int euid;
4747 if (!PyArg_ParseTuple(args, "i", &euid)) {
4748 return NULL;
4749 } else if (seteuid(euid) < 0) {
4750 return posix_error();
4751 } else {
4752 Py_INCREF(Py_None);
4753 return Py_None;
4754 }
4755}
4756#endif /* HAVE_SETEUID */
4757
4758#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004759PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004760"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004761Set the current process's effective group id.");
4762
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004763static PyObject *
4764posix_setegid (PyObject *self, PyObject *args)
4765{
4766 int egid;
4767 if (!PyArg_ParseTuple(args, "i", &egid)) {
4768 return NULL;
4769 } else if (setegid(egid) < 0) {
4770 return posix_error();
4771 } else {
4772 Py_INCREF(Py_None);
4773 return Py_None;
4774 }
4775}
4776#endif /* HAVE_SETEGID */
4777
4778#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004779PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004780"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004781Set the current process's real and effective user ids.");
4782
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004783static PyObject *
4784posix_setreuid (PyObject *self, PyObject *args)
4785{
4786 int ruid, euid;
4787 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
4788 return NULL;
4789 } else if (setreuid(ruid, euid) < 0) {
4790 return posix_error();
4791 } else {
4792 Py_INCREF(Py_None);
4793 return Py_None;
4794 }
4795}
4796#endif /* HAVE_SETREUID */
4797
4798#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004799PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004800"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004801Set the current process's real and effective group ids.");
4802
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004803static PyObject *
4804posix_setregid (PyObject *self, PyObject *args)
4805{
4806 int rgid, egid;
4807 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
4808 return NULL;
4809 } else if (setregid(rgid, egid) < 0) {
4810 return posix_error();
4811 } else {
4812 Py_INCREF(Py_None);
4813 return Py_None;
4814 }
4815}
4816#endif /* HAVE_SETREGID */
4817
Guido van Rossumb6775db1994-08-01 11:34:53 +00004818#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004819PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004820"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004821Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004822
Barry Warsaw53699e91996-12-10 23:23:01 +00004823static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004824posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004825{
4826 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004827 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004828 return NULL;
4829 if (setgid(gid) < 0)
4830 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004831 Py_INCREF(Py_None);
4832 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004833}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004834#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004835
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004836#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004837PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004838"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004839Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004840
4841static PyObject *
4842posix_setgroups(PyObject *self, PyObject *args)
4843{
4844 PyObject *groups;
4845 int i, len;
4846 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00004847
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004848 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
4849 return NULL;
4850 if (!PySequence_Check(groups)) {
4851 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
4852 return NULL;
4853 }
4854 len = PySequence_Size(groups);
4855 if (len > MAX_GROUPS) {
4856 PyErr_SetString(PyExc_ValueError, "too many groups");
4857 return NULL;
4858 }
4859 for(i = 0; i < len; i++) {
4860 PyObject *elem;
4861 elem = PySequence_GetItem(groups, i);
4862 if (!elem)
4863 return NULL;
4864 if (!PyInt_Check(elem)) {
4865 PyErr_SetString(PyExc_TypeError,
4866 "groups must be integers");
4867 Py_DECREF(elem);
4868 return NULL;
4869 }
4870 /* XXX: check that value fits into gid_t. */
4871 grouplist[i] = PyInt_AsLong(elem);
4872 Py_DECREF(elem);
4873 }
4874
4875 if (setgroups(len, grouplist) < 0)
4876 return posix_error();
4877 Py_INCREF(Py_None);
4878 return Py_None;
4879}
4880#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004881
Guido van Rossumb6775db1994-08-01 11:34:53 +00004882#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004883PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004884"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004885Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004886
Barry Warsaw53699e91996-12-10 23:23:01 +00004887static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004888posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004889{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004890 int pid, options;
4891#ifdef UNION_WAIT
4892 union wait status;
4893#define status_i (status.w_status)
4894#else
4895 int status;
4896#define status_i status
4897#endif
4898 status_i = 0;
4899
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004900 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00004901 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004902 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00004903 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00004904 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00004905 if (pid == -1)
4906 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00004907 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004908 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00004909}
4910
Tim Petersab034fa2002-02-01 11:27:43 +00004911#elif defined(HAVE_CWAIT)
4912
4913/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004914PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004915"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004916"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00004917
4918static PyObject *
4919posix_waitpid(PyObject *self, PyObject *args)
4920{
4921 int pid, options;
4922 int status;
4923
4924 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
4925 return NULL;
4926 Py_BEGIN_ALLOW_THREADS
4927 pid = _cwait(&status, pid, options);
4928 Py_END_ALLOW_THREADS
4929 if (pid == -1)
4930 return posix_error();
4931 else
4932 /* shift the status left a byte so this is more like the
4933 POSIX waitpid */
4934 return Py_BuildValue("ii", pid, status << 8);
4935}
4936#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004937
Guido van Rossumad0ee831995-03-01 10:34:45 +00004938#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004939PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004940"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004941Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004942
Barry Warsaw53699e91996-12-10 23:23:01 +00004943static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004944posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00004945{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004946 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004947#ifdef UNION_WAIT
4948 union wait status;
4949#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004950#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004951 int status;
4952#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004953#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00004954
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004955 status_i = 0;
4956 Py_BEGIN_ALLOW_THREADS
4957 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00004958 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00004959 if (pid == -1)
4960 return posix_error();
4961 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004962 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004963#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00004964}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004965#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004966
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004967
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004968PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004969"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004970Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004971
Barry Warsaw53699e91996-12-10 23:23:01 +00004972static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004973posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004974{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004975#ifdef HAVE_LSTAT
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004976 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004977#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004978#ifdef MS_WINDOWS
Mark Hammond7edd0a92003-08-06 02:46:58 +00004979 return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", _wstati64);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004980#else
4981 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
4982#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00004983#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004984}
4985
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004986
Guido van Rossumb6775db1994-08-01 11:34:53 +00004987#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004988PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004989"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004990Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004991
Barry Warsaw53699e91996-12-10 23:23:01 +00004992static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004993posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004994{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004995 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004996 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004997 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004998 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004999 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005000 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00005001 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00005002 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005003 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00005004 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00005005 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005006}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005007#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005008
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005009
Guido van Rossumb6775db1994-08-01 11:34:53 +00005010#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005011PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005012"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00005013Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005014
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005015static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005016posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005017{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005018 return posix_2str(args, "etet:symlink", symlink, NULL, NULL);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005019}
5020#endif /* HAVE_SYMLINK */
5021
5022
5023#ifdef HAVE_TIMES
5024#ifndef HZ
5025#define HZ 60 /* Universal constant :-) */
5026#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00005027
Guido van Rossumd48f2521997-12-05 22:19:34 +00005028#if defined(PYCC_VACPP) && defined(PYOS_OS2)
5029static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005030system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005031{
5032 ULONG value = 0;
5033
5034 Py_BEGIN_ALLOW_THREADS
5035 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
5036 Py_END_ALLOW_THREADS
5037
5038 return value;
5039}
5040
5041static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005042posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005043{
Guido van Rossumd48f2521997-12-05 22:19:34 +00005044 /* Currently Only Uptime is Provided -- Others Later */
5045 return Py_BuildValue("ddddd",
5046 (double)0 /* t.tms_utime / HZ */,
5047 (double)0 /* t.tms_stime / HZ */,
5048 (double)0 /* t.tms_cutime / HZ */,
5049 (double)0 /* t.tms_cstime / HZ */,
5050 (double)system_uptime() / 1000);
5051}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005052#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00005053static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005054posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00005055{
5056 struct tms t;
5057 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +00005058 errno = 0;
5059 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00005060 if (c == (clock_t) -1)
5061 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005062 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00005063 (double)t.tms_utime / HZ,
5064 (double)t.tms_stime / HZ,
5065 (double)t.tms_cutime / HZ,
5066 (double)t.tms_cstime / HZ,
5067 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00005068}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005069#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005070#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005071
5072
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005073#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005074#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00005075static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005076posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005077{
5078 FILETIME create, exit, kernel, user;
5079 HANDLE hProc;
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005080 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00005081 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
5082 /* The fields of a FILETIME structure are the hi and lo part
5083 of a 64-bit value expressed in 100 nanosecond units.
5084 1e7 is one second in such units; 1e-7 the inverse.
5085 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
5086 */
Barry Warsaw53699e91996-12-10 23:23:01 +00005087 return Py_BuildValue(
5088 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00005089 (double)(kernel.dwHighDateTime*429.4967296 +
5090 kernel.dwLowDateTime*1e-7),
5091 (double)(user.dwHighDateTime*429.4967296 +
5092 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00005093 (double)0,
5094 (double)0,
5095 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005096}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005097#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005098
5099#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005100PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005101"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005102Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005103#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005104
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005105
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00005106#ifdef HAVE_GETSID
5107PyDoc_STRVAR(posix_getsid__doc__,
5108"getsid(pid) -> sid\n\n\
5109Call the system call getsid().");
5110
5111static PyObject *
5112posix_getsid(PyObject *self, PyObject *args)
5113{
5114 int pid, sid;
5115 if (!PyArg_ParseTuple(args, "i:getsid", &pid))
5116 return NULL;
5117 sid = getsid(pid);
5118 if (sid < 0)
5119 return posix_error();
5120 return PyInt_FromLong((long)sid);
5121}
5122#endif /* HAVE_GETSID */
5123
5124
Guido van Rossumb6775db1994-08-01 11:34:53 +00005125#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005126PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005127"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005128Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005129
Barry Warsaw53699e91996-12-10 23:23:01 +00005130static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005131posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005132{
Guido van Rossum687dd131993-05-17 08:34:16 +00005133 if (setsid() < 0)
5134 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005135 Py_INCREF(Py_None);
5136 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005137}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005138#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005139
Guido van Rossumb6775db1994-08-01 11:34:53 +00005140#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005141PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005142"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005143Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005144
Barry Warsaw53699e91996-12-10 23:23:01 +00005145static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005146posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005147{
5148 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005149 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00005150 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005151 if (setpgid(pid, pgrp) < 0)
5152 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005153 Py_INCREF(Py_None);
5154 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005155}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005156#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005157
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005158
Guido van Rossumb6775db1994-08-01 11:34:53 +00005159#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005160PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005161"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005162Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005163
Barry Warsaw53699e91996-12-10 23:23:01 +00005164static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005165posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005166{
5167 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005168 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00005169 return NULL;
5170 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005171 if (pgid < 0)
5172 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005173 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00005174}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005175#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00005176
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005177
Guido van Rossumb6775db1994-08-01 11:34:53 +00005178#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005179PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005180"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005181Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005182
Barry Warsaw53699e91996-12-10 23:23:01 +00005183static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005184posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005185{
5186 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005187 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00005188 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005189 if (tcsetpgrp(fd, pgid) < 0)
5190 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00005191 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00005192 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00005193}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005194#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00005195
Guido van Rossum687dd131993-05-17 08:34:16 +00005196/* Functions acting on file descriptors */
5197
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005198PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005199"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005200Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005201
Barry Warsaw53699e91996-12-10 23:23:01 +00005202static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005203posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005204{
Mark Hammondef8b6542001-05-13 08:04:26 +00005205 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005206 int flag;
5207 int mode = 0777;
5208 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005209
5210#ifdef MS_WINDOWS
5211 if (unicode_file_names()) {
5212 PyUnicodeObject *po;
5213 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
5214 Py_BEGIN_ALLOW_THREADS
5215 /* PyUnicode_AS_UNICODE OK without thread
5216 lock as it is a simple dereference. */
5217 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
5218 Py_END_ALLOW_THREADS
5219 if (fd < 0)
5220 return posix_error();
5221 return PyInt_FromLong((long)fd);
5222 }
5223 /* Drop the argument parsing error as narrow strings
5224 are also valid. */
5225 PyErr_Clear();
5226 }
5227#endif
5228
Tim Peters5aa91602002-01-30 05:46:57 +00005229 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00005230 Py_FileSystemDefaultEncoding, &file,
5231 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00005232 return NULL;
5233
Barry Warsaw53699e91996-12-10 23:23:01 +00005234 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005235 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005236 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005237 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00005238 return posix_error_with_allocated_filename(file);
5239 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00005240 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005241}
5242
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005243
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005244PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005245"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005246Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005247
Barry Warsaw53699e91996-12-10 23:23:01 +00005248static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005249posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005250{
5251 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005252 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005253 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005254 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005255 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00005256 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005257 if (res < 0)
5258 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005259 Py_INCREF(Py_None);
5260 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005261}
5262
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005263
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005264PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005265"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005266Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005267
Barry Warsaw53699e91996-12-10 23:23:01 +00005268static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005269posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005270{
5271 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005272 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005273 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005274 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005275 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00005276 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005277 if (fd < 0)
5278 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005279 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005280}
5281
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005282
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005283PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00005284"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005285Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005286
Barry Warsaw53699e91996-12-10 23:23:01 +00005287static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005288posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005289{
5290 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005291 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00005292 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005293 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005294 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00005295 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005296 if (res < 0)
5297 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005298 Py_INCREF(Py_None);
5299 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005300}
5301
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005302
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005303PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005304"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005305Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005306
Barry Warsaw53699e91996-12-10 23:23:01 +00005307static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005308posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005309{
5310 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005311#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005312 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005313#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00005314 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005315#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005316 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005317 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00005318 return NULL;
5319#ifdef SEEK_SET
5320 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
5321 switch (how) {
5322 case 0: how = SEEK_SET; break;
5323 case 1: how = SEEK_CUR; break;
5324 case 2: how = SEEK_END; break;
5325 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005326#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005327
5328#if !defined(HAVE_LARGEFILE_SUPPORT)
5329 pos = PyInt_AsLong(posobj);
5330#else
5331 pos = PyLong_Check(posobj) ?
5332 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
5333#endif
5334 if (PyErr_Occurred())
5335 return NULL;
5336
Barry Warsaw53699e91996-12-10 23:23:01 +00005337 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005338#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00005339 res = _lseeki64(fd, pos, how);
5340#else
Guido van Rossum687dd131993-05-17 08:34:16 +00005341 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005342#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005343 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005344 if (res < 0)
5345 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00005346
5347#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00005348 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005349#else
5350 return PyLong_FromLongLong(res);
5351#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005352}
5353
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005354
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005355PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005356"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005357Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005358
Barry Warsaw53699e91996-12-10 23:23:01 +00005359static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005360posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005361{
Guido van Rossum8bac5461996-06-11 18:38:48 +00005362 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00005363 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005364 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005365 return NULL;
Michael W. Hudson9867ced2005-01-31 17:01:59 +00005366 if (size < 0) {
5367 errno = EINVAL;
5368 return posix_error();
5369 }
Barry Warsaw53699e91996-12-10 23:23:01 +00005370 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005371 if (buffer == NULL)
5372 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005373 Py_BEGIN_ALLOW_THREADS
5374 n = read(fd, PyString_AsString(buffer), size);
5375 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00005376 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005377 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00005378 return posix_error();
5379 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00005380 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00005381 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00005382 return buffer;
5383}
5384
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005385
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005386PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005387"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005388Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005389
Barry Warsaw53699e91996-12-10 23:23:01 +00005390static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005391posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005392{
5393 int fd, size;
5394 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005395 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005396 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005397 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005398 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00005399 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005400 if (size < 0)
5401 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005402 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005403}
5404
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005405
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005406PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005407"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005408Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005409
Barry Warsaw53699e91996-12-10 23:23:01 +00005410static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005411posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005412{
5413 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00005414 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00005415 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005416 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005417 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005418#ifdef __VMS
5419 /* on OpenVMS we must ensure that all bytes are written to the file */
5420 fsync(fd);
5421#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005422 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00005423 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00005424 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005425 if (res != 0)
5426 return posix_error();
Tim Peters5aa91602002-01-30 05:46:57 +00005427
Fred Drake699f3522000-06-29 21:12:41 +00005428 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00005429}
5430
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005431
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005432PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005433"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005434Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005435
Barry Warsaw53699e91996-12-10 23:23:01 +00005436static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005437posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005438{
Guido van Rossum687dd131993-05-17 08:34:16 +00005439 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005440 char *mode = "r";
5441 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00005442 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00005443 PyObject *f;
5444 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00005445 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00005446
Thomas Heller1f043e22002-11-07 16:00:59 +00005447 if (mode[0] != 'r' && mode[0] != 'w' && mode[0] != 'a') {
5448 PyErr_Format(PyExc_ValueError,
5449 "invalid file mode '%s'", mode);
5450 return NULL;
5451 }
5452
Barry Warsaw53699e91996-12-10 23:23:01 +00005453 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005454 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005455 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005456 if (fp == NULL)
5457 return posix_error();
Guido van Rossumbd6be7a2002-09-15 18:45:46 +00005458 f = PyFile_FromFile(fp, "<fdopen>", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005459 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00005460 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005461 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00005462}
5463
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005464PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005465"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005466Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005467connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00005468
5469static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00005470posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00005471{
5472 int fd;
5473 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
5474 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005475 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00005476}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005477
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005478#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005479PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005480"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005481Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005482
Barry Warsaw53699e91996-12-10 23:23:01 +00005483static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005484posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00005485{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005486#if defined(PYOS_OS2)
5487 HFILE read, write;
5488 APIRET rc;
5489
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005490 Py_BEGIN_ALLOW_THREADS
5491 rc = DosCreatePipe( &read, &write, 4096);
5492 Py_END_ALLOW_THREADS
5493 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005494 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005495
5496 return Py_BuildValue("(ii)", read, write);
5497#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005498#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00005499 int fds[2];
5500 int res;
Barry Warsaw53699e91996-12-10 23:23:01 +00005501 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005502 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00005503 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005504 if (res != 0)
5505 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005506 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005507#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00005508 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005509 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00005510 BOOL ok;
Barry Warsaw53699e91996-12-10 23:23:01 +00005511 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005512 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00005513 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00005514 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005515 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00005516 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
5517 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005518 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005519#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005520#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005521}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005522#endif /* HAVE_PIPE */
5523
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005524
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005525#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005526PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005527"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005528Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005529
Barry Warsaw53699e91996-12-10 23:23:01 +00005530static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005531posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005532{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005533 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005534 int mode = 0666;
5535 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005536 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005537 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005538 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005539 res = mkfifo(filename, mode);
5540 Py_END_ALLOW_THREADS
5541 if (res < 0)
5542 return posix_error();
5543 Py_INCREF(Py_None);
5544 return Py_None;
5545}
5546#endif
5547
5548
Neal Norwitz11690112002-07-30 01:08:28 +00005549#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005550PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005551"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005552Create a filesystem node (file, device special file or named pipe)\n\
5553named filename. mode specifies both the permissions to use and the\n\
5554type of node to be created, being combined (bitwise OR) with one of\n\
5555S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005556device defines the newly created device special file (probably using\n\
5557os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005558
5559
5560static PyObject *
5561posix_mknod(PyObject *self, PyObject *args)
5562{
5563 char *filename;
5564 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005565 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005566 int res;
Martin v. Löwisd631ebe2002-11-02 17:42:33 +00005567 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005568 return NULL;
5569 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005570 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00005571 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005572 if (res < 0)
5573 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005574 Py_INCREF(Py_None);
5575 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005576}
5577#endif
5578
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005579#ifdef HAVE_DEVICE_MACROS
5580PyDoc_STRVAR(posix_major__doc__,
5581"major(device) -> major number\n\
5582Extracts a device major number from a raw device number.");
5583
5584static PyObject *
5585posix_major(PyObject *self, PyObject *args)
5586{
5587 int device;
5588 if (!PyArg_ParseTuple(args, "i:major", &device))
5589 return NULL;
5590 return PyInt_FromLong((long)major(device));
5591}
5592
5593PyDoc_STRVAR(posix_minor__doc__,
5594"minor(device) -> minor number\n\
5595Extracts a device minor number from a raw device number.");
5596
5597static PyObject *
5598posix_minor(PyObject *self, PyObject *args)
5599{
5600 int device;
5601 if (!PyArg_ParseTuple(args, "i:minor", &device))
5602 return NULL;
5603 return PyInt_FromLong((long)minor(device));
5604}
5605
5606PyDoc_STRVAR(posix_makedev__doc__,
5607"makedev(major, minor) -> device number\n\
5608Composes a raw device number from the major and minor device numbers.");
5609
5610static PyObject *
5611posix_makedev(PyObject *self, PyObject *args)
5612{
5613 int major, minor;
5614 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
5615 return NULL;
5616 return PyInt_FromLong((long)makedev(major, minor));
5617}
5618#endif /* device macros */
5619
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005620
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005621#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005622PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005623"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005624Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005625
Barry Warsaw53699e91996-12-10 23:23:01 +00005626static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005627posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005628{
5629 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005630 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005631 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005632 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005633
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005634 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005635 return NULL;
5636
5637#if !defined(HAVE_LARGEFILE_SUPPORT)
5638 length = PyInt_AsLong(lenobj);
5639#else
5640 length = PyLong_Check(lenobj) ?
5641 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
5642#endif
5643 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005644 return NULL;
5645
Barry Warsaw53699e91996-12-10 23:23:01 +00005646 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005647 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00005648 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005649 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005650 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005651 return NULL;
5652 }
Barry Warsaw53699e91996-12-10 23:23:01 +00005653 Py_INCREF(Py_None);
5654 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005655}
5656#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005657
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005658#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005659PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005660"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005661Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005662
Fred Drake762e2061999-08-26 17:23:54 +00005663/* Save putenv() parameters as values here, so we can collect them when they
5664 * get re-set with another call for the same key. */
5665static PyObject *posix_putenv_garbage;
5666
Tim Peters5aa91602002-01-30 05:46:57 +00005667static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005668posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005669{
5670 char *s1, *s2;
5671 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00005672 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00005673 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005674
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005675 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005676 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00005677
5678#if defined(PYOS_OS2)
5679 if (stricmp(s1, "BEGINLIBPATH") == 0) {
5680 APIRET rc;
5681
Guido van Rossumd48f2521997-12-05 22:19:34 +00005682 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
5683 if (rc != NO_ERROR)
5684 return os2_error(rc);
5685
5686 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
5687 APIRET rc;
5688
Guido van Rossumd48f2521997-12-05 22:19:34 +00005689 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
5690 if (rc != NO_ERROR)
5691 return os2_error(rc);
5692 } else {
5693#endif
5694
Fred Drake762e2061999-08-26 17:23:54 +00005695 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00005696 len = strlen(s1) + strlen(s2) + 2;
5697 /* len includes space for a trailing \0; the size arg to
5698 PyString_FromStringAndSize does not count that */
5699 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00005700 if (newstr == NULL)
5701 return PyErr_NoMemory();
5702 new = PyString_AS_STRING(newstr);
Tim Petersc8996f52001-12-03 20:41:00 +00005703 PyOS_snprintf(new, len, "%s=%s", s1, s2);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005704 if (putenv(new)) {
Neal Norwitz4adc9ab2003-02-10 03:10:43 +00005705 Py_DECREF(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005706 posix_error();
5707 return NULL;
5708 }
Fred Drake762e2061999-08-26 17:23:54 +00005709 /* Install the first arg and newstr in posix_putenv_garbage;
5710 * this will cause previous value to be collected. This has to
5711 * happen after the real putenv() call because the old value
5712 * was still accessible until then. */
5713 if (PyDict_SetItem(posix_putenv_garbage,
5714 PyTuple_GET_ITEM(args, 0), newstr)) {
5715 /* really not much we can do; just leak */
5716 PyErr_Clear();
5717 }
5718 else {
5719 Py_DECREF(newstr);
5720 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005721
5722#if defined(PYOS_OS2)
5723 }
5724#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005725 Py_INCREF(Py_None);
5726 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005727}
Guido van Rossumb6a47161997-09-15 22:54:34 +00005728#endif /* putenv */
5729
Guido van Rossumc524d952001-10-19 01:31:59 +00005730#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005731PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005732"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005733Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00005734
5735static PyObject *
5736posix_unsetenv(PyObject *self, PyObject *args)
5737{
5738 char *s1;
5739
5740 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
5741 return NULL;
5742
5743 unsetenv(s1);
5744
5745 /* Remove the key from posix_putenv_garbage;
5746 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00005747 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00005748 * old value was still accessible until then.
5749 */
5750 if (PyDict_DelItem(posix_putenv_garbage,
5751 PyTuple_GET_ITEM(args, 0))) {
5752 /* really not much we can do; just leak */
5753 PyErr_Clear();
5754 }
5755
5756 Py_INCREF(Py_None);
5757 return Py_None;
5758}
5759#endif /* unsetenv */
5760
Guido van Rossumb6a47161997-09-15 22:54:34 +00005761#ifdef HAVE_STRERROR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005762PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005763"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005764Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005765
Guido van Rossumf68d8e52001-04-14 17:55:09 +00005766static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005767posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00005768{
5769 int code;
5770 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005771 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00005772 return NULL;
5773 message = strerror(code);
5774 if (message == NULL) {
5775 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00005776 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005777 return NULL;
5778 }
5779 return PyString_FromString(message);
5780}
5781#endif /* strerror */
5782
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005783
Guido van Rossumc9641791998-08-04 15:26:23 +00005784#ifdef HAVE_SYS_WAIT_H
5785
Fred Drake106c1a02002-04-23 15:58:02 +00005786#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005787PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005788"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005789Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00005790
5791static PyObject *
5792posix_WCOREDUMP(PyObject *self, PyObject *args)
5793{
5794#ifdef UNION_WAIT
5795 union wait status;
5796#define status_i (status.w_status)
5797#else
5798 int status;
5799#define status_i status
5800#endif
5801 status_i = 0;
5802
5803 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &status_i))
5804 {
5805 return NULL;
5806 }
5807
5808 return PyBool_FromLong(WCOREDUMP(status));
5809#undef status_i
5810}
5811#endif /* WCOREDUMP */
5812
5813#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005814PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005815"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005816Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005817job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00005818
5819static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005820posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00005821{
5822#ifdef UNION_WAIT
5823 union wait status;
5824#define status_i (status.w_status)
5825#else
5826 int status;
5827#define status_i status
5828#endif
5829 status_i = 0;
5830
5831 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &status_i))
5832 {
5833 return NULL;
5834 }
5835
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005836 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00005837#undef status_i
5838}
5839#endif /* WIFCONTINUED */
5840
Guido van Rossumc9641791998-08-04 15:26:23 +00005841#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005842PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005843"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005844Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005845
5846static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005847posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005848{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005849#ifdef UNION_WAIT
5850 union wait status;
5851#define status_i (status.w_status)
5852#else
5853 int status;
5854#define status_i status
5855#endif
5856 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005857
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005858 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005859 {
5860 return NULL;
5861 }
Tim Peters5aa91602002-01-30 05:46:57 +00005862
Fred Drake106c1a02002-04-23 15:58:02 +00005863 return PyBool_FromLong(WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005864#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005865}
5866#endif /* WIFSTOPPED */
5867
5868#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005869PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005870"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005871Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005872
5873static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005874posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005875{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005876#ifdef UNION_WAIT
5877 union wait status;
5878#define status_i (status.w_status)
5879#else
5880 int status;
5881#define status_i status
5882#endif
5883 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005884
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005885 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005886 {
5887 return NULL;
5888 }
Tim Peters5aa91602002-01-30 05:46:57 +00005889
Fred Drake106c1a02002-04-23 15:58:02 +00005890 return PyBool_FromLong(WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005891#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005892}
5893#endif /* WIFSIGNALED */
5894
5895#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005896PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005897"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005898Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005899system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005900
5901static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005902posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005903{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005904#ifdef UNION_WAIT
5905 union wait status;
5906#define status_i (status.w_status)
5907#else
5908 int status;
5909#define status_i status
5910#endif
5911 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005912
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005913 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005914 {
5915 return NULL;
5916 }
Tim Peters5aa91602002-01-30 05:46:57 +00005917
Fred Drake106c1a02002-04-23 15:58:02 +00005918 return PyBool_FromLong(WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005919#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005920}
5921#endif /* WIFEXITED */
5922
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005923#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005924PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005925"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005926Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005927
5928static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005929posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005930{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005931#ifdef UNION_WAIT
5932 union wait status;
5933#define status_i (status.w_status)
5934#else
5935 int status;
5936#define status_i status
5937#endif
5938 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005939
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005940 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005941 {
5942 return NULL;
5943 }
Tim Peters5aa91602002-01-30 05:46:57 +00005944
Guido van Rossumc9641791998-08-04 15:26:23 +00005945 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005946#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005947}
5948#endif /* WEXITSTATUS */
5949
5950#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005951PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005952"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005953Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005954value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005955
5956static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005957posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005958{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005959#ifdef UNION_WAIT
5960 union wait status;
5961#define status_i (status.w_status)
5962#else
5963 int status;
5964#define status_i status
5965#endif
5966 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005967
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005968 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005969 {
5970 return NULL;
5971 }
Tim Peters5aa91602002-01-30 05:46:57 +00005972
Guido van Rossumc9641791998-08-04 15:26:23 +00005973 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005974#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005975}
5976#endif /* WTERMSIG */
5977
5978#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005979PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005980"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005981Return the signal that stopped the process that provided\n\
5982the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005983
5984static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005985posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005986{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005987#ifdef UNION_WAIT
5988 union wait status;
5989#define status_i (status.w_status)
5990#else
5991 int status;
5992#define status_i status
5993#endif
5994 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005995
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005996 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005997 {
5998 return NULL;
5999 }
Tim Peters5aa91602002-01-30 05:46:57 +00006000
Guido van Rossumc9641791998-08-04 15:26:23 +00006001 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006002#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00006003}
6004#endif /* WSTOPSIG */
6005
6006#endif /* HAVE_SYS_WAIT_H */
6007
6008
Guido van Rossum94f6f721999-01-06 18:42:14 +00006009#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00006010#ifdef _SCO_DS
6011/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
6012 needed definitions in sys/statvfs.h */
6013#define _SVID3
6014#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006015#include <sys/statvfs.h>
6016
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006017static PyObject*
6018_pystatvfs_fromstructstatvfs(struct statvfs st) {
6019 PyObject *v = PyStructSequence_New(&StatVFSResultType);
6020 if (v == NULL)
6021 return NULL;
6022
6023#if !defined(HAVE_LARGEFILE_SUPPORT)
6024 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6025 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
6026 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
6027 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
6028 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
6029 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
6030 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
6031 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
6032 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6033 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6034#else
6035 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6036 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00006037 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006038 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00006039 PyStructSequence_SET_ITEM(v, 3,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006040 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006041 PyStructSequence_SET_ITEM(v, 4,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006042 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00006043 PyStructSequence_SET_ITEM(v, 5,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006044 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00006045 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006046 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00006047 PyStructSequence_SET_ITEM(v, 7,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006048 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006049 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6050 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6051#endif
6052
6053 return v;
6054}
6055
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006056PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006057"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006058Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006059
6060static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006061posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006062{
6063 int fd, res;
6064 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006065
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006066 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006067 return NULL;
6068 Py_BEGIN_ALLOW_THREADS
6069 res = fstatvfs(fd, &st);
6070 Py_END_ALLOW_THREADS
6071 if (res != 0)
6072 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006073
6074 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006075}
6076#endif /* HAVE_FSTATVFS */
6077
6078
6079#if defined(HAVE_STATVFS)
6080#include <sys/statvfs.h>
6081
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006082PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006083"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006084Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006085
6086static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006087posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006088{
6089 char *path;
6090 int res;
6091 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006092 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006093 return NULL;
6094 Py_BEGIN_ALLOW_THREADS
6095 res = statvfs(path, &st);
6096 Py_END_ALLOW_THREADS
6097 if (res != 0)
6098 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006099
6100 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006101}
6102#endif /* HAVE_STATVFS */
6103
6104
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006105#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006106PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006107"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006108Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00006109The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006110or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006111
6112static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006113posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006114{
6115 PyObject *result = NULL;
6116 char *dir = NULL;
6117 char *pfx = NULL;
6118 char *name;
6119
6120 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
6121 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00006122
6123 if (PyErr_Warn(PyExc_RuntimeWarning,
6124 "tempnam is a potential security risk to your program") < 0)
6125 return NULL;
6126
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006127#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00006128 name = _tempnam(dir, pfx);
6129#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006130 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00006131#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006132 if (name == NULL)
6133 return PyErr_NoMemory();
6134 result = PyString_FromString(name);
6135 free(name);
6136 return result;
6137}
Guido van Rossumd371ff11999-01-25 16:12:23 +00006138#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006139
6140
6141#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006142PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006143"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006144Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006145
6146static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006147posix_tmpfile(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006148{
6149 FILE *fp;
6150
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006151 fp = tmpfile();
6152 if (fp == NULL)
6153 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00006154 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006155}
6156#endif
6157
6158
6159#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006160PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006161"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006162Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006163
6164static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006165posix_tmpnam(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006166{
6167 char buffer[L_tmpnam];
6168 char *name;
6169
Skip Montanaro95618b52001-08-18 18:52:10 +00006170 if (PyErr_Warn(PyExc_RuntimeWarning,
6171 "tmpnam is a potential security risk to your program") < 0)
6172 return NULL;
6173
Greg Wardb48bc172000-03-01 21:51:56 +00006174#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006175 name = tmpnam_r(buffer);
6176#else
6177 name = tmpnam(buffer);
6178#endif
6179 if (name == NULL) {
6180 PyErr_SetObject(PyExc_OSError,
6181 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00006182#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006183 "unexpected NULL from tmpnam_r"
6184#else
6185 "unexpected NULL from tmpnam"
6186#endif
6187 ));
6188 return NULL;
6189 }
6190 return PyString_FromString(buffer);
6191}
6192#endif
6193
6194
Fred Drakec9680921999-12-13 16:37:25 +00006195/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
6196 * It maps strings representing configuration variable names to
6197 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00006198 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00006199 * rarely-used constants. There are three separate tables that use
6200 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00006201 *
6202 * This code is always included, even if none of the interfaces that
6203 * need it are included. The #if hackery needed to avoid it would be
6204 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00006205 */
6206struct constdef {
6207 char *name;
6208 long value;
6209};
6210
Fred Drake12c6e2d1999-12-14 21:25:03 +00006211static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006212conv_confname(PyObject *arg, int *valuep, struct constdef *table,
6213 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006214{
6215 if (PyInt_Check(arg)) {
6216 *valuep = PyInt_AS_LONG(arg);
6217 return 1;
6218 }
6219 if (PyString_Check(arg)) {
6220 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00006221 size_t lo = 0;
6222 size_t mid;
6223 size_t hi = tablesize;
6224 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006225 char *confname = PyString_AS_STRING(arg);
6226 while (lo < hi) {
6227 mid = (lo + hi) / 2;
6228 cmp = strcmp(confname, table[mid].name);
6229 if (cmp < 0)
6230 hi = mid;
6231 else if (cmp > 0)
6232 lo = mid + 1;
6233 else {
6234 *valuep = table[mid].value;
6235 return 1;
6236 }
6237 }
6238 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
6239 }
6240 else
6241 PyErr_SetString(PyExc_TypeError,
6242 "configuration names must be strings or integers");
6243 return 0;
6244}
6245
6246
6247#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
6248static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006249#ifdef _PC_ABI_AIO_XFER_MAX
6250 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
6251#endif
6252#ifdef _PC_ABI_ASYNC_IO
6253 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
6254#endif
Fred Drakec9680921999-12-13 16:37:25 +00006255#ifdef _PC_ASYNC_IO
6256 {"PC_ASYNC_IO", _PC_ASYNC_IO},
6257#endif
6258#ifdef _PC_CHOWN_RESTRICTED
6259 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
6260#endif
6261#ifdef _PC_FILESIZEBITS
6262 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
6263#endif
6264#ifdef _PC_LAST
6265 {"PC_LAST", _PC_LAST},
6266#endif
6267#ifdef _PC_LINK_MAX
6268 {"PC_LINK_MAX", _PC_LINK_MAX},
6269#endif
6270#ifdef _PC_MAX_CANON
6271 {"PC_MAX_CANON", _PC_MAX_CANON},
6272#endif
6273#ifdef _PC_MAX_INPUT
6274 {"PC_MAX_INPUT", _PC_MAX_INPUT},
6275#endif
6276#ifdef _PC_NAME_MAX
6277 {"PC_NAME_MAX", _PC_NAME_MAX},
6278#endif
6279#ifdef _PC_NO_TRUNC
6280 {"PC_NO_TRUNC", _PC_NO_TRUNC},
6281#endif
6282#ifdef _PC_PATH_MAX
6283 {"PC_PATH_MAX", _PC_PATH_MAX},
6284#endif
6285#ifdef _PC_PIPE_BUF
6286 {"PC_PIPE_BUF", _PC_PIPE_BUF},
6287#endif
6288#ifdef _PC_PRIO_IO
6289 {"PC_PRIO_IO", _PC_PRIO_IO},
6290#endif
6291#ifdef _PC_SOCK_MAXBUF
6292 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
6293#endif
6294#ifdef _PC_SYNC_IO
6295 {"PC_SYNC_IO", _PC_SYNC_IO},
6296#endif
6297#ifdef _PC_VDISABLE
6298 {"PC_VDISABLE", _PC_VDISABLE},
6299#endif
6300};
6301
Fred Drakec9680921999-12-13 16:37:25 +00006302static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006303conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006304{
6305 return conv_confname(arg, valuep, posix_constants_pathconf,
6306 sizeof(posix_constants_pathconf)
6307 / sizeof(struct constdef));
6308}
6309#endif
6310
6311#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006312PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006313"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006314Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006315If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006316
6317static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006318posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006319{
6320 PyObject *result = NULL;
6321 int name, fd;
6322
Fred Drake12c6e2d1999-12-14 21:25:03 +00006323 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
6324 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00006325 long limit;
6326
6327 errno = 0;
6328 limit = fpathconf(fd, name);
6329 if (limit == -1 && errno != 0)
6330 posix_error();
6331 else
6332 result = PyInt_FromLong(limit);
6333 }
6334 return result;
6335}
6336#endif
6337
6338
6339#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006340PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006341"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006342Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006343If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006344
6345static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006346posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006347{
6348 PyObject *result = NULL;
6349 int name;
6350 char *path;
6351
6352 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
6353 conv_path_confname, &name)) {
6354 long limit;
6355
6356 errno = 0;
6357 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006358 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00006359 if (errno == EINVAL)
6360 /* could be a path or name problem */
6361 posix_error();
6362 else
6363 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006364 }
Fred Drakec9680921999-12-13 16:37:25 +00006365 else
6366 result = PyInt_FromLong(limit);
6367 }
6368 return result;
6369}
6370#endif
6371
6372#ifdef HAVE_CONFSTR
6373static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006374#ifdef _CS_ARCHITECTURE
6375 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
6376#endif
6377#ifdef _CS_HOSTNAME
6378 {"CS_HOSTNAME", _CS_HOSTNAME},
6379#endif
6380#ifdef _CS_HW_PROVIDER
6381 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
6382#endif
6383#ifdef _CS_HW_SERIAL
6384 {"CS_HW_SERIAL", _CS_HW_SERIAL},
6385#endif
6386#ifdef _CS_INITTAB_NAME
6387 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
6388#endif
Fred Drakec9680921999-12-13 16:37:25 +00006389#ifdef _CS_LFS64_CFLAGS
6390 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
6391#endif
6392#ifdef _CS_LFS64_LDFLAGS
6393 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
6394#endif
6395#ifdef _CS_LFS64_LIBS
6396 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
6397#endif
6398#ifdef _CS_LFS64_LINTFLAGS
6399 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
6400#endif
6401#ifdef _CS_LFS_CFLAGS
6402 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
6403#endif
6404#ifdef _CS_LFS_LDFLAGS
6405 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
6406#endif
6407#ifdef _CS_LFS_LIBS
6408 {"CS_LFS_LIBS", _CS_LFS_LIBS},
6409#endif
6410#ifdef _CS_LFS_LINTFLAGS
6411 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
6412#endif
Fred Draked86ed291999-12-15 15:34:33 +00006413#ifdef _CS_MACHINE
6414 {"CS_MACHINE", _CS_MACHINE},
6415#endif
Fred Drakec9680921999-12-13 16:37:25 +00006416#ifdef _CS_PATH
6417 {"CS_PATH", _CS_PATH},
6418#endif
Fred Draked86ed291999-12-15 15:34:33 +00006419#ifdef _CS_RELEASE
6420 {"CS_RELEASE", _CS_RELEASE},
6421#endif
6422#ifdef _CS_SRPC_DOMAIN
6423 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
6424#endif
6425#ifdef _CS_SYSNAME
6426 {"CS_SYSNAME", _CS_SYSNAME},
6427#endif
6428#ifdef _CS_VERSION
6429 {"CS_VERSION", _CS_VERSION},
6430#endif
Fred Drakec9680921999-12-13 16:37:25 +00006431#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
6432 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
6433#endif
6434#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
6435 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
6436#endif
6437#ifdef _CS_XBS5_ILP32_OFF32_LIBS
6438 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
6439#endif
6440#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
6441 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
6442#endif
6443#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
6444 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
6445#endif
6446#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
6447 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
6448#endif
6449#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
6450 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
6451#endif
6452#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
6453 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
6454#endif
6455#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
6456 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
6457#endif
6458#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
6459 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
6460#endif
6461#ifdef _CS_XBS5_LP64_OFF64_LIBS
6462 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
6463#endif
6464#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
6465 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
6466#endif
6467#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
6468 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
6469#endif
6470#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
6471 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
6472#endif
6473#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
6474 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
6475#endif
6476#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
6477 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
6478#endif
Fred Draked86ed291999-12-15 15:34:33 +00006479#ifdef _MIPS_CS_AVAIL_PROCESSORS
6480 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
6481#endif
6482#ifdef _MIPS_CS_BASE
6483 {"MIPS_CS_BASE", _MIPS_CS_BASE},
6484#endif
6485#ifdef _MIPS_CS_HOSTID
6486 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
6487#endif
6488#ifdef _MIPS_CS_HW_NAME
6489 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
6490#endif
6491#ifdef _MIPS_CS_NUM_PROCESSORS
6492 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
6493#endif
6494#ifdef _MIPS_CS_OSREL_MAJ
6495 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
6496#endif
6497#ifdef _MIPS_CS_OSREL_MIN
6498 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
6499#endif
6500#ifdef _MIPS_CS_OSREL_PATCH
6501 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
6502#endif
6503#ifdef _MIPS_CS_OS_NAME
6504 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
6505#endif
6506#ifdef _MIPS_CS_OS_PROVIDER
6507 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
6508#endif
6509#ifdef _MIPS_CS_PROCESSORS
6510 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
6511#endif
6512#ifdef _MIPS_CS_SERIAL
6513 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
6514#endif
6515#ifdef _MIPS_CS_VENDOR
6516 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
6517#endif
Fred Drakec9680921999-12-13 16:37:25 +00006518};
6519
6520static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006521conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006522{
6523 return conv_confname(arg, valuep, posix_constants_confstr,
6524 sizeof(posix_constants_confstr)
6525 / sizeof(struct constdef));
6526}
6527
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006528PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006529"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006530Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006531
6532static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006533posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006534{
6535 PyObject *result = NULL;
6536 int name;
6537 char buffer[64];
6538
6539 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
6540 int len = confstr(name, buffer, sizeof(buffer));
6541
Fred Drakec9680921999-12-13 16:37:25 +00006542 errno = 0;
6543 if (len == 0) {
6544 if (errno != 0)
6545 posix_error();
6546 else
6547 result = PyString_FromString("");
6548 }
6549 else {
6550 if (len >= sizeof(buffer)) {
6551 result = PyString_FromStringAndSize(NULL, len);
6552 if (result != NULL)
6553 confstr(name, PyString_AS_STRING(result), len+1);
6554 }
6555 else
6556 result = PyString_FromString(buffer);
6557 }
6558 }
6559 return result;
6560}
6561#endif
6562
6563
6564#ifdef HAVE_SYSCONF
6565static struct constdef posix_constants_sysconf[] = {
6566#ifdef _SC_2_CHAR_TERM
6567 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
6568#endif
6569#ifdef _SC_2_C_BIND
6570 {"SC_2_C_BIND", _SC_2_C_BIND},
6571#endif
6572#ifdef _SC_2_C_DEV
6573 {"SC_2_C_DEV", _SC_2_C_DEV},
6574#endif
6575#ifdef _SC_2_C_VERSION
6576 {"SC_2_C_VERSION", _SC_2_C_VERSION},
6577#endif
6578#ifdef _SC_2_FORT_DEV
6579 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
6580#endif
6581#ifdef _SC_2_FORT_RUN
6582 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
6583#endif
6584#ifdef _SC_2_LOCALEDEF
6585 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
6586#endif
6587#ifdef _SC_2_SW_DEV
6588 {"SC_2_SW_DEV", _SC_2_SW_DEV},
6589#endif
6590#ifdef _SC_2_UPE
6591 {"SC_2_UPE", _SC_2_UPE},
6592#endif
6593#ifdef _SC_2_VERSION
6594 {"SC_2_VERSION", _SC_2_VERSION},
6595#endif
Fred Draked86ed291999-12-15 15:34:33 +00006596#ifdef _SC_ABI_ASYNCHRONOUS_IO
6597 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
6598#endif
6599#ifdef _SC_ACL
6600 {"SC_ACL", _SC_ACL},
6601#endif
Fred Drakec9680921999-12-13 16:37:25 +00006602#ifdef _SC_AIO_LISTIO_MAX
6603 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
6604#endif
Fred Drakec9680921999-12-13 16:37:25 +00006605#ifdef _SC_AIO_MAX
6606 {"SC_AIO_MAX", _SC_AIO_MAX},
6607#endif
6608#ifdef _SC_AIO_PRIO_DELTA_MAX
6609 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
6610#endif
6611#ifdef _SC_ARG_MAX
6612 {"SC_ARG_MAX", _SC_ARG_MAX},
6613#endif
6614#ifdef _SC_ASYNCHRONOUS_IO
6615 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
6616#endif
6617#ifdef _SC_ATEXIT_MAX
6618 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
6619#endif
Fred Draked86ed291999-12-15 15:34:33 +00006620#ifdef _SC_AUDIT
6621 {"SC_AUDIT", _SC_AUDIT},
6622#endif
Fred Drakec9680921999-12-13 16:37:25 +00006623#ifdef _SC_AVPHYS_PAGES
6624 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
6625#endif
6626#ifdef _SC_BC_BASE_MAX
6627 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
6628#endif
6629#ifdef _SC_BC_DIM_MAX
6630 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
6631#endif
6632#ifdef _SC_BC_SCALE_MAX
6633 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
6634#endif
6635#ifdef _SC_BC_STRING_MAX
6636 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
6637#endif
Fred Draked86ed291999-12-15 15:34:33 +00006638#ifdef _SC_CAP
6639 {"SC_CAP", _SC_CAP},
6640#endif
Fred Drakec9680921999-12-13 16:37:25 +00006641#ifdef _SC_CHARCLASS_NAME_MAX
6642 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
6643#endif
6644#ifdef _SC_CHAR_BIT
6645 {"SC_CHAR_BIT", _SC_CHAR_BIT},
6646#endif
6647#ifdef _SC_CHAR_MAX
6648 {"SC_CHAR_MAX", _SC_CHAR_MAX},
6649#endif
6650#ifdef _SC_CHAR_MIN
6651 {"SC_CHAR_MIN", _SC_CHAR_MIN},
6652#endif
6653#ifdef _SC_CHILD_MAX
6654 {"SC_CHILD_MAX", _SC_CHILD_MAX},
6655#endif
6656#ifdef _SC_CLK_TCK
6657 {"SC_CLK_TCK", _SC_CLK_TCK},
6658#endif
6659#ifdef _SC_COHER_BLKSZ
6660 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
6661#endif
6662#ifdef _SC_COLL_WEIGHTS_MAX
6663 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
6664#endif
6665#ifdef _SC_DCACHE_ASSOC
6666 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
6667#endif
6668#ifdef _SC_DCACHE_BLKSZ
6669 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
6670#endif
6671#ifdef _SC_DCACHE_LINESZ
6672 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
6673#endif
6674#ifdef _SC_DCACHE_SZ
6675 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
6676#endif
6677#ifdef _SC_DCACHE_TBLKSZ
6678 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
6679#endif
6680#ifdef _SC_DELAYTIMER_MAX
6681 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
6682#endif
6683#ifdef _SC_EQUIV_CLASS_MAX
6684 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
6685#endif
6686#ifdef _SC_EXPR_NEST_MAX
6687 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
6688#endif
6689#ifdef _SC_FSYNC
6690 {"SC_FSYNC", _SC_FSYNC},
6691#endif
6692#ifdef _SC_GETGR_R_SIZE_MAX
6693 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
6694#endif
6695#ifdef _SC_GETPW_R_SIZE_MAX
6696 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
6697#endif
6698#ifdef _SC_ICACHE_ASSOC
6699 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
6700#endif
6701#ifdef _SC_ICACHE_BLKSZ
6702 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
6703#endif
6704#ifdef _SC_ICACHE_LINESZ
6705 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
6706#endif
6707#ifdef _SC_ICACHE_SZ
6708 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
6709#endif
Fred Draked86ed291999-12-15 15:34:33 +00006710#ifdef _SC_INF
6711 {"SC_INF", _SC_INF},
6712#endif
Fred Drakec9680921999-12-13 16:37:25 +00006713#ifdef _SC_INT_MAX
6714 {"SC_INT_MAX", _SC_INT_MAX},
6715#endif
6716#ifdef _SC_INT_MIN
6717 {"SC_INT_MIN", _SC_INT_MIN},
6718#endif
6719#ifdef _SC_IOV_MAX
6720 {"SC_IOV_MAX", _SC_IOV_MAX},
6721#endif
Fred Draked86ed291999-12-15 15:34:33 +00006722#ifdef _SC_IP_SECOPTS
6723 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
6724#endif
Fred Drakec9680921999-12-13 16:37:25 +00006725#ifdef _SC_JOB_CONTROL
6726 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
6727#endif
Fred Draked86ed291999-12-15 15:34:33 +00006728#ifdef _SC_KERN_POINTERS
6729 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
6730#endif
6731#ifdef _SC_KERN_SIM
6732 {"SC_KERN_SIM", _SC_KERN_SIM},
6733#endif
Fred Drakec9680921999-12-13 16:37:25 +00006734#ifdef _SC_LINE_MAX
6735 {"SC_LINE_MAX", _SC_LINE_MAX},
6736#endif
6737#ifdef _SC_LOGIN_NAME_MAX
6738 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
6739#endif
6740#ifdef _SC_LOGNAME_MAX
6741 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
6742#endif
6743#ifdef _SC_LONG_BIT
6744 {"SC_LONG_BIT", _SC_LONG_BIT},
6745#endif
Fred Draked86ed291999-12-15 15:34:33 +00006746#ifdef _SC_MAC
6747 {"SC_MAC", _SC_MAC},
6748#endif
Fred Drakec9680921999-12-13 16:37:25 +00006749#ifdef _SC_MAPPED_FILES
6750 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
6751#endif
6752#ifdef _SC_MAXPID
6753 {"SC_MAXPID", _SC_MAXPID},
6754#endif
6755#ifdef _SC_MB_LEN_MAX
6756 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
6757#endif
6758#ifdef _SC_MEMLOCK
6759 {"SC_MEMLOCK", _SC_MEMLOCK},
6760#endif
6761#ifdef _SC_MEMLOCK_RANGE
6762 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
6763#endif
6764#ifdef _SC_MEMORY_PROTECTION
6765 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
6766#endif
6767#ifdef _SC_MESSAGE_PASSING
6768 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
6769#endif
Fred Draked86ed291999-12-15 15:34:33 +00006770#ifdef _SC_MMAP_FIXED_ALIGNMENT
6771 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
6772#endif
Fred Drakec9680921999-12-13 16:37:25 +00006773#ifdef _SC_MQ_OPEN_MAX
6774 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
6775#endif
6776#ifdef _SC_MQ_PRIO_MAX
6777 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
6778#endif
Fred Draked86ed291999-12-15 15:34:33 +00006779#ifdef _SC_NACLS_MAX
6780 {"SC_NACLS_MAX", _SC_NACLS_MAX},
6781#endif
Fred Drakec9680921999-12-13 16:37:25 +00006782#ifdef _SC_NGROUPS_MAX
6783 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
6784#endif
6785#ifdef _SC_NL_ARGMAX
6786 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
6787#endif
6788#ifdef _SC_NL_LANGMAX
6789 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
6790#endif
6791#ifdef _SC_NL_MSGMAX
6792 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
6793#endif
6794#ifdef _SC_NL_NMAX
6795 {"SC_NL_NMAX", _SC_NL_NMAX},
6796#endif
6797#ifdef _SC_NL_SETMAX
6798 {"SC_NL_SETMAX", _SC_NL_SETMAX},
6799#endif
6800#ifdef _SC_NL_TEXTMAX
6801 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
6802#endif
6803#ifdef _SC_NPROCESSORS_CONF
6804 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
6805#endif
6806#ifdef _SC_NPROCESSORS_ONLN
6807 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
6808#endif
Fred Draked86ed291999-12-15 15:34:33 +00006809#ifdef _SC_NPROC_CONF
6810 {"SC_NPROC_CONF", _SC_NPROC_CONF},
6811#endif
6812#ifdef _SC_NPROC_ONLN
6813 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
6814#endif
Fred Drakec9680921999-12-13 16:37:25 +00006815#ifdef _SC_NZERO
6816 {"SC_NZERO", _SC_NZERO},
6817#endif
6818#ifdef _SC_OPEN_MAX
6819 {"SC_OPEN_MAX", _SC_OPEN_MAX},
6820#endif
6821#ifdef _SC_PAGESIZE
6822 {"SC_PAGESIZE", _SC_PAGESIZE},
6823#endif
6824#ifdef _SC_PAGE_SIZE
6825 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
6826#endif
6827#ifdef _SC_PASS_MAX
6828 {"SC_PASS_MAX", _SC_PASS_MAX},
6829#endif
6830#ifdef _SC_PHYS_PAGES
6831 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
6832#endif
6833#ifdef _SC_PII
6834 {"SC_PII", _SC_PII},
6835#endif
6836#ifdef _SC_PII_INTERNET
6837 {"SC_PII_INTERNET", _SC_PII_INTERNET},
6838#endif
6839#ifdef _SC_PII_INTERNET_DGRAM
6840 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
6841#endif
6842#ifdef _SC_PII_INTERNET_STREAM
6843 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
6844#endif
6845#ifdef _SC_PII_OSI
6846 {"SC_PII_OSI", _SC_PII_OSI},
6847#endif
6848#ifdef _SC_PII_OSI_CLTS
6849 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
6850#endif
6851#ifdef _SC_PII_OSI_COTS
6852 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
6853#endif
6854#ifdef _SC_PII_OSI_M
6855 {"SC_PII_OSI_M", _SC_PII_OSI_M},
6856#endif
6857#ifdef _SC_PII_SOCKET
6858 {"SC_PII_SOCKET", _SC_PII_SOCKET},
6859#endif
6860#ifdef _SC_PII_XTI
6861 {"SC_PII_XTI", _SC_PII_XTI},
6862#endif
6863#ifdef _SC_POLL
6864 {"SC_POLL", _SC_POLL},
6865#endif
6866#ifdef _SC_PRIORITIZED_IO
6867 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
6868#endif
6869#ifdef _SC_PRIORITY_SCHEDULING
6870 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
6871#endif
6872#ifdef _SC_REALTIME_SIGNALS
6873 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
6874#endif
6875#ifdef _SC_RE_DUP_MAX
6876 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
6877#endif
6878#ifdef _SC_RTSIG_MAX
6879 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
6880#endif
6881#ifdef _SC_SAVED_IDS
6882 {"SC_SAVED_IDS", _SC_SAVED_IDS},
6883#endif
6884#ifdef _SC_SCHAR_MAX
6885 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
6886#endif
6887#ifdef _SC_SCHAR_MIN
6888 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
6889#endif
6890#ifdef _SC_SELECT
6891 {"SC_SELECT", _SC_SELECT},
6892#endif
6893#ifdef _SC_SEMAPHORES
6894 {"SC_SEMAPHORES", _SC_SEMAPHORES},
6895#endif
6896#ifdef _SC_SEM_NSEMS_MAX
6897 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
6898#endif
6899#ifdef _SC_SEM_VALUE_MAX
6900 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
6901#endif
6902#ifdef _SC_SHARED_MEMORY_OBJECTS
6903 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
6904#endif
6905#ifdef _SC_SHRT_MAX
6906 {"SC_SHRT_MAX", _SC_SHRT_MAX},
6907#endif
6908#ifdef _SC_SHRT_MIN
6909 {"SC_SHRT_MIN", _SC_SHRT_MIN},
6910#endif
6911#ifdef _SC_SIGQUEUE_MAX
6912 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
6913#endif
6914#ifdef _SC_SIGRT_MAX
6915 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
6916#endif
6917#ifdef _SC_SIGRT_MIN
6918 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
6919#endif
Fred Draked86ed291999-12-15 15:34:33 +00006920#ifdef _SC_SOFTPOWER
6921 {"SC_SOFTPOWER", _SC_SOFTPOWER},
6922#endif
Fred Drakec9680921999-12-13 16:37:25 +00006923#ifdef _SC_SPLIT_CACHE
6924 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
6925#endif
6926#ifdef _SC_SSIZE_MAX
6927 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
6928#endif
6929#ifdef _SC_STACK_PROT
6930 {"SC_STACK_PROT", _SC_STACK_PROT},
6931#endif
6932#ifdef _SC_STREAM_MAX
6933 {"SC_STREAM_MAX", _SC_STREAM_MAX},
6934#endif
6935#ifdef _SC_SYNCHRONIZED_IO
6936 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
6937#endif
6938#ifdef _SC_THREADS
6939 {"SC_THREADS", _SC_THREADS},
6940#endif
6941#ifdef _SC_THREAD_ATTR_STACKADDR
6942 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
6943#endif
6944#ifdef _SC_THREAD_ATTR_STACKSIZE
6945 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
6946#endif
6947#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
6948 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
6949#endif
6950#ifdef _SC_THREAD_KEYS_MAX
6951 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
6952#endif
6953#ifdef _SC_THREAD_PRIORITY_SCHEDULING
6954 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
6955#endif
6956#ifdef _SC_THREAD_PRIO_INHERIT
6957 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
6958#endif
6959#ifdef _SC_THREAD_PRIO_PROTECT
6960 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
6961#endif
6962#ifdef _SC_THREAD_PROCESS_SHARED
6963 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
6964#endif
6965#ifdef _SC_THREAD_SAFE_FUNCTIONS
6966 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
6967#endif
6968#ifdef _SC_THREAD_STACK_MIN
6969 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
6970#endif
6971#ifdef _SC_THREAD_THREADS_MAX
6972 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
6973#endif
6974#ifdef _SC_TIMERS
6975 {"SC_TIMERS", _SC_TIMERS},
6976#endif
6977#ifdef _SC_TIMER_MAX
6978 {"SC_TIMER_MAX", _SC_TIMER_MAX},
6979#endif
6980#ifdef _SC_TTY_NAME_MAX
6981 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
6982#endif
6983#ifdef _SC_TZNAME_MAX
6984 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
6985#endif
6986#ifdef _SC_T_IOV_MAX
6987 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
6988#endif
6989#ifdef _SC_UCHAR_MAX
6990 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
6991#endif
6992#ifdef _SC_UINT_MAX
6993 {"SC_UINT_MAX", _SC_UINT_MAX},
6994#endif
6995#ifdef _SC_UIO_MAXIOV
6996 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
6997#endif
6998#ifdef _SC_ULONG_MAX
6999 {"SC_ULONG_MAX", _SC_ULONG_MAX},
7000#endif
7001#ifdef _SC_USHRT_MAX
7002 {"SC_USHRT_MAX", _SC_USHRT_MAX},
7003#endif
7004#ifdef _SC_VERSION
7005 {"SC_VERSION", _SC_VERSION},
7006#endif
7007#ifdef _SC_WORD_BIT
7008 {"SC_WORD_BIT", _SC_WORD_BIT},
7009#endif
7010#ifdef _SC_XBS5_ILP32_OFF32
7011 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
7012#endif
7013#ifdef _SC_XBS5_ILP32_OFFBIG
7014 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
7015#endif
7016#ifdef _SC_XBS5_LP64_OFF64
7017 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
7018#endif
7019#ifdef _SC_XBS5_LPBIG_OFFBIG
7020 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
7021#endif
7022#ifdef _SC_XOPEN_CRYPT
7023 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
7024#endif
7025#ifdef _SC_XOPEN_ENH_I18N
7026 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
7027#endif
7028#ifdef _SC_XOPEN_LEGACY
7029 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
7030#endif
7031#ifdef _SC_XOPEN_REALTIME
7032 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
7033#endif
7034#ifdef _SC_XOPEN_REALTIME_THREADS
7035 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
7036#endif
7037#ifdef _SC_XOPEN_SHM
7038 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
7039#endif
7040#ifdef _SC_XOPEN_UNIX
7041 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
7042#endif
7043#ifdef _SC_XOPEN_VERSION
7044 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
7045#endif
7046#ifdef _SC_XOPEN_XCU_VERSION
7047 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
7048#endif
7049#ifdef _SC_XOPEN_XPG2
7050 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
7051#endif
7052#ifdef _SC_XOPEN_XPG3
7053 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
7054#endif
7055#ifdef _SC_XOPEN_XPG4
7056 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
7057#endif
7058};
7059
7060static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007061conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007062{
7063 return conv_confname(arg, valuep, posix_constants_sysconf,
7064 sizeof(posix_constants_sysconf)
7065 / sizeof(struct constdef));
7066}
7067
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007068PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007069"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007070Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007071
7072static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007073posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007074{
7075 PyObject *result = NULL;
7076 int name;
7077
7078 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
7079 int value;
7080
7081 errno = 0;
7082 value = sysconf(name);
7083 if (value == -1 && errno != 0)
7084 posix_error();
7085 else
7086 result = PyInt_FromLong(value);
7087 }
7088 return result;
7089}
7090#endif
7091
7092
Fred Drakebec628d1999-12-15 18:31:10 +00007093/* This code is used to ensure that the tables of configuration value names
7094 * are in sorted order as required by conv_confname(), and also to build the
7095 * the exported dictionaries that are used to publish information about the
7096 * names available on the host platform.
7097 *
7098 * Sorting the table at runtime ensures that the table is properly ordered
7099 * when used, even for platforms we're not able to test on. It also makes
7100 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00007101 */
Fred Drakebec628d1999-12-15 18:31:10 +00007102
7103static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007104cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00007105{
7106 const struct constdef *c1 =
7107 (const struct constdef *) v1;
7108 const struct constdef *c2 =
7109 (const struct constdef *) v2;
7110
7111 return strcmp(c1->name, c2->name);
7112}
7113
7114static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007115setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00007116 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007117{
Fred Drakebec628d1999-12-15 18:31:10 +00007118 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00007119 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00007120
7121 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
7122 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00007123 if (d == NULL)
7124 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007125
Barry Warsaw3155db32000-04-13 15:20:40 +00007126 for (i=0; i < tablesize; ++i) {
7127 PyObject *o = PyInt_FromLong(table[i].value);
7128 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
7129 Py_XDECREF(o);
7130 Py_DECREF(d);
7131 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007132 }
Barry Warsaw3155db32000-04-13 15:20:40 +00007133 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00007134 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00007135 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00007136}
7137
Fred Drakebec628d1999-12-15 18:31:10 +00007138/* Return -1 on failure, 0 on success. */
7139static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007140setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007141{
7142#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00007143 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00007144 sizeof(posix_constants_pathconf)
7145 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007146 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007147 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007148#endif
7149#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00007150 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00007151 sizeof(posix_constants_confstr)
7152 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007153 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007154 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007155#endif
7156#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00007157 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00007158 sizeof(posix_constants_sysconf)
7159 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007160 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007161 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007162#endif
Fred Drakebec628d1999-12-15 18:31:10 +00007163 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00007164}
Fred Draked86ed291999-12-15 15:34:33 +00007165
7166
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007167PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007168"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007169Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007170in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007171
7172static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007173posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007174{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007175 abort();
7176 /*NOTREACHED*/
7177 Py_FatalError("abort() called from Python code didn't abort!");
7178 return NULL;
7179}
Fred Drakebec628d1999-12-15 18:31:10 +00007180
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007181#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007182PyDoc_STRVAR(win32_startfile__doc__,
7183"startfile(filepath) - Start a file with its associated application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007184\n\
7185This acts like double-clicking the file in Explorer, or giving the file\n\
7186name as an argument to the DOS \"start\" command: the file is opened\n\
7187with whatever application (if any) its extension is associated.\n\
7188\n\
7189startfile returns as soon as the associated application is launched.\n\
7190There is no option to wait for the application to close, and no way\n\
7191to retrieve the application's exit status.\n\
7192\n\
7193The filepath is relative to the current directory. If you want to use\n\
7194an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007195the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00007196
7197static PyObject *
7198win32_startfile(PyObject *self, PyObject *args)
7199{
7200 char *filepath;
7201 HINSTANCE rc;
7202 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
7203 return NULL;
7204 Py_BEGIN_ALLOW_THREADS
7205 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
7206 Py_END_ALLOW_THREADS
7207 if (rc <= (HINSTANCE)32)
7208 return win32_error("startfile", filepath);
7209 Py_INCREF(Py_None);
7210 return Py_None;
7211}
7212#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007213
Martin v. Löwis438b5342002-12-27 10:16:42 +00007214#ifdef HAVE_GETLOADAVG
7215PyDoc_STRVAR(posix_getloadavg__doc__,
7216"getloadavg() -> (float, float, float)\n\n\
7217Return the number of processes in the system run queue averaged over\n\
7218the last 1, 5, and 15 minutes or raises OSError if the load average\n\
7219was unobtainable");
7220
7221static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007222posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00007223{
7224 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00007225 if (getloadavg(loadavg, 3)!=3) {
7226 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
7227 return NULL;
7228 } else
7229 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
7230}
7231#endif
7232
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007233#ifdef MS_WINDOWS
7234
7235PyDoc_STRVAR(win32_urandom__doc__,
7236"urandom(n) -> str\n\n\
7237Return a string of n random bytes suitable for cryptographic use.");
7238
7239typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
7240 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
7241 DWORD dwFlags );
7242typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
7243 BYTE *pbBuffer );
7244
7245static CRYPTGENRANDOM pCryptGenRandom = NULL;
7246static HCRYPTPROV hCryptProv = 0;
7247
Tim Peters4ad82172004-08-30 17:02:04 +00007248static PyObject*
7249win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007250{
Tim Petersd3115382004-08-30 17:36:46 +00007251 int howMany;
7252 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007253
Tim Peters4ad82172004-08-30 17:02:04 +00007254 /* Read arguments */
Tim Peters9b279a82004-08-30 17:10:53 +00007255 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
Tim Peters4ad82172004-08-30 17:02:04 +00007256 return NULL;
Tim Peters51eba612004-08-30 17:08:02 +00007257 if (howMany < 0)
7258 return PyErr_Format(PyExc_ValueError,
7259 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007260
Tim Peters4ad82172004-08-30 17:02:04 +00007261 if (hCryptProv == 0) {
7262 HINSTANCE hAdvAPI32 = NULL;
7263 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007264
Tim Peters4ad82172004-08-30 17:02:04 +00007265 /* Obtain handle to the DLL containing CryptoAPI
7266 This should not fail */
7267 hAdvAPI32 = GetModuleHandle("advapi32.dll");
7268 if(hAdvAPI32 == NULL)
7269 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007270
Tim Peters4ad82172004-08-30 17:02:04 +00007271 /* Obtain pointers to the CryptoAPI functions
7272 This will fail on some early versions of Win95 */
7273 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
7274 hAdvAPI32,
7275 "CryptAcquireContextA");
7276 if (pCryptAcquireContext == NULL)
7277 return PyErr_Format(PyExc_NotImplementedError,
7278 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007279
Tim Peters4ad82172004-08-30 17:02:04 +00007280 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
7281 hAdvAPI32, "CryptGenRandom");
7282 if (pCryptAcquireContext == NULL)
7283 return PyErr_Format(PyExc_NotImplementedError,
7284 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007285
Tim Peters4ad82172004-08-30 17:02:04 +00007286 /* Acquire context */
7287 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
7288 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
7289 return win32_error("CryptAcquireContext", NULL);
7290 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007291
Tim Peters4ad82172004-08-30 17:02:04 +00007292 /* Allocate bytes */
Tim Petersd3115382004-08-30 17:36:46 +00007293 result = PyString_FromStringAndSize(NULL, howMany);
7294 if (result != NULL) {
7295 /* Get random data */
7296 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
7297 PyString_AS_STRING(result))) {
7298 Py_DECREF(result);
7299 return win32_error("CryptGenRandom", NULL);
7300 }
Tim Peters4ad82172004-08-30 17:02:04 +00007301 }
Tim Petersd3115382004-08-30 17:36:46 +00007302 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007303}
7304#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007305
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007306static PyMethodDef posix_methods[] = {
7307 {"access", posix_access, METH_VARARGS, posix_access__doc__},
7308#ifdef HAVE_TTYNAME
7309 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
7310#endif
7311 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
7312 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007313#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007314 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007315#endif /* HAVE_CHOWN */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007316#ifdef HAVE_LCHOWN
7317 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
7318#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00007319#ifdef HAVE_CHROOT
7320 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
7321#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007322#ifdef HAVE_CTERMID
Neal Norwitze241ce82003-02-17 18:17:05 +00007323 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007324#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00007325#ifdef HAVE_GETCWD
Neal Norwitze241ce82003-02-17 18:17:05 +00007326 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Walter Dörwald3b918c32002-11-21 20:18:46 +00007327#ifdef Py_USING_UNICODE
Neal Norwitze241ce82003-02-17 18:17:05 +00007328 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00007329#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00007330#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007331#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007332 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007333#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007334 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
7335 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
7336 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007337#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007338 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007339#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007340#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007341 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007342#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007343 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
7344 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
7345 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007346 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007347#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007348 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007349#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007350#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007351 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007352#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007353 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007354#ifdef HAVE_UNAME
Neal Norwitze241ce82003-02-17 18:17:05 +00007355 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007356#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007357 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
7358 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
7359 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007360#ifdef HAVE_TIMES
Neal Norwitze241ce82003-02-17 18:17:05 +00007361 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007362#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007363 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007364#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007365 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
7366 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007367#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00007368#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007369 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
7370 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00007371#if defined(PYOS_OS2)
7372 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
7373 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
7374#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00007375#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007376#ifdef HAVE_FORK1
Neal Norwitze241ce82003-02-17 18:17:05 +00007377 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007378#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007379#ifdef HAVE_FORK
Neal Norwitze241ce82003-02-17 18:17:05 +00007380 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007381#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007382#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Neal Norwitze241ce82003-02-17 18:17:05 +00007383 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007384#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007385#ifdef HAVE_FORKPTY
Neal Norwitze241ce82003-02-17 18:17:05 +00007386 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00007387#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007388#ifdef HAVE_GETEGID
Neal Norwitze241ce82003-02-17 18:17:05 +00007389 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007390#endif /* HAVE_GETEGID */
7391#ifdef HAVE_GETEUID
Neal Norwitze241ce82003-02-17 18:17:05 +00007392 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007393#endif /* HAVE_GETEUID */
7394#ifdef HAVE_GETGID
Neal Norwitze241ce82003-02-17 18:17:05 +00007395 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007396#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00007397#ifdef HAVE_GETGROUPS
Neal Norwitze241ce82003-02-17 18:17:05 +00007398 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007399#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007400 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007401#ifdef HAVE_GETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00007402 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007403#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007404#ifdef HAVE_GETPPID
Neal Norwitze241ce82003-02-17 18:17:05 +00007405 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007406#endif /* HAVE_GETPPID */
7407#ifdef HAVE_GETUID
Neal Norwitze241ce82003-02-17 18:17:05 +00007408 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007409#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007410#ifdef HAVE_GETLOGIN
Neal Norwitze241ce82003-02-17 18:17:05 +00007411 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00007412#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00007413#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007414 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007415#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007416#ifdef HAVE_KILLPG
7417 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
7418#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00007419#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007420 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00007421#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007422#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007423 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007424#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00007425 {"popen2", win32_popen2, METH_VARARGS},
7426 {"popen3", win32_popen3, METH_VARARGS},
7427 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00007428 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007429#else
7430#if defined(PYOS_OS2) && defined(PYCC_GCC)
7431 {"popen2", os2emx_popen2, METH_VARARGS},
7432 {"popen3", os2emx_popen3, METH_VARARGS},
7433 {"popen4", os2emx_popen4, METH_VARARGS},
7434#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00007435#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007436#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007437#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007438 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007439#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007440#ifdef HAVE_SETEUID
7441 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
7442#endif /* HAVE_SETEUID */
7443#ifdef HAVE_SETEGID
7444 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
7445#endif /* HAVE_SETEGID */
7446#ifdef HAVE_SETREUID
7447 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
7448#endif /* HAVE_SETREUID */
7449#ifdef HAVE_SETREGID
7450 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
7451#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007452#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007453 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007454#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007455#ifdef HAVE_SETGROUPS
7456 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
7457#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00007458#ifdef HAVE_GETPGID
7459 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
7460#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007461#ifdef HAVE_SETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00007462 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007463#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007464#ifdef HAVE_WAIT
Neal Norwitze241ce82003-02-17 18:17:05 +00007465 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007466#endif /* HAVE_WAIT */
Tim Petersab034fa2002-02-01 11:27:43 +00007467#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007468 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007469#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007470#ifdef HAVE_GETSID
7471 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
7472#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007473#ifdef HAVE_SETSID
Neal Norwitze241ce82003-02-17 18:17:05 +00007474 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007475#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007476#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007477 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007478#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007479#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007480 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007481#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007482#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007483 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007484#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007485 {"open", posix_open, METH_VARARGS, posix_open__doc__},
7486 {"close", posix_close, METH_VARARGS, posix_close__doc__},
7487 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
7488 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
7489 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
7490 {"read", posix_read, METH_VARARGS, posix_read__doc__},
7491 {"write", posix_write, METH_VARARGS, posix_write__doc__},
7492 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
7493 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00007494 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007495#ifdef HAVE_PIPE
Neal Norwitze241ce82003-02-17 18:17:05 +00007496 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007497#endif
7498#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007499 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007500#endif
Neal Norwitz11690112002-07-30 01:08:28 +00007501#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007502 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
7503#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007504#ifdef HAVE_DEVICE_MACROS
7505 {"major", posix_major, METH_VARARGS, posix_major__doc__},
7506 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
7507 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
7508#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007509#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007510 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007511#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007512#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007513 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007514#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007515#ifdef HAVE_UNSETENV
7516 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
7517#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00007518#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007519 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00007520#endif
Fred Drake4d1e64b2002-04-15 19:40:07 +00007521#ifdef HAVE_FCHDIR
7522 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
7523#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00007524#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007525 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007526#endif
7527#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007528 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007529#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00007530#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00007531#ifdef WCOREDUMP
7532 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
7533#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007534#ifdef WIFCONTINUED
7535 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
7536#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00007537#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007538 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007539#endif /* WIFSTOPPED */
7540#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007541 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007542#endif /* WIFSIGNALED */
7543#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007544 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007545#endif /* WIFEXITED */
7546#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007547 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007548#endif /* WEXITSTATUS */
7549#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007550 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007551#endif /* WTERMSIG */
7552#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007553 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007554#endif /* WSTOPSIG */
7555#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007556#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007557 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007558#endif
7559#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007560 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007561#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00007562#ifdef HAVE_TMPFILE
Neal Norwitze241ce82003-02-17 18:17:05 +00007563 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007564#endif
7565#ifdef HAVE_TEMPNAM
7566 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
7567#endif
7568#ifdef HAVE_TMPNAM
Neal Norwitze241ce82003-02-17 18:17:05 +00007569 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007570#endif
Fred Drakec9680921999-12-13 16:37:25 +00007571#ifdef HAVE_CONFSTR
7572 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
7573#endif
7574#ifdef HAVE_SYSCONF
7575 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
7576#endif
7577#ifdef HAVE_FPATHCONF
7578 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
7579#endif
7580#ifdef HAVE_PATHCONF
7581 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
7582#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007583 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007584#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00007585 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
7586#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007587#ifdef HAVE_GETLOADAVG
Neal Norwitze241ce82003-02-17 18:17:05 +00007588 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00007589#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007590 #ifdef MS_WINDOWS
7591 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
7592 #endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007593 {NULL, NULL} /* Sentinel */
7594};
7595
7596
Barry Warsaw4a342091996-12-19 23:50:02 +00007597static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007598ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00007599{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007600 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00007601}
7602
Guido van Rossumd48f2521997-12-05 22:19:34 +00007603#if defined(PYOS_OS2)
7604/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007605static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007606{
7607 APIRET rc;
7608 ULONG values[QSV_MAX+1];
7609 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00007610 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00007611
7612 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00007613 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007614 Py_END_ALLOW_THREADS
7615
7616 if (rc != NO_ERROR) {
7617 os2_error(rc);
7618 return -1;
7619 }
7620
Fred Drake4d1e64b2002-04-15 19:40:07 +00007621 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
7622 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
7623 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
7624 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
7625 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
7626 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
7627 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007628
7629 switch (values[QSV_VERSION_MINOR]) {
7630 case 0: ver = "2.00"; break;
7631 case 10: ver = "2.10"; break;
7632 case 11: ver = "2.11"; break;
7633 case 30: ver = "3.00"; break;
7634 case 40: ver = "4.00"; break;
7635 case 50: ver = "5.00"; break;
7636 default:
Tim Peters885d4572001-11-28 20:27:42 +00007637 PyOS_snprintf(tmp, sizeof(tmp),
7638 "%d-%d", values[QSV_VERSION_MAJOR],
7639 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007640 ver = &tmp[0];
7641 }
7642
7643 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007644 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007645 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007646
7647 /* Add Indicator of Which Drive was Used to Boot the System */
7648 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
7649 tmp[1] = ':';
7650 tmp[2] = '\0';
7651
Fred Drake4d1e64b2002-04-15 19:40:07 +00007652 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007653}
7654#endif
7655
Barry Warsaw4a342091996-12-19 23:50:02 +00007656static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007657all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00007658{
Guido van Rossum94f6f721999-01-06 18:42:14 +00007659#ifdef F_OK
7660 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007661#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007662#ifdef R_OK
7663 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007664#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007665#ifdef W_OK
7666 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007667#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007668#ifdef X_OK
7669 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007670#endif
Fred Drakec9680921999-12-13 16:37:25 +00007671#ifdef NGROUPS_MAX
7672 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
7673#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007674#ifdef TMP_MAX
7675 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
7676#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007677#ifdef WCONTINUED
7678 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
7679#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007680#ifdef WNOHANG
7681 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007682#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007683#ifdef WUNTRACED
7684 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
7685#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007686#ifdef O_RDONLY
7687 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
7688#endif
7689#ifdef O_WRONLY
7690 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
7691#endif
7692#ifdef O_RDWR
7693 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
7694#endif
7695#ifdef O_NDELAY
7696 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
7697#endif
7698#ifdef O_NONBLOCK
7699 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
7700#endif
7701#ifdef O_APPEND
7702 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
7703#endif
7704#ifdef O_DSYNC
7705 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
7706#endif
7707#ifdef O_RSYNC
7708 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
7709#endif
7710#ifdef O_SYNC
7711 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
7712#endif
7713#ifdef O_NOCTTY
7714 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
7715#endif
7716#ifdef O_CREAT
7717 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
7718#endif
7719#ifdef O_EXCL
7720 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
7721#endif
7722#ifdef O_TRUNC
7723 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
7724#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00007725#ifdef O_BINARY
7726 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
7727#endif
7728#ifdef O_TEXT
7729 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
7730#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007731#ifdef O_LARGEFILE
7732 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
7733#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00007734#ifdef O_SHLOCK
7735 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
7736#endif
7737#ifdef O_EXLOCK
7738 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
7739#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007740
Tim Peters5aa91602002-01-30 05:46:57 +00007741/* MS Windows */
7742#ifdef O_NOINHERIT
7743 /* Don't inherit in child processes. */
7744 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
7745#endif
7746#ifdef _O_SHORT_LIVED
7747 /* Optimize for short life (keep in memory). */
7748 /* MS forgot to define this one with a non-underscore form too. */
7749 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
7750#endif
7751#ifdef O_TEMPORARY
7752 /* Automatically delete when last handle is closed. */
7753 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
7754#endif
7755#ifdef O_RANDOM
7756 /* Optimize for random access. */
7757 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
7758#endif
7759#ifdef O_SEQUENTIAL
7760 /* Optimize for sequential access. */
7761 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
7762#endif
7763
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007764/* GNU extensions. */
7765#ifdef O_DIRECT
7766 /* Direct disk access. */
7767 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
7768#endif
7769#ifdef O_DIRECTORY
7770 /* Must be a directory. */
7771 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
7772#endif
7773#ifdef O_NOFOLLOW
7774 /* Do not follow links. */
7775 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
7776#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00007777
Barry Warsaw5676bd12003-01-07 20:57:09 +00007778 /* These come from sysexits.h */
7779#ifdef EX_OK
7780 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007781#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007782#ifdef EX_USAGE
7783 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007784#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007785#ifdef EX_DATAERR
7786 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007787#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007788#ifdef EX_NOINPUT
7789 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007790#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007791#ifdef EX_NOUSER
7792 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007793#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007794#ifdef EX_NOHOST
7795 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007796#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007797#ifdef EX_UNAVAILABLE
7798 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007799#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007800#ifdef EX_SOFTWARE
7801 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007802#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007803#ifdef EX_OSERR
7804 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007805#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007806#ifdef EX_OSFILE
7807 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007808#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007809#ifdef EX_CANTCREAT
7810 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007811#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007812#ifdef EX_IOERR
7813 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007814#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007815#ifdef EX_TEMPFAIL
7816 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007817#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007818#ifdef EX_PROTOCOL
7819 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007820#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007821#ifdef EX_NOPERM
7822 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007823#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007824#ifdef EX_CONFIG
7825 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007826#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007827#ifdef EX_NOTFOUND
7828 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007829#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007830
Guido van Rossum246bc171999-02-01 23:54:31 +00007831#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007832#if defined(PYOS_OS2) && defined(PYCC_GCC)
7833 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
7834 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
7835 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
7836 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
7837 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
7838 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
7839 if (ins(d, "P_PM", (long)P_PM)) return -1;
7840 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
7841 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
7842 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
7843 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
7844 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
7845 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
7846 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
7847 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
7848 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
7849 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
7850 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
7851 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
7852 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
7853#else
Guido van Rossum7d385291999-02-16 19:38:04 +00007854 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
7855 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
7856 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
7857 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
7858 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00007859#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007860#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00007861
Guido van Rossumd48f2521997-12-05 22:19:34 +00007862#if defined(PYOS_OS2)
7863 if (insertvalues(d)) return -1;
7864#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007865 return 0;
7866}
7867
7868
Tim Peters5aa91602002-01-30 05:46:57 +00007869#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007870#define INITFUNC initnt
7871#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007872
7873#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007874#define INITFUNC initos2
7875#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007876
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007877#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007878#define INITFUNC initposix
7879#define MODNAME "posix"
7880#endif
7881
Mark Hammondfe51c6d2002-08-02 02:27:13 +00007882PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007883INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00007884{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007885 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00007886
Fred Drake4d1e64b2002-04-15 19:40:07 +00007887 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007888 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00007889 posix__doc__);
Tim Peters5aa91602002-01-30 05:46:57 +00007890
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007891 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007892 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00007893 Py_XINCREF(v);
7894 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007895 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00007896 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00007897
Fred Drake4d1e64b2002-04-15 19:40:07 +00007898 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00007899 return;
7900
Fred Drake4d1e64b2002-04-15 19:40:07 +00007901 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00007902 return;
7903
Fred Drake4d1e64b2002-04-15 19:40:07 +00007904 Py_INCREF(PyExc_OSError);
7905 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00007906
Guido van Rossumb3d39562000-01-31 18:41:26 +00007907#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00007908 if (posix_putenv_garbage == NULL)
7909 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00007910#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007911
Guido van Rossum14648392001-12-08 18:02:58 +00007912 stat_result_desc.name = MODNAME ".stat_result";
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007913 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
7914 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
7915 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007916 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007917 structseq_new = StatResultType.tp_new;
7918 StatResultType.tp_new = statresult_new;
Fred Drake4d1e64b2002-04-15 19:40:07 +00007919 Py_INCREF((PyObject*) &StatResultType);
7920 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007921
Guido van Rossum14648392001-12-08 18:02:58 +00007922 statvfs_result_desc.name = MODNAME ".statvfs_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007923 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Fred Drake4d1e64b2002-04-15 19:40:07 +00007924 Py_INCREF((PyObject*) &StatVFSResultType);
7925 PyModule_AddObject(m, "statvfs_result",
7926 (PyObject*) &StatVFSResultType);
Guido van Rossumb6775db1994-08-01 11:34:53 +00007927}