blob: e1bdb1c8b395b1c192a6c11b350918a4cbd24a21 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002/* POSIX module implementation */
3
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004/* This file is also used for Windows NT/MS-Win and OS/2. In that case the
5 module actually calls itself 'nt' or 'os2', not 'posix', and a few
6 functions are either unimplemented or implemented differently. The source
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007 assumes that for Windows NT, the macro 'MS_WINDOWS' is defined independent
Guido van Rossumad0ee831995-03-01 10:34:45 +00008 of the compiler used. Different compilers define their own feature
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00009 test macro, e.g. '__BORLANDC__' or '_MSC_VER'. For OS/2, the compiler
10 independent macro PYOS_OS2 should be defined. On OS/2 the default
11 compiler is assumed to be IBM's VisualAge C++ (VACPP). PYCC_GCC is used
12 as the compiler specific macro for the EMX port of gcc to OS/2. */
Guido van Rossumad0ee831995-03-01 10:34:45 +000013
Guido van Rossuma4916fa1996-05-23 22:58:55 +000014/* See also ../Dos/dosmodule.c */
Guido van Rossumad0ee831995-03-01 10:34:45 +000015
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000016#include "Python.h"
17#include "structseq.h"
18
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000019#if defined(__VMS)
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000020# include <unixio.h>
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000021#endif /* defined(__VMS) */
22
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000023PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000024"This module provides access to operating system functionality that is\n\
25standardized by the C Standard and the POSIX standard (a thinly\n\
26disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000027corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000028
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000029#ifndef Py_USING_UNICODE
30/* This is used in signatures of functions. */
31#define Py_UNICODE void
32#endif
33
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000034#if defined(PYOS_OS2)
35#define INCL_DOS
36#define INCL_DOSERRORS
37#define INCL_DOSPROCESS
38#define INCL_NOPMAPI
39#include <os2.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000040#if defined(PYCC_GCC)
41#include <ctype.h>
42#include <io.h>
43#include <stdio.h>
44#include <process.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000045#endif
Andrew MacIntyreda4d6cb2004-03-29 11:53:38 +000046#include "osdefs.h"
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000047#endif
48
Guido van Rossumb6775db1994-08-01 11:34:53 +000049#include <sys/types.h>
50#include <sys/stat.h>
Guido van Rossuma6535fd2001-10-18 19:44:10 +000051
Guido van Rossum36bc6801995-06-14 22:54:23 +000052#ifdef HAVE_SYS_WAIT_H
53#include <sys/wait.h> /* For WNOHANG */
54#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000055
Guido van Rossuma376cc51996-12-05 23:43:35 +000056#include <signal.h>
Guido van Rossuma376cc51996-12-05 23:43:35 +000057
Guido van Rossumb6775db1994-08-01 11:34:53 +000058#ifdef HAVE_FCNTL_H
59#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000060#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000061
Guido van Rossuma6535fd2001-10-18 19:44:10 +000062#ifdef HAVE_GRP_H
63#include <grp.h>
64#endif
65
Barry Warsaw5676bd12003-01-07 20:57:09 +000066#ifdef HAVE_SYSEXITS_H
67#include <sysexits.h>
68#endif /* HAVE_SYSEXITS_H */
69
Anthony Baxter8a560de2004-10-13 15:30:56 +000070#ifdef HAVE_SYS_LOADAVG_H
71#include <sys/loadavg.h>
72#endif
73
Guido van Rossuma4916fa1996-05-23 22:58:55 +000074/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +000075/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000076#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000077#include <process.h>
78#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +000079#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000080#define HAVE_GETCWD 1
81#define HAVE_OPENDIR 1
82#define HAVE_SYSTEM 1
83#if defined(__OS2__)
84#define HAVE_EXECV 1
85#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +000086#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000087#include <process.h>
88#else
89#ifdef __BORLANDC__ /* Borland compiler */
90#define HAVE_EXECV 1
91#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +000092#define HAVE_OPENDIR 1
93#define HAVE_PIPE 1
94#define HAVE_POPEN 1
95#define HAVE_SYSTEM 1
96#define HAVE_WAIT 1
97#else
98#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +000099#define HAVE_GETCWD 1
Guido van Rossuma1065681999-01-25 23:20:23 +0000100#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000101#define HAVE_EXECV 1
102#define HAVE_PIPE 1
103#define HAVE_POPEN 1
104#define HAVE_SYSTEM 1
Tim Petersab034fa2002-02-01 11:27:43 +0000105#define HAVE_CWAIT 1
Tim Peters11b23062003-04-23 02:39:17 +0000106#define HAVE_FSYNC 1
107#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000108#else
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000109#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
110/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000111#else /* all other compilers */
112/* Unix functions that the configure script doesn't check for */
113#define HAVE_EXECV 1
114#define HAVE_FORK 1
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000115#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
116#define HAVE_FORK1 1
117#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000118#define HAVE_GETCWD 1
119#define HAVE_GETEGID 1
120#define HAVE_GETEUID 1
121#define HAVE_GETGID 1
122#define HAVE_GETPPID 1
123#define HAVE_GETUID 1
124#define HAVE_KILL 1
125#define HAVE_OPENDIR 1
126#define HAVE_PIPE 1
Martin v. Löwis212ede62003-09-20 11:20:30 +0000127#ifndef __rtems__
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000128#define HAVE_POPEN 1
Martin v. Löwis212ede62003-09-20 11:20:30 +0000129#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000130#define HAVE_SYSTEM 1
131#define HAVE_WAIT 1
Guido van Rossumd371ff11999-01-25 16:12:23 +0000132#define HAVE_TTYNAME 1
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000133#endif /* PYOS_OS2 && PYCC_GCC && __VMS */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000134#endif /* _MSC_VER */
135#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000136#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000137#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000138
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000139#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000140
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000141#if defined(__sgi)&&_COMPILER_VERSION>=700
142/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
143 (default) */
144extern char *ctermid_r(char *);
145#endif
146
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000147#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000148#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000149extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000150#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000151#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000152extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000153#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000154extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000155#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000156#endif
157#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000158extern int chdir(char *);
159extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000160#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000161extern int chdir(const char *);
162extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000163#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000164#ifdef __BORLANDC__
165extern int chmod(const char *, int);
166#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000167extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000168#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000169extern int chown(const char *, uid_t, gid_t);
170extern char *getcwd(char *, int);
171extern char *strerror(int);
172extern int link(const char *, const char *);
173extern int rename(const char *, const char *);
174extern int stat(const char *, struct stat *);
175extern int unlink(const char *);
176extern int pclose(FILE *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000177#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000178extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000179#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000180#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000181extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000182#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000183#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000184
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000185#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000186
Guido van Rossumb6775db1994-08-01 11:34:53 +0000187#ifdef HAVE_UTIME_H
188#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000189#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000190
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000191#ifdef HAVE_SYS_UTIME_H
192#include <sys/utime.h>
193#define HAVE_UTIME_H /* pretend we do for the rest of this file */
194#endif /* HAVE_SYS_UTIME_H */
195
Guido van Rossumb6775db1994-08-01 11:34:53 +0000196#ifdef HAVE_SYS_TIMES_H
197#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000198#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000199
200#ifdef HAVE_SYS_PARAM_H
201#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000202#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000203
204#ifdef HAVE_SYS_UTSNAME_H
205#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000206#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000207
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000208#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000209#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000210#define NAMLEN(dirent) strlen((dirent)->d_name)
211#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000212#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000213#include <direct.h>
214#define NAMLEN(dirent) strlen((dirent)->d_name)
215#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000216#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000217#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000218#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000219#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000220#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000221#endif
222#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000223#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000224#endif
225#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000226#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000227#endif
228#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000229
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000230#ifdef _MSC_VER
Guido van Rossumb6775db1994-08-01 11:34:53 +0000231#include <direct.h>
232#include <io.h>
233#include <process.h>
Tim Petersbc2e10e2002-03-03 23:17:02 +0000234#include "osdefs.h"
Martin v. Löwisdc3883f2004-08-29 15:46:35 +0000235#define _WIN32_WINNT 0x0400 /* Needed for CryptoAPI on some systems */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000236#include <windows.h>
Tim Petersee66d0c2002-07-15 16:10:55 +0000237#include <shellapi.h> /* for ShellExecute() */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000238#define popen _popen
Guido van Rossum794d8131994-08-23 13:48:48 +0000239#define pclose _pclose
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000240#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000241
Guido van Rossumd48f2521997-12-05 22:19:34 +0000242#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000243#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000244#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000245
Tim Petersbc2e10e2002-03-03 23:17:02 +0000246#ifndef MAXPATHLEN
247#define MAXPATHLEN 1024
248#endif /* MAXPATHLEN */
249
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000250#ifdef UNION_WAIT
251/* Emulate some macros on systems that have a union instead of macros */
252
253#ifndef WIFEXITED
254#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
255#endif
256
257#ifndef WEXITSTATUS
258#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
259#endif
260
261#ifndef WTERMSIG
262#define WTERMSIG(u_wait) ((u_wait).w_termsig)
263#endif
264
265#endif /* UNION_WAIT */
266
Greg Wardb48bc172000-03-01 21:51:56 +0000267/* Don't use the "_r" form if we don't need it (also, won't have a
268 prototype for it, at least on Solaris -- maybe others as well?). */
269#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
270#define USE_CTERMID_R
271#endif
272
273#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
274#define USE_TMPNAM_R
275#endif
276
Fred Drake699f3522000-06-29 21:12:41 +0000277/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000278#undef STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000279#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +0000280# define STAT _stati64
281# define FSTAT _fstati64
282# define STRUCT_STAT struct _stati64
283#else
284# define STAT stat
285# define FSTAT fstat
286# define STRUCT_STAT struct stat
287#endif
288
Tim Peters11b23062003-04-23 02:39:17 +0000289#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000290#include <sys/mkdev.h>
291#else
292#if defined(MAJOR_IN_SYSMACROS)
293#include <sys/sysmacros.h>
294#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000295#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
296#include <sys/mkdev.h>
297#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000298#endif
Fred Drake699f3522000-06-29 21:12:41 +0000299
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000300/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000301#ifdef WITH_NEXT_FRAMEWORK
302/* On Darwin/MacOSX a shared library or framework has no access to
303** environ directly, we must obtain it with _NSGetEnviron().
304*/
305#include <crt_externs.h>
306static char **environ;
307#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000308extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000309#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000310
Barry Warsaw53699e91996-12-10 23:23:01 +0000311static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000312convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000313{
Barry Warsaw53699e91996-12-10 23:23:01 +0000314 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000315 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000316 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000317 if (d == NULL)
318 return NULL;
Jack Jansenea0c3822002-08-01 21:57:49 +0000319#ifdef WITH_NEXT_FRAMEWORK
320 if (environ == NULL)
321 environ = *_NSGetEnviron();
322#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000323 if (environ == NULL)
324 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000325 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000326 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000327 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000328 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000329 char *p = strchr(*e, '=');
330 if (p == NULL)
331 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000332 k = PyString_FromStringAndSize(*e, (int)(p-*e));
333 if (k == NULL) {
334 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000335 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000336 }
337 v = PyString_FromString(p+1);
338 if (v == NULL) {
339 PyErr_Clear();
340 Py_DECREF(k);
341 continue;
342 }
343 if (PyDict_GetItem(d, k) == NULL) {
344 if (PyDict_SetItem(d, k, v) != 0)
345 PyErr_Clear();
346 }
347 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000348 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000349 }
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000350#if defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000351 {
352 APIRET rc;
353 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
354
355 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000356 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000357 PyObject *v = PyString_FromString(buffer);
358 PyDict_SetItemString(d, "BEGINLIBPATH", v);
359 Py_DECREF(v);
360 }
361 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
362 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
363 PyObject *v = PyString_FromString(buffer);
364 PyDict_SetItemString(d, "ENDLIBPATH", v);
365 Py_DECREF(v);
366 }
367 }
368#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000369 return d;
370}
371
372
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000373/* Set a POSIX-specific error from errno, and return NULL */
374
Barry Warsawd58d7641998-07-23 16:14:40 +0000375static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000376posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000377{
Barry Warsawca74da41999-02-09 19:31:45 +0000378 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000379}
Barry Warsawd58d7641998-07-23 16:14:40 +0000380static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000381posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000382{
Barry Warsawca74da41999-02-09 19:31:45 +0000383 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000384}
385
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000386#ifdef Py_WIN_WIDE_FILENAMES
387static PyObject *
388posix_error_with_unicode_filename(Py_UNICODE* name)
389{
390 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
391}
392#endif /* Py_WIN_WIDE_FILENAMES */
393
394
Mark Hammondef8b6542001-05-13 08:04:26 +0000395static PyObject *
396posix_error_with_allocated_filename(char* name)
397{
398 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
399 PyMem_Free(name);
400 return rc;
401}
402
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000403#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000404static PyObject *
405win32_error(char* function, char* filename)
406{
Mark Hammond33a6da92000-08-15 00:46:38 +0000407 /* XXX We should pass the function name along in the future.
408 (_winreg.c also wants to pass the function name.)
Tim Peters5aa91602002-01-30 05:46:57 +0000409 This would however require an additional param to the
Mark Hammond33a6da92000-08-15 00:46:38 +0000410 Windows error object, which is non-trivial.
411 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000412 errno = GetLastError();
413 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000414 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000415 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000416 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000417}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000418
419#ifdef Py_WIN_WIDE_FILENAMES
420static PyObject *
421win32_error_unicode(char* function, Py_UNICODE* filename)
422{
423 /* XXX - see win32_error for comments on 'function' */
424 errno = GetLastError();
425 if (filename)
426 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
427 else
428 return PyErr_SetFromWindowsErr(errno);
429}
430
431static PyObject *_PyUnicode_FromFileSystemEncodedObject(register PyObject *obj)
432{
433 /* XXX Perhaps we should make this API an alias of
434 PyObject_Unicode() instead ?! */
435 if (PyUnicode_CheckExact(obj)) {
436 Py_INCREF(obj);
437 return obj;
438 }
439 if (PyUnicode_Check(obj)) {
440 /* For a Unicode subtype that's not a Unicode object,
441 return a true Unicode object with the same data. */
442 return PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(obj),
443 PyUnicode_GET_SIZE(obj));
444 }
Tim Peters11b23062003-04-23 02:39:17 +0000445 return PyUnicode_FromEncodedObject(obj,
446 Py_FileSystemDefaultEncoding,
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000447 "strict");
448}
449
450#endif /* Py_WIN_WIDE_FILENAMES */
451
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000452#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000453
Guido van Rossumd48f2521997-12-05 22:19:34 +0000454#if defined(PYOS_OS2)
455/**********************************************************************
456 * Helper Function to Trim and Format OS/2 Messages
457 **********************************************************************/
458 static void
459os2_formatmsg(char *msgbuf, int msglen, char *reason)
460{
461 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
462
463 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
464 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
465
466 while (lastc > msgbuf && isspace(*lastc))
467 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
468 }
469
470 /* Add Optional Reason Text */
471 if (reason) {
472 strcat(msgbuf, " : ");
473 strcat(msgbuf, reason);
474 }
475}
476
477/**********************************************************************
478 * Decode an OS/2 Operating System Error Code
479 *
480 * A convenience function to lookup an OS/2 error code and return a
481 * text message we can use to raise a Python exception.
482 *
483 * Notes:
484 * The messages for errors returned from the OS/2 kernel reside in
485 * the file OSO001.MSG in the \OS2 directory hierarchy.
486 *
487 **********************************************************************/
488 static char *
489os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
490{
491 APIRET rc;
492 ULONG msglen;
493
494 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
495 Py_BEGIN_ALLOW_THREADS
496 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
497 errorcode, "oso001.msg", &msglen);
498 Py_END_ALLOW_THREADS
499
500 if (rc == NO_ERROR)
501 os2_formatmsg(msgbuf, msglen, reason);
502 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000503 PyOS_snprintf(msgbuf, msgbuflen,
Tim Peters885d4572001-11-28 20:27:42 +0000504 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000505
506 return msgbuf;
507}
508
509/* Set an OS/2-specific error and return NULL. OS/2 kernel
510 errors are not in a global variable e.g. 'errno' nor are
511 they congruent with posix error numbers. */
512
513static PyObject * os2_error(int code)
514{
515 char text[1024];
516 PyObject *v;
517
518 os2_strerror(text, sizeof(text), code, "");
519
520 v = Py_BuildValue("(is)", code, text);
521 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000522 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000523 Py_DECREF(v);
524 }
525 return NULL; /* Signal to Python that an Exception is Pending */
526}
527
528#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000529
530/* POSIX generic methods */
531
Barry Warsaw53699e91996-12-10 23:23:01 +0000532static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000533posix_fildes(PyObject *fdobj, int (*func)(int))
534{
535 int fd;
536 int res;
537 fd = PyObject_AsFileDescriptor(fdobj);
538 if (fd < 0)
539 return NULL;
540 Py_BEGIN_ALLOW_THREADS
541 res = (*func)(fd);
542 Py_END_ALLOW_THREADS
543 if (res < 0)
544 return posix_error();
545 Py_INCREF(Py_None);
546 return Py_None;
547}
Guido van Rossum21142a01999-01-08 21:05:37 +0000548
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000549#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters11b23062003-04-23 02:39:17 +0000550static int
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000551unicode_file_names(void)
552{
553 static int canusewide = -1;
554 if (canusewide == -1) {
Tim Peters11b23062003-04-23 02:39:17 +0000555 /* As per doc for ::GetVersion(), this is the correct test for
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000556 the Windows NT family. */
557 canusewide = (GetVersion() < 0x80000000) ? 1 : 0;
558 }
559 return canusewide;
560}
561#endif
Tim Peters11b23062003-04-23 02:39:17 +0000562
Guido van Rossum21142a01999-01-08 21:05:37 +0000563static PyObject *
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000564posix_1str(PyObject *args, char *format, int (*func)(const char*),
565 char *wformat, int (*wfunc)(const Py_UNICODE*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000566{
Mark Hammondef8b6542001-05-13 08:04:26 +0000567 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000568 int res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000569#ifdef Py_WIN_WIDE_FILENAMES
570 if (unicode_file_names()) {
571 PyUnicodeObject *po;
572 if (PyArg_ParseTuple(args, wformat, &po)) {
573 Py_BEGIN_ALLOW_THREADS
574 /* PyUnicode_AS_UNICODE OK without thread
575 lock as it is a simple dereference. */
576 res = (*wfunc)(PyUnicode_AS_UNICODE(po));
577 Py_END_ALLOW_THREADS
578 if (res < 0)
Mark Hammondd3890362002-10-03 07:24:48 +0000579 return posix_error_with_unicode_filename(PyUnicode_AS_UNICODE(po));
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000580 Py_INCREF(Py_None);
581 return Py_None;
582 }
583 /* Drop the argument parsing error as narrow
584 strings are also valid. */
585 PyErr_Clear();
586 }
587#else
588 /* Platforms that don't support Unicode filenames
589 shouldn't be passing these extra params */
590 assert(wformat==NULL && wfunc == NULL);
591#endif
592
Tim Peters5aa91602002-01-30 05:46:57 +0000593 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000594 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000595 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000596 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000597 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000598 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000599 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000600 return posix_error_with_allocated_filename(path1);
601 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000602 Py_INCREF(Py_None);
603 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000604}
605
Barry Warsaw53699e91996-12-10 23:23:01 +0000606static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000607posix_2str(PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000608 char *format,
609 int (*func)(const char *, const char *),
610 char *wformat,
611 int (*wfunc)(const Py_UNICODE *, const Py_UNICODE *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000612{
Mark Hammondef8b6542001-05-13 08:04:26 +0000613 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000614 int res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000615#ifdef Py_WIN_WIDE_FILENAMES
616 if (unicode_file_names()) {
617 PyObject *po1;
618 PyObject *po2;
619 if (PyArg_ParseTuple(args, wformat, &po1, &po2)) {
620 if (PyUnicode_Check(po1) || PyUnicode_Check(po2)) {
621 PyObject *wpath1;
622 PyObject *wpath2;
623 wpath1 = _PyUnicode_FromFileSystemEncodedObject(po1);
624 wpath2 = _PyUnicode_FromFileSystemEncodedObject(po2);
625 if (!wpath1 || !wpath2) {
626 Py_XDECREF(wpath1);
627 Py_XDECREF(wpath2);
628 return NULL;
629 }
630 Py_BEGIN_ALLOW_THREADS
631 /* PyUnicode_AS_UNICODE OK without thread
632 lock as it is a simple dereference. */
633 res = (*wfunc)(PyUnicode_AS_UNICODE(wpath1),
634 PyUnicode_AS_UNICODE(wpath2));
635 Py_END_ALLOW_THREADS
636 Py_XDECREF(wpath1);
637 Py_XDECREF(wpath2);
638 if (res != 0)
639 return posix_error();
640 Py_INCREF(Py_None);
641 return Py_None;
642 }
643 /* Else flow through as neither is Unicode. */
644 }
645 /* Drop the argument parsing error as narrow
646 strings are also valid. */
647 PyErr_Clear();
648 }
649#else
650 /* Platforms that don't support Unicode filenames
651 shouldn't be passing these extra params */
652 assert(wformat==NULL && wfunc == NULL);
653#endif
654
Mark Hammondef8b6542001-05-13 08:04:26 +0000655 if (!PyArg_ParseTuple(args, format,
Tim Peters5aa91602002-01-30 05:46:57 +0000656 Py_FileSystemDefaultEncoding, &path1,
Mark Hammondef8b6542001-05-13 08:04:26 +0000657 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000658 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000659 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000660 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000661 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000662 PyMem_Free(path1);
663 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000664 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000665 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000666 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000667 Py_INCREF(Py_None);
668 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000669}
670
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000671PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000672"stat_result: Result from stat or lstat.\n\n\
673This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +0000674 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000675or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
676\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +0000677Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
678or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000679\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000680See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000681
682static PyStructSequence_Field stat_result_fields[] = {
683 {"st_mode", "protection bits"},
684 {"st_ino", "inode"},
685 {"st_dev", "device"},
686 {"st_nlink", "number of hard links"},
687 {"st_uid", "user ID of owner"},
688 {"st_gid", "group ID of owner"},
689 {"st_size", "total size, in bytes"},
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000690 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
691 {NULL, "integer time of last access"},
692 {NULL, "integer time of last modification"},
693 {NULL, "integer time of last change"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000694 {"st_atime", "time of last access"},
695 {"st_mtime", "time of last modification"},
696 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000697#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000698 {"st_blksize", "blocksize for filesystem I/O"},
699#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000700#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000701 {"st_blocks", "number of blocks allocated"},
702#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000703#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000704 {"st_rdev", "device type (if inode device)"},
705#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +0000706#ifdef HAVE_STRUCT_STAT_ST_FLAGS
707 {"st_flags", "user defined flags for file"},
708#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +0000709#ifdef HAVE_STRUCT_STAT_ST_GEN
710 {"st_gen", "generation number"},
711#endif
712#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
713 {"st_birthtime", "time of creation"},
714#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000715 {0}
716};
717
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000718#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000719#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000720#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000721#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000722#endif
723
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000724#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000725#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
726#else
727#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
728#endif
729
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000730#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000731#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
732#else
733#define ST_RDEV_IDX ST_BLOCKS_IDX
734#endif
735
Hye-Shik Chang5f937a72005-06-02 13:09:30 +0000736#ifdef HAVE_STRUCT_STAT_ST_FLAGS
737#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
738#else
739#define ST_FLAGS_IDX ST_RDEV_IDX
740#endif
741
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +0000742#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +0000743#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +0000744#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +0000745#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +0000746#endif
747
748#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
749#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
750#else
751#define ST_BIRTHTIME_IDX ST_GEN_IDX
752#endif
753
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000754static PyStructSequence_Desc stat_result_desc = {
755 "stat_result", /* name */
756 stat_result__doc__, /* doc */
757 stat_result_fields,
758 10
759};
760
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000761PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000762"statvfs_result: Result from statvfs or fstatvfs.\n\n\
763This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +0000764 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000765or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000766\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000767See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000768
769static PyStructSequence_Field statvfs_result_fields[] = {
770 {"f_bsize", },
771 {"f_frsize", },
772 {"f_blocks", },
773 {"f_bfree", },
774 {"f_bavail", },
775 {"f_files", },
776 {"f_ffree", },
777 {"f_favail", },
778 {"f_flag", },
779 {"f_namemax",},
780 {0}
781};
782
783static PyStructSequence_Desc statvfs_result_desc = {
784 "statvfs_result", /* name */
785 statvfs_result__doc__, /* doc */
786 statvfs_result_fields,
787 10
788};
789
790static PyTypeObject StatResultType;
791static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000792static newfunc structseq_new;
793
794static PyObject *
795statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
796{
797 PyStructSequence *result;
798 int i;
799
800 result = (PyStructSequence*)structseq_new(type, args, kwds);
801 if (!result)
802 return NULL;
803 /* If we have been initialized from a tuple,
804 st_?time might be set to None. Initialize it
805 from the int slots. */
806 for (i = 7; i <= 9; i++) {
807 if (result->ob_item[i+3] == Py_None) {
808 Py_DECREF(Py_None);
809 Py_INCREF(result->ob_item[i]);
810 result->ob_item[i+3] = result->ob_item[i];
811 }
812 }
813 return (PyObject*)result;
814}
815
816
817
818/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +0000819static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000820
821PyDoc_STRVAR(stat_float_times__doc__,
822"stat_float_times([newval]) -> oldval\n\n\
823Determine whether os.[lf]stat represents time stamps as float objects.\n\
824If newval is True, future calls to stat() return floats, if it is False,\n\
825future calls return ints. \n\
826If newval is omitted, return the current setting.\n");
827
828static PyObject*
829stat_float_times(PyObject* self, PyObject *args)
830{
831 int newval = -1;
832 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
833 return NULL;
834 if (newval == -1)
835 /* Return old value */
836 return PyBool_FromLong(_stat_float_times);
837 _stat_float_times = newval;
838 Py_INCREF(Py_None);
839 return Py_None;
840}
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000841
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000842static void
843fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
844{
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000845 PyObject *fval,*ival;
846#if SIZEOF_TIME_T > SIZEOF_LONG
Martin v. Löwisb9a0f912003-03-29 10:06:18 +0000847 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000848#else
849 ival = PyInt_FromLong((long)sec);
850#endif
851 if (_stat_float_times) {
852 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
853 } else {
854 fval = ival;
855 Py_INCREF(fval);
856 }
857 PyStructSequence_SET_ITEM(v, index, ival);
858 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000859}
860
Tim Peters5aa91602002-01-30 05:46:57 +0000861/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +0000862 (used by posix_stat() and posix_fstat()) */
863static PyObject*
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000864_pystat_fromstructstat(STRUCT_STAT st)
Fred Drake699f3522000-06-29 21:12:41 +0000865{
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000866 unsigned long ansec, mnsec, cnsec;
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000867 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +0000868 if (v == NULL)
869 return NULL;
870
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000871 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st.st_mode));
Fred Drake699f3522000-06-29 21:12:41 +0000872#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +0000873 PyStructSequence_SET_ITEM(v, 1,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +0000874 PyLong_FromLongLong((PY_LONG_LONG)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +0000875#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000876 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st.st_ino));
Fred Drake699f3522000-06-29 21:12:41 +0000877#endif
878#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +0000879 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +0000880 PyLong_FromLongLong((PY_LONG_LONG)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +0000881#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000882 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st.st_dev));
Fred Drake699f3522000-06-29 21:12:41 +0000883#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000884 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st.st_nlink));
885 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st.st_uid));
886 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st.st_gid));
Fred Drake699f3522000-06-29 21:12:41 +0000887#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +0000888 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +0000889 PyLong_FromLongLong((PY_LONG_LONG)st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +0000890#else
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000891 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st.st_size));
Fred Drake699f3522000-06-29 21:12:41 +0000892#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000893
894#ifdef HAVE_STAT_TV_NSEC
895 ansec = st.st_atim.tv_nsec;
896 mnsec = st.st_mtim.tv_nsec;
897 cnsec = st.st_ctim.tv_nsec;
Fred Drake699f3522000-06-29 21:12:41 +0000898#else
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +0000899#ifdef HAVE_STAT_TV_NSEC2
900 ansec = st.st_atimespec.tv_nsec;
901 mnsec = st.st_mtimespec.tv_nsec;
902 cnsec = st.st_ctimespec.tv_nsec;
903#else
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000904 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000905#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +0000906#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +0000907 fill_time(v, 7, st.st_atime, ansec);
908 fill_time(v, 8, st.st_mtime, mnsec);
909 fill_time(v, 9, st.st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000910
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000911#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +0000912 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000913 PyInt_FromLong((long)st.st_blksize));
914#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000915#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +0000916 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000917 PyInt_FromLong((long)st.st_blocks));
918#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000919#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000920 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
921 PyInt_FromLong((long)st.st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +0000922#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +0000923#ifdef HAVE_STRUCT_STAT_ST_GEN
924 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
925 PyInt_FromLong((long)st.st_gen));
926#endif
927#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
928 {
929 PyObject *val;
930 unsigned long bsec,bnsec;
931 bsec = (long)st.st_birthtime;
932#ifdef HAVE_STAT_TV_NSEC2
933 bnsec = st.st_birthtimespec.tv_nsec;
934#else
935 bnsec = 0;
936#endif
937 if (_stat_float_times) {
938 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
939 } else {
940 val = PyInt_FromLong((long)bsec);
941 }
942 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
943 val);
944 }
945#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +0000946#ifdef HAVE_STRUCT_STAT_ST_FLAGS
947 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
948 PyInt_FromLong((long)st.st_flags));
949#endif
Fred Drake699f3522000-06-29 21:12:41 +0000950
951 if (PyErr_Occurred()) {
952 Py_DECREF(v);
953 return NULL;
954 }
955
956 return v;
957}
958
Martin v. Löwisd8948722004-06-02 09:57:56 +0000959#ifdef MS_WINDOWS
960
961/* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
962 where / can be used in place of \ and the trailing slash is optional.
963 Both SERVER and SHARE must have at least one character.
964*/
965
966#define ISSLASHA(c) ((c) == '\\' || (c) == '/')
967#define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
968#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
969
Tim Peters4ad82172004-08-30 17:02:04 +0000970static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +0000971IsUNCRootA(char *path, int pathlen)
972{
973 #define ISSLASH ISSLASHA
974
975 int i, share;
976
977 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
978 /* minimum UNCRoot is \\x\y */
979 return FALSE;
980 for (i = 2; i < pathlen ; i++)
981 if (ISSLASH(path[i])) break;
982 if (i == 2 || i == pathlen)
983 /* do not allow \\\SHARE or \\SERVER */
984 return FALSE;
985 share = i+1;
986 for (i = share; i < pathlen; i++)
987 if (ISSLASH(path[i])) break;
988 return (i != share && (i == pathlen || i == pathlen-1));
989
990 #undef ISSLASH
991}
992
993#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters4ad82172004-08-30 17:02:04 +0000994static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +0000995IsUNCRootW(Py_UNICODE *path, int pathlen)
996{
997 #define ISSLASH ISSLASHW
998
999 int i, share;
1000
1001 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1002 /* minimum UNCRoot is \\x\y */
1003 return FALSE;
1004 for (i = 2; i < pathlen ; i++)
1005 if (ISSLASH(path[i])) break;
1006 if (i == 2 || i == pathlen)
1007 /* do not allow \\\SHARE or \\SERVER */
1008 return FALSE;
1009 share = i+1;
1010 for (i = share; i < pathlen; i++)
1011 if (ISSLASH(path[i])) break;
1012 return (i != share && (i == pathlen || i == pathlen-1));
1013
1014 #undef ISSLASH
1015}
1016#endif /* Py_WIN_WIDE_FILENAMES */
1017#endif /* MS_WINDOWS */
1018
Barry Warsaw53699e91996-12-10 23:23:01 +00001019static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001020posix_do_stat(PyObject *self, PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001021 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001022#ifdef __VMS
1023 int (*statfunc)(const char *, STRUCT_STAT *, ...),
1024#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001025 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001026#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001027 char *wformat,
1028 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001029{
Fred Drake699f3522000-06-29 21:12:41 +00001030 STRUCT_STAT st;
Tim Peters500bd032001-12-19 19:05:01 +00001031 char *path = NULL; /* pass this to stat; do not free() it */
1032 char *pathfree = NULL; /* this memory must be free'd */
Guido van Rossumff4949e1992-08-05 19:58:53 +00001033 int res;
Guido van Rossumace88ae2000-04-21 18:54:45 +00001034
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001035#ifdef MS_WINDOWS
Tim Peters500bd032001-12-19 19:05:01 +00001036 int pathlen;
1037 char pathcopy[MAX_PATH];
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001038#endif /* MS_WINDOWS */
Guido van Rossumace88ae2000-04-21 18:54:45 +00001039
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001040
1041#ifdef Py_WIN_WIDE_FILENAMES
1042 /* If on wide-character-capable OS see if argument
1043 is Unicode and if so use wide API. */
1044 if (unicode_file_names()) {
1045 PyUnicodeObject *po;
1046 if (PyArg_ParseTuple(args, wformat, &po)) {
1047 Py_UNICODE wpath[MAX_PATH+1];
1048 pathlen = wcslen(PyUnicode_AS_UNICODE(po));
1049 /* the library call can blow up if the file name is too long! */
1050 if (pathlen > MAX_PATH) {
1051 errno = ENAMETOOLONG;
1052 return posix_error();
1053 }
1054 wcscpy(wpath, PyUnicode_AS_UNICODE(po));
1055 /* Remove trailing slash or backslash, unless it's the current
1056 drive root (/ or \) or a specific drive's root (like c:\ or c:/).
1057 */
Martin v. Löwisd8948722004-06-02 09:57:56 +00001058 if (pathlen > 0) {
1059 if (ISSLASHW(wpath[pathlen-1])) {
1060 /* It does end with a slash -- exempt the root drive cases. */
Tim Peters4ad82172004-08-30 17:02:04 +00001061 if (pathlen == 1 || (pathlen == 3 && wpath[1] == L':') ||
Martin v. Löwisd8948722004-06-02 09:57:56 +00001062 IsUNCRootW(wpath, pathlen))
1063 /* leave it alone */;
1064 else {
1065 /* nuke the trailing backslash */
1066 wpath[pathlen-1] = L'\0';
1067 }
1068 }
Tim Peters4ad82172004-08-30 17:02:04 +00001069 else if (ISSLASHW(wpath[1]) && pathlen < ARRAYSIZE(wpath)-1 &&
Martin v. Löwisd8948722004-06-02 09:57:56 +00001070 IsUNCRootW(wpath, pathlen)) {
1071 /* UNC root w/o trailing slash: add one when there's room */
1072 wpath[pathlen++] = L'\\';
1073 wpath[pathlen] = L'\0';
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001074 }
1075 }
1076 Py_BEGIN_ALLOW_THREADS
1077 /* PyUnicode_AS_UNICODE result OK without
1078 thread lock as it is a simple dereference. */
1079 res = wstatfunc(wpath, &st);
1080 Py_END_ALLOW_THREADS
1081 if (res != 0)
1082 return posix_error_with_unicode_filename(wpath);
1083 return _pystat_fromstructstat(st);
1084 }
1085 /* Drop the argument parsing error as narrow strings
1086 are also valid. */
1087 PyErr_Clear();
1088 }
1089#endif
1090
Tim Peters5aa91602002-01-30 05:46:57 +00001091 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +00001092 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001093 return NULL;
Tim Peters500bd032001-12-19 19:05:01 +00001094 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +00001095
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001096#ifdef MS_WINDOWS
Guido van Rossumace88ae2000-04-21 18:54:45 +00001097 pathlen = strlen(path);
1098 /* the library call can blow up if the file name is too long! */
1099 if (pathlen > MAX_PATH) {
Tim Peters500bd032001-12-19 19:05:01 +00001100 PyMem_Free(pathfree);
Guido van Rossumace88ae2000-04-21 18:54:45 +00001101 errno = ENAMETOOLONG;
1102 return posix_error();
1103 }
1104
Tim Peters500bd032001-12-19 19:05:01 +00001105 /* Remove trailing slash or backslash, unless it's the current
1106 drive root (/ or \) or a specific drive's root (like c:\ or c:/).
1107 */
Martin v. Löwisd8948722004-06-02 09:57:56 +00001108 if (pathlen > 0) {
1109 if (ISSLASHA(path[pathlen-1])) {
1110 /* It does end with a slash -- exempt the root drive cases. */
Tim Peters4ad82172004-08-30 17:02:04 +00001111 if (pathlen == 1 || (pathlen == 3 && path[1] == ':') ||
Martin v. Löwisd8948722004-06-02 09:57:56 +00001112 IsUNCRootA(path, pathlen))
1113 /* leave it alone */;
1114 else {
1115 /* nuke the trailing backslash */
1116 strncpy(pathcopy, path, pathlen);
1117 pathcopy[pathlen-1] = '\0';
1118 path = pathcopy;
1119 }
1120 }
Tim Peters4ad82172004-08-30 17:02:04 +00001121 else if (ISSLASHA(path[1]) && pathlen < ARRAYSIZE(pathcopy)-1 &&
Martin v. Löwisd8948722004-06-02 09:57:56 +00001122 IsUNCRootA(path, pathlen)) {
1123 /* UNC root w/o trailing slash: add one when there's room */
Guido van Rossumace88ae2000-04-21 18:54:45 +00001124 strncpy(pathcopy, path, pathlen);
Martin v. Löwisd8948722004-06-02 09:57:56 +00001125 pathcopy[pathlen++] = '\\';
1126 pathcopy[pathlen] = '\0';
Guido van Rossumace88ae2000-04-21 18:54:45 +00001127 path = pathcopy;
1128 }
1129 }
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001130#endif /* MS_WINDOWS */
Guido van Rossumace88ae2000-04-21 18:54:45 +00001131
Barry Warsaw53699e91996-12-10 23:23:01 +00001132 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001133 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00001134 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001135 if (res != 0)
Tim Peters500bd032001-12-19 19:05:01 +00001136 return posix_error_with_allocated_filename(pathfree);
Fred Drake699f3522000-06-29 21:12:41 +00001137
Tim Peters500bd032001-12-19 19:05:01 +00001138 PyMem_Free(pathfree);
Fred Drake699f3522000-06-29 21:12:41 +00001139 return _pystat_fromstructstat(st);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001140}
1141
1142
1143/* POSIX methods */
1144
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001145PyDoc_STRVAR(posix_access__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001146"access(path, mode) -> 1 if granted, 0 otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001147Use the real uid/gid to test for access to a path. Note that most\n\
1148operations will use the effective uid/gid, therefore this routine can\n\
1149be used in a suid/sgid environment to test if the invoking user has the\n\
1150specified access to the path. The mode argument can be F_OK to test\n\
1151existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001152
1153static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001154posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001155{
Guido van Rossum015f22a1999-01-06 22:52:38 +00001156 char *path;
1157 int mode;
1158 int res;
1159
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001160#ifdef Py_WIN_WIDE_FILENAMES
1161 if (unicode_file_names()) {
1162 PyUnicodeObject *po;
1163 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1164 Py_BEGIN_ALLOW_THREADS
1165 /* PyUnicode_AS_UNICODE OK without thread lock as
1166 it is a simple dereference. */
1167 res = _waccess(PyUnicode_AS_UNICODE(po), mode);
1168 Py_END_ALLOW_THREADS
1169 return(PyBool_FromLong(res == 0));
1170 }
1171 /* Drop the argument parsing error as narrow strings
1172 are also valid. */
1173 PyErr_Clear();
1174 }
1175#endif
Martin v. Löwisb60ae992005-03-08 09:10:29 +00001176 if (!PyArg_ParseTuple(args, "eti:access",
1177 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +00001178 return NULL;
1179 Py_BEGIN_ALLOW_THREADS
1180 res = access(path, mode);
1181 Py_END_ALLOW_THREADS
Neal Norwitz24b3c222005-09-19 06:43:44 +00001182 PyMem_Free(path);
Guido van Rossum674deb22002-09-01 15:06:28 +00001183 return(PyBool_FromLong(res == 0));
Guido van Rossum94f6f721999-01-06 18:42:14 +00001184}
1185
Guido van Rossumd371ff11999-01-25 16:12:23 +00001186#ifndef F_OK
1187#define F_OK 0
1188#endif
1189#ifndef R_OK
1190#define R_OK 4
1191#endif
1192#ifndef W_OK
1193#define W_OK 2
1194#endif
1195#ifndef X_OK
1196#define X_OK 1
1197#endif
1198
1199#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001200PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001201"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001202Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001203
1204static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001205posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001206{
Guido van Rossum94f6f721999-01-06 18:42:14 +00001207 int id;
1208 char *ret;
1209
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001210 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +00001211 return NULL;
1212
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001213#if defined(__VMS)
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +00001214 /* file descriptor 0 only, the default input device (stdin) */
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001215 if (id == 0) {
1216 ret = ttyname();
1217 }
1218 else {
1219 ret = NULL;
1220 }
1221#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00001222 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001223#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001224 if (ret == NULL)
1225 return(posix_error());
1226 return(PyString_FromString(ret));
1227}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001228#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001229
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001230#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001231PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001232"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001233Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001234
1235static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001236posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001237{
1238 char *ret;
1239 char buffer[L_ctermid];
1240
Greg Wardb48bc172000-03-01 21:51:56 +00001241#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001242 ret = ctermid_r(buffer);
1243#else
1244 ret = ctermid(buffer);
1245#endif
1246 if (ret == NULL)
1247 return(posix_error());
1248 return(PyString_FromString(buffer));
1249}
1250#endif
1251
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001252PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001253"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001254Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001255
Barry Warsaw53699e91996-12-10 23:23:01 +00001256static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001257posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001258{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001259#ifdef MS_WINDOWS
1260 return posix_1str(args, "et:chdir", chdir, "U:chdir", _wchdir);
1261#elif defined(PYOS_OS2) && defined(PYCC_GCC)
1262 return posix_1str(args, "et:chdir", _chdir2, NULL, NULL);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001263#elif defined(__VMS)
Tim Peters11b23062003-04-23 02:39:17 +00001264 return posix_1str(args, "et:chdir", (int (*)(const char *))chdir,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001265 NULL, NULL);
1266#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001267 return posix_1str(args, "et:chdir", chdir, NULL, NULL);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001268#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001269}
1270
Fred Drake4d1e64b2002-04-15 19:40:07 +00001271#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001272PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001273"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001274Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001275opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001276
1277static PyObject *
1278posix_fchdir(PyObject *self, PyObject *fdobj)
1279{
1280 return posix_fildes(fdobj, fchdir);
1281}
1282#endif /* HAVE_FCHDIR */
1283
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001284
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001285PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001286"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001287Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001288
Barry Warsaw53699e91996-12-10 23:23:01 +00001289static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001290posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001291{
Mark Hammondef8b6542001-05-13 08:04:26 +00001292 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +00001293 int i;
1294 int res;
Mark Hammond817c9292003-12-03 01:22:38 +00001295#ifdef Py_WIN_WIDE_FILENAMES
1296 if (unicode_file_names()) {
1297 PyUnicodeObject *po;
1298 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1299 Py_BEGIN_ALLOW_THREADS
1300 res = _wchmod(PyUnicode_AS_UNICODE(po), i);
1301 Py_END_ALLOW_THREADS
1302 if (res < 0)
1303 return posix_error_with_unicode_filename(
1304 PyUnicode_AS_UNICODE(po));
1305 Py_INCREF(Py_None);
1306 return Py_None;
1307 }
1308 /* Drop the argument parsing error as narrow strings
1309 are also valid. */
1310 PyErr_Clear();
1311 }
1312#endif /* Py_WIN_WIDE_FILENAMES */
1313 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
Mark Hammondef8b6542001-05-13 08:04:26 +00001314 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +00001315 return NULL;
1316 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +00001317 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001318 Py_END_ALLOW_THREADS
1319 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001320 return posix_error_with_allocated_filename(path);
1321 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001322 Py_INCREF(Py_None);
1323 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001324}
1325
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001326
Martin v. Löwis244edc82001-10-04 22:44:26 +00001327#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001328PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001329"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001330Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00001331
1332static PyObject *
1333posix_chroot(PyObject *self, PyObject *args)
1334{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001335 return posix_1str(args, "et:chroot", chroot, NULL, NULL);
Martin v. Löwis244edc82001-10-04 22:44:26 +00001336}
1337#endif
1338
Guido van Rossum21142a01999-01-08 21:05:37 +00001339#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001340PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001341"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001342force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001343
1344static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001345posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001346{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001347 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001348}
1349#endif /* HAVE_FSYNC */
1350
1351#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00001352
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00001353#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00001354extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1355#endif
1356
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001357PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001358"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00001359force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001360 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001361
1362static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001363posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001364{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001365 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001366}
1367#endif /* HAVE_FDATASYNC */
1368
1369
Fredrik Lundh10723342000-07-10 16:38:09 +00001370#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001371PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001372"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001373Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001374
Barry Warsaw53699e91996-12-10 23:23:01 +00001375static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001376posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001377{
Mark Hammondef8b6542001-05-13 08:04:26 +00001378 char *path = NULL;
Fredrik Lundh44328e62000-07-10 15:59:30 +00001379 int uid, gid;
1380 int res;
Tim Peters5aa91602002-01-30 05:46:57 +00001381 if (!PyArg_ParseTuple(args, "etii:chown",
1382 Py_FileSystemDefaultEncoding, &path,
Mark Hammondef8b6542001-05-13 08:04:26 +00001383 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +00001384 return NULL;
1385 Py_BEGIN_ALLOW_THREADS
1386 res = chown(path, (uid_t) uid, (gid_t) gid);
1387 Py_END_ALLOW_THREADS
1388 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001389 return posix_error_with_allocated_filename(path);
1390 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +00001391 Py_INCREF(Py_None);
1392 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001393}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001394#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001395
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001396#ifdef HAVE_LCHOWN
1397PyDoc_STRVAR(posix_lchown__doc__,
1398"lchown(path, uid, gid)\n\n\
1399Change the owner and group id of path to the numeric uid and gid.\n\
1400This function will not follow symbolic links.");
1401
1402static PyObject *
1403posix_lchown(PyObject *self, PyObject *args)
1404{
1405 char *path = NULL;
1406 int uid, gid;
1407 int res;
1408 if (!PyArg_ParseTuple(args, "etii:lchown",
1409 Py_FileSystemDefaultEncoding, &path,
1410 &uid, &gid))
1411 return NULL;
1412 Py_BEGIN_ALLOW_THREADS
1413 res = lchown(path, (uid_t) uid, (gid_t) gid);
1414 Py_END_ALLOW_THREADS
Tim Peters11b23062003-04-23 02:39:17 +00001415 if (res < 0)
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001416 return posix_error_with_allocated_filename(path);
1417 PyMem_Free(path);
1418 Py_INCREF(Py_None);
1419 return Py_None;
1420}
1421#endif /* HAVE_LCHOWN */
1422
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001423
Guido van Rossum36bc6801995-06-14 22:54:23 +00001424#ifdef HAVE_GETCWD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001425PyDoc_STRVAR(posix_getcwd__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001426"getcwd() -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001427Return a string representing the current working directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001428
Barry Warsaw53699e91996-12-10 23:23:01 +00001429static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001430posix_getcwd(PyObject *self, PyObject *noargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001431{
1432 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +00001433 char *res;
Neal Norwitze241ce82003-02-17 18:17:05 +00001434
Barry Warsaw53699e91996-12-10 23:23:01 +00001435 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001436#if defined(PYOS_OS2) && defined(PYCC_GCC)
1437 res = _getcwd2(buf, sizeof buf);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001438#else
Guido van Rossumff4949e1992-08-05 19:58:53 +00001439 res = getcwd(buf, sizeof buf);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001440#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001441 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001442 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001443 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001444 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001445}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001446
Walter Dörwald3b918c32002-11-21 20:18:46 +00001447#ifdef Py_USING_UNICODE
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001448PyDoc_STRVAR(posix_getcwdu__doc__,
1449"getcwdu() -> path\n\n\
1450Return a unicode string representing the current working directory.");
1451
1452static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001453posix_getcwdu(PyObject *self, PyObject *noargs)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001454{
1455 char buf[1026];
1456 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001457
1458#ifdef Py_WIN_WIDE_FILENAMES
1459 if (unicode_file_names()) {
1460 wchar_t *wres;
1461 wchar_t wbuf[1026];
1462 Py_BEGIN_ALLOW_THREADS
1463 wres = _wgetcwd(wbuf, sizeof wbuf/ sizeof wbuf[0]);
1464 Py_END_ALLOW_THREADS
1465 if (wres == NULL)
1466 return posix_error();
1467 return PyUnicode_FromWideChar(wbuf, wcslen(wbuf));
1468 }
1469#endif
1470
1471 Py_BEGIN_ALLOW_THREADS
1472#if defined(PYOS_OS2) && defined(PYCC_GCC)
1473 res = _getcwd2(buf, sizeof buf);
1474#else
1475 res = getcwd(buf, sizeof buf);
1476#endif
1477 Py_END_ALLOW_THREADS
1478 if (res == NULL)
1479 return posix_error();
1480 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
1481}
Guido van Rossum36bc6801995-06-14 22:54:23 +00001482#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00001483#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001484
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001485
Guido van Rossumb6775db1994-08-01 11:34:53 +00001486#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001487PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001488"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001489Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001490
Barry Warsaw53699e91996-12-10 23:23:01 +00001491static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001492posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001493{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001494 return posix_2str(args, "etet:link", link, NULL, NULL);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001495}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001496#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001497
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001498
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001499PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001500"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001501Return a list containing the names of the entries in the directory.\n\
1502\n\
1503 path: path of directory to list\n\
1504\n\
1505The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001506entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001507
Barry Warsaw53699e91996-12-10 23:23:01 +00001508static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001509posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001510{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001511 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001512 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001513#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001514
Barry Warsaw53699e91996-12-10 23:23:01 +00001515 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001516 HANDLE hFindFile;
1517 WIN32_FIND_DATA FileData;
Mark Hammondef8b6542001-05-13 08:04:26 +00001518 /* MAX_PATH characters could mean a bigger encoded string */
1519 char namebuf[MAX_PATH*2+5];
1520 char *bufptr = namebuf;
1521 int len = sizeof(namebuf)/sizeof(namebuf[0]);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001522
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001523#ifdef Py_WIN_WIDE_FILENAMES
1524 /* If on wide-character-capable OS see if argument
1525 is Unicode and if so use wide API. */
1526 if (unicode_file_names()) {
1527 PyUnicodeObject *po;
1528 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
1529 WIN32_FIND_DATAW wFileData;
1530 Py_UNICODE wnamebuf[MAX_PATH*2+5];
1531 Py_UNICODE wch;
1532 wcsncpy(wnamebuf, PyUnicode_AS_UNICODE(po), MAX_PATH);
1533 wnamebuf[MAX_PATH] = L'\0';
1534 len = wcslen(wnamebuf);
1535 wch = (len > 0) ? wnamebuf[len-1] : L'\0';
1536 if (wch != L'/' && wch != L'\\' && wch != L':')
1537 wnamebuf[len++] = L'/';
1538 wcscpy(wnamebuf + len, L"*.*");
1539 if ((d = PyList_New(0)) == NULL)
1540 return NULL;
1541 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
1542 if (hFindFile == INVALID_HANDLE_VALUE) {
1543 errno = GetLastError();
1544 if (errno == ERROR_FILE_NOT_FOUND) {
1545 return d;
1546 }
1547 Py_DECREF(d);
1548 return win32_error_unicode("FindFirstFileW", wnamebuf);
1549 }
1550 do {
1551 if (wFileData.cFileName[0] == L'.' &&
1552 (wFileData.cFileName[1] == L'\0' ||
1553 wFileData.cFileName[1] == L'.' &&
1554 wFileData.cFileName[2] == L'\0'))
1555 continue;
1556 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
1557 if (v == NULL) {
1558 Py_DECREF(d);
1559 d = NULL;
1560 break;
1561 }
1562 if (PyList_Append(d, v) != 0) {
1563 Py_DECREF(v);
1564 Py_DECREF(d);
1565 d = NULL;
1566 break;
1567 }
1568 Py_DECREF(v);
1569 } while (FindNextFileW(hFindFile, &wFileData) == TRUE);
1570
1571 if (FindClose(hFindFile) == FALSE) {
1572 Py_DECREF(d);
1573 return win32_error_unicode("FindClose", wnamebuf);
1574 }
1575 return d;
1576 }
1577 /* Drop the argument parsing error as narrow strings
1578 are also valid. */
1579 PyErr_Clear();
1580 }
1581#endif
1582
Tim Peters5aa91602002-01-30 05:46:57 +00001583 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001584 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +00001585 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +00001586 if (len > 0) {
1587 char ch = namebuf[len-1];
1588 if (ch != SEP && ch != ALTSEP && ch != ':')
1589 namebuf[len++] = '/';
1590 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001591 strcpy(namebuf + len, "*.*");
1592
Barry Warsaw53699e91996-12-10 23:23:01 +00001593 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001594 return NULL;
1595
1596 hFindFile = FindFirstFile(namebuf, &FileData);
1597 if (hFindFile == INVALID_HANDLE_VALUE) {
1598 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +00001599 if (errno == ERROR_FILE_NOT_FOUND)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001600 return d;
1601 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00001602 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001603 }
1604 do {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001605 if (FileData.cFileName[0] == '.' &&
1606 (FileData.cFileName[1] == '\0' ||
1607 FileData.cFileName[1] == '.' &&
1608 FileData.cFileName[2] == '\0'))
1609 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001610 v = PyString_FromString(FileData.cFileName);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001611 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001612 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001613 d = NULL;
1614 break;
1615 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001616 if (PyList_Append(d, v) != 0) {
1617 Py_DECREF(v);
1618 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001619 d = NULL;
1620 break;
1621 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001622 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001623 } while (FindNextFile(hFindFile, &FileData) == TRUE);
1624
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001625 if (FindClose(hFindFile) == FALSE) {
1626 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00001627 return win32_error("FindClose", namebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001628 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001629
1630 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001631
Tim Peters0bb44a42000-09-15 07:44:49 +00001632#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001633
1634#ifndef MAX_PATH
1635#define MAX_PATH CCHMAXPATH
1636#endif
1637 char *name, *pt;
1638 int len;
1639 PyObject *d, *v;
1640 char namebuf[MAX_PATH+5];
1641 HDIR hdir = 1;
1642 ULONG srchcnt = 1;
1643 FILEFINDBUF3 ep;
1644 APIRET rc;
1645
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001646 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001647 return NULL;
1648 if (len >= MAX_PATH) {
1649 PyErr_SetString(PyExc_ValueError, "path too long");
1650 return NULL;
1651 }
1652 strcpy(namebuf, name);
1653 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001654 if (*pt == ALTSEP)
1655 *pt = SEP;
1656 if (namebuf[len-1] != SEP)
1657 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001658 strcpy(namebuf + len, "*.*");
1659
1660 if ((d = PyList_New(0)) == NULL)
1661 return NULL;
1662
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001663 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
1664 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001665 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001666 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
1667 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
1668 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001669
1670 if (rc != NO_ERROR) {
1671 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001672 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001673 }
1674
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001675 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001676 do {
1677 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001678 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001679 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001680
1681 strcpy(namebuf, ep.achName);
1682
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001683 /* Leave Case of Name Alone -- In Native Form */
1684 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001685
1686 v = PyString_FromString(namebuf);
1687 if (v == NULL) {
1688 Py_DECREF(d);
1689 d = NULL;
1690 break;
1691 }
1692 if (PyList_Append(d, v) != 0) {
1693 Py_DECREF(v);
1694 Py_DECREF(d);
1695 d = NULL;
1696 break;
1697 }
1698 Py_DECREF(v);
1699 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1700 }
1701
1702 return d;
1703#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001704
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001705 char *name = NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001706 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001707 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001708 struct dirent *ep;
Just van Rossum96b1c902003-03-03 17:32:15 +00001709 int arg_is_unicode = 1;
1710
1711 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
1712 arg_is_unicode = 0;
1713 PyErr_Clear();
1714 }
1715 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001716 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001717 if ((dirp = opendir(name)) == NULL) {
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001718 return posix_error_with_allocated_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001719 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001720 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001721 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001722 PyMem_Free(name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001723 return NULL;
1724 }
1725 while ((ep = readdir(dirp)) != NULL) {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001726 if (ep->d_name[0] == '.' &&
1727 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001728 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001729 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001730 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001731 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001732 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001733 d = NULL;
1734 break;
1735 }
Just van Rossum46c97842003-02-25 21:42:15 +00001736#ifdef Py_USING_UNICODE
Just van Rossum96b1c902003-03-03 17:32:15 +00001737 if (arg_is_unicode) {
Just van Rossum46c97842003-02-25 21:42:15 +00001738 PyObject *w;
1739
1740 w = PyUnicode_FromEncodedObject(v,
Tim Peters11b23062003-04-23 02:39:17 +00001741 Py_FileSystemDefaultEncoding,
Just van Rossum46c97842003-02-25 21:42:15 +00001742 "strict");
Just van Rossum6a421832003-03-04 19:30:44 +00001743 if (w != NULL) {
1744 Py_DECREF(v);
1745 v = w;
1746 }
1747 else {
1748 /* fall back to the original byte string, as
1749 discussed in patch #683592 */
1750 PyErr_Clear();
Just van Rossum46c97842003-02-25 21:42:15 +00001751 }
Just van Rossum46c97842003-02-25 21:42:15 +00001752 }
1753#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001754 if (PyList_Append(d, v) != 0) {
1755 Py_DECREF(v);
1756 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001757 d = NULL;
1758 break;
1759 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001760 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001761 }
1762 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001763 PyMem_Free(name);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001764
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001765 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001766
Tim Peters0bb44a42000-09-15 07:44:49 +00001767#endif /* which OS */
1768} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001769
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001770#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00001771/* A helper function for abspath on win32 */
1772static PyObject *
1773posix__getfullpathname(PyObject *self, PyObject *args)
1774{
1775 /* assume encoded strings wont more than double no of chars */
1776 char inbuf[MAX_PATH*2];
1777 char *inbufp = inbuf;
1778 int insize = sizeof(inbuf)/sizeof(inbuf[0]);
1779 char outbuf[MAX_PATH*2];
1780 char *temp;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001781#ifdef Py_WIN_WIDE_FILENAMES
1782 if (unicode_file_names()) {
1783 PyUnicodeObject *po;
1784 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
1785 Py_UNICODE woutbuf[MAX_PATH*2];
1786 Py_UNICODE *wtemp;
Tim Peters11b23062003-04-23 02:39:17 +00001787 if (!GetFullPathNameW(PyUnicode_AS_UNICODE(po),
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001788 sizeof(woutbuf)/sizeof(woutbuf[0]),
1789 woutbuf, &wtemp))
1790 return win32_error("GetFullPathName", "");
1791 return PyUnicode_FromUnicode(woutbuf, wcslen(woutbuf));
1792 }
1793 /* Drop the argument parsing error as narrow strings
1794 are also valid. */
1795 PyErr_Clear();
1796 }
1797#endif
Tim Peters5aa91602002-01-30 05:46:57 +00001798 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
1799 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00001800 &insize))
1801 return NULL;
1802 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
1803 outbuf, &temp))
1804 return win32_error("GetFullPathName", inbuf);
Martin v. Löwis969297f2004-06-15 18:49:58 +00001805 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
1806 return PyUnicode_Decode(outbuf, strlen(outbuf),
1807 Py_FileSystemDefaultEncoding, NULL);
1808 }
Mark Hammondef8b6542001-05-13 08:04:26 +00001809 return PyString_FromString(outbuf);
1810} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001811#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00001812
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001813PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001814"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001815Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001816
Barry Warsaw53699e91996-12-10 23:23:01 +00001817static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001818posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001819{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001820 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00001821 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001822 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001823
1824#ifdef Py_WIN_WIDE_FILENAMES
1825 if (unicode_file_names()) {
1826 PyUnicodeObject *po;
Mark Hammond05107b62003-02-19 04:08:27 +00001827 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001828 Py_BEGIN_ALLOW_THREADS
1829 /* PyUnicode_AS_UNICODE OK without thread lock as
1830 it is a simple dereference. */
1831 res = _wmkdir(PyUnicode_AS_UNICODE(po));
1832 Py_END_ALLOW_THREADS
1833 if (res < 0)
1834 return posix_error();
1835 Py_INCREF(Py_None);
1836 return Py_None;
1837 }
1838 /* Drop the argument parsing error as narrow strings
1839 are also valid. */
1840 PyErr_Clear();
1841 }
1842#endif
1843
Tim Peters5aa91602002-01-30 05:46:57 +00001844 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001845 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001846 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001847 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001848#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001849 res = mkdir(path);
1850#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001851 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001852#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001853 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001854 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001855 return posix_error_with_allocated_filename(path);
1856 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001857 Py_INCREF(Py_None);
1858 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001859}
1860
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001861
Guido van Rossumb6775db1994-08-01 11:34:53 +00001862#ifdef HAVE_NICE
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001863#if defined(HAVE_BROKEN_NICE) && defined(HAVE_SYS_RESOURCE_H)
1864#if defined(HAVE_GETPRIORITY) && !defined(PRIO_PROCESS)
1865#include <sys/resource.h>
1866#endif
1867#endif
1868
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001869PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001870"nice(inc) -> new_priority\n\n\
1871Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001872
Barry Warsaw53699e91996-12-10 23:23:01 +00001873static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001874posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00001875{
1876 int increment, value;
1877
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001878 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00001879 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001880
1881 /* There are two flavours of 'nice': one that returns the new
1882 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001883 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
1884 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00001885
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001886 If we are of the nice family that returns the new priority, we
1887 need to clear errno before the call, and check if errno is filled
1888 before calling posix_error() on a returnvalue of -1, because the
1889 -1 may be the actual new priority! */
1890
1891 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00001892 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001893#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00001894 if (value == 0)
1895 value = getpriority(PRIO_PROCESS, 0);
1896#endif
1897 if (value == -1 && errno != 0)
1898 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00001899 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001900 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00001901}
Guido van Rossumb6775db1994-08-01 11:34:53 +00001902#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00001903
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001904
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001905PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001906"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001907Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001908
Barry Warsaw53699e91996-12-10 23:23:01 +00001909static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001910posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001911{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001912#ifdef MS_WINDOWS
1913 return posix_2str(args, "etet:rename", rename, "OO:rename", _wrename);
1914#else
1915 return posix_2str(args, "etet:rename", rename, NULL, NULL);
1916#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001917}
1918
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001919
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001920PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001921"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001922Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001923
Barry Warsaw53699e91996-12-10 23:23:01 +00001924static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001925posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001926{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001927#ifdef MS_WINDOWS
1928 return posix_1str(args, "et:rmdir", rmdir, "U:rmdir", _wrmdir);
1929#else
1930 return posix_1str(args, "et:rmdir", rmdir, NULL, NULL);
1931#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001932}
1933
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001934
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001935PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001936"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001937Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001938
Barry Warsaw53699e91996-12-10 23:23:01 +00001939static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001940posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001941{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001942#ifdef MS_WINDOWS
1943 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", _wstati64);
1944#else
1945 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
1946#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001947}
1948
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001949
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001950#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001951PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001952"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001953Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001954
Barry Warsaw53699e91996-12-10 23:23:01 +00001955static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001956posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001957{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001958 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001959 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001960 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001961 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001962 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00001963 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00001964 Py_END_ALLOW_THREADS
1965 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001966}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001967#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001968
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001969
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001970PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001971"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001972Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001973
Barry Warsaw53699e91996-12-10 23:23:01 +00001974static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001975posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001976{
1977 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001978 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001979 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00001980 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001981 if (i < 0)
1982 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001983 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001984}
1985
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001986
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001987PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001988"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001989Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001990
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001991PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001992"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001993Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001994
Barry Warsaw53699e91996-12-10 23:23:01 +00001995static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001996posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001997{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001998#ifdef MS_WINDOWS
1999 return posix_1str(args, "et:remove", unlink, "U:remove", _wunlink);
2000#else
2001 return posix_1str(args, "et:remove", unlink, NULL, NULL);
2002#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002003}
2004
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002005
Guido van Rossumb6775db1994-08-01 11:34:53 +00002006#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002007PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002008"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002009Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002010
Barry Warsaw53699e91996-12-10 23:23:01 +00002011static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002012posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002013{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002014 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002015 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00002016
Barry Warsaw53699e91996-12-10 23:23:01 +00002017 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002018 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00002019 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002020 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002021 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002022 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00002023 u.sysname,
2024 u.nodename,
2025 u.release,
2026 u.version,
2027 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002028}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002029#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002030
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002031static int
2032extract_time(PyObject *t, long* sec, long* usec)
2033{
2034 long intval;
2035 if (PyFloat_Check(t)) {
2036 double tval = PyFloat_AsDouble(t);
2037 PyObject *intobj = t->ob_type->tp_as_number->nb_int(t);
2038 if (!intobj)
2039 return -1;
2040 intval = PyInt_AsLong(intobj);
2041 Py_DECREF(intobj);
Michael W. Hudsonb8963812005-07-05 15:21:58 +00002042 if (intval == -1 && PyErr_Occurred())
2043 return -1;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002044 *sec = intval;
Tim Peters96940cf2002-09-10 15:37:28 +00002045 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002046 if (*usec < 0)
2047 /* If rounding gave us a negative number,
2048 truncate. */
2049 *usec = 0;
2050 return 0;
2051 }
2052 intval = PyInt_AsLong(t);
2053 if (intval == -1 && PyErr_Occurred())
2054 return -1;
2055 *sec = intval;
2056 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00002057 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002058}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002059
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002060PyDoc_STRVAR(posix_utime__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002061"utime(path, (atime, utime))\n\
2062utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00002063Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002064second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002065
Barry Warsaw53699e91996-12-10 23:23:01 +00002066static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002067posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002068{
Neal Norwitz2adf2102004-06-09 01:46:02 +00002069 char *path = NULL;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002070 long atime, mtime, ausec, musec;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002071 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002072 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002073
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002074#if defined(HAVE_UTIMES)
2075 struct timeval buf[2];
2076#define ATIME buf[0].tv_sec
2077#define MTIME buf[1].tv_sec
2078#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002079/* XXX should define struct utimbuf instead, above */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002080 struct utimbuf buf;
2081#define ATIME buf.actime
2082#define MTIME buf.modtime
2083#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002084#else /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002085 time_t buf[2];
2086#define ATIME buf[0]
2087#define MTIME buf[1]
2088#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002089#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002090
Mark Hammond817c9292003-12-03 01:22:38 +00002091 int have_unicode_filename = 0;
2092#ifdef Py_WIN_WIDE_FILENAMES
2093 PyUnicodeObject *obwpath;
2094 wchar_t *wpath;
2095 if (unicode_file_names()) {
2096 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
2097 wpath = PyUnicode_AS_UNICODE(obwpath);
2098 have_unicode_filename = 1;
2099 } else
2100 /* Drop the argument parsing error as narrow strings
2101 are also valid. */
2102 PyErr_Clear();
2103 }
2104#endif /* Py_WIN_WIDE_FILENAMES */
2105
2106 if (!have_unicode_filename && \
Hye-Shik Chang2b2c9732004-01-04 13:54:25 +00002107 !PyArg_ParseTuple(args, "etO:utime",
2108 Py_FileSystemDefaultEncoding, &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002109 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002110 if (arg == Py_None) {
2111 /* optional time values not given */
2112 Py_BEGIN_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002113#ifdef Py_WIN_WIDE_FILENAMES
2114 if (have_unicode_filename)
2115 res = _wutime(wpath, NULL);
2116 else
2117#endif /* Py_WIN_WIDE_FILENAMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002118 res = utime(path, NULL);
2119 Py_END_ALLOW_THREADS
2120 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002121 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00002122 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002123 "utime() arg 2 must be a tuple (atime, mtime)");
Neal Norwitz96652712004-06-06 20:40:27 +00002124 PyMem_Free(path);
Barry Warsaw3cef8562000-05-01 16:17:24 +00002125 return NULL;
2126 }
2127 else {
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002128 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Neal Norwitz96652712004-06-06 20:40:27 +00002129 &atime, &ausec) == -1) {
2130 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002131 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002132 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002133 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Neal Norwitz96652712004-06-06 20:40:27 +00002134 &mtime, &musec) == -1) {
2135 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002136 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002137 }
Barry Warsaw3cef8562000-05-01 16:17:24 +00002138 ATIME = atime;
2139 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002140#ifdef HAVE_UTIMES
2141 buf[0].tv_usec = ausec;
2142 buf[1].tv_usec = musec;
2143 Py_BEGIN_ALLOW_THREADS
2144 res = utimes(path, buf);
2145 Py_END_ALLOW_THREADS
2146#else
Barry Warsaw3cef8562000-05-01 16:17:24 +00002147 Py_BEGIN_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002148#ifdef Py_WIN_WIDE_FILENAMES
2149 if (have_unicode_filename)
Tim Peters4ad82172004-08-30 17:02:04 +00002150 /* utime is OK with utimbuf, but _wutime insists
2151 on _utimbuf (the msvc headers assert the
Mark Hammond817c9292003-12-03 01:22:38 +00002152 underscore version is ansi) */
2153 res = _wutime(wpath, (struct _utimbuf *)UTIME_ARG);
2154 else
2155#endif /* Py_WIN_WIDE_FILENAMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002156 res = utime(path, UTIME_ARG);
2157 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002158#endif /* HAVE_UTIMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002159 }
Mark Hammond2d5914b2004-05-04 08:10:37 +00002160 if (res < 0) {
2161#ifdef Py_WIN_WIDE_FILENAMES
Neal Norwitz2adf2102004-06-09 01:46:02 +00002162 if (have_unicode_filename)
Mark Hammond2d5914b2004-05-04 08:10:37 +00002163 return posix_error_with_unicode_filename(wpath);
2164#endif /* Py_WIN_WIDE_FILENAMES */
Neal Norwitz96652712004-06-06 20:40:27 +00002165 return posix_error_with_allocated_filename(path);
Mark Hammond2d5914b2004-05-04 08:10:37 +00002166 }
Neal Norwitz96652712004-06-06 20:40:27 +00002167 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002168 Py_INCREF(Py_None);
2169 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002170#undef UTIME_ARG
2171#undef ATIME
2172#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002173}
2174
Guido van Rossum85e3b011991-06-03 12:42:10 +00002175
Guido van Rossum3b066191991-06-04 19:40:25 +00002176/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002177
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002178PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002179"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002180Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002181
Barry Warsaw53699e91996-12-10 23:23:01 +00002182static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002183posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002184{
2185 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002186 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002187 return NULL;
2188 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00002189 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002190}
2191
Martin v. Löwis114619e2002-10-07 06:44:21 +00002192#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
2193static void
2194free_string_array(char **array, int count)
2195{
2196 int i;
2197 for (i = 0; i < count; i++)
2198 PyMem_Free(array[i]);
2199 PyMem_DEL(array);
2200}
2201#endif
2202
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002203
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002204#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002205PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002206"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002207Execute an executable path with arguments, replacing current process.\n\
2208\n\
2209 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002210 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002211
Barry Warsaw53699e91996-12-10 23:23:01 +00002212static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002213posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002214{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002215 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002216 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002217 char **argvlist;
2218 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002219 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002220
Guido van Rossum89b33251993-10-22 14:26:06 +00002221 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00002222 argv is a list or tuple of strings. */
2223
Martin v. Löwis114619e2002-10-07 06:44:21 +00002224 if (!PyArg_ParseTuple(args, "etO:execv",
2225 Py_FileSystemDefaultEncoding,
2226 &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002227 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002228 if (PyList_Check(argv)) {
2229 argc = PyList_Size(argv);
2230 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002231 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002232 else if (PyTuple_Check(argv)) {
2233 argc = PyTuple_Size(argv);
2234 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002235 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002236 else {
Fred Drake661ea262000-10-24 19:57:45 +00002237 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002238 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002239 return NULL;
2240 }
2241
Barry Warsaw53699e91996-12-10 23:23:01 +00002242 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002243 if (argvlist == NULL) {
2244 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002245 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002246 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002247 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002248 if (!PyArg_Parse((*getitem)(argv, i), "et",
2249 Py_FileSystemDefaultEncoding,
2250 &argvlist[i])) {
2251 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00002252 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002253 "execv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002254 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002255 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00002256
Guido van Rossum85e3b011991-06-03 12:42:10 +00002257 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002258 }
2259 argvlist[argc] = NULL;
2260
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002261 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002262
Guido van Rossum85e3b011991-06-03 12:42:10 +00002263 /* If we get here it's definitely an error */
2264
Martin v. Löwis114619e2002-10-07 06:44:21 +00002265 free_string_array(argvlist, argc);
2266 PyMem_Free(path);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002267 return posix_error();
2268}
2269
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002270
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002271PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002272"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002273Execute a path with arguments and environment, replacing current process.\n\
2274\n\
2275 path: path of executable file\n\
2276 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002277 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002278
Barry Warsaw53699e91996-12-10 23:23:01 +00002279static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002280posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002281{
2282 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002283 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002284 char **argvlist;
2285 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002286 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002287 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002288 PyObject *(*getitem)(PyObject *, int);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002289 int lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002290
2291 /* execve has three arguments: (path, argv, env), where
2292 argv is a list or tuple of strings and env is a dictionary
2293 like posix.environ. */
2294
Martin v. Löwis114619e2002-10-07 06:44:21 +00002295 if (!PyArg_ParseTuple(args, "etOO:execve",
2296 Py_FileSystemDefaultEncoding,
2297 &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002298 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002299 if (PyList_Check(argv)) {
2300 argc = PyList_Size(argv);
2301 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002302 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002303 else if (PyTuple_Check(argv)) {
2304 argc = PyTuple_Size(argv);
2305 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002306 }
2307 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002308 PyErr_SetString(PyExc_TypeError,
2309 "execve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002310 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002311 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002312 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002313 PyErr_SetString(PyExc_TypeError,
2314 "execve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002315 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002316 }
2317
Barry Warsaw53699e91996-12-10 23:23:01 +00002318 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002319 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002320 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002321 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002322 }
2323 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002324 if (!PyArg_Parse((*getitem)(argv, i),
Martin v. Löwis114619e2002-10-07 06:44:21 +00002325 "et;execve() arg 2 must contain only strings",
Guido van Rossum1e700d22002-10-16 16:52:11 +00002326 Py_FileSystemDefaultEncoding,
Barry Warsaw43d68b81996-12-19 22:10:44 +00002327 &argvlist[i]))
2328 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002329 lastarg = i;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002330 goto fail_1;
2331 }
2332 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002333 lastarg = argc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002334 argvlist[argc] = NULL;
2335
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002336 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002337 if (i < 0)
2338 goto fail_1;
Barry Warsaw53699e91996-12-10 23:23:01 +00002339 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002340 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002341 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002342 goto fail_1;
2343 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002344 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002345 keys = PyMapping_Keys(env);
2346 vals = PyMapping_Values(env);
2347 if (!keys || !vals)
2348 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002349 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2350 PyErr_SetString(PyExc_TypeError,
2351 "execve(): env.keys() or env.values() is not a list");
2352 goto fail_2;
2353 }
Tim Peters5aa91602002-01-30 05:46:57 +00002354
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002355 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002356 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002357 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002358
2359 key = PyList_GetItem(keys, pos);
2360 val = PyList_GetItem(vals, pos);
2361 if (!key || !val)
2362 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002363
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002364 if (!PyArg_Parse(
2365 key,
2366 "s;execve() arg 3 contains a non-string key",
2367 &k) ||
2368 !PyArg_Parse(
2369 val,
2370 "s;execve() arg 3 contains a non-string value",
2371 &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00002372 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002373 goto fail_2;
2374 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00002375
2376#if defined(PYOS_OS2)
2377 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
2378 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
2379#endif
Tim Petersc8996f52001-12-03 20:41:00 +00002380 len = PyString_Size(key) + PyString_Size(val) + 2;
2381 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002382 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002383 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002384 goto fail_2;
2385 }
Tim Petersc8996f52001-12-03 20:41:00 +00002386 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002387 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00002388#if defined(PYOS_OS2)
2389 }
2390#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002391 }
2392 envlist[envc] = 0;
2393
2394 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00002395
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002396 /* If we get here it's definitely an error */
2397
2398 (void) posix_error();
2399
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002400 fail_2:
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002401 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00002402 PyMem_DEL(envlist[envc]);
2403 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002404 fail_1:
2405 free_string_array(argvlist, lastarg);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002406 Py_XDECREF(vals);
2407 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002408 fail_0:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002409 PyMem_Free(path);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002410 return NULL;
2411}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002412#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002413
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002414
Guido van Rossuma1065681999-01-25 23:20:23 +00002415#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002416PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002417"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002418Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002419\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002420 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002421 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002422 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002423
2424static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002425posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002426{
2427 char *path;
2428 PyObject *argv;
2429 char **argvlist;
2430 int mode, i, argc;
Tim Peters79248aa2001-08-29 21:37:10 +00002431 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002432 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00002433
2434 /* spawnv has three arguments: (mode, path, argv), where
2435 argv is a list or tuple of strings. */
2436
Martin v. Löwis114619e2002-10-07 06:44:21 +00002437 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
2438 Py_FileSystemDefaultEncoding,
2439 &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00002440 return NULL;
2441 if (PyList_Check(argv)) {
2442 argc = PyList_Size(argv);
2443 getitem = PyList_GetItem;
2444 }
2445 else if (PyTuple_Check(argv)) {
2446 argc = PyTuple_Size(argv);
2447 getitem = PyTuple_GetItem;
2448 }
2449 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002450 PyErr_SetString(PyExc_TypeError,
2451 "spawnv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002452 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002453 return NULL;
2454 }
2455
2456 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002457 if (argvlist == NULL) {
2458 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002459 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002460 }
Guido van Rossuma1065681999-01-25 23:20:23 +00002461 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002462 if (!PyArg_Parse((*getitem)(argv, i), "et",
2463 Py_FileSystemDefaultEncoding,
2464 &argvlist[i])) {
2465 free_string_array(argvlist, i);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002466 PyErr_SetString(
2467 PyExc_TypeError,
2468 "spawnv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002469 PyMem_Free(path);
Fred Drake137507e2000-06-01 02:02:46 +00002470 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00002471 }
2472 }
2473 argvlist[argc] = NULL;
2474
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002475#if defined(PYOS_OS2) && defined(PYCC_GCC)
2476 Py_BEGIN_ALLOW_THREADS
2477 spawnval = spawnv(mode, path, argvlist);
2478 Py_END_ALLOW_THREADS
2479#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002480 if (mode == _OLD_P_OVERLAY)
2481 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00002482
Tim Peters25059d32001-12-07 20:35:43 +00002483 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002484 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00002485 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002486#endif
Tim Peters5aa91602002-01-30 05:46:57 +00002487
Martin v. Löwis114619e2002-10-07 06:44:21 +00002488 free_string_array(argvlist, argc);
2489 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002490
Fred Drake699f3522000-06-29 21:12:41 +00002491 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002492 return posix_error();
2493 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002494#if SIZEOF_LONG == SIZEOF_VOID_P
2495 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002496#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00002497 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002498#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002499}
2500
2501
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002502PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002503"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002504Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002505\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002506 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002507 path: path of executable file\n\
2508 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002509 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002510
2511static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002512posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002513{
2514 char *path;
2515 PyObject *argv, *env;
2516 char **argvlist;
2517 char **envlist;
2518 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
2519 int mode, i, pos, argc, envc;
Tim Peters79248aa2001-08-29 21:37:10 +00002520 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002521 PyObject *(*getitem)(PyObject *, int);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002522 int lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002523
2524 /* spawnve has four arguments: (mode, path, argv, env), where
2525 argv is a list or tuple of strings and env is a dictionary
2526 like posix.environ. */
2527
Martin v. Löwis114619e2002-10-07 06:44:21 +00002528 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
2529 Py_FileSystemDefaultEncoding,
2530 &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00002531 return NULL;
2532 if (PyList_Check(argv)) {
2533 argc = PyList_Size(argv);
2534 getitem = PyList_GetItem;
2535 }
2536 else if (PyTuple_Check(argv)) {
2537 argc = PyTuple_Size(argv);
2538 getitem = PyTuple_GetItem;
2539 }
2540 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002541 PyErr_SetString(PyExc_TypeError,
2542 "spawnve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002543 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002544 }
2545 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002546 PyErr_SetString(PyExc_TypeError,
2547 "spawnve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002548 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002549 }
2550
2551 argvlist = PyMem_NEW(char *, argc+1);
2552 if (argvlist == NULL) {
2553 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002554 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002555 }
2556 for (i = 0; i < argc; i++) {
2557 if (!PyArg_Parse((*getitem)(argv, i),
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002558 "et;spawnve() arg 2 must contain only strings",
Martin v. Löwis114619e2002-10-07 06:44:21 +00002559 Py_FileSystemDefaultEncoding,
Guido van Rossuma1065681999-01-25 23:20:23 +00002560 &argvlist[i]))
2561 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002562 lastarg = i;
Guido van Rossuma1065681999-01-25 23:20:23 +00002563 goto fail_1;
2564 }
2565 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002566 lastarg = argc;
Guido van Rossuma1065681999-01-25 23:20:23 +00002567 argvlist[argc] = NULL;
2568
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002569 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002570 if (i < 0)
2571 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00002572 envlist = PyMem_NEW(char *, i + 1);
2573 if (envlist == NULL) {
2574 PyErr_NoMemory();
2575 goto fail_1;
2576 }
2577 envc = 0;
2578 keys = PyMapping_Keys(env);
2579 vals = PyMapping_Values(env);
2580 if (!keys || !vals)
2581 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002582 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2583 PyErr_SetString(PyExc_TypeError,
2584 "spawnve(): env.keys() or env.values() is not a list");
2585 goto fail_2;
2586 }
Tim Peters5aa91602002-01-30 05:46:57 +00002587
Guido van Rossuma1065681999-01-25 23:20:23 +00002588 for (pos = 0; pos < i; pos++) {
2589 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002590 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00002591
2592 key = PyList_GetItem(keys, pos);
2593 val = PyList_GetItem(vals, pos);
2594 if (!key || !val)
2595 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002596
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002597 if (!PyArg_Parse(
2598 key,
2599 "s;spawnve() arg 3 contains a non-string key",
2600 &k) ||
2601 !PyArg_Parse(
2602 val,
2603 "s;spawnve() arg 3 contains a non-string value",
2604 &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00002605 {
2606 goto fail_2;
2607 }
Tim Petersc8996f52001-12-03 20:41:00 +00002608 len = PyString_Size(key) + PyString_Size(val) + 2;
2609 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00002610 if (p == NULL) {
2611 PyErr_NoMemory();
2612 goto fail_2;
2613 }
Tim Petersc8996f52001-12-03 20:41:00 +00002614 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00002615 envlist[envc++] = p;
2616 }
2617 envlist[envc] = 0;
2618
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002619#if defined(PYOS_OS2) && defined(PYCC_GCC)
2620 Py_BEGIN_ALLOW_THREADS
2621 spawnval = spawnve(mode, path, argvlist, envlist);
2622 Py_END_ALLOW_THREADS
2623#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002624 if (mode == _OLD_P_OVERLAY)
2625 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00002626
2627 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002628 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00002629 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002630#endif
Tim Peters25059d32001-12-07 20:35:43 +00002631
Fred Drake699f3522000-06-29 21:12:41 +00002632 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002633 (void) posix_error();
2634 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002635#if SIZEOF_LONG == SIZEOF_VOID_P
2636 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002637#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00002638 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002639#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002640
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002641 fail_2:
Guido van Rossuma1065681999-01-25 23:20:23 +00002642 while (--envc >= 0)
2643 PyMem_DEL(envlist[envc]);
2644 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002645 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002646 free_string_array(argvlist, lastarg);
Guido van Rossuma1065681999-01-25 23:20:23 +00002647 Py_XDECREF(vals);
2648 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002649 fail_0:
2650 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002651 return res;
2652}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00002653
2654/* OS/2 supports spawnvp & spawnvpe natively */
2655#if defined(PYOS_OS2)
2656PyDoc_STRVAR(posix_spawnvp__doc__,
2657"spawnvp(mode, file, args)\n\n\
2658Execute the program 'file' in a new process, using the environment\n\
2659search path to find the file.\n\
2660\n\
2661 mode: mode of process creation\n\
2662 file: executable file name\n\
2663 args: tuple or list of strings");
2664
2665static PyObject *
2666posix_spawnvp(PyObject *self, PyObject *args)
2667{
2668 char *path;
2669 PyObject *argv;
2670 char **argvlist;
2671 int mode, i, argc;
2672 Py_intptr_t spawnval;
2673 PyObject *(*getitem)(PyObject *, int);
2674
2675 /* spawnvp has three arguments: (mode, path, argv), where
2676 argv is a list or tuple of strings. */
2677
2678 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
2679 Py_FileSystemDefaultEncoding,
2680 &path, &argv))
2681 return NULL;
2682 if (PyList_Check(argv)) {
2683 argc = PyList_Size(argv);
2684 getitem = PyList_GetItem;
2685 }
2686 else if (PyTuple_Check(argv)) {
2687 argc = PyTuple_Size(argv);
2688 getitem = PyTuple_GetItem;
2689 }
2690 else {
2691 PyErr_SetString(PyExc_TypeError,
2692 "spawnvp() arg 2 must be a tuple or list");
2693 PyMem_Free(path);
2694 return NULL;
2695 }
2696
2697 argvlist = PyMem_NEW(char *, argc+1);
2698 if (argvlist == NULL) {
2699 PyMem_Free(path);
2700 return PyErr_NoMemory();
2701 }
2702 for (i = 0; i < argc; i++) {
2703 if (!PyArg_Parse((*getitem)(argv, i), "et",
2704 Py_FileSystemDefaultEncoding,
2705 &argvlist[i])) {
2706 free_string_array(argvlist, i);
2707 PyErr_SetString(
2708 PyExc_TypeError,
2709 "spawnvp() arg 2 must contain only strings");
2710 PyMem_Free(path);
2711 return NULL;
2712 }
2713 }
2714 argvlist[argc] = NULL;
2715
2716 Py_BEGIN_ALLOW_THREADS
2717#if defined(PYCC_GCC)
2718 spawnval = spawnvp(mode, path, argvlist);
2719#else
2720 spawnval = _spawnvp(mode, path, argvlist);
2721#endif
2722 Py_END_ALLOW_THREADS
2723
2724 free_string_array(argvlist, argc);
2725 PyMem_Free(path);
2726
2727 if (spawnval == -1)
2728 return posix_error();
2729 else
2730 return Py_BuildValue("l", (long) spawnval);
2731}
2732
2733
2734PyDoc_STRVAR(posix_spawnvpe__doc__,
2735"spawnvpe(mode, file, args, env)\n\n\
2736Execute the program 'file' in a new process, using the environment\n\
2737search path to find the file.\n\
2738\n\
2739 mode: mode of process creation\n\
2740 file: executable file name\n\
2741 args: tuple or list of arguments\n\
2742 env: dictionary of strings mapping to strings");
2743
2744static PyObject *
2745posix_spawnvpe(PyObject *self, PyObject *args)
2746{
2747 char *path;
2748 PyObject *argv, *env;
2749 char **argvlist;
2750 char **envlist;
2751 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
2752 int mode, i, pos, argc, envc;
2753 Py_intptr_t spawnval;
2754 PyObject *(*getitem)(PyObject *, int);
2755 int lastarg = 0;
2756
2757 /* spawnvpe has four arguments: (mode, path, argv, env), where
2758 argv is a list or tuple of strings and env is a dictionary
2759 like posix.environ. */
2760
2761 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
2762 Py_FileSystemDefaultEncoding,
2763 &path, &argv, &env))
2764 return NULL;
2765 if (PyList_Check(argv)) {
2766 argc = PyList_Size(argv);
2767 getitem = PyList_GetItem;
2768 }
2769 else if (PyTuple_Check(argv)) {
2770 argc = PyTuple_Size(argv);
2771 getitem = PyTuple_GetItem;
2772 }
2773 else {
2774 PyErr_SetString(PyExc_TypeError,
2775 "spawnvpe() arg 2 must be a tuple or list");
2776 goto fail_0;
2777 }
2778 if (!PyMapping_Check(env)) {
2779 PyErr_SetString(PyExc_TypeError,
2780 "spawnvpe() arg 3 must be a mapping object");
2781 goto fail_0;
2782 }
2783
2784 argvlist = PyMem_NEW(char *, argc+1);
2785 if (argvlist == NULL) {
2786 PyErr_NoMemory();
2787 goto fail_0;
2788 }
2789 for (i = 0; i < argc; i++) {
2790 if (!PyArg_Parse((*getitem)(argv, i),
2791 "et;spawnvpe() arg 2 must contain only strings",
2792 Py_FileSystemDefaultEncoding,
2793 &argvlist[i]))
2794 {
2795 lastarg = i;
2796 goto fail_1;
2797 }
2798 }
2799 lastarg = argc;
2800 argvlist[argc] = NULL;
2801
2802 i = PyMapping_Size(env);
2803 if (i < 0)
2804 goto fail_1;
2805 envlist = PyMem_NEW(char *, i + 1);
2806 if (envlist == NULL) {
2807 PyErr_NoMemory();
2808 goto fail_1;
2809 }
2810 envc = 0;
2811 keys = PyMapping_Keys(env);
2812 vals = PyMapping_Values(env);
2813 if (!keys || !vals)
2814 goto fail_2;
2815 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2816 PyErr_SetString(PyExc_TypeError,
2817 "spawnvpe(): env.keys() or env.values() is not a list");
2818 goto fail_2;
2819 }
2820
2821 for (pos = 0; pos < i; pos++) {
2822 char *p, *k, *v;
2823 size_t len;
2824
2825 key = PyList_GetItem(keys, pos);
2826 val = PyList_GetItem(vals, pos);
2827 if (!key || !val)
2828 goto fail_2;
2829
2830 if (!PyArg_Parse(
2831 key,
2832 "s;spawnvpe() arg 3 contains a non-string key",
2833 &k) ||
2834 !PyArg_Parse(
2835 val,
2836 "s;spawnvpe() arg 3 contains a non-string value",
2837 &v))
2838 {
2839 goto fail_2;
2840 }
2841 len = PyString_Size(key) + PyString_Size(val) + 2;
2842 p = PyMem_NEW(char, len);
2843 if (p == NULL) {
2844 PyErr_NoMemory();
2845 goto fail_2;
2846 }
2847 PyOS_snprintf(p, len, "%s=%s", k, v);
2848 envlist[envc++] = p;
2849 }
2850 envlist[envc] = 0;
2851
2852 Py_BEGIN_ALLOW_THREADS
2853#if defined(PYCC_GCC)
2854 spawnval = spawnve(mode, path, argvlist, envlist);
2855#else
2856 spawnval = _spawnve(mode, path, argvlist, envlist);
2857#endif
2858 Py_END_ALLOW_THREADS
2859
2860 if (spawnval == -1)
2861 (void) posix_error();
2862 else
2863 res = Py_BuildValue("l", (long) spawnval);
2864
2865 fail_2:
2866 while (--envc >= 0)
2867 PyMem_DEL(envlist[envc]);
2868 PyMem_DEL(envlist);
2869 fail_1:
2870 free_string_array(argvlist, lastarg);
2871 Py_XDECREF(vals);
2872 Py_XDECREF(keys);
2873 fail_0:
2874 PyMem_Free(path);
2875 return res;
2876}
2877#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00002878#endif /* HAVE_SPAWNV */
2879
2880
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002881#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002882PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002883"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002884Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
2885\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002886Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002887
2888static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002889posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002890{
Neal Norwitze241ce82003-02-17 18:17:05 +00002891 int pid = fork1();
Guido van Rossum2242f2f2001-04-11 20:58:20 +00002892 if (pid == -1)
2893 return posix_error();
2894 PyOS_AfterFork();
2895 return PyInt_FromLong((long)pid);
2896}
2897#endif
2898
2899
Guido van Rossumad0ee831995-03-01 10:34:45 +00002900#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002901PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002902"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002903Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002904Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002905
Barry Warsaw53699e91996-12-10 23:23:01 +00002906static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002907posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002908{
Neal Norwitze241ce82003-02-17 18:17:05 +00002909 int pid = fork();
Guido van Rossum85e3b011991-06-03 12:42:10 +00002910 if (pid == -1)
2911 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00002912 if (pid == 0)
2913 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00002914 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002915}
Guido van Rossumad0ee831995-03-01 10:34:45 +00002916#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00002917
Neal Norwitzb59798b2003-03-21 01:43:31 +00002918/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00002919/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
2920#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00002921#define DEV_PTY_FILE "/dev/ptc"
2922#define HAVE_DEV_PTMX
2923#else
2924#define DEV_PTY_FILE "/dev/ptmx"
2925#endif
2926
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002927#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002928#ifdef HAVE_PTY_H
2929#include <pty.h>
2930#else
2931#ifdef HAVE_LIBUTIL_H
2932#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00002933#endif /* HAVE_LIBUTIL_H */
2934#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00002935#ifdef HAVE_STROPTS_H
2936#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002937#endif
2938#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00002939
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002940#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002941PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002942"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002943Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00002944
2945static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002946posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00002947{
2948 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00002949#ifndef HAVE_OPENPTY
2950 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00002951#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002952#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00002953 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002954#ifdef sun
2955 extern char *ptsname();
2956#endif
2957#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00002958
Thomas Wouters70c21a12000-07-14 14:28:33 +00002959#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00002960 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
2961 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00002962#elif defined(HAVE__GETPTY)
Thomas Wouters70c21a12000-07-14 14:28:33 +00002963 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
2964 if (slave_name == NULL)
2965 return posix_error();
2966
2967 slave_fd = open(slave_name, O_RDWR);
2968 if (slave_fd < 0)
2969 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002970#else
Neal Norwitzb59798b2003-03-21 01:43:31 +00002971 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002972 if (master_fd < 0)
2973 return posix_error();
Anthony Baxter9ceaa722004-10-13 14:48:50 +00002974 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00002975 /* change permission of slave */
2976 if (grantpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00002977 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002978 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00002979 }
2980 /* unlock slave */
2981 if (unlockpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00002982 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002983 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00002984 }
Anthony Baxter9ceaa722004-10-13 14:48:50 +00002985 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002986 slave_name = ptsname(master_fd); /* get name of slave */
2987 if (slave_name == NULL)
2988 return posix_error();
2989 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
2990 if (slave_fd < 0)
2991 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00002992#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002993 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
2994 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00002995#ifndef __hpux
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002996 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00002997#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00002998#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00002999#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00003000
Fred Drake8cef4cf2000-06-28 16:40:38 +00003001 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00003002
Fred Drake8cef4cf2000-06-28 16:40:38 +00003003}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003004#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003005
3006#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003007PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003008"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00003009Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
3010Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003011To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003012
3013static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003014posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003015{
Neal Norwitz24b3c222005-09-19 06:43:44 +00003016 int master_fd = -1, pid;
Tim Peters5aa91602002-01-30 05:46:57 +00003017
Fred Drake8cef4cf2000-06-28 16:40:38 +00003018 pid = forkpty(&master_fd, NULL, NULL, NULL);
3019 if (pid == -1)
3020 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003021 if (pid == 0)
3022 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00003023 return Py_BuildValue("(ii)", pid, master_fd);
3024}
3025#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003026
Guido van Rossumad0ee831995-03-01 10:34:45 +00003027#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003028PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003029"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003030Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003031
Barry Warsaw53699e91996-12-10 23:23:01 +00003032static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003033posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003034{
Barry Warsaw53699e91996-12-10 23:23:01 +00003035 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003036}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003037#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003038
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003039
Guido van Rossumad0ee831995-03-01 10:34:45 +00003040#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003041PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003042"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003043Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003044
Barry Warsaw53699e91996-12-10 23:23:01 +00003045static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003046posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003047{
Barry Warsaw53699e91996-12-10 23:23:01 +00003048 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003049}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003050#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003051
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003052
Guido van Rossumad0ee831995-03-01 10:34:45 +00003053#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003054PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003055"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003056Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003057
Barry Warsaw53699e91996-12-10 23:23:01 +00003058static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003059posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003060{
Barry Warsaw53699e91996-12-10 23:23:01 +00003061 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003062}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003063#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003064
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003065
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003066PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003067"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003068Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003069
Barry Warsaw53699e91996-12-10 23:23:01 +00003070static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003071posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003072{
Barry Warsaw53699e91996-12-10 23:23:01 +00003073 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003074}
3075
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003076
Fred Drakec9680921999-12-13 16:37:25 +00003077#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003078PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003079"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003080Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00003081
3082static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003083posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00003084{
3085 PyObject *result = NULL;
3086
Fred Drakec9680921999-12-13 16:37:25 +00003087#ifdef NGROUPS_MAX
3088#define MAX_GROUPS NGROUPS_MAX
3089#else
3090 /* defined to be 16 on Solaris7, so this should be a small number */
3091#define MAX_GROUPS 64
3092#endif
3093 gid_t grouplist[MAX_GROUPS];
3094 int n;
3095
3096 n = getgroups(MAX_GROUPS, grouplist);
3097 if (n < 0)
3098 posix_error();
3099 else {
3100 result = PyList_New(n);
3101 if (result != NULL) {
Fred Drakec9680921999-12-13 16:37:25 +00003102 int i;
3103 for (i = 0; i < n; ++i) {
Neal Norwitze241ce82003-02-17 18:17:05 +00003104 PyObject *o = PyInt_FromLong((long)grouplist[i]);
Fred Drakec9680921999-12-13 16:37:25 +00003105 if (o == NULL) {
3106 Py_DECREF(result);
3107 result = NULL;
3108 break;
3109 }
3110 PyList_SET_ITEM(result, i, o);
3111 }
3112 }
3113 }
Neal Norwitze241ce82003-02-17 18:17:05 +00003114
Fred Drakec9680921999-12-13 16:37:25 +00003115 return result;
3116}
3117#endif
3118
Martin v. Löwis606edc12002-06-13 21:09:11 +00003119#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003120PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003121"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003122Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00003123
3124static PyObject *
3125posix_getpgid(PyObject *self, PyObject *args)
3126{
3127 int pid, pgid;
3128 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
3129 return NULL;
3130 pgid = getpgid(pid);
3131 if (pgid < 0)
3132 return posix_error();
3133 return PyInt_FromLong((long)pgid);
3134}
3135#endif /* HAVE_GETPGID */
3136
3137
Guido van Rossumb6775db1994-08-01 11:34:53 +00003138#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003139PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003140"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003141Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003142
Barry Warsaw53699e91996-12-10 23:23:01 +00003143static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003144posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00003145{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003146#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00003147 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003148#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00003149 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003150#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00003151}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003152#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00003153
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003154
Guido van Rossumb6775db1994-08-01 11:34:53 +00003155#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003156PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003157"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003158Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003159
Barry Warsaw53699e91996-12-10 23:23:01 +00003160static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003161posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003162{
Guido van Rossum64933891994-10-20 21:56:42 +00003163#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00003164 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003165#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003166 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003167#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00003168 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003169 Py_INCREF(Py_None);
3170 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003171}
3172
Guido van Rossumb6775db1994-08-01 11:34:53 +00003173#endif /* HAVE_SETPGRP */
3174
Guido van Rossumad0ee831995-03-01 10:34:45 +00003175#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003176PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003177"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003178Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003179
Barry Warsaw53699e91996-12-10 23:23:01 +00003180static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003181posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003182{
Barry Warsaw53699e91996-12-10 23:23:01 +00003183 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003184}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003185#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003186
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003187
Fred Drake12c6e2d1999-12-14 21:25:03 +00003188#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003189PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003190"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003191Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00003192
3193static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003194posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00003195{
Neal Norwitze241ce82003-02-17 18:17:05 +00003196 PyObject *result = NULL;
Fred Drakea30680b2000-12-06 21:24:28 +00003197 char *name;
3198 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00003199
Fred Drakea30680b2000-12-06 21:24:28 +00003200 errno = 0;
3201 name = getlogin();
3202 if (name == NULL) {
3203 if (errno)
3204 posix_error();
3205 else
3206 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00003207 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00003208 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00003209 else
3210 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00003211 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00003212
Fred Drake12c6e2d1999-12-14 21:25:03 +00003213 return result;
3214}
3215#endif
3216
Guido van Rossumad0ee831995-03-01 10:34:45 +00003217#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003218PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003219"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003220Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003221
Barry Warsaw53699e91996-12-10 23:23:01 +00003222static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003223posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003224{
Barry Warsaw53699e91996-12-10 23:23:01 +00003225 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003226}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003227#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003228
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003229
Guido van Rossumad0ee831995-03-01 10:34:45 +00003230#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003231PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003232"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003233Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003234
Barry Warsaw53699e91996-12-10 23:23:01 +00003235static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003236posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003237{
3238 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003239 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00003240 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003241#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003242 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
3243 APIRET rc;
3244 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003245 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003246
3247 } else if (sig == XCPT_SIGNAL_KILLPROC) {
3248 APIRET rc;
3249 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003250 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003251
3252 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003253 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003254#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00003255 if (kill(pid, sig) == -1)
3256 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003257#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003258 Py_INCREF(Py_None);
3259 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003260}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003261#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003262
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003263#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003264PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003265"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003266Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003267
3268static PyObject *
3269posix_killpg(PyObject *self, PyObject *args)
3270{
3271 int pgid, sig;
3272 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
3273 return NULL;
3274 if (killpg(pgid, sig) == -1)
3275 return posix_error();
3276 Py_INCREF(Py_None);
3277 return Py_None;
3278}
3279#endif
3280
Guido van Rossumc0125471996-06-28 18:55:32 +00003281#ifdef HAVE_PLOCK
3282
3283#ifdef HAVE_SYS_LOCK_H
3284#include <sys/lock.h>
3285#endif
3286
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003287PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003288"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003289Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003290
Barry Warsaw53699e91996-12-10 23:23:01 +00003291static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003292posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00003293{
3294 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003295 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00003296 return NULL;
3297 if (plock(op) == -1)
3298 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003299 Py_INCREF(Py_None);
3300 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00003301}
3302#endif
3303
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003304
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003305#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003306PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003307"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003308Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003309
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003310#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003311#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003312static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003313async_system(const char *command)
3314{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003315 char errormsg[256], args[1024];
3316 RESULTCODES rcodes;
3317 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003318
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003319 char *shell = getenv("COMSPEC");
3320 if (!shell)
3321 shell = "cmd";
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003322
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003323 /* avoid overflowing the argument buffer */
3324 if (strlen(shell) + 3 + strlen(command) >= 1024)
3325 return ERROR_NOT_ENOUGH_MEMORY
3326
3327 args[0] = '\0';
3328 strcat(args, shell);
3329 strcat(args, "/c ");
3330 strcat(args, command);
3331
3332 /* execute asynchronously, inheriting the environment */
3333 rc = DosExecPgm(errormsg,
3334 sizeof(errormsg),
3335 EXEC_ASYNC,
3336 args,
3337 NULL,
3338 &rcodes,
3339 shell);
3340 return rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003341}
3342
Guido van Rossumd48f2521997-12-05 22:19:34 +00003343static FILE *
3344popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003345{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003346 int oldfd, tgtfd;
3347 HFILE pipeh[2];
3348 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003349
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003350 /* mode determines which of stdin or stdout is reconnected to
3351 * the pipe to the child
3352 */
3353 if (strchr(mode, 'r') != NULL) {
3354 tgt_fd = 1; /* stdout */
3355 } else if (strchr(mode, 'w')) {
3356 tgt_fd = 0; /* stdin */
3357 } else {
3358 *err = ERROR_INVALID_ACCESS;
3359 return NULL;
3360 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003361
Andrew MacIntyrea3be2582004-12-18 09:51:05 +00003362 /* setup the pipe */
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003363 if ((rc = DosCreatePipe(&pipeh[0], &pipeh[1], pipesize)) != NO_ERROR) {
3364 *err = rc;
3365 return NULL;
3366 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003367
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003368 /* prevent other threads accessing stdio */
3369 DosEnterCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003370
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003371 /* reconnect stdio and execute child */
3372 oldfd = dup(tgtfd);
3373 close(tgtfd);
3374 if (dup2(pipeh[tgtfd], tgtfd) == 0) {
3375 DosClose(pipeh[tgtfd]);
3376 rc = async_system(command);
3377 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003378
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003379 /* restore stdio */
3380 dup2(oldfd, tgtfd);
3381 close(oldfd);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003382
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003383 /* allow other threads access to stdio */
3384 DosExitCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003385
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003386 /* if execution of child was successful return file stream */
3387 if (rc == NO_ERROR)
3388 return fdopen(pipeh[1 - tgtfd], mode);
3389 else {
3390 DosClose(pipeh[1 - tgtfd]);
3391 *err = rc;
3392 return NULL;
3393 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003394}
3395
3396static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003397posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003398{
3399 char *name;
3400 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00003401 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003402 FILE *fp;
3403 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003404 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003405 return NULL;
3406 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00003407 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003408 Py_END_ALLOW_THREADS
3409 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003410 return os2_error(err);
3411
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003412 f = PyFile_FromFile(fp, name, mode, fclose);
3413 if (f != NULL)
3414 PyFile_SetBufSize(f, bufsize);
3415 return f;
3416}
3417
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003418#elif defined(PYCC_GCC)
3419
3420/* standard posix version of popen() support */
3421static PyObject *
3422posix_popen(PyObject *self, PyObject *args)
3423{
3424 char *name;
3425 char *mode = "r";
3426 int bufsize = -1;
3427 FILE *fp;
3428 PyObject *f;
3429 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
3430 return NULL;
3431 Py_BEGIN_ALLOW_THREADS
3432 fp = popen(name, mode);
3433 Py_END_ALLOW_THREADS
3434 if (fp == NULL)
3435 return posix_error();
3436 f = PyFile_FromFile(fp, name, mode, pclose);
3437 if (f != NULL)
3438 PyFile_SetBufSize(f, bufsize);
3439 return f;
3440}
3441
3442/* fork() under OS/2 has lots'o'warts
3443 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
3444 * most of this code is a ripoff of the win32 code, but using the
3445 * capabilities of EMX's C library routines
3446 */
3447
3448/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
3449#define POPEN_1 1
3450#define POPEN_2 2
3451#define POPEN_3 3
3452#define POPEN_4 4
3453
3454static PyObject *_PyPopen(char *, int, int, int);
3455static int _PyPclose(FILE *file);
3456
3457/*
3458 * Internal dictionary mapping popen* file pointers to process handles,
3459 * for use when retrieving the process exit code. See _PyPclose() below
3460 * for more information on this dictionary's use.
3461 */
3462static PyObject *_PyPopenProcs = NULL;
3463
3464/* os2emx version of popen2()
3465 *
3466 * The result of this function is a pipe (file) connected to the
3467 * process's stdin, and a pipe connected to the process's stdout.
3468 */
3469
3470static PyObject *
3471os2emx_popen2(PyObject *self, PyObject *args)
3472{
3473 PyObject *f;
3474 int tm=0;
3475
3476 char *cmdstring;
3477 char *mode = "t";
3478 int bufsize = -1;
3479 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
3480 return NULL;
3481
3482 if (*mode == 't')
3483 tm = O_TEXT;
3484 else if (*mode != 'b') {
3485 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3486 return NULL;
3487 } else
3488 tm = O_BINARY;
3489
3490 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
3491
3492 return f;
3493}
3494
3495/*
3496 * Variation on os2emx.popen2
3497 *
3498 * The result of this function is 3 pipes - the process's stdin,
3499 * stdout and stderr
3500 */
3501
3502static PyObject *
3503os2emx_popen3(PyObject *self, PyObject *args)
3504{
3505 PyObject *f;
3506 int tm = 0;
3507
3508 char *cmdstring;
3509 char *mode = "t";
3510 int bufsize = -1;
3511 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
3512 return NULL;
3513
3514 if (*mode == 't')
3515 tm = O_TEXT;
3516 else if (*mode != 'b') {
3517 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3518 return NULL;
3519 } else
3520 tm = O_BINARY;
3521
3522 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
3523
3524 return f;
3525}
3526
3527/*
3528 * Variation on os2emx.popen2
3529 *
Tim Peters11b23062003-04-23 02:39:17 +00003530 * The result of this function is 2 pipes - the processes stdin,
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003531 * and stdout+stderr combined as a single pipe.
3532 */
3533
3534static PyObject *
3535os2emx_popen4(PyObject *self, PyObject *args)
3536{
3537 PyObject *f;
3538 int tm = 0;
3539
3540 char *cmdstring;
3541 char *mode = "t";
3542 int bufsize = -1;
3543 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
3544 return NULL;
3545
3546 if (*mode == 't')
3547 tm = O_TEXT;
3548 else if (*mode != 'b') {
3549 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3550 return NULL;
3551 } else
3552 tm = O_BINARY;
3553
3554 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
3555
3556 return f;
3557}
3558
3559/* a couple of structures for convenient handling of multiple
3560 * file handles and pipes
3561 */
3562struct file_ref
3563{
3564 int handle;
3565 int flags;
3566};
3567
3568struct pipe_ref
3569{
3570 int rd;
3571 int wr;
3572};
3573
3574/* The following code is derived from the win32 code */
3575
3576static PyObject *
3577_PyPopen(char *cmdstring, int mode, int n, int bufsize)
3578{
3579 struct file_ref stdio[3];
3580 struct pipe_ref p_fd[3];
3581 FILE *p_s[3];
3582 int file_count, i, pipe_err, pipe_pid;
3583 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
3584 PyObject *f, *p_f[3];
3585
3586 /* file modes for subsequent fdopen's on pipe handles */
3587 if (mode == O_TEXT)
3588 {
3589 rd_mode = "rt";
3590 wr_mode = "wt";
3591 }
3592 else
3593 {
3594 rd_mode = "rb";
3595 wr_mode = "wb";
3596 }
3597
3598 /* prepare shell references */
3599 if ((shell = getenv("EMXSHELL")) == NULL)
3600 if ((shell = getenv("COMSPEC")) == NULL)
3601 {
3602 errno = ENOENT;
3603 return posix_error();
3604 }
3605
3606 sh_name = _getname(shell);
3607 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
3608 opt = "/c";
3609 else
3610 opt = "-c";
3611
3612 /* save current stdio fds + their flags, and set not inheritable */
3613 i = pipe_err = 0;
3614 while (pipe_err >= 0 && i < 3)
3615 {
3616 pipe_err = stdio[i].handle = dup(i);
3617 stdio[i].flags = fcntl(i, F_GETFD, 0);
3618 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
3619 i++;
3620 }
3621 if (pipe_err < 0)
3622 {
3623 /* didn't get them all saved - clean up and bail out */
3624 int saved_err = errno;
3625 while (i-- > 0)
3626 {
3627 close(stdio[i].handle);
3628 }
3629 errno = saved_err;
3630 return posix_error();
3631 }
3632
3633 /* create pipe ends */
3634 file_count = 2;
3635 if (n == POPEN_3)
3636 file_count = 3;
3637 i = pipe_err = 0;
3638 while ((pipe_err == 0) && (i < file_count))
3639 pipe_err = pipe((int *)&p_fd[i++]);
3640 if (pipe_err < 0)
3641 {
3642 /* didn't get them all made - clean up and bail out */
3643 while (i-- > 0)
3644 {
3645 close(p_fd[i].wr);
3646 close(p_fd[i].rd);
3647 }
3648 errno = EPIPE;
3649 return posix_error();
3650 }
3651
3652 /* change the actual standard IO streams over temporarily,
3653 * making the retained pipe ends non-inheritable
3654 */
3655 pipe_err = 0;
3656
3657 /* - stdin */
3658 if (dup2(p_fd[0].rd, 0) == 0)
3659 {
3660 close(p_fd[0].rd);
3661 i = fcntl(p_fd[0].wr, F_GETFD, 0);
3662 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
3663 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
3664 {
3665 close(p_fd[0].wr);
3666 pipe_err = -1;
3667 }
3668 }
3669 else
3670 {
3671 pipe_err = -1;
3672 }
3673
3674 /* - stdout */
3675 if (pipe_err == 0)
3676 {
3677 if (dup2(p_fd[1].wr, 1) == 1)
3678 {
3679 close(p_fd[1].wr);
3680 i = fcntl(p_fd[1].rd, F_GETFD, 0);
3681 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
3682 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
3683 {
3684 close(p_fd[1].rd);
3685 pipe_err = -1;
3686 }
3687 }
3688 else
3689 {
3690 pipe_err = -1;
3691 }
3692 }
3693
3694 /* - stderr, as required */
3695 if (pipe_err == 0)
3696 switch (n)
3697 {
3698 case POPEN_3:
3699 {
3700 if (dup2(p_fd[2].wr, 2) == 2)
3701 {
3702 close(p_fd[2].wr);
3703 i = fcntl(p_fd[2].rd, F_GETFD, 0);
3704 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
3705 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
3706 {
3707 close(p_fd[2].rd);
3708 pipe_err = -1;
3709 }
3710 }
3711 else
3712 {
3713 pipe_err = -1;
3714 }
3715 break;
3716 }
3717
3718 case POPEN_4:
3719 {
3720 if (dup2(1, 2) != 2)
3721 {
3722 pipe_err = -1;
3723 }
3724 break;
3725 }
3726 }
3727
3728 /* spawn the child process */
3729 if (pipe_err == 0)
3730 {
3731 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
3732 if (pipe_pid == -1)
3733 {
3734 pipe_err = -1;
3735 }
3736 else
3737 {
3738 /* save the PID into the FILE structure
3739 * NOTE: this implementation doesn't actually
3740 * take advantage of this, but do it for
3741 * completeness - AIM Apr01
3742 */
3743 for (i = 0; i < file_count; i++)
3744 p_s[i]->_pid = pipe_pid;
3745 }
3746 }
3747
3748 /* reset standard IO to normal */
3749 for (i = 0; i < 3; i++)
3750 {
3751 dup2(stdio[i].handle, i);
3752 fcntl(i, F_SETFD, stdio[i].flags);
3753 close(stdio[i].handle);
3754 }
3755
3756 /* if any remnant problems, clean up and bail out */
3757 if (pipe_err < 0)
3758 {
3759 for (i = 0; i < 3; i++)
3760 {
3761 close(p_fd[i].rd);
3762 close(p_fd[i].wr);
3763 }
3764 errno = EPIPE;
3765 return posix_error_with_filename(cmdstring);
3766 }
3767
3768 /* build tuple of file objects to return */
3769 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
3770 PyFile_SetBufSize(p_f[0], bufsize);
3771 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
3772 PyFile_SetBufSize(p_f[1], bufsize);
3773 if (n == POPEN_3)
3774 {
3775 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
3776 PyFile_SetBufSize(p_f[0], bufsize);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00003777 f = PyTuple_Pack(3, p_f[0], p_f[1], p_f[2]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003778 }
3779 else
Raymond Hettinger8ae46892003-10-12 19:09:37 +00003780 f = PyTuple_Pack(2, p_f[0], p_f[1]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003781
3782 /*
3783 * Insert the files we've created into the process dictionary
3784 * all referencing the list with the process handle and the
3785 * initial number of files (see description below in _PyPclose).
3786 * Since if _PyPclose later tried to wait on a process when all
3787 * handles weren't closed, it could create a deadlock with the
3788 * child, we spend some energy here to try to ensure that we
3789 * either insert all file handles into the dictionary or none
3790 * at all. It's a little clumsy with the various popen modes
3791 * and variable number of files involved.
3792 */
3793 if (!_PyPopenProcs)
3794 {
3795 _PyPopenProcs = PyDict_New();
3796 }
3797
3798 if (_PyPopenProcs)
3799 {
3800 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
3801 int ins_rc[3];
3802
3803 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
3804 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
3805
3806 procObj = PyList_New(2);
3807 pidObj = PyInt_FromLong((long) pipe_pid);
3808 intObj = PyInt_FromLong((long) file_count);
3809
3810 if (procObj && pidObj && intObj)
3811 {
3812 PyList_SetItem(procObj, 0, pidObj);
3813 PyList_SetItem(procObj, 1, intObj);
3814
3815 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
3816 if (fileObj[0])
3817 {
3818 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
3819 fileObj[0],
3820 procObj);
3821 }
3822 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
3823 if (fileObj[1])
3824 {
3825 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
3826 fileObj[1],
3827 procObj);
3828 }
3829 if (file_count >= 3)
3830 {
3831 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
3832 if (fileObj[2])
3833 {
3834 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
3835 fileObj[2],
3836 procObj);
3837 }
3838 }
3839
3840 if (ins_rc[0] < 0 || !fileObj[0] ||
3841 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
3842 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
3843 {
3844 /* Something failed - remove any dictionary
3845 * entries that did make it.
3846 */
3847 if (!ins_rc[0] && fileObj[0])
3848 {
3849 PyDict_DelItem(_PyPopenProcs,
3850 fileObj[0]);
3851 }
3852 if (!ins_rc[1] && fileObj[1])
3853 {
3854 PyDict_DelItem(_PyPopenProcs,
3855 fileObj[1]);
3856 }
3857 if (!ins_rc[2] && fileObj[2])
3858 {
3859 PyDict_DelItem(_PyPopenProcs,
3860 fileObj[2]);
3861 }
3862 }
3863 }
Tim Peters11b23062003-04-23 02:39:17 +00003864
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003865 /*
3866 * Clean up our localized references for the dictionary keys
3867 * and value since PyDict_SetItem will Py_INCREF any copies
3868 * that got placed in the dictionary.
3869 */
3870 Py_XDECREF(procObj);
3871 Py_XDECREF(fileObj[0]);
3872 Py_XDECREF(fileObj[1]);
3873 Py_XDECREF(fileObj[2]);
3874 }
3875
3876 /* Child is launched. */
3877 return f;
3878}
3879
3880/*
3881 * Wrapper for fclose() to use for popen* files, so we can retrieve the
3882 * exit code for the child process and return as a result of the close.
3883 *
3884 * This function uses the _PyPopenProcs dictionary in order to map the
3885 * input file pointer to information about the process that was
3886 * originally created by the popen* call that created the file pointer.
3887 * The dictionary uses the file pointer as a key (with one entry
3888 * inserted for each file returned by the original popen* call) and a
3889 * single list object as the value for all files from a single call.
3890 * The list object contains the Win32 process handle at [0], and a file
3891 * count at [1], which is initialized to the total number of file
3892 * handles using that list.
3893 *
3894 * This function closes whichever handle it is passed, and decrements
3895 * the file count in the dictionary for the process handle pointed to
3896 * by this file. On the last close (when the file count reaches zero),
3897 * this function will wait for the child process and then return its
3898 * exit code as the result of the close() operation. This permits the
3899 * files to be closed in any order - it is always the close() of the
3900 * final handle that will return the exit code.
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00003901 *
3902 * NOTE: This function is currently called with the GIL released.
3903 * hence we use the GILState API to manage our state.
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003904 */
3905
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003906static int _PyPclose(FILE *file)
3907{
3908 int result;
3909 int exit_code;
3910 int pipe_pid;
3911 PyObject *procObj, *pidObj, *intObj, *fileObj;
3912 int file_count;
3913#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00003914 PyGILState_STATE state;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003915#endif
3916
3917 /* Close the file handle first, to ensure it can't block the
3918 * child from exiting if it's the last handle.
3919 */
3920 result = fclose(file);
3921
3922#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00003923 state = PyGILState_Ensure();
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003924#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003925 if (_PyPopenProcs)
3926 {
3927 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
3928 (procObj = PyDict_GetItem(_PyPopenProcs,
3929 fileObj)) != NULL &&
3930 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
3931 (intObj = PyList_GetItem(procObj,1)) != NULL)
3932 {
3933 pipe_pid = (int) PyInt_AsLong(pidObj);
3934 file_count = (int) PyInt_AsLong(intObj);
3935
3936 if (file_count > 1)
3937 {
3938 /* Still other files referencing process */
3939 file_count--;
3940 PyList_SetItem(procObj,1,
3941 PyInt_FromLong((long) file_count));
3942 }
3943 else
3944 {
3945 /* Last file for this process */
3946 if (result != EOF &&
3947 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
3948 {
3949 /* extract exit status */
3950 if (WIFEXITED(exit_code))
3951 {
3952 result = WEXITSTATUS(exit_code);
3953 }
3954 else
3955 {
3956 errno = EPIPE;
3957 result = -1;
3958 }
3959 }
3960 else
3961 {
3962 /* Indicate failure - this will cause the file object
3963 * to raise an I/O error and translate the last
3964 * error code from errno. We do have a problem with
3965 * last errors that overlap the normal errno table,
3966 * but that's a consistent problem with the file object.
3967 */
3968 result = -1;
3969 }
3970 }
3971
3972 /* Remove this file pointer from dictionary */
3973 PyDict_DelItem(_PyPopenProcs, fileObj);
3974
3975 if (PyDict_Size(_PyPopenProcs) == 0)
3976 {
3977 Py_DECREF(_PyPopenProcs);
3978 _PyPopenProcs = NULL;
3979 }
3980
3981 } /* if object retrieval ok */
3982
3983 Py_XDECREF(fileObj);
3984 } /* if _PyPopenProcs */
3985
3986#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00003987 PyGILState_Release(state);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003988#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003989 return result;
3990}
3991
3992#endif /* PYCC_??? */
3993
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003994#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00003995
3996/*
3997 * Portable 'popen' replacement for Win32.
3998 *
3999 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
4000 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00004001 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004002 */
4003
4004#include <malloc.h>
4005#include <io.h>
4006#include <fcntl.h>
4007
4008/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
4009#define POPEN_1 1
4010#define POPEN_2 2
4011#define POPEN_3 3
4012#define POPEN_4 4
4013
4014static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004015static int _PyPclose(FILE *file);
4016
4017/*
4018 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00004019 * for use when retrieving the process exit code. See _PyPclose() below
4020 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004021 */
4022static PyObject *_PyPopenProcs = NULL;
4023
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004024
4025/* popen that works from a GUI.
4026 *
4027 * The result of this function is a pipe (file) connected to the
4028 * processes stdin or stdout, depending on the requested mode.
4029 */
4030
4031static PyObject *
4032posix_popen(PyObject *self, PyObject *args)
4033{
Raymond Hettingerb5cb6652003-09-01 22:25:41 +00004034 PyObject *f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004035 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004036
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004037 char *cmdstring;
4038 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004039 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004040 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004041 return NULL;
4042
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004043 if (*mode == 'r')
4044 tm = _O_RDONLY;
4045 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00004046 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004047 return NULL;
4048 } else
4049 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00004050
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004051 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004052 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004053 return NULL;
4054 }
4055
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004056 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004057 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004058 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004059 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004060 else
4061 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
4062
4063 return f;
4064}
4065
4066/* Variation on win32pipe.popen
4067 *
4068 * The result of this function is a pipe (file) connected to the
4069 * process's stdin, and a pipe connected to the process's stdout.
4070 */
4071
4072static PyObject *
4073win32_popen2(PyObject *self, PyObject *args)
4074{
4075 PyObject *f;
4076 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00004077
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004078 char *cmdstring;
4079 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004080 int bufsize = -1;
4081 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004082 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004083
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004084 if (*mode == 't')
4085 tm = _O_TEXT;
4086 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004087 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004088 return NULL;
4089 } else
4090 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004091
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004092 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004093 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004094 return NULL;
4095 }
4096
4097 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00004098
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004099 return f;
4100}
4101
4102/*
4103 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004104 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004105 * The result of this function is 3 pipes - the process's stdin,
4106 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004107 */
4108
4109static PyObject *
4110win32_popen3(PyObject *self, PyObject *args)
4111{
4112 PyObject *f;
4113 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004114
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004115 char *cmdstring;
4116 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004117 int bufsize = -1;
4118 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004119 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004120
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004121 if (*mode == 't')
4122 tm = _O_TEXT;
4123 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004124 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004125 return NULL;
4126 } else
4127 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004128
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004129 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004130 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004131 return NULL;
4132 }
4133
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004134 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00004135
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004136 return f;
4137}
4138
4139/*
4140 * Variation on win32pipe.popen
4141 *
Tim Peters5aa91602002-01-30 05:46:57 +00004142 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004143 * and stdout+stderr combined as a single pipe.
4144 */
4145
4146static PyObject *
4147win32_popen4(PyObject *self, PyObject *args)
4148{
4149 PyObject *f;
4150 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004151
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004152 char *cmdstring;
4153 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004154 int bufsize = -1;
4155 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004156 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004157
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004158 if (*mode == 't')
4159 tm = _O_TEXT;
4160 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004161 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004162 return NULL;
4163 } else
4164 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004165
4166 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004167 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004168 return NULL;
4169 }
4170
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004171 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004172
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004173 return f;
4174}
4175
Mark Hammond08501372001-01-31 07:30:29 +00004176static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00004177_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004178 HANDLE hStdin,
4179 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00004180 HANDLE hStderr,
4181 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004182{
4183 PROCESS_INFORMATION piProcInfo;
4184 STARTUPINFO siStartInfo;
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004185 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004186 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00004187 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004188 int i;
4189 int x;
4190
4191 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00004192 char *comshell;
4193
Tim Peters92e4dd82002-10-05 01:47:34 +00004194 s1 = (char *)alloca(i);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004195 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
4196 return x;
Tim Peters402d5982001-08-27 06:37:48 +00004197
4198 /* Explicitly check if we are using COMMAND.COM. If we are
4199 * then use the w9xpopen hack.
4200 */
4201 comshell = s1 + x;
4202 while (comshell >= s1 && *comshell != '\\')
4203 --comshell;
4204 ++comshell;
4205
4206 if (GetVersion() < 0x80000000 &&
4207 _stricmp(comshell, "command.com") != 0) {
4208 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004209 x = i + strlen(s3) + strlen(cmdstring) + 1;
Tim Peters92e4dd82002-10-05 01:47:34 +00004210 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004211 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00004212 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004213 }
4214 else {
4215 /*
Tim Peters402d5982001-08-27 06:37:48 +00004216 * Oh gag, we're on Win9x or using COMMAND.COM. Use
4217 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004218 */
Mark Hammond08501372001-01-31 07:30:29 +00004219 char modulepath[_MAX_PATH];
4220 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004221 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
4222 for (i = x = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004223 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004224 x = i+1;
4225 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00004226 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00004227 strncat(modulepath,
4228 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00004229 (sizeof(modulepath)/sizeof(modulepath[0]))
4230 -strlen(modulepath));
4231 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00004232 /* Eeek - file-not-found - possibly an embedding
4233 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00004234 */
Tim Peters5aa91602002-01-30 05:46:57 +00004235 strncpy(modulepath,
4236 Py_GetExecPrefix(),
Mark Hammond08501372001-01-31 07:30:29 +00004237 sizeof(modulepath)/sizeof(modulepath[0]));
4238 if (modulepath[strlen(modulepath)-1] != '\\')
4239 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00004240 strncat(modulepath,
4241 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00004242 (sizeof(modulepath)/sizeof(modulepath[0]))
4243 -strlen(modulepath));
4244 /* No where else to look - raise an easily identifiable
4245 error, rather than leaving Windows to report
4246 "file not found" - as the user is probably blissfully
4247 unaware this shim EXE is used, and it will confuse them.
4248 (well, it confused me for a while ;-)
4249 */
4250 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00004251 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00004252 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00004253 "for popen to work with your shell "
4254 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00004255 szConsoleSpawn);
4256 return FALSE;
4257 }
4258 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004259 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00004260 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004261 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00004262
Tim Peters92e4dd82002-10-05 01:47:34 +00004263 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004264 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004265 /* To maintain correct argument passing semantics,
4266 we pass the command-line as it stands, and allow
4267 quoting to be applied. w9xpopen.exe will then
4268 use its argv vector, and re-quote the necessary
4269 args for the ultimate child process.
4270 */
Tim Peters75cdad52001-11-28 22:07:30 +00004271 PyOS_snprintf(
4272 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004273 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004274 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004275 s1,
4276 s3,
4277 cmdstring);
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004278 /* Not passing CREATE_NEW_CONSOLE has been known to
Tim Peters11b23062003-04-23 02:39:17 +00004279 cause random failures on win9x. Specifically a
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004280 dialog:
4281 "Your program accessed mem currently in use at xxx"
4282 and a hopeful warning about the stability of your
4283 system.
4284 Cost is Ctrl+C wont kill children, but anyone
4285 who cares can have a go!
4286 */
4287 dwProcessFlags |= CREATE_NEW_CONSOLE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004288 }
4289 }
4290
4291 /* Could be an else here to try cmd.exe / command.com in the path
4292 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00004293 else {
Tim Peters402d5982001-08-27 06:37:48 +00004294 PyErr_SetString(PyExc_RuntimeError,
4295 "Cannot locate a COMSPEC environment variable to "
4296 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00004297 return FALSE;
4298 }
Tim Peters5aa91602002-01-30 05:46:57 +00004299
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004300 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
4301 siStartInfo.cb = sizeof(STARTUPINFO);
4302 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
4303 siStartInfo.hStdInput = hStdin;
4304 siStartInfo.hStdOutput = hStdout;
4305 siStartInfo.hStdError = hStderr;
4306 siStartInfo.wShowWindow = SW_HIDE;
4307
4308 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004309 s2,
4310 NULL,
4311 NULL,
4312 TRUE,
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004313 dwProcessFlags,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004314 NULL,
4315 NULL,
4316 &siStartInfo,
4317 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004318 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004319 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004320
Mark Hammondb37a3732000-08-14 04:47:33 +00004321 /* Return process handle */
4322 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004323 return TRUE;
4324 }
Tim Peters402d5982001-08-27 06:37:48 +00004325 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004326 return FALSE;
4327}
4328
4329/* The following code is based off of KB: Q190351 */
4330
4331static PyObject *
4332_PyPopen(char *cmdstring, int mode, int n)
4333{
4334 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
4335 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00004336 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00004337
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004338 SECURITY_ATTRIBUTES saAttr;
4339 BOOL fSuccess;
4340 int fd1, fd2, fd3;
4341 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00004342 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004343 PyObject *f;
4344
4345 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
4346 saAttr.bInheritHandle = TRUE;
4347 saAttr.lpSecurityDescriptor = NULL;
4348
4349 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
4350 return win32_error("CreatePipe", NULL);
4351
4352 /* Create new output read handle and the input write handle. Set
4353 * the inheritance properties to FALSE. Otherwise, the child inherits
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00004354 * these handles; resulting in non-closeable handles to the pipes
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004355 * being created. */
4356 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004357 GetCurrentProcess(), &hChildStdinWrDup, 0,
4358 FALSE,
4359 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004360 if (!fSuccess)
4361 return win32_error("DuplicateHandle", NULL);
4362
4363 /* Close the inheritable version of ChildStdin
4364 that we're using. */
4365 CloseHandle(hChildStdinWr);
4366
4367 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
4368 return win32_error("CreatePipe", NULL);
4369
4370 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004371 GetCurrentProcess(), &hChildStdoutRdDup, 0,
4372 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004373 if (!fSuccess)
4374 return win32_error("DuplicateHandle", NULL);
4375
4376 /* Close the inheritable version of ChildStdout
4377 that we're using. */
4378 CloseHandle(hChildStdoutRd);
4379
4380 if (n != POPEN_4) {
4381 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
4382 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004383 fSuccess = DuplicateHandle(GetCurrentProcess(),
4384 hChildStderrRd,
4385 GetCurrentProcess(),
4386 &hChildStderrRdDup, 0,
4387 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004388 if (!fSuccess)
4389 return win32_error("DuplicateHandle", NULL);
4390 /* Close the inheritable version of ChildStdErr that we're using. */
4391 CloseHandle(hChildStderrRd);
4392 }
Tim Peters5aa91602002-01-30 05:46:57 +00004393
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004394 switch (n) {
4395 case POPEN_1:
4396 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
4397 case _O_WRONLY | _O_TEXT:
4398 /* Case for writing to child Stdin in text mode. */
4399 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4400 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004401 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004402 PyFile_SetBufSize(f, 0);
4403 /* We don't care about these pipes anymore, so close them. */
4404 CloseHandle(hChildStdoutRdDup);
4405 CloseHandle(hChildStderrRdDup);
4406 break;
4407
4408 case _O_RDONLY | _O_TEXT:
4409 /* Case for reading from child Stdout in text mode. */
4410 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4411 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004412 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004413 PyFile_SetBufSize(f, 0);
4414 /* We don't care about these pipes anymore, so close them. */
4415 CloseHandle(hChildStdinWrDup);
4416 CloseHandle(hChildStderrRdDup);
4417 break;
4418
4419 case _O_RDONLY | _O_BINARY:
4420 /* Case for readinig from child Stdout in binary mode. */
4421 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4422 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004423 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004424 PyFile_SetBufSize(f, 0);
4425 /* We don't care about these pipes anymore, so close them. */
4426 CloseHandle(hChildStdinWrDup);
4427 CloseHandle(hChildStderrRdDup);
4428 break;
4429
4430 case _O_WRONLY | _O_BINARY:
4431 /* Case for writing to child Stdin in binary mode. */
4432 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4433 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004434 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004435 PyFile_SetBufSize(f, 0);
4436 /* We don't care about these pipes anymore, so close them. */
4437 CloseHandle(hChildStdoutRdDup);
4438 CloseHandle(hChildStderrRdDup);
4439 break;
4440 }
Mark Hammondb37a3732000-08-14 04:47:33 +00004441 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004442 break;
Tim Peters5aa91602002-01-30 05:46:57 +00004443
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004444 case POPEN_2:
4445 case POPEN_4:
4446 {
4447 char *m1, *m2;
4448 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00004449
Tim Peters7dca21e2002-08-19 00:42:29 +00004450 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004451 m1 = "r";
4452 m2 = "w";
4453 } else {
4454 m1 = "rb";
4455 m2 = "wb";
4456 }
4457
4458 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4459 f1 = _fdopen(fd1, m2);
4460 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4461 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004462 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004463 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00004464 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004465 PyFile_SetBufSize(p2, 0);
4466
4467 if (n != 4)
4468 CloseHandle(hChildStderrRdDup);
4469
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004470 f = PyTuple_Pack(2,p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00004471 Py_XDECREF(p1);
4472 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00004473 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004474 break;
4475 }
Tim Peters5aa91602002-01-30 05:46:57 +00004476
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004477 case POPEN_3:
4478 {
4479 char *m1, *m2;
4480 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00004481
Tim Peters7dca21e2002-08-19 00:42:29 +00004482 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004483 m1 = "r";
4484 m2 = "w";
4485 } else {
4486 m1 = "rb";
4487 m2 = "wb";
4488 }
4489
4490 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4491 f1 = _fdopen(fd1, m2);
4492 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4493 f2 = _fdopen(fd2, m1);
4494 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
4495 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004496 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00004497 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
4498 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004499 PyFile_SetBufSize(p1, 0);
4500 PyFile_SetBufSize(p2, 0);
4501 PyFile_SetBufSize(p3, 0);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004502 f = PyTuple_Pack(3,p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00004503 Py_XDECREF(p1);
4504 Py_XDECREF(p2);
4505 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00004506 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004507 break;
4508 }
4509 }
4510
4511 if (n == POPEN_4) {
4512 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004513 hChildStdinRd,
4514 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004515 hChildStdoutWr,
4516 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004517 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004518 }
4519 else {
4520 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004521 hChildStdinRd,
4522 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004523 hChildStderrWr,
4524 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004525 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004526 }
4527
Mark Hammondb37a3732000-08-14 04:47:33 +00004528 /*
4529 * Insert the files we've created into the process dictionary
4530 * all referencing the list with the process handle and the
4531 * initial number of files (see description below in _PyPclose).
4532 * Since if _PyPclose later tried to wait on a process when all
4533 * handles weren't closed, it could create a deadlock with the
4534 * child, we spend some energy here to try to ensure that we
4535 * either insert all file handles into the dictionary or none
4536 * at all. It's a little clumsy with the various popen modes
4537 * and variable number of files involved.
4538 */
4539 if (!_PyPopenProcs) {
4540 _PyPopenProcs = PyDict_New();
4541 }
4542
4543 if (_PyPopenProcs) {
4544 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
4545 int ins_rc[3];
4546
4547 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4548 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4549
4550 procObj = PyList_New(2);
4551 hProcessObj = PyLong_FromVoidPtr(hProcess);
4552 intObj = PyInt_FromLong(file_count);
4553
4554 if (procObj && hProcessObj && intObj) {
4555 PyList_SetItem(procObj,0,hProcessObj);
4556 PyList_SetItem(procObj,1,intObj);
4557
4558 fileObj[0] = PyLong_FromVoidPtr(f1);
4559 if (fileObj[0]) {
4560 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4561 fileObj[0],
4562 procObj);
4563 }
4564 if (file_count >= 2) {
4565 fileObj[1] = PyLong_FromVoidPtr(f2);
4566 if (fileObj[1]) {
4567 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4568 fileObj[1],
4569 procObj);
4570 }
4571 }
4572 if (file_count >= 3) {
4573 fileObj[2] = PyLong_FromVoidPtr(f3);
4574 if (fileObj[2]) {
4575 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4576 fileObj[2],
4577 procObj);
4578 }
4579 }
4580
4581 if (ins_rc[0] < 0 || !fileObj[0] ||
4582 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4583 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
4584 /* Something failed - remove any dictionary
4585 * entries that did make it.
4586 */
4587 if (!ins_rc[0] && fileObj[0]) {
4588 PyDict_DelItem(_PyPopenProcs,
4589 fileObj[0]);
4590 }
4591 if (!ins_rc[1] && fileObj[1]) {
4592 PyDict_DelItem(_PyPopenProcs,
4593 fileObj[1]);
4594 }
4595 if (!ins_rc[2] && fileObj[2]) {
4596 PyDict_DelItem(_PyPopenProcs,
4597 fileObj[2]);
4598 }
4599 }
4600 }
Tim Peters5aa91602002-01-30 05:46:57 +00004601
Mark Hammondb37a3732000-08-14 04:47:33 +00004602 /*
4603 * Clean up our localized references for the dictionary keys
4604 * and value since PyDict_SetItem will Py_INCREF any copies
4605 * that got placed in the dictionary.
4606 */
4607 Py_XDECREF(procObj);
4608 Py_XDECREF(fileObj[0]);
4609 Py_XDECREF(fileObj[1]);
4610 Py_XDECREF(fileObj[2]);
4611 }
4612
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004613 /* Child is launched. Close the parents copy of those pipe
4614 * handles that only the child should have open. You need to
4615 * make sure that no handles to the write end of the output pipe
4616 * are maintained in this process or else the pipe will not close
4617 * when the child process exits and the ReadFile will hang. */
4618
4619 if (!CloseHandle(hChildStdinRd))
4620 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004621
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004622 if (!CloseHandle(hChildStdoutWr))
4623 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004624
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004625 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
4626 return win32_error("CloseHandle", NULL);
4627
4628 return f;
4629}
Fredrik Lundh56055a42000-07-23 19:47:12 +00004630
4631/*
4632 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4633 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00004634 *
4635 * This function uses the _PyPopenProcs dictionary in order to map the
4636 * input file pointer to information about the process that was
4637 * originally created by the popen* call that created the file pointer.
4638 * The dictionary uses the file pointer as a key (with one entry
4639 * inserted for each file returned by the original popen* call) and a
4640 * single list object as the value for all files from a single call.
4641 * The list object contains the Win32 process handle at [0], and a file
4642 * count at [1], which is initialized to the total number of file
4643 * handles using that list.
4644 *
4645 * This function closes whichever handle it is passed, and decrements
4646 * the file count in the dictionary for the process handle pointed to
4647 * by this file. On the last close (when the file count reaches zero),
4648 * this function will wait for the child process and then return its
4649 * exit code as the result of the close() operation. This permits the
4650 * files to be closed in any order - it is always the close() of the
4651 * final handle that will return the exit code.
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004652 *
4653 * NOTE: This function is currently called with the GIL released.
4654 * hence we use the GILState API to manage our state.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004655 */
Tim Peters736aa322000-09-01 06:51:24 +00004656
Fredrik Lundh56055a42000-07-23 19:47:12 +00004657static int _PyPclose(FILE *file)
4658{
Fredrik Lundh20318932000-07-26 17:29:12 +00004659 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004660 DWORD exit_code;
4661 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00004662 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
4663 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00004664#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004665 PyGILState_STATE state;
Tim Peters736aa322000-09-01 06:51:24 +00004666#endif
4667
Fredrik Lundh20318932000-07-26 17:29:12 +00004668 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00004669 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00004670 */
4671 result = fclose(file);
Tim Peters736aa322000-09-01 06:51:24 +00004672#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004673 state = PyGILState_Ensure();
Tim Peters736aa322000-09-01 06:51:24 +00004674#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00004675 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00004676 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4677 (procObj = PyDict_GetItem(_PyPopenProcs,
4678 fileObj)) != NULL &&
4679 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
4680 (intObj = PyList_GetItem(procObj,1)) != NULL) {
4681
4682 hProcess = PyLong_AsVoidPtr(hProcessObj);
4683 file_count = PyInt_AsLong(intObj);
4684
4685 if (file_count > 1) {
4686 /* Still other files referencing process */
4687 file_count--;
4688 PyList_SetItem(procObj,1,
4689 PyInt_FromLong(file_count));
4690 } else {
4691 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00004692 if (result != EOF &&
4693 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
4694 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00004695 /* Possible truncation here in 16-bit environments, but
4696 * real exit codes are just the lower byte in any event.
4697 */
4698 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004699 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00004700 /* Indicate failure - this will cause the file object
4701 * to raise an I/O error and translate the last Win32
4702 * error code from errno. We do have a problem with
4703 * last errors that overlap the normal errno table,
4704 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004705 */
Fredrik Lundh20318932000-07-26 17:29:12 +00004706 if (result != EOF) {
4707 /* If the error wasn't from the fclose(), then
4708 * set errno for the file object error handling.
4709 */
4710 errno = GetLastError();
4711 }
4712 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004713 }
4714
4715 /* Free up the native handle at this point */
4716 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00004717 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00004718
Mark Hammondb37a3732000-08-14 04:47:33 +00004719 /* Remove this file pointer from dictionary */
4720 PyDict_DelItem(_PyPopenProcs, fileObj);
4721
4722 if (PyDict_Size(_PyPopenProcs) == 0) {
4723 Py_DECREF(_PyPopenProcs);
4724 _PyPopenProcs = NULL;
4725 }
4726
4727 } /* if object retrieval ok */
4728
4729 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004730 } /* if _PyPopenProcs */
4731
Tim Peters736aa322000-09-01 06:51:24 +00004732#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004733 PyGILState_Release(state);
Tim Peters736aa322000-09-01 06:51:24 +00004734#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00004735 return result;
4736}
Tim Peters9acdd3a2000-09-01 19:26:36 +00004737
4738#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00004739static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004740posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00004741{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004742 char *name;
4743 char *mode = "r";
4744 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00004745 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00004746 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004747 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00004748 return NULL;
Martin v. Löwis9ad853b2003-10-31 10:01:53 +00004749 /* Strip mode of binary or text modifiers */
4750 if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
4751 mode = "r";
4752 else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
4753 mode = "w";
Barry Warsaw53699e91996-12-10 23:23:01 +00004754 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004755 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004756 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00004757 if (fp == NULL)
4758 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004759 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004760 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00004761 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004762 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00004763}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004764
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004765#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004766#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00004767
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004768
Guido van Rossumb6775db1994-08-01 11:34:53 +00004769#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004770PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004771"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004772Set the current process's user id.");
4773
Barry Warsaw53699e91996-12-10 23:23:01 +00004774static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004775posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004776{
4777 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004778 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004779 return NULL;
4780 if (setuid(uid) < 0)
4781 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004782 Py_INCREF(Py_None);
4783 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004784}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004785#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004786
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004787
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004788#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004789PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004790"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004791Set the current process's effective user id.");
4792
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004793static PyObject *
4794posix_seteuid (PyObject *self, PyObject *args)
4795{
4796 int euid;
4797 if (!PyArg_ParseTuple(args, "i", &euid)) {
4798 return NULL;
4799 } else if (seteuid(euid) < 0) {
4800 return posix_error();
4801 } else {
4802 Py_INCREF(Py_None);
4803 return Py_None;
4804 }
4805}
4806#endif /* HAVE_SETEUID */
4807
4808#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004809PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004810"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004811Set the current process's effective group id.");
4812
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004813static PyObject *
4814posix_setegid (PyObject *self, PyObject *args)
4815{
4816 int egid;
4817 if (!PyArg_ParseTuple(args, "i", &egid)) {
4818 return NULL;
4819 } else if (setegid(egid) < 0) {
4820 return posix_error();
4821 } else {
4822 Py_INCREF(Py_None);
4823 return Py_None;
4824 }
4825}
4826#endif /* HAVE_SETEGID */
4827
4828#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004829PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004830"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004831Set the current process's real and effective user ids.");
4832
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004833static PyObject *
4834posix_setreuid (PyObject *self, PyObject *args)
4835{
4836 int ruid, euid;
4837 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
4838 return NULL;
4839 } else if (setreuid(ruid, euid) < 0) {
4840 return posix_error();
4841 } else {
4842 Py_INCREF(Py_None);
4843 return Py_None;
4844 }
4845}
4846#endif /* HAVE_SETREUID */
4847
4848#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004849PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004850"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004851Set the current process's real and effective group ids.");
4852
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004853static PyObject *
4854posix_setregid (PyObject *self, PyObject *args)
4855{
4856 int rgid, egid;
4857 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
4858 return NULL;
4859 } else if (setregid(rgid, egid) < 0) {
4860 return posix_error();
4861 } else {
4862 Py_INCREF(Py_None);
4863 return Py_None;
4864 }
4865}
4866#endif /* HAVE_SETREGID */
4867
Guido van Rossumb6775db1994-08-01 11:34:53 +00004868#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004869PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004870"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004871Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004872
Barry Warsaw53699e91996-12-10 23:23:01 +00004873static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004874posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004875{
4876 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004877 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004878 return NULL;
4879 if (setgid(gid) < 0)
4880 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004881 Py_INCREF(Py_None);
4882 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004883}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004884#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004885
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004886#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004887PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004888"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004889Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004890
4891static PyObject *
4892posix_setgroups(PyObject *self, PyObject *args)
4893{
4894 PyObject *groups;
4895 int i, len;
4896 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00004897
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004898 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
4899 return NULL;
4900 if (!PySequence_Check(groups)) {
4901 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
4902 return NULL;
4903 }
4904 len = PySequence_Size(groups);
4905 if (len > MAX_GROUPS) {
4906 PyErr_SetString(PyExc_ValueError, "too many groups");
4907 return NULL;
4908 }
4909 for(i = 0; i < len; i++) {
4910 PyObject *elem;
4911 elem = PySequence_GetItem(groups, i);
4912 if (!elem)
4913 return NULL;
4914 if (!PyInt_Check(elem)) {
4915 PyErr_SetString(PyExc_TypeError,
4916 "groups must be integers");
4917 Py_DECREF(elem);
4918 return NULL;
4919 }
4920 /* XXX: check that value fits into gid_t. */
4921 grouplist[i] = PyInt_AsLong(elem);
4922 Py_DECREF(elem);
4923 }
4924
4925 if (setgroups(len, grouplist) < 0)
4926 return posix_error();
4927 Py_INCREF(Py_None);
4928 return Py_None;
4929}
4930#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004931
Guido van Rossumb6775db1994-08-01 11:34:53 +00004932#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004933PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004934"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004935Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004936
Barry Warsaw53699e91996-12-10 23:23:01 +00004937static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004938posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004939{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004940 int pid, options;
4941#ifdef UNION_WAIT
4942 union wait status;
4943#define status_i (status.w_status)
4944#else
4945 int status;
4946#define status_i status
4947#endif
4948 status_i = 0;
4949
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004950 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00004951 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004952 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00004953 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00004954 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00004955 if (pid == -1)
4956 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00004957 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004958 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00004959}
4960
Tim Petersab034fa2002-02-01 11:27:43 +00004961#elif defined(HAVE_CWAIT)
4962
4963/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004964PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004965"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004966"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00004967
4968static PyObject *
4969posix_waitpid(PyObject *self, PyObject *args)
4970{
4971 int pid, options;
4972 int status;
4973
4974 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
4975 return NULL;
4976 Py_BEGIN_ALLOW_THREADS
4977 pid = _cwait(&status, pid, options);
4978 Py_END_ALLOW_THREADS
4979 if (pid == -1)
4980 return posix_error();
4981 else
4982 /* shift the status left a byte so this is more like the
4983 POSIX waitpid */
4984 return Py_BuildValue("ii", pid, status << 8);
4985}
4986#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004987
Guido van Rossumad0ee831995-03-01 10:34:45 +00004988#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004989PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004990"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004991Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004992
Barry Warsaw53699e91996-12-10 23:23:01 +00004993static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00004994posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00004995{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004996 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004997#ifdef UNION_WAIT
4998 union wait status;
4999#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00005000#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005001 int status;
5002#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00005003#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00005004
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005005 status_i = 0;
5006 Py_BEGIN_ALLOW_THREADS
5007 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00005008 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00005009 if (pid == -1)
5010 return posix_error();
5011 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005012 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005013#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00005014}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005015#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005016
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005017
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005018PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005019"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005020Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005021
Barry Warsaw53699e91996-12-10 23:23:01 +00005022static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005023posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005024{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005025#ifdef HAVE_LSTAT
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005026 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005027#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005028#ifdef MS_WINDOWS
Mark Hammond7edd0a92003-08-06 02:46:58 +00005029 return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", _wstati64);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005030#else
5031 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
5032#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005033#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005034}
5035
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005036
Guido van Rossumb6775db1994-08-01 11:34:53 +00005037#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005038PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005039"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005040Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005041
Barry Warsaw53699e91996-12-10 23:23:01 +00005042static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005043posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005044{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005045 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00005046 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005047 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005048 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005049 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005050 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00005051 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00005052 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005053 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00005054 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00005055 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005056}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005057#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005058
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005059
Guido van Rossumb6775db1994-08-01 11:34:53 +00005060#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005061PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005062"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00005063Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005064
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005065static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005066posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005067{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005068 return posix_2str(args, "etet:symlink", symlink, NULL, NULL);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005069}
5070#endif /* HAVE_SYMLINK */
5071
5072
5073#ifdef HAVE_TIMES
5074#ifndef HZ
5075#define HZ 60 /* Universal constant :-) */
5076#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00005077
Guido van Rossumd48f2521997-12-05 22:19:34 +00005078#if defined(PYCC_VACPP) && defined(PYOS_OS2)
5079static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005080system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005081{
5082 ULONG value = 0;
5083
5084 Py_BEGIN_ALLOW_THREADS
5085 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
5086 Py_END_ALLOW_THREADS
5087
5088 return value;
5089}
5090
5091static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005092posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005093{
Guido van Rossumd48f2521997-12-05 22:19:34 +00005094 /* Currently Only Uptime is Provided -- Others Later */
5095 return Py_BuildValue("ddddd",
5096 (double)0 /* t.tms_utime / HZ */,
5097 (double)0 /* t.tms_stime / HZ */,
5098 (double)0 /* t.tms_cutime / HZ */,
5099 (double)0 /* t.tms_cstime / HZ */,
5100 (double)system_uptime() / 1000);
5101}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005102#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00005103static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005104posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00005105{
5106 struct tms t;
5107 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +00005108 errno = 0;
5109 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00005110 if (c == (clock_t) -1)
5111 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005112 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00005113 (double)t.tms_utime / HZ,
5114 (double)t.tms_stime / HZ,
5115 (double)t.tms_cutime / HZ,
5116 (double)t.tms_cstime / HZ,
5117 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00005118}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005119#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005120#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005121
5122
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005123#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005124#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00005125static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005126posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005127{
5128 FILETIME create, exit, kernel, user;
5129 HANDLE hProc;
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005130 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00005131 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
5132 /* The fields of a FILETIME structure are the hi and lo part
5133 of a 64-bit value expressed in 100 nanosecond units.
5134 1e7 is one second in such units; 1e-7 the inverse.
5135 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
5136 */
Barry Warsaw53699e91996-12-10 23:23:01 +00005137 return Py_BuildValue(
5138 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00005139 (double)(kernel.dwHighDateTime*429.4967296 +
5140 kernel.dwLowDateTime*1e-7),
5141 (double)(user.dwHighDateTime*429.4967296 +
5142 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00005143 (double)0,
5144 (double)0,
5145 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005146}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005147#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005148
5149#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005150PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005151"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005152Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005153#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005154
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005155
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00005156#ifdef HAVE_GETSID
5157PyDoc_STRVAR(posix_getsid__doc__,
5158"getsid(pid) -> sid\n\n\
5159Call the system call getsid().");
5160
5161static PyObject *
5162posix_getsid(PyObject *self, PyObject *args)
5163{
5164 int pid, sid;
5165 if (!PyArg_ParseTuple(args, "i:getsid", &pid))
5166 return NULL;
5167 sid = getsid(pid);
5168 if (sid < 0)
5169 return posix_error();
5170 return PyInt_FromLong((long)sid);
5171}
5172#endif /* HAVE_GETSID */
5173
5174
Guido van Rossumb6775db1994-08-01 11:34:53 +00005175#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005176PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005177"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005178Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005179
Barry Warsaw53699e91996-12-10 23:23:01 +00005180static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005181posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005182{
Guido van Rossum687dd131993-05-17 08:34:16 +00005183 if (setsid() < 0)
5184 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005185 Py_INCREF(Py_None);
5186 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005187}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005188#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005189
Guido van Rossumb6775db1994-08-01 11:34:53 +00005190#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005191PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005192"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005193Call the system call setpgid().");
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_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005197{
5198 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005199 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00005200 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005201 if (setpgid(pid, pgrp) < 0)
5202 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005203 Py_INCREF(Py_None);
5204 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005205}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005206#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005207
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005208
Guido van Rossumb6775db1994-08-01 11:34:53 +00005209#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005210PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005211"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005212Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005213
Barry Warsaw53699e91996-12-10 23:23:01 +00005214static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005215posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005216{
5217 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005218 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00005219 return NULL;
5220 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005221 if (pgid < 0)
5222 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005223 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00005224}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005225#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00005226
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005227
Guido van Rossumb6775db1994-08-01 11:34:53 +00005228#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005229PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005230"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005231Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005232
Barry Warsaw53699e91996-12-10 23:23:01 +00005233static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005234posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005235{
5236 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005237 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00005238 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005239 if (tcsetpgrp(fd, pgid) < 0)
5240 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00005241 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00005242 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00005243}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005244#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00005245
Guido van Rossum687dd131993-05-17 08:34:16 +00005246/* Functions acting on file descriptors */
5247
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005248PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005249"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005250Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005251
Barry Warsaw53699e91996-12-10 23:23:01 +00005252static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005253posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005254{
Mark Hammondef8b6542001-05-13 08:04:26 +00005255 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005256 int flag;
5257 int mode = 0777;
5258 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005259
5260#ifdef MS_WINDOWS
5261 if (unicode_file_names()) {
5262 PyUnicodeObject *po;
5263 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
5264 Py_BEGIN_ALLOW_THREADS
5265 /* PyUnicode_AS_UNICODE OK without thread
5266 lock as it is a simple dereference. */
5267 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
5268 Py_END_ALLOW_THREADS
5269 if (fd < 0)
5270 return posix_error();
5271 return PyInt_FromLong((long)fd);
5272 }
5273 /* Drop the argument parsing error as narrow strings
5274 are also valid. */
5275 PyErr_Clear();
5276 }
5277#endif
5278
Tim Peters5aa91602002-01-30 05:46:57 +00005279 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00005280 Py_FileSystemDefaultEncoding, &file,
5281 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00005282 return NULL;
5283
Barry Warsaw53699e91996-12-10 23:23:01 +00005284 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005285 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005286 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005287 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00005288 return posix_error_with_allocated_filename(file);
5289 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00005290 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005291}
5292
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005293
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005294PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005295"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005296Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005297
Barry Warsaw53699e91996-12-10 23:23:01 +00005298static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005299posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005300{
5301 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005302 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005303 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005304 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005305 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00005306 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005307 if (res < 0)
5308 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005309 Py_INCREF(Py_None);
5310 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005311}
5312
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005313
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005314PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005315"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005316Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005317
Barry Warsaw53699e91996-12-10 23:23:01 +00005318static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005319posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005320{
5321 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005322 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005323 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005324 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005325 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00005326 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005327 if (fd < 0)
5328 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005329 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005330}
5331
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005332
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005333PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00005334"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005335Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005336
Barry Warsaw53699e91996-12-10 23:23:01 +00005337static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005338posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005339{
5340 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005341 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00005342 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005343 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005344 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00005345 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005346 if (res < 0)
5347 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005348 Py_INCREF(Py_None);
5349 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005350}
5351
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005352
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005353PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005354"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005355Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005356
Barry Warsaw53699e91996-12-10 23:23:01 +00005357static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005358posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005359{
5360 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005361#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005362 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005363#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00005364 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005365#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005366 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005367 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00005368 return NULL;
5369#ifdef SEEK_SET
5370 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
5371 switch (how) {
5372 case 0: how = SEEK_SET; break;
5373 case 1: how = SEEK_CUR; break;
5374 case 2: how = SEEK_END; break;
5375 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005376#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005377
5378#if !defined(HAVE_LARGEFILE_SUPPORT)
5379 pos = PyInt_AsLong(posobj);
5380#else
5381 pos = PyLong_Check(posobj) ?
5382 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
5383#endif
5384 if (PyErr_Occurred())
5385 return NULL;
5386
Barry Warsaw53699e91996-12-10 23:23:01 +00005387 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005388#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00005389 res = _lseeki64(fd, pos, how);
5390#else
Guido van Rossum687dd131993-05-17 08:34:16 +00005391 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005392#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005393 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005394 if (res < 0)
5395 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00005396
5397#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00005398 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005399#else
5400 return PyLong_FromLongLong(res);
5401#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005402}
5403
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005404
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005405PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005406"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005407Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005408
Barry Warsaw53699e91996-12-10 23:23:01 +00005409static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005410posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005411{
Guido van Rossum8bac5461996-06-11 18:38:48 +00005412 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00005413 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005414 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005415 return NULL;
Michael W. Hudson9867ced2005-01-31 17:01:59 +00005416 if (size < 0) {
5417 errno = EINVAL;
5418 return posix_error();
5419 }
Barry Warsaw53699e91996-12-10 23:23:01 +00005420 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005421 if (buffer == NULL)
5422 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005423 Py_BEGIN_ALLOW_THREADS
5424 n = read(fd, PyString_AsString(buffer), size);
5425 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00005426 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005427 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00005428 return posix_error();
5429 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00005430 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00005431 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00005432 return buffer;
5433}
5434
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005435
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005436PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005437"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005438Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005439
Barry Warsaw53699e91996-12-10 23:23:01 +00005440static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005441posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005442{
5443 int fd, size;
5444 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005445 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005446 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005447 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005448 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00005449 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005450 if (size < 0)
5451 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005452 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005453}
5454
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005455
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005456PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005457"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005458Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005459
Barry Warsaw53699e91996-12-10 23:23:01 +00005460static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005461posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005462{
5463 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00005464 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00005465 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005466 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005467 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005468#ifdef __VMS
5469 /* on OpenVMS we must ensure that all bytes are written to the file */
5470 fsync(fd);
5471#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005472 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00005473 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00005474 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005475 if (res != 0)
5476 return posix_error();
Tim Peters5aa91602002-01-30 05:46:57 +00005477
Fred Drake699f3522000-06-29 21:12:41 +00005478 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00005479}
5480
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005481
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005482PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005483"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005484Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005485
Barry Warsaw53699e91996-12-10 23:23:01 +00005486static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005487posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005488{
Guido van Rossum687dd131993-05-17 08:34:16 +00005489 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005490 char *mode = "r";
5491 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00005492 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00005493 PyObject *f;
5494 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00005495 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00005496
Thomas Heller1f043e22002-11-07 16:00:59 +00005497 if (mode[0] != 'r' && mode[0] != 'w' && mode[0] != 'a') {
5498 PyErr_Format(PyExc_ValueError,
5499 "invalid file mode '%s'", mode);
5500 return NULL;
5501 }
5502
Barry Warsaw53699e91996-12-10 23:23:01 +00005503 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005504 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005505 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005506 if (fp == NULL)
5507 return posix_error();
Guido van Rossumbd6be7a2002-09-15 18:45:46 +00005508 f = PyFile_FromFile(fp, "<fdopen>", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005509 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00005510 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005511 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00005512}
5513
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005514PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005515"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005516Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005517connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00005518
5519static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00005520posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00005521{
5522 int fd;
5523 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
5524 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005525 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00005526}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005527
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005528#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005529PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005530"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005531Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005532
Barry Warsaw53699e91996-12-10 23:23:01 +00005533static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005534posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00005535{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005536#if defined(PYOS_OS2)
5537 HFILE read, write;
5538 APIRET rc;
5539
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005540 Py_BEGIN_ALLOW_THREADS
5541 rc = DosCreatePipe( &read, &write, 4096);
5542 Py_END_ALLOW_THREADS
5543 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005544 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005545
5546 return Py_BuildValue("(ii)", read, write);
5547#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005548#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00005549 int fds[2];
5550 int res;
Barry Warsaw53699e91996-12-10 23:23:01 +00005551 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005552 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00005553 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005554 if (res != 0)
5555 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005556 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005557#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00005558 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005559 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00005560 BOOL ok;
Barry Warsaw53699e91996-12-10 23:23:01 +00005561 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005562 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00005563 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00005564 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005565 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00005566 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
5567 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005568 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005569#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005570#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005571}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005572#endif /* HAVE_PIPE */
5573
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005574
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005575#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005576PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005577"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005578Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005579
Barry Warsaw53699e91996-12-10 23:23:01 +00005580static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005581posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005582{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005583 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005584 int mode = 0666;
5585 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005586 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005587 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005588 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005589 res = mkfifo(filename, mode);
5590 Py_END_ALLOW_THREADS
5591 if (res < 0)
5592 return posix_error();
5593 Py_INCREF(Py_None);
5594 return Py_None;
5595}
5596#endif
5597
5598
Neal Norwitz11690112002-07-30 01:08:28 +00005599#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005600PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005601"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005602Create a filesystem node (file, device special file or named pipe)\n\
5603named filename. mode specifies both the permissions to use and the\n\
5604type of node to be created, being combined (bitwise OR) with one of\n\
5605S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005606device defines the newly created device special file (probably using\n\
5607os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005608
5609
5610static PyObject *
5611posix_mknod(PyObject *self, PyObject *args)
5612{
5613 char *filename;
5614 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005615 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005616 int res;
Martin v. Löwisd631ebe2002-11-02 17:42:33 +00005617 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005618 return NULL;
5619 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005620 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00005621 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005622 if (res < 0)
5623 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005624 Py_INCREF(Py_None);
5625 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005626}
5627#endif
5628
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005629#ifdef HAVE_DEVICE_MACROS
5630PyDoc_STRVAR(posix_major__doc__,
5631"major(device) -> major number\n\
5632Extracts a device major number from a raw device number.");
5633
5634static PyObject *
5635posix_major(PyObject *self, PyObject *args)
5636{
5637 int device;
5638 if (!PyArg_ParseTuple(args, "i:major", &device))
5639 return NULL;
5640 return PyInt_FromLong((long)major(device));
5641}
5642
5643PyDoc_STRVAR(posix_minor__doc__,
5644"minor(device) -> minor number\n\
5645Extracts a device minor number from a raw device number.");
5646
5647static PyObject *
5648posix_minor(PyObject *self, PyObject *args)
5649{
5650 int device;
5651 if (!PyArg_ParseTuple(args, "i:minor", &device))
5652 return NULL;
5653 return PyInt_FromLong((long)minor(device));
5654}
5655
5656PyDoc_STRVAR(posix_makedev__doc__,
5657"makedev(major, minor) -> device number\n\
5658Composes a raw device number from the major and minor device numbers.");
5659
5660static PyObject *
5661posix_makedev(PyObject *self, PyObject *args)
5662{
5663 int major, minor;
5664 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
5665 return NULL;
5666 return PyInt_FromLong((long)makedev(major, minor));
5667}
5668#endif /* device macros */
5669
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005670
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005671#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005672PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005673"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005674Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005675
Barry Warsaw53699e91996-12-10 23:23:01 +00005676static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005677posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005678{
5679 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005680 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005681 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005682 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005683
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005684 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005685 return NULL;
5686
5687#if !defined(HAVE_LARGEFILE_SUPPORT)
5688 length = PyInt_AsLong(lenobj);
5689#else
5690 length = PyLong_Check(lenobj) ?
5691 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
5692#endif
5693 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005694 return NULL;
5695
Barry Warsaw53699e91996-12-10 23:23:01 +00005696 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005697 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00005698 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005699 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005700 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005701 return NULL;
5702 }
Barry Warsaw53699e91996-12-10 23:23:01 +00005703 Py_INCREF(Py_None);
5704 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005705}
5706#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005707
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005708#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005709PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005710"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005711Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005712
Fred Drake762e2061999-08-26 17:23:54 +00005713/* Save putenv() parameters as values here, so we can collect them when they
5714 * get re-set with another call for the same key. */
5715static PyObject *posix_putenv_garbage;
5716
Tim Peters5aa91602002-01-30 05:46:57 +00005717static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005718posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005719{
5720 char *s1, *s2;
5721 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00005722 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00005723 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005724
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005725 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005726 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00005727
5728#if defined(PYOS_OS2)
5729 if (stricmp(s1, "BEGINLIBPATH") == 0) {
5730 APIRET rc;
5731
Guido van Rossumd48f2521997-12-05 22:19:34 +00005732 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
5733 if (rc != NO_ERROR)
5734 return os2_error(rc);
5735
5736 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
5737 APIRET rc;
5738
Guido van Rossumd48f2521997-12-05 22:19:34 +00005739 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
5740 if (rc != NO_ERROR)
5741 return os2_error(rc);
5742 } else {
5743#endif
5744
Fred Drake762e2061999-08-26 17:23:54 +00005745 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00005746 len = strlen(s1) + strlen(s2) + 2;
5747 /* len includes space for a trailing \0; the size arg to
5748 PyString_FromStringAndSize does not count that */
5749 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00005750 if (newstr == NULL)
5751 return PyErr_NoMemory();
5752 new = PyString_AS_STRING(newstr);
Tim Petersc8996f52001-12-03 20:41:00 +00005753 PyOS_snprintf(new, len, "%s=%s", s1, s2);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005754 if (putenv(new)) {
Neal Norwitz4adc9ab2003-02-10 03:10:43 +00005755 Py_DECREF(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005756 posix_error();
5757 return NULL;
5758 }
Fred Drake762e2061999-08-26 17:23:54 +00005759 /* Install the first arg and newstr in posix_putenv_garbage;
5760 * this will cause previous value to be collected. This has to
5761 * happen after the real putenv() call because the old value
5762 * was still accessible until then. */
5763 if (PyDict_SetItem(posix_putenv_garbage,
5764 PyTuple_GET_ITEM(args, 0), newstr)) {
5765 /* really not much we can do; just leak */
5766 PyErr_Clear();
5767 }
5768 else {
5769 Py_DECREF(newstr);
5770 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005771
5772#if defined(PYOS_OS2)
5773 }
5774#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005775 Py_INCREF(Py_None);
5776 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005777}
Guido van Rossumb6a47161997-09-15 22:54:34 +00005778#endif /* putenv */
5779
Guido van Rossumc524d952001-10-19 01:31:59 +00005780#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005781PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005782"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005783Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00005784
5785static PyObject *
5786posix_unsetenv(PyObject *self, PyObject *args)
5787{
5788 char *s1;
5789
5790 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
5791 return NULL;
5792
5793 unsetenv(s1);
5794
5795 /* Remove the key from posix_putenv_garbage;
5796 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00005797 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00005798 * old value was still accessible until then.
5799 */
5800 if (PyDict_DelItem(posix_putenv_garbage,
5801 PyTuple_GET_ITEM(args, 0))) {
5802 /* really not much we can do; just leak */
5803 PyErr_Clear();
5804 }
5805
5806 Py_INCREF(Py_None);
5807 return Py_None;
5808}
5809#endif /* unsetenv */
5810
Guido van Rossumb6a47161997-09-15 22:54:34 +00005811#ifdef HAVE_STRERROR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005812PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005813"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005814Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005815
Guido van Rossumf68d8e52001-04-14 17:55:09 +00005816static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005817posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00005818{
5819 int code;
5820 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005821 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00005822 return NULL;
5823 message = strerror(code);
5824 if (message == NULL) {
5825 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00005826 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005827 return NULL;
5828 }
5829 return PyString_FromString(message);
5830}
5831#endif /* strerror */
5832
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005833
Guido van Rossumc9641791998-08-04 15:26:23 +00005834#ifdef HAVE_SYS_WAIT_H
5835
Fred Drake106c1a02002-04-23 15:58:02 +00005836#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005837PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005838"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005839Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00005840
5841static PyObject *
5842posix_WCOREDUMP(PyObject *self, PyObject *args)
5843{
5844#ifdef UNION_WAIT
5845 union wait status;
5846#define status_i (status.w_status)
5847#else
5848 int status;
5849#define status_i status
5850#endif
5851 status_i = 0;
5852
5853 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &status_i))
5854 {
5855 return NULL;
5856 }
5857
5858 return PyBool_FromLong(WCOREDUMP(status));
5859#undef status_i
5860}
5861#endif /* WCOREDUMP */
5862
5863#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005864PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005865"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005866Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005867job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00005868
5869static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005870posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00005871{
5872#ifdef UNION_WAIT
5873 union wait status;
5874#define status_i (status.w_status)
5875#else
5876 int status;
5877#define status_i status
5878#endif
5879 status_i = 0;
5880
5881 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &status_i))
5882 {
5883 return NULL;
5884 }
5885
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005886 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00005887#undef status_i
5888}
5889#endif /* WIFCONTINUED */
5890
Guido van Rossumc9641791998-08-04 15:26:23 +00005891#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005892PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005893"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005894Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005895
5896static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005897posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005898{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005899#ifdef UNION_WAIT
5900 union wait status;
5901#define status_i (status.w_status)
5902#else
5903 int status;
5904#define status_i status
5905#endif
5906 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005907
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005908 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005909 {
5910 return NULL;
5911 }
Tim Peters5aa91602002-01-30 05:46:57 +00005912
Fred Drake106c1a02002-04-23 15:58:02 +00005913 return PyBool_FromLong(WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005914#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005915}
5916#endif /* WIFSTOPPED */
5917
5918#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005919PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005920"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005921Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005922
5923static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005924posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005925{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005926#ifdef UNION_WAIT
5927 union wait status;
5928#define status_i (status.w_status)
5929#else
5930 int status;
5931#define status_i status
5932#endif
5933 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005934
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005935 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005936 {
5937 return NULL;
5938 }
Tim Peters5aa91602002-01-30 05:46:57 +00005939
Fred Drake106c1a02002-04-23 15:58:02 +00005940 return PyBool_FromLong(WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005941#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005942}
5943#endif /* WIFSIGNALED */
5944
5945#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005946PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005947"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005948Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005949system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005950
5951static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005952posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005953{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005954#ifdef UNION_WAIT
5955 union wait status;
5956#define status_i (status.w_status)
5957#else
5958 int status;
5959#define status_i status
5960#endif
5961 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005962
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005963 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005964 {
5965 return NULL;
5966 }
Tim Peters5aa91602002-01-30 05:46:57 +00005967
Fred Drake106c1a02002-04-23 15:58:02 +00005968 return PyBool_FromLong(WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005969#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005970}
5971#endif /* WIFEXITED */
5972
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005973#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005974PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005975"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005976Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005977
5978static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005979posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005980{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005981#ifdef UNION_WAIT
5982 union wait status;
5983#define status_i (status.w_status)
5984#else
5985 int status;
5986#define status_i status
5987#endif
5988 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005989
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005990 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005991 {
5992 return NULL;
5993 }
Tim Peters5aa91602002-01-30 05:46:57 +00005994
Guido van Rossumc9641791998-08-04 15:26:23 +00005995 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005996#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005997}
5998#endif /* WEXITSTATUS */
5999
6000#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006001PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006002"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006003Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006004value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006005
6006static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006007posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006008{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006009#ifdef UNION_WAIT
6010 union wait status;
6011#define status_i (status.w_status)
6012#else
6013 int status;
6014#define status_i status
6015#endif
6016 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006017
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006018 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00006019 {
6020 return NULL;
6021 }
Tim Peters5aa91602002-01-30 05:46:57 +00006022
Guido van Rossumc9641791998-08-04 15:26:23 +00006023 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006024#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00006025}
6026#endif /* WTERMSIG */
6027
6028#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006029PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006030"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006031Return the signal that stopped the process that provided\n\
6032the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006033
6034static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006035posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006036{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006037#ifdef UNION_WAIT
6038 union wait status;
6039#define status_i (status.w_status)
6040#else
6041 int status;
6042#define status_i status
6043#endif
6044 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006045
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006046 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00006047 {
6048 return NULL;
6049 }
Tim Peters5aa91602002-01-30 05:46:57 +00006050
Guido van Rossumc9641791998-08-04 15:26:23 +00006051 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006052#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00006053}
6054#endif /* WSTOPSIG */
6055
6056#endif /* HAVE_SYS_WAIT_H */
6057
6058
Guido van Rossum94f6f721999-01-06 18:42:14 +00006059#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00006060#ifdef _SCO_DS
6061/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
6062 needed definitions in sys/statvfs.h */
6063#define _SVID3
6064#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006065#include <sys/statvfs.h>
6066
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006067static PyObject*
6068_pystatvfs_fromstructstatvfs(struct statvfs st) {
6069 PyObject *v = PyStructSequence_New(&StatVFSResultType);
6070 if (v == NULL)
6071 return NULL;
6072
6073#if !defined(HAVE_LARGEFILE_SUPPORT)
6074 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6075 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
6076 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
6077 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
6078 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
6079 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
6080 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
6081 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
6082 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6083 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6084#else
6085 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6086 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00006087 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006088 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00006089 PyStructSequence_SET_ITEM(v, 3,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006090 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006091 PyStructSequence_SET_ITEM(v, 4,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006092 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00006093 PyStructSequence_SET_ITEM(v, 5,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006094 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00006095 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006096 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00006097 PyStructSequence_SET_ITEM(v, 7,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006098 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006099 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6100 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6101#endif
6102
6103 return v;
6104}
6105
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006106PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006107"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006108Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006109
6110static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006111posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006112{
6113 int fd, res;
6114 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006115
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006116 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006117 return NULL;
6118 Py_BEGIN_ALLOW_THREADS
6119 res = fstatvfs(fd, &st);
6120 Py_END_ALLOW_THREADS
6121 if (res != 0)
6122 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006123
6124 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006125}
6126#endif /* HAVE_FSTATVFS */
6127
6128
6129#if defined(HAVE_STATVFS)
6130#include <sys/statvfs.h>
6131
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006132PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006133"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006134Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006135
6136static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006137posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006138{
6139 char *path;
6140 int res;
6141 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006142 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006143 return NULL;
6144 Py_BEGIN_ALLOW_THREADS
6145 res = statvfs(path, &st);
6146 Py_END_ALLOW_THREADS
6147 if (res != 0)
6148 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006149
6150 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006151}
6152#endif /* HAVE_STATVFS */
6153
6154
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006155#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006156PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006157"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006158Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00006159The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006160or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006161
6162static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006163posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006164{
6165 PyObject *result = NULL;
6166 char *dir = NULL;
6167 char *pfx = NULL;
6168 char *name;
6169
6170 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
6171 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00006172
6173 if (PyErr_Warn(PyExc_RuntimeWarning,
6174 "tempnam is a potential security risk to your program") < 0)
6175 return NULL;
6176
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006177#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00006178 name = _tempnam(dir, pfx);
6179#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006180 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00006181#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006182 if (name == NULL)
6183 return PyErr_NoMemory();
6184 result = PyString_FromString(name);
6185 free(name);
6186 return result;
6187}
Guido van Rossumd371ff11999-01-25 16:12:23 +00006188#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006189
6190
6191#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006192PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006193"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006194Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006195
6196static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006197posix_tmpfile(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006198{
6199 FILE *fp;
6200
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006201 fp = tmpfile();
6202 if (fp == NULL)
6203 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00006204 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006205}
6206#endif
6207
6208
6209#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006210PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006211"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006212Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006213
6214static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006215posix_tmpnam(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006216{
6217 char buffer[L_tmpnam];
6218 char *name;
6219
Skip Montanaro95618b52001-08-18 18:52:10 +00006220 if (PyErr_Warn(PyExc_RuntimeWarning,
6221 "tmpnam is a potential security risk to your program") < 0)
6222 return NULL;
6223
Greg Wardb48bc172000-03-01 21:51:56 +00006224#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006225 name = tmpnam_r(buffer);
6226#else
6227 name = tmpnam(buffer);
6228#endif
6229 if (name == NULL) {
6230 PyErr_SetObject(PyExc_OSError,
6231 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00006232#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006233 "unexpected NULL from tmpnam_r"
6234#else
6235 "unexpected NULL from tmpnam"
6236#endif
6237 ));
6238 return NULL;
6239 }
6240 return PyString_FromString(buffer);
6241}
6242#endif
6243
6244
Fred Drakec9680921999-12-13 16:37:25 +00006245/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
6246 * It maps strings representing configuration variable names to
6247 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00006248 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00006249 * rarely-used constants. There are three separate tables that use
6250 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00006251 *
6252 * This code is always included, even if none of the interfaces that
6253 * need it are included. The #if hackery needed to avoid it would be
6254 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00006255 */
6256struct constdef {
6257 char *name;
6258 long value;
6259};
6260
Fred Drake12c6e2d1999-12-14 21:25:03 +00006261static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006262conv_confname(PyObject *arg, int *valuep, struct constdef *table,
6263 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006264{
6265 if (PyInt_Check(arg)) {
6266 *valuep = PyInt_AS_LONG(arg);
6267 return 1;
6268 }
6269 if (PyString_Check(arg)) {
6270 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00006271 size_t lo = 0;
6272 size_t mid;
6273 size_t hi = tablesize;
6274 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006275 char *confname = PyString_AS_STRING(arg);
6276 while (lo < hi) {
6277 mid = (lo + hi) / 2;
6278 cmp = strcmp(confname, table[mid].name);
6279 if (cmp < 0)
6280 hi = mid;
6281 else if (cmp > 0)
6282 lo = mid + 1;
6283 else {
6284 *valuep = table[mid].value;
6285 return 1;
6286 }
6287 }
6288 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
6289 }
6290 else
6291 PyErr_SetString(PyExc_TypeError,
6292 "configuration names must be strings or integers");
6293 return 0;
6294}
6295
6296
6297#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
6298static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006299#ifdef _PC_ABI_AIO_XFER_MAX
6300 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
6301#endif
6302#ifdef _PC_ABI_ASYNC_IO
6303 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
6304#endif
Fred Drakec9680921999-12-13 16:37:25 +00006305#ifdef _PC_ASYNC_IO
6306 {"PC_ASYNC_IO", _PC_ASYNC_IO},
6307#endif
6308#ifdef _PC_CHOWN_RESTRICTED
6309 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
6310#endif
6311#ifdef _PC_FILESIZEBITS
6312 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
6313#endif
6314#ifdef _PC_LAST
6315 {"PC_LAST", _PC_LAST},
6316#endif
6317#ifdef _PC_LINK_MAX
6318 {"PC_LINK_MAX", _PC_LINK_MAX},
6319#endif
6320#ifdef _PC_MAX_CANON
6321 {"PC_MAX_CANON", _PC_MAX_CANON},
6322#endif
6323#ifdef _PC_MAX_INPUT
6324 {"PC_MAX_INPUT", _PC_MAX_INPUT},
6325#endif
6326#ifdef _PC_NAME_MAX
6327 {"PC_NAME_MAX", _PC_NAME_MAX},
6328#endif
6329#ifdef _PC_NO_TRUNC
6330 {"PC_NO_TRUNC", _PC_NO_TRUNC},
6331#endif
6332#ifdef _PC_PATH_MAX
6333 {"PC_PATH_MAX", _PC_PATH_MAX},
6334#endif
6335#ifdef _PC_PIPE_BUF
6336 {"PC_PIPE_BUF", _PC_PIPE_BUF},
6337#endif
6338#ifdef _PC_PRIO_IO
6339 {"PC_PRIO_IO", _PC_PRIO_IO},
6340#endif
6341#ifdef _PC_SOCK_MAXBUF
6342 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
6343#endif
6344#ifdef _PC_SYNC_IO
6345 {"PC_SYNC_IO", _PC_SYNC_IO},
6346#endif
6347#ifdef _PC_VDISABLE
6348 {"PC_VDISABLE", _PC_VDISABLE},
6349#endif
6350};
6351
Fred Drakec9680921999-12-13 16:37:25 +00006352static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006353conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006354{
6355 return conv_confname(arg, valuep, posix_constants_pathconf,
6356 sizeof(posix_constants_pathconf)
6357 / sizeof(struct constdef));
6358}
6359#endif
6360
6361#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006362PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006363"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006364Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006365If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006366
6367static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006368posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006369{
6370 PyObject *result = NULL;
6371 int name, fd;
6372
Fred Drake12c6e2d1999-12-14 21:25:03 +00006373 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
6374 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00006375 long limit;
6376
6377 errno = 0;
6378 limit = fpathconf(fd, name);
6379 if (limit == -1 && errno != 0)
6380 posix_error();
6381 else
6382 result = PyInt_FromLong(limit);
6383 }
6384 return result;
6385}
6386#endif
6387
6388
6389#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006390PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006391"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006392Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006393If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006394
6395static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006396posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006397{
6398 PyObject *result = NULL;
6399 int name;
6400 char *path;
6401
6402 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
6403 conv_path_confname, &name)) {
6404 long limit;
6405
6406 errno = 0;
6407 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006408 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00006409 if (errno == EINVAL)
6410 /* could be a path or name problem */
6411 posix_error();
6412 else
6413 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006414 }
Fred Drakec9680921999-12-13 16:37:25 +00006415 else
6416 result = PyInt_FromLong(limit);
6417 }
6418 return result;
6419}
6420#endif
6421
6422#ifdef HAVE_CONFSTR
6423static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006424#ifdef _CS_ARCHITECTURE
6425 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
6426#endif
6427#ifdef _CS_HOSTNAME
6428 {"CS_HOSTNAME", _CS_HOSTNAME},
6429#endif
6430#ifdef _CS_HW_PROVIDER
6431 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
6432#endif
6433#ifdef _CS_HW_SERIAL
6434 {"CS_HW_SERIAL", _CS_HW_SERIAL},
6435#endif
6436#ifdef _CS_INITTAB_NAME
6437 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
6438#endif
Fred Drakec9680921999-12-13 16:37:25 +00006439#ifdef _CS_LFS64_CFLAGS
6440 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
6441#endif
6442#ifdef _CS_LFS64_LDFLAGS
6443 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
6444#endif
6445#ifdef _CS_LFS64_LIBS
6446 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
6447#endif
6448#ifdef _CS_LFS64_LINTFLAGS
6449 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
6450#endif
6451#ifdef _CS_LFS_CFLAGS
6452 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
6453#endif
6454#ifdef _CS_LFS_LDFLAGS
6455 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
6456#endif
6457#ifdef _CS_LFS_LIBS
6458 {"CS_LFS_LIBS", _CS_LFS_LIBS},
6459#endif
6460#ifdef _CS_LFS_LINTFLAGS
6461 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
6462#endif
Fred Draked86ed291999-12-15 15:34:33 +00006463#ifdef _CS_MACHINE
6464 {"CS_MACHINE", _CS_MACHINE},
6465#endif
Fred Drakec9680921999-12-13 16:37:25 +00006466#ifdef _CS_PATH
6467 {"CS_PATH", _CS_PATH},
6468#endif
Fred Draked86ed291999-12-15 15:34:33 +00006469#ifdef _CS_RELEASE
6470 {"CS_RELEASE", _CS_RELEASE},
6471#endif
6472#ifdef _CS_SRPC_DOMAIN
6473 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
6474#endif
6475#ifdef _CS_SYSNAME
6476 {"CS_SYSNAME", _CS_SYSNAME},
6477#endif
6478#ifdef _CS_VERSION
6479 {"CS_VERSION", _CS_VERSION},
6480#endif
Fred Drakec9680921999-12-13 16:37:25 +00006481#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
6482 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
6483#endif
6484#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
6485 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
6486#endif
6487#ifdef _CS_XBS5_ILP32_OFF32_LIBS
6488 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
6489#endif
6490#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
6491 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
6492#endif
6493#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
6494 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
6495#endif
6496#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
6497 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
6498#endif
6499#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
6500 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
6501#endif
6502#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
6503 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
6504#endif
6505#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
6506 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
6507#endif
6508#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
6509 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
6510#endif
6511#ifdef _CS_XBS5_LP64_OFF64_LIBS
6512 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
6513#endif
6514#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
6515 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
6516#endif
6517#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
6518 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
6519#endif
6520#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
6521 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
6522#endif
6523#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
6524 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
6525#endif
6526#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
6527 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
6528#endif
Fred Draked86ed291999-12-15 15:34:33 +00006529#ifdef _MIPS_CS_AVAIL_PROCESSORS
6530 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
6531#endif
6532#ifdef _MIPS_CS_BASE
6533 {"MIPS_CS_BASE", _MIPS_CS_BASE},
6534#endif
6535#ifdef _MIPS_CS_HOSTID
6536 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
6537#endif
6538#ifdef _MIPS_CS_HW_NAME
6539 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
6540#endif
6541#ifdef _MIPS_CS_NUM_PROCESSORS
6542 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
6543#endif
6544#ifdef _MIPS_CS_OSREL_MAJ
6545 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
6546#endif
6547#ifdef _MIPS_CS_OSREL_MIN
6548 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
6549#endif
6550#ifdef _MIPS_CS_OSREL_PATCH
6551 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
6552#endif
6553#ifdef _MIPS_CS_OS_NAME
6554 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
6555#endif
6556#ifdef _MIPS_CS_OS_PROVIDER
6557 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
6558#endif
6559#ifdef _MIPS_CS_PROCESSORS
6560 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
6561#endif
6562#ifdef _MIPS_CS_SERIAL
6563 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
6564#endif
6565#ifdef _MIPS_CS_VENDOR
6566 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
6567#endif
Fred Drakec9680921999-12-13 16:37:25 +00006568};
6569
6570static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006571conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006572{
6573 return conv_confname(arg, valuep, posix_constants_confstr,
6574 sizeof(posix_constants_confstr)
6575 / sizeof(struct constdef));
6576}
6577
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006578PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006579"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006580Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006581
6582static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006583posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006584{
6585 PyObject *result = NULL;
6586 int name;
6587 char buffer[64];
6588
6589 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
6590 int len = confstr(name, buffer, sizeof(buffer));
6591
Fred Drakec9680921999-12-13 16:37:25 +00006592 errno = 0;
6593 if (len == 0) {
6594 if (errno != 0)
6595 posix_error();
6596 else
6597 result = PyString_FromString("");
6598 }
6599 else {
6600 if (len >= sizeof(buffer)) {
6601 result = PyString_FromStringAndSize(NULL, len);
6602 if (result != NULL)
6603 confstr(name, PyString_AS_STRING(result), len+1);
6604 }
6605 else
6606 result = PyString_FromString(buffer);
6607 }
6608 }
6609 return result;
6610}
6611#endif
6612
6613
6614#ifdef HAVE_SYSCONF
6615static struct constdef posix_constants_sysconf[] = {
6616#ifdef _SC_2_CHAR_TERM
6617 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
6618#endif
6619#ifdef _SC_2_C_BIND
6620 {"SC_2_C_BIND", _SC_2_C_BIND},
6621#endif
6622#ifdef _SC_2_C_DEV
6623 {"SC_2_C_DEV", _SC_2_C_DEV},
6624#endif
6625#ifdef _SC_2_C_VERSION
6626 {"SC_2_C_VERSION", _SC_2_C_VERSION},
6627#endif
6628#ifdef _SC_2_FORT_DEV
6629 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
6630#endif
6631#ifdef _SC_2_FORT_RUN
6632 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
6633#endif
6634#ifdef _SC_2_LOCALEDEF
6635 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
6636#endif
6637#ifdef _SC_2_SW_DEV
6638 {"SC_2_SW_DEV", _SC_2_SW_DEV},
6639#endif
6640#ifdef _SC_2_UPE
6641 {"SC_2_UPE", _SC_2_UPE},
6642#endif
6643#ifdef _SC_2_VERSION
6644 {"SC_2_VERSION", _SC_2_VERSION},
6645#endif
Fred Draked86ed291999-12-15 15:34:33 +00006646#ifdef _SC_ABI_ASYNCHRONOUS_IO
6647 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
6648#endif
6649#ifdef _SC_ACL
6650 {"SC_ACL", _SC_ACL},
6651#endif
Fred Drakec9680921999-12-13 16:37:25 +00006652#ifdef _SC_AIO_LISTIO_MAX
6653 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
6654#endif
Fred Drakec9680921999-12-13 16:37:25 +00006655#ifdef _SC_AIO_MAX
6656 {"SC_AIO_MAX", _SC_AIO_MAX},
6657#endif
6658#ifdef _SC_AIO_PRIO_DELTA_MAX
6659 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
6660#endif
6661#ifdef _SC_ARG_MAX
6662 {"SC_ARG_MAX", _SC_ARG_MAX},
6663#endif
6664#ifdef _SC_ASYNCHRONOUS_IO
6665 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
6666#endif
6667#ifdef _SC_ATEXIT_MAX
6668 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
6669#endif
Fred Draked86ed291999-12-15 15:34:33 +00006670#ifdef _SC_AUDIT
6671 {"SC_AUDIT", _SC_AUDIT},
6672#endif
Fred Drakec9680921999-12-13 16:37:25 +00006673#ifdef _SC_AVPHYS_PAGES
6674 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
6675#endif
6676#ifdef _SC_BC_BASE_MAX
6677 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
6678#endif
6679#ifdef _SC_BC_DIM_MAX
6680 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
6681#endif
6682#ifdef _SC_BC_SCALE_MAX
6683 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
6684#endif
6685#ifdef _SC_BC_STRING_MAX
6686 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
6687#endif
Fred Draked86ed291999-12-15 15:34:33 +00006688#ifdef _SC_CAP
6689 {"SC_CAP", _SC_CAP},
6690#endif
Fred Drakec9680921999-12-13 16:37:25 +00006691#ifdef _SC_CHARCLASS_NAME_MAX
6692 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
6693#endif
6694#ifdef _SC_CHAR_BIT
6695 {"SC_CHAR_BIT", _SC_CHAR_BIT},
6696#endif
6697#ifdef _SC_CHAR_MAX
6698 {"SC_CHAR_MAX", _SC_CHAR_MAX},
6699#endif
6700#ifdef _SC_CHAR_MIN
6701 {"SC_CHAR_MIN", _SC_CHAR_MIN},
6702#endif
6703#ifdef _SC_CHILD_MAX
6704 {"SC_CHILD_MAX", _SC_CHILD_MAX},
6705#endif
6706#ifdef _SC_CLK_TCK
6707 {"SC_CLK_TCK", _SC_CLK_TCK},
6708#endif
6709#ifdef _SC_COHER_BLKSZ
6710 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
6711#endif
6712#ifdef _SC_COLL_WEIGHTS_MAX
6713 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
6714#endif
6715#ifdef _SC_DCACHE_ASSOC
6716 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
6717#endif
6718#ifdef _SC_DCACHE_BLKSZ
6719 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
6720#endif
6721#ifdef _SC_DCACHE_LINESZ
6722 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
6723#endif
6724#ifdef _SC_DCACHE_SZ
6725 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
6726#endif
6727#ifdef _SC_DCACHE_TBLKSZ
6728 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
6729#endif
6730#ifdef _SC_DELAYTIMER_MAX
6731 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
6732#endif
6733#ifdef _SC_EQUIV_CLASS_MAX
6734 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
6735#endif
6736#ifdef _SC_EXPR_NEST_MAX
6737 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
6738#endif
6739#ifdef _SC_FSYNC
6740 {"SC_FSYNC", _SC_FSYNC},
6741#endif
6742#ifdef _SC_GETGR_R_SIZE_MAX
6743 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
6744#endif
6745#ifdef _SC_GETPW_R_SIZE_MAX
6746 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
6747#endif
6748#ifdef _SC_ICACHE_ASSOC
6749 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
6750#endif
6751#ifdef _SC_ICACHE_BLKSZ
6752 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
6753#endif
6754#ifdef _SC_ICACHE_LINESZ
6755 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
6756#endif
6757#ifdef _SC_ICACHE_SZ
6758 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
6759#endif
Fred Draked86ed291999-12-15 15:34:33 +00006760#ifdef _SC_INF
6761 {"SC_INF", _SC_INF},
6762#endif
Fred Drakec9680921999-12-13 16:37:25 +00006763#ifdef _SC_INT_MAX
6764 {"SC_INT_MAX", _SC_INT_MAX},
6765#endif
6766#ifdef _SC_INT_MIN
6767 {"SC_INT_MIN", _SC_INT_MIN},
6768#endif
6769#ifdef _SC_IOV_MAX
6770 {"SC_IOV_MAX", _SC_IOV_MAX},
6771#endif
Fred Draked86ed291999-12-15 15:34:33 +00006772#ifdef _SC_IP_SECOPTS
6773 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
6774#endif
Fred Drakec9680921999-12-13 16:37:25 +00006775#ifdef _SC_JOB_CONTROL
6776 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
6777#endif
Fred Draked86ed291999-12-15 15:34:33 +00006778#ifdef _SC_KERN_POINTERS
6779 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
6780#endif
6781#ifdef _SC_KERN_SIM
6782 {"SC_KERN_SIM", _SC_KERN_SIM},
6783#endif
Fred Drakec9680921999-12-13 16:37:25 +00006784#ifdef _SC_LINE_MAX
6785 {"SC_LINE_MAX", _SC_LINE_MAX},
6786#endif
6787#ifdef _SC_LOGIN_NAME_MAX
6788 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
6789#endif
6790#ifdef _SC_LOGNAME_MAX
6791 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
6792#endif
6793#ifdef _SC_LONG_BIT
6794 {"SC_LONG_BIT", _SC_LONG_BIT},
6795#endif
Fred Draked86ed291999-12-15 15:34:33 +00006796#ifdef _SC_MAC
6797 {"SC_MAC", _SC_MAC},
6798#endif
Fred Drakec9680921999-12-13 16:37:25 +00006799#ifdef _SC_MAPPED_FILES
6800 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
6801#endif
6802#ifdef _SC_MAXPID
6803 {"SC_MAXPID", _SC_MAXPID},
6804#endif
6805#ifdef _SC_MB_LEN_MAX
6806 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
6807#endif
6808#ifdef _SC_MEMLOCK
6809 {"SC_MEMLOCK", _SC_MEMLOCK},
6810#endif
6811#ifdef _SC_MEMLOCK_RANGE
6812 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
6813#endif
6814#ifdef _SC_MEMORY_PROTECTION
6815 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
6816#endif
6817#ifdef _SC_MESSAGE_PASSING
6818 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
6819#endif
Fred Draked86ed291999-12-15 15:34:33 +00006820#ifdef _SC_MMAP_FIXED_ALIGNMENT
6821 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
6822#endif
Fred Drakec9680921999-12-13 16:37:25 +00006823#ifdef _SC_MQ_OPEN_MAX
6824 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
6825#endif
6826#ifdef _SC_MQ_PRIO_MAX
6827 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
6828#endif
Fred Draked86ed291999-12-15 15:34:33 +00006829#ifdef _SC_NACLS_MAX
6830 {"SC_NACLS_MAX", _SC_NACLS_MAX},
6831#endif
Fred Drakec9680921999-12-13 16:37:25 +00006832#ifdef _SC_NGROUPS_MAX
6833 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
6834#endif
6835#ifdef _SC_NL_ARGMAX
6836 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
6837#endif
6838#ifdef _SC_NL_LANGMAX
6839 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
6840#endif
6841#ifdef _SC_NL_MSGMAX
6842 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
6843#endif
6844#ifdef _SC_NL_NMAX
6845 {"SC_NL_NMAX", _SC_NL_NMAX},
6846#endif
6847#ifdef _SC_NL_SETMAX
6848 {"SC_NL_SETMAX", _SC_NL_SETMAX},
6849#endif
6850#ifdef _SC_NL_TEXTMAX
6851 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
6852#endif
6853#ifdef _SC_NPROCESSORS_CONF
6854 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
6855#endif
6856#ifdef _SC_NPROCESSORS_ONLN
6857 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
6858#endif
Fred Draked86ed291999-12-15 15:34:33 +00006859#ifdef _SC_NPROC_CONF
6860 {"SC_NPROC_CONF", _SC_NPROC_CONF},
6861#endif
6862#ifdef _SC_NPROC_ONLN
6863 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
6864#endif
Fred Drakec9680921999-12-13 16:37:25 +00006865#ifdef _SC_NZERO
6866 {"SC_NZERO", _SC_NZERO},
6867#endif
6868#ifdef _SC_OPEN_MAX
6869 {"SC_OPEN_MAX", _SC_OPEN_MAX},
6870#endif
6871#ifdef _SC_PAGESIZE
6872 {"SC_PAGESIZE", _SC_PAGESIZE},
6873#endif
6874#ifdef _SC_PAGE_SIZE
6875 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
6876#endif
6877#ifdef _SC_PASS_MAX
6878 {"SC_PASS_MAX", _SC_PASS_MAX},
6879#endif
6880#ifdef _SC_PHYS_PAGES
6881 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
6882#endif
6883#ifdef _SC_PII
6884 {"SC_PII", _SC_PII},
6885#endif
6886#ifdef _SC_PII_INTERNET
6887 {"SC_PII_INTERNET", _SC_PII_INTERNET},
6888#endif
6889#ifdef _SC_PII_INTERNET_DGRAM
6890 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
6891#endif
6892#ifdef _SC_PII_INTERNET_STREAM
6893 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
6894#endif
6895#ifdef _SC_PII_OSI
6896 {"SC_PII_OSI", _SC_PII_OSI},
6897#endif
6898#ifdef _SC_PII_OSI_CLTS
6899 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
6900#endif
6901#ifdef _SC_PII_OSI_COTS
6902 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
6903#endif
6904#ifdef _SC_PII_OSI_M
6905 {"SC_PII_OSI_M", _SC_PII_OSI_M},
6906#endif
6907#ifdef _SC_PII_SOCKET
6908 {"SC_PII_SOCKET", _SC_PII_SOCKET},
6909#endif
6910#ifdef _SC_PII_XTI
6911 {"SC_PII_XTI", _SC_PII_XTI},
6912#endif
6913#ifdef _SC_POLL
6914 {"SC_POLL", _SC_POLL},
6915#endif
6916#ifdef _SC_PRIORITIZED_IO
6917 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
6918#endif
6919#ifdef _SC_PRIORITY_SCHEDULING
6920 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
6921#endif
6922#ifdef _SC_REALTIME_SIGNALS
6923 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
6924#endif
6925#ifdef _SC_RE_DUP_MAX
6926 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
6927#endif
6928#ifdef _SC_RTSIG_MAX
6929 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
6930#endif
6931#ifdef _SC_SAVED_IDS
6932 {"SC_SAVED_IDS", _SC_SAVED_IDS},
6933#endif
6934#ifdef _SC_SCHAR_MAX
6935 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
6936#endif
6937#ifdef _SC_SCHAR_MIN
6938 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
6939#endif
6940#ifdef _SC_SELECT
6941 {"SC_SELECT", _SC_SELECT},
6942#endif
6943#ifdef _SC_SEMAPHORES
6944 {"SC_SEMAPHORES", _SC_SEMAPHORES},
6945#endif
6946#ifdef _SC_SEM_NSEMS_MAX
6947 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
6948#endif
6949#ifdef _SC_SEM_VALUE_MAX
6950 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
6951#endif
6952#ifdef _SC_SHARED_MEMORY_OBJECTS
6953 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
6954#endif
6955#ifdef _SC_SHRT_MAX
6956 {"SC_SHRT_MAX", _SC_SHRT_MAX},
6957#endif
6958#ifdef _SC_SHRT_MIN
6959 {"SC_SHRT_MIN", _SC_SHRT_MIN},
6960#endif
6961#ifdef _SC_SIGQUEUE_MAX
6962 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
6963#endif
6964#ifdef _SC_SIGRT_MAX
6965 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
6966#endif
6967#ifdef _SC_SIGRT_MIN
6968 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
6969#endif
Fred Draked86ed291999-12-15 15:34:33 +00006970#ifdef _SC_SOFTPOWER
6971 {"SC_SOFTPOWER", _SC_SOFTPOWER},
6972#endif
Fred Drakec9680921999-12-13 16:37:25 +00006973#ifdef _SC_SPLIT_CACHE
6974 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
6975#endif
6976#ifdef _SC_SSIZE_MAX
6977 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
6978#endif
6979#ifdef _SC_STACK_PROT
6980 {"SC_STACK_PROT", _SC_STACK_PROT},
6981#endif
6982#ifdef _SC_STREAM_MAX
6983 {"SC_STREAM_MAX", _SC_STREAM_MAX},
6984#endif
6985#ifdef _SC_SYNCHRONIZED_IO
6986 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
6987#endif
6988#ifdef _SC_THREADS
6989 {"SC_THREADS", _SC_THREADS},
6990#endif
6991#ifdef _SC_THREAD_ATTR_STACKADDR
6992 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
6993#endif
6994#ifdef _SC_THREAD_ATTR_STACKSIZE
6995 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
6996#endif
6997#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
6998 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
6999#endif
7000#ifdef _SC_THREAD_KEYS_MAX
7001 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
7002#endif
7003#ifdef _SC_THREAD_PRIORITY_SCHEDULING
7004 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
7005#endif
7006#ifdef _SC_THREAD_PRIO_INHERIT
7007 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
7008#endif
7009#ifdef _SC_THREAD_PRIO_PROTECT
7010 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
7011#endif
7012#ifdef _SC_THREAD_PROCESS_SHARED
7013 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
7014#endif
7015#ifdef _SC_THREAD_SAFE_FUNCTIONS
7016 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
7017#endif
7018#ifdef _SC_THREAD_STACK_MIN
7019 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
7020#endif
7021#ifdef _SC_THREAD_THREADS_MAX
7022 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
7023#endif
7024#ifdef _SC_TIMERS
7025 {"SC_TIMERS", _SC_TIMERS},
7026#endif
7027#ifdef _SC_TIMER_MAX
7028 {"SC_TIMER_MAX", _SC_TIMER_MAX},
7029#endif
7030#ifdef _SC_TTY_NAME_MAX
7031 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
7032#endif
7033#ifdef _SC_TZNAME_MAX
7034 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
7035#endif
7036#ifdef _SC_T_IOV_MAX
7037 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
7038#endif
7039#ifdef _SC_UCHAR_MAX
7040 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
7041#endif
7042#ifdef _SC_UINT_MAX
7043 {"SC_UINT_MAX", _SC_UINT_MAX},
7044#endif
7045#ifdef _SC_UIO_MAXIOV
7046 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
7047#endif
7048#ifdef _SC_ULONG_MAX
7049 {"SC_ULONG_MAX", _SC_ULONG_MAX},
7050#endif
7051#ifdef _SC_USHRT_MAX
7052 {"SC_USHRT_MAX", _SC_USHRT_MAX},
7053#endif
7054#ifdef _SC_VERSION
7055 {"SC_VERSION", _SC_VERSION},
7056#endif
7057#ifdef _SC_WORD_BIT
7058 {"SC_WORD_BIT", _SC_WORD_BIT},
7059#endif
7060#ifdef _SC_XBS5_ILP32_OFF32
7061 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
7062#endif
7063#ifdef _SC_XBS5_ILP32_OFFBIG
7064 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
7065#endif
7066#ifdef _SC_XBS5_LP64_OFF64
7067 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
7068#endif
7069#ifdef _SC_XBS5_LPBIG_OFFBIG
7070 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
7071#endif
7072#ifdef _SC_XOPEN_CRYPT
7073 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
7074#endif
7075#ifdef _SC_XOPEN_ENH_I18N
7076 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
7077#endif
7078#ifdef _SC_XOPEN_LEGACY
7079 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
7080#endif
7081#ifdef _SC_XOPEN_REALTIME
7082 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
7083#endif
7084#ifdef _SC_XOPEN_REALTIME_THREADS
7085 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
7086#endif
7087#ifdef _SC_XOPEN_SHM
7088 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
7089#endif
7090#ifdef _SC_XOPEN_UNIX
7091 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
7092#endif
7093#ifdef _SC_XOPEN_VERSION
7094 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
7095#endif
7096#ifdef _SC_XOPEN_XCU_VERSION
7097 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
7098#endif
7099#ifdef _SC_XOPEN_XPG2
7100 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
7101#endif
7102#ifdef _SC_XOPEN_XPG3
7103 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
7104#endif
7105#ifdef _SC_XOPEN_XPG4
7106 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
7107#endif
7108};
7109
7110static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007111conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007112{
7113 return conv_confname(arg, valuep, posix_constants_sysconf,
7114 sizeof(posix_constants_sysconf)
7115 / sizeof(struct constdef));
7116}
7117
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007118PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007119"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007120Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007121
7122static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007123posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007124{
7125 PyObject *result = NULL;
7126 int name;
7127
7128 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
7129 int value;
7130
7131 errno = 0;
7132 value = sysconf(name);
7133 if (value == -1 && errno != 0)
7134 posix_error();
7135 else
7136 result = PyInt_FromLong(value);
7137 }
7138 return result;
7139}
7140#endif
7141
7142
Fred Drakebec628d1999-12-15 18:31:10 +00007143/* This code is used to ensure that the tables of configuration value names
7144 * are in sorted order as required by conv_confname(), and also to build the
7145 * the exported dictionaries that are used to publish information about the
7146 * names available on the host platform.
7147 *
7148 * Sorting the table at runtime ensures that the table is properly ordered
7149 * when used, even for platforms we're not able to test on. It also makes
7150 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00007151 */
Fred Drakebec628d1999-12-15 18:31:10 +00007152
7153static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007154cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00007155{
7156 const struct constdef *c1 =
7157 (const struct constdef *) v1;
7158 const struct constdef *c2 =
7159 (const struct constdef *) v2;
7160
7161 return strcmp(c1->name, c2->name);
7162}
7163
7164static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007165setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00007166 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007167{
Fred Drakebec628d1999-12-15 18:31:10 +00007168 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00007169 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00007170
7171 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
7172 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00007173 if (d == NULL)
7174 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007175
Barry Warsaw3155db32000-04-13 15:20:40 +00007176 for (i=0; i < tablesize; ++i) {
7177 PyObject *o = PyInt_FromLong(table[i].value);
7178 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
7179 Py_XDECREF(o);
7180 Py_DECREF(d);
7181 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007182 }
Barry Warsaw3155db32000-04-13 15:20:40 +00007183 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00007184 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00007185 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00007186}
7187
Fred Drakebec628d1999-12-15 18:31:10 +00007188/* Return -1 on failure, 0 on success. */
7189static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007190setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007191{
7192#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00007193 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00007194 sizeof(posix_constants_pathconf)
7195 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007196 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007197 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007198#endif
7199#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00007200 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00007201 sizeof(posix_constants_confstr)
7202 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007203 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007204 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007205#endif
7206#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00007207 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00007208 sizeof(posix_constants_sysconf)
7209 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007210 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007211 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007212#endif
Fred Drakebec628d1999-12-15 18:31:10 +00007213 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00007214}
Fred Draked86ed291999-12-15 15:34:33 +00007215
7216
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007217PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007218"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007219Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007220in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007221
7222static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007223posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007224{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007225 abort();
7226 /*NOTREACHED*/
7227 Py_FatalError("abort() called from Python code didn't abort!");
7228 return NULL;
7229}
Fred Drakebec628d1999-12-15 18:31:10 +00007230
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007231#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007232PyDoc_STRVAR(win32_startfile__doc__,
7233"startfile(filepath) - Start a file with its associated application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007234\n\
7235This acts like double-clicking the file in Explorer, or giving the file\n\
7236name as an argument to the DOS \"start\" command: the file is opened\n\
7237with whatever application (if any) its extension is associated.\n\
7238\n\
7239startfile returns as soon as the associated application is launched.\n\
7240There is no option to wait for the application to close, and no way\n\
7241to retrieve the application's exit status.\n\
7242\n\
7243The filepath is relative to the current directory. If you want to use\n\
7244an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007245the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00007246
7247static PyObject *
7248win32_startfile(PyObject *self, PyObject *args)
7249{
7250 char *filepath;
7251 HINSTANCE rc;
Georg Brandl402b53d2005-09-14 20:51:40 +00007252 if (!PyArg_ParseTuple(args, "et:startfile",
7253 Py_FileSystemDefaultEncoding, &filepath))
Tim Petersf58a7aa2000-09-22 10:05:54 +00007254 return NULL;
7255 Py_BEGIN_ALLOW_THREADS
7256 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
7257 Py_END_ALLOW_THREADS
7258 if (rc <= (HINSTANCE)32)
7259 return win32_error("startfile", filepath);
7260 Py_INCREF(Py_None);
7261 return Py_None;
7262}
7263#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007264
Martin v. Löwis438b5342002-12-27 10:16:42 +00007265#ifdef HAVE_GETLOADAVG
7266PyDoc_STRVAR(posix_getloadavg__doc__,
7267"getloadavg() -> (float, float, float)\n\n\
7268Return the number of processes in the system run queue averaged over\n\
7269the last 1, 5, and 15 minutes or raises OSError if the load average\n\
7270was unobtainable");
7271
7272static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007273posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00007274{
7275 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00007276 if (getloadavg(loadavg, 3)!=3) {
7277 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
7278 return NULL;
7279 } else
7280 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
7281}
7282#endif
7283
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007284#ifdef MS_WINDOWS
7285
7286PyDoc_STRVAR(win32_urandom__doc__,
7287"urandom(n) -> str\n\n\
7288Return a string of n random bytes suitable for cryptographic use.");
7289
7290typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
7291 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
7292 DWORD dwFlags );
7293typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
7294 BYTE *pbBuffer );
7295
7296static CRYPTGENRANDOM pCryptGenRandom = NULL;
7297static HCRYPTPROV hCryptProv = 0;
7298
Tim Peters4ad82172004-08-30 17:02:04 +00007299static PyObject*
7300win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007301{
Tim Petersd3115382004-08-30 17:36:46 +00007302 int howMany;
7303 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007304
Tim Peters4ad82172004-08-30 17:02:04 +00007305 /* Read arguments */
Tim Peters9b279a82004-08-30 17:10:53 +00007306 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
Tim Peters4ad82172004-08-30 17:02:04 +00007307 return NULL;
Tim Peters51eba612004-08-30 17:08:02 +00007308 if (howMany < 0)
7309 return PyErr_Format(PyExc_ValueError,
7310 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007311
Tim Peters4ad82172004-08-30 17:02:04 +00007312 if (hCryptProv == 0) {
7313 HINSTANCE hAdvAPI32 = NULL;
7314 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007315
Tim Peters4ad82172004-08-30 17:02:04 +00007316 /* Obtain handle to the DLL containing CryptoAPI
7317 This should not fail */
7318 hAdvAPI32 = GetModuleHandle("advapi32.dll");
7319 if(hAdvAPI32 == NULL)
7320 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007321
Tim Peters4ad82172004-08-30 17:02:04 +00007322 /* Obtain pointers to the CryptoAPI functions
7323 This will fail on some early versions of Win95 */
7324 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
7325 hAdvAPI32,
7326 "CryptAcquireContextA");
7327 if (pCryptAcquireContext == NULL)
7328 return PyErr_Format(PyExc_NotImplementedError,
7329 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007330
Tim Peters4ad82172004-08-30 17:02:04 +00007331 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
7332 hAdvAPI32, "CryptGenRandom");
7333 if (pCryptAcquireContext == NULL)
7334 return PyErr_Format(PyExc_NotImplementedError,
7335 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007336
Tim Peters4ad82172004-08-30 17:02:04 +00007337 /* Acquire context */
7338 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
7339 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
7340 return win32_error("CryptAcquireContext", NULL);
7341 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007342
Tim Peters4ad82172004-08-30 17:02:04 +00007343 /* Allocate bytes */
Tim Petersd3115382004-08-30 17:36:46 +00007344 result = PyString_FromStringAndSize(NULL, howMany);
7345 if (result != NULL) {
7346 /* Get random data */
7347 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
7348 PyString_AS_STRING(result))) {
7349 Py_DECREF(result);
7350 return win32_error("CryptGenRandom", NULL);
7351 }
Tim Peters4ad82172004-08-30 17:02:04 +00007352 }
Tim Petersd3115382004-08-30 17:36:46 +00007353 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007354}
7355#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007356
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007357static PyMethodDef posix_methods[] = {
7358 {"access", posix_access, METH_VARARGS, posix_access__doc__},
7359#ifdef HAVE_TTYNAME
7360 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
7361#endif
7362 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
7363 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007364#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007365 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007366#endif /* HAVE_CHOWN */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007367#ifdef HAVE_LCHOWN
7368 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
7369#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00007370#ifdef HAVE_CHROOT
7371 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
7372#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007373#ifdef HAVE_CTERMID
Neal Norwitze241ce82003-02-17 18:17:05 +00007374 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007375#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00007376#ifdef HAVE_GETCWD
Neal Norwitze241ce82003-02-17 18:17:05 +00007377 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Walter Dörwald3b918c32002-11-21 20:18:46 +00007378#ifdef Py_USING_UNICODE
Neal Norwitze241ce82003-02-17 18:17:05 +00007379 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00007380#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00007381#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007382#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007383 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007384#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007385 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
7386 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
7387 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007388#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007389 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007390#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007391#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007392 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007393#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007394 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
7395 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
7396 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007397 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007398#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007399 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007400#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007401#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007402 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007403#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007404 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007405#ifdef HAVE_UNAME
Neal Norwitze241ce82003-02-17 18:17:05 +00007406 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007407#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007408 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
7409 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
7410 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007411#ifdef HAVE_TIMES
Neal Norwitze241ce82003-02-17 18:17:05 +00007412 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007413#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007414 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007415#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007416 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
7417 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007418#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00007419#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007420 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
7421 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00007422#if defined(PYOS_OS2)
7423 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
7424 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
7425#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00007426#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007427#ifdef HAVE_FORK1
Neal Norwitze241ce82003-02-17 18:17:05 +00007428 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007429#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007430#ifdef HAVE_FORK
Neal Norwitze241ce82003-02-17 18:17:05 +00007431 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007432#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007433#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Neal Norwitze241ce82003-02-17 18:17:05 +00007434 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007435#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007436#ifdef HAVE_FORKPTY
Neal Norwitze241ce82003-02-17 18:17:05 +00007437 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00007438#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007439#ifdef HAVE_GETEGID
Neal Norwitze241ce82003-02-17 18:17:05 +00007440 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007441#endif /* HAVE_GETEGID */
7442#ifdef HAVE_GETEUID
Neal Norwitze241ce82003-02-17 18:17:05 +00007443 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007444#endif /* HAVE_GETEUID */
7445#ifdef HAVE_GETGID
Neal Norwitze241ce82003-02-17 18:17:05 +00007446 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007447#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00007448#ifdef HAVE_GETGROUPS
Neal Norwitze241ce82003-02-17 18:17:05 +00007449 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007450#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007451 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007452#ifdef HAVE_GETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00007453 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007454#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007455#ifdef HAVE_GETPPID
Neal Norwitze241ce82003-02-17 18:17:05 +00007456 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007457#endif /* HAVE_GETPPID */
7458#ifdef HAVE_GETUID
Neal Norwitze241ce82003-02-17 18:17:05 +00007459 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007460#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007461#ifdef HAVE_GETLOGIN
Neal Norwitze241ce82003-02-17 18:17:05 +00007462 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00007463#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00007464#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007465 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007466#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007467#ifdef HAVE_KILLPG
7468 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
7469#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00007470#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007471 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00007472#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007473#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007474 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007475#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00007476 {"popen2", win32_popen2, METH_VARARGS},
7477 {"popen3", win32_popen3, METH_VARARGS},
7478 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00007479 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007480#else
7481#if defined(PYOS_OS2) && defined(PYCC_GCC)
7482 {"popen2", os2emx_popen2, METH_VARARGS},
7483 {"popen3", os2emx_popen3, METH_VARARGS},
7484 {"popen4", os2emx_popen4, METH_VARARGS},
7485#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00007486#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007487#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007488#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007489 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007490#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007491#ifdef HAVE_SETEUID
7492 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
7493#endif /* HAVE_SETEUID */
7494#ifdef HAVE_SETEGID
7495 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
7496#endif /* HAVE_SETEGID */
7497#ifdef HAVE_SETREUID
7498 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
7499#endif /* HAVE_SETREUID */
7500#ifdef HAVE_SETREGID
7501 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
7502#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007503#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007504 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007505#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007506#ifdef HAVE_SETGROUPS
7507 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
7508#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00007509#ifdef HAVE_GETPGID
7510 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
7511#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007512#ifdef HAVE_SETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00007513 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007514#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007515#ifdef HAVE_WAIT
Neal Norwitze241ce82003-02-17 18:17:05 +00007516 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007517#endif /* HAVE_WAIT */
Tim Petersab034fa2002-02-01 11:27:43 +00007518#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007519 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007520#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007521#ifdef HAVE_GETSID
7522 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
7523#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007524#ifdef HAVE_SETSID
Neal Norwitze241ce82003-02-17 18:17:05 +00007525 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007526#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007527#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007528 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007529#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007530#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007531 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007532#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007533#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007534 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007535#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007536 {"open", posix_open, METH_VARARGS, posix_open__doc__},
7537 {"close", posix_close, METH_VARARGS, posix_close__doc__},
7538 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
7539 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
7540 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
7541 {"read", posix_read, METH_VARARGS, posix_read__doc__},
7542 {"write", posix_write, METH_VARARGS, posix_write__doc__},
7543 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
7544 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00007545 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007546#ifdef HAVE_PIPE
Neal Norwitze241ce82003-02-17 18:17:05 +00007547 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007548#endif
7549#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007550 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007551#endif
Neal Norwitz11690112002-07-30 01:08:28 +00007552#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007553 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
7554#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007555#ifdef HAVE_DEVICE_MACROS
7556 {"major", posix_major, METH_VARARGS, posix_major__doc__},
7557 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
7558 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
7559#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007560#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007561 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007562#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007563#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007564 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007565#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007566#ifdef HAVE_UNSETENV
7567 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
7568#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00007569#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007570 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00007571#endif
Fred Drake4d1e64b2002-04-15 19:40:07 +00007572#ifdef HAVE_FCHDIR
7573 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
7574#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00007575#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007576 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007577#endif
7578#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007579 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007580#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00007581#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00007582#ifdef WCOREDUMP
7583 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
7584#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007585#ifdef WIFCONTINUED
7586 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
7587#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00007588#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007589 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007590#endif /* WIFSTOPPED */
7591#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007592 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007593#endif /* WIFSIGNALED */
7594#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007595 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007596#endif /* WIFEXITED */
7597#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007598 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007599#endif /* WEXITSTATUS */
7600#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007601 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007602#endif /* WTERMSIG */
7603#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007604 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007605#endif /* WSTOPSIG */
7606#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007607#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007608 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007609#endif
7610#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007611 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007612#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00007613#ifdef HAVE_TMPFILE
Neal Norwitze241ce82003-02-17 18:17:05 +00007614 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007615#endif
7616#ifdef HAVE_TEMPNAM
7617 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
7618#endif
7619#ifdef HAVE_TMPNAM
Neal Norwitze241ce82003-02-17 18:17:05 +00007620 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007621#endif
Fred Drakec9680921999-12-13 16:37:25 +00007622#ifdef HAVE_CONFSTR
7623 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
7624#endif
7625#ifdef HAVE_SYSCONF
7626 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
7627#endif
7628#ifdef HAVE_FPATHCONF
7629 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
7630#endif
7631#ifdef HAVE_PATHCONF
7632 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
7633#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007634 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007635#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00007636 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
7637#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007638#ifdef HAVE_GETLOADAVG
Neal Norwitze241ce82003-02-17 18:17:05 +00007639 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00007640#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007641 #ifdef MS_WINDOWS
7642 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
7643 #endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007644 {NULL, NULL} /* Sentinel */
7645};
7646
7647
Barry Warsaw4a342091996-12-19 23:50:02 +00007648static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007649ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00007650{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007651 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00007652}
7653
Guido van Rossumd48f2521997-12-05 22:19:34 +00007654#if defined(PYOS_OS2)
7655/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007656static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007657{
7658 APIRET rc;
7659 ULONG values[QSV_MAX+1];
7660 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00007661 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00007662
7663 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00007664 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007665 Py_END_ALLOW_THREADS
7666
7667 if (rc != NO_ERROR) {
7668 os2_error(rc);
7669 return -1;
7670 }
7671
Fred Drake4d1e64b2002-04-15 19:40:07 +00007672 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
7673 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
7674 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
7675 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
7676 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
7677 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
7678 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007679
7680 switch (values[QSV_VERSION_MINOR]) {
7681 case 0: ver = "2.00"; break;
7682 case 10: ver = "2.10"; break;
7683 case 11: ver = "2.11"; break;
7684 case 30: ver = "3.00"; break;
7685 case 40: ver = "4.00"; break;
7686 case 50: ver = "5.00"; break;
7687 default:
Tim Peters885d4572001-11-28 20:27:42 +00007688 PyOS_snprintf(tmp, sizeof(tmp),
7689 "%d-%d", values[QSV_VERSION_MAJOR],
7690 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007691 ver = &tmp[0];
7692 }
7693
7694 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007695 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007696 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007697
7698 /* Add Indicator of Which Drive was Used to Boot the System */
7699 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
7700 tmp[1] = ':';
7701 tmp[2] = '\0';
7702
Fred Drake4d1e64b2002-04-15 19:40:07 +00007703 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007704}
7705#endif
7706
Barry Warsaw4a342091996-12-19 23:50:02 +00007707static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007708all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00007709{
Guido van Rossum94f6f721999-01-06 18:42:14 +00007710#ifdef F_OK
7711 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007712#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007713#ifdef R_OK
7714 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007715#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007716#ifdef W_OK
7717 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007718#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007719#ifdef X_OK
7720 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007721#endif
Fred Drakec9680921999-12-13 16:37:25 +00007722#ifdef NGROUPS_MAX
7723 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
7724#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007725#ifdef TMP_MAX
7726 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
7727#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007728#ifdef WCONTINUED
7729 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
7730#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007731#ifdef WNOHANG
7732 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007733#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007734#ifdef WUNTRACED
7735 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
7736#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007737#ifdef O_RDONLY
7738 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
7739#endif
7740#ifdef O_WRONLY
7741 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
7742#endif
7743#ifdef O_RDWR
7744 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
7745#endif
7746#ifdef O_NDELAY
7747 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
7748#endif
7749#ifdef O_NONBLOCK
7750 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
7751#endif
7752#ifdef O_APPEND
7753 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
7754#endif
7755#ifdef O_DSYNC
7756 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
7757#endif
7758#ifdef O_RSYNC
7759 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
7760#endif
7761#ifdef O_SYNC
7762 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
7763#endif
7764#ifdef O_NOCTTY
7765 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
7766#endif
7767#ifdef O_CREAT
7768 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
7769#endif
7770#ifdef O_EXCL
7771 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
7772#endif
7773#ifdef O_TRUNC
7774 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
7775#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00007776#ifdef O_BINARY
7777 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
7778#endif
7779#ifdef O_TEXT
7780 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
7781#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007782#ifdef O_LARGEFILE
7783 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
7784#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00007785#ifdef O_SHLOCK
7786 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
7787#endif
7788#ifdef O_EXLOCK
7789 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
7790#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007791
Tim Peters5aa91602002-01-30 05:46:57 +00007792/* MS Windows */
7793#ifdef O_NOINHERIT
7794 /* Don't inherit in child processes. */
7795 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
7796#endif
7797#ifdef _O_SHORT_LIVED
7798 /* Optimize for short life (keep in memory). */
7799 /* MS forgot to define this one with a non-underscore form too. */
7800 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
7801#endif
7802#ifdef O_TEMPORARY
7803 /* Automatically delete when last handle is closed. */
7804 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
7805#endif
7806#ifdef O_RANDOM
7807 /* Optimize for random access. */
7808 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
7809#endif
7810#ifdef O_SEQUENTIAL
7811 /* Optimize for sequential access. */
7812 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
7813#endif
7814
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007815/* GNU extensions. */
7816#ifdef O_DIRECT
7817 /* Direct disk access. */
7818 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
7819#endif
7820#ifdef O_DIRECTORY
7821 /* Must be a directory. */
7822 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
7823#endif
7824#ifdef O_NOFOLLOW
7825 /* Do not follow links. */
7826 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
7827#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00007828
Barry Warsaw5676bd12003-01-07 20:57:09 +00007829 /* These come from sysexits.h */
7830#ifdef EX_OK
7831 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007832#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007833#ifdef EX_USAGE
7834 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007835#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007836#ifdef EX_DATAERR
7837 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007838#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007839#ifdef EX_NOINPUT
7840 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007841#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007842#ifdef EX_NOUSER
7843 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007844#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007845#ifdef EX_NOHOST
7846 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007847#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007848#ifdef EX_UNAVAILABLE
7849 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007850#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007851#ifdef EX_SOFTWARE
7852 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007853#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007854#ifdef EX_OSERR
7855 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007856#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007857#ifdef EX_OSFILE
7858 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007859#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007860#ifdef EX_CANTCREAT
7861 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007862#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007863#ifdef EX_IOERR
7864 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007865#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007866#ifdef EX_TEMPFAIL
7867 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007868#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007869#ifdef EX_PROTOCOL
7870 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007871#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007872#ifdef EX_NOPERM
7873 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007874#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007875#ifdef EX_CONFIG
7876 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007877#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007878#ifdef EX_NOTFOUND
7879 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007880#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007881
Guido van Rossum246bc171999-02-01 23:54:31 +00007882#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007883#if defined(PYOS_OS2) && defined(PYCC_GCC)
7884 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
7885 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
7886 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
7887 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
7888 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
7889 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
7890 if (ins(d, "P_PM", (long)P_PM)) return -1;
7891 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
7892 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
7893 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
7894 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
7895 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
7896 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
7897 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
7898 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
7899 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
7900 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
7901 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
7902 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
7903 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
7904#else
Guido van Rossum7d385291999-02-16 19:38:04 +00007905 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
7906 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
7907 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
7908 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
7909 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00007910#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007911#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00007912
Guido van Rossumd48f2521997-12-05 22:19:34 +00007913#if defined(PYOS_OS2)
7914 if (insertvalues(d)) return -1;
7915#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007916 return 0;
7917}
7918
7919
Tim Peters5aa91602002-01-30 05:46:57 +00007920#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007921#define INITFUNC initnt
7922#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007923
7924#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007925#define INITFUNC initos2
7926#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007927
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007928#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007929#define INITFUNC initposix
7930#define MODNAME "posix"
7931#endif
7932
Mark Hammondfe51c6d2002-08-02 02:27:13 +00007933PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007934INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00007935{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007936 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00007937
Fred Drake4d1e64b2002-04-15 19:40:07 +00007938 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007939 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00007940 posix__doc__);
Tim Peters5aa91602002-01-30 05:46:57 +00007941
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007942 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007943 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00007944 Py_XINCREF(v);
7945 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007946 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00007947 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00007948
Fred Drake4d1e64b2002-04-15 19:40:07 +00007949 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00007950 return;
7951
Fred Drake4d1e64b2002-04-15 19:40:07 +00007952 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00007953 return;
7954
Fred Drake4d1e64b2002-04-15 19:40:07 +00007955 Py_INCREF(PyExc_OSError);
7956 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00007957
Guido van Rossumb3d39562000-01-31 18:41:26 +00007958#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00007959 if (posix_putenv_garbage == NULL)
7960 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00007961#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007962
Guido van Rossum14648392001-12-08 18:02:58 +00007963 stat_result_desc.name = MODNAME ".stat_result";
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007964 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
7965 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
7966 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007967 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007968 structseq_new = StatResultType.tp_new;
7969 StatResultType.tp_new = statresult_new;
Fred Drake4d1e64b2002-04-15 19:40:07 +00007970 Py_INCREF((PyObject*) &StatResultType);
7971 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007972
Guido van Rossum14648392001-12-08 18:02:58 +00007973 statvfs_result_desc.name = MODNAME ".statvfs_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007974 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Fred Drake4d1e64b2002-04-15 19:40:07 +00007975 Py_INCREF((PyObject*) &StatVFSResultType);
7976 PyModule_AddObject(m, "statvfs_result",
7977 (PyObject*) &StatVFSResultType);
Guido van Rossumb6775db1994-08-01 11:34:53 +00007978}