blob: a08058f6f1f58c5646c4cf134e1eb2faf7425cfc [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
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001169 return PyBool_FromLong(res == 0);
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001170 }
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);
Neal Norwitz3efd0a12005-09-19 06:45:53 +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)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001225 return posix_error();
1226 return PyString_FromString(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001227}
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)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001247 return posix_error();
1248 return PyString_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001249}
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)) {
Georg Brandla13c2442005-11-22 19:30:31 +00004915 if (!PyLong_Check(elem)) {
4916 PyErr_SetString(PyExc_TypeError,
4917 "groups must be integers");
4918 Py_DECREF(elem);
4919 return NULL;
4920 } else {
4921 unsigned long x = PyLong_AsUnsignedLong(elem);
4922 if (PyErr_Occurred()) {
4923 PyErr_SetString(PyExc_TypeError,
4924 "group id too big");
4925 Py_DECREF(elem);
4926 return NULL;
4927 }
4928 grouplist[i] = x;
4929 /* read back the value to see if it fitted in gid_t */
4930 if (grouplist[i] != x) {
4931 PyErr_SetString(PyExc_TypeError,
4932 "group id too big");
4933 Py_DECREF(elem);
4934 return NULL;
4935 }
4936 }
4937 } else {
4938 long x = PyInt_AsLong(elem);
4939 grouplist[i] = x;
4940 if (grouplist[i] != x) {
4941 PyErr_SetString(PyExc_TypeError,
4942 "group id too big");
4943 Py_DECREF(elem);
4944 return NULL;
4945 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004946 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00004947 Py_DECREF(elem);
4948 }
4949
4950 if (setgroups(len, grouplist) < 0)
4951 return posix_error();
4952 Py_INCREF(Py_None);
4953 return Py_None;
4954}
4955#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004956
Guido van Rossumb6775db1994-08-01 11:34:53 +00004957#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004958PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004959"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004960Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004961
Barry Warsaw53699e91996-12-10 23:23:01 +00004962static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004963posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00004964{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004965 int pid, options;
4966#ifdef UNION_WAIT
4967 union wait status;
4968#define status_i (status.w_status)
4969#else
4970 int status;
4971#define status_i status
4972#endif
4973 status_i = 0;
4974
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004975 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00004976 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00004977 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00004978 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00004979 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00004980 if (pid == -1)
4981 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00004982 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00004983 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00004984}
4985
Tim Petersab034fa2002-02-01 11:27:43 +00004986#elif defined(HAVE_CWAIT)
4987
4988/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004989PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004990"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004991"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00004992
4993static PyObject *
4994posix_waitpid(PyObject *self, PyObject *args)
4995{
4996 int pid, options;
4997 int status;
4998
4999 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
5000 return NULL;
5001 Py_BEGIN_ALLOW_THREADS
5002 pid = _cwait(&status, pid, options);
5003 Py_END_ALLOW_THREADS
5004 if (pid == -1)
5005 return posix_error();
5006 else
5007 /* shift the status left a byte so this is more like the
5008 POSIX waitpid */
5009 return Py_BuildValue("ii", pid, status << 8);
5010}
5011#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005012
Guido van Rossumad0ee831995-03-01 10:34:45 +00005013#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005014PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005015"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005016Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005017
Barry Warsaw53699e91996-12-10 23:23:01 +00005018static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005019posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00005020{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005021 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005022#ifdef UNION_WAIT
5023 union wait status;
5024#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00005025#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005026 int status;
5027#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00005028#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00005029
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005030 status_i = 0;
5031 Py_BEGIN_ALLOW_THREADS
5032 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00005033 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00005034 if (pid == -1)
5035 return posix_error();
5036 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005037 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005038#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00005039}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005040#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005041
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005042
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005043PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005044"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005045Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005046
Barry Warsaw53699e91996-12-10 23:23:01 +00005047static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005048posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005049{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005050#ifdef HAVE_LSTAT
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005051 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005052#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005053#ifdef MS_WINDOWS
Mark Hammond7edd0a92003-08-06 02:46:58 +00005054 return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", _wstati64);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005055#else
5056 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
5057#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005058#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005059}
5060
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005061
Guido van Rossumb6775db1994-08-01 11:34:53 +00005062#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005063PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005064"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005065Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005066
Barry Warsaw53699e91996-12-10 23:23:01 +00005067static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005068posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005069{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005070 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00005071 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005072 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005073 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005074 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005075 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00005076 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00005077 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005078 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00005079 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00005080 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005081}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005082#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005083
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005084
Guido van Rossumb6775db1994-08-01 11:34:53 +00005085#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005086PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005087"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00005088Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005089
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005090static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005091posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005092{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005093 return posix_2str(args, "etet:symlink", symlink, NULL, NULL);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005094}
5095#endif /* HAVE_SYMLINK */
5096
5097
5098#ifdef HAVE_TIMES
5099#ifndef HZ
5100#define HZ 60 /* Universal constant :-) */
5101#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00005102
Guido van Rossumd48f2521997-12-05 22:19:34 +00005103#if defined(PYCC_VACPP) && defined(PYOS_OS2)
5104static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005105system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005106{
5107 ULONG value = 0;
5108
5109 Py_BEGIN_ALLOW_THREADS
5110 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
5111 Py_END_ALLOW_THREADS
5112
5113 return value;
5114}
5115
5116static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005117posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005118{
Guido van Rossumd48f2521997-12-05 22:19:34 +00005119 /* Currently Only Uptime is Provided -- Others Later */
5120 return Py_BuildValue("ddddd",
5121 (double)0 /* t.tms_utime / HZ */,
5122 (double)0 /* t.tms_stime / HZ */,
5123 (double)0 /* t.tms_cutime / HZ */,
5124 (double)0 /* t.tms_cstime / HZ */,
5125 (double)system_uptime() / 1000);
5126}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005127#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00005128static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005129posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00005130{
5131 struct tms t;
5132 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +00005133 errno = 0;
5134 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00005135 if (c == (clock_t) -1)
5136 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005137 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00005138 (double)t.tms_utime / HZ,
5139 (double)t.tms_stime / HZ,
5140 (double)t.tms_cutime / HZ,
5141 (double)t.tms_cstime / HZ,
5142 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00005143}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005144#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005145#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005146
5147
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005148#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005149#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00005150static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005151posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005152{
5153 FILETIME create, exit, kernel, user;
5154 HANDLE hProc;
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005155 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00005156 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
5157 /* The fields of a FILETIME structure are the hi and lo part
5158 of a 64-bit value expressed in 100 nanosecond units.
5159 1e7 is one second in such units; 1e-7 the inverse.
5160 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
5161 */
Barry Warsaw53699e91996-12-10 23:23:01 +00005162 return Py_BuildValue(
5163 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00005164 (double)(kernel.dwHighDateTime*429.4967296 +
5165 kernel.dwLowDateTime*1e-7),
5166 (double)(user.dwHighDateTime*429.4967296 +
5167 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00005168 (double)0,
5169 (double)0,
5170 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005171}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005172#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005173
5174#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005175PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005176"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005177Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005178#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005179
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005180
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00005181#ifdef HAVE_GETSID
5182PyDoc_STRVAR(posix_getsid__doc__,
5183"getsid(pid) -> sid\n\n\
5184Call the system call getsid().");
5185
5186static PyObject *
5187posix_getsid(PyObject *self, PyObject *args)
5188{
5189 int pid, sid;
5190 if (!PyArg_ParseTuple(args, "i:getsid", &pid))
5191 return NULL;
5192 sid = getsid(pid);
5193 if (sid < 0)
5194 return posix_error();
5195 return PyInt_FromLong((long)sid);
5196}
5197#endif /* HAVE_GETSID */
5198
5199
Guido van Rossumb6775db1994-08-01 11:34:53 +00005200#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005201PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005202"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005203Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005204
Barry Warsaw53699e91996-12-10 23:23:01 +00005205static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005206posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005207{
Guido van Rossum687dd131993-05-17 08:34:16 +00005208 if (setsid() < 0)
5209 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005210 Py_INCREF(Py_None);
5211 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005212}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005213#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005214
Guido van Rossumb6775db1994-08-01 11:34:53 +00005215#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005216PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005217"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005218Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005219
Barry Warsaw53699e91996-12-10 23:23:01 +00005220static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005221posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005222{
5223 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005224 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00005225 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005226 if (setpgid(pid, pgrp) < 0)
5227 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005228 Py_INCREF(Py_None);
5229 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005230}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005231#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005232
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005233
Guido van Rossumb6775db1994-08-01 11:34:53 +00005234#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005235PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005236"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005237Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005238
Barry Warsaw53699e91996-12-10 23:23:01 +00005239static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005240posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005241{
5242 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005243 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00005244 return NULL;
5245 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005246 if (pgid < 0)
5247 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005248 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00005249}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005250#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00005251
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005252
Guido van Rossumb6775db1994-08-01 11:34:53 +00005253#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005254PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005255"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005256Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005257
Barry Warsaw53699e91996-12-10 23:23:01 +00005258static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005259posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005260{
5261 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005262 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00005263 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005264 if (tcsetpgrp(fd, pgid) < 0)
5265 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00005266 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00005267 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00005268}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005269#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00005270
Guido van Rossum687dd131993-05-17 08:34:16 +00005271/* Functions acting on file descriptors */
5272
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005273PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005274"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005275Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005276
Barry Warsaw53699e91996-12-10 23:23:01 +00005277static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005278posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005279{
Mark Hammondef8b6542001-05-13 08:04:26 +00005280 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005281 int flag;
5282 int mode = 0777;
5283 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005284
5285#ifdef MS_WINDOWS
5286 if (unicode_file_names()) {
5287 PyUnicodeObject *po;
5288 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
5289 Py_BEGIN_ALLOW_THREADS
5290 /* PyUnicode_AS_UNICODE OK without thread
5291 lock as it is a simple dereference. */
5292 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
5293 Py_END_ALLOW_THREADS
5294 if (fd < 0)
5295 return posix_error();
5296 return PyInt_FromLong((long)fd);
5297 }
5298 /* Drop the argument parsing error as narrow strings
5299 are also valid. */
5300 PyErr_Clear();
5301 }
5302#endif
5303
Tim Peters5aa91602002-01-30 05:46:57 +00005304 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00005305 Py_FileSystemDefaultEncoding, &file,
5306 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00005307 return NULL;
5308
Barry Warsaw53699e91996-12-10 23:23:01 +00005309 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005310 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005311 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005312 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00005313 return posix_error_with_allocated_filename(file);
5314 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00005315 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005316}
5317
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005318
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005319PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005320"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005321Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005322
Barry Warsaw53699e91996-12-10 23:23:01 +00005323static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005324posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005325{
5326 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005327 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005328 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005329 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005330 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00005331 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005332 if (res < 0)
5333 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005334 Py_INCREF(Py_None);
5335 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005336}
5337
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005338
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005339PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005340"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005341Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005342
Barry Warsaw53699e91996-12-10 23:23:01 +00005343static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005344posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005345{
5346 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005347 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005348 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005349 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005350 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00005351 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005352 if (fd < 0)
5353 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005354 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005355}
5356
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005357
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005358PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00005359"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005360Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005361
Barry Warsaw53699e91996-12-10 23:23:01 +00005362static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005363posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005364{
5365 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005366 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00005367 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005368 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005369 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00005370 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005371 if (res < 0)
5372 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005373 Py_INCREF(Py_None);
5374 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005375}
5376
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005377
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005378PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005379"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005380Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005381
Barry Warsaw53699e91996-12-10 23:23:01 +00005382static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005383posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005384{
5385 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005386#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005387 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005388#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00005389 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005390#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005391 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005392 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00005393 return NULL;
5394#ifdef SEEK_SET
5395 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
5396 switch (how) {
5397 case 0: how = SEEK_SET; break;
5398 case 1: how = SEEK_CUR; break;
5399 case 2: how = SEEK_END; break;
5400 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005401#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005402
5403#if !defined(HAVE_LARGEFILE_SUPPORT)
5404 pos = PyInt_AsLong(posobj);
5405#else
5406 pos = PyLong_Check(posobj) ?
5407 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
5408#endif
5409 if (PyErr_Occurred())
5410 return NULL;
5411
Barry Warsaw53699e91996-12-10 23:23:01 +00005412 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005413#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00005414 res = _lseeki64(fd, pos, how);
5415#else
Guido van Rossum687dd131993-05-17 08:34:16 +00005416 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005417#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005418 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005419 if (res < 0)
5420 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00005421
5422#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00005423 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005424#else
5425 return PyLong_FromLongLong(res);
5426#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005427}
5428
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005429
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005430PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005431"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005432Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005433
Barry Warsaw53699e91996-12-10 23:23:01 +00005434static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005435posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005436{
Guido van Rossum8bac5461996-06-11 18:38:48 +00005437 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00005438 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005439 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005440 return NULL;
Michael W. Hudson9867ced2005-01-31 17:01:59 +00005441 if (size < 0) {
5442 errno = EINVAL;
5443 return posix_error();
5444 }
Barry Warsaw53699e91996-12-10 23:23:01 +00005445 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005446 if (buffer == NULL)
5447 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005448 Py_BEGIN_ALLOW_THREADS
5449 n = read(fd, PyString_AsString(buffer), size);
5450 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00005451 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005452 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00005453 return posix_error();
5454 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00005455 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00005456 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00005457 return buffer;
5458}
5459
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005460
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005461PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005462"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005463Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005464
Barry Warsaw53699e91996-12-10 23:23:01 +00005465static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005466posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005467{
5468 int fd, size;
5469 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005470 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005471 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005472 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005473 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00005474 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005475 if (size < 0)
5476 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005477 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005478}
5479
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005480
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005481PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005482"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005483Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005484
Barry Warsaw53699e91996-12-10 23:23:01 +00005485static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005486posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005487{
5488 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00005489 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00005490 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005491 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005492 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005493#ifdef __VMS
5494 /* on OpenVMS we must ensure that all bytes are written to the file */
5495 fsync(fd);
5496#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005497 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00005498 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00005499 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005500 if (res != 0)
5501 return posix_error();
Tim Peters5aa91602002-01-30 05:46:57 +00005502
Fred Drake699f3522000-06-29 21:12:41 +00005503 return _pystat_fromstructstat(st);
Guido van Rossum687dd131993-05-17 08:34:16 +00005504}
5505
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005506
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005507PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005508"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005509Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005510
Barry Warsaw53699e91996-12-10 23:23:01 +00005511static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005512posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005513{
Guido van Rossum687dd131993-05-17 08:34:16 +00005514 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005515 char *mode = "r";
5516 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00005517 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00005518 PyObject *f;
5519 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00005520 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00005521
Thomas Heller1f043e22002-11-07 16:00:59 +00005522 if (mode[0] != 'r' && mode[0] != 'w' && mode[0] != 'a') {
5523 PyErr_Format(PyExc_ValueError,
5524 "invalid file mode '%s'", mode);
5525 return NULL;
5526 }
5527
Barry Warsaw53699e91996-12-10 23:23:01 +00005528 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005529 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005530 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005531 if (fp == NULL)
5532 return posix_error();
Guido van Rossumbd6be7a2002-09-15 18:45:46 +00005533 f = PyFile_FromFile(fp, "<fdopen>", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005534 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00005535 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005536 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00005537}
5538
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005539PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005540"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005541Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005542connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00005543
5544static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00005545posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00005546{
5547 int fd;
5548 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
5549 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005550 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00005551}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005552
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005553#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005554PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005555"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005556Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005557
Barry Warsaw53699e91996-12-10 23:23:01 +00005558static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005559posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00005560{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005561#if defined(PYOS_OS2)
5562 HFILE read, write;
5563 APIRET rc;
5564
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005565 Py_BEGIN_ALLOW_THREADS
5566 rc = DosCreatePipe( &read, &write, 4096);
5567 Py_END_ALLOW_THREADS
5568 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005569 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005570
5571 return Py_BuildValue("(ii)", read, write);
5572#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005573#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00005574 int fds[2];
5575 int res;
Barry Warsaw53699e91996-12-10 23:23:01 +00005576 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005577 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00005578 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005579 if (res != 0)
5580 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005581 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005582#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00005583 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005584 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00005585 BOOL ok;
Barry Warsaw53699e91996-12-10 23:23:01 +00005586 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005587 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00005588 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00005589 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005590 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00005591 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
5592 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005593 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005594#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005595#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005596}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005597#endif /* HAVE_PIPE */
5598
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005599
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005600#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005601PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005602"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005603Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005604
Barry Warsaw53699e91996-12-10 23:23:01 +00005605static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005606posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005607{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005608 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005609 int mode = 0666;
5610 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005611 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005612 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005613 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005614 res = mkfifo(filename, mode);
5615 Py_END_ALLOW_THREADS
5616 if (res < 0)
5617 return posix_error();
5618 Py_INCREF(Py_None);
5619 return Py_None;
5620}
5621#endif
5622
5623
Neal Norwitz11690112002-07-30 01:08:28 +00005624#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005625PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005626"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005627Create a filesystem node (file, device special file or named pipe)\n\
5628named filename. mode specifies both the permissions to use and the\n\
5629type of node to be created, being combined (bitwise OR) with one of\n\
5630S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005631device defines the newly created device special file (probably using\n\
5632os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005633
5634
5635static PyObject *
5636posix_mknod(PyObject *self, PyObject *args)
5637{
5638 char *filename;
5639 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005640 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005641 int res;
Martin v. Löwisd631ebe2002-11-02 17:42:33 +00005642 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005643 return NULL;
5644 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005645 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00005646 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005647 if (res < 0)
5648 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005649 Py_INCREF(Py_None);
5650 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005651}
5652#endif
5653
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005654#ifdef HAVE_DEVICE_MACROS
5655PyDoc_STRVAR(posix_major__doc__,
5656"major(device) -> major number\n\
5657Extracts a device major number from a raw device number.");
5658
5659static PyObject *
5660posix_major(PyObject *self, PyObject *args)
5661{
5662 int device;
5663 if (!PyArg_ParseTuple(args, "i:major", &device))
5664 return NULL;
5665 return PyInt_FromLong((long)major(device));
5666}
5667
5668PyDoc_STRVAR(posix_minor__doc__,
5669"minor(device) -> minor number\n\
5670Extracts a device minor number from a raw device number.");
5671
5672static PyObject *
5673posix_minor(PyObject *self, PyObject *args)
5674{
5675 int device;
5676 if (!PyArg_ParseTuple(args, "i:minor", &device))
5677 return NULL;
5678 return PyInt_FromLong((long)minor(device));
5679}
5680
5681PyDoc_STRVAR(posix_makedev__doc__,
5682"makedev(major, minor) -> device number\n\
5683Composes a raw device number from the major and minor device numbers.");
5684
5685static PyObject *
5686posix_makedev(PyObject *self, PyObject *args)
5687{
5688 int major, minor;
5689 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
5690 return NULL;
5691 return PyInt_FromLong((long)makedev(major, minor));
5692}
5693#endif /* device macros */
5694
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005695
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005696#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005697PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005698"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005699Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005700
Barry Warsaw53699e91996-12-10 23:23:01 +00005701static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005702posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005703{
5704 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005705 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005706 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005707 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005708
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005709 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005710 return NULL;
5711
5712#if !defined(HAVE_LARGEFILE_SUPPORT)
5713 length = PyInt_AsLong(lenobj);
5714#else
5715 length = PyLong_Check(lenobj) ?
5716 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
5717#endif
5718 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005719 return NULL;
5720
Barry Warsaw53699e91996-12-10 23:23:01 +00005721 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005722 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00005723 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005724 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005725 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005726 return NULL;
5727 }
Barry Warsaw53699e91996-12-10 23:23:01 +00005728 Py_INCREF(Py_None);
5729 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005730}
5731#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005732
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005733#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005734PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005735"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005736Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005737
Fred Drake762e2061999-08-26 17:23:54 +00005738/* Save putenv() parameters as values here, so we can collect them when they
5739 * get re-set with another call for the same key. */
5740static PyObject *posix_putenv_garbage;
5741
Tim Peters5aa91602002-01-30 05:46:57 +00005742static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005743posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005744{
5745 char *s1, *s2;
5746 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00005747 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00005748 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005749
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005750 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005751 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00005752
5753#if defined(PYOS_OS2)
5754 if (stricmp(s1, "BEGINLIBPATH") == 0) {
5755 APIRET rc;
5756
Guido van Rossumd48f2521997-12-05 22:19:34 +00005757 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
5758 if (rc != NO_ERROR)
5759 return os2_error(rc);
5760
5761 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
5762 APIRET rc;
5763
Guido van Rossumd48f2521997-12-05 22:19:34 +00005764 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
5765 if (rc != NO_ERROR)
5766 return os2_error(rc);
5767 } else {
5768#endif
5769
Fred Drake762e2061999-08-26 17:23:54 +00005770 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00005771 len = strlen(s1) + strlen(s2) + 2;
5772 /* len includes space for a trailing \0; the size arg to
5773 PyString_FromStringAndSize does not count that */
5774 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00005775 if (newstr == NULL)
5776 return PyErr_NoMemory();
5777 new = PyString_AS_STRING(newstr);
Tim Petersc8996f52001-12-03 20:41:00 +00005778 PyOS_snprintf(new, len, "%s=%s", s1, s2);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005779 if (putenv(new)) {
Neal Norwitz4adc9ab2003-02-10 03:10:43 +00005780 Py_DECREF(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005781 posix_error();
5782 return NULL;
5783 }
Fred Drake762e2061999-08-26 17:23:54 +00005784 /* Install the first arg and newstr in posix_putenv_garbage;
5785 * this will cause previous value to be collected. This has to
5786 * happen after the real putenv() call because the old value
5787 * was still accessible until then. */
5788 if (PyDict_SetItem(posix_putenv_garbage,
5789 PyTuple_GET_ITEM(args, 0), newstr)) {
5790 /* really not much we can do; just leak */
5791 PyErr_Clear();
5792 }
5793 else {
5794 Py_DECREF(newstr);
5795 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005796
5797#if defined(PYOS_OS2)
5798 }
5799#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005800 Py_INCREF(Py_None);
5801 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005802}
Guido van Rossumb6a47161997-09-15 22:54:34 +00005803#endif /* putenv */
5804
Guido van Rossumc524d952001-10-19 01:31:59 +00005805#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005806PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005807"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005808Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00005809
5810static PyObject *
5811posix_unsetenv(PyObject *self, PyObject *args)
5812{
5813 char *s1;
5814
5815 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
5816 return NULL;
5817
5818 unsetenv(s1);
5819
5820 /* Remove the key from posix_putenv_garbage;
5821 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00005822 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00005823 * old value was still accessible until then.
5824 */
5825 if (PyDict_DelItem(posix_putenv_garbage,
5826 PyTuple_GET_ITEM(args, 0))) {
5827 /* really not much we can do; just leak */
5828 PyErr_Clear();
5829 }
5830
5831 Py_INCREF(Py_None);
5832 return Py_None;
5833}
5834#endif /* unsetenv */
5835
Guido van Rossumb6a47161997-09-15 22:54:34 +00005836#ifdef HAVE_STRERROR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005837PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005838"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005839Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005840
Guido van Rossumf68d8e52001-04-14 17:55:09 +00005841static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005842posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00005843{
5844 int code;
5845 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005846 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00005847 return NULL;
5848 message = strerror(code);
5849 if (message == NULL) {
5850 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00005851 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005852 return NULL;
5853 }
5854 return PyString_FromString(message);
5855}
5856#endif /* strerror */
5857
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005858
Guido van Rossumc9641791998-08-04 15:26:23 +00005859#ifdef HAVE_SYS_WAIT_H
5860
Fred Drake106c1a02002-04-23 15:58:02 +00005861#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005862PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005863"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005864Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00005865
5866static PyObject *
5867posix_WCOREDUMP(PyObject *self, PyObject *args)
5868{
5869#ifdef UNION_WAIT
5870 union wait status;
5871#define status_i (status.w_status)
5872#else
5873 int status;
5874#define status_i status
5875#endif
5876 status_i = 0;
5877
5878 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &status_i))
5879 {
5880 return NULL;
5881 }
5882
5883 return PyBool_FromLong(WCOREDUMP(status));
5884#undef status_i
5885}
5886#endif /* WCOREDUMP */
5887
5888#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005889PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005890"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005891Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005892job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00005893
5894static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005895posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00005896{
5897#ifdef UNION_WAIT
5898 union wait status;
5899#define status_i (status.w_status)
5900#else
5901 int status;
5902#define status_i status
5903#endif
5904 status_i = 0;
5905
5906 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &status_i))
5907 {
5908 return NULL;
5909 }
5910
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00005911 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00005912#undef status_i
5913}
5914#endif /* WIFCONTINUED */
5915
Guido van Rossumc9641791998-08-04 15:26:23 +00005916#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005917PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005918"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005919Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005920
5921static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005922posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005923{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005924#ifdef UNION_WAIT
5925 union wait status;
5926#define status_i (status.w_status)
5927#else
5928 int status;
5929#define status_i status
5930#endif
5931 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005932
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005933 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005934 {
5935 return NULL;
5936 }
Tim Peters5aa91602002-01-30 05:46:57 +00005937
Fred Drake106c1a02002-04-23 15:58:02 +00005938 return PyBool_FromLong(WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005939#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005940}
5941#endif /* WIFSTOPPED */
5942
5943#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005944PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005945"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005946Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005947
5948static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005949posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005950{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005951#ifdef UNION_WAIT
5952 union wait status;
5953#define status_i (status.w_status)
5954#else
5955 int status;
5956#define status_i status
5957#endif
5958 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005959
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005960 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005961 {
5962 return NULL;
5963 }
Tim Peters5aa91602002-01-30 05:46:57 +00005964
Fred Drake106c1a02002-04-23 15:58:02 +00005965 return PyBool_FromLong(WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005966#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005967}
5968#endif /* WIFSIGNALED */
5969
5970#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005971PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005972"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00005973Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005974system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00005975
5976static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005977posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00005978{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005979#ifdef UNION_WAIT
5980 union wait status;
5981#define status_i (status.w_status)
5982#else
5983 int status;
5984#define status_i status
5985#endif
5986 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00005987
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005988 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00005989 {
5990 return NULL;
5991 }
Tim Peters5aa91602002-01-30 05:46:57 +00005992
Fred Drake106c1a02002-04-23 15:58:02 +00005993 return PyBool_FromLong(WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005994#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00005995}
5996#endif /* WIFEXITED */
5997
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005998#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005999PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006000"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006001Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006002
6003static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006004posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006005{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006006#ifdef UNION_WAIT
6007 union wait status;
6008#define status_i (status.w_status)
6009#else
6010 int status;
6011#define status_i status
6012#endif
6013 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006014
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006015 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00006016 {
6017 return NULL;
6018 }
Tim Peters5aa91602002-01-30 05:46:57 +00006019
Guido van Rossumc9641791998-08-04 15:26:23 +00006020 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006021#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00006022}
6023#endif /* WEXITSTATUS */
6024
6025#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006026PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006027"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006028Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006029value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006030
6031static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006032posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006033{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006034#ifdef UNION_WAIT
6035 union wait status;
6036#define status_i (status.w_status)
6037#else
6038 int status;
6039#define status_i status
6040#endif
6041 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006042
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006043 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00006044 {
6045 return NULL;
6046 }
Tim Peters5aa91602002-01-30 05:46:57 +00006047
Guido van Rossumc9641791998-08-04 15:26:23 +00006048 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006049#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00006050}
6051#endif /* WTERMSIG */
6052
6053#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006054PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006055"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006056Return the signal that stopped the process that provided\n\
6057the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006058
6059static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006060posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006061{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006062#ifdef UNION_WAIT
6063 union wait status;
6064#define status_i (status.w_status)
6065#else
6066 int status;
6067#define status_i status
6068#endif
6069 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006070
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006071 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00006072 {
6073 return NULL;
6074 }
Tim Peters5aa91602002-01-30 05:46:57 +00006075
Guido van Rossumc9641791998-08-04 15:26:23 +00006076 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006077#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00006078}
6079#endif /* WSTOPSIG */
6080
6081#endif /* HAVE_SYS_WAIT_H */
6082
6083
Guido van Rossum94f6f721999-01-06 18:42:14 +00006084#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00006085#ifdef _SCO_DS
6086/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
6087 needed definitions in sys/statvfs.h */
6088#define _SVID3
6089#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006090#include <sys/statvfs.h>
6091
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006092static PyObject*
6093_pystatvfs_fromstructstatvfs(struct statvfs st) {
6094 PyObject *v = PyStructSequence_New(&StatVFSResultType);
6095 if (v == NULL)
6096 return NULL;
6097
6098#if !defined(HAVE_LARGEFILE_SUPPORT)
6099 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6100 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
6101 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
6102 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
6103 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
6104 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
6105 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
6106 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
6107 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6108 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6109#else
6110 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6111 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00006112 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006113 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00006114 PyStructSequence_SET_ITEM(v, 3,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006115 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006116 PyStructSequence_SET_ITEM(v, 4,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006117 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00006118 PyStructSequence_SET_ITEM(v, 5,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006119 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00006120 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006121 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00006122 PyStructSequence_SET_ITEM(v, 7,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006123 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006124 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6125 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6126#endif
6127
6128 return v;
6129}
6130
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006131PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006132"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006133Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006134
6135static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006136posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006137{
6138 int fd, res;
6139 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006140
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006141 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006142 return NULL;
6143 Py_BEGIN_ALLOW_THREADS
6144 res = fstatvfs(fd, &st);
6145 Py_END_ALLOW_THREADS
6146 if (res != 0)
6147 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006148
6149 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006150}
6151#endif /* HAVE_FSTATVFS */
6152
6153
6154#if defined(HAVE_STATVFS)
6155#include <sys/statvfs.h>
6156
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006157PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006158"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006159Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006160
6161static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006162posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006163{
6164 char *path;
6165 int res;
6166 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006167 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006168 return NULL;
6169 Py_BEGIN_ALLOW_THREADS
6170 res = statvfs(path, &st);
6171 Py_END_ALLOW_THREADS
6172 if (res != 0)
6173 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006174
6175 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006176}
6177#endif /* HAVE_STATVFS */
6178
6179
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006180#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006181PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006182"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006183Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00006184The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006185or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006186
6187static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006188posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006189{
6190 PyObject *result = NULL;
6191 char *dir = NULL;
6192 char *pfx = NULL;
6193 char *name;
6194
6195 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
6196 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00006197
6198 if (PyErr_Warn(PyExc_RuntimeWarning,
6199 "tempnam is a potential security risk to your program") < 0)
6200 return NULL;
6201
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006202#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00006203 name = _tempnam(dir, pfx);
6204#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006205 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00006206#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006207 if (name == NULL)
6208 return PyErr_NoMemory();
6209 result = PyString_FromString(name);
6210 free(name);
6211 return result;
6212}
Guido van Rossumd371ff11999-01-25 16:12:23 +00006213#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006214
6215
6216#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006217PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006218"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006219Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006220
6221static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006222posix_tmpfile(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006223{
6224 FILE *fp;
6225
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006226 fp = tmpfile();
6227 if (fp == NULL)
6228 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00006229 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006230}
6231#endif
6232
6233
6234#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006235PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006236"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006237Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006238
6239static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006240posix_tmpnam(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006241{
6242 char buffer[L_tmpnam];
6243 char *name;
6244
Skip Montanaro95618b52001-08-18 18:52:10 +00006245 if (PyErr_Warn(PyExc_RuntimeWarning,
6246 "tmpnam is a potential security risk to your program") < 0)
6247 return NULL;
6248
Greg Wardb48bc172000-03-01 21:51:56 +00006249#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006250 name = tmpnam_r(buffer);
6251#else
6252 name = tmpnam(buffer);
6253#endif
6254 if (name == NULL) {
6255 PyErr_SetObject(PyExc_OSError,
6256 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00006257#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006258 "unexpected NULL from tmpnam_r"
6259#else
6260 "unexpected NULL from tmpnam"
6261#endif
6262 ));
6263 return NULL;
6264 }
6265 return PyString_FromString(buffer);
6266}
6267#endif
6268
6269
Fred Drakec9680921999-12-13 16:37:25 +00006270/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
6271 * It maps strings representing configuration variable names to
6272 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00006273 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00006274 * rarely-used constants. There are three separate tables that use
6275 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00006276 *
6277 * This code is always included, even if none of the interfaces that
6278 * need it are included. The #if hackery needed to avoid it would be
6279 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00006280 */
6281struct constdef {
6282 char *name;
6283 long value;
6284};
6285
Fred Drake12c6e2d1999-12-14 21:25:03 +00006286static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006287conv_confname(PyObject *arg, int *valuep, struct constdef *table,
6288 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006289{
6290 if (PyInt_Check(arg)) {
6291 *valuep = PyInt_AS_LONG(arg);
6292 return 1;
6293 }
6294 if (PyString_Check(arg)) {
6295 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00006296 size_t lo = 0;
6297 size_t mid;
6298 size_t hi = tablesize;
6299 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006300 char *confname = PyString_AS_STRING(arg);
6301 while (lo < hi) {
6302 mid = (lo + hi) / 2;
6303 cmp = strcmp(confname, table[mid].name);
6304 if (cmp < 0)
6305 hi = mid;
6306 else if (cmp > 0)
6307 lo = mid + 1;
6308 else {
6309 *valuep = table[mid].value;
6310 return 1;
6311 }
6312 }
6313 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
6314 }
6315 else
6316 PyErr_SetString(PyExc_TypeError,
6317 "configuration names must be strings or integers");
6318 return 0;
6319}
6320
6321
6322#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
6323static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006324#ifdef _PC_ABI_AIO_XFER_MAX
6325 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
6326#endif
6327#ifdef _PC_ABI_ASYNC_IO
6328 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
6329#endif
Fred Drakec9680921999-12-13 16:37:25 +00006330#ifdef _PC_ASYNC_IO
6331 {"PC_ASYNC_IO", _PC_ASYNC_IO},
6332#endif
6333#ifdef _PC_CHOWN_RESTRICTED
6334 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
6335#endif
6336#ifdef _PC_FILESIZEBITS
6337 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
6338#endif
6339#ifdef _PC_LAST
6340 {"PC_LAST", _PC_LAST},
6341#endif
6342#ifdef _PC_LINK_MAX
6343 {"PC_LINK_MAX", _PC_LINK_MAX},
6344#endif
6345#ifdef _PC_MAX_CANON
6346 {"PC_MAX_CANON", _PC_MAX_CANON},
6347#endif
6348#ifdef _PC_MAX_INPUT
6349 {"PC_MAX_INPUT", _PC_MAX_INPUT},
6350#endif
6351#ifdef _PC_NAME_MAX
6352 {"PC_NAME_MAX", _PC_NAME_MAX},
6353#endif
6354#ifdef _PC_NO_TRUNC
6355 {"PC_NO_TRUNC", _PC_NO_TRUNC},
6356#endif
6357#ifdef _PC_PATH_MAX
6358 {"PC_PATH_MAX", _PC_PATH_MAX},
6359#endif
6360#ifdef _PC_PIPE_BUF
6361 {"PC_PIPE_BUF", _PC_PIPE_BUF},
6362#endif
6363#ifdef _PC_PRIO_IO
6364 {"PC_PRIO_IO", _PC_PRIO_IO},
6365#endif
6366#ifdef _PC_SOCK_MAXBUF
6367 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
6368#endif
6369#ifdef _PC_SYNC_IO
6370 {"PC_SYNC_IO", _PC_SYNC_IO},
6371#endif
6372#ifdef _PC_VDISABLE
6373 {"PC_VDISABLE", _PC_VDISABLE},
6374#endif
6375};
6376
Fred Drakec9680921999-12-13 16:37:25 +00006377static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006378conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006379{
6380 return conv_confname(arg, valuep, posix_constants_pathconf,
6381 sizeof(posix_constants_pathconf)
6382 / sizeof(struct constdef));
6383}
6384#endif
6385
6386#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006387PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006388"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006389Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006390If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006391
6392static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006393posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006394{
6395 PyObject *result = NULL;
6396 int name, fd;
6397
Fred Drake12c6e2d1999-12-14 21:25:03 +00006398 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
6399 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00006400 long limit;
6401
6402 errno = 0;
6403 limit = fpathconf(fd, name);
6404 if (limit == -1 && errno != 0)
6405 posix_error();
6406 else
6407 result = PyInt_FromLong(limit);
6408 }
6409 return result;
6410}
6411#endif
6412
6413
6414#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006415PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006416"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006417Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006418If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006419
6420static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006421posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006422{
6423 PyObject *result = NULL;
6424 int name;
6425 char *path;
6426
6427 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
6428 conv_path_confname, &name)) {
6429 long limit;
6430
6431 errno = 0;
6432 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006433 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00006434 if (errno == EINVAL)
6435 /* could be a path or name problem */
6436 posix_error();
6437 else
6438 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006439 }
Fred Drakec9680921999-12-13 16:37:25 +00006440 else
6441 result = PyInt_FromLong(limit);
6442 }
6443 return result;
6444}
6445#endif
6446
6447#ifdef HAVE_CONFSTR
6448static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006449#ifdef _CS_ARCHITECTURE
6450 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
6451#endif
6452#ifdef _CS_HOSTNAME
6453 {"CS_HOSTNAME", _CS_HOSTNAME},
6454#endif
6455#ifdef _CS_HW_PROVIDER
6456 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
6457#endif
6458#ifdef _CS_HW_SERIAL
6459 {"CS_HW_SERIAL", _CS_HW_SERIAL},
6460#endif
6461#ifdef _CS_INITTAB_NAME
6462 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
6463#endif
Fred Drakec9680921999-12-13 16:37:25 +00006464#ifdef _CS_LFS64_CFLAGS
6465 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
6466#endif
6467#ifdef _CS_LFS64_LDFLAGS
6468 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
6469#endif
6470#ifdef _CS_LFS64_LIBS
6471 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
6472#endif
6473#ifdef _CS_LFS64_LINTFLAGS
6474 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
6475#endif
6476#ifdef _CS_LFS_CFLAGS
6477 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
6478#endif
6479#ifdef _CS_LFS_LDFLAGS
6480 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
6481#endif
6482#ifdef _CS_LFS_LIBS
6483 {"CS_LFS_LIBS", _CS_LFS_LIBS},
6484#endif
6485#ifdef _CS_LFS_LINTFLAGS
6486 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
6487#endif
Fred Draked86ed291999-12-15 15:34:33 +00006488#ifdef _CS_MACHINE
6489 {"CS_MACHINE", _CS_MACHINE},
6490#endif
Fred Drakec9680921999-12-13 16:37:25 +00006491#ifdef _CS_PATH
6492 {"CS_PATH", _CS_PATH},
6493#endif
Fred Draked86ed291999-12-15 15:34:33 +00006494#ifdef _CS_RELEASE
6495 {"CS_RELEASE", _CS_RELEASE},
6496#endif
6497#ifdef _CS_SRPC_DOMAIN
6498 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
6499#endif
6500#ifdef _CS_SYSNAME
6501 {"CS_SYSNAME", _CS_SYSNAME},
6502#endif
6503#ifdef _CS_VERSION
6504 {"CS_VERSION", _CS_VERSION},
6505#endif
Fred Drakec9680921999-12-13 16:37:25 +00006506#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
6507 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
6508#endif
6509#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
6510 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
6511#endif
6512#ifdef _CS_XBS5_ILP32_OFF32_LIBS
6513 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
6514#endif
6515#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
6516 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
6517#endif
6518#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
6519 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
6520#endif
6521#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
6522 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
6523#endif
6524#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
6525 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
6526#endif
6527#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
6528 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
6529#endif
6530#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
6531 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
6532#endif
6533#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
6534 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
6535#endif
6536#ifdef _CS_XBS5_LP64_OFF64_LIBS
6537 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
6538#endif
6539#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
6540 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
6541#endif
6542#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
6543 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
6544#endif
6545#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
6546 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
6547#endif
6548#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
6549 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
6550#endif
6551#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
6552 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
6553#endif
Fred Draked86ed291999-12-15 15:34:33 +00006554#ifdef _MIPS_CS_AVAIL_PROCESSORS
6555 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
6556#endif
6557#ifdef _MIPS_CS_BASE
6558 {"MIPS_CS_BASE", _MIPS_CS_BASE},
6559#endif
6560#ifdef _MIPS_CS_HOSTID
6561 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
6562#endif
6563#ifdef _MIPS_CS_HW_NAME
6564 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
6565#endif
6566#ifdef _MIPS_CS_NUM_PROCESSORS
6567 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
6568#endif
6569#ifdef _MIPS_CS_OSREL_MAJ
6570 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
6571#endif
6572#ifdef _MIPS_CS_OSREL_MIN
6573 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
6574#endif
6575#ifdef _MIPS_CS_OSREL_PATCH
6576 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
6577#endif
6578#ifdef _MIPS_CS_OS_NAME
6579 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
6580#endif
6581#ifdef _MIPS_CS_OS_PROVIDER
6582 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
6583#endif
6584#ifdef _MIPS_CS_PROCESSORS
6585 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
6586#endif
6587#ifdef _MIPS_CS_SERIAL
6588 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
6589#endif
6590#ifdef _MIPS_CS_VENDOR
6591 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
6592#endif
Fred Drakec9680921999-12-13 16:37:25 +00006593};
6594
6595static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006596conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006597{
6598 return conv_confname(arg, valuep, posix_constants_confstr,
6599 sizeof(posix_constants_confstr)
6600 / sizeof(struct constdef));
6601}
6602
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006603PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006604"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006605Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006606
6607static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006608posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006609{
6610 PyObject *result = NULL;
6611 int name;
6612 char buffer[64];
6613
6614 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
6615 int len = confstr(name, buffer, sizeof(buffer));
6616
Fred Drakec9680921999-12-13 16:37:25 +00006617 errno = 0;
6618 if (len == 0) {
6619 if (errno != 0)
6620 posix_error();
6621 else
6622 result = PyString_FromString("");
6623 }
6624 else {
6625 if (len >= sizeof(buffer)) {
6626 result = PyString_FromStringAndSize(NULL, len);
6627 if (result != NULL)
6628 confstr(name, PyString_AS_STRING(result), len+1);
6629 }
6630 else
6631 result = PyString_FromString(buffer);
6632 }
6633 }
6634 return result;
6635}
6636#endif
6637
6638
6639#ifdef HAVE_SYSCONF
6640static struct constdef posix_constants_sysconf[] = {
6641#ifdef _SC_2_CHAR_TERM
6642 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
6643#endif
6644#ifdef _SC_2_C_BIND
6645 {"SC_2_C_BIND", _SC_2_C_BIND},
6646#endif
6647#ifdef _SC_2_C_DEV
6648 {"SC_2_C_DEV", _SC_2_C_DEV},
6649#endif
6650#ifdef _SC_2_C_VERSION
6651 {"SC_2_C_VERSION", _SC_2_C_VERSION},
6652#endif
6653#ifdef _SC_2_FORT_DEV
6654 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
6655#endif
6656#ifdef _SC_2_FORT_RUN
6657 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
6658#endif
6659#ifdef _SC_2_LOCALEDEF
6660 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
6661#endif
6662#ifdef _SC_2_SW_DEV
6663 {"SC_2_SW_DEV", _SC_2_SW_DEV},
6664#endif
6665#ifdef _SC_2_UPE
6666 {"SC_2_UPE", _SC_2_UPE},
6667#endif
6668#ifdef _SC_2_VERSION
6669 {"SC_2_VERSION", _SC_2_VERSION},
6670#endif
Fred Draked86ed291999-12-15 15:34:33 +00006671#ifdef _SC_ABI_ASYNCHRONOUS_IO
6672 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
6673#endif
6674#ifdef _SC_ACL
6675 {"SC_ACL", _SC_ACL},
6676#endif
Fred Drakec9680921999-12-13 16:37:25 +00006677#ifdef _SC_AIO_LISTIO_MAX
6678 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
6679#endif
Fred Drakec9680921999-12-13 16:37:25 +00006680#ifdef _SC_AIO_MAX
6681 {"SC_AIO_MAX", _SC_AIO_MAX},
6682#endif
6683#ifdef _SC_AIO_PRIO_DELTA_MAX
6684 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
6685#endif
6686#ifdef _SC_ARG_MAX
6687 {"SC_ARG_MAX", _SC_ARG_MAX},
6688#endif
6689#ifdef _SC_ASYNCHRONOUS_IO
6690 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
6691#endif
6692#ifdef _SC_ATEXIT_MAX
6693 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
6694#endif
Fred Draked86ed291999-12-15 15:34:33 +00006695#ifdef _SC_AUDIT
6696 {"SC_AUDIT", _SC_AUDIT},
6697#endif
Fred Drakec9680921999-12-13 16:37:25 +00006698#ifdef _SC_AVPHYS_PAGES
6699 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
6700#endif
6701#ifdef _SC_BC_BASE_MAX
6702 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
6703#endif
6704#ifdef _SC_BC_DIM_MAX
6705 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
6706#endif
6707#ifdef _SC_BC_SCALE_MAX
6708 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
6709#endif
6710#ifdef _SC_BC_STRING_MAX
6711 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
6712#endif
Fred Draked86ed291999-12-15 15:34:33 +00006713#ifdef _SC_CAP
6714 {"SC_CAP", _SC_CAP},
6715#endif
Fred Drakec9680921999-12-13 16:37:25 +00006716#ifdef _SC_CHARCLASS_NAME_MAX
6717 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
6718#endif
6719#ifdef _SC_CHAR_BIT
6720 {"SC_CHAR_BIT", _SC_CHAR_BIT},
6721#endif
6722#ifdef _SC_CHAR_MAX
6723 {"SC_CHAR_MAX", _SC_CHAR_MAX},
6724#endif
6725#ifdef _SC_CHAR_MIN
6726 {"SC_CHAR_MIN", _SC_CHAR_MIN},
6727#endif
6728#ifdef _SC_CHILD_MAX
6729 {"SC_CHILD_MAX", _SC_CHILD_MAX},
6730#endif
6731#ifdef _SC_CLK_TCK
6732 {"SC_CLK_TCK", _SC_CLK_TCK},
6733#endif
6734#ifdef _SC_COHER_BLKSZ
6735 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
6736#endif
6737#ifdef _SC_COLL_WEIGHTS_MAX
6738 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
6739#endif
6740#ifdef _SC_DCACHE_ASSOC
6741 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
6742#endif
6743#ifdef _SC_DCACHE_BLKSZ
6744 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
6745#endif
6746#ifdef _SC_DCACHE_LINESZ
6747 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
6748#endif
6749#ifdef _SC_DCACHE_SZ
6750 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
6751#endif
6752#ifdef _SC_DCACHE_TBLKSZ
6753 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
6754#endif
6755#ifdef _SC_DELAYTIMER_MAX
6756 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
6757#endif
6758#ifdef _SC_EQUIV_CLASS_MAX
6759 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
6760#endif
6761#ifdef _SC_EXPR_NEST_MAX
6762 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
6763#endif
6764#ifdef _SC_FSYNC
6765 {"SC_FSYNC", _SC_FSYNC},
6766#endif
6767#ifdef _SC_GETGR_R_SIZE_MAX
6768 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
6769#endif
6770#ifdef _SC_GETPW_R_SIZE_MAX
6771 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
6772#endif
6773#ifdef _SC_ICACHE_ASSOC
6774 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
6775#endif
6776#ifdef _SC_ICACHE_BLKSZ
6777 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
6778#endif
6779#ifdef _SC_ICACHE_LINESZ
6780 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
6781#endif
6782#ifdef _SC_ICACHE_SZ
6783 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
6784#endif
Fred Draked86ed291999-12-15 15:34:33 +00006785#ifdef _SC_INF
6786 {"SC_INF", _SC_INF},
6787#endif
Fred Drakec9680921999-12-13 16:37:25 +00006788#ifdef _SC_INT_MAX
6789 {"SC_INT_MAX", _SC_INT_MAX},
6790#endif
6791#ifdef _SC_INT_MIN
6792 {"SC_INT_MIN", _SC_INT_MIN},
6793#endif
6794#ifdef _SC_IOV_MAX
6795 {"SC_IOV_MAX", _SC_IOV_MAX},
6796#endif
Fred Draked86ed291999-12-15 15:34:33 +00006797#ifdef _SC_IP_SECOPTS
6798 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
6799#endif
Fred Drakec9680921999-12-13 16:37:25 +00006800#ifdef _SC_JOB_CONTROL
6801 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
6802#endif
Fred Draked86ed291999-12-15 15:34:33 +00006803#ifdef _SC_KERN_POINTERS
6804 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
6805#endif
6806#ifdef _SC_KERN_SIM
6807 {"SC_KERN_SIM", _SC_KERN_SIM},
6808#endif
Fred Drakec9680921999-12-13 16:37:25 +00006809#ifdef _SC_LINE_MAX
6810 {"SC_LINE_MAX", _SC_LINE_MAX},
6811#endif
6812#ifdef _SC_LOGIN_NAME_MAX
6813 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
6814#endif
6815#ifdef _SC_LOGNAME_MAX
6816 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
6817#endif
6818#ifdef _SC_LONG_BIT
6819 {"SC_LONG_BIT", _SC_LONG_BIT},
6820#endif
Fred Draked86ed291999-12-15 15:34:33 +00006821#ifdef _SC_MAC
6822 {"SC_MAC", _SC_MAC},
6823#endif
Fred Drakec9680921999-12-13 16:37:25 +00006824#ifdef _SC_MAPPED_FILES
6825 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
6826#endif
6827#ifdef _SC_MAXPID
6828 {"SC_MAXPID", _SC_MAXPID},
6829#endif
6830#ifdef _SC_MB_LEN_MAX
6831 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
6832#endif
6833#ifdef _SC_MEMLOCK
6834 {"SC_MEMLOCK", _SC_MEMLOCK},
6835#endif
6836#ifdef _SC_MEMLOCK_RANGE
6837 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
6838#endif
6839#ifdef _SC_MEMORY_PROTECTION
6840 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
6841#endif
6842#ifdef _SC_MESSAGE_PASSING
6843 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
6844#endif
Fred Draked86ed291999-12-15 15:34:33 +00006845#ifdef _SC_MMAP_FIXED_ALIGNMENT
6846 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
6847#endif
Fred Drakec9680921999-12-13 16:37:25 +00006848#ifdef _SC_MQ_OPEN_MAX
6849 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
6850#endif
6851#ifdef _SC_MQ_PRIO_MAX
6852 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
6853#endif
Fred Draked86ed291999-12-15 15:34:33 +00006854#ifdef _SC_NACLS_MAX
6855 {"SC_NACLS_MAX", _SC_NACLS_MAX},
6856#endif
Fred Drakec9680921999-12-13 16:37:25 +00006857#ifdef _SC_NGROUPS_MAX
6858 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
6859#endif
6860#ifdef _SC_NL_ARGMAX
6861 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
6862#endif
6863#ifdef _SC_NL_LANGMAX
6864 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
6865#endif
6866#ifdef _SC_NL_MSGMAX
6867 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
6868#endif
6869#ifdef _SC_NL_NMAX
6870 {"SC_NL_NMAX", _SC_NL_NMAX},
6871#endif
6872#ifdef _SC_NL_SETMAX
6873 {"SC_NL_SETMAX", _SC_NL_SETMAX},
6874#endif
6875#ifdef _SC_NL_TEXTMAX
6876 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
6877#endif
6878#ifdef _SC_NPROCESSORS_CONF
6879 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
6880#endif
6881#ifdef _SC_NPROCESSORS_ONLN
6882 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
6883#endif
Fred Draked86ed291999-12-15 15:34:33 +00006884#ifdef _SC_NPROC_CONF
6885 {"SC_NPROC_CONF", _SC_NPROC_CONF},
6886#endif
6887#ifdef _SC_NPROC_ONLN
6888 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
6889#endif
Fred Drakec9680921999-12-13 16:37:25 +00006890#ifdef _SC_NZERO
6891 {"SC_NZERO", _SC_NZERO},
6892#endif
6893#ifdef _SC_OPEN_MAX
6894 {"SC_OPEN_MAX", _SC_OPEN_MAX},
6895#endif
6896#ifdef _SC_PAGESIZE
6897 {"SC_PAGESIZE", _SC_PAGESIZE},
6898#endif
6899#ifdef _SC_PAGE_SIZE
6900 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
6901#endif
6902#ifdef _SC_PASS_MAX
6903 {"SC_PASS_MAX", _SC_PASS_MAX},
6904#endif
6905#ifdef _SC_PHYS_PAGES
6906 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
6907#endif
6908#ifdef _SC_PII
6909 {"SC_PII", _SC_PII},
6910#endif
6911#ifdef _SC_PII_INTERNET
6912 {"SC_PII_INTERNET", _SC_PII_INTERNET},
6913#endif
6914#ifdef _SC_PII_INTERNET_DGRAM
6915 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
6916#endif
6917#ifdef _SC_PII_INTERNET_STREAM
6918 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
6919#endif
6920#ifdef _SC_PII_OSI
6921 {"SC_PII_OSI", _SC_PII_OSI},
6922#endif
6923#ifdef _SC_PII_OSI_CLTS
6924 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
6925#endif
6926#ifdef _SC_PII_OSI_COTS
6927 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
6928#endif
6929#ifdef _SC_PII_OSI_M
6930 {"SC_PII_OSI_M", _SC_PII_OSI_M},
6931#endif
6932#ifdef _SC_PII_SOCKET
6933 {"SC_PII_SOCKET", _SC_PII_SOCKET},
6934#endif
6935#ifdef _SC_PII_XTI
6936 {"SC_PII_XTI", _SC_PII_XTI},
6937#endif
6938#ifdef _SC_POLL
6939 {"SC_POLL", _SC_POLL},
6940#endif
6941#ifdef _SC_PRIORITIZED_IO
6942 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
6943#endif
6944#ifdef _SC_PRIORITY_SCHEDULING
6945 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
6946#endif
6947#ifdef _SC_REALTIME_SIGNALS
6948 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
6949#endif
6950#ifdef _SC_RE_DUP_MAX
6951 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
6952#endif
6953#ifdef _SC_RTSIG_MAX
6954 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
6955#endif
6956#ifdef _SC_SAVED_IDS
6957 {"SC_SAVED_IDS", _SC_SAVED_IDS},
6958#endif
6959#ifdef _SC_SCHAR_MAX
6960 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
6961#endif
6962#ifdef _SC_SCHAR_MIN
6963 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
6964#endif
6965#ifdef _SC_SELECT
6966 {"SC_SELECT", _SC_SELECT},
6967#endif
6968#ifdef _SC_SEMAPHORES
6969 {"SC_SEMAPHORES", _SC_SEMAPHORES},
6970#endif
6971#ifdef _SC_SEM_NSEMS_MAX
6972 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
6973#endif
6974#ifdef _SC_SEM_VALUE_MAX
6975 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
6976#endif
6977#ifdef _SC_SHARED_MEMORY_OBJECTS
6978 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
6979#endif
6980#ifdef _SC_SHRT_MAX
6981 {"SC_SHRT_MAX", _SC_SHRT_MAX},
6982#endif
6983#ifdef _SC_SHRT_MIN
6984 {"SC_SHRT_MIN", _SC_SHRT_MIN},
6985#endif
6986#ifdef _SC_SIGQUEUE_MAX
6987 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
6988#endif
6989#ifdef _SC_SIGRT_MAX
6990 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
6991#endif
6992#ifdef _SC_SIGRT_MIN
6993 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
6994#endif
Fred Draked86ed291999-12-15 15:34:33 +00006995#ifdef _SC_SOFTPOWER
6996 {"SC_SOFTPOWER", _SC_SOFTPOWER},
6997#endif
Fred Drakec9680921999-12-13 16:37:25 +00006998#ifdef _SC_SPLIT_CACHE
6999 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
7000#endif
7001#ifdef _SC_SSIZE_MAX
7002 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
7003#endif
7004#ifdef _SC_STACK_PROT
7005 {"SC_STACK_PROT", _SC_STACK_PROT},
7006#endif
7007#ifdef _SC_STREAM_MAX
7008 {"SC_STREAM_MAX", _SC_STREAM_MAX},
7009#endif
7010#ifdef _SC_SYNCHRONIZED_IO
7011 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
7012#endif
7013#ifdef _SC_THREADS
7014 {"SC_THREADS", _SC_THREADS},
7015#endif
7016#ifdef _SC_THREAD_ATTR_STACKADDR
7017 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
7018#endif
7019#ifdef _SC_THREAD_ATTR_STACKSIZE
7020 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
7021#endif
7022#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
7023 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
7024#endif
7025#ifdef _SC_THREAD_KEYS_MAX
7026 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
7027#endif
7028#ifdef _SC_THREAD_PRIORITY_SCHEDULING
7029 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
7030#endif
7031#ifdef _SC_THREAD_PRIO_INHERIT
7032 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
7033#endif
7034#ifdef _SC_THREAD_PRIO_PROTECT
7035 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
7036#endif
7037#ifdef _SC_THREAD_PROCESS_SHARED
7038 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
7039#endif
7040#ifdef _SC_THREAD_SAFE_FUNCTIONS
7041 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
7042#endif
7043#ifdef _SC_THREAD_STACK_MIN
7044 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
7045#endif
7046#ifdef _SC_THREAD_THREADS_MAX
7047 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
7048#endif
7049#ifdef _SC_TIMERS
7050 {"SC_TIMERS", _SC_TIMERS},
7051#endif
7052#ifdef _SC_TIMER_MAX
7053 {"SC_TIMER_MAX", _SC_TIMER_MAX},
7054#endif
7055#ifdef _SC_TTY_NAME_MAX
7056 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
7057#endif
7058#ifdef _SC_TZNAME_MAX
7059 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
7060#endif
7061#ifdef _SC_T_IOV_MAX
7062 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
7063#endif
7064#ifdef _SC_UCHAR_MAX
7065 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
7066#endif
7067#ifdef _SC_UINT_MAX
7068 {"SC_UINT_MAX", _SC_UINT_MAX},
7069#endif
7070#ifdef _SC_UIO_MAXIOV
7071 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
7072#endif
7073#ifdef _SC_ULONG_MAX
7074 {"SC_ULONG_MAX", _SC_ULONG_MAX},
7075#endif
7076#ifdef _SC_USHRT_MAX
7077 {"SC_USHRT_MAX", _SC_USHRT_MAX},
7078#endif
7079#ifdef _SC_VERSION
7080 {"SC_VERSION", _SC_VERSION},
7081#endif
7082#ifdef _SC_WORD_BIT
7083 {"SC_WORD_BIT", _SC_WORD_BIT},
7084#endif
7085#ifdef _SC_XBS5_ILP32_OFF32
7086 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
7087#endif
7088#ifdef _SC_XBS5_ILP32_OFFBIG
7089 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
7090#endif
7091#ifdef _SC_XBS5_LP64_OFF64
7092 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
7093#endif
7094#ifdef _SC_XBS5_LPBIG_OFFBIG
7095 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
7096#endif
7097#ifdef _SC_XOPEN_CRYPT
7098 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
7099#endif
7100#ifdef _SC_XOPEN_ENH_I18N
7101 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
7102#endif
7103#ifdef _SC_XOPEN_LEGACY
7104 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
7105#endif
7106#ifdef _SC_XOPEN_REALTIME
7107 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
7108#endif
7109#ifdef _SC_XOPEN_REALTIME_THREADS
7110 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
7111#endif
7112#ifdef _SC_XOPEN_SHM
7113 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
7114#endif
7115#ifdef _SC_XOPEN_UNIX
7116 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
7117#endif
7118#ifdef _SC_XOPEN_VERSION
7119 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
7120#endif
7121#ifdef _SC_XOPEN_XCU_VERSION
7122 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
7123#endif
7124#ifdef _SC_XOPEN_XPG2
7125 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
7126#endif
7127#ifdef _SC_XOPEN_XPG3
7128 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
7129#endif
7130#ifdef _SC_XOPEN_XPG4
7131 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
7132#endif
7133};
7134
7135static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007136conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007137{
7138 return conv_confname(arg, valuep, posix_constants_sysconf,
7139 sizeof(posix_constants_sysconf)
7140 / sizeof(struct constdef));
7141}
7142
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007143PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007144"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007145Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007146
7147static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007148posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007149{
7150 PyObject *result = NULL;
7151 int name;
7152
7153 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
7154 int value;
7155
7156 errno = 0;
7157 value = sysconf(name);
7158 if (value == -1 && errno != 0)
7159 posix_error();
7160 else
7161 result = PyInt_FromLong(value);
7162 }
7163 return result;
7164}
7165#endif
7166
7167
Fred Drakebec628d1999-12-15 18:31:10 +00007168/* This code is used to ensure that the tables of configuration value names
7169 * are in sorted order as required by conv_confname(), and also to build the
7170 * the exported dictionaries that are used to publish information about the
7171 * names available on the host platform.
7172 *
7173 * Sorting the table at runtime ensures that the table is properly ordered
7174 * when used, even for platforms we're not able to test on. It also makes
7175 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00007176 */
Fred Drakebec628d1999-12-15 18:31:10 +00007177
7178static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007179cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00007180{
7181 const struct constdef *c1 =
7182 (const struct constdef *) v1;
7183 const struct constdef *c2 =
7184 (const struct constdef *) v2;
7185
7186 return strcmp(c1->name, c2->name);
7187}
7188
7189static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007190setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00007191 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007192{
Fred Drakebec628d1999-12-15 18:31:10 +00007193 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00007194 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00007195
7196 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
7197 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00007198 if (d == NULL)
7199 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007200
Barry Warsaw3155db32000-04-13 15:20:40 +00007201 for (i=0; i < tablesize; ++i) {
7202 PyObject *o = PyInt_FromLong(table[i].value);
7203 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
7204 Py_XDECREF(o);
7205 Py_DECREF(d);
7206 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007207 }
Barry Warsaw3155db32000-04-13 15:20:40 +00007208 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00007209 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00007210 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00007211}
7212
Fred Drakebec628d1999-12-15 18:31:10 +00007213/* Return -1 on failure, 0 on success. */
7214static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007215setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007216{
7217#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00007218 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00007219 sizeof(posix_constants_pathconf)
7220 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007221 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007222 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007223#endif
7224#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00007225 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00007226 sizeof(posix_constants_confstr)
7227 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007228 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007229 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007230#endif
7231#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00007232 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00007233 sizeof(posix_constants_sysconf)
7234 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007235 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007236 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007237#endif
Fred Drakebec628d1999-12-15 18:31:10 +00007238 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00007239}
Fred Draked86ed291999-12-15 15:34:33 +00007240
7241
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007242PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007243"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007244Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007245in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007246
7247static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007248posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007249{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007250 abort();
7251 /*NOTREACHED*/
7252 Py_FatalError("abort() called from Python code didn't abort!");
7253 return NULL;
7254}
Fred Drakebec628d1999-12-15 18:31:10 +00007255
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007256#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007257PyDoc_STRVAR(win32_startfile__doc__,
7258"startfile(filepath) - Start a file with its associated application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007259\n\
7260This acts like double-clicking the file in Explorer, or giving the file\n\
7261name as an argument to the DOS \"start\" command: the file is opened\n\
7262with whatever application (if any) its extension is associated.\n\
7263\n\
7264startfile returns as soon as the associated application is launched.\n\
7265There is no option to wait for the application to close, and no way\n\
7266to retrieve the application's exit status.\n\
7267\n\
7268The filepath is relative to the current directory. If you want to use\n\
7269an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007270the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00007271
7272static PyObject *
7273win32_startfile(PyObject *self, PyObject *args)
7274{
7275 char *filepath;
7276 HINSTANCE rc;
Georg Brandl402b53d2005-09-14 20:51:40 +00007277 if (!PyArg_ParseTuple(args, "et:startfile",
7278 Py_FileSystemDefaultEncoding, &filepath))
Tim Petersf58a7aa2000-09-22 10:05:54 +00007279 return NULL;
7280 Py_BEGIN_ALLOW_THREADS
7281 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
7282 Py_END_ALLOW_THREADS
Georg Brandle9f8ec92005-09-25 06:16:40 +00007283 if (rc <= (HINSTANCE)32) {
7284 PyObject *errval = win32_error("startfile", filepath);
7285 PyMem_Free(filepath);
7286 return errval;
7287 }
7288 PyMem_Free(filepath);
Tim Petersf58a7aa2000-09-22 10:05:54 +00007289 Py_INCREF(Py_None);
7290 return Py_None;
7291}
7292#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007293
Martin v. Löwis438b5342002-12-27 10:16:42 +00007294#ifdef HAVE_GETLOADAVG
7295PyDoc_STRVAR(posix_getloadavg__doc__,
7296"getloadavg() -> (float, float, float)\n\n\
7297Return the number of processes in the system run queue averaged over\n\
7298the last 1, 5, and 15 minutes or raises OSError if the load average\n\
7299was unobtainable");
7300
7301static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007302posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00007303{
7304 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00007305 if (getloadavg(loadavg, 3)!=3) {
7306 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
7307 return NULL;
7308 } else
7309 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
7310}
7311#endif
7312
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007313#ifdef MS_WINDOWS
7314
7315PyDoc_STRVAR(win32_urandom__doc__,
7316"urandom(n) -> str\n\n\
7317Return a string of n random bytes suitable for cryptographic use.");
7318
7319typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
7320 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
7321 DWORD dwFlags );
7322typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
7323 BYTE *pbBuffer );
7324
7325static CRYPTGENRANDOM pCryptGenRandom = NULL;
7326static HCRYPTPROV hCryptProv = 0;
7327
Tim Peters4ad82172004-08-30 17:02:04 +00007328static PyObject*
7329win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007330{
Tim Petersd3115382004-08-30 17:36:46 +00007331 int howMany;
7332 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007333
Tim Peters4ad82172004-08-30 17:02:04 +00007334 /* Read arguments */
Tim Peters9b279a82004-08-30 17:10:53 +00007335 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
Tim Peters4ad82172004-08-30 17:02:04 +00007336 return NULL;
Tim Peters51eba612004-08-30 17:08:02 +00007337 if (howMany < 0)
7338 return PyErr_Format(PyExc_ValueError,
7339 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007340
Tim Peters4ad82172004-08-30 17:02:04 +00007341 if (hCryptProv == 0) {
7342 HINSTANCE hAdvAPI32 = NULL;
7343 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007344
Tim Peters4ad82172004-08-30 17:02:04 +00007345 /* Obtain handle to the DLL containing CryptoAPI
7346 This should not fail */
7347 hAdvAPI32 = GetModuleHandle("advapi32.dll");
7348 if(hAdvAPI32 == NULL)
7349 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007350
Tim Peters4ad82172004-08-30 17:02:04 +00007351 /* Obtain pointers to the CryptoAPI functions
7352 This will fail on some early versions of Win95 */
7353 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
7354 hAdvAPI32,
7355 "CryptAcquireContextA");
7356 if (pCryptAcquireContext == NULL)
7357 return PyErr_Format(PyExc_NotImplementedError,
7358 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007359
Tim Peters4ad82172004-08-30 17:02:04 +00007360 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
7361 hAdvAPI32, "CryptGenRandom");
7362 if (pCryptAcquireContext == NULL)
7363 return PyErr_Format(PyExc_NotImplementedError,
7364 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007365
Tim Peters4ad82172004-08-30 17:02:04 +00007366 /* Acquire context */
7367 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
7368 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
7369 return win32_error("CryptAcquireContext", NULL);
7370 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007371
Tim Peters4ad82172004-08-30 17:02:04 +00007372 /* Allocate bytes */
Tim Petersd3115382004-08-30 17:36:46 +00007373 result = PyString_FromStringAndSize(NULL, howMany);
7374 if (result != NULL) {
7375 /* Get random data */
7376 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
7377 PyString_AS_STRING(result))) {
7378 Py_DECREF(result);
7379 return win32_error("CryptGenRandom", NULL);
7380 }
Tim Peters4ad82172004-08-30 17:02:04 +00007381 }
Tim Petersd3115382004-08-30 17:36:46 +00007382 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007383}
7384#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007385
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007386static PyMethodDef posix_methods[] = {
7387 {"access", posix_access, METH_VARARGS, posix_access__doc__},
7388#ifdef HAVE_TTYNAME
7389 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
7390#endif
7391 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
7392 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007393#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007394 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007395#endif /* HAVE_CHOWN */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007396#ifdef HAVE_LCHOWN
7397 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
7398#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00007399#ifdef HAVE_CHROOT
7400 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
7401#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007402#ifdef HAVE_CTERMID
Neal Norwitze241ce82003-02-17 18:17:05 +00007403 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007404#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00007405#ifdef HAVE_GETCWD
Neal Norwitze241ce82003-02-17 18:17:05 +00007406 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Walter Dörwald3b918c32002-11-21 20:18:46 +00007407#ifdef Py_USING_UNICODE
Neal Norwitze241ce82003-02-17 18:17:05 +00007408 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00007409#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00007410#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007411#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007412 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007413#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007414 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
7415 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
7416 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007417#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007418 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007419#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007420#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007421 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007422#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007423 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
7424 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
7425 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007426 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007427#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007428 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007429#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007430#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007431 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007432#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007433 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007434#ifdef HAVE_UNAME
Neal Norwitze241ce82003-02-17 18:17:05 +00007435 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007436#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007437 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
7438 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
7439 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007440#ifdef HAVE_TIMES
Neal Norwitze241ce82003-02-17 18:17:05 +00007441 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007442#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007443 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007444#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007445 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
7446 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007447#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00007448#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007449 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
7450 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00007451#if defined(PYOS_OS2)
7452 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
7453 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
7454#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00007455#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007456#ifdef HAVE_FORK1
Neal Norwitze241ce82003-02-17 18:17:05 +00007457 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007458#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007459#ifdef HAVE_FORK
Neal Norwitze241ce82003-02-17 18:17:05 +00007460 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007461#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007462#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Neal Norwitze241ce82003-02-17 18:17:05 +00007463 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007464#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007465#ifdef HAVE_FORKPTY
Neal Norwitze241ce82003-02-17 18:17:05 +00007466 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00007467#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007468#ifdef HAVE_GETEGID
Neal Norwitze241ce82003-02-17 18:17:05 +00007469 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007470#endif /* HAVE_GETEGID */
7471#ifdef HAVE_GETEUID
Neal Norwitze241ce82003-02-17 18:17:05 +00007472 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007473#endif /* HAVE_GETEUID */
7474#ifdef HAVE_GETGID
Neal Norwitze241ce82003-02-17 18:17:05 +00007475 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007476#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00007477#ifdef HAVE_GETGROUPS
Neal Norwitze241ce82003-02-17 18:17:05 +00007478 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007479#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007480 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007481#ifdef HAVE_GETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00007482 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007483#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007484#ifdef HAVE_GETPPID
Neal Norwitze241ce82003-02-17 18:17:05 +00007485 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007486#endif /* HAVE_GETPPID */
7487#ifdef HAVE_GETUID
Neal Norwitze241ce82003-02-17 18:17:05 +00007488 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007489#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007490#ifdef HAVE_GETLOGIN
Neal Norwitze241ce82003-02-17 18:17:05 +00007491 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00007492#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00007493#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007494 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007495#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007496#ifdef HAVE_KILLPG
7497 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
7498#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00007499#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007500 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00007501#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007502#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007503 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007504#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00007505 {"popen2", win32_popen2, METH_VARARGS},
7506 {"popen3", win32_popen3, METH_VARARGS},
7507 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00007508 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007509#else
7510#if defined(PYOS_OS2) && defined(PYCC_GCC)
7511 {"popen2", os2emx_popen2, METH_VARARGS},
7512 {"popen3", os2emx_popen3, METH_VARARGS},
7513 {"popen4", os2emx_popen4, METH_VARARGS},
7514#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00007515#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007516#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007517#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007518 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007519#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007520#ifdef HAVE_SETEUID
7521 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
7522#endif /* HAVE_SETEUID */
7523#ifdef HAVE_SETEGID
7524 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
7525#endif /* HAVE_SETEGID */
7526#ifdef HAVE_SETREUID
7527 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
7528#endif /* HAVE_SETREUID */
7529#ifdef HAVE_SETREGID
7530 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
7531#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007532#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007533 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007534#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007535#ifdef HAVE_SETGROUPS
7536 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
7537#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00007538#ifdef HAVE_GETPGID
7539 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
7540#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007541#ifdef HAVE_SETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00007542 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007543#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007544#ifdef HAVE_WAIT
Neal Norwitze241ce82003-02-17 18:17:05 +00007545 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007546#endif /* HAVE_WAIT */
Tim Petersab034fa2002-02-01 11:27:43 +00007547#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007548 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007549#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007550#ifdef HAVE_GETSID
7551 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
7552#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007553#ifdef HAVE_SETSID
Neal Norwitze241ce82003-02-17 18:17:05 +00007554 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007555#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007556#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007557 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007558#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007559#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007560 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007561#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007562#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007563 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007564#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007565 {"open", posix_open, METH_VARARGS, posix_open__doc__},
7566 {"close", posix_close, METH_VARARGS, posix_close__doc__},
7567 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
7568 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
7569 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
7570 {"read", posix_read, METH_VARARGS, posix_read__doc__},
7571 {"write", posix_write, METH_VARARGS, posix_write__doc__},
7572 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
7573 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00007574 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007575#ifdef HAVE_PIPE
Neal Norwitze241ce82003-02-17 18:17:05 +00007576 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007577#endif
7578#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007579 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007580#endif
Neal Norwitz11690112002-07-30 01:08:28 +00007581#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007582 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
7583#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007584#ifdef HAVE_DEVICE_MACROS
7585 {"major", posix_major, METH_VARARGS, posix_major__doc__},
7586 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
7587 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
7588#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007589#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007590 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007591#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007592#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007593 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007594#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007595#ifdef HAVE_UNSETENV
7596 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
7597#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00007598#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007599 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00007600#endif
Fred Drake4d1e64b2002-04-15 19:40:07 +00007601#ifdef HAVE_FCHDIR
7602 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
7603#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00007604#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007605 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007606#endif
7607#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007608 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007609#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00007610#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00007611#ifdef WCOREDUMP
7612 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
7613#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007614#ifdef WIFCONTINUED
7615 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
7616#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00007617#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007618 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007619#endif /* WIFSTOPPED */
7620#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007621 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007622#endif /* WIFSIGNALED */
7623#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007624 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007625#endif /* WIFEXITED */
7626#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007627 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007628#endif /* WEXITSTATUS */
7629#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007630 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007631#endif /* WTERMSIG */
7632#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007633 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007634#endif /* WSTOPSIG */
7635#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007636#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007637 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007638#endif
7639#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007640 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007641#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00007642#ifdef HAVE_TMPFILE
Neal Norwitze241ce82003-02-17 18:17:05 +00007643 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007644#endif
7645#ifdef HAVE_TEMPNAM
7646 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
7647#endif
7648#ifdef HAVE_TMPNAM
Neal Norwitze241ce82003-02-17 18:17:05 +00007649 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007650#endif
Fred Drakec9680921999-12-13 16:37:25 +00007651#ifdef HAVE_CONFSTR
7652 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
7653#endif
7654#ifdef HAVE_SYSCONF
7655 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
7656#endif
7657#ifdef HAVE_FPATHCONF
7658 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
7659#endif
7660#ifdef HAVE_PATHCONF
7661 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
7662#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007663 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007664#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00007665 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
7666#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007667#ifdef HAVE_GETLOADAVG
Neal Norwitze241ce82003-02-17 18:17:05 +00007668 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00007669#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007670 #ifdef MS_WINDOWS
7671 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
7672 #endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007673 {NULL, NULL} /* Sentinel */
7674};
7675
7676
Barry Warsaw4a342091996-12-19 23:50:02 +00007677static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007678ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00007679{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007680 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00007681}
7682
Guido van Rossumd48f2521997-12-05 22:19:34 +00007683#if defined(PYOS_OS2)
7684/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007685static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007686{
7687 APIRET rc;
7688 ULONG values[QSV_MAX+1];
7689 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00007690 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00007691
7692 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00007693 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007694 Py_END_ALLOW_THREADS
7695
7696 if (rc != NO_ERROR) {
7697 os2_error(rc);
7698 return -1;
7699 }
7700
Fred Drake4d1e64b2002-04-15 19:40:07 +00007701 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
7702 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
7703 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
7704 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
7705 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
7706 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
7707 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007708
7709 switch (values[QSV_VERSION_MINOR]) {
7710 case 0: ver = "2.00"; break;
7711 case 10: ver = "2.10"; break;
7712 case 11: ver = "2.11"; break;
7713 case 30: ver = "3.00"; break;
7714 case 40: ver = "4.00"; break;
7715 case 50: ver = "5.00"; break;
7716 default:
Tim Peters885d4572001-11-28 20:27:42 +00007717 PyOS_snprintf(tmp, sizeof(tmp),
7718 "%d-%d", values[QSV_VERSION_MAJOR],
7719 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007720 ver = &tmp[0];
7721 }
7722
7723 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007724 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007725 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007726
7727 /* Add Indicator of Which Drive was Used to Boot the System */
7728 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
7729 tmp[1] = ':';
7730 tmp[2] = '\0';
7731
Fred Drake4d1e64b2002-04-15 19:40:07 +00007732 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007733}
7734#endif
7735
Barry Warsaw4a342091996-12-19 23:50:02 +00007736static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007737all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00007738{
Guido van Rossum94f6f721999-01-06 18:42:14 +00007739#ifdef F_OK
7740 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007741#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007742#ifdef R_OK
7743 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007744#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007745#ifdef W_OK
7746 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007747#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007748#ifdef X_OK
7749 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007750#endif
Fred Drakec9680921999-12-13 16:37:25 +00007751#ifdef NGROUPS_MAX
7752 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
7753#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007754#ifdef TMP_MAX
7755 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
7756#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007757#ifdef WCONTINUED
7758 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
7759#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007760#ifdef WNOHANG
7761 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007762#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007763#ifdef WUNTRACED
7764 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
7765#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007766#ifdef O_RDONLY
7767 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
7768#endif
7769#ifdef O_WRONLY
7770 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
7771#endif
7772#ifdef O_RDWR
7773 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
7774#endif
7775#ifdef O_NDELAY
7776 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
7777#endif
7778#ifdef O_NONBLOCK
7779 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
7780#endif
7781#ifdef O_APPEND
7782 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
7783#endif
7784#ifdef O_DSYNC
7785 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
7786#endif
7787#ifdef O_RSYNC
7788 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
7789#endif
7790#ifdef O_SYNC
7791 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
7792#endif
7793#ifdef O_NOCTTY
7794 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
7795#endif
7796#ifdef O_CREAT
7797 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
7798#endif
7799#ifdef O_EXCL
7800 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
7801#endif
7802#ifdef O_TRUNC
7803 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
7804#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00007805#ifdef O_BINARY
7806 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
7807#endif
7808#ifdef O_TEXT
7809 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
7810#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007811#ifdef O_LARGEFILE
7812 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
7813#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00007814#ifdef O_SHLOCK
7815 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
7816#endif
7817#ifdef O_EXLOCK
7818 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
7819#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007820
Tim Peters5aa91602002-01-30 05:46:57 +00007821/* MS Windows */
7822#ifdef O_NOINHERIT
7823 /* Don't inherit in child processes. */
7824 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
7825#endif
7826#ifdef _O_SHORT_LIVED
7827 /* Optimize for short life (keep in memory). */
7828 /* MS forgot to define this one with a non-underscore form too. */
7829 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
7830#endif
7831#ifdef O_TEMPORARY
7832 /* Automatically delete when last handle is closed. */
7833 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
7834#endif
7835#ifdef O_RANDOM
7836 /* Optimize for random access. */
7837 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
7838#endif
7839#ifdef O_SEQUENTIAL
7840 /* Optimize for sequential access. */
7841 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
7842#endif
7843
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007844/* GNU extensions. */
7845#ifdef O_DIRECT
7846 /* Direct disk access. */
7847 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
7848#endif
7849#ifdef O_DIRECTORY
7850 /* Must be a directory. */
7851 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
7852#endif
7853#ifdef O_NOFOLLOW
7854 /* Do not follow links. */
7855 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
7856#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00007857
Barry Warsaw5676bd12003-01-07 20:57:09 +00007858 /* These come from sysexits.h */
7859#ifdef EX_OK
7860 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007861#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007862#ifdef EX_USAGE
7863 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007864#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007865#ifdef EX_DATAERR
7866 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007867#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007868#ifdef EX_NOINPUT
7869 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007870#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007871#ifdef EX_NOUSER
7872 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007873#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007874#ifdef EX_NOHOST
7875 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007876#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007877#ifdef EX_UNAVAILABLE
7878 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007879#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007880#ifdef EX_SOFTWARE
7881 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007882#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007883#ifdef EX_OSERR
7884 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007885#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007886#ifdef EX_OSFILE
7887 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007888#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007889#ifdef EX_CANTCREAT
7890 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007891#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007892#ifdef EX_IOERR
7893 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007894#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007895#ifdef EX_TEMPFAIL
7896 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007897#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007898#ifdef EX_PROTOCOL
7899 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007900#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007901#ifdef EX_NOPERM
7902 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007903#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007904#ifdef EX_CONFIG
7905 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007906#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007907#ifdef EX_NOTFOUND
7908 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007909#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007910
Guido van Rossum246bc171999-02-01 23:54:31 +00007911#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007912#if defined(PYOS_OS2) && defined(PYCC_GCC)
7913 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
7914 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
7915 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
7916 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
7917 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
7918 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
7919 if (ins(d, "P_PM", (long)P_PM)) return -1;
7920 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
7921 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
7922 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
7923 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
7924 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
7925 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
7926 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
7927 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
7928 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
7929 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
7930 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
7931 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
7932 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
7933#else
Guido van Rossum7d385291999-02-16 19:38:04 +00007934 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
7935 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
7936 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
7937 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
7938 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00007939#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007940#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00007941
Guido van Rossumd48f2521997-12-05 22:19:34 +00007942#if defined(PYOS_OS2)
7943 if (insertvalues(d)) return -1;
7944#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007945 return 0;
7946}
7947
7948
Tim Peters5aa91602002-01-30 05:46:57 +00007949#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007950#define INITFUNC initnt
7951#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007952
7953#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007954#define INITFUNC initos2
7955#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00007956
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00007957#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007958#define INITFUNC initposix
7959#define MODNAME "posix"
7960#endif
7961
Mark Hammondfe51c6d2002-08-02 02:27:13 +00007962PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007963INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00007964{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007965 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00007966
Fred Drake4d1e64b2002-04-15 19:40:07 +00007967 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007968 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00007969 posix__doc__);
Tim Peters5aa91602002-01-30 05:46:57 +00007970
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007971 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007972 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00007973 Py_XINCREF(v);
7974 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00007975 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00007976 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00007977
Fred Drake4d1e64b2002-04-15 19:40:07 +00007978 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00007979 return;
7980
Fred Drake4d1e64b2002-04-15 19:40:07 +00007981 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00007982 return;
7983
Fred Drake4d1e64b2002-04-15 19:40:07 +00007984 Py_INCREF(PyExc_OSError);
7985 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00007986
Guido van Rossumb3d39562000-01-31 18:41:26 +00007987#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00007988 if (posix_putenv_garbage == NULL)
7989 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00007990#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007991
Guido van Rossum14648392001-12-08 18:02:58 +00007992 stat_result_desc.name = MODNAME ".stat_result";
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007993 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
7994 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
7995 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00007996 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007997 structseq_new = StatResultType.tp_new;
7998 StatResultType.tp_new = statresult_new;
Fred Drake4d1e64b2002-04-15 19:40:07 +00007999 Py_INCREF((PyObject*) &StatResultType);
8000 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008001
Guido van Rossum14648392001-12-08 18:02:58 +00008002 statvfs_result_desc.name = MODNAME ".statvfs_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008003 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Fred Drake4d1e64b2002-04-15 19:40:07 +00008004 Py_INCREF((PyObject*) &StatVFSResultType);
8005 PyModule_AddObject(m, "statvfs_result",
8006 (PyObject*) &StatVFSResultType);
Guido van Rossumb6775db1994-08-01 11:34:53 +00008007}