blob: 599d88a380a15a2ed972e6f7574c130954c0bf5e [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
Guido van Rossuma4916fa1996-05-23 22:58:55 +000070/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +000071/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000072#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000073#include <process.h>
74#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +000075#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000076#define HAVE_GETCWD 1
77#define HAVE_OPENDIR 1
78#define HAVE_SYSTEM 1
79#if defined(__OS2__)
80#define HAVE_EXECV 1
81#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +000082#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000083#include <process.h>
84#else
85#ifdef __BORLANDC__ /* Borland compiler */
86#define HAVE_EXECV 1
87#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +000088#define HAVE_OPENDIR 1
89#define HAVE_PIPE 1
90#define HAVE_POPEN 1
91#define HAVE_SYSTEM 1
92#define HAVE_WAIT 1
93#else
94#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +000095#define HAVE_GETCWD 1
Guido van Rossuma1065681999-01-25 23:20:23 +000096#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +000097#define HAVE_EXECV 1
98#define HAVE_PIPE 1
99#define HAVE_POPEN 1
100#define HAVE_SYSTEM 1
Tim Petersab034fa2002-02-01 11:27:43 +0000101#define HAVE_CWAIT 1
Tim Peters11b23062003-04-23 02:39:17 +0000102#define HAVE_FSYNC 1
103#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000104#else
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000105#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
106/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000107#else /* all other compilers */
108/* Unix functions that the configure script doesn't check for */
109#define HAVE_EXECV 1
110#define HAVE_FORK 1
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000111#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
112#define HAVE_FORK1 1
113#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000114#define HAVE_GETCWD 1
115#define HAVE_GETEGID 1
116#define HAVE_GETEUID 1
117#define HAVE_GETGID 1
118#define HAVE_GETPPID 1
119#define HAVE_GETUID 1
120#define HAVE_KILL 1
121#define HAVE_OPENDIR 1
122#define HAVE_PIPE 1
Martin v. Löwis212ede62003-09-20 11:20:30 +0000123#ifndef __rtems__
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000124#define HAVE_POPEN 1
Martin v. Löwis212ede62003-09-20 11:20:30 +0000125#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000126#define HAVE_SYSTEM 1
127#define HAVE_WAIT 1
Guido van Rossumd371ff11999-01-25 16:12:23 +0000128#define HAVE_TTYNAME 1
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000129#endif /* PYOS_OS2 && PYCC_GCC && __VMS */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000130#endif /* _MSC_VER */
131#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000132#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000133#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000134
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000135#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000136
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000137#if defined(__sgi)&&_COMPILER_VERSION>=700
138/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
139 (default) */
140extern char *ctermid_r(char *);
141#endif
142
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000143#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000144#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000145extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000146#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000147#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000148extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000149#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000150extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000151#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000152#endif
153#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000154extern int chdir(char *);
155extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000156#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000157extern int chdir(const char *);
158extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000159#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000160#ifdef __BORLANDC__
161extern int chmod(const char *, int);
162#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000163extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000164#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000165extern int chown(const char *, uid_t, gid_t);
166extern char *getcwd(char *, int);
167extern char *strerror(int);
168extern int link(const char *, const char *);
169extern int rename(const char *, const char *);
170extern int stat(const char *, struct stat *);
171extern int unlink(const char *);
172extern int pclose(FILE *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000173#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000174extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000175#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000176#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000177extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000178#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000179#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000180
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000181#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000182
Guido van Rossumb6775db1994-08-01 11:34:53 +0000183#ifdef HAVE_UTIME_H
184#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000185#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000186
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000187#ifdef HAVE_SYS_UTIME_H
188#include <sys/utime.h>
189#define HAVE_UTIME_H /* pretend we do for the rest of this file */
190#endif /* HAVE_SYS_UTIME_H */
191
Guido van Rossumb6775db1994-08-01 11:34:53 +0000192#ifdef HAVE_SYS_TIMES_H
193#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000194#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000195
196#ifdef HAVE_SYS_PARAM_H
197#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000198#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000199
200#ifdef HAVE_SYS_UTSNAME_H
201#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000202#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000203
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000204#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000205#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000206#define NAMLEN(dirent) strlen((dirent)->d_name)
207#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000208#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000209#include <direct.h>
210#define NAMLEN(dirent) strlen((dirent)->d_name)
211#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000212#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000213#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000214#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000215#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000216#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000217#endif
218#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000219#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000220#endif
221#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000222#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000223#endif
224#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000225
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000226#ifdef _MSC_VER
Guido van Rossumb6775db1994-08-01 11:34:53 +0000227#include <direct.h>
228#include <io.h>
229#include <process.h>
Tim Petersbc2e10e2002-03-03 23:17:02 +0000230#include "osdefs.h"
Tim Petersee66d0c2002-07-15 16:10:55 +0000231#define WIN32_LEAN_AND_MEAN
Guido van Rossumb6775db1994-08-01 11:34:53 +0000232#include <windows.h>
Tim Petersee66d0c2002-07-15 16:10:55 +0000233#include <shellapi.h> /* for ShellExecute() */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000234#define popen _popen
Guido van Rossum794d8131994-08-23 13:48:48 +0000235#define pclose _pclose
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000236#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000237
Guido van Rossumd48f2521997-12-05 22:19:34 +0000238#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000239#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000240#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000241
Tim Petersbc2e10e2002-03-03 23:17:02 +0000242#ifndef MAXPATHLEN
243#define MAXPATHLEN 1024
244#endif /* MAXPATHLEN */
245
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000246#ifdef UNION_WAIT
247/* Emulate some macros on systems that have a union instead of macros */
248
249#ifndef WIFEXITED
250#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
251#endif
252
253#ifndef WEXITSTATUS
254#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
255#endif
256
257#ifndef WTERMSIG
258#define WTERMSIG(u_wait) ((u_wait).w_termsig)
259#endif
260
261#endif /* UNION_WAIT */
262
Greg Wardb48bc172000-03-01 21:51:56 +0000263/* Don't use the "_r" form if we don't need it (also, won't have a
264 prototype for it, at least on Solaris -- maybe others as well?). */
265#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
266#define USE_CTERMID_R
267#endif
268
269#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
270#define USE_TMPNAM_R
271#endif
272
Fred Drake699f3522000-06-29 21:12:41 +0000273/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000274#undef STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000275#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +0000276# define STAT _stati64
277# define FSTAT _fstati64
278# define STRUCT_STAT struct _stati64
279#else
280# define STAT stat
281# define FSTAT fstat
282# define STRUCT_STAT struct stat
283#endif
284
Tim Peters11b23062003-04-23 02:39:17 +0000285#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000286#include <sys/mkdev.h>
287#else
288#if defined(MAJOR_IN_SYSMACROS)
289#include <sys/sysmacros.h>
290#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000291#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
292#include <sys/mkdev.h>
293#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000294#endif
Fred Drake699f3522000-06-29 21:12:41 +0000295
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000296/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000297#ifdef WITH_NEXT_FRAMEWORK
298/* On Darwin/MacOSX a shared library or framework has no access to
299** environ directly, we must obtain it with _NSGetEnviron().
300*/
301#include <crt_externs.h>
302static char **environ;
303#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000304extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000305#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000306
Barry Warsaw53699e91996-12-10 23:23:01 +0000307static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000308convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000309{
Barry Warsaw53699e91996-12-10 23:23:01 +0000310 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000311 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000312 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000313 if (d == NULL)
314 return NULL;
Jack Jansenea0c3822002-08-01 21:57:49 +0000315#ifdef WITH_NEXT_FRAMEWORK
316 if (environ == NULL)
317 environ = *_NSGetEnviron();
318#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000319 if (environ == NULL)
320 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000321 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000322 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000323 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000324 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000325 char *p = strchr(*e, '=');
326 if (p == NULL)
327 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000328 k = PyString_FromStringAndSize(*e, (int)(p-*e));
329 if (k == NULL) {
330 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000331 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000332 }
333 v = PyString_FromString(p+1);
334 if (v == NULL) {
335 PyErr_Clear();
336 Py_DECREF(k);
337 continue;
338 }
339 if (PyDict_GetItem(d, k) == NULL) {
340 if (PyDict_SetItem(d, k, v) != 0)
341 PyErr_Clear();
342 }
343 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000344 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000345 }
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000346#if defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000347 {
348 APIRET rc;
349 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
350
351 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000352 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000353 PyObject *v = PyString_FromString(buffer);
354 PyDict_SetItemString(d, "BEGINLIBPATH", v);
355 Py_DECREF(v);
356 }
357 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
358 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
359 PyObject *v = PyString_FromString(buffer);
360 PyDict_SetItemString(d, "ENDLIBPATH", v);
361 Py_DECREF(v);
362 }
363 }
364#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000365 return d;
366}
367
368
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000369/* Set a POSIX-specific error from errno, and return NULL */
370
Barry Warsawd58d7641998-07-23 16:14:40 +0000371static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000372posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000373{
Barry Warsawca74da41999-02-09 19:31:45 +0000374 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000375}
Barry Warsawd58d7641998-07-23 16:14:40 +0000376static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000377posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000378{
Barry Warsawca74da41999-02-09 19:31:45 +0000379 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000380}
381
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000382#ifdef Py_WIN_WIDE_FILENAMES
383static PyObject *
384posix_error_with_unicode_filename(Py_UNICODE* name)
385{
386 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
387}
388#endif /* Py_WIN_WIDE_FILENAMES */
389
390
Mark Hammondef8b6542001-05-13 08:04:26 +0000391static PyObject *
392posix_error_with_allocated_filename(char* name)
393{
394 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
395 PyMem_Free(name);
396 return rc;
397}
398
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000399#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000400static PyObject *
401win32_error(char* function, char* filename)
402{
Mark Hammond33a6da92000-08-15 00:46:38 +0000403 /* XXX We should pass the function name along in the future.
404 (_winreg.c also wants to pass the function name.)
Tim Peters5aa91602002-01-30 05:46:57 +0000405 This would however require an additional param to the
Mark Hammond33a6da92000-08-15 00:46:38 +0000406 Windows error object, which is non-trivial.
407 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000408 errno = GetLastError();
409 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000410 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000411 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000412 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000413}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000414
415#ifdef Py_WIN_WIDE_FILENAMES
416static PyObject *
417win32_error_unicode(char* function, Py_UNICODE* filename)
418{
419 /* XXX - see win32_error for comments on 'function' */
420 errno = GetLastError();
421 if (filename)
422 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
423 else
424 return PyErr_SetFromWindowsErr(errno);
425}
426
427static PyObject *_PyUnicode_FromFileSystemEncodedObject(register PyObject *obj)
428{
429 /* XXX Perhaps we should make this API an alias of
430 PyObject_Unicode() instead ?! */
431 if (PyUnicode_CheckExact(obj)) {
432 Py_INCREF(obj);
433 return obj;
434 }
435 if (PyUnicode_Check(obj)) {
436 /* For a Unicode subtype that's not a Unicode object,
437 return a true Unicode object with the same data. */
438 return PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(obj),
439 PyUnicode_GET_SIZE(obj));
440 }
Tim Peters11b23062003-04-23 02:39:17 +0000441 return PyUnicode_FromEncodedObject(obj,
442 Py_FileSystemDefaultEncoding,
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000443 "strict");
444}
445
446#endif /* Py_WIN_WIDE_FILENAMES */
447
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000448#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000449
Guido van Rossumd48f2521997-12-05 22:19:34 +0000450#if defined(PYOS_OS2)
451/**********************************************************************
452 * Helper Function to Trim and Format OS/2 Messages
453 **********************************************************************/
454 static void
455os2_formatmsg(char *msgbuf, int msglen, char *reason)
456{
457 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
458
459 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
460 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
461
462 while (lastc > msgbuf && isspace(*lastc))
463 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
464 }
465
466 /* Add Optional Reason Text */
467 if (reason) {
468 strcat(msgbuf, " : ");
469 strcat(msgbuf, reason);
470 }
471}
472
473/**********************************************************************
474 * Decode an OS/2 Operating System Error Code
475 *
476 * A convenience function to lookup an OS/2 error code and return a
477 * text message we can use to raise a Python exception.
478 *
479 * Notes:
480 * The messages for errors returned from the OS/2 kernel reside in
481 * the file OSO001.MSG in the \OS2 directory hierarchy.
482 *
483 **********************************************************************/
484 static char *
485os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
486{
487 APIRET rc;
488 ULONG msglen;
489
490 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
491 Py_BEGIN_ALLOW_THREADS
492 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
493 errorcode, "oso001.msg", &msglen);
494 Py_END_ALLOW_THREADS
495
496 if (rc == NO_ERROR)
497 os2_formatmsg(msgbuf, msglen, reason);
498 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000499 PyOS_snprintf(msgbuf, msgbuflen,
Tim Peters885d4572001-11-28 20:27:42 +0000500 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000501
502 return msgbuf;
503}
504
505/* Set an OS/2-specific error and return NULL. OS/2 kernel
506 errors are not in a global variable e.g. 'errno' nor are
507 they congruent with posix error numbers. */
508
509static PyObject * os2_error(int code)
510{
511 char text[1024];
512 PyObject *v;
513
514 os2_strerror(text, sizeof(text), code, "");
515
516 v = Py_BuildValue("(is)", code, text);
517 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000518 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000519 Py_DECREF(v);
520 }
521 return NULL; /* Signal to Python that an Exception is Pending */
522}
523
524#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000525
526/* POSIX generic methods */
527
Barry Warsaw53699e91996-12-10 23:23:01 +0000528static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000529posix_fildes(PyObject *fdobj, int (*func)(int))
530{
531 int fd;
532 int res;
533 fd = PyObject_AsFileDescriptor(fdobj);
534 if (fd < 0)
535 return NULL;
536 Py_BEGIN_ALLOW_THREADS
537 res = (*func)(fd);
538 Py_END_ALLOW_THREADS
539 if (res < 0)
540 return posix_error();
541 Py_INCREF(Py_None);
542 return Py_None;
543}
Guido van Rossum21142a01999-01-08 21:05:37 +0000544
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000545#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters11b23062003-04-23 02:39:17 +0000546static int
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000547unicode_file_names(void)
548{
549 static int canusewide = -1;
550 if (canusewide == -1) {
Tim Peters11b23062003-04-23 02:39:17 +0000551 /* As per doc for ::GetVersion(), this is the correct test for
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000552 the Windows NT family. */
553 canusewide = (GetVersion() < 0x80000000) ? 1 : 0;
554 }
555 return canusewide;
556}
557#endif
Tim Peters11b23062003-04-23 02:39:17 +0000558
Guido van Rossum21142a01999-01-08 21:05:37 +0000559static PyObject *
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000560posix_1str(PyObject *args, char *format, int (*func)(const char*),
561 char *wformat, int (*wfunc)(const Py_UNICODE*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000562{
Mark Hammondef8b6542001-05-13 08:04:26 +0000563 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000564 int res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000565#ifdef Py_WIN_WIDE_FILENAMES
566 if (unicode_file_names()) {
567 PyUnicodeObject *po;
568 if (PyArg_ParseTuple(args, wformat, &po)) {
569 Py_BEGIN_ALLOW_THREADS
570 /* PyUnicode_AS_UNICODE OK without thread
571 lock as it is a simple dereference. */
572 res = (*wfunc)(PyUnicode_AS_UNICODE(po));
573 Py_END_ALLOW_THREADS
574 if (res < 0)
Mark Hammondd3890362002-10-03 07:24:48 +0000575 return posix_error_with_unicode_filename(PyUnicode_AS_UNICODE(po));
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000576 Py_INCREF(Py_None);
577 return Py_None;
578 }
579 /* Drop the argument parsing error as narrow
580 strings are also valid. */
581 PyErr_Clear();
582 }
583#else
584 /* Platforms that don't support Unicode filenames
585 shouldn't be passing these extra params */
586 assert(wformat==NULL && wfunc == NULL);
587#endif
588
Tim Peters5aa91602002-01-30 05:46:57 +0000589 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000590 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000591 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000592 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000593 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000594 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000595 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000596 return posix_error_with_allocated_filename(path1);
597 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000598 Py_INCREF(Py_None);
599 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000600}
601
Barry Warsaw53699e91996-12-10 23:23:01 +0000602static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000603posix_2str(PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000604 char *format,
605 int (*func)(const char *, const char *),
606 char *wformat,
607 int (*wfunc)(const Py_UNICODE *, const Py_UNICODE *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000608{
Mark Hammondef8b6542001-05-13 08:04:26 +0000609 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000610 int res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000611#ifdef Py_WIN_WIDE_FILENAMES
612 if (unicode_file_names()) {
613 PyObject *po1;
614 PyObject *po2;
615 if (PyArg_ParseTuple(args, wformat, &po1, &po2)) {
616 if (PyUnicode_Check(po1) || PyUnicode_Check(po2)) {
617 PyObject *wpath1;
618 PyObject *wpath2;
619 wpath1 = _PyUnicode_FromFileSystemEncodedObject(po1);
620 wpath2 = _PyUnicode_FromFileSystemEncodedObject(po2);
621 if (!wpath1 || !wpath2) {
622 Py_XDECREF(wpath1);
623 Py_XDECREF(wpath2);
624 return NULL;
625 }
626 Py_BEGIN_ALLOW_THREADS
627 /* PyUnicode_AS_UNICODE OK without thread
628 lock as it is a simple dereference. */
629 res = (*wfunc)(PyUnicode_AS_UNICODE(wpath1),
630 PyUnicode_AS_UNICODE(wpath2));
631 Py_END_ALLOW_THREADS
632 Py_XDECREF(wpath1);
633 Py_XDECREF(wpath2);
634 if (res != 0)
635 return posix_error();
636 Py_INCREF(Py_None);
637 return Py_None;
638 }
639 /* Else flow through as neither is Unicode. */
640 }
641 /* Drop the argument parsing error as narrow
642 strings are also valid. */
643 PyErr_Clear();
644 }
645#else
646 /* Platforms that don't support Unicode filenames
647 shouldn't be passing these extra params */
648 assert(wformat==NULL && wfunc == NULL);
649#endif
650
Mark Hammondef8b6542001-05-13 08:04:26 +0000651 if (!PyArg_ParseTuple(args, format,
Tim Peters5aa91602002-01-30 05:46:57 +0000652 Py_FileSystemDefaultEncoding, &path1,
Mark Hammondef8b6542001-05-13 08:04:26 +0000653 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000654 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000655 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000656 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000657 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000658 PyMem_Free(path1);
659 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000660 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000661 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000662 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000663 Py_INCREF(Py_None);
664 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000665}
666
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000667PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000668"stat_result: Result from stat or lstat.\n\n\
669This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +0000670 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000671or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
672\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000673Posix/windows: If your platform supports st_blksize, st_blocks, or st_rdev,\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000674they are available as attributes only.\n\
675\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000676See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000677
678static PyStructSequence_Field stat_result_fields[] = {
679 {"st_mode", "protection bits"},
680 {"st_ino", "inode"},
681 {"st_dev", "device"},
682 {"st_nlink", "number of hard links"},
683 {"st_uid", "user ID of owner"},
684 {"st_gid", "group ID of owner"},
685 {"st_size", "total size, in bytes"},
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000686 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
687 {NULL, "integer time of last access"},
688 {NULL, "integer time of last modification"},
689 {NULL, "integer time of last change"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000690 {"st_atime", "time of last access"},
691 {"st_mtime", "time of last modification"},
692 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000693#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000694 {"st_blksize", "blocksize for filesystem I/O"},
695#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000696#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000697 {"st_blocks", "number of blocks allocated"},
698#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000699#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000700 {"st_rdev", "device type (if inode device)"},
701#endif
702 {0}
703};
704
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000705#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000706#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000707#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000708#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000709#endif
710
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000711#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000712#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
713#else
714#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
715#endif
716
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000717#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000718#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
719#else
720#define ST_RDEV_IDX ST_BLOCKS_IDX
721#endif
722
723static PyStructSequence_Desc stat_result_desc = {
724 "stat_result", /* name */
725 stat_result__doc__, /* doc */
726 stat_result_fields,
727 10
728};
729
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000730PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000731"statvfs_result: Result from statvfs or fstatvfs.\n\n\
732This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +0000733 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000734or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000735\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000736See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000737
738static PyStructSequence_Field statvfs_result_fields[] = {
739 {"f_bsize", },
740 {"f_frsize", },
741 {"f_blocks", },
742 {"f_bfree", },
743 {"f_bavail", },
744 {"f_files", },
745 {"f_ffree", },
746 {"f_favail", },
747 {"f_flag", },
748 {"f_namemax",},
749 {0}
750};
751
752static PyStructSequence_Desc statvfs_result_desc = {
753 "statvfs_result", /* name */
754 statvfs_result__doc__, /* doc */
755 statvfs_result_fields,
756 10
757};
758
759static PyTypeObject StatResultType;
760static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000761static newfunc structseq_new;
762
763static PyObject *
764statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
765{
766 PyStructSequence *result;
767 int i;
768
769 result = (PyStructSequence*)structseq_new(type, args, kwds);
770 if (!result)
771 return NULL;
772 /* If we have been initialized from a tuple,
773 st_?time might be set to None. Initialize it
774 from the int slots. */
775 for (i = 7; i <= 9; i++) {
776 if (result->ob_item[i+3] == Py_None) {
777 Py_DECREF(Py_None);
778 Py_INCREF(result->ob_item[i]);
779 result->ob_item[i+3] = result->ob_item[i];
780 }
781 }
782 return (PyObject*)result;
783}
784
785
786
787/* If true, st_?time is float. */
788static int _stat_float_times = 0;
789
790PyDoc_STRVAR(stat_float_times__doc__,
791"stat_float_times([newval]) -> oldval\n\n\
792Determine whether os.[lf]stat represents time stamps as float objects.\n\
793If newval is True, future calls to stat() return floats, if it is False,\n\
794future calls return ints. \n\
795If newval is omitted, return the current setting.\n");
796
797static PyObject*
798stat_float_times(PyObject* self, PyObject *args)
799{
800 int newval = -1;
801 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
802 return NULL;
803 if (newval == -1)
804 /* Return old value */
805 return PyBool_FromLong(_stat_float_times);
806 _stat_float_times = newval;
807 Py_INCREF(Py_None);
808 return Py_None;
809}
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000810
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000811static void
812fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
813{
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000814 PyObject *fval,*ival;
815#if SIZEOF_TIME_T > SIZEOF_LONG
Martin v. Löwisb9a0f912003-03-29 10:06:18 +0000816 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000817#else
818 ival = PyInt_FromLong((long)sec);
819#endif
820 if (_stat_float_times) {
821 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
822 } else {
823 fval = ival;
824 Py_INCREF(fval);
825 }
826 PyStructSequence_SET_ITEM(v, index, ival);
827 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000828}
829
Tim Peters5aa91602002-01-30 05:46:57 +0000830/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +0000831 (used by posix_stat() and posix_fstat()) */
832static PyObject*
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000833_pystat_fromstructstat(STRUCT_STAT st)
Fred Drake699f3522000-06-29 21:12:41 +0000834{
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000835 unsigned long ansec, mnsec, cnsec;
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000836 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +0000837 if (v == NULL)
838 return NULL;
839
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000840 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st.st_mode));
Fred Drake699f3522000-06-29 21:12:41 +0000841#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +0000842 PyStructSequence_SET_ITEM(v, 1,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +0000843 PyLong_FromLongLong((PY_LONG_LONG)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +0000844#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000845 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +0000846#endif
847#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +0000848 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +0000849 PyLong_FromLongLong((PY_LONG_LONG)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +0000850#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000851 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +0000852#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000853 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st.st_nlink));
854 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st.st_uid));
855 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st.st_gid));
Fred Drake699f3522000-06-29 21:12:41 +0000856#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +0000857 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +0000858 PyLong_FromLongLong((PY_LONG_LONG)st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +0000859#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000860 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +0000861#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000862
863#ifdef HAVE_STAT_TV_NSEC
864 ansec = st.st_atim.tv_nsec;
865 mnsec = st.st_mtim.tv_nsec;
866 cnsec = st.st_ctim.tv_nsec;
Fred Drake699f3522000-06-29 21:12:41 +0000867#else
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000868 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000869#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000870 fill_time(v, 7, st.st_atime, ansec);
871 fill_time(v, 8, st.st_mtime, mnsec);
872 fill_time(v, 9, st.st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000873
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000874#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +0000875 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000876 PyInt_FromLong((long)st.st_blksize));
877#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000878#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +0000879 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000880 PyInt_FromLong((long)st.st_blocks));
881#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000882#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000883 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
884 PyInt_FromLong((long)st.st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +0000885#endif
886
887 if (PyErr_Occurred()) {
888 Py_DECREF(v);
889 return NULL;
890 }
891
892 return v;
893}
894
Martin v. Löwisd8948722004-06-02 09:57:56 +0000895#ifdef MS_WINDOWS
896
897/* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
898 where / can be used in place of \ and the trailing slash is optional.
899 Both SERVER and SHARE must have at least one character.
900*/
901
902#define ISSLASHA(c) ((c) == '\\' || (c) == '/')
903#define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
904#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
905
906static BOOL
907IsUNCRootA(char *path, int pathlen)
908{
909 #define ISSLASH ISSLASHA
910
911 int i, share;
912
913 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
914 /* minimum UNCRoot is \\x\y */
915 return FALSE;
916 for (i = 2; i < pathlen ; i++)
917 if (ISSLASH(path[i])) break;
918 if (i == 2 || i == pathlen)
919 /* do not allow \\\SHARE or \\SERVER */
920 return FALSE;
921 share = i+1;
922 for (i = share; i < pathlen; i++)
923 if (ISSLASH(path[i])) break;
924 return (i != share && (i == pathlen || i == pathlen-1));
925
926 #undef ISSLASH
927}
928
929#ifdef Py_WIN_WIDE_FILENAMES
930static BOOL
931IsUNCRootW(Py_UNICODE *path, int pathlen)
932{
933 #define ISSLASH ISSLASHW
934
935 int i, share;
936
937 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
938 /* minimum UNCRoot is \\x\y */
939 return FALSE;
940 for (i = 2; i < pathlen ; i++)
941 if (ISSLASH(path[i])) break;
942 if (i == 2 || i == pathlen)
943 /* do not allow \\\SHARE or \\SERVER */
944 return FALSE;
945 share = i+1;
946 for (i = share; i < pathlen; i++)
947 if (ISSLASH(path[i])) break;
948 return (i != share && (i == pathlen || i == pathlen-1));
949
950 #undef ISSLASH
951}
952#endif /* Py_WIN_WIDE_FILENAMES */
953#endif /* MS_WINDOWS */
954
Barry Warsaw53699e91996-12-10 23:23:01 +0000955static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000956posix_do_stat(PyObject *self, PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000957 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000958#ifdef __VMS
959 int (*statfunc)(const char *, STRUCT_STAT *, ...),
960#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000961 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000962#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000963 char *wformat,
964 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000965{
Fred Drake699f3522000-06-29 21:12:41 +0000966 STRUCT_STAT st;
Tim Peters500bd032001-12-19 19:05:01 +0000967 char *path = NULL; /* pass this to stat; do not free() it */
968 char *pathfree = NULL; /* this memory must be free'd */
Guido van Rossumff4949e1992-08-05 19:58:53 +0000969 int res;
Guido van Rossumace88ae2000-04-21 18:54:45 +0000970
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000971#ifdef MS_WINDOWS
Tim Peters500bd032001-12-19 19:05:01 +0000972 int pathlen;
973 char pathcopy[MAX_PATH];
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000974#endif /* MS_WINDOWS */
Guido van Rossumace88ae2000-04-21 18:54:45 +0000975
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000976
977#ifdef Py_WIN_WIDE_FILENAMES
978 /* If on wide-character-capable OS see if argument
979 is Unicode and if so use wide API. */
980 if (unicode_file_names()) {
981 PyUnicodeObject *po;
982 if (PyArg_ParseTuple(args, wformat, &po)) {
983 Py_UNICODE wpath[MAX_PATH+1];
984 pathlen = wcslen(PyUnicode_AS_UNICODE(po));
985 /* the library call can blow up if the file name is too long! */
986 if (pathlen > MAX_PATH) {
987 errno = ENAMETOOLONG;
988 return posix_error();
989 }
990 wcscpy(wpath, PyUnicode_AS_UNICODE(po));
991 /* Remove trailing slash or backslash, unless it's the current
992 drive root (/ or \) or a specific drive's root (like c:\ or c:/).
993 */
Martin v. Löwisd8948722004-06-02 09:57:56 +0000994 if (pathlen > 0) {
995 if (ISSLASHW(wpath[pathlen-1])) {
996 /* It does end with a slash -- exempt the root drive cases. */
997 if (pathlen == 1 || (pathlen == 3 && wpath[1] == L':') ||
998 IsUNCRootW(wpath, pathlen))
999 /* leave it alone */;
1000 else {
1001 /* nuke the trailing backslash */
1002 wpath[pathlen-1] = L'\0';
1003 }
1004 }
1005 else if (ISSLASHW(wpath[1]) && pathlen < ARRAYSIZE(wpath)-1 &&
1006 IsUNCRootW(wpath, pathlen)) {
1007 /* UNC root w/o trailing slash: add one when there's room */
1008 wpath[pathlen++] = L'\\';
1009 wpath[pathlen] = L'\0';
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001010 }
1011 }
1012 Py_BEGIN_ALLOW_THREADS
1013 /* PyUnicode_AS_UNICODE result OK without
1014 thread lock as it is a simple dereference. */
1015 res = wstatfunc(wpath, &st);
1016 Py_END_ALLOW_THREADS
1017 if (res != 0)
1018 return posix_error_with_unicode_filename(wpath);
1019 return _pystat_fromstructstat(st);
1020 }
1021 /* Drop the argument parsing error as narrow strings
1022 are also valid. */
1023 PyErr_Clear();
1024 }
1025#endif
1026
Tim Peters5aa91602002-01-30 05:46:57 +00001027 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +00001028 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001029 return NULL;
Tim Peters500bd032001-12-19 19:05:01 +00001030 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +00001031
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001032#ifdef MS_WINDOWS
Guido van Rossumace88ae2000-04-21 18:54:45 +00001033 pathlen = strlen(path);
1034 /* the library call can blow up if the file name is too long! */
1035 if (pathlen > MAX_PATH) {
Tim Peters500bd032001-12-19 19:05:01 +00001036 PyMem_Free(pathfree);
Guido van Rossumace88ae2000-04-21 18:54:45 +00001037 errno = ENAMETOOLONG;
1038 return posix_error();
1039 }
1040
Tim Peters500bd032001-12-19 19:05:01 +00001041 /* Remove trailing slash or backslash, unless it's the current
1042 drive root (/ or \) or a specific drive's root (like c:\ or c:/).
1043 */
Martin v. Löwisd8948722004-06-02 09:57:56 +00001044 if (pathlen > 0) {
1045 if (ISSLASHA(path[pathlen-1])) {
1046 /* It does end with a slash -- exempt the root drive cases. */
1047 if (pathlen == 1 || (pathlen == 3 && path[1] == ':') ||
1048 IsUNCRootA(path, pathlen))
1049 /* leave it alone */;
1050 else {
1051 /* nuke the trailing backslash */
1052 strncpy(pathcopy, path, pathlen);
1053 pathcopy[pathlen-1] = '\0';
1054 path = pathcopy;
1055 }
1056 }
1057 else if (ISSLASHA(path[1]) && pathlen < ARRAYSIZE(pathcopy)-1 &&
1058 IsUNCRootA(path, pathlen)) {
1059 /* UNC root w/o trailing slash: add one when there's room */
Guido van Rossumace88ae2000-04-21 18:54:45 +00001060 strncpy(pathcopy, path, pathlen);
Martin v. Löwisd8948722004-06-02 09:57:56 +00001061 pathcopy[pathlen++] = '\\';
1062 pathcopy[pathlen] = '\0';
Guido van Rossumace88ae2000-04-21 18:54:45 +00001063 path = pathcopy;
1064 }
1065 }
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001066#endif /* MS_WINDOWS */
Guido van Rossumace88ae2000-04-21 18:54:45 +00001067
Barry Warsaw53699e91996-12-10 23:23:01 +00001068 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001069 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00001070 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001071 if (res != 0)
Tim Peters500bd032001-12-19 19:05:01 +00001072 return posix_error_with_allocated_filename(pathfree);
Fred Drake699f3522000-06-29 21:12:41 +00001073
Tim Peters500bd032001-12-19 19:05:01 +00001074 PyMem_Free(pathfree);
Fred Drake699f3522000-06-29 21:12:41 +00001075 return _pystat_fromstructstat(st);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001076}
1077
1078
1079/* POSIX methods */
1080
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001081PyDoc_STRVAR(posix_access__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001082"access(path, mode) -> 1 if granted, 0 otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001083Use the real uid/gid to test for access to a path. Note that most\n\
1084operations will use the effective uid/gid, therefore this routine can\n\
1085be used in a suid/sgid environment to test if the invoking user has the\n\
1086specified access to the path. The mode argument can be F_OK to test\n\
1087existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001088
1089static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001090posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001091{
Guido van Rossum015f22a1999-01-06 22:52:38 +00001092 char *path;
1093 int mode;
1094 int res;
1095
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001096#ifdef Py_WIN_WIDE_FILENAMES
1097 if (unicode_file_names()) {
1098 PyUnicodeObject *po;
1099 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1100 Py_BEGIN_ALLOW_THREADS
1101 /* PyUnicode_AS_UNICODE OK without thread lock as
1102 it is a simple dereference. */
1103 res = _waccess(PyUnicode_AS_UNICODE(po), mode);
1104 Py_END_ALLOW_THREADS
1105 return(PyBool_FromLong(res == 0));
1106 }
1107 /* Drop the argument parsing error as narrow strings
1108 are also valid. */
1109 PyErr_Clear();
1110 }
1111#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001112 if (!PyArg_ParseTuple(args, "si:access", &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +00001113 return NULL;
1114 Py_BEGIN_ALLOW_THREADS
1115 res = access(path, mode);
1116 Py_END_ALLOW_THREADS
Guido van Rossum674deb22002-09-01 15:06:28 +00001117 return(PyBool_FromLong(res == 0));
Guido van Rossum94f6f721999-01-06 18:42:14 +00001118}
1119
Guido van Rossumd371ff11999-01-25 16:12:23 +00001120#ifndef F_OK
1121#define F_OK 0
1122#endif
1123#ifndef R_OK
1124#define R_OK 4
1125#endif
1126#ifndef W_OK
1127#define W_OK 2
1128#endif
1129#ifndef X_OK
1130#define X_OK 1
1131#endif
1132
1133#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001134PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001135"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001136Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001137
1138static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001139posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001140{
Guido van Rossum94f6f721999-01-06 18:42:14 +00001141 int id;
1142 char *ret;
1143
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001144 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +00001145 return NULL;
1146
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001147#if defined(__VMS)
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +00001148 /* file descriptor 0 only, the default input device (stdin) */
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001149 if (id == 0) {
1150 ret = ttyname();
1151 }
1152 else {
1153 ret = NULL;
1154 }
1155#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00001156 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001157#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001158 if (ret == NULL)
1159 return(posix_error());
1160 return(PyString_FromString(ret));
1161}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001162#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001163
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001164#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001165PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001166"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001167Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001168
1169static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001170posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001171{
1172 char *ret;
1173 char buffer[L_ctermid];
1174
Greg Wardb48bc172000-03-01 21:51:56 +00001175#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001176 ret = ctermid_r(buffer);
1177#else
1178 ret = ctermid(buffer);
1179#endif
1180 if (ret == NULL)
1181 return(posix_error());
1182 return(PyString_FromString(buffer));
1183}
1184#endif
1185
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001186PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001187"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001188Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001189
Barry Warsaw53699e91996-12-10 23:23:01 +00001190static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001191posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001192{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001193#ifdef MS_WINDOWS
1194 return posix_1str(args, "et:chdir", chdir, "U:chdir", _wchdir);
1195#elif defined(PYOS_OS2) && defined(PYCC_GCC)
1196 return posix_1str(args, "et:chdir", _chdir2, NULL, NULL);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001197#elif defined(__VMS)
Tim Peters11b23062003-04-23 02:39:17 +00001198 return posix_1str(args, "et:chdir", (int (*)(const char *))chdir,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001199 NULL, NULL);
1200#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001201 return posix_1str(args, "et:chdir", chdir, NULL, NULL);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001202#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001203}
1204
Fred Drake4d1e64b2002-04-15 19:40:07 +00001205#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001206PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001207"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001208Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001209opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001210
1211static PyObject *
1212posix_fchdir(PyObject *self, PyObject *fdobj)
1213{
1214 return posix_fildes(fdobj, fchdir);
1215}
1216#endif /* HAVE_FCHDIR */
1217
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001218
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001219PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001220"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001221Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001222
Barry Warsaw53699e91996-12-10 23:23:01 +00001223static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001224posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001225{
Mark Hammondef8b6542001-05-13 08:04:26 +00001226 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +00001227 int i;
1228 int res;
Mark Hammond817c9292003-12-03 01:22:38 +00001229#ifdef Py_WIN_WIDE_FILENAMES
1230 if (unicode_file_names()) {
1231 PyUnicodeObject *po;
1232 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1233 Py_BEGIN_ALLOW_THREADS
1234 res = _wchmod(PyUnicode_AS_UNICODE(po), i);
1235 Py_END_ALLOW_THREADS
1236 if (res < 0)
1237 return posix_error_with_unicode_filename(
1238 PyUnicode_AS_UNICODE(po));
1239 Py_INCREF(Py_None);
1240 return Py_None;
1241 }
1242 /* Drop the argument parsing error as narrow strings
1243 are also valid. */
1244 PyErr_Clear();
1245 }
1246#endif /* Py_WIN_WIDE_FILENAMES */
1247 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
Mark Hammondef8b6542001-05-13 08:04:26 +00001248 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +00001249 return NULL;
1250 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +00001251 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001252 Py_END_ALLOW_THREADS
1253 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001254 return posix_error_with_allocated_filename(path);
1255 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001256 Py_INCREF(Py_None);
1257 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001258}
1259
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001260
Martin v. Löwis244edc82001-10-04 22:44:26 +00001261#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001262PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001263"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001264Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00001265
1266static PyObject *
1267posix_chroot(PyObject *self, PyObject *args)
1268{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001269 return posix_1str(args, "et:chroot", chroot, NULL, NULL);
Martin v. Löwis244edc82001-10-04 22:44:26 +00001270}
1271#endif
1272
Guido van Rossum21142a01999-01-08 21:05:37 +00001273#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001274PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001275"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001276force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001277
1278static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001279posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001280{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001281 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001282}
1283#endif /* HAVE_FSYNC */
1284
1285#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00001286
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00001287#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00001288extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1289#endif
1290
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001291PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001292"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00001293force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001294 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001295
1296static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001297posix_fdatasync(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, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001300}
1301#endif /* HAVE_FDATASYNC */
1302
1303
Fredrik Lundh10723342000-07-10 16:38:09 +00001304#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001305PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001306"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001307Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001308
Barry Warsaw53699e91996-12-10 23:23:01 +00001309static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001310posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001311{
Mark Hammondef8b6542001-05-13 08:04:26 +00001312 char *path = NULL;
Fredrik Lundh44328e62000-07-10 15:59:30 +00001313 int uid, gid;
1314 int res;
Tim Peters5aa91602002-01-30 05:46:57 +00001315 if (!PyArg_ParseTuple(args, "etii:chown",
1316 Py_FileSystemDefaultEncoding, &path,
Mark Hammondef8b6542001-05-13 08:04:26 +00001317 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +00001318 return NULL;
1319 Py_BEGIN_ALLOW_THREADS
1320 res = chown(path, (uid_t) uid, (gid_t) gid);
1321 Py_END_ALLOW_THREADS
1322 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001323 return posix_error_with_allocated_filename(path);
1324 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +00001325 Py_INCREF(Py_None);
1326 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001327}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001328#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001329
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001330#ifdef HAVE_LCHOWN
1331PyDoc_STRVAR(posix_lchown__doc__,
1332"lchown(path, uid, gid)\n\n\
1333Change the owner and group id of path to the numeric uid and gid.\n\
1334This function will not follow symbolic links.");
1335
1336static PyObject *
1337posix_lchown(PyObject *self, PyObject *args)
1338{
1339 char *path = NULL;
1340 int uid, gid;
1341 int res;
1342 if (!PyArg_ParseTuple(args, "etii:lchown",
1343 Py_FileSystemDefaultEncoding, &path,
1344 &uid, &gid))
1345 return NULL;
1346 Py_BEGIN_ALLOW_THREADS
1347 res = lchown(path, (uid_t) uid, (gid_t) gid);
1348 Py_END_ALLOW_THREADS
Tim Peters11b23062003-04-23 02:39:17 +00001349 if (res < 0)
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001350 return posix_error_with_allocated_filename(path);
1351 PyMem_Free(path);
1352 Py_INCREF(Py_None);
1353 return Py_None;
1354}
1355#endif /* HAVE_LCHOWN */
1356
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001357
Guido van Rossum36bc6801995-06-14 22:54:23 +00001358#ifdef HAVE_GETCWD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001359PyDoc_STRVAR(posix_getcwd__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001360"getcwd() -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001361Return a string representing the current working directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001362
Barry Warsaw53699e91996-12-10 23:23:01 +00001363static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001364posix_getcwd(PyObject *self, PyObject *noargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001365{
1366 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +00001367 char *res;
Neal Norwitze241ce82003-02-17 18:17:05 +00001368
Barry Warsaw53699e91996-12-10 23:23:01 +00001369 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001370#if defined(PYOS_OS2) && defined(PYCC_GCC)
1371 res = _getcwd2(buf, sizeof buf);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001372#else
Guido van Rossumff4949e1992-08-05 19:58:53 +00001373 res = getcwd(buf, sizeof buf);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001374#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001375 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001376 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001377 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001378 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001379}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001380
Walter Dörwald3b918c32002-11-21 20:18:46 +00001381#ifdef Py_USING_UNICODE
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001382PyDoc_STRVAR(posix_getcwdu__doc__,
1383"getcwdu() -> path\n\n\
1384Return a unicode string representing the current working directory.");
1385
1386static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001387posix_getcwdu(PyObject *self, PyObject *noargs)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001388{
1389 char buf[1026];
1390 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001391
1392#ifdef Py_WIN_WIDE_FILENAMES
1393 if (unicode_file_names()) {
1394 wchar_t *wres;
1395 wchar_t wbuf[1026];
1396 Py_BEGIN_ALLOW_THREADS
1397 wres = _wgetcwd(wbuf, sizeof wbuf/ sizeof wbuf[0]);
1398 Py_END_ALLOW_THREADS
1399 if (wres == NULL)
1400 return posix_error();
1401 return PyUnicode_FromWideChar(wbuf, wcslen(wbuf));
1402 }
1403#endif
1404
1405 Py_BEGIN_ALLOW_THREADS
1406#if defined(PYOS_OS2) && defined(PYCC_GCC)
1407 res = _getcwd2(buf, sizeof buf);
1408#else
1409 res = getcwd(buf, sizeof buf);
1410#endif
1411 Py_END_ALLOW_THREADS
1412 if (res == NULL)
1413 return posix_error();
1414 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
1415}
Guido van Rossum36bc6801995-06-14 22:54:23 +00001416#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00001417#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001418
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001419
Guido van Rossumb6775db1994-08-01 11:34:53 +00001420#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001421PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001422"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001423Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001424
Barry Warsaw53699e91996-12-10 23:23:01 +00001425static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001426posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001427{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001428 return posix_2str(args, "etet:link", link, NULL, NULL);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001429}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001430#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001431
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001432
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001433PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001434"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001435Return a list containing the names of the entries in the directory.\n\
1436\n\
1437 path: path of directory to list\n\
1438\n\
1439The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001440entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001441
Barry Warsaw53699e91996-12-10 23:23:01 +00001442static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001443posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001444{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001445 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001446 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001447#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001448
Barry Warsaw53699e91996-12-10 23:23:01 +00001449 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001450 HANDLE hFindFile;
1451 WIN32_FIND_DATA FileData;
Mark Hammondef8b6542001-05-13 08:04:26 +00001452 /* MAX_PATH characters could mean a bigger encoded string */
1453 char namebuf[MAX_PATH*2+5];
1454 char *bufptr = namebuf;
1455 int len = sizeof(namebuf)/sizeof(namebuf[0]);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001456
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001457#ifdef Py_WIN_WIDE_FILENAMES
1458 /* If on wide-character-capable OS see if argument
1459 is Unicode and if so use wide API. */
1460 if (unicode_file_names()) {
1461 PyUnicodeObject *po;
1462 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
1463 WIN32_FIND_DATAW wFileData;
1464 Py_UNICODE wnamebuf[MAX_PATH*2+5];
1465 Py_UNICODE wch;
1466 wcsncpy(wnamebuf, PyUnicode_AS_UNICODE(po), MAX_PATH);
1467 wnamebuf[MAX_PATH] = L'\0';
1468 len = wcslen(wnamebuf);
1469 wch = (len > 0) ? wnamebuf[len-1] : L'\0';
1470 if (wch != L'/' && wch != L'\\' && wch != L':')
1471 wnamebuf[len++] = L'/';
1472 wcscpy(wnamebuf + len, L"*.*");
1473 if ((d = PyList_New(0)) == NULL)
1474 return NULL;
1475 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
1476 if (hFindFile == INVALID_HANDLE_VALUE) {
1477 errno = GetLastError();
1478 if (errno == ERROR_FILE_NOT_FOUND) {
1479 return d;
1480 }
1481 Py_DECREF(d);
1482 return win32_error_unicode("FindFirstFileW", wnamebuf);
1483 }
1484 do {
1485 if (wFileData.cFileName[0] == L'.' &&
1486 (wFileData.cFileName[1] == L'\0' ||
1487 wFileData.cFileName[1] == L'.' &&
1488 wFileData.cFileName[2] == L'\0'))
1489 continue;
1490 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
1491 if (v == NULL) {
1492 Py_DECREF(d);
1493 d = NULL;
1494 break;
1495 }
1496 if (PyList_Append(d, v) != 0) {
1497 Py_DECREF(v);
1498 Py_DECREF(d);
1499 d = NULL;
1500 break;
1501 }
1502 Py_DECREF(v);
1503 } while (FindNextFileW(hFindFile, &wFileData) == TRUE);
1504
1505 if (FindClose(hFindFile) == FALSE) {
1506 Py_DECREF(d);
1507 return win32_error_unicode("FindClose", wnamebuf);
1508 }
1509 return d;
1510 }
1511 /* Drop the argument parsing error as narrow strings
1512 are also valid. */
1513 PyErr_Clear();
1514 }
1515#endif
1516
Tim Peters5aa91602002-01-30 05:46:57 +00001517 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001518 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +00001519 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +00001520 if (len > 0) {
1521 char ch = namebuf[len-1];
1522 if (ch != SEP && ch != ALTSEP && ch != ':')
1523 namebuf[len++] = '/';
1524 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001525 strcpy(namebuf + len, "*.*");
1526
Barry Warsaw53699e91996-12-10 23:23:01 +00001527 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001528 return NULL;
1529
1530 hFindFile = FindFirstFile(namebuf, &FileData);
1531 if (hFindFile == INVALID_HANDLE_VALUE) {
1532 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +00001533 if (errno == ERROR_FILE_NOT_FOUND)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001534 return d;
1535 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00001536 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001537 }
1538 do {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001539 if (FileData.cFileName[0] == '.' &&
1540 (FileData.cFileName[1] == '\0' ||
1541 FileData.cFileName[1] == '.' &&
1542 FileData.cFileName[2] == '\0'))
1543 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001544 v = PyString_FromString(FileData.cFileName);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001545 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001546 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001547 d = NULL;
1548 break;
1549 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001550 if (PyList_Append(d, v) != 0) {
1551 Py_DECREF(v);
1552 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001553 d = NULL;
1554 break;
1555 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001556 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001557 } while (FindNextFile(hFindFile, &FileData) == TRUE);
1558
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001559 if (FindClose(hFindFile) == FALSE) {
1560 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00001561 return win32_error("FindClose", namebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001562 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001563
1564 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001565
Tim Peters0bb44a42000-09-15 07:44:49 +00001566#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001567
1568#ifndef MAX_PATH
1569#define MAX_PATH CCHMAXPATH
1570#endif
1571 char *name, *pt;
1572 int len;
1573 PyObject *d, *v;
1574 char namebuf[MAX_PATH+5];
1575 HDIR hdir = 1;
1576 ULONG srchcnt = 1;
1577 FILEFINDBUF3 ep;
1578 APIRET rc;
1579
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001580 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001581 return NULL;
1582 if (len >= MAX_PATH) {
1583 PyErr_SetString(PyExc_ValueError, "path too long");
1584 return NULL;
1585 }
1586 strcpy(namebuf, name);
1587 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001588 if (*pt == ALTSEP)
1589 *pt = SEP;
1590 if (namebuf[len-1] != SEP)
1591 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001592 strcpy(namebuf + len, "*.*");
1593
1594 if ((d = PyList_New(0)) == NULL)
1595 return NULL;
1596
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001597 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
1598 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001599 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001600 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
1601 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
1602 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001603
1604 if (rc != NO_ERROR) {
1605 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001606 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001607 }
1608
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001609 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001610 do {
1611 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001612 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001613 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001614
1615 strcpy(namebuf, ep.achName);
1616
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001617 /* Leave Case of Name Alone -- In Native Form */
1618 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001619
1620 v = PyString_FromString(namebuf);
1621 if (v == NULL) {
1622 Py_DECREF(d);
1623 d = NULL;
1624 break;
1625 }
1626 if (PyList_Append(d, v) != 0) {
1627 Py_DECREF(v);
1628 Py_DECREF(d);
1629 d = NULL;
1630 break;
1631 }
1632 Py_DECREF(v);
1633 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1634 }
1635
1636 return d;
1637#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001638
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001639 char *name = NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001640 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001641 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001642 struct dirent *ep;
Just van Rossum96b1c902003-03-03 17:32:15 +00001643 int arg_is_unicode = 1;
1644
1645 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
1646 arg_is_unicode = 0;
1647 PyErr_Clear();
1648 }
1649 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001650 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001651 if ((dirp = opendir(name)) == NULL) {
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001652 return posix_error_with_allocated_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001653 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001654 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001655 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001656 PyMem_Free(name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001657 return NULL;
1658 }
1659 while ((ep = readdir(dirp)) != NULL) {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001660 if (ep->d_name[0] == '.' &&
1661 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001662 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001663 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001664 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001665 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001666 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001667 d = NULL;
1668 break;
1669 }
Just van Rossum46c97842003-02-25 21:42:15 +00001670#ifdef Py_USING_UNICODE
Just van Rossum96b1c902003-03-03 17:32:15 +00001671 if (arg_is_unicode) {
Just van Rossum46c97842003-02-25 21:42:15 +00001672 PyObject *w;
1673
1674 w = PyUnicode_FromEncodedObject(v,
Tim Peters11b23062003-04-23 02:39:17 +00001675 Py_FileSystemDefaultEncoding,
Just van Rossum46c97842003-02-25 21:42:15 +00001676 "strict");
Just van Rossum6a421832003-03-04 19:30:44 +00001677 if (w != NULL) {
1678 Py_DECREF(v);
1679 v = w;
1680 }
1681 else {
1682 /* fall back to the original byte string, as
1683 discussed in patch #683592 */
1684 PyErr_Clear();
Just van Rossum46c97842003-02-25 21:42:15 +00001685 }
Just van Rossum46c97842003-02-25 21:42:15 +00001686 }
1687#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001688 if (PyList_Append(d, v) != 0) {
1689 Py_DECREF(v);
1690 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001691 d = NULL;
1692 break;
1693 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001694 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001695 }
1696 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001697 PyMem_Free(name);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001698
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001699 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001700
Tim Peters0bb44a42000-09-15 07:44:49 +00001701#endif /* which OS */
1702} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001703
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001704#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00001705/* A helper function for abspath on win32 */
1706static PyObject *
1707posix__getfullpathname(PyObject *self, PyObject *args)
1708{
1709 /* assume encoded strings wont more than double no of chars */
1710 char inbuf[MAX_PATH*2];
1711 char *inbufp = inbuf;
1712 int insize = sizeof(inbuf)/sizeof(inbuf[0]);
1713 char outbuf[MAX_PATH*2];
1714 char *temp;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001715#ifdef Py_WIN_WIDE_FILENAMES
1716 if (unicode_file_names()) {
1717 PyUnicodeObject *po;
1718 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
1719 Py_UNICODE woutbuf[MAX_PATH*2];
1720 Py_UNICODE *wtemp;
Tim Peters11b23062003-04-23 02:39:17 +00001721 if (!GetFullPathNameW(PyUnicode_AS_UNICODE(po),
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001722 sizeof(woutbuf)/sizeof(woutbuf[0]),
1723 woutbuf, &wtemp))
1724 return win32_error("GetFullPathName", "");
1725 return PyUnicode_FromUnicode(woutbuf, wcslen(woutbuf));
1726 }
1727 /* Drop the argument parsing error as narrow strings
1728 are also valid. */
1729 PyErr_Clear();
1730 }
1731#endif
Tim Peters5aa91602002-01-30 05:46:57 +00001732 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
1733 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00001734 &insize))
1735 return NULL;
1736 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
1737 outbuf, &temp))
1738 return win32_error("GetFullPathName", inbuf);
1739 return PyString_FromString(outbuf);
1740} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001741#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00001742
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001743PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001744"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001745Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001746
Barry Warsaw53699e91996-12-10 23:23:01 +00001747static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001748posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001749{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001750 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00001751 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001752 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001753
1754#ifdef Py_WIN_WIDE_FILENAMES
1755 if (unicode_file_names()) {
1756 PyUnicodeObject *po;
Mark Hammond05107b62003-02-19 04:08:27 +00001757 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001758 Py_BEGIN_ALLOW_THREADS
1759 /* PyUnicode_AS_UNICODE OK without thread lock as
1760 it is a simple dereference. */
1761 res = _wmkdir(PyUnicode_AS_UNICODE(po));
1762 Py_END_ALLOW_THREADS
1763 if (res < 0)
1764 return posix_error();
1765 Py_INCREF(Py_None);
1766 return Py_None;
1767 }
1768 /* Drop the argument parsing error as narrow strings
1769 are also valid. */
1770 PyErr_Clear();
1771 }
1772#endif
1773
Tim Peters5aa91602002-01-30 05:46:57 +00001774 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001775 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001776 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001777 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001778#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001779 res = mkdir(path);
1780#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001781 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001782#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001783 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001784 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001785 return posix_error_with_allocated_filename(path);
1786 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001787 Py_INCREF(Py_None);
1788 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001789}
1790
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001791
Guido van Rossumb6775db1994-08-01 11:34:53 +00001792#ifdef HAVE_NICE
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001793#if defined(HAVE_BROKEN_NICE) && defined(HAVE_SYS_RESOURCE_H)
1794#if defined(HAVE_GETPRIORITY) && !defined(PRIO_PROCESS)
1795#include <sys/resource.h>
1796#endif
1797#endif
1798
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001799PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001800"nice(inc) -> new_priority\n\n\
1801Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001802
Barry Warsaw53699e91996-12-10 23:23:01 +00001803static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001804posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00001805{
1806 int increment, value;
1807
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001808 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00001809 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001810
1811 /* There are two flavours of 'nice': one that returns the new
1812 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001813 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
1814 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00001815
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001816 If we are of the nice family that returns the new priority, we
1817 need to clear errno before the call, and check if errno is filled
1818 before calling posix_error() on a returnvalue of -1, because the
1819 -1 may be the actual new priority! */
1820
1821 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00001822 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001823#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001824 if (value == 0)
1825 value = getpriority(PRIO_PROCESS, 0);
1826#endif
1827 if (value == -1 && errno != 0)
1828 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00001829 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001830 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00001831}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001832#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001833
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001834
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001835PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001836"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001837Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001838
Barry Warsaw53699e91996-12-10 23:23:01 +00001839static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001840posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001841{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001842#ifdef MS_WINDOWS
1843 return posix_2str(args, "etet:rename", rename, "OO:rename", _wrename);
1844#else
1845 return posix_2str(args, "etet:rename", rename, NULL, NULL);
1846#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001847}
1848
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001849
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001850PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001851"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001852Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001853
Barry Warsaw53699e91996-12-10 23:23:01 +00001854static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001855posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001856{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001857#ifdef MS_WINDOWS
1858 return posix_1str(args, "et:rmdir", rmdir, "U:rmdir", _wrmdir);
1859#else
1860 return posix_1str(args, "et:rmdir", rmdir, NULL, NULL);
1861#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001862}
1863
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001864
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001865PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001866"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001867Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001868
Barry Warsaw53699e91996-12-10 23:23:01 +00001869static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001870posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001871{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001872#ifdef MS_WINDOWS
1873 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", _wstati64);
1874#else
1875 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
1876#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001877}
1878
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001879
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001880#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001881PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001882"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001883Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001884
Barry Warsaw53699e91996-12-10 23:23:01 +00001885static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001886posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001887{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001888 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001889 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001890 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001891 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001892 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001893 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00001894 Py_END_ALLOW_THREADS
1895 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001896}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001897#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001898
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001899
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001900PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001901"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001902Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001903
Barry Warsaw53699e91996-12-10 23:23:01 +00001904static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001905posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001906{
1907 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001908 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001909 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00001910 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001911 if (i < 0)
1912 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001913 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001914}
1915
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001916
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001917PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001918"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001919Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001920
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001921PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001922"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001923Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001924
Barry Warsaw53699e91996-12-10 23:23:01 +00001925static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001926posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001927{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001928#ifdef MS_WINDOWS
1929 return posix_1str(args, "et:remove", unlink, "U:remove", _wunlink);
1930#else
1931 return posix_1str(args, "et:remove", unlink, NULL, NULL);
1932#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001933}
1934
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001935
Guido van Rossumb6775db1994-08-01 11:34:53 +00001936#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001937PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001938"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001939Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001940
Barry Warsaw53699e91996-12-10 23:23:01 +00001941static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001942posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001943{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001944 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001945 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00001946
Barry Warsaw53699e91996-12-10 23:23:01 +00001947 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001948 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00001949 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001950 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001951 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001952 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00001953 u.sysname,
1954 u.nodename,
1955 u.release,
1956 u.version,
1957 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00001958}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001959#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001960
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001961static int
1962extract_time(PyObject *t, long* sec, long* usec)
1963{
1964 long intval;
1965 if (PyFloat_Check(t)) {
1966 double tval = PyFloat_AsDouble(t);
1967 PyObject *intobj = t->ob_type->tp_as_number->nb_int(t);
1968 if (!intobj)
1969 return -1;
1970 intval = PyInt_AsLong(intobj);
1971 Py_DECREF(intobj);
1972 *sec = intval;
Tim Peters96940cf2002-09-10 15:37:28 +00001973 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001974 if (*usec < 0)
1975 /* If rounding gave us a negative number,
1976 truncate. */
1977 *usec = 0;
1978 return 0;
1979 }
1980 intval = PyInt_AsLong(t);
1981 if (intval == -1 && PyErr_Occurred())
1982 return -1;
1983 *sec = intval;
1984 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00001985 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001986}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001987
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001988PyDoc_STRVAR(posix_utime__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001989"utime(path, (atime, utime))\n\
1990utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00001991Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001992second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001993
Barry Warsaw53699e91996-12-10 23:23:01 +00001994static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001995posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001996{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001997 char *path;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00001998 long atime, mtime, ausec, musec;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001999 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002000 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002001
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002002#if defined(HAVE_UTIMES)
2003 struct timeval buf[2];
2004#define ATIME buf[0].tv_sec
2005#define MTIME buf[1].tv_sec
2006#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002007/* XXX should define struct utimbuf instead, above */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002008 struct utimbuf buf;
2009#define ATIME buf.actime
2010#define MTIME buf.modtime
2011#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002012#else /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002013 time_t buf[2];
2014#define ATIME buf[0]
2015#define MTIME buf[1]
2016#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002017#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002018
Mark Hammond817c9292003-12-03 01:22:38 +00002019 int have_unicode_filename = 0;
2020#ifdef Py_WIN_WIDE_FILENAMES
2021 PyUnicodeObject *obwpath;
2022 wchar_t *wpath;
2023 if (unicode_file_names()) {
2024 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
2025 wpath = PyUnicode_AS_UNICODE(obwpath);
2026 have_unicode_filename = 1;
2027 } else
2028 /* Drop the argument parsing error as narrow strings
2029 are also valid. */
2030 PyErr_Clear();
2031 }
2032#endif /* Py_WIN_WIDE_FILENAMES */
2033
2034 if (!have_unicode_filename && \
Hye-Shik Chang2b2c9732004-01-04 13:54:25 +00002035 !PyArg_ParseTuple(args, "etO:utime",
2036 Py_FileSystemDefaultEncoding, &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002037 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002038 if (arg == Py_None) {
2039 /* optional time values not given */
2040 Py_BEGIN_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002041#ifdef Py_WIN_WIDE_FILENAMES
2042 if (have_unicode_filename)
2043 res = _wutime(wpath, NULL);
2044 else
2045#endif /* Py_WIN_WIDE_FILENAMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002046 res = utime(path, NULL);
2047 Py_END_ALLOW_THREADS
2048 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002049 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00002050 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002051 "utime() arg 2 must be a tuple (atime, mtime)");
Neal Norwitz96652712004-06-06 20:40:27 +00002052 PyMem_Free(path);
Barry Warsaw3cef8562000-05-01 16:17:24 +00002053 return NULL;
2054 }
2055 else {
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002056 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Neal Norwitz96652712004-06-06 20:40:27 +00002057 &atime, &ausec) == -1) {
2058 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002059 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002060 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002061 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Neal Norwitz96652712004-06-06 20:40:27 +00002062 &mtime, &musec) == -1) {
2063 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002064 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002065 }
Barry Warsaw3cef8562000-05-01 16:17:24 +00002066 ATIME = atime;
2067 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002068#ifdef HAVE_UTIMES
2069 buf[0].tv_usec = ausec;
2070 buf[1].tv_usec = musec;
2071 Py_BEGIN_ALLOW_THREADS
2072 res = utimes(path, buf);
2073 Py_END_ALLOW_THREADS
2074#else
Barry Warsaw3cef8562000-05-01 16:17:24 +00002075 Py_BEGIN_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002076#ifdef Py_WIN_WIDE_FILENAMES
2077 if (have_unicode_filename)
2078 /* utime is OK with utimbuf, but _wutime insists
2079 on _utimbuf (the msvc headers assert the
2080 underscore version is ansi) */
2081 res = _wutime(wpath, (struct _utimbuf *)UTIME_ARG);
2082 else
2083#endif /* Py_WIN_WIDE_FILENAMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002084 res = utime(path, UTIME_ARG);
2085 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002086#endif /* HAVE_UTIMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002087 }
Mark Hammond2d5914b2004-05-04 08:10:37 +00002088 if (res < 0) {
2089#ifdef Py_WIN_WIDE_FILENAMES
Neal Norwitz96652712004-06-06 20:40:27 +00002090 if (have_unicode_filename) {
2091 PyMem_Free(path);
Mark Hammond2d5914b2004-05-04 08:10:37 +00002092 return posix_error_with_unicode_filename(wpath);
Neal Norwitz96652712004-06-06 20:40:27 +00002093 }
Mark Hammond2d5914b2004-05-04 08:10:37 +00002094#endif /* Py_WIN_WIDE_FILENAMES */
Neal Norwitz96652712004-06-06 20:40:27 +00002095 return posix_error_with_allocated_filename(path);
Mark Hammond2d5914b2004-05-04 08:10:37 +00002096 }
Neal Norwitz96652712004-06-06 20:40:27 +00002097 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002098 Py_INCREF(Py_None);
2099 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002100#undef UTIME_ARG
2101#undef ATIME
2102#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002103}
2104
Guido van Rossum85e3b011991-06-03 12:42:10 +00002105
Guido van Rossum3b066191991-06-04 19:40:25 +00002106/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002107
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002108PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002109"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002110Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002111
Barry Warsaw53699e91996-12-10 23:23:01 +00002112static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002113posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002114{
2115 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002116 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002117 return NULL;
2118 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00002119 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002120}
2121
Martin v. Löwis114619e2002-10-07 06:44:21 +00002122#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
2123static void
2124free_string_array(char **array, int count)
2125{
2126 int i;
2127 for (i = 0; i < count; i++)
2128 PyMem_Free(array[i]);
2129 PyMem_DEL(array);
2130}
2131#endif
2132
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002133
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002134#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002135PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002136"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002137Execute an executable path with arguments, replacing current process.\n\
2138\n\
2139 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002140 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002141
Barry Warsaw53699e91996-12-10 23:23:01 +00002142static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002143posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002144{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002145 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002146 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002147 char **argvlist;
2148 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002149 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002150
Guido van Rossum89b33251993-10-22 14:26:06 +00002151 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00002152 argv is a list or tuple of strings. */
2153
Martin v. Löwis114619e2002-10-07 06:44:21 +00002154 if (!PyArg_ParseTuple(args, "etO:execv",
2155 Py_FileSystemDefaultEncoding,
2156 &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002157 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002158 if (PyList_Check(argv)) {
2159 argc = PyList_Size(argv);
2160 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002161 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002162 else if (PyTuple_Check(argv)) {
2163 argc = PyTuple_Size(argv);
2164 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002165 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002166 else {
Fred Drake661ea262000-10-24 19:57:45 +00002167 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002168 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002169 return NULL;
2170 }
2171
2172 if (argc == 0) {
Fred Drake661ea262000-10-24 19:57:45 +00002173 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002174 PyMem_Free(path);
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002175 return NULL;
2176 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002177
Barry Warsaw53699e91996-12-10 23:23:01 +00002178 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002179 if (argvlist == NULL) {
2180 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002181 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002182 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002183 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002184 if (!PyArg_Parse((*getitem)(argv, i), "et",
2185 Py_FileSystemDefaultEncoding,
2186 &argvlist[i])) {
2187 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00002188 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002189 "execv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002190 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002191 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00002192
Guido van Rossum85e3b011991-06-03 12:42:10 +00002193 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002194 }
2195 argvlist[argc] = NULL;
2196
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002197 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002198
Guido van Rossum85e3b011991-06-03 12:42:10 +00002199 /* If we get here it's definitely an error */
2200
Martin v. Löwis114619e2002-10-07 06:44:21 +00002201 free_string_array(argvlist, argc);
2202 PyMem_Free(path);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002203 return posix_error();
2204}
2205
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002206
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002207PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002208"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002209Execute a path with arguments and environment, replacing current process.\n\
2210\n\
2211 path: path of executable file\n\
2212 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002213 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002214
Barry Warsaw53699e91996-12-10 23:23:01 +00002215static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002216posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002217{
2218 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002219 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002220 char **argvlist;
2221 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002222 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002223 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002224 PyObject *(*getitem)(PyObject *, int);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002225 int lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002226
2227 /* execve has three arguments: (path, argv, env), where
2228 argv is a list or tuple of strings and env is a dictionary
2229 like posix.environ. */
2230
Martin v. Löwis114619e2002-10-07 06:44:21 +00002231 if (!PyArg_ParseTuple(args, "etOO:execve",
2232 Py_FileSystemDefaultEncoding,
2233 &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002234 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002235 if (PyList_Check(argv)) {
2236 argc = PyList_Size(argv);
2237 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002238 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002239 else if (PyTuple_Check(argv)) {
2240 argc = PyTuple_Size(argv);
2241 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002242 }
2243 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002244 PyErr_SetString(PyExc_TypeError,
2245 "execve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002246 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002247 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002248 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002249 PyErr_SetString(PyExc_TypeError,
2250 "execve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002251 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002252 }
2253
Guido van Rossum50422b42000-04-26 20:34:28 +00002254 if (argc == 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00002255 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00002256 "execve() arg 2 must not be empty");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002257 goto fail_0;
Guido van Rossum50422b42000-04-26 20:34:28 +00002258 }
2259
Barry Warsaw53699e91996-12-10 23:23:01 +00002260 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002261 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002262 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002263 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002264 }
2265 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002266 if (!PyArg_Parse((*getitem)(argv, i),
Martin v. Löwis114619e2002-10-07 06:44:21 +00002267 "et;execve() arg 2 must contain only strings",
Guido van Rossum1e700d22002-10-16 16:52:11 +00002268 Py_FileSystemDefaultEncoding,
Barry Warsaw43d68b81996-12-19 22:10:44 +00002269 &argvlist[i]))
2270 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002271 lastarg = i;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002272 goto fail_1;
2273 }
2274 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002275 lastarg = argc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002276 argvlist[argc] = NULL;
2277
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002278 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002279 if (i < 0)
2280 goto fail_1;
Barry Warsaw53699e91996-12-10 23:23:01 +00002281 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002282 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002283 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002284 goto fail_1;
2285 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002286 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002287 keys = PyMapping_Keys(env);
2288 vals = PyMapping_Values(env);
2289 if (!keys || !vals)
2290 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002291 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2292 PyErr_SetString(PyExc_TypeError,
2293 "execve(): env.keys() or env.values() is not a list");
2294 goto fail_2;
2295 }
Tim Peters5aa91602002-01-30 05:46:57 +00002296
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002297 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002298 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002299 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002300
2301 key = PyList_GetItem(keys, pos);
2302 val = PyList_GetItem(vals, pos);
2303 if (!key || !val)
2304 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002305
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002306 if (!PyArg_Parse(
2307 key,
2308 "s;execve() arg 3 contains a non-string key",
2309 &k) ||
2310 !PyArg_Parse(
2311 val,
2312 "s;execve() arg 3 contains a non-string value",
2313 &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00002314 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002315 goto fail_2;
2316 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00002317
2318#if defined(PYOS_OS2)
2319 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
2320 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
2321#endif
Tim Petersc8996f52001-12-03 20:41:00 +00002322 len = PyString_Size(key) + PyString_Size(val) + 2;
2323 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002324 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002325 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002326 goto fail_2;
2327 }
Tim Petersc8996f52001-12-03 20:41:00 +00002328 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002329 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00002330#if defined(PYOS_OS2)
2331 }
2332#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002333 }
2334 envlist[envc] = 0;
2335
2336 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00002337
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002338 /* If we get here it's definitely an error */
2339
2340 (void) posix_error();
2341
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002342 fail_2:
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002343 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00002344 PyMem_DEL(envlist[envc]);
2345 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002346 fail_1:
2347 free_string_array(argvlist, lastarg);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002348 Py_XDECREF(vals);
2349 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002350 fail_0:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002351 PyMem_Free(path);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002352 return NULL;
2353}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002354#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002355
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002356
Guido van Rossuma1065681999-01-25 23:20:23 +00002357#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002358PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002359"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002360Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002361\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002362 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002363 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002364 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002365
2366static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002367posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002368{
2369 char *path;
2370 PyObject *argv;
2371 char **argvlist;
2372 int mode, i, argc;
Tim Peters79248aa2001-08-29 21:37:10 +00002373 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002374 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00002375
2376 /* spawnv has three arguments: (mode, path, argv), where
2377 argv is a list or tuple of strings. */
2378
Martin v. Löwis114619e2002-10-07 06:44:21 +00002379 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
2380 Py_FileSystemDefaultEncoding,
2381 &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00002382 return NULL;
2383 if (PyList_Check(argv)) {
2384 argc = PyList_Size(argv);
2385 getitem = PyList_GetItem;
2386 }
2387 else if (PyTuple_Check(argv)) {
2388 argc = PyTuple_Size(argv);
2389 getitem = PyTuple_GetItem;
2390 }
2391 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002392 PyErr_SetString(PyExc_TypeError,
2393 "spawnv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002394 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002395 return NULL;
2396 }
2397
2398 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002399 if (argvlist == NULL) {
2400 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002401 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002402 }
Guido van Rossuma1065681999-01-25 23:20:23 +00002403 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002404 if (!PyArg_Parse((*getitem)(argv, i), "et",
2405 Py_FileSystemDefaultEncoding,
2406 &argvlist[i])) {
2407 free_string_array(argvlist, i);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002408 PyErr_SetString(
2409 PyExc_TypeError,
2410 "spawnv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002411 PyMem_Free(path);
Fred Drake137507e2000-06-01 02:02:46 +00002412 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00002413 }
2414 }
2415 argvlist[argc] = NULL;
2416
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002417#if defined(PYOS_OS2) && defined(PYCC_GCC)
2418 Py_BEGIN_ALLOW_THREADS
2419 spawnval = spawnv(mode, path, argvlist);
2420 Py_END_ALLOW_THREADS
2421#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002422 if (mode == _OLD_P_OVERLAY)
2423 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00002424
Tim Peters25059d32001-12-07 20:35:43 +00002425 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002426 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00002427 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002428#endif
Tim Peters5aa91602002-01-30 05:46:57 +00002429
Martin v. Löwis114619e2002-10-07 06:44:21 +00002430 free_string_array(argvlist, argc);
2431 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002432
Fred Drake699f3522000-06-29 21:12:41 +00002433 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002434 return posix_error();
2435 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002436#if SIZEOF_LONG == SIZEOF_VOID_P
2437 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002438#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00002439 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002440#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002441}
2442
2443
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002444PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002445"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002446Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002447\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002448 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002449 path: path of executable file\n\
2450 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002451 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002452
2453static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002454posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002455{
2456 char *path;
2457 PyObject *argv, *env;
2458 char **argvlist;
2459 char **envlist;
2460 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
2461 int mode, i, pos, argc, envc;
Tim Peters79248aa2001-08-29 21:37:10 +00002462 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002463 PyObject *(*getitem)(PyObject *, int);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002464 int lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002465
2466 /* spawnve has four arguments: (mode, path, argv, env), where
2467 argv is a list or tuple of strings and env is a dictionary
2468 like posix.environ. */
2469
Martin v. Löwis114619e2002-10-07 06:44:21 +00002470 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
2471 Py_FileSystemDefaultEncoding,
2472 &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00002473 return NULL;
2474 if (PyList_Check(argv)) {
2475 argc = PyList_Size(argv);
2476 getitem = PyList_GetItem;
2477 }
2478 else if (PyTuple_Check(argv)) {
2479 argc = PyTuple_Size(argv);
2480 getitem = PyTuple_GetItem;
2481 }
2482 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002483 PyErr_SetString(PyExc_TypeError,
2484 "spawnve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002485 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002486 }
2487 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002488 PyErr_SetString(PyExc_TypeError,
2489 "spawnve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002490 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002491 }
2492
2493 argvlist = PyMem_NEW(char *, argc+1);
2494 if (argvlist == NULL) {
2495 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002496 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002497 }
2498 for (i = 0; i < argc; i++) {
2499 if (!PyArg_Parse((*getitem)(argv, i),
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002500 "et;spawnve() arg 2 must contain only strings",
Martin v. Löwis114619e2002-10-07 06:44:21 +00002501 Py_FileSystemDefaultEncoding,
Guido van Rossuma1065681999-01-25 23:20:23 +00002502 &argvlist[i]))
2503 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002504 lastarg = i;
Guido van Rossuma1065681999-01-25 23:20:23 +00002505 goto fail_1;
2506 }
2507 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002508 lastarg = argc;
Guido van Rossuma1065681999-01-25 23:20:23 +00002509 argvlist[argc] = NULL;
2510
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002511 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002512 if (i < 0)
2513 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00002514 envlist = PyMem_NEW(char *, i + 1);
2515 if (envlist == NULL) {
2516 PyErr_NoMemory();
2517 goto fail_1;
2518 }
2519 envc = 0;
2520 keys = PyMapping_Keys(env);
2521 vals = PyMapping_Values(env);
2522 if (!keys || !vals)
2523 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002524 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2525 PyErr_SetString(PyExc_TypeError,
2526 "spawnve(): env.keys() or env.values() is not a list");
2527 goto fail_2;
2528 }
Tim Peters5aa91602002-01-30 05:46:57 +00002529
Guido van Rossuma1065681999-01-25 23:20:23 +00002530 for (pos = 0; pos < i; pos++) {
2531 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002532 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00002533
2534 key = PyList_GetItem(keys, pos);
2535 val = PyList_GetItem(vals, pos);
2536 if (!key || !val)
2537 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002538
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002539 if (!PyArg_Parse(
2540 key,
2541 "s;spawnve() arg 3 contains a non-string key",
2542 &k) ||
2543 !PyArg_Parse(
2544 val,
2545 "s;spawnve() arg 3 contains a non-string value",
2546 &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00002547 {
2548 goto fail_2;
2549 }
Tim Petersc8996f52001-12-03 20:41:00 +00002550 len = PyString_Size(key) + PyString_Size(val) + 2;
2551 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00002552 if (p == NULL) {
2553 PyErr_NoMemory();
2554 goto fail_2;
2555 }
Tim Petersc8996f52001-12-03 20:41:00 +00002556 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00002557 envlist[envc++] = p;
2558 }
2559 envlist[envc] = 0;
2560
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002561#if defined(PYOS_OS2) && defined(PYCC_GCC)
2562 Py_BEGIN_ALLOW_THREADS
2563 spawnval = spawnve(mode, path, argvlist, envlist);
2564 Py_END_ALLOW_THREADS
2565#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002566 if (mode == _OLD_P_OVERLAY)
2567 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00002568
2569 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002570 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00002571 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002572#endif
Tim Peters25059d32001-12-07 20:35:43 +00002573
Fred Drake699f3522000-06-29 21:12:41 +00002574 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002575 (void) posix_error();
2576 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002577#if SIZEOF_LONG == SIZEOF_VOID_P
2578 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002579#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00002580 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002581#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002582
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002583 fail_2:
Guido van Rossuma1065681999-01-25 23:20:23 +00002584 while (--envc >= 0)
2585 PyMem_DEL(envlist[envc]);
2586 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002587 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002588 free_string_array(argvlist, lastarg);
Guido van Rossuma1065681999-01-25 23:20:23 +00002589 Py_XDECREF(vals);
2590 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002591 fail_0:
2592 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002593 return res;
2594}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00002595
2596/* OS/2 supports spawnvp & spawnvpe natively */
2597#if defined(PYOS_OS2)
2598PyDoc_STRVAR(posix_spawnvp__doc__,
2599"spawnvp(mode, file, args)\n\n\
2600Execute the program 'file' in a new process, using the environment\n\
2601search path to find the file.\n\
2602\n\
2603 mode: mode of process creation\n\
2604 file: executable file name\n\
2605 args: tuple or list of strings");
2606
2607static PyObject *
2608posix_spawnvp(PyObject *self, PyObject *args)
2609{
2610 char *path;
2611 PyObject *argv;
2612 char **argvlist;
2613 int mode, i, argc;
2614 Py_intptr_t spawnval;
2615 PyObject *(*getitem)(PyObject *, int);
2616
2617 /* spawnvp has three arguments: (mode, path, argv), where
2618 argv is a list or tuple of strings. */
2619
2620 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
2621 Py_FileSystemDefaultEncoding,
2622 &path, &argv))
2623 return NULL;
2624 if (PyList_Check(argv)) {
2625 argc = PyList_Size(argv);
2626 getitem = PyList_GetItem;
2627 }
2628 else if (PyTuple_Check(argv)) {
2629 argc = PyTuple_Size(argv);
2630 getitem = PyTuple_GetItem;
2631 }
2632 else {
2633 PyErr_SetString(PyExc_TypeError,
2634 "spawnvp() arg 2 must be a tuple or list");
2635 PyMem_Free(path);
2636 return NULL;
2637 }
2638
2639 argvlist = PyMem_NEW(char *, argc+1);
2640 if (argvlist == NULL) {
2641 PyMem_Free(path);
2642 return PyErr_NoMemory();
2643 }
2644 for (i = 0; i < argc; i++) {
2645 if (!PyArg_Parse((*getitem)(argv, i), "et",
2646 Py_FileSystemDefaultEncoding,
2647 &argvlist[i])) {
2648 free_string_array(argvlist, i);
2649 PyErr_SetString(
2650 PyExc_TypeError,
2651 "spawnvp() arg 2 must contain only strings");
2652 PyMem_Free(path);
2653 return NULL;
2654 }
2655 }
2656 argvlist[argc] = NULL;
2657
2658 Py_BEGIN_ALLOW_THREADS
2659#if defined(PYCC_GCC)
2660 spawnval = spawnvp(mode, path, argvlist);
2661#else
2662 spawnval = _spawnvp(mode, path, argvlist);
2663#endif
2664 Py_END_ALLOW_THREADS
2665
2666 free_string_array(argvlist, argc);
2667 PyMem_Free(path);
2668
2669 if (spawnval == -1)
2670 return posix_error();
2671 else
2672 return Py_BuildValue("l", (long) spawnval);
2673}
2674
2675
2676PyDoc_STRVAR(posix_spawnvpe__doc__,
2677"spawnvpe(mode, file, args, env)\n\n\
2678Execute the program 'file' in a new process, using the environment\n\
2679search path to find the file.\n\
2680\n\
2681 mode: mode of process creation\n\
2682 file: executable file name\n\
2683 args: tuple or list of arguments\n\
2684 env: dictionary of strings mapping to strings");
2685
2686static PyObject *
2687posix_spawnvpe(PyObject *self, PyObject *args)
2688{
2689 char *path;
2690 PyObject *argv, *env;
2691 char **argvlist;
2692 char **envlist;
2693 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
2694 int mode, i, pos, argc, envc;
2695 Py_intptr_t spawnval;
2696 PyObject *(*getitem)(PyObject *, int);
2697 int lastarg = 0;
2698
2699 /* spawnvpe has four arguments: (mode, path, argv, env), where
2700 argv is a list or tuple of strings and env is a dictionary
2701 like posix.environ. */
2702
2703 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
2704 Py_FileSystemDefaultEncoding,
2705 &path, &argv, &env))
2706 return NULL;
2707 if (PyList_Check(argv)) {
2708 argc = PyList_Size(argv);
2709 getitem = PyList_GetItem;
2710 }
2711 else if (PyTuple_Check(argv)) {
2712 argc = PyTuple_Size(argv);
2713 getitem = PyTuple_GetItem;
2714 }
2715 else {
2716 PyErr_SetString(PyExc_TypeError,
2717 "spawnvpe() arg 2 must be a tuple or list");
2718 goto fail_0;
2719 }
2720 if (!PyMapping_Check(env)) {
2721 PyErr_SetString(PyExc_TypeError,
2722 "spawnvpe() arg 3 must be a mapping object");
2723 goto fail_0;
2724 }
2725
2726 argvlist = PyMem_NEW(char *, argc+1);
2727 if (argvlist == NULL) {
2728 PyErr_NoMemory();
2729 goto fail_0;
2730 }
2731 for (i = 0; i < argc; i++) {
2732 if (!PyArg_Parse((*getitem)(argv, i),
2733 "et;spawnvpe() arg 2 must contain only strings",
2734 Py_FileSystemDefaultEncoding,
2735 &argvlist[i]))
2736 {
2737 lastarg = i;
2738 goto fail_1;
2739 }
2740 }
2741 lastarg = argc;
2742 argvlist[argc] = NULL;
2743
2744 i = PyMapping_Size(env);
2745 if (i < 0)
2746 goto fail_1;
2747 envlist = PyMem_NEW(char *, i + 1);
2748 if (envlist == NULL) {
2749 PyErr_NoMemory();
2750 goto fail_1;
2751 }
2752 envc = 0;
2753 keys = PyMapping_Keys(env);
2754 vals = PyMapping_Values(env);
2755 if (!keys || !vals)
2756 goto fail_2;
2757 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2758 PyErr_SetString(PyExc_TypeError,
2759 "spawnvpe(): env.keys() or env.values() is not a list");
2760 goto fail_2;
2761 }
2762
2763 for (pos = 0; pos < i; pos++) {
2764 char *p, *k, *v;
2765 size_t len;
2766
2767 key = PyList_GetItem(keys, pos);
2768 val = PyList_GetItem(vals, pos);
2769 if (!key || !val)
2770 goto fail_2;
2771
2772 if (!PyArg_Parse(
2773 key,
2774 "s;spawnvpe() arg 3 contains a non-string key",
2775 &k) ||
2776 !PyArg_Parse(
2777 val,
2778 "s;spawnvpe() arg 3 contains a non-string value",
2779 &v))
2780 {
2781 goto fail_2;
2782 }
2783 len = PyString_Size(key) + PyString_Size(val) + 2;
2784 p = PyMem_NEW(char, len);
2785 if (p == NULL) {
2786 PyErr_NoMemory();
2787 goto fail_2;
2788 }
2789 PyOS_snprintf(p, len, "%s=%s", k, v);
2790 envlist[envc++] = p;
2791 }
2792 envlist[envc] = 0;
2793
2794 Py_BEGIN_ALLOW_THREADS
2795#if defined(PYCC_GCC)
2796 spawnval = spawnve(mode, path, argvlist, envlist);
2797#else
2798 spawnval = _spawnve(mode, path, argvlist, envlist);
2799#endif
2800 Py_END_ALLOW_THREADS
2801
2802 if (spawnval == -1)
2803 (void) posix_error();
2804 else
2805 res = Py_BuildValue("l", (long) spawnval);
2806
2807 fail_2:
2808 while (--envc >= 0)
2809 PyMem_DEL(envlist[envc]);
2810 PyMem_DEL(envlist);
2811 fail_1:
2812 free_string_array(argvlist, lastarg);
2813 Py_XDECREF(vals);
2814 Py_XDECREF(keys);
2815 fail_0:
2816 PyMem_Free(path);
2817 return res;
2818}
2819#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00002820#endif /* HAVE_SPAWNV */
2821
2822
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002823#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002824PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002825"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002826Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
2827\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002828Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002829
2830static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002831posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002832{
Neal Norwitze241ce82003-02-17 18:17:05 +00002833 int pid = fork1();
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002834 if (pid == -1)
2835 return posix_error();
2836 PyOS_AfterFork();
2837 return PyInt_FromLong((long)pid);
2838}
2839#endif
2840
2841
Guido van Rossumad0ee831995-03-01 10:34:45 +00002842#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002843PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002844"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002845Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002846Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002847
Barry Warsaw53699e91996-12-10 23:23:01 +00002848static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002849posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002850{
Neal Norwitze241ce82003-02-17 18:17:05 +00002851 int pid = fork();
Guido van Rossum85e3b011991-06-03 12:42:10 +00002852 if (pid == -1)
2853 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00002854 if (pid == 0)
2855 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00002856 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002857}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002858#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002859
Neal Norwitzb59798b2003-03-21 01:43:31 +00002860/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00002861/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
2862#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00002863#define DEV_PTY_FILE "/dev/ptc"
2864#define HAVE_DEV_PTMX
2865#else
2866#define DEV_PTY_FILE "/dev/ptmx"
2867#endif
2868
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002869#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002870#ifdef HAVE_PTY_H
2871#include <pty.h>
2872#else
2873#ifdef HAVE_LIBUTIL_H
2874#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00002875#endif /* HAVE_LIBUTIL_H */
2876#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00002877#ifdef HAVE_STROPTS_H
2878#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002879#endif
2880#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00002881
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002882#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002883PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002884"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002885Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00002886
2887static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002888posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002889{
2890 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00002891#ifndef HAVE_OPENPTY
2892 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00002893#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002894#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00002895 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002896#ifdef sun
2897 extern char *ptsname();
2898#endif
2899#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00002900
Thomas Wouters70c21a12000-07-14 14:28:33 +00002901#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00002902 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
2903 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00002904#elif defined(HAVE__GETPTY)
Thomas Wouters70c21a12000-07-14 14:28:33 +00002905 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
2906 if (slave_name == NULL)
2907 return posix_error();
2908
2909 slave_fd = open(slave_name, O_RDWR);
2910 if (slave_fd < 0)
2911 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002912#else
Neal Norwitzb59798b2003-03-21 01:43:31 +00002913 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002914 if (master_fd < 0)
2915 return posix_error();
2916 sig_saved = signal(SIGCHLD, SIG_DFL);
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00002917 /* change permission of slave */
2918 if (grantpt(master_fd) < 0) {
2919 signal(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002920 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00002921 }
2922 /* unlock slave */
2923 if (unlockpt(master_fd) < 0) {
2924 signal(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002925 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00002926 }
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002927 signal(SIGCHLD, sig_saved);
2928 slave_name = ptsname(master_fd); /* get name of slave */
2929 if (slave_name == NULL)
2930 return posix_error();
2931 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
2932 if (slave_fd < 0)
2933 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00002934#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002935 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
2936 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00002937#ifndef __hpux
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002938 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00002939#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002940#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00002941#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00002942
Fred Drake8cef4cf2000-06-28 16:40:38 +00002943 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00002944
Fred Drake8cef4cf2000-06-28 16:40:38 +00002945}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002946#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00002947
2948#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002949PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002950"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00002951Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
2952Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002953To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00002954
2955static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002956posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002957{
2958 int master_fd, pid;
Tim Peters5aa91602002-01-30 05:46:57 +00002959
Fred Drake8cef4cf2000-06-28 16:40:38 +00002960 pid = forkpty(&master_fd, NULL, NULL, NULL);
2961 if (pid == -1)
2962 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00002963 if (pid == 0)
2964 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00002965 return Py_BuildValue("(ii)", pid, master_fd);
2966}
2967#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002968
Guido van Rossumad0ee831995-03-01 10:34:45 +00002969#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002970PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002971"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002972Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002973
Barry Warsaw53699e91996-12-10 23:23:01 +00002974static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002975posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002976{
Barry Warsaw53699e91996-12-10 23:23:01 +00002977 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002978}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002979#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002980
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002981
Guido van Rossumad0ee831995-03-01 10:34:45 +00002982#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002983PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002984"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002985Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002986
Barry Warsaw53699e91996-12-10 23:23:01 +00002987static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002988posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00002989{
Barry Warsaw53699e91996-12-10 23:23:01 +00002990 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00002991}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002992#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00002993
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002994
Guido van Rossumad0ee831995-03-01 10:34:45 +00002995#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002996PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002997"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002998Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002999
Barry Warsaw53699e91996-12-10 23:23:01 +00003000static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003001posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003002{
Barry Warsaw53699e91996-12-10 23:23:01 +00003003 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003004}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003005#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003006
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003007
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003008PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003009"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003010Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003011
Barry Warsaw53699e91996-12-10 23:23:01 +00003012static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003013posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003014{
Barry Warsaw53699e91996-12-10 23:23:01 +00003015 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003016}
3017
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003018
Fred Drakec9680921999-12-13 16:37:25 +00003019#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003020PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003021"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003022Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00003023
3024static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003025posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00003026{
3027 PyObject *result = NULL;
3028
Fred Drakec9680921999-12-13 16:37:25 +00003029#ifdef NGROUPS_MAX
3030#define MAX_GROUPS NGROUPS_MAX
3031#else
3032 /* defined to be 16 on Solaris7, so this should be a small number */
3033#define MAX_GROUPS 64
3034#endif
3035 gid_t grouplist[MAX_GROUPS];
3036 int n;
3037
3038 n = getgroups(MAX_GROUPS, grouplist);
3039 if (n < 0)
3040 posix_error();
3041 else {
3042 result = PyList_New(n);
3043 if (result != NULL) {
Fred Drakec9680921999-12-13 16:37:25 +00003044 int i;
3045 for (i = 0; i < n; ++i) {
Neal Norwitze241ce82003-02-17 18:17:05 +00003046 PyObject *o = PyInt_FromLong((long)grouplist[i]);
Fred Drakec9680921999-12-13 16:37:25 +00003047 if (o == NULL) {
3048 Py_DECREF(result);
3049 result = NULL;
3050 break;
3051 }
3052 PyList_SET_ITEM(result, i, o);
3053 }
3054 }
3055 }
Neal Norwitze241ce82003-02-17 18:17:05 +00003056
Fred Drakec9680921999-12-13 16:37:25 +00003057 return result;
3058}
3059#endif
3060
Martin v. Löwis606edc12002-06-13 21:09:11 +00003061#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003062PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003063"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003064Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00003065
3066static PyObject *
3067posix_getpgid(PyObject *self, PyObject *args)
3068{
3069 int pid, pgid;
3070 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
3071 return NULL;
3072 pgid = getpgid(pid);
3073 if (pgid < 0)
3074 return posix_error();
3075 return PyInt_FromLong((long)pgid);
3076}
3077#endif /* HAVE_GETPGID */
3078
3079
Guido van Rossumb6775db1994-08-01 11:34:53 +00003080#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003081PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003082"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003083Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003084
Barry Warsaw53699e91996-12-10 23:23:01 +00003085static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003086posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00003087{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003088#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00003089 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003090#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00003091 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003092#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00003093}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003094#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00003095
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003096
Guido van Rossumb6775db1994-08-01 11:34:53 +00003097#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003098PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003099"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003100Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003101
Barry Warsaw53699e91996-12-10 23:23:01 +00003102static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003103posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003104{
Guido van Rossum64933891994-10-20 21:56:42 +00003105#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00003106 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003107#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003108 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003109#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00003110 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003111 Py_INCREF(Py_None);
3112 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003113}
3114
Guido van Rossumb6775db1994-08-01 11:34:53 +00003115#endif /* HAVE_SETPGRP */
3116
Guido van Rossumad0ee831995-03-01 10:34:45 +00003117#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003118PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003119"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003120Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003121
Barry Warsaw53699e91996-12-10 23:23:01 +00003122static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003123posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003124{
Barry Warsaw53699e91996-12-10 23:23:01 +00003125 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003126}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003127#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003128
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003129
Fred Drake12c6e2d1999-12-14 21:25:03 +00003130#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003131PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003132"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003133Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00003134
3135static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003136posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00003137{
Neal Norwitze241ce82003-02-17 18:17:05 +00003138 PyObject *result = NULL;
Fred Drakea30680b2000-12-06 21:24:28 +00003139 char *name;
3140 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00003141
Fred Drakea30680b2000-12-06 21:24:28 +00003142 errno = 0;
3143 name = getlogin();
3144 if (name == NULL) {
3145 if (errno)
3146 posix_error();
3147 else
3148 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00003149 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00003150 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00003151 else
3152 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00003153 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00003154
Fred Drake12c6e2d1999-12-14 21:25:03 +00003155 return result;
3156}
3157#endif
3158
Guido van Rossumad0ee831995-03-01 10:34:45 +00003159#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003160PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003161"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003162Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003163
Barry Warsaw53699e91996-12-10 23:23:01 +00003164static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003165posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003166{
Barry Warsaw53699e91996-12-10 23:23:01 +00003167 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003168}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003169#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003170
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003171
Guido van Rossumad0ee831995-03-01 10:34:45 +00003172#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003173PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003174"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003175Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003176
Barry Warsaw53699e91996-12-10 23:23:01 +00003177static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003178posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003179{
3180 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003181 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00003182 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003183#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003184 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
3185 APIRET rc;
3186 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003187 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003188
3189 } else if (sig == XCPT_SIGNAL_KILLPROC) {
3190 APIRET rc;
3191 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003192 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003193
3194 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003195 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003196#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00003197 if (kill(pid, sig) == -1)
3198 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003199#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003200 Py_INCREF(Py_None);
3201 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003202}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003203#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003204
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003205#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003206PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003207"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003208Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003209
3210static PyObject *
3211posix_killpg(PyObject *self, PyObject *args)
3212{
3213 int pgid, sig;
3214 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
3215 return NULL;
3216 if (killpg(pgid, sig) == -1)
3217 return posix_error();
3218 Py_INCREF(Py_None);
3219 return Py_None;
3220}
3221#endif
3222
Guido van Rossumc0125471996-06-28 18:55:32 +00003223#ifdef HAVE_PLOCK
3224
3225#ifdef HAVE_SYS_LOCK_H
3226#include <sys/lock.h>
3227#endif
3228
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003229PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003230"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003231Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003232
Barry Warsaw53699e91996-12-10 23:23:01 +00003233static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003234posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00003235{
3236 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003237 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00003238 return NULL;
3239 if (plock(op) == -1)
3240 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003241 Py_INCREF(Py_None);
3242 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00003243}
3244#endif
3245
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003246
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003247#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003248PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003249"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003250Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003251
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003252#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003253#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003254static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003255async_system(const char *command)
3256{
3257 char *p, errormsg[256], args[1024];
3258 RESULTCODES rcodes;
3259 APIRET rc;
3260 char *shell = getenv("COMSPEC");
3261 if (!shell)
3262 shell = "cmd";
3263
3264 strcpy(args, shell);
3265 p = &args[ strlen(args)+1 ];
3266 strcpy(p, "/c ");
3267 strcat(p, command);
3268 p += strlen(p) + 1;
3269 *p = '\0';
3270
3271 rc = DosExecPgm(errormsg, sizeof(errormsg),
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003272 EXEC_ASYNC, /* Execute Async w/o Wait for Results */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003273 args,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003274 NULL, /* Inherit Parent's Environment */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003275 &rcodes, shell);
3276 return rc;
3277}
3278
Guido van Rossumd48f2521997-12-05 22:19:34 +00003279static FILE *
3280popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003281{
3282 HFILE rhan, whan;
3283 FILE *retfd = NULL;
3284 APIRET rc = DosCreatePipe(&rhan, &whan, pipesize);
3285
Guido van Rossumd48f2521997-12-05 22:19:34 +00003286 if (rc != NO_ERROR) {
3287 *err = rc;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003288 return NULL; /* ERROR - Unable to Create Anon Pipe */
Guido van Rossumd48f2521997-12-05 22:19:34 +00003289 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003290
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003291 if (strchr(mode, 'r') != NULL) { /* Treat Command as a Data Source */
3292 int oldfd = dup(1); /* Save STDOUT Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003293
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003294 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
3295 close(1); /* Make STDOUT Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003296
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003297 if (dup2(whan, 1) == 0) { /* Connect STDOUT to Pipe Write Side */
3298 DosClose(whan); /* Close Now-Unused Pipe Write Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003299
Martin v. Löwisdedbe252001-11-02 23:59:11 +00003300 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003301 }
3302
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003303 dup2(oldfd, 1); /* Reconnect STDOUT to Original Handle */
3304 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003305
Martin v. Löwisdedbe252001-11-02 23:59:11 +00003306 if (rc == NO_ERROR)
3307 retfd = fdopen(rhan, mode); /* And Return Pipe Read Handle */
3308
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003309 close(oldfd); /* And Close Saved STDOUT Handle */
3310 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003311
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003312 } else if (strchr(mode, 'w')) { /* Treat Command as a Data Sink */
3313 int oldfd = dup(0); /* Save STDIN Handle in Another Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003314
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003315 DosEnterCritSec(); /* Stop Other Threads While Changing Handles */
3316 close(0); /* Make STDIN Available for Reallocation */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003317
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003318 if (dup2(rhan, 0) == 0) { /* Connect STDIN to Pipe Read Side */
3319 DosClose(rhan); /* Close Now-Unused Pipe Read Handle */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003320
Martin v. Löwisdedbe252001-11-02 23:59:11 +00003321 rc = async_system(command);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003322 }
3323
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003324 dup2(oldfd, 0); /* Reconnect STDIN to Original Handle */
3325 DosExitCritSec(); /* Now Allow Other Threads to Run */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003326
Martin v. Löwisdedbe252001-11-02 23:59:11 +00003327 if (rc == NO_ERROR)
3328 retfd = fdopen(whan, mode); /* And Return Pipe Write Handle */
3329
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003330 close(oldfd); /* And Close Saved STDIN Handle */
3331 return retfd; /* Return fd of Pipe or NULL if Error */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003332
Guido van Rossumd48f2521997-12-05 22:19:34 +00003333 } else {
3334 *err = ERROR_INVALID_ACCESS;
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003335 return NULL; /* ERROR - Invalid Mode (Neither Read nor Write) */
Guido van Rossumd48f2521997-12-05 22:19:34 +00003336 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003337}
3338
3339static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003340posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003341{
3342 char *name;
3343 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00003344 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003345 FILE *fp;
3346 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003347 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003348 return NULL;
3349 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00003350 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003351 Py_END_ALLOW_THREADS
3352 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003353 return os2_error(err);
3354
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003355 f = PyFile_FromFile(fp, name, mode, fclose);
3356 if (f != NULL)
3357 PyFile_SetBufSize(f, bufsize);
3358 return f;
3359}
3360
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003361#elif defined(PYCC_GCC)
3362
3363/* standard posix version of popen() support */
3364static PyObject *
3365posix_popen(PyObject *self, PyObject *args)
3366{
3367 char *name;
3368 char *mode = "r";
3369 int bufsize = -1;
3370 FILE *fp;
3371 PyObject *f;
3372 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
3373 return NULL;
3374 Py_BEGIN_ALLOW_THREADS
3375 fp = popen(name, mode);
3376 Py_END_ALLOW_THREADS
3377 if (fp == NULL)
3378 return posix_error();
3379 f = PyFile_FromFile(fp, name, mode, pclose);
3380 if (f != NULL)
3381 PyFile_SetBufSize(f, bufsize);
3382 return f;
3383}
3384
3385/* fork() under OS/2 has lots'o'warts
3386 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
3387 * most of this code is a ripoff of the win32 code, but using the
3388 * capabilities of EMX's C library routines
3389 */
3390
3391/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
3392#define POPEN_1 1
3393#define POPEN_2 2
3394#define POPEN_3 3
3395#define POPEN_4 4
3396
3397static PyObject *_PyPopen(char *, int, int, int);
3398static int _PyPclose(FILE *file);
3399
3400/*
3401 * Internal dictionary mapping popen* file pointers to process handles,
3402 * for use when retrieving the process exit code. See _PyPclose() below
3403 * for more information on this dictionary's use.
3404 */
3405static PyObject *_PyPopenProcs = NULL;
3406
3407/* os2emx version of popen2()
3408 *
3409 * The result of this function is a pipe (file) connected to the
3410 * process's stdin, and a pipe connected to the process's stdout.
3411 */
3412
3413static PyObject *
3414os2emx_popen2(PyObject *self, PyObject *args)
3415{
3416 PyObject *f;
3417 int tm=0;
3418
3419 char *cmdstring;
3420 char *mode = "t";
3421 int bufsize = -1;
3422 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
3423 return NULL;
3424
3425 if (*mode == 't')
3426 tm = O_TEXT;
3427 else if (*mode != 'b') {
3428 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3429 return NULL;
3430 } else
3431 tm = O_BINARY;
3432
3433 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
3434
3435 return f;
3436}
3437
3438/*
3439 * Variation on os2emx.popen2
3440 *
3441 * The result of this function is 3 pipes - the process's stdin,
3442 * stdout and stderr
3443 */
3444
3445static PyObject *
3446os2emx_popen3(PyObject *self, PyObject *args)
3447{
3448 PyObject *f;
3449 int tm = 0;
3450
3451 char *cmdstring;
3452 char *mode = "t";
3453 int bufsize = -1;
3454 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
3455 return NULL;
3456
3457 if (*mode == 't')
3458 tm = O_TEXT;
3459 else if (*mode != 'b') {
3460 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3461 return NULL;
3462 } else
3463 tm = O_BINARY;
3464
3465 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
3466
3467 return f;
3468}
3469
3470/*
3471 * Variation on os2emx.popen2
3472 *
Tim Peters11b23062003-04-23 02:39:17 +00003473 * The result of this function is 2 pipes - the processes stdin,
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003474 * and stdout+stderr combined as a single pipe.
3475 */
3476
3477static PyObject *
3478os2emx_popen4(PyObject *self, PyObject *args)
3479{
3480 PyObject *f;
3481 int tm = 0;
3482
3483 char *cmdstring;
3484 char *mode = "t";
3485 int bufsize = -1;
3486 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
3487 return NULL;
3488
3489 if (*mode == 't')
3490 tm = O_TEXT;
3491 else if (*mode != 'b') {
3492 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3493 return NULL;
3494 } else
3495 tm = O_BINARY;
3496
3497 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
3498
3499 return f;
3500}
3501
3502/* a couple of structures for convenient handling of multiple
3503 * file handles and pipes
3504 */
3505struct file_ref
3506{
3507 int handle;
3508 int flags;
3509};
3510
3511struct pipe_ref
3512{
3513 int rd;
3514 int wr;
3515};
3516
3517/* The following code is derived from the win32 code */
3518
3519static PyObject *
3520_PyPopen(char *cmdstring, int mode, int n, int bufsize)
3521{
3522 struct file_ref stdio[3];
3523 struct pipe_ref p_fd[3];
3524 FILE *p_s[3];
3525 int file_count, i, pipe_err, pipe_pid;
3526 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
3527 PyObject *f, *p_f[3];
3528
3529 /* file modes for subsequent fdopen's on pipe handles */
3530 if (mode == O_TEXT)
3531 {
3532 rd_mode = "rt";
3533 wr_mode = "wt";
3534 }
3535 else
3536 {
3537 rd_mode = "rb";
3538 wr_mode = "wb";
3539 }
3540
3541 /* prepare shell references */
3542 if ((shell = getenv("EMXSHELL")) == NULL)
3543 if ((shell = getenv("COMSPEC")) == NULL)
3544 {
3545 errno = ENOENT;
3546 return posix_error();
3547 }
3548
3549 sh_name = _getname(shell);
3550 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
3551 opt = "/c";
3552 else
3553 opt = "-c";
3554
3555 /* save current stdio fds + their flags, and set not inheritable */
3556 i = pipe_err = 0;
3557 while (pipe_err >= 0 && i < 3)
3558 {
3559 pipe_err = stdio[i].handle = dup(i);
3560 stdio[i].flags = fcntl(i, F_GETFD, 0);
3561 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
3562 i++;
3563 }
3564 if (pipe_err < 0)
3565 {
3566 /* didn't get them all saved - clean up and bail out */
3567 int saved_err = errno;
3568 while (i-- > 0)
3569 {
3570 close(stdio[i].handle);
3571 }
3572 errno = saved_err;
3573 return posix_error();
3574 }
3575
3576 /* create pipe ends */
3577 file_count = 2;
3578 if (n == POPEN_3)
3579 file_count = 3;
3580 i = pipe_err = 0;
3581 while ((pipe_err == 0) && (i < file_count))
3582 pipe_err = pipe((int *)&p_fd[i++]);
3583 if (pipe_err < 0)
3584 {
3585 /* didn't get them all made - clean up and bail out */
3586 while (i-- > 0)
3587 {
3588 close(p_fd[i].wr);
3589 close(p_fd[i].rd);
3590 }
3591 errno = EPIPE;
3592 return posix_error();
3593 }
3594
3595 /* change the actual standard IO streams over temporarily,
3596 * making the retained pipe ends non-inheritable
3597 */
3598 pipe_err = 0;
3599
3600 /* - stdin */
3601 if (dup2(p_fd[0].rd, 0) == 0)
3602 {
3603 close(p_fd[0].rd);
3604 i = fcntl(p_fd[0].wr, F_GETFD, 0);
3605 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
3606 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
3607 {
3608 close(p_fd[0].wr);
3609 pipe_err = -1;
3610 }
3611 }
3612 else
3613 {
3614 pipe_err = -1;
3615 }
3616
3617 /* - stdout */
3618 if (pipe_err == 0)
3619 {
3620 if (dup2(p_fd[1].wr, 1) == 1)
3621 {
3622 close(p_fd[1].wr);
3623 i = fcntl(p_fd[1].rd, F_GETFD, 0);
3624 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
3625 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
3626 {
3627 close(p_fd[1].rd);
3628 pipe_err = -1;
3629 }
3630 }
3631 else
3632 {
3633 pipe_err = -1;
3634 }
3635 }
3636
3637 /* - stderr, as required */
3638 if (pipe_err == 0)
3639 switch (n)
3640 {
3641 case POPEN_3:
3642 {
3643 if (dup2(p_fd[2].wr, 2) == 2)
3644 {
3645 close(p_fd[2].wr);
3646 i = fcntl(p_fd[2].rd, F_GETFD, 0);
3647 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
3648 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
3649 {
3650 close(p_fd[2].rd);
3651 pipe_err = -1;
3652 }
3653 }
3654 else
3655 {
3656 pipe_err = -1;
3657 }
3658 break;
3659 }
3660
3661 case POPEN_4:
3662 {
3663 if (dup2(1, 2) != 2)
3664 {
3665 pipe_err = -1;
3666 }
3667 break;
3668 }
3669 }
3670
3671 /* spawn the child process */
3672 if (pipe_err == 0)
3673 {
3674 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
3675 if (pipe_pid == -1)
3676 {
3677 pipe_err = -1;
3678 }
3679 else
3680 {
3681 /* save the PID into the FILE structure
3682 * NOTE: this implementation doesn't actually
3683 * take advantage of this, but do it for
3684 * completeness - AIM Apr01
3685 */
3686 for (i = 0; i < file_count; i++)
3687 p_s[i]->_pid = pipe_pid;
3688 }
3689 }
3690
3691 /* reset standard IO to normal */
3692 for (i = 0; i < 3; i++)
3693 {
3694 dup2(stdio[i].handle, i);
3695 fcntl(i, F_SETFD, stdio[i].flags);
3696 close(stdio[i].handle);
3697 }
3698
3699 /* if any remnant problems, clean up and bail out */
3700 if (pipe_err < 0)
3701 {
3702 for (i = 0; i < 3; i++)
3703 {
3704 close(p_fd[i].rd);
3705 close(p_fd[i].wr);
3706 }
3707 errno = EPIPE;
3708 return posix_error_with_filename(cmdstring);
3709 }
3710
3711 /* build tuple of file objects to return */
3712 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
3713 PyFile_SetBufSize(p_f[0], bufsize);
3714 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
3715 PyFile_SetBufSize(p_f[1], bufsize);
3716 if (n == POPEN_3)
3717 {
3718 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
3719 PyFile_SetBufSize(p_f[0], bufsize);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00003720 f = PyTuple_Pack(3, p_f[0], p_f[1], p_f[2]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003721 }
3722 else
Raymond Hettinger8ae46892003-10-12 19:09:37 +00003723 f = PyTuple_Pack(2, p_f[0], p_f[1]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003724
3725 /*
3726 * Insert the files we've created into the process dictionary
3727 * all referencing the list with the process handle and the
3728 * initial number of files (see description below in _PyPclose).
3729 * Since if _PyPclose later tried to wait on a process when all
3730 * handles weren't closed, it could create a deadlock with the
3731 * child, we spend some energy here to try to ensure that we
3732 * either insert all file handles into the dictionary or none
3733 * at all. It's a little clumsy with the various popen modes
3734 * and variable number of files involved.
3735 */
3736 if (!_PyPopenProcs)
3737 {
3738 _PyPopenProcs = PyDict_New();
3739 }
3740
3741 if (_PyPopenProcs)
3742 {
3743 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
3744 int ins_rc[3];
3745
3746 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
3747 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
3748
3749 procObj = PyList_New(2);
3750 pidObj = PyInt_FromLong((long) pipe_pid);
3751 intObj = PyInt_FromLong((long) file_count);
3752
3753 if (procObj && pidObj && intObj)
3754 {
3755 PyList_SetItem(procObj, 0, pidObj);
3756 PyList_SetItem(procObj, 1, intObj);
3757
3758 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
3759 if (fileObj[0])
3760 {
3761 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
3762 fileObj[0],
3763 procObj);
3764 }
3765 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
3766 if (fileObj[1])
3767 {
3768 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
3769 fileObj[1],
3770 procObj);
3771 }
3772 if (file_count >= 3)
3773 {
3774 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
3775 if (fileObj[2])
3776 {
3777 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
3778 fileObj[2],
3779 procObj);
3780 }
3781 }
3782
3783 if (ins_rc[0] < 0 || !fileObj[0] ||
3784 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
3785 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
3786 {
3787 /* Something failed - remove any dictionary
3788 * entries that did make it.
3789 */
3790 if (!ins_rc[0] && fileObj[0])
3791 {
3792 PyDict_DelItem(_PyPopenProcs,
3793 fileObj[0]);
3794 }
3795 if (!ins_rc[1] && fileObj[1])
3796 {
3797 PyDict_DelItem(_PyPopenProcs,
3798 fileObj[1]);
3799 }
3800 if (!ins_rc[2] && fileObj[2])
3801 {
3802 PyDict_DelItem(_PyPopenProcs,
3803 fileObj[2]);
3804 }
3805 }
3806 }
Tim Peters11b23062003-04-23 02:39:17 +00003807
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003808 /*
3809 * Clean up our localized references for the dictionary keys
3810 * and value since PyDict_SetItem will Py_INCREF any copies
3811 * that got placed in the dictionary.
3812 */
3813 Py_XDECREF(procObj);
3814 Py_XDECREF(fileObj[0]);
3815 Py_XDECREF(fileObj[1]);
3816 Py_XDECREF(fileObj[2]);
3817 }
3818
3819 /* Child is launched. */
3820 return f;
3821}
3822
3823/*
3824 * Wrapper for fclose() to use for popen* files, so we can retrieve the
3825 * exit code for the child process and return as a result of the close.
3826 *
3827 * This function uses the _PyPopenProcs dictionary in order to map the
3828 * input file pointer to information about the process that was
3829 * originally created by the popen* call that created the file pointer.
3830 * The dictionary uses the file pointer as a key (with one entry
3831 * inserted for each file returned by the original popen* call) and a
3832 * single list object as the value for all files from a single call.
3833 * The list object contains the Win32 process handle at [0], and a file
3834 * count at [1], which is initialized to the total number of file
3835 * handles using that list.
3836 *
3837 * This function closes whichever handle it is passed, and decrements
3838 * the file count in the dictionary for the process handle pointed to
3839 * by this file. On the last close (when the file count reaches zero),
3840 * this function will wait for the child process and then return its
3841 * exit code as the result of the close() operation. This permits the
3842 * files to be closed in any order - it is always the close() of the
3843 * final handle that will return the exit code.
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00003844 *
3845 * NOTE: This function is currently called with the GIL released.
3846 * hence we use the GILState API to manage our state.
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003847 */
3848
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003849static int _PyPclose(FILE *file)
3850{
3851 int result;
3852 int exit_code;
3853 int pipe_pid;
3854 PyObject *procObj, *pidObj, *intObj, *fileObj;
3855 int file_count;
3856#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00003857 PyGILState_STATE state;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003858#endif
3859
3860 /* Close the file handle first, to ensure it can't block the
3861 * child from exiting if it's the last handle.
3862 */
3863 result = fclose(file);
3864
3865#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00003866 state = PyGILState_Ensure();
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003867#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003868 if (_PyPopenProcs)
3869 {
3870 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
3871 (procObj = PyDict_GetItem(_PyPopenProcs,
3872 fileObj)) != NULL &&
3873 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
3874 (intObj = PyList_GetItem(procObj,1)) != NULL)
3875 {
3876 pipe_pid = (int) PyInt_AsLong(pidObj);
3877 file_count = (int) PyInt_AsLong(intObj);
3878
3879 if (file_count > 1)
3880 {
3881 /* Still other files referencing process */
3882 file_count--;
3883 PyList_SetItem(procObj,1,
3884 PyInt_FromLong((long) file_count));
3885 }
3886 else
3887 {
3888 /* Last file for this process */
3889 if (result != EOF &&
3890 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
3891 {
3892 /* extract exit status */
3893 if (WIFEXITED(exit_code))
3894 {
3895 result = WEXITSTATUS(exit_code);
3896 }
3897 else
3898 {
3899 errno = EPIPE;
3900 result = -1;
3901 }
3902 }
3903 else
3904 {
3905 /* Indicate failure - this will cause the file object
3906 * to raise an I/O error and translate the last
3907 * error code from errno. We do have a problem with
3908 * last errors that overlap the normal errno table,
3909 * but that's a consistent problem with the file object.
3910 */
3911 result = -1;
3912 }
3913 }
3914
3915 /* Remove this file pointer from dictionary */
3916 PyDict_DelItem(_PyPopenProcs, fileObj);
3917
3918 if (PyDict_Size(_PyPopenProcs) == 0)
3919 {
3920 Py_DECREF(_PyPopenProcs);
3921 _PyPopenProcs = NULL;
3922 }
3923
3924 } /* if object retrieval ok */
3925
3926 Py_XDECREF(fileObj);
3927 } /* if _PyPopenProcs */
3928
3929#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00003930 PyGILState_Release(state);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003931#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003932 return result;
3933}
3934
3935#endif /* PYCC_??? */
3936
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003937#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003938
3939/*
3940 * Portable 'popen' replacement for Win32.
3941 *
3942 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
3943 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00003944 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003945 */
3946
3947#include <malloc.h>
3948#include <io.h>
3949#include <fcntl.h>
3950
3951/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
3952#define POPEN_1 1
3953#define POPEN_2 2
3954#define POPEN_3 3
3955#define POPEN_4 4
3956
3957static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00003958static int _PyPclose(FILE *file);
3959
3960/*
3961 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00003962 * for use when retrieving the process exit code. See _PyPclose() below
3963 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00003964 */
3965static PyObject *_PyPopenProcs = NULL;
3966
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003967
3968/* popen that works from a GUI.
3969 *
3970 * The result of this function is a pipe (file) connected to the
3971 * processes stdin or stdout, depending on the requested mode.
3972 */
3973
3974static PyObject *
3975posix_popen(PyObject *self, PyObject *args)
3976{
Raymond Hettingerb5cb6652003-09-01 22:25:41 +00003977 PyObject *f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003978 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00003979
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003980 char *cmdstring;
3981 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00003982 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003983 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003984 return NULL;
3985
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003986 if (*mode == 'r')
3987 tm = _O_RDONLY;
3988 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00003989 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003990 return NULL;
3991 } else
3992 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00003993
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003994 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00003995 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00003996 return NULL;
3997 }
3998
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003999 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004000 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004001 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004002 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004003 else
4004 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
4005
4006 return f;
4007}
4008
4009/* Variation on win32pipe.popen
4010 *
4011 * The result of this function is a pipe (file) connected to the
4012 * process's stdin, and a pipe connected to the process's stdout.
4013 */
4014
4015static PyObject *
4016win32_popen2(PyObject *self, PyObject *args)
4017{
4018 PyObject *f;
4019 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00004020
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004021 char *cmdstring;
4022 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004023 int bufsize = -1;
4024 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004025 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004026
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004027 if (*mode == 't')
4028 tm = _O_TEXT;
4029 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004030 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004031 return NULL;
4032 } else
4033 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004034
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004035 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004036 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004037 return NULL;
4038 }
4039
4040 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00004041
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004042 return f;
4043}
4044
4045/*
4046 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004047 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004048 * The result of this function is 3 pipes - the process's stdin,
4049 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004050 */
4051
4052static PyObject *
4053win32_popen3(PyObject *self, PyObject *args)
4054{
4055 PyObject *f;
4056 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004057
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004058 char *cmdstring;
4059 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004060 int bufsize = -1;
4061 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004062 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004063
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004064 if (*mode == 't')
4065 tm = _O_TEXT;
4066 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004067 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004068 return NULL;
4069 } else
4070 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004071
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004072 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004073 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004074 return NULL;
4075 }
4076
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004077 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00004078
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004079 return f;
4080}
4081
4082/*
4083 * Variation on win32pipe.popen
4084 *
Tim Peters5aa91602002-01-30 05:46:57 +00004085 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004086 * and stdout+stderr combined as a single pipe.
4087 */
4088
4089static PyObject *
4090win32_popen4(PyObject *self, PyObject *args)
4091{
4092 PyObject *f;
4093 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004094
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004095 char *cmdstring;
4096 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004097 int bufsize = -1;
4098 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004099 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004100
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004101 if (*mode == 't')
4102 tm = _O_TEXT;
4103 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004104 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004105 return NULL;
4106 } else
4107 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004108
4109 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004110 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004111 return NULL;
4112 }
4113
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004114 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004115
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004116 return f;
4117}
4118
Mark Hammond08501372001-01-31 07:30:29 +00004119static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00004120_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004121 HANDLE hStdin,
4122 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00004123 HANDLE hStderr,
4124 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004125{
4126 PROCESS_INFORMATION piProcInfo;
4127 STARTUPINFO siStartInfo;
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004128 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004129 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00004130 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004131 int i;
4132 int x;
4133
4134 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00004135 char *comshell;
4136
Tim Peters92e4dd82002-10-05 01:47:34 +00004137 s1 = (char *)alloca(i);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004138 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
4139 return x;
Tim Peters402d5982001-08-27 06:37:48 +00004140
4141 /* Explicitly check if we are using COMMAND.COM. If we are
4142 * then use the w9xpopen hack.
4143 */
4144 comshell = s1 + x;
4145 while (comshell >= s1 && *comshell != '\\')
4146 --comshell;
4147 ++comshell;
4148
4149 if (GetVersion() < 0x80000000 &&
4150 _stricmp(comshell, "command.com") != 0) {
4151 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004152 x = i + strlen(s3) + strlen(cmdstring) + 1;
Tim Peters92e4dd82002-10-05 01:47:34 +00004153 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004154 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00004155 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004156 }
4157 else {
4158 /*
Tim Peters402d5982001-08-27 06:37:48 +00004159 * Oh gag, we're on Win9x or using COMMAND.COM. Use
4160 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004161 */
Mark Hammond08501372001-01-31 07:30:29 +00004162 char modulepath[_MAX_PATH];
4163 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004164 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
4165 for (i = x = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004166 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004167 x = i+1;
4168 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00004169 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00004170 strncat(modulepath,
4171 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00004172 (sizeof(modulepath)/sizeof(modulepath[0]))
4173 -strlen(modulepath));
4174 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00004175 /* Eeek - file-not-found - possibly an embedding
4176 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00004177 */
Tim Peters5aa91602002-01-30 05:46:57 +00004178 strncpy(modulepath,
4179 Py_GetExecPrefix(),
Mark Hammond08501372001-01-31 07:30:29 +00004180 sizeof(modulepath)/sizeof(modulepath[0]));
4181 if (modulepath[strlen(modulepath)-1] != '\\')
4182 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00004183 strncat(modulepath,
4184 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00004185 (sizeof(modulepath)/sizeof(modulepath[0]))
4186 -strlen(modulepath));
4187 /* No where else to look - raise an easily identifiable
4188 error, rather than leaving Windows to report
4189 "file not found" - as the user is probably blissfully
4190 unaware this shim EXE is used, and it will confuse them.
4191 (well, it confused me for a while ;-)
4192 */
4193 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00004194 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00004195 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00004196 "for popen to work with your shell "
4197 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00004198 szConsoleSpawn);
4199 return FALSE;
4200 }
4201 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004202 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00004203 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004204 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00004205
Tim Peters92e4dd82002-10-05 01:47:34 +00004206 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004207 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004208 /* To maintain correct argument passing semantics,
4209 we pass the command-line as it stands, and allow
4210 quoting to be applied. w9xpopen.exe will then
4211 use its argv vector, and re-quote the necessary
4212 args for the ultimate child process.
4213 */
Tim Peters75cdad52001-11-28 22:07:30 +00004214 PyOS_snprintf(
4215 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004216 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004217 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004218 s1,
4219 s3,
4220 cmdstring);
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004221 /* Not passing CREATE_NEW_CONSOLE has been known to
Tim Peters11b23062003-04-23 02:39:17 +00004222 cause random failures on win9x. Specifically a
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004223 dialog:
4224 "Your program accessed mem currently in use at xxx"
4225 and a hopeful warning about the stability of your
4226 system.
4227 Cost is Ctrl+C wont kill children, but anyone
4228 who cares can have a go!
4229 */
4230 dwProcessFlags |= CREATE_NEW_CONSOLE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004231 }
4232 }
4233
4234 /* Could be an else here to try cmd.exe / command.com in the path
4235 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00004236 else {
Tim Peters402d5982001-08-27 06:37:48 +00004237 PyErr_SetString(PyExc_RuntimeError,
4238 "Cannot locate a COMSPEC environment variable to "
4239 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00004240 return FALSE;
4241 }
Tim Peters5aa91602002-01-30 05:46:57 +00004242
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004243 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
4244 siStartInfo.cb = sizeof(STARTUPINFO);
4245 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
4246 siStartInfo.hStdInput = hStdin;
4247 siStartInfo.hStdOutput = hStdout;
4248 siStartInfo.hStdError = hStderr;
4249 siStartInfo.wShowWindow = SW_HIDE;
4250
4251 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004252 s2,
4253 NULL,
4254 NULL,
4255 TRUE,
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004256 dwProcessFlags,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004257 NULL,
4258 NULL,
4259 &siStartInfo,
4260 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004261 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004262 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004263
Mark Hammondb37a3732000-08-14 04:47:33 +00004264 /* Return process handle */
4265 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004266 return TRUE;
4267 }
Tim Peters402d5982001-08-27 06:37:48 +00004268 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004269 return FALSE;
4270}
4271
4272/* The following code is based off of KB: Q190351 */
4273
4274static PyObject *
4275_PyPopen(char *cmdstring, int mode, int n)
4276{
4277 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
4278 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00004279 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00004280
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004281 SECURITY_ATTRIBUTES saAttr;
4282 BOOL fSuccess;
4283 int fd1, fd2, fd3;
4284 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00004285 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004286 PyObject *f;
4287
4288 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
4289 saAttr.bInheritHandle = TRUE;
4290 saAttr.lpSecurityDescriptor = NULL;
4291
4292 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
4293 return win32_error("CreatePipe", NULL);
4294
4295 /* Create new output read handle and the input write handle. Set
4296 * the inheritance properties to FALSE. Otherwise, the child inherits
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00004297 * these handles; resulting in non-closeable handles to the pipes
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004298 * being created. */
4299 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004300 GetCurrentProcess(), &hChildStdinWrDup, 0,
4301 FALSE,
4302 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004303 if (!fSuccess)
4304 return win32_error("DuplicateHandle", NULL);
4305
4306 /* Close the inheritable version of ChildStdin
4307 that we're using. */
4308 CloseHandle(hChildStdinWr);
4309
4310 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
4311 return win32_error("CreatePipe", NULL);
4312
4313 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004314 GetCurrentProcess(), &hChildStdoutRdDup, 0,
4315 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004316 if (!fSuccess)
4317 return win32_error("DuplicateHandle", NULL);
4318
4319 /* Close the inheritable version of ChildStdout
4320 that we're using. */
4321 CloseHandle(hChildStdoutRd);
4322
4323 if (n != POPEN_4) {
4324 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
4325 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004326 fSuccess = DuplicateHandle(GetCurrentProcess(),
4327 hChildStderrRd,
4328 GetCurrentProcess(),
4329 &hChildStderrRdDup, 0,
4330 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004331 if (!fSuccess)
4332 return win32_error("DuplicateHandle", NULL);
4333 /* Close the inheritable version of ChildStdErr that we're using. */
4334 CloseHandle(hChildStderrRd);
4335 }
Tim Peters5aa91602002-01-30 05:46:57 +00004336
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004337 switch (n) {
4338 case POPEN_1:
4339 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
4340 case _O_WRONLY | _O_TEXT:
4341 /* Case for writing to child Stdin in text mode. */
4342 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4343 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004344 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004345 PyFile_SetBufSize(f, 0);
4346 /* We don't care about these pipes anymore, so close them. */
4347 CloseHandle(hChildStdoutRdDup);
4348 CloseHandle(hChildStderrRdDup);
4349 break;
4350
4351 case _O_RDONLY | _O_TEXT:
4352 /* Case for reading from child Stdout in text mode. */
4353 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4354 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004355 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004356 PyFile_SetBufSize(f, 0);
4357 /* We don't care about these pipes anymore, so close them. */
4358 CloseHandle(hChildStdinWrDup);
4359 CloseHandle(hChildStderrRdDup);
4360 break;
4361
4362 case _O_RDONLY | _O_BINARY:
4363 /* Case for readinig from child Stdout in binary mode. */
4364 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4365 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004366 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004367 PyFile_SetBufSize(f, 0);
4368 /* We don't care about these pipes anymore, so close them. */
4369 CloseHandle(hChildStdinWrDup);
4370 CloseHandle(hChildStderrRdDup);
4371 break;
4372
4373 case _O_WRONLY | _O_BINARY:
4374 /* Case for writing to child Stdin in binary mode. */
4375 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4376 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004377 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004378 PyFile_SetBufSize(f, 0);
4379 /* We don't care about these pipes anymore, so close them. */
4380 CloseHandle(hChildStdoutRdDup);
4381 CloseHandle(hChildStderrRdDup);
4382 break;
4383 }
Mark Hammondb37a3732000-08-14 04:47:33 +00004384 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004385 break;
Tim Peters5aa91602002-01-30 05:46:57 +00004386
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004387 case POPEN_2:
4388 case POPEN_4:
4389 {
4390 char *m1, *m2;
4391 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00004392
Tim Peters7dca21e2002-08-19 00:42:29 +00004393 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004394 m1 = "r";
4395 m2 = "w";
4396 } else {
4397 m1 = "rb";
4398 m2 = "wb";
4399 }
4400
4401 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4402 f1 = _fdopen(fd1, m2);
4403 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4404 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004405 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004406 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00004407 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004408 PyFile_SetBufSize(p2, 0);
4409
4410 if (n != 4)
4411 CloseHandle(hChildStderrRdDup);
4412
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004413 f = PyTuple_Pack(2,p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00004414 Py_XDECREF(p1);
4415 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00004416 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004417 break;
4418 }
Tim Peters5aa91602002-01-30 05:46:57 +00004419
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004420 case POPEN_3:
4421 {
4422 char *m1, *m2;
4423 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00004424
Tim Peters7dca21e2002-08-19 00:42:29 +00004425 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004426 m1 = "r";
4427 m2 = "w";
4428 } else {
4429 m1 = "rb";
4430 m2 = "wb";
4431 }
4432
4433 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4434 f1 = _fdopen(fd1, m2);
4435 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4436 f2 = _fdopen(fd2, m1);
4437 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
4438 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004439 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00004440 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
4441 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004442 PyFile_SetBufSize(p1, 0);
4443 PyFile_SetBufSize(p2, 0);
4444 PyFile_SetBufSize(p3, 0);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004445 f = PyTuple_Pack(3,p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00004446 Py_XDECREF(p1);
4447 Py_XDECREF(p2);
4448 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00004449 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004450 break;
4451 }
4452 }
4453
4454 if (n == POPEN_4) {
4455 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004456 hChildStdinRd,
4457 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004458 hChildStdoutWr,
4459 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004460 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004461 }
4462 else {
4463 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004464 hChildStdinRd,
4465 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004466 hChildStderrWr,
4467 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004468 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004469 }
4470
Mark Hammondb37a3732000-08-14 04:47:33 +00004471 /*
4472 * Insert the files we've created into the process dictionary
4473 * all referencing the list with the process handle and the
4474 * initial number of files (see description below in _PyPclose).
4475 * Since if _PyPclose later tried to wait on a process when all
4476 * handles weren't closed, it could create a deadlock with the
4477 * child, we spend some energy here to try to ensure that we
4478 * either insert all file handles into the dictionary or none
4479 * at all. It's a little clumsy with the various popen modes
4480 * and variable number of files involved.
4481 */
4482 if (!_PyPopenProcs) {
4483 _PyPopenProcs = PyDict_New();
4484 }
4485
4486 if (_PyPopenProcs) {
4487 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
4488 int ins_rc[3];
4489
4490 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4491 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4492
4493 procObj = PyList_New(2);
4494 hProcessObj = PyLong_FromVoidPtr(hProcess);
4495 intObj = PyInt_FromLong(file_count);
4496
4497 if (procObj && hProcessObj && intObj) {
4498 PyList_SetItem(procObj,0,hProcessObj);
4499 PyList_SetItem(procObj,1,intObj);
4500
4501 fileObj[0] = PyLong_FromVoidPtr(f1);
4502 if (fileObj[0]) {
4503 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4504 fileObj[0],
4505 procObj);
4506 }
4507 if (file_count >= 2) {
4508 fileObj[1] = PyLong_FromVoidPtr(f2);
4509 if (fileObj[1]) {
4510 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4511 fileObj[1],
4512 procObj);
4513 }
4514 }
4515 if (file_count >= 3) {
4516 fileObj[2] = PyLong_FromVoidPtr(f3);
4517 if (fileObj[2]) {
4518 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4519 fileObj[2],
4520 procObj);
4521 }
4522 }
4523
4524 if (ins_rc[0] < 0 || !fileObj[0] ||
4525 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4526 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
4527 /* Something failed - remove any dictionary
4528 * entries that did make it.
4529 */
4530 if (!ins_rc[0] && fileObj[0]) {
4531 PyDict_DelItem(_PyPopenProcs,
4532 fileObj[0]);
4533 }
4534 if (!ins_rc[1] && fileObj[1]) {
4535 PyDict_DelItem(_PyPopenProcs,
4536 fileObj[1]);
4537 }
4538 if (!ins_rc[2] && fileObj[2]) {
4539 PyDict_DelItem(_PyPopenProcs,
4540 fileObj[2]);
4541 }
4542 }
4543 }
Tim Peters5aa91602002-01-30 05:46:57 +00004544
Mark Hammondb37a3732000-08-14 04:47:33 +00004545 /*
4546 * Clean up our localized references for the dictionary keys
4547 * and value since PyDict_SetItem will Py_INCREF any copies
4548 * that got placed in the dictionary.
4549 */
4550 Py_XDECREF(procObj);
4551 Py_XDECREF(fileObj[0]);
4552 Py_XDECREF(fileObj[1]);
4553 Py_XDECREF(fileObj[2]);
4554 }
4555
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004556 /* Child is launched. Close the parents copy of those pipe
4557 * handles that only the child should have open. You need to
4558 * make sure that no handles to the write end of the output pipe
4559 * are maintained in this process or else the pipe will not close
4560 * when the child process exits and the ReadFile will hang. */
4561
4562 if (!CloseHandle(hChildStdinRd))
4563 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004564
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004565 if (!CloseHandle(hChildStdoutWr))
4566 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004567
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004568 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
4569 return win32_error("CloseHandle", NULL);
4570
4571 return f;
4572}
Fredrik Lundh56055a42000-07-23 19:47:12 +00004573
4574/*
4575 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4576 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00004577 *
4578 * This function uses the _PyPopenProcs dictionary in order to map the
4579 * input file pointer to information about the process that was
4580 * originally created by the popen* call that created the file pointer.
4581 * The dictionary uses the file pointer as a key (with one entry
4582 * inserted for each file returned by the original popen* call) and a
4583 * single list object as the value for all files from a single call.
4584 * The list object contains the Win32 process handle at [0], and a file
4585 * count at [1], which is initialized to the total number of file
4586 * handles using that list.
4587 *
4588 * This function closes whichever handle it is passed, and decrements
4589 * the file count in the dictionary for the process handle pointed to
4590 * by this file. On the last close (when the file count reaches zero),
4591 * this function will wait for the child process and then return its
4592 * exit code as the result of the close() operation. This permits the
4593 * files to be closed in any order - it is always the close() of the
4594 * final handle that will return the exit code.
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004595 *
4596 * NOTE: This function is currently called with the GIL released.
4597 * hence we use the GILState API to manage our state.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004598 */
Tim Peters736aa322000-09-01 06:51:24 +00004599
Fredrik Lundh56055a42000-07-23 19:47:12 +00004600static int _PyPclose(FILE *file)
4601{
Fredrik Lundh20318932000-07-26 17:29:12 +00004602 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004603 DWORD exit_code;
4604 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00004605 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
4606 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00004607#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004608 PyGILState_STATE state;
Tim Peters736aa322000-09-01 06:51:24 +00004609#endif
4610
Fredrik Lundh20318932000-07-26 17:29:12 +00004611 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00004612 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00004613 */
4614 result = fclose(file);
Tim Peters736aa322000-09-01 06:51:24 +00004615#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004616 state = PyGILState_Ensure();
Tim Peters736aa322000-09-01 06:51:24 +00004617#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00004618 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00004619 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4620 (procObj = PyDict_GetItem(_PyPopenProcs,
4621 fileObj)) != NULL &&
4622 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
4623 (intObj = PyList_GetItem(procObj,1)) != NULL) {
4624
4625 hProcess = PyLong_AsVoidPtr(hProcessObj);
4626 file_count = PyInt_AsLong(intObj);
4627
4628 if (file_count > 1) {
4629 /* Still other files referencing process */
4630 file_count--;
4631 PyList_SetItem(procObj,1,
4632 PyInt_FromLong(file_count));
4633 } else {
4634 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00004635 if (result != EOF &&
4636 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
4637 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00004638 /* Possible truncation here in 16-bit environments, but
4639 * real exit codes are just the lower byte in any event.
4640 */
4641 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004642 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00004643 /* Indicate failure - this will cause the file object
4644 * to raise an I/O error and translate the last Win32
4645 * error code from errno. We do have a problem with
4646 * last errors that overlap the normal errno table,
4647 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004648 */
Fredrik Lundh20318932000-07-26 17:29:12 +00004649 if (result != EOF) {
4650 /* If the error wasn't from the fclose(), then
4651 * set errno for the file object error handling.
4652 */
4653 errno = GetLastError();
4654 }
4655 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004656 }
4657
4658 /* Free up the native handle at this point */
4659 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00004660 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00004661
Mark Hammondb37a3732000-08-14 04:47:33 +00004662 /* Remove this file pointer from dictionary */
4663 PyDict_DelItem(_PyPopenProcs, fileObj);
4664
4665 if (PyDict_Size(_PyPopenProcs) == 0) {
4666 Py_DECREF(_PyPopenProcs);
4667 _PyPopenProcs = NULL;
4668 }
4669
4670 } /* if object retrieval ok */
4671
4672 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004673 } /* if _PyPopenProcs */
4674
Tim Peters736aa322000-09-01 06:51:24 +00004675#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004676 PyGILState_Release(state);
Tim Peters736aa322000-09-01 06:51:24 +00004677#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00004678 return result;
4679}
Tim Peters9acdd3a2000-09-01 19:26:36 +00004680
4681#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00004682static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004683posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00004684{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004685 char *name;
4686 char *mode = "r";
4687 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00004688 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00004689 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004690 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00004691 return NULL;
Martin v. Löwis9ad853b2003-10-31 10:01:53 +00004692 /* Strip mode of binary or text modifiers */
4693 if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
4694 mode = "r";
4695 else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
4696 mode = "w";
Barry Warsaw53699e91996-12-10 23:23:01 +00004697 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004698 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004699 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00004700 if (fp == NULL)
4701 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004702 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004703 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00004704 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004705 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00004706}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004707
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004708#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004709#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00004710
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004711
Guido van Rossumb6775db1994-08-01 11:34:53 +00004712#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004713PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004714"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004715Set the current process's user id.");
4716
Barry Warsaw53699e91996-12-10 23:23:01 +00004717static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004718posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004719{
4720 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004721 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004722 return NULL;
4723 if (setuid(uid) < 0)
4724 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004725 Py_INCREF(Py_None);
4726 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004727}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004728#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004729
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004730
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004731#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004732PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004733"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004734Set the current process's effective user id.");
4735
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004736static PyObject *
4737posix_seteuid (PyObject *self, PyObject *args)
4738{
4739 int euid;
4740 if (!PyArg_ParseTuple(args, "i", &euid)) {
4741 return NULL;
4742 } else if (seteuid(euid) < 0) {
4743 return posix_error();
4744 } else {
4745 Py_INCREF(Py_None);
4746 return Py_None;
4747 }
4748}
4749#endif /* HAVE_SETEUID */
4750
4751#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004752PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004753"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004754Set the current process's effective group id.");
4755
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004756static PyObject *
4757posix_setegid (PyObject *self, PyObject *args)
4758{
4759 int egid;
4760 if (!PyArg_ParseTuple(args, "i", &egid)) {
4761 return NULL;
4762 } else if (setegid(egid) < 0) {
4763 return posix_error();
4764 } else {
4765 Py_INCREF(Py_None);
4766 return Py_None;
4767 }
4768}
4769#endif /* HAVE_SETEGID */
4770
4771#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004772PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004773"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004774Set the current process's real and effective user ids.");
4775
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004776static PyObject *
4777posix_setreuid (PyObject *self, PyObject *args)
4778{
4779 int ruid, euid;
4780 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
4781 return NULL;
4782 } else if (setreuid(ruid, euid) < 0) {
4783 return posix_error();
4784 } else {
4785 Py_INCREF(Py_None);
4786 return Py_None;
4787 }
4788}
4789#endif /* HAVE_SETREUID */
4790
4791#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004792PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004793"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004794Set the current process's real and effective group ids.");
4795
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004796static PyObject *
4797posix_setregid (PyObject *self, PyObject *args)
4798{
4799 int rgid, egid;
4800 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
4801 return NULL;
4802 } else if (setregid(rgid, egid) < 0) {
4803 return posix_error();
4804 } else {
4805 Py_INCREF(Py_None);
4806 return Py_None;
4807 }
4808}
4809#endif /* HAVE_SETREGID */
4810
Guido van Rossumb6775db1994-08-01 11:34:53 +00004811#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004812PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004813"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004814Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004815
Barry Warsaw53699e91996-12-10 23:23:01 +00004816static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004817posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004818{
4819 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004820 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004821 return NULL;
4822 if (setgid(gid) < 0)
4823 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004824 Py_INCREF(Py_None);
4825 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004826}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004827#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004828
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004829#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004830PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004831"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004832Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004833
4834static PyObject *
4835posix_setgroups(PyObject *self, PyObject *args)
4836{
4837 PyObject *groups;
4838 int i, len;
4839 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00004840
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004841 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
4842 return NULL;
4843 if (!PySequence_Check(groups)) {
4844 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
4845 return NULL;
4846 }
4847 len = PySequence_Size(groups);
4848 if (len > MAX_GROUPS) {
4849 PyErr_SetString(PyExc_ValueError, "too many groups");
4850 return NULL;
4851 }
4852 for(i = 0; i < len; i++) {
4853 PyObject *elem;
4854 elem = PySequence_GetItem(groups, i);
4855 if (!elem)
4856 return NULL;
4857 if (!PyInt_Check(elem)) {
4858 PyErr_SetString(PyExc_TypeError,
4859 "groups must be integers");
4860 Py_DECREF(elem);
4861 return NULL;
4862 }
4863 /* XXX: check that value fits into gid_t. */
4864 grouplist[i] = PyInt_AsLong(elem);
4865 Py_DECREF(elem);
4866 }
4867
4868 if (setgroups(len, grouplist) < 0)
4869 return posix_error();
4870 Py_INCREF(Py_None);
4871 return Py_None;
4872}
4873#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004874
Guido van Rossumb6775db1994-08-01 11:34:53 +00004875#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004876PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004877"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004878Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004879
Barry Warsaw53699e91996-12-10 23:23:01 +00004880static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004881posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004882{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004883 int pid, options;
4884#ifdef UNION_WAIT
4885 union wait status;
4886#define status_i (status.w_status)
4887#else
4888 int status;
4889#define status_i status
4890#endif
4891 status_i = 0;
4892
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004893 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00004894 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004895 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00004896 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00004897 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00004898 if (pid == -1)
4899 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00004900 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004901 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00004902}
4903
Tim Petersab034fa2002-02-01 11:27:43 +00004904#elif defined(HAVE_CWAIT)
4905
4906/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004907PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004908"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004909"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00004910
4911static PyObject *
4912posix_waitpid(PyObject *self, PyObject *args)
4913{
4914 int pid, options;
4915 int status;
4916
4917 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
4918 return NULL;
4919 Py_BEGIN_ALLOW_THREADS
4920 pid = _cwait(&status, pid, options);
4921 Py_END_ALLOW_THREADS
4922 if (pid == -1)
4923 return posix_error();
4924 else
4925 /* shift the status left a byte so this is more like the
4926 POSIX waitpid */
4927 return Py_BuildValue("ii", pid, status << 8);
4928}
4929#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004930
Guido van Rossumad0ee831995-03-01 10:34:45 +00004931#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004932PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004933"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004934Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004935
Barry Warsaw53699e91996-12-10 23:23:01 +00004936static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004937posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00004938{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004939 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004940#ifdef UNION_WAIT
4941 union wait status;
4942#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004943#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004944 int status;
4945#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00004946#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00004947
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004948 status_i = 0;
4949 Py_BEGIN_ALLOW_THREADS
4950 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00004951 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00004952 if (pid == -1)
4953 return posix_error();
4954 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004955 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004956#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00004957}
Guido van Rossumad0ee831995-03-01 10:34:45 +00004958#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00004959
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004960
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004961PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004962"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004963Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004964
Barry Warsaw53699e91996-12-10 23:23:01 +00004965static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004966posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004967{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004968#ifdef HAVE_LSTAT
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004969 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00004970#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004971#ifdef MS_WINDOWS
Mark Hammond7edd0a92003-08-06 02:46:58 +00004972 return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", _wstati64);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004973#else
4974 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
4975#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00004976#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004977}
4978
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004979
Guido van Rossumb6775db1994-08-01 11:34:53 +00004980#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004981PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004982"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004983Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004984
Barry Warsaw53699e91996-12-10 23:23:01 +00004985static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004986posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004987{
Guido van Rossumb6775db1994-08-01 11:34:53 +00004988 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004989 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004990 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004991 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004992 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004993 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00004994 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00004995 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004996 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00004997 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00004998 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004999}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005000#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005001
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005002
Guido van Rossumb6775db1994-08-01 11:34:53 +00005003#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005004PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005005"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00005006Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005007
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005008static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005009posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005010{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005011 return posix_2str(args, "etet:symlink", symlink, NULL, NULL);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005012}
5013#endif /* HAVE_SYMLINK */
5014
5015
5016#ifdef HAVE_TIMES
5017#ifndef HZ
5018#define HZ 60 /* Universal constant :-) */
5019#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00005020
Guido van Rossumd48f2521997-12-05 22:19:34 +00005021#if defined(PYCC_VACPP) && defined(PYOS_OS2)
5022static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005023system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005024{
5025 ULONG value = 0;
5026
5027 Py_BEGIN_ALLOW_THREADS
5028 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
5029 Py_END_ALLOW_THREADS
5030
5031 return value;
5032}
5033
5034static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005035posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005036{
Guido van Rossumd48f2521997-12-05 22:19:34 +00005037 /* Currently Only Uptime is Provided -- Others Later */
5038 return Py_BuildValue("ddddd",
5039 (double)0 /* t.tms_utime / HZ */,
5040 (double)0 /* t.tms_stime / HZ */,
5041 (double)0 /* t.tms_cutime / HZ */,
5042 (double)0 /* t.tms_cstime / HZ */,
5043 (double)system_uptime() / 1000);
5044}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005045#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00005046static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005047posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00005048{
5049 struct tms t;
5050 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +00005051 errno = 0;
5052 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00005053 if (c == (clock_t) -1)
5054 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005055 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00005056 (double)t.tms_utime / HZ,
5057 (double)t.tms_stime / HZ,
5058 (double)t.tms_cutime / HZ,
5059 (double)t.tms_cstime / HZ,
5060 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00005061}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005062#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005063#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005064
5065
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005066#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005067#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00005068static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005069posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005070{
5071 FILETIME create, exit, kernel, user;
5072 HANDLE hProc;
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005073 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00005074 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
5075 /* The fields of a FILETIME structure are the hi and lo part
5076 of a 64-bit value expressed in 100 nanosecond units.
5077 1e7 is one second in such units; 1e-7 the inverse.
5078 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
5079 */
Barry Warsaw53699e91996-12-10 23:23:01 +00005080 return Py_BuildValue(
5081 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00005082 (double)(kernel.dwHighDateTime*429.4967296 +
5083 kernel.dwLowDateTime*1e-7),
5084 (double)(user.dwHighDateTime*429.4967296 +
5085 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00005086 (double)0,
5087 (double)0,
5088 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005089}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005090#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005091
5092#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005093PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005094"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005095Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005096#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005097
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005098
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00005099#ifdef HAVE_GETSID
5100PyDoc_STRVAR(posix_getsid__doc__,
5101"getsid(pid) -> sid\n\n\
5102Call the system call getsid().");
5103
5104static PyObject *
5105posix_getsid(PyObject *self, PyObject *args)
5106{
5107 int pid, sid;
5108 if (!PyArg_ParseTuple(args, "i:getsid", &pid))
5109 return NULL;
5110 sid = getsid(pid);
5111 if (sid < 0)
5112 return posix_error();
5113 return PyInt_FromLong((long)sid);
5114}
5115#endif /* HAVE_GETSID */
5116
5117
Guido van Rossumb6775db1994-08-01 11:34:53 +00005118#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005119PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005120"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005121Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005122
Barry Warsaw53699e91996-12-10 23:23:01 +00005123static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005124posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005125{
Guido van Rossum687dd131993-05-17 08:34:16 +00005126 if (setsid() < 0)
5127 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005128 Py_INCREF(Py_None);
5129 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005130}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005131#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005132
Guido van Rossumb6775db1994-08-01 11:34:53 +00005133#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005134PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005135"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005136Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005137
Barry Warsaw53699e91996-12-10 23:23:01 +00005138static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005139posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005140{
5141 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005142 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00005143 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005144 if (setpgid(pid, pgrp) < 0)
5145 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005146 Py_INCREF(Py_None);
5147 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005148}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005149#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005150
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005151
Guido van Rossumb6775db1994-08-01 11:34:53 +00005152#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005153PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005154"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005155Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005156
Barry Warsaw53699e91996-12-10 23:23:01 +00005157static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005158posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005159{
5160 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005161 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00005162 return NULL;
5163 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005164 if (pgid < 0)
5165 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005166 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00005167}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005168#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00005169
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005170
Guido van Rossumb6775db1994-08-01 11:34:53 +00005171#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005172PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005173"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005174Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005175
Barry Warsaw53699e91996-12-10 23:23:01 +00005176static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005177posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005178{
5179 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005180 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00005181 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005182 if (tcsetpgrp(fd, pgid) < 0)
5183 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00005184 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00005185 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00005186}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005187#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00005188
Guido van Rossum687dd131993-05-17 08:34:16 +00005189/* Functions acting on file descriptors */
5190
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005191PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005192"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005193Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005194
Barry Warsaw53699e91996-12-10 23:23:01 +00005195static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005196posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005197{
Mark Hammondef8b6542001-05-13 08:04:26 +00005198 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005199 int flag;
5200 int mode = 0777;
5201 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005202
5203#ifdef MS_WINDOWS
5204 if (unicode_file_names()) {
5205 PyUnicodeObject *po;
5206 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
5207 Py_BEGIN_ALLOW_THREADS
5208 /* PyUnicode_AS_UNICODE OK without thread
5209 lock as it is a simple dereference. */
5210 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
5211 Py_END_ALLOW_THREADS
5212 if (fd < 0)
5213 return posix_error();
5214 return PyInt_FromLong((long)fd);
5215 }
5216 /* Drop the argument parsing error as narrow strings
5217 are also valid. */
5218 PyErr_Clear();
5219 }
5220#endif
5221
Tim Peters5aa91602002-01-30 05:46:57 +00005222 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00005223 Py_FileSystemDefaultEncoding, &file,
5224 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00005225 return NULL;
5226
Barry Warsaw53699e91996-12-10 23:23:01 +00005227 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005228 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005229 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005230 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00005231 return posix_error_with_allocated_filename(file);
5232 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00005233 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005234}
5235
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005236
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005237PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005238"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005239Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005240
Barry Warsaw53699e91996-12-10 23:23:01 +00005241static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005242posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005243{
5244 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005245 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005246 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005247 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005248 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00005249 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005250 if (res < 0)
5251 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005252 Py_INCREF(Py_None);
5253 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005254}
5255
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005256
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005257PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005258"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005259Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005260
Barry Warsaw53699e91996-12-10 23:23:01 +00005261static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005262posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005263{
5264 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005265 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005266 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005267 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005268 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00005269 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005270 if (fd < 0)
5271 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005272 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005273}
5274
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005275
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005276PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00005277"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005278Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005279
Barry Warsaw53699e91996-12-10 23:23:01 +00005280static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005281posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005282{
5283 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005284 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00005285 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005286 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005287 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00005288 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005289 if (res < 0)
5290 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005291 Py_INCREF(Py_None);
5292 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005293}
5294
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005295
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005296PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005297"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005298Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005299
Barry Warsaw53699e91996-12-10 23:23:01 +00005300static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005301posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005302{
5303 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005304#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005305 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005306#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00005307 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005308#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005309 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005310 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00005311 return NULL;
5312#ifdef SEEK_SET
5313 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
5314 switch (how) {
5315 case 0: how = SEEK_SET; break;
5316 case 1: how = SEEK_CUR; break;
5317 case 2: how = SEEK_END; break;
5318 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005319#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005320
5321#if !defined(HAVE_LARGEFILE_SUPPORT)
5322 pos = PyInt_AsLong(posobj);
5323#else
5324 pos = PyLong_Check(posobj) ?
5325 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
5326#endif
5327 if (PyErr_Occurred())
5328 return NULL;
5329
Barry Warsaw53699e91996-12-10 23:23:01 +00005330 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005331#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00005332 res = _lseeki64(fd, pos, how);
5333#else
Guido van Rossum687dd131993-05-17 08:34:16 +00005334 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005335#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005336 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005337 if (res < 0)
5338 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00005339
5340#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00005341 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005342#else
5343 return PyLong_FromLongLong(res);
5344#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005345}
5346
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005347
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005348PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005349"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005350Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005351
Barry Warsaw53699e91996-12-10 23:23:01 +00005352static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005353posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005354{
Guido van Rossum8bac5461996-06-11 18:38:48 +00005355 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00005356 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005357 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005358 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005359 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005360 if (buffer == NULL)
5361 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005362 Py_BEGIN_ALLOW_THREADS
5363 n = read(fd, PyString_AsString(buffer), size);
5364 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00005365 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005366 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00005367 return posix_error();
5368 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00005369 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00005370 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00005371 return buffer;
5372}
5373
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005374
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005375PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005376"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005377Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005378
Barry Warsaw53699e91996-12-10 23:23:01 +00005379static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005380posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005381{
5382 int fd, size;
5383 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005384 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005385 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005386 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005387 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00005388 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005389 if (size < 0)
5390 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005391 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005392}
5393
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005394
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005395PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005396"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005397Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005398
Barry Warsaw53699e91996-12-10 23:23:01 +00005399static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005400posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005401{
5402 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00005403 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00005404 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005405 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005406 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005407#ifdef __VMS
5408 /* on OpenVMS we must ensure that all bytes are written to the file */
5409 fsync(fd);
5410#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005411 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00005412 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00005413 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005414 if (res != 0)
5415 return posix_error();
Tim Peters5aa91602002-01-30 05:46:57 +00005416
Fred Drake699f3522000-06-29 21:12:41 +00005417 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00005418}
5419
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005420
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005421PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005422"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005423Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005424
Barry Warsaw53699e91996-12-10 23:23:01 +00005425static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005426posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005427{
Guido van Rossum687dd131993-05-17 08:34:16 +00005428 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005429 char *mode = "r";
5430 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00005431 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00005432 PyObject *f;
5433 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00005434 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00005435
Thomas Heller1f043e22002-11-07 16:00:59 +00005436 if (mode[0] != 'r' && mode[0] != 'w' && mode[0] != 'a') {
5437 PyErr_Format(PyExc_ValueError,
5438 "invalid file mode '%s'", mode);
5439 return NULL;
5440 }
5441
Barry Warsaw53699e91996-12-10 23:23:01 +00005442 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005443 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005444 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005445 if (fp == NULL)
5446 return posix_error();
Guido van Rossumbd6be7a2002-09-15 18:45:46 +00005447 f = PyFile_FromFile(fp, "<fdopen>", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005448 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00005449 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005450 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00005451}
5452
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005453PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005454"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005455Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005456connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00005457
5458static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00005459posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00005460{
5461 int fd;
5462 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
5463 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005464 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00005465}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005466
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005467#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005468PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005469"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005470Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005471
Barry Warsaw53699e91996-12-10 23:23:01 +00005472static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005473posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00005474{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005475#if defined(PYOS_OS2)
5476 HFILE read, write;
5477 APIRET rc;
5478
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005479 Py_BEGIN_ALLOW_THREADS
5480 rc = DosCreatePipe( &read, &write, 4096);
5481 Py_END_ALLOW_THREADS
5482 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005483 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005484
5485 return Py_BuildValue("(ii)", read, write);
5486#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005487#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00005488 int fds[2];
5489 int res;
Barry Warsaw53699e91996-12-10 23:23:01 +00005490 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005491 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00005492 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005493 if (res != 0)
5494 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005495 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005496#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00005497 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005498 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00005499 BOOL ok;
Barry Warsaw53699e91996-12-10 23:23:01 +00005500 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005501 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00005502 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00005503 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005504 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00005505 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
5506 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005507 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005508#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005509#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005510}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005511#endif /* HAVE_PIPE */
5512
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005513
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005514#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005515PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005516"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005517Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005518
Barry Warsaw53699e91996-12-10 23:23:01 +00005519static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005520posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005521{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005522 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005523 int mode = 0666;
5524 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005525 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005526 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005527 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005528 res = mkfifo(filename, mode);
5529 Py_END_ALLOW_THREADS
5530 if (res < 0)
5531 return posix_error();
5532 Py_INCREF(Py_None);
5533 return Py_None;
5534}
5535#endif
5536
5537
Neal Norwitz11690112002-07-30 01:08:28 +00005538#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005539PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005540"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005541Create a filesystem node (file, device special file or named pipe)\n\
5542named filename. mode specifies both the permissions to use and the\n\
5543type of node to be created, being combined (bitwise OR) with one of\n\
5544S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005545device defines the newly created device special file (probably using\n\
5546os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005547
5548
5549static PyObject *
5550posix_mknod(PyObject *self, PyObject *args)
5551{
5552 char *filename;
5553 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005554 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005555 int res;
Martin v. Löwisd631ebe2002-11-02 17:42:33 +00005556 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005557 return NULL;
5558 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005559 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00005560 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005561 if (res < 0)
5562 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005563 Py_INCREF(Py_None);
5564 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005565}
5566#endif
5567
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005568#ifdef HAVE_DEVICE_MACROS
5569PyDoc_STRVAR(posix_major__doc__,
5570"major(device) -> major number\n\
5571Extracts a device major number from a raw device number.");
5572
5573static PyObject *
5574posix_major(PyObject *self, PyObject *args)
5575{
5576 int device;
5577 if (!PyArg_ParseTuple(args, "i:major", &device))
5578 return NULL;
5579 return PyInt_FromLong((long)major(device));
5580}
5581
5582PyDoc_STRVAR(posix_minor__doc__,
5583"minor(device) -> minor number\n\
5584Extracts a device minor number from a raw device number.");
5585
5586static PyObject *
5587posix_minor(PyObject *self, PyObject *args)
5588{
5589 int device;
5590 if (!PyArg_ParseTuple(args, "i:minor", &device))
5591 return NULL;
5592 return PyInt_FromLong((long)minor(device));
5593}
5594
5595PyDoc_STRVAR(posix_makedev__doc__,
5596"makedev(major, minor) -> device number\n\
5597Composes a raw device number from the major and minor device numbers.");
5598
5599static PyObject *
5600posix_makedev(PyObject *self, PyObject *args)
5601{
5602 int major, minor;
5603 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
5604 return NULL;
5605 return PyInt_FromLong((long)makedev(major, minor));
5606}
5607#endif /* device macros */
5608
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005609
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005610#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005611PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005612"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005613Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005614
Barry Warsaw53699e91996-12-10 23:23:01 +00005615static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005616posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005617{
5618 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005619 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005620 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005621 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005622
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005623 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005624 return NULL;
5625
5626#if !defined(HAVE_LARGEFILE_SUPPORT)
5627 length = PyInt_AsLong(lenobj);
5628#else
5629 length = PyLong_Check(lenobj) ?
5630 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
5631#endif
5632 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005633 return NULL;
5634
Barry Warsaw53699e91996-12-10 23:23:01 +00005635 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005636 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00005637 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005638 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005639 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005640 return NULL;
5641 }
Barry Warsaw53699e91996-12-10 23:23:01 +00005642 Py_INCREF(Py_None);
5643 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005644}
5645#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005646
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005647#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005648PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005649"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005650Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005651
Fred Drake762e2061999-08-26 17:23:54 +00005652/* Save putenv() parameters as values here, so we can collect them when they
5653 * get re-set with another call for the same key. */
5654static PyObject *posix_putenv_garbage;
5655
Tim Peters5aa91602002-01-30 05:46:57 +00005656static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005657posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005658{
5659 char *s1, *s2;
5660 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00005661 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00005662 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005663
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005664 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005665 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00005666
5667#if defined(PYOS_OS2)
5668 if (stricmp(s1, "BEGINLIBPATH") == 0) {
5669 APIRET rc;
5670
Guido van Rossumd48f2521997-12-05 22:19:34 +00005671 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
5672 if (rc != NO_ERROR)
5673 return os2_error(rc);
5674
5675 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
5676 APIRET rc;
5677
Guido van Rossumd48f2521997-12-05 22:19:34 +00005678 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
5679 if (rc != NO_ERROR)
5680 return os2_error(rc);
5681 } else {
5682#endif
5683
Fred Drake762e2061999-08-26 17:23:54 +00005684 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00005685 len = strlen(s1) + strlen(s2) + 2;
5686 /* len includes space for a trailing \0; the size arg to
5687 PyString_FromStringAndSize does not count that */
5688 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00005689 if (newstr == NULL)
5690 return PyErr_NoMemory();
5691 new = PyString_AS_STRING(newstr);
Tim Petersc8996f52001-12-03 20:41:00 +00005692 PyOS_snprintf(new, len, "%s=%s", s1, s2);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005693 if (putenv(new)) {
Neal Norwitz4adc9ab2003-02-10 03:10:43 +00005694 Py_DECREF(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005695 posix_error();
5696 return NULL;
5697 }
Fred Drake762e2061999-08-26 17:23:54 +00005698 /* Install the first arg and newstr in posix_putenv_garbage;
5699 * this will cause previous value to be collected. This has to
5700 * happen after the real putenv() call because the old value
5701 * was still accessible until then. */
5702 if (PyDict_SetItem(posix_putenv_garbage,
5703 PyTuple_GET_ITEM(args, 0), newstr)) {
5704 /* really not much we can do; just leak */
5705 PyErr_Clear();
5706 }
5707 else {
5708 Py_DECREF(newstr);
5709 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005710
5711#if defined(PYOS_OS2)
5712 }
5713#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005714 Py_INCREF(Py_None);
5715 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005716}
Guido van Rossumb6a47161997-09-15 22:54:34 +00005717#endif /* putenv */
5718
Guido van Rossumc524d952001-10-19 01:31:59 +00005719#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005720PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005721"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005722Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00005723
5724static PyObject *
5725posix_unsetenv(PyObject *self, PyObject *args)
5726{
5727 char *s1;
5728
5729 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
5730 return NULL;
5731
5732 unsetenv(s1);
5733
5734 /* Remove the key from posix_putenv_garbage;
5735 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00005736 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00005737 * old value was still accessible until then.
5738 */
5739 if (PyDict_DelItem(posix_putenv_garbage,
5740 PyTuple_GET_ITEM(args, 0))) {
5741 /* really not much we can do; just leak */
5742 PyErr_Clear();
5743 }
5744
5745 Py_INCREF(Py_None);
5746 return Py_None;
5747}
5748#endif /* unsetenv */
5749
Guido van Rossumb6a47161997-09-15 22:54:34 +00005750#ifdef HAVE_STRERROR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005751PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005752"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005753Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005754
Guido van Rossumf68d8e52001-04-14 17:55:09 +00005755static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005756posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00005757{
5758 int code;
5759 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005760 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00005761 return NULL;
5762 message = strerror(code);
5763 if (message == NULL) {
5764 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00005765 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005766 return NULL;
5767 }
5768 return PyString_FromString(message);
5769}
5770#endif /* strerror */
5771
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005772
Guido van Rossumc9641791998-08-04 15:26:23 +00005773#ifdef HAVE_SYS_WAIT_H
5774
Fred Drake106c1a02002-04-23 15:58:02 +00005775#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005776PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005777"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005778Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00005779
5780static PyObject *
5781posix_WCOREDUMP(PyObject *self, PyObject *args)
5782{
5783#ifdef UNION_WAIT
5784 union wait status;
5785#define status_i (status.w_status)
5786#else
5787 int status;
5788#define status_i status
5789#endif
5790 status_i = 0;
5791
5792 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &status_i))
5793 {
5794 return NULL;
5795 }
5796
5797 return PyBool_FromLong(WCOREDUMP(status));
5798#undef status_i
5799}
5800#endif /* WCOREDUMP */
5801
5802#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005803PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005804"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005805Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005806job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00005807
5808static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005809posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00005810{
5811#ifdef UNION_WAIT
5812 union wait status;
5813#define status_i (status.w_status)
5814#else
5815 int status;
5816#define status_i status
5817#endif
5818 status_i = 0;
5819
5820 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &status_i))
5821 {
5822 return NULL;
5823 }
5824
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005825 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00005826#undef status_i
5827}
5828#endif /* WIFCONTINUED */
5829
Guido van Rossumc9641791998-08-04 15:26:23 +00005830#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005831PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005832"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005833Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005834
5835static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005836posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005837{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005838#ifdef UNION_WAIT
5839 union wait status;
5840#define status_i (status.w_status)
5841#else
5842 int status;
5843#define status_i status
5844#endif
5845 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005846
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005847 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005848 {
5849 return NULL;
5850 }
Tim Peters5aa91602002-01-30 05:46:57 +00005851
Fred Drake106c1a02002-04-23 15:58:02 +00005852 return PyBool_FromLong(WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005853#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005854}
5855#endif /* WIFSTOPPED */
5856
5857#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005858PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005859"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005860Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005861
5862static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005863posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005864{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005865#ifdef UNION_WAIT
5866 union wait status;
5867#define status_i (status.w_status)
5868#else
5869 int status;
5870#define status_i status
5871#endif
5872 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005873
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005874 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005875 {
5876 return NULL;
5877 }
Tim Peters5aa91602002-01-30 05:46:57 +00005878
Fred Drake106c1a02002-04-23 15:58:02 +00005879 return PyBool_FromLong(WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005880#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005881}
5882#endif /* WIFSIGNALED */
5883
5884#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005885PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005886"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005887Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005888system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005889
5890static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005891posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005892{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005893#ifdef UNION_WAIT
5894 union wait status;
5895#define status_i (status.w_status)
5896#else
5897 int status;
5898#define status_i status
5899#endif
5900 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005901
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005902 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005903 {
5904 return NULL;
5905 }
Tim Peters5aa91602002-01-30 05:46:57 +00005906
Fred Drake106c1a02002-04-23 15:58:02 +00005907 return PyBool_FromLong(WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005908#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005909}
5910#endif /* WIFEXITED */
5911
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005912#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005913PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005914"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005915Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005916
5917static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005918posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005919{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005920#ifdef UNION_WAIT
5921 union wait status;
5922#define status_i (status.w_status)
5923#else
5924 int status;
5925#define status_i status
5926#endif
5927 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005928
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005929 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005930 {
5931 return NULL;
5932 }
Tim Peters5aa91602002-01-30 05:46:57 +00005933
Guido van Rossumc9641791998-08-04 15:26:23 +00005934 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005935#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005936}
5937#endif /* WEXITSTATUS */
5938
5939#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005940PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005941"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005942Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005943value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005944
5945static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005946posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005947{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005948#ifdef UNION_WAIT
5949 union wait status;
5950#define status_i (status.w_status)
5951#else
5952 int status;
5953#define status_i status
5954#endif
5955 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005956
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005957 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005958 {
5959 return NULL;
5960 }
Tim Peters5aa91602002-01-30 05:46:57 +00005961
Guido van Rossumc9641791998-08-04 15:26:23 +00005962 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005963#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005964}
5965#endif /* WTERMSIG */
5966
5967#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005968PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005969"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005970Return the signal that stopped the process that provided\n\
5971the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005972
5973static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005974posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005975{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005976#ifdef UNION_WAIT
5977 union wait status;
5978#define status_i (status.w_status)
5979#else
5980 int status;
5981#define status_i status
5982#endif
5983 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005984
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005985 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005986 {
5987 return NULL;
5988 }
Tim Peters5aa91602002-01-30 05:46:57 +00005989
Guido van Rossumc9641791998-08-04 15:26:23 +00005990 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005991#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005992}
5993#endif /* WSTOPSIG */
5994
5995#endif /* HAVE_SYS_WAIT_H */
5996
5997
Guido van Rossum94f6f721999-01-06 18:42:14 +00005998#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00005999#ifdef _SCO_DS
6000/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
6001 needed definitions in sys/statvfs.h */
6002#define _SVID3
6003#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006004#include <sys/statvfs.h>
6005
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006006static PyObject*
6007_pystatvfs_fromstructstatvfs(struct statvfs st) {
6008 PyObject *v = PyStructSequence_New(&StatVFSResultType);
6009 if (v == NULL)
6010 return NULL;
6011
6012#if !defined(HAVE_LARGEFILE_SUPPORT)
6013 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6014 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
6015 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
6016 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
6017 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
6018 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
6019 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
6020 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
6021 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6022 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6023#else
6024 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6025 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00006026 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006027 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00006028 PyStructSequence_SET_ITEM(v, 3,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006029 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006030 PyStructSequence_SET_ITEM(v, 4,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006031 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00006032 PyStructSequence_SET_ITEM(v, 5,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006033 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00006034 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006035 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00006036 PyStructSequence_SET_ITEM(v, 7,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006037 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006038 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6039 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6040#endif
6041
6042 return v;
6043}
6044
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006045PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006046"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006047Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006048
6049static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006050posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006051{
6052 int fd, res;
6053 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006054
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006055 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006056 return NULL;
6057 Py_BEGIN_ALLOW_THREADS
6058 res = fstatvfs(fd, &st);
6059 Py_END_ALLOW_THREADS
6060 if (res != 0)
6061 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006062
6063 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006064}
6065#endif /* HAVE_FSTATVFS */
6066
6067
6068#if defined(HAVE_STATVFS)
6069#include <sys/statvfs.h>
6070
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006071PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006072"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006073Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006074
6075static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006076posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006077{
6078 char *path;
6079 int res;
6080 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006081 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006082 return NULL;
6083 Py_BEGIN_ALLOW_THREADS
6084 res = statvfs(path, &st);
6085 Py_END_ALLOW_THREADS
6086 if (res != 0)
6087 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006088
6089 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006090}
6091#endif /* HAVE_STATVFS */
6092
6093
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006094#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006095PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006096"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006097Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00006098The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006099or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006100
6101static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006102posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006103{
6104 PyObject *result = NULL;
6105 char *dir = NULL;
6106 char *pfx = NULL;
6107 char *name;
6108
6109 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
6110 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00006111
6112 if (PyErr_Warn(PyExc_RuntimeWarning,
6113 "tempnam is a potential security risk to your program") < 0)
6114 return NULL;
6115
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006116#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00006117 name = _tempnam(dir, pfx);
6118#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006119 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00006120#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006121 if (name == NULL)
6122 return PyErr_NoMemory();
6123 result = PyString_FromString(name);
6124 free(name);
6125 return result;
6126}
Guido van Rossumd371ff11999-01-25 16:12:23 +00006127#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006128
6129
6130#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006131PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006132"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006133Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006134
6135static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006136posix_tmpfile(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006137{
6138 FILE *fp;
6139
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006140 fp = tmpfile();
6141 if (fp == NULL)
6142 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00006143 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006144}
6145#endif
6146
6147
6148#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006149PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006150"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006151Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006152
6153static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006154posix_tmpnam(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006155{
6156 char buffer[L_tmpnam];
6157 char *name;
6158
Skip Montanaro95618b52001-08-18 18:52:10 +00006159 if (PyErr_Warn(PyExc_RuntimeWarning,
6160 "tmpnam is a potential security risk to your program") < 0)
6161 return NULL;
6162
Greg Wardb48bc172000-03-01 21:51:56 +00006163#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006164 name = tmpnam_r(buffer);
6165#else
6166 name = tmpnam(buffer);
6167#endif
6168 if (name == NULL) {
6169 PyErr_SetObject(PyExc_OSError,
6170 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00006171#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006172 "unexpected NULL from tmpnam_r"
6173#else
6174 "unexpected NULL from tmpnam"
6175#endif
6176 ));
6177 return NULL;
6178 }
6179 return PyString_FromString(buffer);
6180}
6181#endif
6182
6183
Fred Drakec9680921999-12-13 16:37:25 +00006184/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
6185 * It maps strings representing configuration variable names to
6186 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00006187 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00006188 * rarely-used constants. There are three separate tables that use
6189 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00006190 *
6191 * This code is always included, even if none of the interfaces that
6192 * need it are included. The #if hackery needed to avoid it would be
6193 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00006194 */
6195struct constdef {
6196 char *name;
6197 long value;
6198};
6199
Fred Drake12c6e2d1999-12-14 21:25:03 +00006200static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006201conv_confname(PyObject *arg, int *valuep, struct constdef *table,
6202 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006203{
6204 if (PyInt_Check(arg)) {
6205 *valuep = PyInt_AS_LONG(arg);
6206 return 1;
6207 }
6208 if (PyString_Check(arg)) {
6209 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00006210 size_t lo = 0;
6211 size_t mid;
6212 size_t hi = tablesize;
6213 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006214 char *confname = PyString_AS_STRING(arg);
6215 while (lo < hi) {
6216 mid = (lo + hi) / 2;
6217 cmp = strcmp(confname, table[mid].name);
6218 if (cmp < 0)
6219 hi = mid;
6220 else if (cmp > 0)
6221 lo = mid + 1;
6222 else {
6223 *valuep = table[mid].value;
6224 return 1;
6225 }
6226 }
6227 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
6228 }
6229 else
6230 PyErr_SetString(PyExc_TypeError,
6231 "configuration names must be strings or integers");
6232 return 0;
6233}
6234
6235
6236#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
6237static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006238#ifdef _PC_ABI_AIO_XFER_MAX
6239 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
6240#endif
6241#ifdef _PC_ABI_ASYNC_IO
6242 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
6243#endif
Fred Drakec9680921999-12-13 16:37:25 +00006244#ifdef _PC_ASYNC_IO
6245 {"PC_ASYNC_IO", _PC_ASYNC_IO},
6246#endif
6247#ifdef _PC_CHOWN_RESTRICTED
6248 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
6249#endif
6250#ifdef _PC_FILESIZEBITS
6251 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
6252#endif
6253#ifdef _PC_LAST
6254 {"PC_LAST", _PC_LAST},
6255#endif
6256#ifdef _PC_LINK_MAX
6257 {"PC_LINK_MAX", _PC_LINK_MAX},
6258#endif
6259#ifdef _PC_MAX_CANON
6260 {"PC_MAX_CANON", _PC_MAX_CANON},
6261#endif
6262#ifdef _PC_MAX_INPUT
6263 {"PC_MAX_INPUT", _PC_MAX_INPUT},
6264#endif
6265#ifdef _PC_NAME_MAX
6266 {"PC_NAME_MAX", _PC_NAME_MAX},
6267#endif
6268#ifdef _PC_NO_TRUNC
6269 {"PC_NO_TRUNC", _PC_NO_TRUNC},
6270#endif
6271#ifdef _PC_PATH_MAX
6272 {"PC_PATH_MAX", _PC_PATH_MAX},
6273#endif
6274#ifdef _PC_PIPE_BUF
6275 {"PC_PIPE_BUF", _PC_PIPE_BUF},
6276#endif
6277#ifdef _PC_PRIO_IO
6278 {"PC_PRIO_IO", _PC_PRIO_IO},
6279#endif
6280#ifdef _PC_SOCK_MAXBUF
6281 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
6282#endif
6283#ifdef _PC_SYNC_IO
6284 {"PC_SYNC_IO", _PC_SYNC_IO},
6285#endif
6286#ifdef _PC_VDISABLE
6287 {"PC_VDISABLE", _PC_VDISABLE},
6288#endif
6289};
6290
Fred Drakec9680921999-12-13 16:37:25 +00006291static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006292conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006293{
6294 return conv_confname(arg, valuep, posix_constants_pathconf,
6295 sizeof(posix_constants_pathconf)
6296 / sizeof(struct constdef));
6297}
6298#endif
6299
6300#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006301PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006302"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006303Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006304If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006305
6306static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006307posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006308{
6309 PyObject *result = NULL;
6310 int name, fd;
6311
Fred Drake12c6e2d1999-12-14 21:25:03 +00006312 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
6313 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00006314 long limit;
6315
6316 errno = 0;
6317 limit = fpathconf(fd, name);
6318 if (limit == -1 && errno != 0)
6319 posix_error();
6320 else
6321 result = PyInt_FromLong(limit);
6322 }
6323 return result;
6324}
6325#endif
6326
6327
6328#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006329PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006330"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006331Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006332If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006333
6334static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006335posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006336{
6337 PyObject *result = NULL;
6338 int name;
6339 char *path;
6340
6341 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
6342 conv_path_confname, &name)) {
6343 long limit;
6344
6345 errno = 0;
6346 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006347 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00006348 if (errno == EINVAL)
6349 /* could be a path or name problem */
6350 posix_error();
6351 else
6352 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006353 }
Fred Drakec9680921999-12-13 16:37:25 +00006354 else
6355 result = PyInt_FromLong(limit);
6356 }
6357 return result;
6358}
6359#endif
6360
6361#ifdef HAVE_CONFSTR
6362static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006363#ifdef _CS_ARCHITECTURE
6364 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
6365#endif
6366#ifdef _CS_HOSTNAME
6367 {"CS_HOSTNAME", _CS_HOSTNAME},
6368#endif
6369#ifdef _CS_HW_PROVIDER
6370 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
6371#endif
6372#ifdef _CS_HW_SERIAL
6373 {"CS_HW_SERIAL", _CS_HW_SERIAL},
6374#endif
6375#ifdef _CS_INITTAB_NAME
6376 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
6377#endif
Fred Drakec9680921999-12-13 16:37:25 +00006378#ifdef _CS_LFS64_CFLAGS
6379 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
6380#endif
6381#ifdef _CS_LFS64_LDFLAGS
6382 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
6383#endif
6384#ifdef _CS_LFS64_LIBS
6385 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
6386#endif
6387#ifdef _CS_LFS64_LINTFLAGS
6388 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
6389#endif
6390#ifdef _CS_LFS_CFLAGS
6391 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
6392#endif
6393#ifdef _CS_LFS_LDFLAGS
6394 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
6395#endif
6396#ifdef _CS_LFS_LIBS
6397 {"CS_LFS_LIBS", _CS_LFS_LIBS},
6398#endif
6399#ifdef _CS_LFS_LINTFLAGS
6400 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
6401#endif
Fred Draked86ed291999-12-15 15:34:33 +00006402#ifdef _CS_MACHINE
6403 {"CS_MACHINE", _CS_MACHINE},
6404#endif
Fred Drakec9680921999-12-13 16:37:25 +00006405#ifdef _CS_PATH
6406 {"CS_PATH", _CS_PATH},
6407#endif
Fred Draked86ed291999-12-15 15:34:33 +00006408#ifdef _CS_RELEASE
6409 {"CS_RELEASE", _CS_RELEASE},
6410#endif
6411#ifdef _CS_SRPC_DOMAIN
6412 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
6413#endif
6414#ifdef _CS_SYSNAME
6415 {"CS_SYSNAME", _CS_SYSNAME},
6416#endif
6417#ifdef _CS_VERSION
6418 {"CS_VERSION", _CS_VERSION},
6419#endif
Fred Drakec9680921999-12-13 16:37:25 +00006420#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
6421 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
6422#endif
6423#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
6424 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
6425#endif
6426#ifdef _CS_XBS5_ILP32_OFF32_LIBS
6427 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
6428#endif
6429#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
6430 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
6431#endif
6432#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
6433 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
6434#endif
6435#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
6436 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
6437#endif
6438#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
6439 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
6440#endif
6441#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
6442 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
6443#endif
6444#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
6445 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
6446#endif
6447#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
6448 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
6449#endif
6450#ifdef _CS_XBS5_LP64_OFF64_LIBS
6451 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
6452#endif
6453#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
6454 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
6455#endif
6456#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
6457 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
6458#endif
6459#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
6460 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
6461#endif
6462#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
6463 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
6464#endif
6465#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
6466 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
6467#endif
Fred Draked86ed291999-12-15 15:34:33 +00006468#ifdef _MIPS_CS_AVAIL_PROCESSORS
6469 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
6470#endif
6471#ifdef _MIPS_CS_BASE
6472 {"MIPS_CS_BASE", _MIPS_CS_BASE},
6473#endif
6474#ifdef _MIPS_CS_HOSTID
6475 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
6476#endif
6477#ifdef _MIPS_CS_HW_NAME
6478 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
6479#endif
6480#ifdef _MIPS_CS_NUM_PROCESSORS
6481 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
6482#endif
6483#ifdef _MIPS_CS_OSREL_MAJ
6484 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
6485#endif
6486#ifdef _MIPS_CS_OSREL_MIN
6487 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
6488#endif
6489#ifdef _MIPS_CS_OSREL_PATCH
6490 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
6491#endif
6492#ifdef _MIPS_CS_OS_NAME
6493 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
6494#endif
6495#ifdef _MIPS_CS_OS_PROVIDER
6496 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
6497#endif
6498#ifdef _MIPS_CS_PROCESSORS
6499 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
6500#endif
6501#ifdef _MIPS_CS_SERIAL
6502 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
6503#endif
6504#ifdef _MIPS_CS_VENDOR
6505 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
6506#endif
Fred Drakec9680921999-12-13 16:37:25 +00006507};
6508
6509static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006510conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006511{
6512 return conv_confname(arg, valuep, posix_constants_confstr,
6513 sizeof(posix_constants_confstr)
6514 / sizeof(struct constdef));
6515}
6516
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006517PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006518"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006519Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006520
6521static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006522posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006523{
6524 PyObject *result = NULL;
6525 int name;
6526 char buffer[64];
6527
6528 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
6529 int len = confstr(name, buffer, sizeof(buffer));
6530
Fred Drakec9680921999-12-13 16:37:25 +00006531 errno = 0;
6532 if (len == 0) {
6533 if (errno != 0)
6534 posix_error();
6535 else
6536 result = PyString_FromString("");
6537 }
6538 else {
6539 if (len >= sizeof(buffer)) {
6540 result = PyString_FromStringAndSize(NULL, len);
6541 if (result != NULL)
6542 confstr(name, PyString_AS_STRING(result), len+1);
6543 }
6544 else
6545 result = PyString_FromString(buffer);
6546 }
6547 }
6548 return result;
6549}
6550#endif
6551
6552
6553#ifdef HAVE_SYSCONF
6554static struct constdef posix_constants_sysconf[] = {
6555#ifdef _SC_2_CHAR_TERM
6556 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
6557#endif
6558#ifdef _SC_2_C_BIND
6559 {"SC_2_C_BIND", _SC_2_C_BIND},
6560#endif
6561#ifdef _SC_2_C_DEV
6562 {"SC_2_C_DEV", _SC_2_C_DEV},
6563#endif
6564#ifdef _SC_2_C_VERSION
6565 {"SC_2_C_VERSION", _SC_2_C_VERSION},
6566#endif
6567#ifdef _SC_2_FORT_DEV
6568 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
6569#endif
6570#ifdef _SC_2_FORT_RUN
6571 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
6572#endif
6573#ifdef _SC_2_LOCALEDEF
6574 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
6575#endif
6576#ifdef _SC_2_SW_DEV
6577 {"SC_2_SW_DEV", _SC_2_SW_DEV},
6578#endif
6579#ifdef _SC_2_UPE
6580 {"SC_2_UPE", _SC_2_UPE},
6581#endif
6582#ifdef _SC_2_VERSION
6583 {"SC_2_VERSION", _SC_2_VERSION},
6584#endif
Fred Draked86ed291999-12-15 15:34:33 +00006585#ifdef _SC_ABI_ASYNCHRONOUS_IO
6586 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
6587#endif
6588#ifdef _SC_ACL
6589 {"SC_ACL", _SC_ACL},
6590#endif
Fred Drakec9680921999-12-13 16:37:25 +00006591#ifdef _SC_AIO_LISTIO_MAX
6592 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
6593#endif
Fred Drakec9680921999-12-13 16:37:25 +00006594#ifdef _SC_AIO_MAX
6595 {"SC_AIO_MAX", _SC_AIO_MAX},
6596#endif
6597#ifdef _SC_AIO_PRIO_DELTA_MAX
6598 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
6599#endif
6600#ifdef _SC_ARG_MAX
6601 {"SC_ARG_MAX", _SC_ARG_MAX},
6602#endif
6603#ifdef _SC_ASYNCHRONOUS_IO
6604 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
6605#endif
6606#ifdef _SC_ATEXIT_MAX
6607 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
6608#endif
Fred Draked86ed291999-12-15 15:34:33 +00006609#ifdef _SC_AUDIT
6610 {"SC_AUDIT", _SC_AUDIT},
6611#endif
Fred Drakec9680921999-12-13 16:37:25 +00006612#ifdef _SC_AVPHYS_PAGES
6613 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
6614#endif
6615#ifdef _SC_BC_BASE_MAX
6616 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
6617#endif
6618#ifdef _SC_BC_DIM_MAX
6619 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
6620#endif
6621#ifdef _SC_BC_SCALE_MAX
6622 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
6623#endif
6624#ifdef _SC_BC_STRING_MAX
6625 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
6626#endif
Fred Draked86ed291999-12-15 15:34:33 +00006627#ifdef _SC_CAP
6628 {"SC_CAP", _SC_CAP},
6629#endif
Fred Drakec9680921999-12-13 16:37:25 +00006630#ifdef _SC_CHARCLASS_NAME_MAX
6631 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
6632#endif
6633#ifdef _SC_CHAR_BIT
6634 {"SC_CHAR_BIT", _SC_CHAR_BIT},
6635#endif
6636#ifdef _SC_CHAR_MAX
6637 {"SC_CHAR_MAX", _SC_CHAR_MAX},
6638#endif
6639#ifdef _SC_CHAR_MIN
6640 {"SC_CHAR_MIN", _SC_CHAR_MIN},
6641#endif
6642#ifdef _SC_CHILD_MAX
6643 {"SC_CHILD_MAX", _SC_CHILD_MAX},
6644#endif
6645#ifdef _SC_CLK_TCK
6646 {"SC_CLK_TCK", _SC_CLK_TCK},
6647#endif
6648#ifdef _SC_COHER_BLKSZ
6649 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
6650#endif
6651#ifdef _SC_COLL_WEIGHTS_MAX
6652 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
6653#endif
6654#ifdef _SC_DCACHE_ASSOC
6655 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
6656#endif
6657#ifdef _SC_DCACHE_BLKSZ
6658 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
6659#endif
6660#ifdef _SC_DCACHE_LINESZ
6661 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
6662#endif
6663#ifdef _SC_DCACHE_SZ
6664 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
6665#endif
6666#ifdef _SC_DCACHE_TBLKSZ
6667 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
6668#endif
6669#ifdef _SC_DELAYTIMER_MAX
6670 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
6671#endif
6672#ifdef _SC_EQUIV_CLASS_MAX
6673 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
6674#endif
6675#ifdef _SC_EXPR_NEST_MAX
6676 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
6677#endif
6678#ifdef _SC_FSYNC
6679 {"SC_FSYNC", _SC_FSYNC},
6680#endif
6681#ifdef _SC_GETGR_R_SIZE_MAX
6682 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
6683#endif
6684#ifdef _SC_GETPW_R_SIZE_MAX
6685 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
6686#endif
6687#ifdef _SC_ICACHE_ASSOC
6688 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
6689#endif
6690#ifdef _SC_ICACHE_BLKSZ
6691 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
6692#endif
6693#ifdef _SC_ICACHE_LINESZ
6694 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
6695#endif
6696#ifdef _SC_ICACHE_SZ
6697 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
6698#endif
Fred Draked86ed291999-12-15 15:34:33 +00006699#ifdef _SC_INF
6700 {"SC_INF", _SC_INF},
6701#endif
Fred Drakec9680921999-12-13 16:37:25 +00006702#ifdef _SC_INT_MAX
6703 {"SC_INT_MAX", _SC_INT_MAX},
6704#endif
6705#ifdef _SC_INT_MIN
6706 {"SC_INT_MIN", _SC_INT_MIN},
6707#endif
6708#ifdef _SC_IOV_MAX
6709 {"SC_IOV_MAX", _SC_IOV_MAX},
6710#endif
Fred Draked86ed291999-12-15 15:34:33 +00006711#ifdef _SC_IP_SECOPTS
6712 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
6713#endif
Fred Drakec9680921999-12-13 16:37:25 +00006714#ifdef _SC_JOB_CONTROL
6715 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
6716#endif
Fred Draked86ed291999-12-15 15:34:33 +00006717#ifdef _SC_KERN_POINTERS
6718 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
6719#endif
6720#ifdef _SC_KERN_SIM
6721 {"SC_KERN_SIM", _SC_KERN_SIM},
6722#endif
Fred Drakec9680921999-12-13 16:37:25 +00006723#ifdef _SC_LINE_MAX
6724 {"SC_LINE_MAX", _SC_LINE_MAX},
6725#endif
6726#ifdef _SC_LOGIN_NAME_MAX
6727 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
6728#endif
6729#ifdef _SC_LOGNAME_MAX
6730 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
6731#endif
6732#ifdef _SC_LONG_BIT
6733 {"SC_LONG_BIT", _SC_LONG_BIT},
6734#endif
Fred Draked86ed291999-12-15 15:34:33 +00006735#ifdef _SC_MAC
6736 {"SC_MAC", _SC_MAC},
6737#endif
Fred Drakec9680921999-12-13 16:37:25 +00006738#ifdef _SC_MAPPED_FILES
6739 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
6740#endif
6741#ifdef _SC_MAXPID
6742 {"SC_MAXPID", _SC_MAXPID},
6743#endif
6744#ifdef _SC_MB_LEN_MAX
6745 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
6746#endif
6747#ifdef _SC_MEMLOCK
6748 {"SC_MEMLOCK", _SC_MEMLOCK},
6749#endif
6750#ifdef _SC_MEMLOCK_RANGE
6751 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
6752#endif
6753#ifdef _SC_MEMORY_PROTECTION
6754 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
6755#endif
6756#ifdef _SC_MESSAGE_PASSING
6757 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
6758#endif
Fred Draked86ed291999-12-15 15:34:33 +00006759#ifdef _SC_MMAP_FIXED_ALIGNMENT
6760 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
6761#endif
Fred Drakec9680921999-12-13 16:37:25 +00006762#ifdef _SC_MQ_OPEN_MAX
6763 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
6764#endif
6765#ifdef _SC_MQ_PRIO_MAX
6766 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
6767#endif
Fred Draked86ed291999-12-15 15:34:33 +00006768#ifdef _SC_NACLS_MAX
6769 {"SC_NACLS_MAX", _SC_NACLS_MAX},
6770#endif
Fred Drakec9680921999-12-13 16:37:25 +00006771#ifdef _SC_NGROUPS_MAX
6772 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
6773#endif
6774#ifdef _SC_NL_ARGMAX
6775 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
6776#endif
6777#ifdef _SC_NL_LANGMAX
6778 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
6779#endif
6780#ifdef _SC_NL_MSGMAX
6781 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
6782#endif
6783#ifdef _SC_NL_NMAX
6784 {"SC_NL_NMAX", _SC_NL_NMAX},
6785#endif
6786#ifdef _SC_NL_SETMAX
6787 {"SC_NL_SETMAX", _SC_NL_SETMAX},
6788#endif
6789#ifdef _SC_NL_TEXTMAX
6790 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
6791#endif
6792#ifdef _SC_NPROCESSORS_CONF
6793 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
6794#endif
6795#ifdef _SC_NPROCESSORS_ONLN
6796 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
6797#endif
Fred Draked86ed291999-12-15 15:34:33 +00006798#ifdef _SC_NPROC_CONF
6799 {"SC_NPROC_CONF", _SC_NPROC_CONF},
6800#endif
6801#ifdef _SC_NPROC_ONLN
6802 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
6803#endif
Fred Drakec9680921999-12-13 16:37:25 +00006804#ifdef _SC_NZERO
6805 {"SC_NZERO", _SC_NZERO},
6806#endif
6807#ifdef _SC_OPEN_MAX
6808 {"SC_OPEN_MAX", _SC_OPEN_MAX},
6809#endif
6810#ifdef _SC_PAGESIZE
6811 {"SC_PAGESIZE", _SC_PAGESIZE},
6812#endif
6813#ifdef _SC_PAGE_SIZE
6814 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
6815#endif
6816#ifdef _SC_PASS_MAX
6817 {"SC_PASS_MAX", _SC_PASS_MAX},
6818#endif
6819#ifdef _SC_PHYS_PAGES
6820 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
6821#endif
6822#ifdef _SC_PII
6823 {"SC_PII", _SC_PII},
6824#endif
6825#ifdef _SC_PII_INTERNET
6826 {"SC_PII_INTERNET", _SC_PII_INTERNET},
6827#endif
6828#ifdef _SC_PII_INTERNET_DGRAM
6829 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
6830#endif
6831#ifdef _SC_PII_INTERNET_STREAM
6832 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
6833#endif
6834#ifdef _SC_PII_OSI
6835 {"SC_PII_OSI", _SC_PII_OSI},
6836#endif
6837#ifdef _SC_PII_OSI_CLTS
6838 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
6839#endif
6840#ifdef _SC_PII_OSI_COTS
6841 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
6842#endif
6843#ifdef _SC_PII_OSI_M
6844 {"SC_PII_OSI_M", _SC_PII_OSI_M},
6845#endif
6846#ifdef _SC_PII_SOCKET
6847 {"SC_PII_SOCKET", _SC_PII_SOCKET},
6848#endif
6849#ifdef _SC_PII_XTI
6850 {"SC_PII_XTI", _SC_PII_XTI},
6851#endif
6852#ifdef _SC_POLL
6853 {"SC_POLL", _SC_POLL},
6854#endif
6855#ifdef _SC_PRIORITIZED_IO
6856 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
6857#endif
6858#ifdef _SC_PRIORITY_SCHEDULING
6859 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
6860#endif
6861#ifdef _SC_REALTIME_SIGNALS
6862 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
6863#endif
6864#ifdef _SC_RE_DUP_MAX
6865 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
6866#endif
6867#ifdef _SC_RTSIG_MAX
6868 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
6869#endif
6870#ifdef _SC_SAVED_IDS
6871 {"SC_SAVED_IDS", _SC_SAVED_IDS},
6872#endif
6873#ifdef _SC_SCHAR_MAX
6874 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
6875#endif
6876#ifdef _SC_SCHAR_MIN
6877 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
6878#endif
6879#ifdef _SC_SELECT
6880 {"SC_SELECT", _SC_SELECT},
6881#endif
6882#ifdef _SC_SEMAPHORES
6883 {"SC_SEMAPHORES", _SC_SEMAPHORES},
6884#endif
6885#ifdef _SC_SEM_NSEMS_MAX
6886 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
6887#endif
6888#ifdef _SC_SEM_VALUE_MAX
6889 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
6890#endif
6891#ifdef _SC_SHARED_MEMORY_OBJECTS
6892 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
6893#endif
6894#ifdef _SC_SHRT_MAX
6895 {"SC_SHRT_MAX", _SC_SHRT_MAX},
6896#endif
6897#ifdef _SC_SHRT_MIN
6898 {"SC_SHRT_MIN", _SC_SHRT_MIN},
6899#endif
6900#ifdef _SC_SIGQUEUE_MAX
6901 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
6902#endif
6903#ifdef _SC_SIGRT_MAX
6904 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
6905#endif
6906#ifdef _SC_SIGRT_MIN
6907 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
6908#endif
Fred Draked86ed291999-12-15 15:34:33 +00006909#ifdef _SC_SOFTPOWER
6910 {"SC_SOFTPOWER", _SC_SOFTPOWER},
6911#endif
Fred Drakec9680921999-12-13 16:37:25 +00006912#ifdef _SC_SPLIT_CACHE
6913 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
6914#endif
6915#ifdef _SC_SSIZE_MAX
6916 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
6917#endif
6918#ifdef _SC_STACK_PROT
6919 {"SC_STACK_PROT", _SC_STACK_PROT},
6920#endif
6921#ifdef _SC_STREAM_MAX
6922 {"SC_STREAM_MAX", _SC_STREAM_MAX},
6923#endif
6924#ifdef _SC_SYNCHRONIZED_IO
6925 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
6926#endif
6927#ifdef _SC_THREADS
6928 {"SC_THREADS", _SC_THREADS},
6929#endif
6930#ifdef _SC_THREAD_ATTR_STACKADDR
6931 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
6932#endif
6933#ifdef _SC_THREAD_ATTR_STACKSIZE
6934 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
6935#endif
6936#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
6937 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
6938#endif
6939#ifdef _SC_THREAD_KEYS_MAX
6940 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
6941#endif
6942#ifdef _SC_THREAD_PRIORITY_SCHEDULING
6943 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
6944#endif
6945#ifdef _SC_THREAD_PRIO_INHERIT
6946 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
6947#endif
6948#ifdef _SC_THREAD_PRIO_PROTECT
6949 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
6950#endif
6951#ifdef _SC_THREAD_PROCESS_SHARED
6952 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
6953#endif
6954#ifdef _SC_THREAD_SAFE_FUNCTIONS
6955 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
6956#endif
6957#ifdef _SC_THREAD_STACK_MIN
6958 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
6959#endif
6960#ifdef _SC_THREAD_THREADS_MAX
6961 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
6962#endif
6963#ifdef _SC_TIMERS
6964 {"SC_TIMERS", _SC_TIMERS},
6965#endif
6966#ifdef _SC_TIMER_MAX
6967 {"SC_TIMER_MAX", _SC_TIMER_MAX},
6968#endif
6969#ifdef _SC_TTY_NAME_MAX
6970 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
6971#endif
6972#ifdef _SC_TZNAME_MAX
6973 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
6974#endif
6975#ifdef _SC_T_IOV_MAX
6976 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
6977#endif
6978#ifdef _SC_UCHAR_MAX
6979 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
6980#endif
6981#ifdef _SC_UINT_MAX
6982 {"SC_UINT_MAX", _SC_UINT_MAX},
6983#endif
6984#ifdef _SC_UIO_MAXIOV
6985 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
6986#endif
6987#ifdef _SC_ULONG_MAX
6988 {"SC_ULONG_MAX", _SC_ULONG_MAX},
6989#endif
6990#ifdef _SC_USHRT_MAX
6991 {"SC_USHRT_MAX", _SC_USHRT_MAX},
6992#endif
6993#ifdef _SC_VERSION
6994 {"SC_VERSION", _SC_VERSION},
6995#endif
6996#ifdef _SC_WORD_BIT
6997 {"SC_WORD_BIT", _SC_WORD_BIT},
6998#endif
6999#ifdef _SC_XBS5_ILP32_OFF32
7000 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
7001#endif
7002#ifdef _SC_XBS5_ILP32_OFFBIG
7003 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
7004#endif
7005#ifdef _SC_XBS5_LP64_OFF64
7006 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
7007#endif
7008#ifdef _SC_XBS5_LPBIG_OFFBIG
7009 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
7010#endif
7011#ifdef _SC_XOPEN_CRYPT
7012 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
7013#endif
7014#ifdef _SC_XOPEN_ENH_I18N
7015 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
7016#endif
7017#ifdef _SC_XOPEN_LEGACY
7018 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
7019#endif
7020#ifdef _SC_XOPEN_REALTIME
7021 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
7022#endif
7023#ifdef _SC_XOPEN_REALTIME_THREADS
7024 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
7025#endif
7026#ifdef _SC_XOPEN_SHM
7027 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
7028#endif
7029#ifdef _SC_XOPEN_UNIX
7030 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
7031#endif
7032#ifdef _SC_XOPEN_VERSION
7033 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
7034#endif
7035#ifdef _SC_XOPEN_XCU_VERSION
7036 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
7037#endif
7038#ifdef _SC_XOPEN_XPG2
7039 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
7040#endif
7041#ifdef _SC_XOPEN_XPG3
7042 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
7043#endif
7044#ifdef _SC_XOPEN_XPG4
7045 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
7046#endif
7047};
7048
7049static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007050conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007051{
7052 return conv_confname(arg, valuep, posix_constants_sysconf,
7053 sizeof(posix_constants_sysconf)
7054 / sizeof(struct constdef));
7055}
7056
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007057PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007058"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007059Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007060
7061static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007062posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007063{
7064 PyObject *result = NULL;
7065 int name;
7066
7067 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
7068 int value;
7069
7070 errno = 0;
7071 value = sysconf(name);
7072 if (value == -1 && errno != 0)
7073 posix_error();
7074 else
7075 result = PyInt_FromLong(value);
7076 }
7077 return result;
7078}
7079#endif
7080
7081
Fred Drakebec628d1999-12-15 18:31:10 +00007082/* This code is used to ensure that the tables of configuration value names
7083 * are in sorted order as required by conv_confname(), and also to build the
7084 * the exported dictionaries that are used to publish information about the
7085 * names available on the host platform.
7086 *
7087 * Sorting the table at runtime ensures that the table is properly ordered
7088 * when used, even for platforms we're not able to test on. It also makes
7089 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00007090 */
Fred Drakebec628d1999-12-15 18:31:10 +00007091
7092static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007093cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00007094{
7095 const struct constdef *c1 =
7096 (const struct constdef *) v1;
7097 const struct constdef *c2 =
7098 (const struct constdef *) v2;
7099
7100 return strcmp(c1->name, c2->name);
7101}
7102
7103static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007104setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00007105 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007106{
Fred Drakebec628d1999-12-15 18:31:10 +00007107 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00007108 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00007109
7110 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
7111 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00007112 if (d == NULL)
7113 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007114
Barry Warsaw3155db32000-04-13 15:20:40 +00007115 for (i=0; i < tablesize; ++i) {
7116 PyObject *o = PyInt_FromLong(table[i].value);
7117 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
7118 Py_XDECREF(o);
7119 Py_DECREF(d);
7120 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007121 }
Barry Warsaw3155db32000-04-13 15:20:40 +00007122 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00007123 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00007124 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00007125}
7126
Fred Drakebec628d1999-12-15 18:31:10 +00007127/* Return -1 on failure, 0 on success. */
7128static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007129setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007130{
7131#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00007132 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00007133 sizeof(posix_constants_pathconf)
7134 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007135 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007136 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007137#endif
7138#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00007139 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00007140 sizeof(posix_constants_confstr)
7141 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007142 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007143 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007144#endif
7145#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00007146 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00007147 sizeof(posix_constants_sysconf)
7148 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007149 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007150 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007151#endif
Fred Drakebec628d1999-12-15 18:31:10 +00007152 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00007153}
Fred Draked86ed291999-12-15 15:34:33 +00007154
7155
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007156PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007157"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007158Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007159in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007160
7161static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007162posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007163{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007164 abort();
7165 /*NOTREACHED*/
7166 Py_FatalError("abort() called from Python code didn't abort!");
7167 return NULL;
7168}
Fred Drakebec628d1999-12-15 18:31:10 +00007169
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007170#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007171PyDoc_STRVAR(win32_startfile__doc__,
7172"startfile(filepath) - Start a file with its associated application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007173\n\
7174This acts like double-clicking the file in Explorer, or giving the file\n\
7175name as an argument to the DOS \"start\" command: the file is opened\n\
7176with whatever application (if any) its extension is associated.\n\
7177\n\
7178startfile returns as soon as the associated application is launched.\n\
7179There is no option to wait for the application to close, and no way\n\
7180to retrieve the application's exit status.\n\
7181\n\
7182The filepath is relative to the current directory. If you want to use\n\
7183an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007184the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00007185
7186static PyObject *
7187win32_startfile(PyObject *self, PyObject *args)
7188{
7189 char *filepath;
7190 HINSTANCE rc;
7191 if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
7192 return NULL;
7193 Py_BEGIN_ALLOW_THREADS
7194 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
7195 Py_END_ALLOW_THREADS
7196 if (rc <= (HINSTANCE)32)
7197 return win32_error("startfile", filepath);
7198 Py_INCREF(Py_None);
7199 return Py_None;
7200}
7201#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007202
Martin v. Löwis438b5342002-12-27 10:16:42 +00007203#ifdef HAVE_GETLOADAVG
7204PyDoc_STRVAR(posix_getloadavg__doc__,
7205"getloadavg() -> (float, float, float)\n\n\
7206Return the number of processes in the system run queue averaged over\n\
7207the last 1, 5, and 15 minutes or raises OSError if the load average\n\
7208was unobtainable");
7209
7210static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007211posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00007212{
7213 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00007214 if (getloadavg(loadavg, 3)!=3) {
7215 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
7216 return NULL;
7217 } else
7218 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
7219}
7220#endif
7221
7222
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007223static PyMethodDef posix_methods[] = {
7224 {"access", posix_access, METH_VARARGS, posix_access__doc__},
7225#ifdef HAVE_TTYNAME
7226 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
7227#endif
7228 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
7229 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007230#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007231 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007232#endif /* HAVE_CHOWN */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007233#ifdef HAVE_LCHOWN
7234 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
7235#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00007236#ifdef HAVE_CHROOT
7237 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
7238#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007239#ifdef HAVE_CTERMID
Neal Norwitze241ce82003-02-17 18:17:05 +00007240 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007241#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00007242#ifdef HAVE_GETCWD
Neal Norwitze241ce82003-02-17 18:17:05 +00007243 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Walter Dörwald3b918c32002-11-21 20:18:46 +00007244#ifdef Py_USING_UNICODE
Neal Norwitze241ce82003-02-17 18:17:05 +00007245 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00007246#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00007247#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007248#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007249 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007250#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007251 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
7252 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
7253 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007254#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007255 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007256#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007257#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007258 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007259#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007260 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
7261 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
7262 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007263 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007264#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007265 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007266#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007267#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007268 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007269#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007270 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007271#ifdef HAVE_UNAME
Neal Norwitze241ce82003-02-17 18:17:05 +00007272 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007273#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007274 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
7275 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
7276 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007277#ifdef HAVE_TIMES
Neal Norwitze241ce82003-02-17 18:17:05 +00007278 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007279#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007280 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007281#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007282 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
7283 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007284#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00007285#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007286 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
7287 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00007288#if defined(PYOS_OS2)
7289 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
7290 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
7291#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00007292#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007293#ifdef HAVE_FORK1
Neal Norwitze241ce82003-02-17 18:17:05 +00007294 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007295#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007296#ifdef HAVE_FORK
Neal Norwitze241ce82003-02-17 18:17:05 +00007297 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007298#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007299#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Neal Norwitze241ce82003-02-17 18:17:05 +00007300 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007301#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007302#ifdef HAVE_FORKPTY
Neal Norwitze241ce82003-02-17 18:17:05 +00007303 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00007304#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007305#ifdef HAVE_GETEGID
Neal Norwitze241ce82003-02-17 18:17:05 +00007306 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007307#endif /* HAVE_GETEGID */
7308#ifdef HAVE_GETEUID
Neal Norwitze241ce82003-02-17 18:17:05 +00007309 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007310#endif /* HAVE_GETEUID */
7311#ifdef HAVE_GETGID
Neal Norwitze241ce82003-02-17 18:17:05 +00007312 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007313#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00007314#ifdef HAVE_GETGROUPS
Neal Norwitze241ce82003-02-17 18:17:05 +00007315 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007316#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007317 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007318#ifdef HAVE_GETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00007319 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007320#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007321#ifdef HAVE_GETPPID
Neal Norwitze241ce82003-02-17 18:17:05 +00007322 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007323#endif /* HAVE_GETPPID */
7324#ifdef HAVE_GETUID
Neal Norwitze241ce82003-02-17 18:17:05 +00007325 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007326#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007327#ifdef HAVE_GETLOGIN
Neal Norwitze241ce82003-02-17 18:17:05 +00007328 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00007329#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00007330#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007331 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007332#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007333#ifdef HAVE_KILLPG
7334 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
7335#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00007336#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007337 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00007338#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007339#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007340 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007341#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00007342 {"popen2", win32_popen2, METH_VARARGS},
7343 {"popen3", win32_popen3, METH_VARARGS},
7344 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00007345 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007346#else
7347#if defined(PYOS_OS2) && defined(PYCC_GCC)
7348 {"popen2", os2emx_popen2, METH_VARARGS},
7349 {"popen3", os2emx_popen3, METH_VARARGS},
7350 {"popen4", os2emx_popen4, METH_VARARGS},
7351#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00007352#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007353#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007354#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007355 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007356#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007357#ifdef HAVE_SETEUID
7358 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
7359#endif /* HAVE_SETEUID */
7360#ifdef HAVE_SETEGID
7361 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
7362#endif /* HAVE_SETEGID */
7363#ifdef HAVE_SETREUID
7364 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
7365#endif /* HAVE_SETREUID */
7366#ifdef HAVE_SETREGID
7367 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
7368#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007369#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007370 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007371#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007372#ifdef HAVE_SETGROUPS
7373 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
7374#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00007375#ifdef HAVE_GETPGID
7376 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
7377#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007378#ifdef HAVE_SETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00007379 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007380#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007381#ifdef HAVE_WAIT
Neal Norwitze241ce82003-02-17 18:17:05 +00007382 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007383#endif /* HAVE_WAIT */
Tim Petersab034fa2002-02-01 11:27:43 +00007384#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007385 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007386#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007387#ifdef HAVE_GETSID
7388 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
7389#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007390#ifdef HAVE_SETSID
Neal Norwitze241ce82003-02-17 18:17:05 +00007391 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007392#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007393#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007394 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007395#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007396#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007397 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007398#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007399#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007400 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007401#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007402 {"open", posix_open, METH_VARARGS, posix_open__doc__},
7403 {"close", posix_close, METH_VARARGS, posix_close__doc__},
7404 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
7405 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
7406 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
7407 {"read", posix_read, METH_VARARGS, posix_read__doc__},
7408 {"write", posix_write, METH_VARARGS, posix_write__doc__},
7409 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
7410 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00007411 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007412#ifdef HAVE_PIPE
Neal Norwitze241ce82003-02-17 18:17:05 +00007413 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007414#endif
7415#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007416 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007417#endif
Neal Norwitz11690112002-07-30 01:08:28 +00007418#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007419 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
7420#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007421#ifdef HAVE_DEVICE_MACROS
7422 {"major", posix_major, METH_VARARGS, posix_major__doc__},
7423 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
7424 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
7425#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007426#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007427 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007428#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007429#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007430 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007431#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007432#ifdef HAVE_UNSETENV
7433 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
7434#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00007435#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007436 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00007437#endif
Fred Drake4d1e64b2002-04-15 19:40:07 +00007438#ifdef HAVE_FCHDIR
7439 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
7440#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00007441#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007442 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007443#endif
7444#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007445 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007446#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00007447#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00007448#ifdef WCOREDUMP
7449 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
7450#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007451#ifdef WIFCONTINUED
7452 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
7453#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00007454#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007455 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007456#endif /* WIFSTOPPED */
7457#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007458 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007459#endif /* WIFSIGNALED */
7460#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007461 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007462#endif /* WIFEXITED */
7463#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007464 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007465#endif /* WEXITSTATUS */
7466#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007467 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007468#endif /* WTERMSIG */
7469#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007470 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007471#endif /* WSTOPSIG */
7472#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007473#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007474 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007475#endif
7476#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007477 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007478#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00007479#ifdef HAVE_TMPFILE
Neal Norwitze241ce82003-02-17 18:17:05 +00007480 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007481#endif
7482#ifdef HAVE_TEMPNAM
7483 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
7484#endif
7485#ifdef HAVE_TMPNAM
Neal Norwitze241ce82003-02-17 18:17:05 +00007486 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007487#endif
Fred Drakec9680921999-12-13 16:37:25 +00007488#ifdef HAVE_CONFSTR
7489 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
7490#endif
7491#ifdef HAVE_SYSCONF
7492 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
7493#endif
7494#ifdef HAVE_FPATHCONF
7495 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
7496#endif
7497#ifdef HAVE_PATHCONF
7498 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
7499#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007500 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007501#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00007502 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
7503#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007504#ifdef HAVE_GETLOADAVG
Neal Norwitze241ce82003-02-17 18:17:05 +00007505 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00007506#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007507 {NULL, NULL} /* Sentinel */
7508};
7509
7510
Barry Warsaw4a342091996-12-19 23:50:02 +00007511static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007512ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00007513{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007514 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00007515}
7516
Guido van Rossumd48f2521997-12-05 22:19:34 +00007517#if defined(PYOS_OS2)
7518/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007519static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007520{
7521 APIRET rc;
7522 ULONG values[QSV_MAX+1];
7523 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00007524 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00007525
7526 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00007527 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007528 Py_END_ALLOW_THREADS
7529
7530 if (rc != NO_ERROR) {
7531 os2_error(rc);
7532 return -1;
7533 }
7534
Fred Drake4d1e64b2002-04-15 19:40:07 +00007535 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
7536 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
7537 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
7538 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
7539 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
7540 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
7541 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007542
7543 switch (values[QSV_VERSION_MINOR]) {
7544 case 0: ver = "2.00"; break;
7545 case 10: ver = "2.10"; break;
7546 case 11: ver = "2.11"; break;
7547 case 30: ver = "3.00"; break;
7548 case 40: ver = "4.00"; break;
7549 case 50: ver = "5.00"; break;
7550 default:
Tim Peters885d4572001-11-28 20:27:42 +00007551 PyOS_snprintf(tmp, sizeof(tmp),
7552 "%d-%d", values[QSV_VERSION_MAJOR],
7553 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007554 ver = &tmp[0];
7555 }
7556
7557 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007558 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007559 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007560
7561 /* Add Indicator of Which Drive was Used to Boot the System */
7562 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
7563 tmp[1] = ':';
7564 tmp[2] = '\0';
7565
Fred Drake4d1e64b2002-04-15 19:40:07 +00007566 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007567}
7568#endif
7569
Barry Warsaw4a342091996-12-19 23:50:02 +00007570static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007571all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00007572{
Guido van Rossum94f6f721999-01-06 18:42:14 +00007573#ifdef F_OK
7574 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007575#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007576#ifdef R_OK
7577 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007578#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007579#ifdef W_OK
7580 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007581#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007582#ifdef X_OK
7583 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007584#endif
Fred Drakec9680921999-12-13 16:37:25 +00007585#ifdef NGROUPS_MAX
7586 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
7587#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007588#ifdef TMP_MAX
7589 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
7590#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007591#ifdef WCONTINUED
7592 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
7593#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007594#ifdef WNOHANG
7595 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007596#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007597#ifdef WUNTRACED
7598 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
7599#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007600#ifdef O_RDONLY
7601 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
7602#endif
7603#ifdef O_WRONLY
7604 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
7605#endif
7606#ifdef O_RDWR
7607 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
7608#endif
7609#ifdef O_NDELAY
7610 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
7611#endif
7612#ifdef O_NONBLOCK
7613 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
7614#endif
7615#ifdef O_APPEND
7616 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
7617#endif
7618#ifdef O_DSYNC
7619 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
7620#endif
7621#ifdef O_RSYNC
7622 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
7623#endif
7624#ifdef O_SYNC
7625 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
7626#endif
7627#ifdef O_NOCTTY
7628 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
7629#endif
7630#ifdef O_CREAT
7631 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
7632#endif
7633#ifdef O_EXCL
7634 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
7635#endif
7636#ifdef O_TRUNC
7637 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
7638#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00007639#ifdef O_BINARY
7640 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
7641#endif
7642#ifdef O_TEXT
7643 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
7644#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007645#ifdef O_LARGEFILE
7646 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
7647#endif
7648
Tim Peters5aa91602002-01-30 05:46:57 +00007649/* MS Windows */
7650#ifdef O_NOINHERIT
7651 /* Don't inherit in child processes. */
7652 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
7653#endif
7654#ifdef _O_SHORT_LIVED
7655 /* Optimize for short life (keep in memory). */
7656 /* MS forgot to define this one with a non-underscore form too. */
7657 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
7658#endif
7659#ifdef O_TEMPORARY
7660 /* Automatically delete when last handle is closed. */
7661 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
7662#endif
7663#ifdef O_RANDOM
7664 /* Optimize for random access. */
7665 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
7666#endif
7667#ifdef O_SEQUENTIAL
7668 /* Optimize for sequential access. */
7669 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
7670#endif
7671
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007672/* GNU extensions. */
7673#ifdef O_DIRECT
7674 /* Direct disk access. */
7675 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
7676#endif
7677#ifdef O_DIRECTORY
7678 /* Must be a directory. */
7679 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
7680#endif
7681#ifdef O_NOFOLLOW
7682 /* Do not follow links. */
7683 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
7684#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00007685
Barry Warsaw5676bd12003-01-07 20:57:09 +00007686 /* These come from sysexits.h */
7687#ifdef EX_OK
7688 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007689#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007690#ifdef EX_USAGE
7691 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007692#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007693#ifdef EX_DATAERR
7694 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007695#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007696#ifdef EX_NOINPUT
7697 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007698#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007699#ifdef EX_NOUSER
7700 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007701#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007702#ifdef EX_NOHOST
7703 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007704#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007705#ifdef EX_UNAVAILABLE
7706 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007707#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007708#ifdef EX_SOFTWARE
7709 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007710#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007711#ifdef EX_OSERR
7712 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007713#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007714#ifdef EX_OSFILE
7715 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007716#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007717#ifdef EX_CANTCREAT
7718 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007719#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007720#ifdef EX_IOERR
7721 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007722#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007723#ifdef EX_TEMPFAIL
7724 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007725#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007726#ifdef EX_PROTOCOL
7727 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007728#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007729#ifdef EX_NOPERM
7730 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007731#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007732#ifdef EX_CONFIG
7733 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007734#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007735#ifdef EX_NOTFOUND
7736 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007737#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007738
Guido van Rossum246bc171999-02-01 23:54:31 +00007739#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007740#if defined(PYOS_OS2) && defined(PYCC_GCC)
7741 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
7742 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
7743 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
7744 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
7745 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
7746 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
7747 if (ins(d, "P_PM", (long)P_PM)) return -1;
7748 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
7749 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
7750 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
7751 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
7752 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
7753 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
7754 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
7755 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
7756 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
7757 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
7758 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
7759 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
7760 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
7761#else
Guido van Rossum7d385291999-02-16 19:38:04 +00007762 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
7763 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
7764 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
7765 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
7766 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00007767#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007768#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00007769
Guido van Rossumd48f2521997-12-05 22:19:34 +00007770#if defined(PYOS_OS2)
7771 if (insertvalues(d)) return -1;
7772#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007773 return 0;
7774}
7775
7776
Tim Peters5aa91602002-01-30 05:46:57 +00007777#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007778#define INITFUNC initnt
7779#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007780
7781#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007782#define INITFUNC initos2
7783#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007784
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007785#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007786#define INITFUNC initposix
7787#define MODNAME "posix"
7788#endif
7789
Mark Hammondfe51c6d2002-08-02 02:27:13 +00007790PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007791INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00007792{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007793 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00007794
Fred Drake4d1e64b2002-04-15 19:40:07 +00007795 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007796 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00007797 posix__doc__);
Tim Peters5aa91602002-01-30 05:46:57 +00007798
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007799 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007800 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00007801 Py_XINCREF(v);
7802 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007803 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00007804 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00007805
Fred Drake4d1e64b2002-04-15 19:40:07 +00007806 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00007807 return;
7808
Fred Drake4d1e64b2002-04-15 19:40:07 +00007809 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00007810 return;
7811
Fred Drake4d1e64b2002-04-15 19:40:07 +00007812 Py_INCREF(PyExc_OSError);
7813 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00007814
Guido van Rossumb3d39562000-01-31 18:41:26 +00007815#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00007816 if (posix_putenv_garbage == NULL)
7817 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00007818#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007819
Guido van Rossum14648392001-12-08 18:02:58 +00007820 stat_result_desc.name = MODNAME ".stat_result";
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007821 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
7822 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
7823 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007824 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007825 structseq_new = StatResultType.tp_new;
7826 StatResultType.tp_new = statresult_new;
Fred Drake4d1e64b2002-04-15 19:40:07 +00007827 Py_INCREF((PyObject*) &StatResultType);
7828 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007829
Guido van Rossum14648392001-12-08 18:02:58 +00007830 statvfs_result_desc.name = MODNAME ".statvfs_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007831 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Fred Drake4d1e64b2002-04-15 19:40:07 +00007832 Py_INCREF((PyObject*) &StatVFSResultType);
7833 PyModule_AddObject(m, "statvfs_result",
7834 (PyObject*) &StatVFSResultType);
Guido van Rossumb6775db1994-08-01 11:34:53 +00007835}