blob: ba7ea7058eef65e3e910416ff31b0be1191bd4cc [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)
Martin v. Löwis14694662006-02-03 12:54:16 +0000280# define STAT win32_stat
281# define FSTAT win32_fstat
282# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000283#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
Neal Norwitz30b5c5d2005-12-19 06:05:18 +0000466 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
Guido van Rossumd48f2521997-12-05 22:19:34 +0000467 *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öwis14694662006-02-03 12:54:16 +0000671#ifdef MS_WINDOWS
672/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
673 - time stamps are restricted to second resolution
674 - file modification times suffer from forth-and-back conversions between
675 UTC and local time
676 Therefore, we implement our own stat, based on the Win32 API directly.
677*/
678#define HAVE_STAT_NSEC 1
679
680struct win32_stat{
681 int st_dev;
682 __int64 st_ino;
683 unsigned short st_mode;
684 int st_nlink;
685 int st_uid;
686 int st_gid;
687 int st_rdev;
688 __int64 st_size;
689 int st_atime;
690 int st_atime_nsec;
691 int st_mtime;
692 int st_mtime_nsec;
693 int st_ctime;
694 int st_ctime_nsec;
695};
696
697static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
698
699static void
700FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, int *time_out, int* nsec_out)
701{
702 /* XXX endianness */
703 __int64 in = *(__int64*)in_ptr;
704 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
705 /* XXX Win32 supports time stamps past 2038; we currently don't */
706 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, int);
707}
708
709/* Below, we *know* that ugo+r is 0444 */
710#if _S_IREAD != 0400
711#error Unsupported C library
712#endif
713static int
714attributes_to_mode(DWORD attr)
715{
716 int m = 0;
717 if (attr & FILE_ATTRIBUTE_DIRECTORY)
718 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
719 else
720 m |= _S_IFREG;
721 if (attr & FILE_ATTRIBUTE_READONLY)
722 m |= 0444;
723 else
724 m |= 0666;
725 return m;
726}
727
728static int
729attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *result)
730{
731 memset(result, 0, sizeof(*result));
732 result->st_mode = attributes_to_mode(info->dwFileAttributes);
733 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
734 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
735 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
736 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
737
738 return 0;
739}
740
741static int
742win32_stat(const char* path, struct win32_stat *result)
743{
744 WIN32_FILE_ATTRIBUTE_DATA info;
745 int code;
746 char *dot;
747 /* XXX not supported on Win95 and NT 3.x */
748 if (!GetFileAttributesExA(path, GetFileExInfoStandard, &info)) {
749 /* Protocol violation: we explicitly clear errno, instead of
750 setting it to a POSIX error. Callers should use GetLastError. */
751 errno = 0;
752 return -1;
753 }
754 code = attribute_data_to_stat(&info, result);
755 if (code != 0)
756 return code;
757 /* Set S_IFEXEC if it is an .exe, .bat, ... */
758 dot = strrchr(path, '.');
759 if (dot) {
760 if (stricmp(dot, ".bat") == 0 ||
761 stricmp(dot, ".cmd") == 0 ||
762 stricmp(dot, ".exe") == 0 ||
763 stricmp(dot, ".com") == 0)
764 result->st_mode |= 0111;
765 }
766 return code;
767}
768
769static int
770win32_wstat(const wchar_t* path, struct win32_stat *result)
771{
772 int code;
773 const wchar_t *dot;
774 WIN32_FILE_ATTRIBUTE_DATA info;
775 /* XXX not supported on Win95 and NT 3.x */
776 if (!GetFileAttributesExW(path, GetFileExInfoStandard, &info)) {
777 /* Protocol violation: we explicitly clear errno, instead of
778 setting it to a POSIX error. Callers should use GetLastError. */
779 errno = 0;
780 return -1;
781 }
782 code = attribute_data_to_stat(&info, result);
783 if (code < 0)
784 return code;
785 /* Set IFEXEC if it is an .exe, .bat, ... */
786 dot = wcsrchr(path, '.');
787 if (dot) {
788 if (_wcsicmp(dot, L".bat") == 0 ||
789 _wcsicmp(dot, L".cmd") == 0 ||
790 _wcsicmp(dot, L".exe") == 0 ||
791 _wcsicmp(dot, L".com") == 0)
792 result->st_mode |= 0111;
793 }
794 return code;
795}
796
797static int
798win32_fstat(int file_number, struct win32_stat *result)
799{
800 BY_HANDLE_FILE_INFORMATION info;
801 HANDLE h;
802 int type;
803
804 h = (HANDLE)_get_osfhandle(file_number);
805
806 /* Protocol violation: we explicitly clear errno, instead of
807 setting it to a POSIX error. Callers should use GetLastError. */
808 errno = 0;
809
810 if (h == INVALID_HANDLE_VALUE) {
811 /* This is really a C library error (invalid file handle).
812 We set the Win32 error to the closes one matching. */
813 SetLastError(ERROR_INVALID_HANDLE);
814 return -1;
815 }
816 memset(result, 0, sizeof(*result));
817
818 type = GetFileType(h);
819 if (type == FILE_TYPE_UNKNOWN) {
820 DWORD error = GetLastError();
821 if (error != 0) {
822 return -1;
823 }
824 /* else: valid but unknown file */
825 }
826
827 if (type != FILE_TYPE_DISK) {
828 if (type == FILE_TYPE_CHAR)
829 result->st_mode = _S_IFCHR;
830 else if (type == FILE_TYPE_PIPE)
831 result->st_mode = _S_IFIFO;
832 return 0;
833 }
834
835 if (!GetFileInformationByHandle(h, &info)) {
836 return -1;
837 }
838
839 /* similar to stat() */
840 result->st_mode = attributes_to_mode(info.dwFileAttributes);
841 result->st_size = (((__int64)info.nFileSizeHigh)<<32) + info.nFileSizeLow;
842 FILE_TIME_to_time_t_nsec(&info.ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
843 FILE_TIME_to_time_t_nsec(&info.ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
844 FILE_TIME_to_time_t_nsec(&info.ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
845 /* specific to fstat() */
846 result->st_nlink = info.nNumberOfLinks;
847 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
848 return 0;
849}
850
851#endif /* MS_WINDOWS */
852
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000853PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000854"stat_result: Result from stat or lstat.\n\n\
855This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +0000856 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000857or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
858\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +0000859Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
860or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000861\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000862See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000863
864static PyStructSequence_Field stat_result_fields[] = {
865 {"st_mode", "protection bits"},
866 {"st_ino", "inode"},
867 {"st_dev", "device"},
868 {"st_nlink", "number of hard links"},
869 {"st_uid", "user ID of owner"},
870 {"st_gid", "group ID of owner"},
871 {"st_size", "total size, in bytes"},
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000872 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
873 {NULL, "integer time of last access"},
874 {NULL, "integer time of last modification"},
875 {NULL, "integer time of last change"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000876 {"st_atime", "time of last access"},
877 {"st_mtime", "time of last modification"},
878 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000879#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000880 {"st_blksize", "blocksize for filesystem I/O"},
881#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000882#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000883 {"st_blocks", "number of blocks allocated"},
884#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000885#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000886 {"st_rdev", "device type (if inode device)"},
887#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +0000888#ifdef HAVE_STRUCT_STAT_ST_FLAGS
889 {"st_flags", "user defined flags for file"},
890#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +0000891#ifdef HAVE_STRUCT_STAT_ST_GEN
892 {"st_gen", "generation number"},
893#endif
894#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
895 {"st_birthtime", "time of creation"},
896#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000897 {0}
898};
899
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000900#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000901#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000902#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000903#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000904#endif
905
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000906#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000907#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
908#else
909#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
910#endif
911
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000912#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000913#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
914#else
915#define ST_RDEV_IDX ST_BLOCKS_IDX
916#endif
917
Hye-Shik Chang5f937a72005-06-02 13:09:30 +0000918#ifdef HAVE_STRUCT_STAT_ST_FLAGS
919#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
920#else
921#define ST_FLAGS_IDX ST_RDEV_IDX
922#endif
923
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +0000924#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +0000925#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +0000926#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +0000927#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +0000928#endif
929
930#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
931#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
932#else
933#define ST_BIRTHTIME_IDX ST_GEN_IDX
934#endif
935
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000936static PyStructSequence_Desc stat_result_desc = {
937 "stat_result", /* name */
938 stat_result__doc__, /* doc */
939 stat_result_fields,
940 10
941};
942
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000943PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000944"statvfs_result: Result from statvfs or fstatvfs.\n\n\
945This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +0000946 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000947or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000948\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000949See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000950
951static PyStructSequence_Field statvfs_result_fields[] = {
952 {"f_bsize", },
953 {"f_frsize", },
954 {"f_blocks", },
955 {"f_bfree", },
956 {"f_bavail", },
957 {"f_files", },
958 {"f_ffree", },
959 {"f_favail", },
960 {"f_flag", },
961 {"f_namemax",},
962 {0}
963};
964
965static PyStructSequence_Desc statvfs_result_desc = {
966 "statvfs_result", /* name */
967 statvfs_result__doc__, /* doc */
968 statvfs_result_fields,
969 10
970};
971
972static PyTypeObject StatResultType;
973static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000974static newfunc structseq_new;
975
976static PyObject *
977statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
978{
979 PyStructSequence *result;
980 int i;
981
982 result = (PyStructSequence*)structseq_new(type, args, kwds);
983 if (!result)
984 return NULL;
985 /* If we have been initialized from a tuple,
986 st_?time might be set to None. Initialize it
987 from the int slots. */
988 for (i = 7; i <= 9; i++) {
989 if (result->ob_item[i+3] == Py_None) {
990 Py_DECREF(Py_None);
991 Py_INCREF(result->ob_item[i]);
992 result->ob_item[i+3] = result->ob_item[i];
993 }
994 }
995 return (PyObject*)result;
996}
997
998
999
1000/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001001static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001002
1003PyDoc_STRVAR(stat_float_times__doc__,
1004"stat_float_times([newval]) -> oldval\n\n\
1005Determine whether os.[lf]stat represents time stamps as float objects.\n\
1006If newval is True, future calls to stat() return floats, if it is False,\n\
1007future calls return ints. \n\
1008If newval is omitted, return the current setting.\n");
1009
1010static PyObject*
1011stat_float_times(PyObject* self, PyObject *args)
1012{
1013 int newval = -1;
1014 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1015 return NULL;
1016 if (newval == -1)
1017 /* Return old value */
1018 return PyBool_FromLong(_stat_float_times);
1019 _stat_float_times = newval;
1020 Py_INCREF(Py_None);
1021 return Py_None;
1022}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001023
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001024static void
1025fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1026{
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001027 PyObject *fval,*ival;
1028#if SIZEOF_TIME_T > SIZEOF_LONG
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00001029 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001030#else
1031 ival = PyInt_FromLong((long)sec);
1032#endif
1033 if (_stat_float_times) {
1034 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1035 } else {
1036 fval = ival;
1037 Py_INCREF(fval);
1038 }
1039 PyStructSequence_SET_ITEM(v, index, ival);
1040 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001041}
1042
Tim Peters5aa91602002-01-30 05:46:57 +00001043/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001044 (used by posix_stat() and posix_fstat()) */
1045static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001046_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001047{
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001048 unsigned long ansec, mnsec, cnsec;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001049 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +00001050 if (v == NULL)
1051 return NULL;
1052
Martin v. Löwis14694662006-02-03 12:54:16 +00001053 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001054#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001055 PyStructSequence_SET_ITEM(v, 1,
Martin v. Löwis14694662006-02-03 12:54:16 +00001056 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001057#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001058 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001059#endif
1060#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +00001061 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwis14694662006-02-03 12:54:16 +00001062 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001063#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001064 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001065#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001066 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st->st_nlink));
1067 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st->st_uid));
1068 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001069#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001070 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwis14694662006-02-03 12:54:16 +00001071 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001072#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001073 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001074#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001075
Martin v. Löwis14694662006-02-03 12:54:16 +00001076#if defined(HAVE_STAT_TV_NSEC)
1077 ansec = st->st_atim.tv_nsec;
1078 mnsec = st->st_mtim.tv_nsec;
1079 cnsec = st->st_ctim.tv_nsec;
1080#elif defined(HAVE_STAT_TV_NSEC2)
1081 ansec = st->st_atimespec.tv_nsec;
1082 mnsec = st->st_mtimespec.tv_nsec;
1083 cnsec = st->st_ctimespec.tv_nsec;
1084#elif defined(HAVE_STAT_NSEC)
1085 ansec = st->st_atime_nsec;
1086 mnsec = st->st_mtime_nsec;
1087 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001088#else
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001089 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001090#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001091 fill_time(v, 7, st->st_atime, ansec);
1092 fill_time(v, 8, st->st_mtime, mnsec);
1093 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001094
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001095#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +00001096 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001097 PyInt_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001098#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001099#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +00001100 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001101 PyInt_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001102#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001103#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001104 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001105 PyInt_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001106#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001107#ifdef HAVE_STRUCT_STAT_ST_GEN
1108 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001109 PyInt_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001110#endif
1111#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1112 {
1113 PyObject *val;
1114 unsigned long bsec,bnsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001115 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001116#ifdef HAVE_STAT_TV_NSEC2
Martin v. Löwis14694662006-02-03 12:54:16 +00001117 bnsec = st.st_birthtimespec->tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001118#else
1119 bnsec = 0;
1120#endif
1121 if (_stat_float_times) {
1122 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1123 } else {
1124 val = PyInt_FromLong((long)bsec);
1125 }
1126 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1127 val);
1128 }
1129#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001130#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1131 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001132 PyInt_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001133#endif
Fred Drake699f3522000-06-29 21:12:41 +00001134
1135 if (PyErr_Occurred()) {
1136 Py_DECREF(v);
1137 return NULL;
1138 }
1139
1140 return v;
1141}
1142
Martin v. Löwisd8948722004-06-02 09:57:56 +00001143#ifdef MS_WINDOWS
1144
1145/* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
1146 where / can be used in place of \ and the trailing slash is optional.
1147 Both SERVER and SHARE must have at least one character.
1148*/
1149
1150#define ISSLASHA(c) ((c) == '\\' || (c) == '/')
1151#define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
1152#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
1153
Tim Peters4ad82172004-08-30 17:02:04 +00001154static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001155IsUNCRootA(char *path, int pathlen)
1156{
1157 #define ISSLASH ISSLASHA
1158
1159 int i, share;
1160
1161 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1162 /* minimum UNCRoot is \\x\y */
1163 return FALSE;
1164 for (i = 2; i < pathlen ; i++)
1165 if (ISSLASH(path[i])) break;
1166 if (i == 2 || i == pathlen)
1167 /* do not allow \\\SHARE or \\SERVER */
1168 return FALSE;
1169 share = i+1;
1170 for (i = share; i < pathlen; i++)
1171 if (ISSLASH(path[i])) break;
1172 return (i != share && (i == pathlen || i == pathlen-1));
1173
1174 #undef ISSLASH
1175}
1176
1177#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters4ad82172004-08-30 17:02:04 +00001178static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001179IsUNCRootW(Py_UNICODE *path, int pathlen)
1180{
1181 #define ISSLASH ISSLASHW
1182
1183 int i, share;
1184
1185 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1186 /* minimum UNCRoot is \\x\y */
1187 return FALSE;
1188 for (i = 2; i < pathlen ; i++)
1189 if (ISSLASH(path[i])) break;
1190 if (i == 2 || i == pathlen)
1191 /* do not allow \\\SHARE or \\SERVER */
1192 return FALSE;
1193 share = i+1;
1194 for (i = share; i < pathlen; i++)
1195 if (ISSLASH(path[i])) break;
1196 return (i != share && (i == pathlen || i == pathlen-1));
1197
1198 #undef ISSLASH
1199}
1200#endif /* Py_WIN_WIDE_FILENAMES */
1201#endif /* MS_WINDOWS */
1202
Barry Warsaw53699e91996-12-10 23:23:01 +00001203static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001204posix_do_stat(PyObject *self, PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001205 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001206#ifdef __VMS
1207 int (*statfunc)(const char *, STRUCT_STAT *, ...),
1208#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001209 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001210#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001211 char *wformat,
1212 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001213{
Fred Drake699f3522000-06-29 21:12:41 +00001214 STRUCT_STAT st;
Tim Peters500bd032001-12-19 19:05:01 +00001215 char *path = NULL; /* pass this to stat; do not free() it */
1216 char *pathfree = NULL; /* this memory must be free'd */
Guido van Rossumff4949e1992-08-05 19:58:53 +00001217 int res;
Martin v. Löwis14694662006-02-03 12:54:16 +00001218 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001219
1220#ifdef Py_WIN_WIDE_FILENAMES
1221 /* If on wide-character-capable OS see if argument
1222 is Unicode and if so use wide API. */
1223 if (unicode_file_names()) {
1224 PyUnicodeObject *po;
1225 if (PyArg_ParseTuple(args, wformat, &po)) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001226 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
1227
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001228 Py_BEGIN_ALLOW_THREADS
1229 /* PyUnicode_AS_UNICODE result OK without
1230 thread lock as it is a simple dereference. */
1231 res = wstatfunc(wpath, &st);
1232 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001233
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001234 if (res != 0)
Martin v. Löwis14694662006-02-03 12:54:16 +00001235 return win32_error_unicode("stat", wpath);
1236 return _pystat_fromstructstat(&st);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001237 }
1238 /* Drop the argument parsing error as narrow strings
1239 are also valid. */
1240 PyErr_Clear();
1241 }
1242#endif
1243
Tim Peters5aa91602002-01-30 05:46:57 +00001244 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +00001245 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001246 return NULL;
Tim Peters500bd032001-12-19 19:05:01 +00001247 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +00001248
Barry Warsaw53699e91996-12-10 23:23:01 +00001249 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001250 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00001251 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001252
1253 if (res != 0) {
1254#ifdef MS_WINDOWS
1255 result = win32_error("stat", pathfree);
1256#else
1257 result = posix_error_with_filename(pathfree);
1258#endif
1259 }
1260 else
1261 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001262
Tim Peters500bd032001-12-19 19:05:01 +00001263 PyMem_Free(pathfree);
Martin v. Löwis14694662006-02-03 12:54:16 +00001264 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001265}
1266
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001267/* POSIX methods */
1268
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001269PyDoc_STRVAR(posix_access__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001270"access(path, mode) -> 1 if granted, 0 otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001271Use the real uid/gid to test for access to a path. Note that most\n\
1272operations will use the effective uid/gid, therefore this routine can\n\
1273be used in a suid/sgid environment to test if the invoking user has the\n\
1274specified access to the path. The mode argument can be F_OK to test\n\
1275existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001276
1277static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001278posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001279{
Guido van Rossum015f22a1999-01-06 22:52:38 +00001280 char *path;
1281 int mode;
1282 int res;
1283
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001284#ifdef Py_WIN_WIDE_FILENAMES
1285 if (unicode_file_names()) {
1286 PyUnicodeObject *po;
1287 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1288 Py_BEGIN_ALLOW_THREADS
1289 /* PyUnicode_AS_UNICODE OK without thread lock as
1290 it is a simple dereference. */
1291 res = _waccess(PyUnicode_AS_UNICODE(po), mode);
1292 Py_END_ALLOW_THREADS
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001293 return PyBool_FromLong(res == 0);
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001294 }
1295 /* Drop the argument parsing error as narrow strings
1296 are also valid. */
1297 PyErr_Clear();
1298 }
1299#endif
Martin v. Löwisb60ae992005-03-08 09:10:29 +00001300 if (!PyArg_ParseTuple(args, "eti:access",
1301 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +00001302 return NULL;
1303 Py_BEGIN_ALLOW_THREADS
1304 res = access(path, mode);
1305 Py_END_ALLOW_THREADS
Neal Norwitz24b3c222005-09-19 06:43:44 +00001306 PyMem_Free(path);
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001307 return PyBool_FromLong(res == 0);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001308}
1309
Guido van Rossumd371ff11999-01-25 16:12:23 +00001310#ifndef F_OK
1311#define F_OK 0
1312#endif
1313#ifndef R_OK
1314#define R_OK 4
1315#endif
1316#ifndef W_OK
1317#define W_OK 2
1318#endif
1319#ifndef X_OK
1320#define X_OK 1
1321#endif
1322
1323#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001324PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001325"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001326Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001327
1328static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001329posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001330{
Guido van Rossum94f6f721999-01-06 18:42:14 +00001331 int id;
1332 char *ret;
1333
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001334 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +00001335 return NULL;
1336
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001337#if defined(__VMS)
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +00001338 /* file descriptor 0 only, the default input device (stdin) */
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001339 if (id == 0) {
1340 ret = ttyname();
1341 }
1342 else {
1343 ret = NULL;
1344 }
1345#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00001346 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001347#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001348 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001349 return posix_error();
1350 return PyString_FromString(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001351}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001352#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001353
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001354#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001355PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001356"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001357Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001358
1359static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001360posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001361{
1362 char *ret;
1363 char buffer[L_ctermid];
1364
Greg Wardb48bc172000-03-01 21:51:56 +00001365#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001366 ret = ctermid_r(buffer);
1367#else
1368 ret = ctermid(buffer);
1369#endif
1370 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001371 return posix_error();
1372 return PyString_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001373}
1374#endif
1375
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001376PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001377"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001378Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001379
Barry Warsaw53699e91996-12-10 23:23:01 +00001380static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001381posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001382{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001383#ifdef MS_WINDOWS
1384 return posix_1str(args, "et:chdir", chdir, "U:chdir", _wchdir);
1385#elif defined(PYOS_OS2) && defined(PYCC_GCC)
1386 return posix_1str(args, "et:chdir", _chdir2, NULL, NULL);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001387#elif defined(__VMS)
Tim Peters11b23062003-04-23 02:39:17 +00001388 return posix_1str(args, "et:chdir", (int (*)(const char *))chdir,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001389 NULL, NULL);
1390#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001391 return posix_1str(args, "et:chdir", chdir, NULL, NULL);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001392#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001393}
1394
Fred Drake4d1e64b2002-04-15 19:40:07 +00001395#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001396PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001397"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001398Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001399opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001400
1401static PyObject *
1402posix_fchdir(PyObject *self, PyObject *fdobj)
1403{
1404 return posix_fildes(fdobj, fchdir);
1405}
1406#endif /* HAVE_FCHDIR */
1407
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001408
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001409PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001410"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001411Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001412
Barry Warsaw53699e91996-12-10 23:23:01 +00001413static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001414posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001415{
Mark Hammondef8b6542001-05-13 08:04:26 +00001416 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +00001417 int i;
1418 int res;
Mark Hammond817c9292003-12-03 01:22:38 +00001419#ifdef Py_WIN_WIDE_FILENAMES
1420 if (unicode_file_names()) {
1421 PyUnicodeObject *po;
1422 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1423 Py_BEGIN_ALLOW_THREADS
1424 res = _wchmod(PyUnicode_AS_UNICODE(po), i);
1425 Py_END_ALLOW_THREADS
1426 if (res < 0)
1427 return posix_error_with_unicode_filename(
1428 PyUnicode_AS_UNICODE(po));
1429 Py_INCREF(Py_None);
1430 return Py_None;
1431 }
1432 /* Drop the argument parsing error as narrow strings
1433 are also valid. */
1434 PyErr_Clear();
1435 }
1436#endif /* Py_WIN_WIDE_FILENAMES */
1437 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
Mark Hammondef8b6542001-05-13 08:04:26 +00001438 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +00001439 return NULL;
1440 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +00001441 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001442 Py_END_ALLOW_THREADS
1443 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001444 return posix_error_with_allocated_filename(path);
1445 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001446 Py_INCREF(Py_None);
1447 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001448}
1449
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001450
Martin v. Löwis244edc82001-10-04 22:44:26 +00001451#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001452PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001453"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001454Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00001455
1456static PyObject *
1457posix_chroot(PyObject *self, PyObject *args)
1458{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001459 return posix_1str(args, "et:chroot", chroot, NULL, NULL);
Martin v. Löwis244edc82001-10-04 22:44:26 +00001460}
1461#endif
1462
Guido van Rossum21142a01999-01-08 21:05:37 +00001463#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001464PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001465"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001466force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001467
1468static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001469posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001470{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001471 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001472}
1473#endif /* HAVE_FSYNC */
1474
1475#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00001476
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00001477#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00001478extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1479#endif
1480
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001481PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001482"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00001483force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001484 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001485
1486static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001487posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001488{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001489 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001490}
1491#endif /* HAVE_FDATASYNC */
1492
1493
Fredrik Lundh10723342000-07-10 16:38:09 +00001494#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001495PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001496"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001497Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001498
Barry Warsaw53699e91996-12-10 23:23:01 +00001499static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001500posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001501{
Mark Hammondef8b6542001-05-13 08:04:26 +00001502 char *path = NULL;
Fredrik Lundh44328e62000-07-10 15:59:30 +00001503 int uid, gid;
1504 int res;
Tim Peters5aa91602002-01-30 05:46:57 +00001505 if (!PyArg_ParseTuple(args, "etii:chown",
1506 Py_FileSystemDefaultEncoding, &path,
Mark Hammondef8b6542001-05-13 08:04:26 +00001507 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +00001508 return NULL;
1509 Py_BEGIN_ALLOW_THREADS
1510 res = chown(path, (uid_t) uid, (gid_t) gid);
1511 Py_END_ALLOW_THREADS
1512 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001513 return posix_error_with_allocated_filename(path);
1514 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +00001515 Py_INCREF(Py_None);
1516 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001517}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001518#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001519
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001520#ifdef HAVE_LCHOWN
1521PyDoc_STRVAR(posix_lchown__doc__,
1522"lchown(path, uid, gid)\n\n\
1523Change the owner and group id of path to the numeric uid and gid.\n\
1524This function will not follow symbolic links.");
1525
1526static PyObject *
1527posix_lchown(PyObject *self, PyObject *args)
1528{
1529 char *path = NULL;
1530 int uid, gid;
1531 int res;
1532 if (!PyArg_ParseTuple(args, "etii:lchown",
1533 Py_FileSystemDefaultEncoding, &path,
1534 &uid, &gid))
1535 return NULL;
1536 Py_BEGIN_ALLOW_THREADS
1537 res = lchown(path, (uid_t) uid, (gid_t) gid);
1538 Py_END_ALLOW_THREADS
Tim Peters11b23062003-04-23 02:39:17 +00001539 if (res < 0)
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001540 return posix_error_with_allocated_filename(path);
1541 PyMem_Free(path);
1542 Py_INCREF(Py_None);
1543 return Py_None;
1544}
1545#endif /* HAVE_LCHOWN */
1546
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001547
Guido van Rossum36bc6801995-06-14 22:54:23 +00001548#ifdef HAVE_GETCWD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001549PyDoc_STRVAR(posix_getcwd__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001550"getcwd() -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001551Return a string representing the current working directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001552
Barry Warsaw53699e91996-12-10 23:23:01 +00001553static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001554posix_getcwd(PyObject *self, PyObject *noargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001555{
1556 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +00001557 char *res;
Neal Norwitze241ce82003-02-17 18:17:05 +00001558
Barry Warsaw53699e91996-12-10 23:23:01 +00001559 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001560#if defined(PYOS_OS2) && defined(PYCC_GCC)
1561 res = _getcwd2(buf, sizeof buf);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001562#else
Guido van Rossumff4949e1992-08-05 19:58:53 +00001563 res = getcwd(buf, sizeof buf);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001564#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001565 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001566 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001567 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001568 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001569}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001570
Walter Dörwald3b918c32002-11-21 20:18:46 +00001571#ifdef Py_USING_UNICODE
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001572PyDoc_STRVAR(posix_getcwdu__doc__,
1573"getcwdu() -> path\n\n\
1574Return a unicode string representing the current working directory.");
1575
1576static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001577posix_getcwdu(PyObject *self, PyObject *noargs)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001578{
1579 char buf[1026];
1580 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001581
1582#ifdef Py_WIN_WIDE_FILENAMES
1583 if (unicode_file_names()) {
1584 wchar_t *wres;
1585 wchar_t wbuf[1026];
1586 Py_BEGIN_ALLOW_THREADS
1587 wres = _wgetcwd(wbuf, sizeof wbuf/ sizeof wbuf[0]);
1588 Py_END_ALLOW_THREADS
1589 if (wres == NULL)
1590 return posix_error();
1591 return PyUnicode_FromWideChar(wbuf, wcslen(wbuf));
1592 }
1593#endif
1594
1595 Py_BEGIN_ALLOW_THREADS
1596#if defined(PYOS_OS2) && defined(PYCC_GCC)
1597 res = _getcwd2(buf, sizeof buf);
1598#else
1599 res = getcwd(buf, sizeof buf);
1600#endif
1601 Py_END_ALLOW_THREADS
1602 if (res == NULL)
1603 return posix_error();
1604 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
1605}
Guido van Rossum36bc6801995-06-14 22:54:23 +00001606#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00001607#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001608
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001609
Guido van Rossumb6775db1994-08-01 11:34:53 +00001610#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001611PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001612"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001613Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001614
Barry Warsaw53699e91996-12-10 23:23:01 +00001615static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001616posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001617{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001618 return posix_2str(args, "etet:link", link, NULL, NULL);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001619}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001620#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001621
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001622
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001623PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001624"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001625Return a list containing the names of the entries in the directory.\n\
1626\n\
1627 path: path of directory to list\n\
1628\n\
1629The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001630entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001631
Barry Warsaw53699e91996-12-10 23:23:01 +00001632static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001633posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001634{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001635 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001636 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001637#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001638
Barry Warsaw53699e91996-12-10 23:23:01 +00001639 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001640 HANDLE hFindFile;
1641 WIN32_FIND_DATA FileData;
Mark Hammondef8b6542001-05-13 08:04:26 +00001642 /* MAX_PATH characters could mean a bigger encoded string */
1643 char namebuf[MAX_PATH*2+5];
1644 char *bufptr = namebuf;
1645 int len = sizeof(namebuf)/sizeof(namebuf[0]);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001646
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001647#ifdef Py_WIN_WIDE_FILENAMES
1648 /* If on wide-character-capable OS see if argument
1649 is Unicode and if so use wide API. */
1650 if (unicode_file_names()) {
1651 PyUnicodeObject *po;
1652 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
1653 WIN32_FIND_DATAW wFileData;
1654 Py_UNICODE wnamebuf[MAX_PATH*2+5];
1655 Py_UNICODE wch;
1656 wcsncpy(wnamebuf, PyUnicode_AS_UNICODE(po), MAX_PATH);
1657 wnamebuf[MAX_PATH] = L'\0';
1658 len = wcslen(wnamebuf);
1659 wch = (len > 0) ? wnamebuf[len-1] : L'\0';
1660 if (wch != L'/' && wch != L'\\' && wch != L':')
1661 wnamebuf[len++] = L'/';
1662 wcscpy(wnamebuf + len, L"*.*");
1663 if ((d = PyList_New(0)) == NULL)
1664 return NULL;
1665 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
1666 if (hFindFile == INVALID_HANDLE_VALUE) {
1667 errno = GetLastError();
1668 if (errno == ERROR_FILE_NOT_FOUND) {
1669 return d;
1670 }
1671 Py_DECREF(d);
1672 return win32_error_unicode("FindFirstFileW", wnamebuf);
1673 }
1674 do {
1675 if (wFileData.cFileName[0] == L'.' &&
1676 (wFileData.cFileName[1] == L'\0' ||
1677 wFileData.cFileName[1] == L'.' &&
1678 wFileData.cFileName[2] == L'\0'))
1679 continue;
1680 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
1681 if (v == NULL) {
1682 Py_DECREF(d);
1683 d = NULL;
1684 break;
1685 }
1686 if (PyList_Append(d, v) != 0) {
1687 Py_DECREF(v);
1688 Py_DECREF(d);
1689 d = NULL;
1690 break;
1691 }
1692 Py_DECREF(v);
1693 } while (FindNextFileW(hFindFile, &wFileData) == TRUE);
1694
1695 if (FindClose(hFindFile) == FALSE) {
1696 Py_DECREF(d);
1697 return win32_error_unicode("FindClose", wnamebuf);
1698 }
1699 return d;
1700 }
1701 /* Drop the argument parsing error as narrow strings
1702 are also valid. */
1703 PyErr_Clear();
1704 }
1705#endif
1706
Tim Peters5aa91602002-01-30 05:46:57 +00001707 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001708 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +00001709 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +00001710 if (len > 0) {
1711 char ch = namebuf[len-1];
1712 if (ch != SEP && ch != ALTSEP && ch != ':')
1713 namebuf[len++] = '/';
1714 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001715 strcpy(namebuf + len, "*.*");
1716
Barry Warsaw53699e91996-12-10 23:23:01 +00001717 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001718 return NULL;
1719
1720 hFindFile = FindFirstFile(namebuf, &FileData);
1721 if (hFindFile == INVALID_HANDLE_VALUE) {
1722 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +00001723 if (errno == ERROR_FILE_NOT_FOUND)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001724 return d;
1725 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00001726 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001727 }
1728 do {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001729 if (FileData.cFileName[0] == '.' &&
1730 (FileData.cFileName[1] == '\0' ||
1731 FileData.cFileName[1] == '.' &&
1732 FileData.cFileName[2] == '\0'))
1733 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001734 v = PyString_FromString(FileData.cFileName);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001735 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001736 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001737 d = NULL;
1738 break;
1739 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001740 if (PyList_Append(d, v) != 0) {
1741 Py_DECREF(v);
1742 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001743 d = NULL;
1744 break;
1745 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001746 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001747 } while (FindNextFile(hFindFile, &FileData) == TRUE);
1748
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001749 if (FindClose(hFindFile) == FALSE) {
1750 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00001751 return win32_error("FindClose", namebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001752 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001753
1754 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001755
Tim Peters0bb44a42000-09-15 07:44:49 +00001756#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001757
1758#ifndef MAX_PATH
1759#define MAX_PATH CCHMAXPATH
1760#endif
1761 char *name, *pt;
1762 int len;
1763 PyObject *d, *v;
1764 char namebuf[MAX_PATH+5];
1765 HDIR hdir = 1;
1766 ULONG srchcnt = 1;
1767 FILEFINDBUF3 ep;
1768 APIRET rc;
1769
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001770 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001771 return NULL;
1772 if (len >= MAX_PATH) {
1773 PyErr_SetString(PyExc_ValueError, "path too long");
1774 return NULL;
1775 }
1776 strcpy(namebuf, name);
1777 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001778 if (*pt == ALTSEP)
1779 *pt = SEP;
1780 if (namebuf[len-1] != SEP)
1781 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001782 strcpy(namebuf + len, "*.*");
1783
1784 if ((d = PyList_New(0)) == NULL)
1785 return NULL;
1786
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001787 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
1788 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001789 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001790 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
1791 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
1792 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001793
1794 if (rc != NO_ERROR) {
1795 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001796 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001797 }
1798
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001799 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001800 do {
1801 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001802 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001803 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001804
1805 strcpy(namebuf, ep.achName);
1806
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001807 /* Leave Case of Name Alone -- In Native Form */
1808 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001809
1810 v = PyString_FromString(namebuf);
1811 if (v == NULL) {
1812 Py_DECREF(d);
1813 d = NULL;
1814 break;
1815 }
1816 if (PyList_Append(d, v) != 0) {
1817 Py_DECREF(v);
1818 Py_DECREF(d);
1819 d = NULL;
1820 break;
1821 }
1822 Py_DECREF(v);
1823 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1824 }
1825
1826 return d;
1827#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001828
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001829 char *name = NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001830 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001831 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001832 struct dirent *ep;
Just van Rossum96b1c902003-03-03 17:32:15 +00001833 int arg_is_unicode = 1;
1834
1835 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
1836 arg_is_unicode = 0;
1837 PyErr_Clear();
1838 }
1839 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001840 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001841 if ((dirp = opendir(name)) == NULL) {
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001842 return posix_error_with_allocated_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001843 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001844 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001845 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001846 PyMem_Free(name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001847 return NULL;
1848 }
1849 while ((ep = readdir(dirp)) != NULL) {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001850 if (ep->d_name[0] == '.' &&
1851 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001852 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001853 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001854 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001855 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001856 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001857 d = NULL;
1858 break;
1859 }
Just van Rossum46c97842003-02-25 21:42:15 +00001860#ifdef Py_USING_UNICODE
Just van Rossum96b1c902003-03-03 17:32:15 +00001861 if (arg_is_unicode) {
Just van Rossum46c97842003-02-25 21:42:15 +00001862 PyObject *w;
1863
1864 w = PyUnicode_FromEncodedObject(v,
Tim Peters11b23062003-04-23 02:39:17 +00001865 Py_FileSystemDefaultEncoding,
Just van Rossum46c97842003-02-25 21:42:15 +00001866 "strict");
Just van Rossum6a421832003-03-04 19:30:44 +00001867 if (w != NULL) {
1868 Py_DECREF(v);
1869 v = w;
1870 }
1871 else {
1872 /* fall back to the original byte string, as
1873 discussed in patch #683592 */
1874 PyErr_Clear();
Just van Rossum46c97842003-02-25 21:42:15 +00001875 }
Just van Rossum46c97842003-02-25 21:42:15 +00001876 }
1877#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001878 if (PyList_Append(d, v) != 0) {
1879 Py_DECREF(v);
1880 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001881 d = NULL;
1882 break;
1883 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001884 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001885 }
1886 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001887 PyMem_Free(name);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001888
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001889 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001890
Tim Peters0bb44a42000-09-15 07:44:49 +00001891#endif /* which OS */
1892} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001893
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001894#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00001895/* A helper function for abspath on win32 */
1896static PyObject *
1897posix__getfullpathname(PyObject *self, PyObject *args)
1898{
1899 /* assume encoded strings wont more than double no of chars */
1900 char inbuf[MAX_PATH*2];
1901 char *inbufp = inbuf;
1902 int insize = sizeof(inbuf)/sizeof(inbuf[0]);
1903 char outbuf[MAX_PATH*2];
1904 char *temp;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001905#ifdef Py_WIN_WIDE_FILENAMES
1906 if (unicode_file_names()) {
1907 PyUnicodeObject *po;
1908 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
1909 Py_UNICODE woutbuf[MAX_PATH*2];
1910 Py_UNICODE *wtemp;
Tim Peters11b23062003-04-23 02:39:17 +00001911 if (!GetFullPathNameW(PyUnicode_AS_UNICODE(po),
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001912 sizeof(woutbuf)/sizeof(woutbuf[0]),
1913 woutbuf, &wtemp))
1914 return win32_error("GetFullPathName", "");
1915 return PyUnicode_FromUnicode(woutbuf, wcslen(woutbuf));
1916 }
1917 /* Drop the argument parsing error as narrow strings
1918 are also valid. */
1919 PyErr_Clear();
1920 }
1921#endif
Tim Peters5aa91602002-01-30 05:46:57 +00001922 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
1923 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00001924 &insize))
1925 return NULL;
1926 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
1927 outbuf, &temp))
1928 return win32_error("GetFullPathName", inbuf);
Martin v. Löwis969297f2004-06-15 18:49:58 +00001929 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
1930 return PyUnicode_Decode(outbuf, strlen(outbuf),
1931 Py_FileSystemDefaultEncoding, NULL);
1932 }
Mark Hammondef8b6542001-05-13 08:04:26 +00001933 return PyString_FromString(outbuf);
1934} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001935#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00001936
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001937PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001938"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001939Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001940
Barry Warsaw53699e91996-12-10 23:23:01 +00001941static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001942posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001943{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001944 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00001945 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001946 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001947
1948#ifdef Py_WIN_WIDE_FILENAMES
1949 if (unicode_file_names()) {
1950 PyUnicodeObject *po;
Mark Hammond05107b62003-02-19 04:08:27 +00001951 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001952 Py_BEGIN_ALLOW_THREADS
1953 /* PyUnicode_AS_UNICODE OK without thread lock as
1954 it is a simple dereference. */
1955 res = _wmkdir(PyUnicode_AS_UNICODE(po));
1956 Py_END_ALLOW_THREADS
1957 if (res < 0)
1958 return posix_error();
1959 Py_INCREF(Py_None);
1960 return Py_None;
1961 }
1962 /* Drop the argument parsing error as narrow strings
1963 are also valid. */
1964 PyErr_Clear();
1965 }
1966#endif
1967
Tim Peters5aa91602002-01-30 05:46:57 +00001968 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001969 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001970 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001971 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001972#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001973 res = mkdir(path);
1974#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001975 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001976#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001977 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001978 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001979 return posix_error_with_allocated_filename(path);
1980 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001981 Py_INCREF(Py_None);
1982 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001983}
1984
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001985
Guido van Rossumb6775db1994-08-01 11:34:53 +00001986#ifdef HAVE_NICE
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001987#if defined(HAVE_BROKEN_NICE) && defined(HAVE_SYS_RESOURCE_H)
1988#if defined(HAVE_GETPRIORITY) && !defined(PRIO_PROCESS)
1989#include <sys/resource.h>
1990#endif
1991#endif
1992
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001993PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001994"nice(inc) -> new_priority\n\n\
1995Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001996
Barry Warsaw53699e91996-12-10 23:23:01 +00001997static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001998posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00001999{
2000 int increment, value;
2001
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002002 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00002003 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002004
2005 /* There are two flavours of 'nice': one that returns the new
2006 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002007 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2008 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002009
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002010 If we are of the nice family that returns the new priority, we
2011 need to clear errno before the call, and check if errno is filled
2012 before calling posix_error() on a returnvalue of -1, because the
2013 -1 may be the actual new priority! */
2014
2015 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002016 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002017#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002018 if (value == 0)
2019 value = getpriority(PRIO_PROCESS, 0);
2020#endif
2021 if (value == -1 && errno != 0)
2022 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00002023 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002024 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002025}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002026#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002027
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002028
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002029PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002030"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002031Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002032
Barry Warsaw53699e91996-12-10 23:23:01 +00002033static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002034posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002035{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002036#ifdef MS_WINDOWS
2037 return posix_2str(args, "etet:rename", rename, "OO:rename", _wrename);
2038#else
2039 return posix_2str(args, "etet:rename", rename, NULL, NULL);
2040#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002041}
2042
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002043
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002044PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002045"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002046Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002047
Barry Warsaw53699e91996-12-10 23:23:01 +00002048static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002049posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002050{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002051#ifdef MS_WINDOWS
2052 return posix_1str(args, "et:rmdir", rmdir, "U:rmdir", _wrmdir);
2053#else
2054 return posix_1str(args, "et:rmdir", rmdir, NULL, NULL);
2055#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002056}
2057
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002058
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002059PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002060"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002061Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002062
Barry Warsaw53699e91996-12-10 23:23:01 +00002063static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002064posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002065{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002066#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00002067 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002068#else
2069 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
2070#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002071}
2072
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002073
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002074#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002075PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002076"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002077Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002078
Barry Warsaw53699e91996-12-10 23:23:01 +00002079static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002080posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002081{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002082 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002083 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002084 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002085 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002086 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002087 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00002088 Py_END_ALLOW_THREADS
2089 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002090}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002091#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002092
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002093
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002094PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002095"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002096Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002097
Barry Warsaw53699e91996-12-10 23:23:01 +00002098static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002099posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002100{
2101 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002102 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002103 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00002104 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002105 if (i < 0)
2106 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002107 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002108}
2109
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002110
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002111PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002112"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002113Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002114
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002115PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002116"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002117Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002118
Barry Warsaw53699e91996-12-10 23:23:01 +00002119static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002120posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002121{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002122#ifdef MS_WINDOWS
2123 return posix_1str(args, "et:remove", unlink, "U:remove", _wunlink);
2124#else
2125 return posix_1str(args, "et:remove", unlink, NULL, NULL);
2126#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002127}
2128
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002129
Guido van Rossumb6775db1994-08-01 11:34:53 +00002130#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002131PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002132"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002133Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002134
Barry Warsaw53699e91996-12-10 23:23:01 +00002135static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002136posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002137{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002138 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002139 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00002140
Barry Warsaw53699e91996-12-10 23:23:01 +00002141 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002142 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00002143 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002144 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002145 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002146 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00002147 u.sysname,
2148 u.nodename,
2149 u.release,
2150 u.version,
2151 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002152}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002153#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002154
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002155static int
2156extract_time(PyObject *t, long* sec, long* usec)
2157{
2158 long intval;
2159 if (PyFloat_Check(t)) {
2160 double tval = PyFloat_AsDouble(t);
2161 PyObject *intobj = t->ob_type->tp_as_number->nb_int(t);
2162 if (!intobj)
2163 return -1;
2164 intval = PyInt_AsLong(intobj);
2165 Py_DECREF(intobj);
Michael W. Hudsonb8963812005-07-05 15:21:58 +00002166 if (intval == -1 && PyErr_Occurred())
2167 return -1;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002168 *sec = intval;
Tim Peters96940cf2002-09-10 15:37:28 +00002169 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002170 if (*usec < 0)
2171 /* If rounding gave us a negative number,
2172 truncate. */
2173 *usec = 0;
2174 return 0;
2175 }
2176 intval = PyInt_AsLong(t);
2177 if (intval == -1 && PyErr_Occurred())
2178 return -1;
2179 *sec = intval;
2180 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00002181 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002182}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002183
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002184PyDoc_STRVAR(posix_utime__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002185"utime(path, (atime, utime))\n\
2186utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00002187Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002188second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002189
Barry Warsaw53699e91996-12-10 23:23:01 +00002190static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002191posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002192{
Neal Norwitz2adf2102004-06-09 01:46:02 +00002193 char *path = NULL;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002194 long atime, mtime, ausec, musec;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002195 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002196 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002197
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002198#if defined(HAVE_UTIMES)
2199 struct timeval buf[2];
2200#define ATIME buf[0].tv_sec
2201#define MTIME buf[1].tv_sec
2202#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002203/* XXX should define struct utimbuf instead, above */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002204 struct utimbuf buf;
2205#define ATIME buf.actime
2206#define MTIME buf.modtime
2207#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002208#else /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002209 time_t buf[2];
2210#define ATIME buf[0]
2211#define MTIME buf[1]
2212#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002213#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002214
Mark Hammond817c9292003-12-03 01:22:38 +00002215 int have_unicode_filename = 0;
2216#ifdef Py_WIN_WIDE_FILENAMES
2217 PyUnicodeObject *obwpath;
2218 wchar_t *wpath;
2219 if (unicode_file_names()) {
2220 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
2221 wpath = PyUnicode_AS_UNICODE(obwpath);
2222 have_unicode_filename = 1;
2223 } else
2224 /* Drop the argument parsing error as narrow strings
2225 are also valid. */
2226 PyErr_Clear();
2227 }
2228#endif /* Py_WIN_WIDE_FILENAMES */
2229
2230 if (!have_unicode_filename && \
Hye-Shik Chang2b2c9732004-01-04 13:54:25 +00002231 !PyArg_ParseTuple(args, "etO:utime",
2232 Py_FileSystemDefaultEncoding, &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002233 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002234 if (arg == Py_None) {
2235 /* optional time values not given */
2236 Py_BEGIN_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002237#ifdef Py_WIN_WIDE_FILENAMES
2238 if (have_unicode_filename)
2239 res = _wutime(wpath, NULL);
2240 else
2241#endif /* Py_WIN_WIDE_FILENAMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002242 res = utime(path, NULL);
2243 Py_END_ALLOW_THREADS
2244 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002245 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00002246 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002247 "utime() arg 2 must be a tuple (atime, mtime)");
Neal Norwitz96652712004-06-06 20:40:27 +00002248 PyMem_Free(path);
Barry Warsaw3cef8562000-05-01 16:17:24 +00002249 return NULL;
2250 }
2251 else {
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002252 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Neal Norwitz96652712004-06-06 20:40:27 +00002253 &atime, &ausec) == -1) {
2254 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002255 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002256 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002257 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Neal Norwitz96652712004-06-06 20:40:27 +00002258 &mtime, &musec) == -1) {
2259 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002260 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002261 }
Barry Warsaw3cef8562000-05-01 16:17:24 +00002262 ATIME = atime;
2263 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002264#ifdef HAVE_UTIMES
2265 buf[0].tv_usec = ausec;
2266 buf[1].tv_usec = musec;
2267 Py_BEGIN_ALLOW_THREADS
2268 res = utimes(path, buf);
2269 Py_END_ALLOW_THREADS
2270#else
Barry Warsaw3cef8562000-05-01 16:17:24 +00002271 Py_BEGIN_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002272#ifdef Py_WIN_WIDE_FILENAMES
2273 if (have_unicode_filename)
Tim Peters4ad82172004-08-30 17:02:04 +00002274 /* utime is OK with utimbuf, but _wutime insists
2275 on _utimbuf (the msvc headers assert the
Mark Hammond817c9292003-12-03 01:22:38 +00002276 underscore version is ansi) */
2277 res = _wutime(wpath, (struct _utimbuf *)UTIME_ARG);
2278 else
2279#endif /* Py_WIN_WIDE_FILENAMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002280 res = utime(path, UTIME_ARG);
2281 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002282#endif /* HAVE_UTIMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002283 }
Mark Hammond2d5914b2004-05-04 08:10:37 +00002284 if (res < 0) {
2285#ifdef Py_WIN_WIDE_FILENAMES
Neal Norwitz2adf2102004-06-09 01:46:02 +00002286 if (have_unicode_filename)
Mark Hammond2d5914b2004-05-04 08:10:37 +00002287 return posix_error_with_unicode_filename(wpath);
2288#endif /* Py_WIN_WIDE_FILENAMES */
Neal Norwitz96652712004-06-06 20:40:27 +00002289 return posix_error_with_allocated_filename(path);
Mark Hammond2d5914b2004-05-04 08:10:37 +00002290 }
Neal Norwitz96652712004-06-06 20:40:27 +00002291 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002292 Py_INCREF(Py_None);
2293 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002294#undef UTIME_ARG
2295#undef ATIME
2296#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002297}
2298
Guido van Rossum85e3b011991-06-03 12:42:10 +00002299
Guido van Rossum3b066191991-06-04 19:40:25 +00002300/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002301
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002302PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002303"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002304Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002305
Barry Warsaw53699e91996-12-10 23:23:01 +00002306static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002307posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002308{
2309 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002310 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002311 return NULL;
2312 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00002313 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002314}
2315
Martin v. Löwis114619e2002-10-07 06:44:21 +00002316#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
2317static void
2318free_string_array(char **array, int count)
2319{
2320 int i;
2321 for (i = 0; i < count; i++)
2322 PyMem_Free(array[i]);
2323 PyMem_DEL(array);
2324}
2325#endif
2326
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002327
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002328#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002329PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002330"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002331Execute an executable path with arguments, replacing current process.\n\
2332\n\
2333 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002334 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002335
Barry Warsaw53699e91996-12-10 23:23:01 +00002336static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002337posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002338{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002339 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002340 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002341 char **argvlist;
2342 int i, argc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002343 PyObject *(*getitem)(PyObject *, int);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002344
Guido van Rossum89b33251993-10-22 14:26:06 +00002345 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00002346 argv is a list or tuple of strings. */
2347
Martin v. Löwis114619e2002-10-07 06:44:21 +00002348 if (!PyArg_ParseTuple(args, "etO:execv",
2349 Py_FileSystemDefaultEncoding,
2350 &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002351 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002352 if (PyList_Check(argv)) {
2353 argc = PyList_Size(argv);
2354 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002355 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002356 else if (PyTuple_Check(argv)) {
2357 argc = PyTuple_Size(argv);
2358 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002359 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002360 else {
Fred Drake661ea262000-10-24 19:57:45 +00002361 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002362 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002363 return NULL;
2364 }
2365
Barry Warsaw53699e91996-12-10 23:23:01 +00002366 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002367 if (argvlist == NULL) {
2368 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002369 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002370 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002371 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002372 if (!PyArg_Parse((*getitem)(argv, i), "et",
2373 Py_FileSystemDefaultEncoding,
2374 &argvlist[i])) {
2375 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00002376 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002377 "execv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002378 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002379 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00002380
Guido van Rossum85e3b011991-06-03 12:42:10 +00002381 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002382 }
2383 argvlist[argc] = NULL;
2384
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002385 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002386
Guido van Rossum85e3b011991-06-03 12:42:10 +00002387 /* If we get here it's definitely an error */
2388
Martin v. Löwis114619e2002-10-07 06:44:21 +00002389 free_string_array(argvlist, argc);
2390 PyMem_Free(path);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002391 return posix_error();
2392}
2393
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002394
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002395PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002396"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002397Execute a path with arguments and environment, replacing current process.\n\
2398\n\
2399 path: path of executable file\n\
2400 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002401 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002402
Barry Warsaw53699e91996-12-10 23:23:01 +00002403static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002404posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002405{
2406 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002407 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002408 char **argvlist;
2409 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002410 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002411 int i, pos, argc, envc;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002412 PyObject *(*getitem)(PyObject *, int);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002413 int lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002414
2415 /* execve has three arguments: (path, argv, env), where
2416 argv is a list or tuple of strings and env is a dictionary
2417 like posix.environ. */
2418
Martin v. Löwis114619e2002-10-07 06:44:21 +00002419 if (!PyArg_ParseTuple(args, "etOO:execve",
2420 Py_FileSystemDefaultEncoding,
2421 &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002422 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002423 if (PyList_Check(argv)) {
2424 argc = PyList_Size(argv);
2425 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002426 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002427 else if (PyTuple_Check(argv)) {
2428 argc = PyTuple_Size(argv);
2429 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002430 }
2431 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002432 PyErr_SetString(PyExc_TypeError,
2433 "execve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002434 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002435 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002436 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002437 PyErr_SetString(PyExc_TypeError,
2438 "execve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002439 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002440 }
2441
Barry Warsaw53699e91996-12-10 23:23:01 +00002442 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002443 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002444 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002445 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002446 }
2447 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002448 if (!PyArg_Parse((*getitem)(argv, i),
Martin v. Löwis114619e2002-10-07 06:44:21 +00002449 "et;execve() arg 2 must contain only strings",
Guido van Rossum1e700d22002-10-16 16:52:11 +00002450 Py_FileSystemDefaultEncoding,
Barry Warsaw43d68b81996-12-19 22:10:44 +00002451 &argvlist[i]))
2452 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002453 lastarg = i;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002454 goto fail_1;
2455 }
2456 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002457 lastarg = argc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002458 argvlist[argc] = NULL;
2459
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002460 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002461 if (i < 0)
2462 goto fail_1;
Barry Warsaw53699e91996-12-10 23:23:01 +00002463 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002464 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002465 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002466 goto fail_1;
2467 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002468 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002469 keys = PyMapping_Keys(env);
2470 vals = PyMapping_Values(env);
2471 if (!keys || !vals)
2472 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002473 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2474 PyErr_SetString(PyExc_TypeError,
2475 "execve(): env.keys() or env.values() is not a list");
2476 goto fail_2;
2477 }
Tim Peters5aa91602002-01-30 05:46:57 +00002478
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002479 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002480 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002481 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002482
2483 key = PyList_GetItem(keys, pos);
2484 val = PyList_GetItem(vals, pos);
2485 if (!key || !val)
2486 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002487
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002488 if (!PyArg_Parse(
2489 key,
2490 "s;execve() arg 3 contains a non-string key",
2491 &k) ||
2492 !PyArg_Parse(
2493 val,
2494 "s;execve() arg 3 contains a non-string value",
2495 &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00002496 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002497 goto fail_2;
2498 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00002499
2500#if defined(PYOS_OS2)
2501 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
2502 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
2503#endif
Tim Petersc8996f52001-12-03 20:41:00 +00002504 len = PyString_Size(key) + PyString_Size(val) + 2;
2505 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002506 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002507 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002508 goto fail_2;
2509 }
Tim Petersc8996f52001-12-03 20:41:00 +00002510 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002511 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00002512#if defined(PYOS_OS2)
2513 }
2514#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002515 }
2516 envlist[envc] = 0;
2517
2518 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00002519
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002520 /* If we get here it's definitely an error */
2521
2522 (void) posix_error();
2523
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002524 fail_2:
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002525 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00002526 PyMem_DEL(envlist[envc]);
2527 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002528 fail_1:
2529 free_string_array(argvlist, lastarg);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002530 Py_XDECREF(vals);
2531 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002532 fail_0:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002533 PyMem_Free(path);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002534 return NULL;
2535}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002536#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002537
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002538
Guido van Rossuma1065681999-01-25 23:20:23 +00002539#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002540PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002541"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002542Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002543\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002544 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002545 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002546 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002547
2548static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002549posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002550{
2551 char *path;
2552 PyObject *argv;
2553 char **argvlist;
2554 int mode, i, argc;
Tim Peters79248aa2001-08-29 21:37:10 +00002555 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002556 PyObject *(*getitem)(PyObject *, int);
Guido van Rossuma1065681999-01-25 23:20:23 +00002557
2558 /* spawnv has three arguments: (mode, path, argv), where
2559 argv is a list or tuple of strings. */
2560
Martin v. Löwis114619e2002-10-07 06:44:21 +00002561 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
2562 Py_FileSystemDefaultEncoding,
2563 &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00002564 return NULL;
2565 if (PyList_Check(argv)) {
2566 argc = PyList_Size(argv);
2567 getitem = PyList_GetItem;
2568 }
2569 else if (PyTuple_Check(argv)) {
2570 argc = PyTuple_Size(argv);
2571 getitem = PyTuple_GetItem;
2572 }
2573 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002574 PyErr_SetString(PyExc_TypeError,
2575 "spawnv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002576 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002577 return NULL;
2578 }
2579
2580 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002581 if (argvlist == NULL) {
2582 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002583 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002584 }
Guido van Rossuma1065681999-01-25 23:20:23 +00002585 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002586 if (!PyArg_Parse((*getitem)(argv, i), "et",
2587 Py_FileSystemDefaultEncoding,
2588 &argvlist[i])) {
2589 free_string_array(argvlist, i);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002590 PyErr_SetString(
2591 PyExc_TypeError,
2592 "spawnv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002593 PyMem_Free(path);
Fred Drake137507e2000-06-01 02:02:46 +00002594 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00002595 }
2596 }
2597 argvlist[argc] = NULL;
2598
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002599#if defined(PYOS_OS2) && defined(PYCC_GCC)
2600 Py_BEGIN_ALLOW_THREADS
2601 spawnval = spawnv(mode, path, argvlist);
2602 Py_END_ALLOW_THREADS
2603#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002604 if (mode == _OLD_P_OVERLAY)
2605 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00002606
Tim Peters25059d32001-12-07 20:35:43 +00002607 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002608 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00002609 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002610#endif
Tim Peters5aa91602002-01-30 05:46:57 +00002611
Martin v. Löwis114619e2002-10-07 06:44:21 +00002612 free_string_array(argvlist, argc);
2613 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002614
Fred Drake699f3522000-06-29 21:12:41 +00002615 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002616 return posix_error();
2617 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002618#if SIZEOF_LONG == SIZEOF_VOID_P
2619 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002620#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00002621 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002622#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002623}
2624
2625
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002626PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002627"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002628Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002629\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002630 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002631 path: path of executable file\n\
2632 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002633 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002634
2635static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002636posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002637{
2638 char *path;
2639 PyObject *argv, *env;
2640 char **argvlist;
2641 char **envlist;
2642 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
2643 int mode, i, pos, argc, envc;
Tim Peters79248aa2001-08-29 21:37:10 +00002644 Py_intptr_t spawnval;
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002645 PyObject *(*getitem)(PyObject *, int);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002646 int lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002647
2648 /* spawnve has four arguments: (mode, path, argv, env), where
2649 argv is a list or tuple of strings and env is a dictionary
2650 like posix.environ. */
2651
Martin v. Löwis114619e2002-10-07 06:44:21 +00002652 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
2653 Py_FileSystemDefaultEncoding,
2654 &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00002655 return NULL;
2656 if (PyList_Check(argv)) {
2657 argc = PyList_Size(argv);
2658 getitem = PyList_GetItem;
2659 }
2660 else if (PyTuple_Check(argv)) {
2661 argc = PyTuple_Size(argv);
2662 getitem = PyTuple_GetItem;
2663 }
2664 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002665 PyErr_SetString(PyExc_TypeError,
2666 "spawnve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002667 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002668 }
2669 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002670 PyErr_SetString(PyExc_TypeError,
2671 "spawnve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002672 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002673 }
2674
2675 argvlist = PyMem_NEW(char *, argc+1);
2676 if (argvlist == NULL) {
2677 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002678 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002679 }
2680 for (i = 0; i < argc; i++) {
2681 if (!PyArg_Parse((*getitem)(argv, i),
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002682 "et;spawnve() arg 2 must contain only strings",
Martin v. Löwis114619e2002-10-07 06:44:21 +00002683 Py_FileSystemDefaultEncoding,
Guido van Rossuma1065681999-01-25 23:20:23 +00002684 &argvlist[i]))
2685 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002686 lastarg = i;
Guido van Rossuma1065681999-01-25 23:20:23 +00002687 goto fail_1;
2688 }
2689 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002690 lastarg = argc;
Guido van Rossuma1065681999-01-25 23:20:23 +00002691 argvlist[argc] = NULL;
2692
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002693 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002694 if (i < 0)
2695 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00002696 envlist = PyMem_NEW(char *, i + 1);
2697 if (envlist == NULL) {
2698 PyErr_NoMemory();
2699 goto fail_1;
2700 }
2701 envc = 0;
2702 keys = PyMapping_Keys(env);
2703 vals = PyMapping_Values(env);
2704 if (!keys || !vals)
2705 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002706 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2707 PyErr_SetString(PyExc_TypeError,
2708 "spawnve(): env.keys() or env.values() is not a list");
2709 goto fail_2;
2710 }
Tim Peters5aa91602002-01-30 05:46:57 +00002711
Guido van Rossuma1065681999-01-25 23:20:23 +00002712 for (pos = 0; pos < i; pos++) {
2713 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002714 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00002715
2716 key = PyList_GetItem(keys, pos);
2717 val = PyList_GetItem(vals, pos);
2718 if (!key || !val)
2719 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002720
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002721 if (!PyArg_Parse(
2722 key,
2723 "s;spawnve() arg 3 contains a non-string key",
2724 &k) ||
2725 !PyArg_Parse(
2726 val,
2727 "s;spawnve() arg 3 contains a non-string value",
2728 &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00002729 {
2730 goto fail_2;
2731 }
Tim Petersc8996f52001-12-03 20:41:00 +00002732 len = PyString_Size(key) + PyString_Size(val) + 2;
2733 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00002734 if (p == NULL) {
2735 PyErr_NoMemory();
2736 goto fail_2;
2737 }
Tim Petersc8996f52001-12-03 20:41:00 +00002738 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00002739 envlist[envc++] = p;
2740 }
2741 envlist[envc] = 0;
2742
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002743#if defined(PYOS_OS2) && defined(PYCC_GCC)
2744 Py_BEGIN_ALLOW_THREADS
2745 spawnval = spawnve(mode, path, argvlist, envlist);
2746 Py_END_ALLOW_THREADS
2747#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002748 if (mode == _OLD_P_OVERLAY)
2749 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00002750
2751 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002752 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00002753 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002754#endif
Tim Peters25059d32001-12-07 20:35:43 +00002755
Fred Drake699f3522000-06-29 21:12:41 +00002756 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002757 (void) posix_error();
2758 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002759#if SIZEOF_LONG == SIZEOF_VOID_P
2760 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002761#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00002762 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002763#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002764
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002765 fail_2:
Guido van Rossuma1065681999-01-25 23:20:23 +00002766 while (--envc >= 0)
2767 PyMem_DEL(envlist[envc]);
2768 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002769 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002770 free_string_array(argvlist, lastarg);
Guido van Rossuma1065681999-01-25 23:20:23 +00002771 Py_XDECREF(vals);
2772 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002773 fail_0:
2774 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002775 return res;
2776}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00002777
2778/* OS/2 supports spawnvp & spawnvpe natively */
2779#if defined(PYOS_OS2)
2780PyDoc_STRVAR(posix_spawnvp__doc__,
2781"spawnvp(mode, file, args)\n\n\
2782Execute the program 'file' in a new process, using the environment\n\
2783search path to find the file.\n\
2784\n\
2785 mode: mode of process creation\n\
2786 file: executable file name\n\
2787 args: tuple or list of strings");
2788
2789static PyObject *
2790posix_spawnvp(PyObject *self, PyObject *args)
2791{
2792 char *path;
2793 PyObject *argv;
2794 char **argvlist;
2795 int mode, i, argc;
2796 Py_intptr_t spawnval;
2797 PyObject *(*getitem)(PyObject *, int);
2798
2799 /* spawnvp has three arguments: (mode, path, argv), where
2800 argv is a list or tuple of strings. */
2801
2802 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
2803 Py_FileSystemDefaultEncoding,
2804 &path, &argv))
2805 return NULL;
2806 if (PyList_Check(argv)) {
2807 argc = PyList_Size(argv);
2808 getitem = PyList_GetItem;
2809 }
2810 else if (PyTuple_Check(argv)) {
2811 argc = PyTuple_Size(argv);
2812 getitem = PyTuple_GetItem;
2813 }
2814 else {
2815 PyErr_SetString(PyExc_TypeError,
2816 "spawnvp() arg 2 must be a tuple or list");
2817 PyMem_Free(path);
2818 return NULL;
2819 }
2820
2821 argvlist = PyMem_NEW(char *, argc+1);
2822 if (argvlist == NULL) {
2823 PyMem_Free(path);
2824 return PyErr_NoMemory();
2825 }
2826 for (i = 0; i < argc; i++) {
2827 if (!PyArg_Parse((*getitem)(argv, i), "et",
2828 Py_FileSystemDefaultEncoding,
2829 &argvlist[i])) {
2830 free_string_array(argvlist, i);
2831 PyErr_SetString(
2832 PyExc_TypeError,
2833 "spawnvp() arg 2 must contain only strings");
2834 PyMem_Free(path);
2835 return NULL;
2836 }
2837 }
2838 argvlist[argc] = NULL;
2839
2840 Py_BEGIN_ALLOW_THREADS
2841#if defined(PYCC_GCC)
2842 spawnval = spawnvp(mode, path, argvlist);
2843#else
2844 spawnval = _spawnvp(mode, path, argvlist);
2845#endif
2846 Py_END_ALLOW_THREADS
2847
2848 free_string_array(argvlist, argc);
2849 PyMem_Free(path);
2850
2851 if (spawnval == -1)
2852 return posix_error();
2853 else
2854 return Py_BuildValue("l", (long) spawnval);
2855}
2856
2857
2858PyDoc_STRVAR(posix_spawnvpe__doc__,
2859"spawnvpe(mode, file, args, env)\n\n\
2860Execute the program 'file' in a new process, using the environment\n\
2861search path to find the file.\n\
2862\n\
2863 mode: mode of process creation\n\
2864 file: executable file name\n\
2865 args: tuple or list of arguments\n\
2866 env: dictionary of strings mapping to strings");
2867
2868static PyObject *
2869posix_spawnvpe(PyObject *self, PyObject *args)
2870{
2871 char *path;
2872 PyObject *argv, *env;
2873 char **argvlist;
2874 char **envlist;
2875 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
2876 int mode, i, pos, argc, envc;
2877 Py_intptr_t spawnval;
2878 PyObject *(*getitem)(PyObject *, int);
2879 int lastarg = 0;
2880
2881 /* spawnvpe has four arguments: (mode, path, argv, env), where
2882 argv is a list or tuple of strings and env is a dictionary
2883 like posix.environ. */
2884
2885 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
2886 Py_FileSystemDefaultEncoding,
2887 &path, &argv, &env))
2888 return NULL;
2889 if (PyList_Check(argv)) {
2890 argc = PyList_Size(argv);
2891 getitem = PyList_GetItem;
2892 }
2893 else if (PyTuple_Check(argv)) {
2894 argc = PyTuple_Size(argv);
2895 getitem = PyTuple_GetItem;
2896 }
2897 else {
2898 PyErr_SetString(PyExc_TypeError,
2899 "spawnvpe() arg 2 must be a tuple or list");
2900 goto fail_0;
2901 }
2902 if (!PyMapping_Check(env)) {
2903 PyErr_SetString(PyExc_TypeError,
2904 "spawnvpe() arg 3 must be a mapping object");
2905 goto fail_0;
2906 }
2907
2908 argvlist = PyMem_NEW(char *, argc+1);
2909 if (argvlist == NULL) {
2910 PyErr_NoMemory();
2911 goto fail_0;
2912 }
2913 for (i = 0; i < argc; i++) {
2914 if (!PyArg_Parse((*getitem)(argv, i),
2915 "et;spawnvpe() arg 2 must contain only strings",
2916 Py_FileSystemDefaultEncoding,
2917 &argvlist[i]))
2918 {
2919 lastarg = i;
2920 goto fail_1;
2921 }
2922 }
2923 lastarg = argc;
2924 argvlist[argc] = NULL;
2925
2926 i = PyMapping_Size(env);
2927 if (i < 0)
2928 goto fail_1;
2929 envlist = PyMem_NEW(char *, i + 1);
2930 if (envlist == NULL) {
2931 PyErr_NoMemory();
2932 goto fail_1;
2933 }
2934 envc = 0;
2935 keys = PyMapping_Keys(env);
2936 vals = PyMapping_Values(env);
2937 if (!keys || !vals)
2938 goto fail_2;
2939 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2940 PyErr_SetString(PyExc_TypeError,
2941 "spawnvpe(): env.keys() or env.values() is not a list");
2942 goto fail_2;
2943 }
2944
2945 for (pos = 0; pos < i; pos++) {
2946 char *p, *k, *v;
2947 size_t len;
2948
2949 key = PyList_GetItem(keys, pos);
2950 val = PyList_GetItem(vals, pos);
2951 if (!key || !val)
2952 goto fail_2;
2953
2954 if (!PyArg_Parse(
2955 key,
2956 "s;spawnvpe() arg 3 contains a non-string key",
2957 &k) ||
2958 !PyArg_Parse(
2959 val,
2960 "s;spawnvpe() arg 3 contains a non-string value",
2961 &v))
2962 {
2963 goto fail_2;
2964 }
2965 len = PyString_Size(key) + PyString_Size(val) + 2;
2966 p = PyMem_NEW(char, len);
2967 if (p == NULL) {
2968 PyErr_NoMemory();
2969 goto fail_2;
2970 }
2971 PyOS_snprintf(p, len, "%s=%s", k, v);
2972 envlist[envc++] = p;
2973 }
2974 envlist[envc] = 0;
2975
2976 Py_BEGIN_ALLOW_THREADS
2977#if defined(PYCC_GCC)
2978 spawnval = spawnve(mode, path, argvlist, envlist);
2979#else
2980 spawnval = _spawnve(mode, path, argvlist, envlist);
2981#endif
2982 Py_END_ALLOW_THREADS
2983
2984 if (spawnval == -1)
2985 (void) posix_error();
2986 else
2987 res = Py_BuildValue("l", (long) spawnval);
2988
2989 fail_2:
2990 while (--envc >= 0)
2991 PyMem_DEL(envlist[envc]);
2992 PyMem_DEL(envlist);
2993 fail_1:
2994 free_string_array(argvlist, lastarg);
2995 Py_XDECREF(vals);
2996 Py_XDECREF(keys);
2997 fail_0:
2998 PyMem_Free(path);
2999 return res;
3000}
3001#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003002#endif /* HAVE_SPAWNV */
3003
3004
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003005#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003006PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003007"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003008Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3009\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003010Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003011
3012static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003013posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003014{
Neal Norwitze241ce82003-02-17 18:17:05 +00003015 int pid = fork1();
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003016 if (pid == -1)
3017 return posix_error();
3018 PyOS_AfterFork();
3019 return PyInt_FromLong((long)pid);
3020}
3021#endif
3022
3023
Guido van Rossumad0ee831995-03-01 10:34:45 +00003024#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003025PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003026"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003027Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003028Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003029
Barry Warsaw53699e91996-12-10 23:23:01 +00003030static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003031posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003032{
Neal Norwitze241ce82003-02-17 18:17:05 +00003033 int pid = fork();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003034 if (pid == -1)
3035 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003036 if (pid == 0)
3037 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00003038 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003039}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003040#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003041
Neal Norwitzb59798b2003-03-21 01:43:31 +00003042/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00003043/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3044#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00003045#define DEV_PTY_FILE "/dev/ptc"
3046#define HAVE_DEV_PTMX
3047#else
3048#define DEV_PTY_FILE "/dev/ptmx"
3049#endif
3050
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003051#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003052#ifdef HAVE_PTY_H
3053#include <pty.h>
3054#else
3055#ifdef HAVE_LIBUTIL_H
3056#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00003057#endif /* HAVE_LIBUTIL_H */
3058#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00003059#ifdef HAVE_STROPTS_H
3060#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003061#endif
3062#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003063
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003064#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003065PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003066"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003067Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003068
3069static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003070posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003071{
3072 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003073#ifndef HAVE_OPENPTY
3074 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003075#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003076#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003077 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003078#ifdef sun
3079 extern char *ptsname();
3080#endif
3081#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00003082
Thomas Wouters70c21a12000-07-14 14:28:33 +00003083#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00003084 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
3085 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003086#elif defined(HAVE__GETPTY)
Thomas Wouters70c21a12000-07-14 14:28:33 +00003087 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
3088 if (slave_name == NULL)
3089 return posix_error();
3090
3091 slave_fd = open(slave_name, O_RDWR);
3092 if (slave_fd < 0)
3093 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003094#else
Neal Norwitzb59798b2003-03-21 01:43:31 +00003095 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003096 if (master_fd < 0)
3097 return posix_error();
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003098 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003099 /* change permission of slave */
3100 if (grantpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003101 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003102 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003103 }
3104 /* unlock slave */
3105 if (unlockpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003106 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003107 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003108 }
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003109 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003110 slave_name = ptsname(master_fd); /* get name of slave */
3111 if (slave_name == NULL)
3112 return posix_error();
3113 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
3114 if (slave_fd < 0)
3115 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003116#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003117 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
3118 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00003119#ifndef __hpux
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003120 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00003121#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003122#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00003123#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00003124
Fred Drake8cef4cf2000-06-28 16:40:38 +00003125 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00003126
Fred Drake8cef4cf2000-06-28 16:40:38 +00003127}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003128#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003129
3130#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003131PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003132"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00003133Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
3134Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003135To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003136
3137static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003138posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003139{
Neal Norwitz24b3c222005-09-19 06:43:44 +00003140 int master_fd = -1, pid;
Tim Peters5aa91602002-01-30 05:46:57 +00003141
Fred Drake8cef4cf2000-06-28 16:40:38 +00003142 pid = forkpty(&master_fd, NULL, NULL, NULL);
3143 if (pid == -1)
3144 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003145 if (pid == 0)
3146 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00003147 return Py_BuildValue("(ii)", pid, master_fd);
3148}
3149#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003150
Guido van Rossumad0ee831995-03-01 10:34:45 +00003151#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003152PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003153"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003154Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003155
Barry Warsaw53699e91996-12-10 23:23:01 +00003156static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003157posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003158{
Barry Warsaw53699e91996-12-10 23:23:01 +00003159 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003160}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003161#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003162
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003163
Guido van Rossumad0ee831995-03-01 10:34:45 +00003164#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003165PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003166"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003167Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003168
Barry Warsaw53699e91996-12-10 23:23:01 +00003169static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003170posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003171{
Barry Warsaw53699e91996-12-10 23:23:01 +00003172 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003173}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003174#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003175
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003176
Guido van Rossumad0ee831995-03-01 10:34:45 +00003177#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003178PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003179"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003180Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003181
Barry Warsaw53699e91996-12-10 23:23:01 +00003182static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003183posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003184{
Barry Warsaw53699e91996-12-10 23:23:01 +00003185 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003186}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003187#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003188
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003189
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003190PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003191"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003192Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003193
Barry Warsaw53699e91996-12-10 23:23:01 +00003194static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003195posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003196{
Barry Warsaw53699e91996-12-10 23:23:01 +00003197 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003198}
3199
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003200
Fred Drakec9680921999-12-13 16:37:25 +00003201#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003202PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003203"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003204Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00003205
3206static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003207posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00003208{
3209 PyObject *result = NULL;
3210
Fred Drakec9680921999-12-13 16:37:25 +00003211#ifdef NGROUPS_MAX
3212#define MAX_GROUPS NGROUPS_MAX
3213#else
3214 /* defined to be 16 on Solaris7, so this should be a small number */
3215#define MAX_GROUPS 64
3216#endif
3217 gid_t grouplist[MAX_GROUPS];
3218 int n;
3219
3220 n = getgroups(MAX_GROUPS, grouplist);
3221 if (n < 0)
3222 posix_error();
3223 else {
3224 result = PyList_New(n);
3225 if (result != NULL) {
Fred Drakec9680921999-12-13 16:37:25 +00003226 int i;
3227 for (i = 0; i < n; ++i) {
Neal Norwitze241ce82003-02-17 18:17:05 +00003228 PyObject *o = PyInt_FromLong((long)grouplist[i]);
Fred Drakec9680921999-12-13 16:37:25 +00003229 if (o == NULL) {
3230 Py_DECREF(result);
3231 result = NULL;
3232 break;
3233 }
3234 PyList_SET_ITEM(result, i, o);
3235 }
3236 }
3237 }
Neal Norwitze241ce82003-02-17 18:17:05 +00003238
Fred Drakec9680921999-12-13 16:37:25 +00003239 return result;
3240}
3241#endif
3242
Martin v. Löwis606edc12002-06-13 21:09:11 +00003243#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003244PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003245"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003246Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00003247
3248static PyObject *
3249posix_getpgid(PyObject *self, PyObject *args)
3250{
3251 int pid, pgid;
3252 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
3253 return NULL;
3254 pgid = getpgid(pid);
3255 if (pgid < 0)
3256 return posix_error();
3257 return PyInt_FromLong((long)pgid);
3258}
3259#endif /* HAVE_GETPGID */
3260
3261
Guido van Rossumb6775db1994-08-01 11:34:53 +00003262#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003263PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003264"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003265Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003266
Barry Warsaw53699e91996-12-10 23:23:01 +00003267static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003268posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00003269{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003270#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00003271 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003272#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00003273 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003274#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00003275}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003276#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00003277
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003278
Guido van Rossumb6775db1994-08-01 11:34:53 +00003279#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003280PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003281"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003282Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003283
Barry Warsaw53699e91996-12-10 23:23:01 +00003284static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003285posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003286{
Guido van Rossum64933891994-10-20 21:56:42 +00003287#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00003288 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003289#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003290 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003291#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00003292 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003293 Py_INCREF(Py_None);
3294 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003295}
3296
Guido van Rossumb6775db1994-08-01 11:34:53 +00003297#endif /* HAVE_SETPGRP */
3298
Guido van Rossumad0ee831995-03-01 10:34:45 +00003299#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003300PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003301"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003302Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003303
Barry Warsaw53699e91996-12-10 23:23:01 +00003304static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003305posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003306{
Barry Warsaw53699e91996-12-10 23:23:01 +00003307 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003308}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003309#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003310
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003311
Fred Drake12c6e2d1999-12-14 21:25:03 +00003312#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003313PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003314"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003315Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00003316
3317static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003318posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00003319{
Neal Norwitze241ce82003-02-17 18:17:05 +00003320 PyObject *result = NULL;
Fred Drakea30680b2000-12-06 21:24:28 +00003321 char *name;
3322 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00003323
Fred Drakea30680b2000-12-06 21:24:28 +00003324 errno = 0;
3325 name = getlogin();
3326 if (name == NULL) {
3327 if (errno)
3328 posix_error();
3329 else
3330 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00003331 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00003332 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00003333 else
3334 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00003335 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00003336
Fred Drake12c6e2d1999-12-14 21:25:03 +00003337 return result;
3338}
3339#endif
3340
Guido van Rossumad0ee831995-03-01 10:34:45 +00003341#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003342PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003343"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003344Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003345
Barry Warsaw53699e91996-12-10 23:23:01 +00003346static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003347posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003348{
Barry Warsaw53699e91996-12-10 23:23:01 +00003349 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003350}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003351#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003352
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003353
Guido van Rossumad0ee831995-03-01 10:34:45 +00003354#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003355PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003356"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003357Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003358
Barry Warsaw53699e91996-12-10 23:23:01 +00003359static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003360posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003361{
3362 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003363 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00003364 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003365#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003366 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
3367 APIRET rc;
3368 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003369 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003370
3371 } else if (sig == XCPT_SIGNAL_KILLPROC) {
3372 APIRET rc;
3373 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003374 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003375
3376 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003377 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003378#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00003379 if (kill(pid, sig) == -1)
3380 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003381#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003382 Py_INCREF(Py_None);
3383 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003384}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003385#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003386
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003387#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003388PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003389"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003390Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003391
3392static PyObject *
3393posix_killpg(PyObject *self, PyObject *args)
3394{
3395 int pgid, sig;
3396 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
3397 return NULL;
3398 if (killpg(pgid, sig) == -1)
3399 return posix_error();
3400 Py_INCREF(Py_None);
3401 return Py_None;
3402}
3403#endif
3404
Guido van Rossumc0125471996-06-28 18:55:32 +00003405#ifdef HAVE_PLOCK
3406
3407#ifdef HAVE_SYS_LOCK_H
3408#include <sys/lock.h>
3409#endif
3410
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003411PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003412"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003413Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003414
Barry Warsaw53699e91996-12-10 23:23:01 +00003415static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003416posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00003417{
3418 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003419 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00003420 return NULL;
3421 if (plock(op) == -1)
3422 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003423 Py_INCREF(Py_None);
3424 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00003425}
3426#endif
3427
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003428
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003429#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003430PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003431"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003432Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003433
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003434#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003435#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003436static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003437async_system(const char *command)
3438{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003439 char errormsg[256], args[1024];
3440 RESULTCODES rcodes;
3441 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003442
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003443 char *shell = getenv("COMSPEC");
3444 if (!shell)
3445 shell = "cmd";
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003446
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003447 /* avoid overflowing the argument buffer */
3448 if (strlen(shell) + 3 + strlen(command) >= 1024)
3449 return ERROR_NOT_ENOUGH_MEMORY
3450
3451 args[0] = '\0';
3452 strcat(args, shell);
3453 strcat(args, "/c ");
3454 strcat(args, command);
3455
3456 /* execute asynchronously, inheriting the environment */
3457 rc = DosExecPgm(errormsg,
3458 sizeof(errormsg),
3459 EXEC_ASYNC,
3460 args,
3461 NULL,
3462 &rcodes,
3463 shell);
3464 return rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003465}
3466
Guido van Rossumd48f2521997-12-05 22:19:34 +00003467static FILE *
3468popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003469{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003470 int oldfd, tgtfd;
3471 HFILE pipeh[2];
3472 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003473
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003474 /* mode determines which of stdin or stdout is reconnected to
3475 * the pipe to the child
3476 */
3477 if (strchr(mode, 'r') != NULL) {
3478 tgt_fd = 1; /* stdout */
3479 } else if (strchr(mode, 'w')) {
3480 tgt_fd = 0; /* stdin */
3481 } else {
3482 *err = ERROR_INVALID_ACCESS;
3483 return NULL;
3484 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003485
Andrew MacIntyrea3be2582004-12-18 09:51:05 +00003486 /* setup the pipe */
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003487 if ((rc = DosCreatePipe(&pipeh[0], &pipeh[1], pipesize)) != NO_ERROR) {
3488 *err = rc;
3489 return NULL;
3490 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003491
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003492 /* prevent other threads accessing stdio */
3493 DosEnterCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003494
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003495 /* reconnect stdio and execute child */
3496 oldfd = dup(tgtfd);
3497 close(tgtfd);
3498 if (dup2(pipeh[tgtfd], tgtfd) == 0) {
3499 DosClose(pipeh[tgtfd]);
3500 rc = async_system(command);
3501 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003502
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003503 /* restore stdio */
3504 dup2(oldfd, tgtfd);
3505 close(oldfd);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003506
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003507 /* allow other threads access to stdio */
3508 DosExitCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003509
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003510 /* if execution of child was successful return file stream */
3511 if (rc == NO_ERROR)
3512 return fdopen(pipeh[1 - tgtfd], mode);
3513 else {
3514 DosClose(pipeh[1 - tgtfd]);
3515 *err = rc;
3516 return NULL;
3517 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003518}
3519
3520static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003521posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003522{
3523 char *name;
3524 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00003525 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003526 FILE *fp;
3527 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003528 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003529 return NULL;
3530 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00003531 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003532 Py_END_ALLOW_THREADS
3533 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003534 return os2_error(err);
3535
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003536 f = PyFile_FromFile(fp, name, mode, fclose);
3537 if (f != NULL)
3538 PyFile_SetBufSize(f, bufsize);
3539 return f;
3540}
3541
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003542#elif defined(PYCC_GCC)
3543
3544/* standard posix version of popen() support */
3545static PyObject *
3546posix_popen(PyObject *self, PyObject *args)
3547{
3548 char *name;
3549 char *mode = "r";
3550 int bufsize = -1;
3551 FILE *fp;
3552 PyObject *f;
3553 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
3554 return NULL;
3555 Py_BEGIN_ALLOW_THREADS
3556 fp = popen(name, mode);
3557 Py_END_ALLOW_THREADS
3558 if (fp == NULL)
3559 return posix_error();
3560 f = PyFile_FromFile(fp, name, mode, pclose);
3561 if (f != NULL)
3562 PyFile_SetBufSize(f, bufsize);
3563 return f;
3564}
3565
3566/* fork() under OS/2 has lots'o'warts
3567 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
3568 * most of this code is a ripoff of the win32 code, but using the
3569 * capabilities of EMX's C library routines
3570 */
3571
3572/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
3573#define POPEN_1 1
3574#define POPEN_2 2
3575#define POPEN_3 3
3576#define POPEN_4 4
3577
3578static PyObject *_PyPopen(char *, int, int, int);
3579static int _PyPclose(FILE *file);
3580
3581/*
3582 * Internal dictionary mapping popen* file pointers to process handles,
3583 * for use when retrieving the process exit code. See _PyPclose() below
3584 * for more information on this dictionary's use.
3585 */
3586static PyObject *_PyPopenProcs = NULL;
3587
3588/* os2emx version of popen2()
3589 *
3590 * The result of this function is a pipe (file) connected to the
3591 * process's stdin, and a pipe connected to the process's stdout.
3592 */
3593
3594static PyObject *
3595os2emx_popen2(PyObject *self, PyObject *args)
3596{
3597 PyObject *f;
3598 int tm=0;
3599
3600 char *cmdstring;
3601 char *mode = "t";
3602 int bufsize = -1;
3603 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
3604 return NULL;
3605
3606 if (*mode == 't')
3607 tm = O_TEXT;
3608 else if (*mode != 'b') {
3609 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3610 return NULL;
3611 } else
3612 tm = O_BINARY;
3613
3614 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
3615
3616 return f;
3617}
3618
3619/*
3620 * Variation on os2emx.popen2
3621 *
3622 * The result of this function is 3 pipes - the process's stdin,
3623 * stdout and stderr
3624 */
3625
3626static PyObject *
3627os2emx_popen3(PyObject *self, PyObject *args)
3628{
3629 PyObject *f;
3630 int tm = 0;
3631
3632 char *cmdstring;
3633 char *mode = "t";
3634 int bufsize = -1;
3635 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
3636 return NULL;
3637
3638 if (*mode == 't')
3639 tm = O_TEXT;
3640 else if (*mode != 'b') {
3641 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3642 return NULL;
3643 } else
3644 tm = O_BINARY;
3645
3646 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
3647
3648 return f;
3649}
3650
3651/*
3652 * Variation on os2emx.popen2
3653 *
Tim Peters11b23062003-04-23 02:39:17 +00003654 * The result of this function is 2 pipes - the processes stdin,
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003655 * and stdout+stderr combined as a single pipe.
3656 */
3657
3658static PyObject *
3659os2emx_popen4(PyObject *self, PyObject *args)
3660{
3661 PyObject *f;
3662 int tm = 0;
3663
3664 char *cmdstring;
3665 char *mode = "t";
3666 int bufsize = -1;
3667 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
3668 return NULL;
3669
3670 if (*mode == 't')
3671 tm = O_TEXT;
3672 else if (*mode != 'b') {
3673 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3674 return NULL;
3675 } else
3676 tm = O_BINARY;
3677
3678 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
3679
3680 return f;
3681}
3682
3683/* a couple of structures for convenient handling of multiple
3684 * file handles and pipes
3685 */
3686struct file_ref
3687{
3688 int handle;
3689 int flags;
3690};
3691
3692struct pipe_ref
3693{
3694 int rd;
3695 int wr;
3696};
3697
3698/* The following code is derived from the win32 code */
3699
3700static PyObject *
3701_PyPopen(char *cmdstring, int mode, int n, int bufsize)
3702{
3703 struct file_ref stdio[3];
3704 struct pipe_ref p_fd[3];
3705 FILE *p_s[3];
3706 int file_count, i, pipe_err, pipe_pid;
3707 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
3708 PyObject *f, *p_f[3];
3709
3710 /* file modes for subsequent fdopen's on pipe handles */
3711 if (mode == O_TEXT)
3712 {
3713 rd_mode = "rt";
3714 wr_mode = "wt";
3715 }
3716 else
3717 {
3718 rd_mode = "rb";
3719 wr_mode = "wb";
3720 }
3721
3722 /* prepare shell references */
3723 if ((shell = getenv("EMXSHELL")) == NULL)
3724 if ((shell = getenv("COMSPEC")) == NULL)
3725 {
3726 errno = ENOENT;
3727 return posix_error();
3728 }
3729
3730 sh_name = _getname(shell);
3731 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
3732 opt = "/c";
3733 else
3734 opt = "-c";
3735
3736 /* save current stdio fds + their flags, and set not inheritable */
3737 i = pipe_err = 0;
3738 while (pipe_err >= 0 && i < 3)
3739 {
3740 pipe_err = stdio[i].handle = dup(i);
3741 stdio[i].flags = fcntl(i, F_GETFD, 0);
3742 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
3743 i++;
3744 }
3745 if (pipe_err < 0)
3746 {
3747 /* didn't get them all saved - clean up and bail out */
3748 int saved_err = errno;
3749 while (i-- > 0)
3750 {
3751 close(stdio[i].handle);
3752 }
3753 errno = saved_err;
3754 return posix_error();
3755 }
3756
3757 /* create pipe ends */
3758 file_count = 2;
3759 if (n == POPEN_3)
3760 file_count = 3;
3761 i = pipe_err = 0;
3762 while ((pipe_err == 0) && (i < file_count))
3763 pipe_err = pipe((int *)&p_fd[i++]);
3764 if (pipe_err < 0)
3765 {
3766 /* didn't get them all made - clean up and bail out */
3767 while (i-- > 0)
3768 {
3769 close(p_fd[i].wr);
3770 close(p_fd[i].rd);
3771 }
3772 errno = EPIPE;
3773 return posix_error();
3774 }
3775
3776 /* change the actual standard IO streams over temporarily,
3777 * making the retained pipe ends non-inheritable
3778 */
3779 pipe_err = 0;
3780
3781 /* - stdin */
3782 if (dup2(p_fd[0].rd, 0) == 0)
3783 {
3784 close(p_fd[0].rd);
3785 i = fcntl(p_fd[0].wr, F_GETFD, 0);
3786 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
3787 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
3788 {
3789 close(p_fd[0].wr);
3790 pipe_err = -1;
3791 }
3792 }
3793 else
3794 {
3795 pipe_err = -1;
3796 }
3797
3798 /* - stdout */
3799 if (pipe_err == 0)
3800 {
3801 if (dup2(p_fd[1].wr, 1) == 1)
3802 {
3803 close(p_fd[1].wr);
3804 i = fcntl(p_fd[1].rd, F_GETFD, 0);
3805 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
3806 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
3807 {
3808 close(p_fd[1].rd);
3809 pipe_err = -1;
3810 }
3811 }
3812 else
3813 {
3814 pipe_err = -1;
3815 }
3816 }
3817
3818 /* - stderr, as required */
3819 if (pipe_err == 0)
3820 switch (n)
3821 {
3822 case POPEN_3:
3823 {
3824 if (dup2(p_fd[2].wr, 2) == 2)
3825 {
3826 close(p_fd[2].wr);
3827 i = fcntl(p_fd[2].rd, F_GETFD, 0);
3828 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
3829 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
3830 {
3831 close(p_fd[2].rd);
3832 pipe_err = -1;
3833 }
3834 }
3835 else
3836 {
3837 pipe_err = -1;
3838 }
3839 break;
3840 }
3841
3842 case POPEN_4:
3843 {
3844 if (dup2(1, 2) != 2)
3845 {
3846 pipe_err = -1;
3847 }
3848 break;
3849 }
3850 }
3851
3852 /* spawn the child process */
3853 if (pipe_err == 0)
3854 {
3855 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
3856 if (pipe_pid == -1)
3857 {
3858 pipe_err = -1;
3859 }
3860 else
3861 {
3862 /* save the PID into the FILE structure
3863 * NOTE: this implementation doesn't actually
3864 * take advantage of this, but do it for
3865 * completeness - AIM Apr01
3866 */
3867 for (i = 0; i < file_count; i++)
3868 p_s[i]->_pid = pipe_pid;
3869 }
3870 }
3871
3872 /* reset standard IO to normal */
3873 for (i = 0; i < 3; i++)
3874 {
3875 dup2(stdio[i].handle, i);
3876 fcntl(i, F_SETFD, stdio[i].flags);
3877 close(stdio[i].handle);
3878 }
3879
3880 /* if any remnant problems, clean up and bail out */
3881 if (pipe_err < 0)
3882 {
3883 for (i = 0; i < 3; i++)
3884 {
3885 close(p_fd[i].rd);
3886 close(p_fd[i].wr);
3887 }
3888 errno = EPIPE;
3889 return posix_error_with_filename(cmdstring);
3890 }
3891
3892 /* build tuple of file objects to return */
3893 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
3894 PyFile_SetBufSize(p_f[0], bufsize);
3895 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
3896 PyFile_SetBufSize(p_f[1], bufsize);
3897 if (n == POPEN_3)
3898 {
3899 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
3900 PyFile_SetBufSize(p_f[0], bufsize);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00003901 f = PyTuple_Pack(3, p_f[0], p_f[1], p_f[2]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003902 }
3903 else
Raymond Hettinger8ae46892003-10-12 19:09:37 +00003904 f = PyTuple_Pack(2, p_f[0], p_f[1]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003905
3906 /*
3907 * Insert the files we've created into the process dictionary
3908 * all referencing the list with the process handle and the
3909 * initial number of files (see description below in _PyPclose).
3910 * Since if _PyPclose later tried to wait on a process when all
3911 * handles weren't closed, it could create a deadlock with the
3912 * child, we spend some energy here to try to ensure that we
3913 * either insert all file handles into the dictionary or none
3914 * at all. It's a little clumsy with the various popen modes
3915 * and variable number of files involved.
3916 */
3917 if (!_PyPopenProcs)
3918 {
3919 _PyPopenProcs = PyDict_New();
3920 }
3921
3922 if (_PyPopenProcs)
3923 {
3924 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
3925 int ins_rc[3];
3926
3927 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
3928 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
3929
3930 procObj = PyList_New(2);
3931 pidObj = PyInt_FromLong((long) pipe_pid);
3932 intObj = PyInt_FromLong((long) file_count);
3933
3934 if (procObj && pidObj && intObj)
3935 {
3936 PyList_SetItem(procObj, 0, pidObj);
3937 PyList_SetItem(procObj, 1, intObj);
3938
3939 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
3940 if (fileObj[0])
3941 {
3942 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
3943 fileObj[0],
3944 procObj);
3945 }
3946 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
3947 if (fileObj[1])
3948 {
3949 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
3950 fileObj[1],
3951 procObj);
3952 }
3953 if (file_count >= 3)
3954 {
3955 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
3956 if (fileObj[2])
3957 {
3958 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
3959 fileObj[2],
3960 procObj);
3961 }
3962 }
3963
3964 if (ins_rc[0] < 0 || !fileObj[0] ||
3965 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
3966 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
3967 {
3968 /* Something failed - remove any dictionary
3969 * entries that did make it.
3970 */
3971 if (!ins_rc[0] && fileObj[0])
3972 {
3973 PyDict_DelItem(_PyPopenProcs,
3974 fileObj[0]);
3975 }
3976 if (!ins_rc[1] && fileObj[1])
3977 {
3978 PyDict_DelItem(_PyPopenProcs,
3979 fileObj[1]);
3980 }
3981 if (!ins_rc[2] && fileObj[2])
3982 {
3983 PyDict_DelItem(_PyPopenProcs,
3984 fileObj[2]);
3985 }
3986 }
3987 }
Tim Peters11b23062003-04-23 02:39:17 +00003988
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003989 /*
3990 * Clean up our localized references for the dictionary keys
3991 * and value since PyDict_SetItem will Py_INCREF any copies
3992 * that got placed in the dictionary.
3993 */
3994 Py_XDECREF(procObj);
3995 Py_XDECREF(fileObj[0]);
3996 Py_XDECREF(fileObj[1]);
3997 Py_XDECREF(fileObj[2]);
3998 }
3999
4000 /* Child is launched. */
4001 return f;
4002}
4003
4004/*
4005 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4006 * exit code for the child process and return as a result of the close.
4007 *
4008 * This function uses the _PyPopenProcs dictionary in order to map the
4009 * input file pointer to information about the process that was
4010 * originally created by the popen* call that created the file pointer.
4011 * The dictionary uses the file pointer as a key (with one entry
4012 * inserted for each file returned by the original popen* call) and a
4013 * single list object as the value for all files from a single call.
4014 * The list object contains the Win32 process handle at [0], and a file
4015 * count at [1], which is initialized to the total number of file
4016 * handles using that list.
4017 *
4018 * This function closes whichever handle it is passed, and decrements
4019 * the file count in the dictionary for the process handle pointed to
4020 * by this file. On the last close (when the file count reaches zero),
4021 * this function will wait for the child process and then return its
4022 * exit code as the result of the close() operation. This permits the
4023 * files to be closed in any order - it is always the close() of the
4024 * final handle that will return the exit code.
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004025 *
4026 * NOTE: This function is currently called with the GIL released.
4027 * hence we use the GILState API to manage our state.
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004028 */
4029
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004030static int _PyPclose(FILE *file)
4031{
4032 int result;
4033 int exit_code;
4034 int pipe_pid;
4035 PyObject *procObj, *pidObj, *intObj, *fileObj;
4036 int file_count;
4037#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004038 PyGILState_STATE state;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004039#endif
4040
4041 /* Close the file handle first, to ensure it can't block the
4042 * child from exiting if it's the last handle.
4043 */
4044 result = fclose(file);
4045
4046#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004047 state = PyGILState_Ensure();
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004048#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004049 if (_PyPopenProcs)
4050 {
4051 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4052 (procObj = PyDict_GetItem(_PyPopenProcs,
4053 fileObj)) != NULL &&
4054 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
4055 (intObj = PyList_GetItem(procObj,1)) != NULL)
4056 {
4057 pipe_pid = (int) PyInt_AsLong(pidObj);
4058 file_count = (int) PyInt_AsLong(intObj);
4059
4060 if (file_count > 1)
4061 {
4062 /* Still other files referencing process */
4063 file_count--;
4064 PyList_SetItem(procObj,1,
4065 PyInt_FromLong((long) file_count));
4066 }
4067 else
4068 {
4069 /* Last file for this process */
4070 if (result != EOF &&
4071 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
4072 {
4073 /* extract exit status */
4074 if (WIFEXITED(exit_code))
4075 {
4076 result = WEXITSTATUS(exit_code);
4077 }
4078 else
4079 {
4080 errno = EPIPE;
4081 result = -1;
4082 }
4083 }
4084 else
4085 {
4086 /* Indicate failure - this will cause the file object
4087 * to raise an I/O error and translate the last
4088 * error code from errno. We do have a problem with
4089 * last errors that overlap the normal errno table,
4090 * but that's a consistent problem with the file object.
4091 */
4092 result = -1;
4093 }
4094 }
4095
4096 /* Remove this file pointer from dictionary */
4097 PyDict_DelItem(_PyPopenProcs, fileObj);
4098
4099 if (PyDict_Size(_PyPopenProcs) == 0)
4100 {
4101 Py_DECREF(_PyPopenProcs);
4102 _PyPopenProcs = NULL;
4103 }
4104
4105 } /* if object retrieval ok */
4106
4107 Py_XDECREF(fileObj);
4108 } /* if _PyPopenProcs */
4109
4110#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004111 PyGILState_Release(state);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004112#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004113 return result;
4114}
4115
4116#endif /* PYCC_??? */
4117
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004118#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004119
4120/*
4121 * Portable 'popen' replacement for Win32.
4122 *
4123 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
4124 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00004125 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004126 */
4127
4128#include <malloc.h>
4129#include <io.h>
4130#include <fcntl.h>
4131
4132/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
4133#define POPEN_1 1
4134#define POPEN_2 2
4135#define POPEN_3 3
4136#define POPEN_4 4
4137
4138static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004139static int _PyPclose(FILE *file);
4140
4141/*
4142 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00004143 * for use when retrieving the process exit code. See _PyPclose() below
4144 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004145 */
4146static PyObject *_PyPopenProcs = NULL;
4147
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004148
4149/* popen that works from a GUI.
4150 *
4151 * The result of this function is a pipe (file) connected to the
4152 * processes stdin or stdout, depending on the requested mode.
4153 */
4154
4155static PyObject *
4156posix_popen(PyObject *self, PyObject *args)
4157{
Raymond Hettingerb5cb6652003-09-01 22:25:41 +00004158 PyObject *f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004159 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004160
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004161 char *cmdstring;
4162 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004163 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004164 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004165 return NULL;
4166
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004167 if (*mode == 'r')
4168 tm = _O_RDONLY;
4169 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00004170 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004171 return NULL;
4172 } else
4173 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00004174
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004175 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004176 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004177 return NULL;
4178 }
4179
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004180 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004181 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004182 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004183 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004184 else
4185 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
4186
4187 return f;
4188}
4189
4190/* Variation on win32pipe.popen
4191 *
4192 * The result of this function is a pipe (file) connected to the
4193 * process's stdin, and a pipe connected to the process's stdout.
4194 */
4195
4196static PyObject *
4197win32_popen2(PyObject *self, PyObject *args)
4198{
4199 PyObject *f;
4200 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00004201
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004202 char *cmdstring;
4203 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004204 int bufsize = -1;
4205 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004206 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004207
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004208 if (*mode == 't')
4209 tm = _O_TEXT;
4210 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004211 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004212 return NULL;
4213 } else
4214 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004215
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004216 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004217 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004218 return NULL;
4219 }
4220
4221 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00004222
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004223 return f;
4224}
4225
4226/*
4227 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004228 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004229 * The result of this function is 3 pipes - the process's stdin,
4230 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004231 */
4232
4233static PyObject *
4234win32_popen3(PyObject *self, PyObject *args)
4235{
4236 PyObject *f;
4237 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004238
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004239 char *cmdstring;
4240 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004241 int bufsize = -1;
4242 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004243 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004244
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004245 if (*mode == 't')
4246 tm = _O_TEXT;
4247 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004248 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004249 return NULL;
4250 } else
4251 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004252
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004253 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004254 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004255 return NULL;
4256 }
4257
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004258 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00004259
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004260 return f;
4261}
4262
4263/*
4264 * Variation on win32pipe.popen
4265 *
Tim Peters5aa91602002-01-30 05:46:57 +00004266 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004267 * and stdout+stderr combined as a single pipe.
4268 */
4269
4270static PyObject *
4271win32_popen4(PyObject *self, PyObject *args)
4272{
4273 PyObject *f;
4274 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004275
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004276 char *cmdstring;
4277 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004278 int bufsize = -1;
4279 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004280 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004281
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004282 if (*mode == 't')
4283 tm = _O_TEXT;
4284 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004285 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004286 return NULL;
4287 } else
4288 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004289
4290 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004291 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004292 return NULL;
4293 }
4294
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004295 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004296
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004297 return f;
4298}
4299
Mark Hammond08501372001-01-31 07:30:29 +00004300static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00004301_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004302 HANDLE hStdin,
4303 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00004304 HANDLE hStderr,
4305 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004306{
4307 PROCESS_INFORMATION piProcInfo;
4308 STARTUPINFO siStartInfo;
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004309 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004310 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00004311 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004312 int i;
4313 int x;
4314
4315 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00004316 char *comshell;
4317
Tim Peters92e4dd82002-10-05 01:47:34 +00004318 s1 = (char *)alloca(i);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004319 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
4320 return x;
Tim Peters402d5982001-08-27 06:37:48 +00004321
4322 /* Explicitly check if we are using COMMAND.COM. If we are
4323 * then use the w9xpopen hack.
4324 */
4325 comshell = s1 + x;
4326 while (comshell >= s1 && *comshell != '\\')
4327 --comshell;
4328 ++comshell;
4329
4330 if (GetVersion() < 0x80000000 &&
4331 _stricmp(comshell, "command.com") != 0) {
4332 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004333 x = i + strlen(s3) + strlen(cmdstring) + 1;
Tim Peters92e4dd82002-10-05 01:47:34 +00004334 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004335 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00004336 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004337 }
4338 else {
4339 /*
Tim Peters402d5982001-08-27 06:37:48 +00004340 * Oh gag, we're on Win9x or using COMMAND.COM. Use
4341 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004342 */
Mark Hammond08501372001-01-31 07:30:29 +00004343 char modulepath[_MAX_PATH];
4344 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004345 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
4346 for (i = x = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004347 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004348 x = i+1;
4349 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00004350 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00004351 strncat(modulepath,
4352 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00004353 (sizeof(modulepath)/sizeof(modulepath[0]))
4354 -strlen(modulepath));
4355 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00004356 /* Eeek - file-not-found - possibly an embedding
4357 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00004358 */
Tim Peters5aa91602002-01-30 05:46:57 +00004359 strncpy(modulepath,
4360 Py_GetExecPrefix(),
Mark Hammond08501372001-01-31 07:30:29 +00004361 sizeof(modulepath)/sizeof(modulepath[0]));
4362 if (modulepath[strlen(modulepath)-1] != '\\')
4363 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00004364 strncat(modulepath,
4365 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00004366 (sizeof(modulepath)/sizeof(modulepath[0]))
4367 -strlen(modulepath));
4368 /* No where else to look - raise an easily identifiable
4369 error, rather than leaving Windows to report
4370 "file not found" - as the user is probably blissfully
4371 unaware this shim EXE is used, and it will confuse them.
4372 (well, it confused me for a while ;-)
4373 */
4374 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00004375 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00004376 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00004377 "for popen to work with your shell "
4378 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00004379 szConsoleSpawn);
4380 return FALSE;
4381 }
4382 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004383 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00004384 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004385 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00004386
Tim Peters92e4dd82002-10-05 01:47:34 +00004387 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004388 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004389 /* To maintain correct argument passing semantics,
4390 we pass the command-line as it stands, and allow
4391 quoting to be applied. w9xpopen.exe will then
4392 use its argv vector, and re-quote the necessary
4393 args for the ultimate child process.
4394 */
Tim Peters75cdad52001-11-28 22:07:30 +00004395 PyOS_snprintf(
4396 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004397 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004398 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004399 s1,
4400 s3,
4401 cmdstring);
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004402 /* Not passing CREATE_NEW_CONSOLE has been known to
Tim Peters11b23062003-04-23 02:39:17 +00004403 cause random failures on win9x. Specifically a
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004404 dialog:
4405 "Your program accessed mem currently in use at xxx"
4406 and a hopeful warning about the stability of your
4407 system.
4408 Cost is Ctrl+C wont kill children, but anyone
4409 who cares can have a go!
4410 */
4411 dwProcessFlags |= CREATE_NEW_CONSOLE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004412 }
4413 }
4414
4415 /* Could be an else here to try cmd.exe / command.com in the path
4416 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00004417 else {
Tim Peters402d5982001-08-27 06:37:48 +00004418 PyErr_SetString(PyExc_RuntimeError,
4419 "Cannot locate a COMSPEC environment variable to "
4420 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00004421 return FALSE;
4422 }
Tim Peters5aa91602002-01-30 05:46:57 +00004423
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004424 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
4425 siStartInfo.cb = sizeof(STARTUPINFO);
4426 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
4427 siStartInfo.hStdInput = hStdin;
4428 siStartInfo.hStdOutput = hStdout;
4429 siStartInfo.hStdError = hStderr;
4430 siStartInfo.wShowWindow = SW_HIDE;
4431
4432 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004433 s2,
4434 NULL,
4435 NULL,
4436 TRUE,
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004437 dwProcessFlags,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004438 NULL,
4439 NULL,
4440 &siStartInfo,
4441 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004442 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004443 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004444
Mark Hammondb37a3732000-08-14 04:47:33 +00004445 /* Return process handle */
4446 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004447 return TRUE;
4448 }
Tim Peters402d5982001-08-27 06:37:48 +00004449 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004450 return FALSE;
4451}
4452
4453/* The following code is based off of KB: Q190351 */
4454
4455static PyObject *
4456_PyPopen(char *cmdstring, int mode, int n)
4457{
4458 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
4459 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00004460 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00004461
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004462 SECURITY_ATTRIBUTES saAttr;
4463 BOOL fSuccess;
4464 int fd1, fd2, fd3;
4465 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00004466 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004467 PyObject *f;
4468
4469 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
4470 saAttr.bInheritHandle = TRUE;
4471 saAttr.lpSecurityDescriptor = NULL;
4472
4473 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
4474 return win32_error("CreatePipe", NULL);
4475
4476 /* Create new output read handle and the input write handle. Set
4477 * the inheritance properties to FALSE. Otherwise, the child inherits
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00004478 * these handles; resulting in non-closeable handles to the pipes
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004479 * being created. */
4480 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004481 GetCurrentProcess(), &hChildStdinWrDup, 0,
4482 FALSE,
4483 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004484 if (!fSuccess)
4485 return win32_error("DuplicateHandle", NULL);
4486
4487 /* Close the inheritable version of ChildStdin
4488 that we're using. */
4489 CloseHandle(hChildStdinWr);
4490
4491 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
4492 return win32_error("CreatePipe", NULL);
4493
4494 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004495 GetCurrentProcess(), &hChildStdoutRdDup, 0,
4496 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004497 if (!fSuccess)
4498 return win32_error("DuplicateHandle", NULL);
4499
4500 /* Close the inheritable version of ChildStdout
4501 that we're using. */
4502 CloseHandle(hChildStdoutRd);
4503
4504 if (n != POPEN_4) {
4505 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
4506 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004507 fSuccess = DuplicateHandle(GetCurrentProcess(),
4508 hChildStderrRd,
4509 GetCurrentProcess(),
4510 &hChildStderrRdDup, 0,
4511 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004512 if (!fSuccess)
4513 return win32_error("DuplicateHandle", NULL);
4514 /* Close the inheritable version of ChildStdErr that we're using. */
4515 CloseHandle(hChildStderrRd);
4516 }
Tim Peters5aa91602002-01-30 05:46:57 +00004517
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004518 switch (n) {
4519 case POPEN_1:
4520 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
4521 case _O_WRONLY | _O_TEXT:
4522 /* Case for writing to child Stdin in text mode. */
4523 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4524 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004525 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004526 PyFile_SetBufSize(f, 0);
4527 /* We don't care about these pipes anymore, so close them. */
4528 CloseHandle(hChildStdoutRdDup);
4529 CloseHandle(hChildStderrRdDup);
4530 break;
4531
4532 case _O_RDONLY | _O_TEXT:
4533 /* Case for reading from child Stdout in text mode. */
4534 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4535 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004536 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004537 PyFile_SetBufSize(f, 0);
4538 /* We don't care about these pipes anymore, so close them. */
4539 CloseHandle(hChildStdinWrDup);
4540 CloseHandle(hChildStderrRdDup);
4541 break;
4542
4543 case _O_RDONLY | _O_BINARY:
4544 /* Case for readinig from child Stdout in binary mode. */
4545 fd1 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4546 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004547 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004548 PyFile_SetBufSize(f, 0);
4549 /* We don't care about these pipes anymore, so close them. */
4550 CloseHandle(hChildStdinWrDup);
4551 CloseHandle(hChildStderrRdDup);
4552 break;
4553
4554 case _O_WRONLY | _O_BINARY:
4555 /* Case for writing to child Stdin in binary mode. */
4556 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4557 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004558 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004559 PyFile_SetBufSize(f, 0);
4560 /* We don't care about these pipes anymore, so close them. */
4561 CloseHandle(hChildStdoutRdDup);
4562 CloseHandle(hChildStderrRdDup);
4563 break;
4564 }
Mark Hammondb37a3732000-08-14 04:47:33 +00004565 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004566 break;
Tim Peters5aa91602002-01-30 05:46:57 +00004567
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004568 case POPEN_2:
4569 case POPEN_4:
4570 {
4571 char *m1, *m2;
4572 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00004573
Tim Peters7dca21e2002-08-19 00:42:29 +00004574 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004575 m1 = "r";
4576 m2 = "w";
4577 } else {
4578 m1 = "rb";
4579 m2 = "wb";
4580 }
4581
4582 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4583 f1 = _fdopen(fd1, m2);
4584 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4585 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004586 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004587 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00004588 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004589 PyFile_SetBufSize(p2, 0);
4590
4591 if (n != 4)
4592 CloseHandle(hChildStderrRdDup);
4593
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004594 f = PyTuple_Pack(2,p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00004595 Py_XDECREF(p1);
4596 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00004597 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004598 break;
4599 }
Tim Peters5aa91602002-01-30 05:46:57 +00004600
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004601 case POPEN_3:
4602 {
4603 char *m1, *m2;
4604 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00004605
Tim Peters7dca21e2002-08-19 00:42:29 +00004606 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004607 m1 = "r";
4608 m2 = "w";
4609 } else {
4610 m1 = "rb";
4611 m2 = "wb";
4612 }
4613
4614 fd1 = _open_osfhandle((long)hChildStdinWrDup, mode);
4615 f1 = _fdopen(fd1, m2);
4616 fd2 = _open_osfhandle((long)hChildStdoutRdDup, mode);
4617 f2 = _fdopen(fd2, m1);
4618 fd3 = _open_osfhandle((long)hChildStderrRdDup, mode);
4619 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004620 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00004621 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
4622 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004623 PyFile_SetBufSize(p1, 0);
4624 PyFile_SetBufSize(p2, 0);
4625 PyFile_SetBufSize(p3, 0);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004626 f = PyTuple_Pack(3,p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00004627 Py_XDECREF(p1);
4628 Py_XDECREF(p2);
4629 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00004630 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004631 break;
4632 }
4633 }
4634
4635 if (n == POPEN_4) {
4636 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004637 hChildStdinRd,
4638 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004639 hChildStdoutWr,
4640 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004641 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004642 }
4643 else {
4644 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004645 hChildStdinRd,
4646 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004647 hChildStderrWr,
4648 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004649 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004650 }
4651
Mark Hammondb37a3732000-08-14 04:47:33 +00004652 /*
4653 * Insert the files we've created into the process dictionary
4654 * all referencing the list with the process handle and the
4655 * initial number of files (see description below in _PyPclose).
4656 * Since if _PyPclose later tried to wait on a process when all
4657 * handles weren't closed, it could create a deadlock with the
4658 * child, we spend some energy here to try to ensure that we
4659 * either insert all file handles into the dictionary or none
4660 * at all. It's a little clumsy with the various popen modes
4661 * and variable number of files involved.
4662 */
4663 if (!_PyPopenProcs) {
4664 _PyPopenProcs = PyDict_New();
4665 }
4666
4667 if (_PyPopenProcs) {
4668 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
4669 int ins_rc[3];
4670
4671 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4672 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4673
4674 procObj = PyList_New(2);
4675 hProcessObj = PyLong_FromVoidPtr(hProcess);
4676 intObj = PyInt_FromLong(file_count);
4677
4678 if (procObj && hProcessObj && intObj) {
4679 PyList_SetItem(procObj,0,hProcessObj);
4680 PyList_SetItem(procObj,1,intObj);
4681
4682 fileObj[0] = PyLong_FromVoidPtr(f1);
4683 if (fileObj[0]) {
4684 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4685 fileObj[0],
4686 procObj);
4687 }
4688 if (file_count >= 2) {
4689 fileObj[1] = PyLong_FromVoidPtr(f2);
4690 if (fileObj[1]) {
4691 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4692 fileObj[1],
4693 procObj);
4694 }
4695 }
4696 if (file_count >= 3) {
4697 fileObj[2] = PyLong_FromVoidPtr(f3);
4698 if (fileObj[2]) {
4699 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4700 fileObj[2],
4701 procObj);
4702 }
4703 }
4704
4705 if (ins_rc[0] < 0 || !fileObj[0] ||
4706 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4707 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
4708 /* Something failed - remove any dictionary
4709 * entries that did make it.
4710 */
4711 if (!ins_rc[0] && fileObj[0]) {
4712 PyDict_DelItem(_PyPopenProcs,
4713 fileObj[0]);
4714 }
4715 if (!ins_rc[1] && fileObj[1]) {
4716 PyDict_DelItem(_PyPopenProcs,
4717 fileObj[1]);
4718 }
4719 if (!ins_rc[2] && fileObj[2]) {
4720 PyDict_DelItem(_PyPopenProcs,
4721 fileObj[2]);
4722 }
4723 }
4724 }
Tim Peters5aa91602002-01-30 05:46:57 +00004725
Mark Hammondb37a3732000-08-14 04:47:33 +00004726 /*
4727 * Clean up our localized references for the dictionary keys
4728 * and value since PyDict_SetItem will Py_INCREF any copies
4729 * that got placed in the dictionary.
4730 */
4731 Py_XDECREF(procObj);
4732 Py_XDECREF(fileObj[0]);
4733 Py_XDECREF(fileObj[1]);
4734 Py_XDECREF(fileObj[2]);
4735 }
4736
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004737 /* Child is launched. Close the parents copy of those pipe
4738 * handles that only the child should have open. You need to
4739 * make sure that no handles to the write end of the output pipe
4740 * are maintained in this process or else the pipe will not close
4741 * when the child process exits and the ReadFile will hang. */
4742
4743 if (!CloseHandle(hChildStdinRd))
4744 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004745
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004746 if (!CloseHandle(hChildStdoutWr))
4747 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004748
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004749 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
4750 return win32_error("CloseHandle", NULL);
4751
4752 return f;
4753}
Fredrik Lundh56055a42000-07-23 19:47:12 +00004754
4755/*
4756 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4757 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00004758 *
4759 * This function uses the _PyPopenProcs dictionary in order to map the
4760 * input file pointer to information about the process that was
4761 * originally created by the popen* call that created the file pointer.
4762 * The dictionary uses the file pointer as a key (with one entry
4763 * inserted for each file returned by the original popen* call) and a
4764 * single list object as the value for all files from a single call.
4765 * The list object contains the Win32 process handle at [0], and a file
4766 * count at [1], which is initialized to the total number of file
4767 * handles using that list.
4768 *
4769 * This function closes whichever handle it is passed, and decrements
4770 * the file count in the dictionary for the process handle pointed to
4771 * by this file. On the last close (when the file count reaches zero),
4772 * this function will wait for the child process and then return its
4773 * exit code as the result of the close() operation. This permits the
4774 * files to be closed in any order - it is always the close() of the
4775 * final handle that will return the exit code.
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004776 *
4777 * NOTE: This function is currently called with the GIL released.
4778 * hence we use the GILState API to manage our state.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004779 */
Tim Peters736aa322000-09-01 06:51:24 +00004780
Fredrik Lundh56055a42000-07-23 19:47:12 +00004781static int _PyPclose(FILE *file)
4782{
Fredrik Lundh20318932000-07-26 17:29:12 +00004783 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004784 DWORD exit_code;
4785 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00004786 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
4787 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00004788#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004789 PyGILState_STATE state;
Tim Peters736aa322000-09-01 06:51:24 +00004790#endif
4791
Fredrik Lundh20318932000-07-26 17:29:12 +00004792 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00004793 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00004794 */
4795 result = fclose(file);
Tim Peters736aa322000-09-01 06:51:24 +00004796#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004797 state = PyGILState_Ensure();
Tim Peters736aa322000-09-01 06:51:24 +00004798#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00004799 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00004800 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4801 (procObj = PyDict_GetItem(_PyPopenProcs,
4802 fileObj)) != NULL &&
4803 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
4804 (intObj = PyList_GetItem(procObj,1)) != NULL) {
4805
4806 hProcess = PyLong_AsVoidPtr(hProcessObj);
4807 file_count = PyInt_AsLong(intObj);
4808
4809 if (file_count > 1) {
4810 /* Still other files referencing process */
4811 file_count--;
4812 PyList_SetItem(procObj,1,
4813 PyInt_FromLong(file_count));
4814 } else {
4815 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00004816 if (result != EOF &&
4817 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
4818 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00004819 /* Possible truncation here in 16-bit environments, but
4820 * real exit codes are just the lower byte in any event.
4821 */
4822 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004823 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00004824 /* Indicate failure - this will cause the file object
4825 * to raise an I/O error and translate the last Win32
4826 * error code from errno. We do have a problem with
4827 * last errors that overlap the normal errno table,
4828 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004829 */
Fredrik Lundh20318932000-07-26 17:29:12 +00004830 if (result != EOF) {
4831 /* If the error wasn't from the fclose(), then
4832 * set errno for the file object error handling.
4833 */
4834 errno = GetLastError();
4835 }
4836 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004837 }
4838
4839 /* Free up the native handle at this point */
4840 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00004841 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00004842
Mark Hammondb37a3732000-08-14 04:47:33 +00004843 /* Remove this file pointer from dictionary */
4844 PyDict_DelItem(_PyPopenProcs, fileObj);
4845
4846 if (PyDict_Size(_PyPopenProcs) == 0) {
4847 Py_DECREF(_PyPopenProcs);
4848 _PyPopenProcs = NULL;
4849 }
4850
4851 } /* if object retrieval ok */
4852
4853 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004854 } /* if _PyPopenProcs */
4855
Tim Peters736aa322000-09-01 06:51:24 +00004856#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004857 PyGILState_Release(state);
Tim Peters736aa322000-09-01 06:51:24 +00004858#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00004859 return result;
4860}
Tim Peters9acdd3a2000-09-01 19:26:36 +00004861
4862#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00004863static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004864posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00004865{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004866 char *name;
4867 char *mode = "r";
4868 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00004869 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00004870 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004871 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00004872 return NULL;
Martin v. Löwis9ad853b2003-10-31 10:01:53 +00004873 /* Strip mode of binary or text modifiers */
4874 if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
4875 mode = "r";
4876 else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
4877 mode = "w";
Barry Warsaw53699e91996-12-10 23:23:01 +00004878 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004879 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004880 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00004881 if (fp == NULL)
4882 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004883 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004884 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00004885 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004886 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00004887}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004888
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004889#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004890#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00004891
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004892
Guido van Rossumb6775db1994-08-01 11:34:53 +00004893#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004894PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004895"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004896Set the current process's user id.");
4897
Barry Warsaw53699e91996-12-10 23:23:01 +00004898static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004899posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004900{
4901 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004902 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004903 return NULL;
4904 if (setuid(uid) < 0)
4905 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004906 Py_INCREF(Py_None);
4907 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004908}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004909#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004910
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004911
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004912#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004913PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004914"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004915Set the current process's effective user id.");
4916
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004917static PyObject *
4918posix_seteuid (PyObject *self, PyObject *args)
4919{
4920 int euid;
4921 if (!PyArg_ParseTuple(args, "i", &euid)) {
4922 return NULL;
4923 } else if (seteuid(euid) < 0) {
4924 return posix_error();
4925 } else {
4926 Py_INCREF(Py_None);
4927 return Py_None;
4928 }
4929}
4930#endif /* HAVE_SETEUID */
4931
4932#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004933PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004934"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004935Set the current process's effective group id.");
4936
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004937static PyObject *
4938posix_setegid (PyObject *self, PyObject *args)
4939{
4940 int egid;
4941 if (!PyArg_ParseTuple(args, "i", &egid)) {
4942 return NULL;
4943 } else if (setegid(egid) < 0) {
4944 return posix_error();
4945 } else {
4946 Py_INCREF(Py_None);
4947 return Py_None;
4948 }
4949}
4950#endif /* HAVE_SETEGID */
4951
4952#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004953PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004954"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004955Set the current process's real and effective user ids.");
4956
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004957static PyObject *
4958posix_setreuid (PyObject *self, PyObject *args)
4959{
4960 int ruid, euid;
4961 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
4962 return NULL;
4963 } else if (setreuid(ruid, euid) < 0) {
4964 return posix_error();
4965 } else {
4966 Py_INCREF(Py_None);
4967 return Py_None;
4968 }
4969}
4970#endif /* HAVE_SETREUID */
4971
4972#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004973PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004974"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004975Set the current process's real and effective group ids.");
4976
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004977static PyObject *
4978posix_setregid (PyObject *self, PyObject *args)
4979{
4980 int rgid, egid;
4981 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
4982 return NULL;
4983 } else if (setregid(rgid, egid) < 0) {
4984 return posix_error();
4985 } else {
4986 Py_INCREF(Py_None);
4987 return Py_None;
4988 }
4989}
4990#endif /* HAVE_SETREGID */
4991
Guido van Rossumb6775db1994-08-01 11:34:53 +00004992#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004993PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004994"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004995Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004996
Barry Warsaw53699e91996-12-10 23:23:01 +00004997static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004998posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004999{
5000 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005001 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005002 return NULL;
5003 if (setgid(gid) < 0)
5004 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005005 Py_INCREF(Py_None);
5006 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005007}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005008#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005009
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005010#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005011PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005012"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005013Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005014
5015static PyObject *
5016posix_setgroups(PyObject *self, PyObject *args)
5017{
5018 PyObject *groups;
5019 int i, len;
5020 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00005021
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005022 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
5023 return NULL;
5024 if (!PySequence_Check(groups)) {
5025 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
5026 return NULL;
5027 }
5028 len = PySequence_Size(groups);
5029 if (len > MAX_GROUPS) {
5030 PyErr_SetString(PyExc_ValueError, "too many groups");
5031 return NULL;
5032 }
5033 for(i = 0; i < len; i++) {
5034 PyObject *elem;
5035 elem = PySequence_GetItem(groups, i);
5036 if (!elem)
5037 return NULL;
5038 if (!PyInt_Check(elem)) {
Georg Brandla13c2442005-11-22 19:30:31 +00005039 if (!PyLong_Check(elem)) {
5040 PyErr_SetString(PyExc_TypeError,
5041 "groups must be integers");
5042 Py_DECREF(elem);
5043 return NULL;
5044 } else {
5045 unsigned long x = PyLong_AsUnsignedLong(elem);
5046 if (PyErr_Occurred()) {
5047 PyErr_SetString(PyExc_TypeError,
5048 "group id too big");
5049 Py_DECREF(elem);
5050 return NULL;
5051 }
5052 grouplist[i] = x;
5053 /* read back the value to see if it fitted in gid_t */
5054 if (grouplist[i] != x) {
5055 PyErr_SetString(PyExc_TypeError,
5056 "group id too big");
5057 Py_DECREF(elem);
5058 return NULL;
5059 }
5060 }
5061 } else {
5062 long x = PyInt_AsLong(elem);
5063 grouplist[i] = x;
5064 if (grouplist[i] != x) {
5065 PyErr_SetString(PyExc_TypeError,
5066 "group id too big");
5067 Py_DECREF(elem);
5068 return NULL;
5069 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005070 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005071 Py_DECREF(elem);
5072 }
5073
5074 if (setgroups(len, grouplist) < 0)
5075 return posix_error();
5076 Py_INCREF(Py_None);
5077 return Py_None;
5078}
5079#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005080
Guido van Rossumb6775db1994-08-01 11:34:53 +00005081#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005082PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005083"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005084Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005085
Barry Warsaw53699e91996-12-10 23:23:01 +00005086static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005087posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005088{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005089 int pid, options;
5090#ifdef UNION_WAIT
5091 union wait status;
5092#define status_i (status.w_status)
5093#else
5094 int status;
5095#define status_i status
5096#endif
5097 status_i = 0;
5098
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005099 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00005100 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005101 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00005102 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00005103 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00005104 if (pid == -1)
5105 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00005106 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005107 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00005108}
5109
Tim Petersab034fa2002-02-01 11:27:43 +00005110#elif defined(HAVE_CWAIT)
5111
5112/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005113PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005114"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005115"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00005116
5117static PyObject *
5118posix_waitpid(PyObject *self, PyObject *args)
5119{
5120 int pid, options;
5121 int status;
5122
5123 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
5124 return NULL;
5125 Py_BEGIN_ALLOW_THREADS
5126 pid = _cwait(&status, pid, options);
5127 Py_END_ALLOW_THREADS
5128 if (pid == -1)
5129 return posix_error();
5130 else
5131 /* shift the status left a byte so this is more like the
5132 POSIX waitpid */
5133 return Py_BuildValue("ii", pid, status << 8);
5134}
5135#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005136
Guido van Rossumad0ee831995-03-01 10:34:45 +00005137#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005138PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005139"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005140Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005141
Barry Warsaw53699e91996-12-10 23:23:01 +00005142static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005143posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00005144{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005145 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005146#ifdef UNION_WAIT
5147 union wait status;
5148#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00005149#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005150 int status;
5151#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00005152#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00005153
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005154 status_i = 0;
5155 Py_BEGIN_ALLOW_THREADS
5156 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00005157 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00005158 if (pid == -1)
5159 return posix_error();
5160 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005161 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005162#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00005163}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005164#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005165
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005166
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005167PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005168"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005169Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005170
Barry Warsaw53699e91996-12-10 23:23:01 +00005171static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005172posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005173{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005174#ifdef HAVE_LSTAT
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005175 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005176#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005177#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00005178 return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005179#else
5180 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
5181#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005182#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005183}
5184
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005185
Guido van Rossumb6775db1994-08-01 11:34:53 +00005186#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005187PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005188"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005189Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005190
Barry Warsaw53699e91996-12-10 23:23:01 +00005191static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005192posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005193{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005194 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00005195 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005196 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005197 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005198 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005199 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00005200 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00005201 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005202 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00005203 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00005204 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005205}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005206#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005207
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005208
Guido van Rossumb6775db1994-08-01 11:34:53 +00005209#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005210PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005211"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00005212Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005213
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005214static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005215posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005216{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005217 return posix_2str(args, "etet:symlink", symlink, NULL, NULL);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005218}
5219#endif /* HAVE_SYMLINK */
5220
5221
5222#ifdef HAVE_TIMES
5223#ifndef HZ
5224#define HZ 60 /* Universal constant :-) */
5225#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00005226
Guido van Rossumd48f2521997-12-05 22:19:34 +00005227#if defined(PYCC_VACPP) && defined(PYOS_OS2)
5228static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005229system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005230{
5231 ULONG value = 0;
5232
5233 Py_BEGIN_ALLOW_THREADS
5234 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
5235 Py_END_ALLOW_THREADS
5236
5237 return value;
5238}
5239
5240static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005241posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005242{
Guido van Rossumd48f2521997-12-05 22:19:34 +00005243 /* Currently Only Uptime is Provided -- Others Later */
5244 return Py_BuildValue("ddddd",
5245 (double)0 /* t.tms_utime / HZ */,
5246 (double)0 /* t.tms_stime / HZ */,
5247 (double)0 /* t.tms_cutime / HZ */,
5248 (double)0 /* t.tms_cstime / HZ */,
5249 (double)system_uptime() / 1000);
5250}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005251#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00005252static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005253posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00005254{
5255 struct tms t;
5256 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +00005257 errno = 0;
5258 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00005259 if (c == (clock_t) -1)
5260 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005261 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00005262 (double)t.tms_utime / HZ,
5263 (double)t.tms_stime / HZ,
5264 (double)t.tms_cutime / HZ,
5265 (double)t.tms_cstime / HZ,
5266 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00005267}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005268#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005269#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005270
5271
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005272#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005273#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00005274static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005275posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005276{
5277 FILETIME create, exit, kernel, user;
5278 HANDLE hProc;
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005279 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00005280 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
5281 /* The fields of a FILETIME structure are the hi and lo part
5282 of a 64-bit value expressed in 100 nanosecond units.
5283 1e7 is one second in such units; 1e-7 the inverse.
5284 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
5285 */
Barry Warsaw53699e91996-12-10 23:23:01 +00005286 return Py_BuildValue(
5287 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00005288 (double)(kernel.dwHighDateTime*429.4967296 +
5289 kernel.dwLowDateTime*1e-7),
5290 (double)(user.dwHighDateTime*429.4967296 +
5291 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00005292 (double)0,
5293 (double)0,
5294 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005295}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005296#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005297
5298#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005299PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005300"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005301Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005302#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005303
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005304
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00005305#ifdef HAVE_GETSID
5306PyDoc_STRVAR(posix_getsid__doc__,
5307"getsid(pid) -> sid\n\n\
5308Call the system call getsid().");
5309
5310static PyObject *
5311posix_getsid(PyObject *self, PyObject *args)
5312{
5313 int pid, sid;
5314 if (!PyArg_ParseTuple(args, "i:getsid", &pid))
5315 return NULL;
5316 sid = getsid(pid);
5317 if (sid < 0)
5318 return posix_error();
5319 return PyInt_FromLong((long)sid);
5320}
5321#endif /* HAVE_GETSID */
5322
5323
Guido van Rossumb6775db1994-08-01 11:34:53 +00005324#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005325PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005326"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005327Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005328
Barry Warsaw53699e91996-12-10 23:23:01 +00005329static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005330posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005331{
Guido van Rossum687dd131993-05-17 08:34:16 +00005332 if (setsid() < 0)
5333 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005334 Py_INCREF(Py_None);
5335 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005336}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005337#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005338
Guido van Rossumb6775db1994-08-01 11:34:53 +00005339#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005340PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005341"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005342Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005343
Barry Warsaw53699e91996-12-10 23:23:01 +00005344static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005345posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005346{
5347 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005348 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00005349 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005350 if (setpgid(pid, pgrp) < 0)
5351 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005352 Py_INCREF(Py_None);
5353 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005354}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005355#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005356
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005357
Guido van Rossumb6775db1994-08-01 11:34:53 +00005358#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005359PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005360"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005361Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005362
Barry Warsaw53699e91996-12-10 23:23:01 +00005363static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005364posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005365{
5366 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005367 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00005368 return NULL;
5369 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005370 if (pgid < 0)
5371 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005372 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00005373}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005374#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00005375
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005376
Guido van Rossumb6775db1994-08-01 11:34:53 +00005377#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005378PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005379"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005380Set the process group associated with the terminal given by a fd.");
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_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005384{
5385 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005386 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00005387 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005388 if (tcsetpgrp(fd, pgid) < 0)
5389 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00005390 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00005391 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00005392}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005393#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00005394
Guido van Rossum687dd131993-05-17 08:34:16 +00005395/* Functions acting on file descriptors */
5396
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005397PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005398"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005399Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005400
Barry Warsaw53699e91996-12-10 23:23:01 +00005401static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005402posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005403{
Mark Hammondef8b6542001-05-13 08:04:26 +00005404 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005405 int flag;
5406 int mode = 0777;
5407 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005408
5409#ifdef MS_WINDOWS
5410 if (unicode_file_names()) {
5411 PyUnicodeObject *po;
5412 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
5413 Py_BEGIN_ALLOW_THREADS
5414 /* PyUnicode_AS_UNICODE OK without thread
5415 lock as it is a simple dereference. */
5416 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
5417 Py_END_ALLOW_THREADS
5418 if (fd < 0)
5419 return posix_error();
5420 return PyInt_FromLong((long)fd);
5421 }
5422 /* Drop the argument parsing error as narrow strings
5423 are also valid. */
5424 PyErr_Clear();
5425 }
5426#endif
5427
Tim Peters5aa91602002-01-30 05:46:57 +00005428 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00005429 Py_FileSystemDefaultEncoding, &file,
5430 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00005431 return NULL;
5432
Barry Warsaw53699e91996-12-10 23:23:01 +00005433 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005434 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005435 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005436 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00005437 return posix_error_with_allocated_filename(file);
5438 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00005439 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005440}
5441
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005442
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005443PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005444"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005445Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005446
Barry Warsaw53699e91996-12-10 23:23:01 +00005447static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005448posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005449{
5450 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005451 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005452 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005453 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005454 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00005455 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005456 if (res < 0)
5457 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005458 Py_INCREF(Py_None);
5459 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005460}
5461
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005462
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005463PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005464"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005465Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005466
Barry Warsaw53699e91996-12-10 23:23:01 +00005467static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005468posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005469{
5470 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005471 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005472 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005473 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005474 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00005475 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005476 if (fd < 0)
5477 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005478 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005479}
5480
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005481
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005482PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00005483"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005484Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005485
Barry Warsaw53699e91996-12-10 23:23:01 +00005486static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005487posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005488{
5489 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005490 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00005491 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005492 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005493 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00005494 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005495 if (res < 0)
5496 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005497 Py_INCREF(Py_None);
5498 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005499}
5500
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005501
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005502PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005503"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005504Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005505
Barry Warsaw53699e91996-12-10 23:23:01 +00005506static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005507posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005508{
5509 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005510#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005511 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005512#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00005513 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005514#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005515 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005516 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00005517 return NULL;
5518#ifdef SEEK_SET
5519 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
5520 switch (how) {
5521 case 0: how = SEEK_SET; break;
5522 case 1: how = SEEK_CUR; break;
5523 case 2: how = SEEK_END; break;
5524 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005525#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005526
5527#if !defined(HAVE_LARGEFILE_SUPPORT)
5528 pos = PyInt_AsLong(posobj);
5529#else
5530 pos = PyLong_Check(posobj) ?
5531 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
5532#endif
5533 if (PyErr_Occurred())
5534 return NULL;
5535
Barry Warsaw53699e91996-12-10 23:23:01 +00005536 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005537#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00005538 res = _lseeki64(fd, pos, how);
5539#else
Guido van Rossum687dd131993-05-17 08:34:16 +00005540 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005541#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005542 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005543 if (res < 0)
5544 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00005545
5546#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00005547 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005548#else
5549 return PyLong_FromLongLong(res);
5550#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005551}
5552
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005553
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005554PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005555"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005556Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005557
Barry Warsaw53699e91996-12-10 23:23:01 +00005558static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005559posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005560{
Guido van Rossum8bac5461996-06-11 18:38:48 +00005561 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00005562 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005563 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005564 return NULL;
Michael W. Hudson9867ced2005-01-31 17:01:59 +00005565 if (size < 0) {
5566 errno = EINVAL;
5567 return posix_error();
5568 }
Barry Warsaw53699e91996-12-10 23:23:01 +00005569 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005570 if (buffer == NULL)
5571 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005572 Py_BEGIN_ALLOW_THREADS
5573 n = read(fd, PyString_AsString(buffer), size);
5574 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00005575 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005576 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00005577 return posix_error();
5578 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00005579 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00005580 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00005581 return buffer;
5582}
5583
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005584
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005585PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005586"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005587Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005588
Barry Warsaw53699e91996-12-10 23:23:01 +00005589static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005590posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005591{
5592 int fd, size;
5593 char *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005594 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005595 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005596 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005597 size = write(fd, buffer, size);
Barry Warsaw53699e91996-12-10 23:23:01 +00005598 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005599 if (size < 0)
5600 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005601 return PyInt_FromLong((long)size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005602}
5603
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005604
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005605PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005606"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005607Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005608
Barry Warsaw53699e91996-12-10 23:23:01 +00005609static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005610posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005611{
5612 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00005613 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00005614 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005615 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005616 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005617#ifdef __VMS
5618 /* on OpenVMS we must ensure that all bytes are written to the file */
5619 fsync(fd);
5620#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005621 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00005622 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00005623 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00005624 if (res != 0) {
5625#ifdef MS_WINDOWS
5626 return win32_error("fstat", NULL);
5627#else
Guido van Rossum687dd131993-05-17 08:34:16 +00005628 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00005629#endif
5630 }
Tim Peters5aa91602002-01-30 05:46:57 +00005631
Martin v. Löwis14694662006-02-03 12:54:16 +00005632 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00005633}
5634
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005635
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005636PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005637"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005638Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005639
Barry Warsaw53699e91996-12-10 23:23:01 +00005640static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005641posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005642{
Guido van Rossum687dd131993-05-17 08:34:16 +00005643 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005644 char *mode = "r";
5645 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00005646 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00005647 PyObject *f;
5648 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00005649 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00005650
Thomas Heller1f043e22002-11-07 16:00:59 +00005651 if (mode[0] != 'r' && mode[0] != 'w' && mode[0] != 'a') {
5652 PyErr_Format(PyExc_ValueError,
5653 "invalid file mode '%s'", mode);
5654 return NULL;
5655 }
5656
Barry Warsaw53699e91996-12-10 23:23:01 +00005657 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005658 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005659 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005660 if (fp == NULL)
5661 return posix_error();
Guido van Rossumbd6be7a2002-09-15 18:45:46 +00005662 f = PyFile_FromFile(fp, "<fdopen>", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005663 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00005664 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005665 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00005666}
5667
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005668PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005669"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005670Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005671connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00005672
5673static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00005674posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00005675{
5676 int fd;
5677 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
5678 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005679 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00005680}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005681
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005682#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005683PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005684"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005685Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005686
Barry Warsaw53699e91996-12-10 23:23:01 +00005687static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005688posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00005689{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005690#if defined(PYOS_OS2)
5691 HFILE read, write;
5692 APIRET rc;
5693
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005694 Py_BEGIN_ALLOW_THREADS
5695 rc = DosCreatePipe( &read, &write, 4096);
5696 Py_END_ALLOW_THREADS
5697 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005698 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005699
5700 return Py_BuildValue("(ii)", read, write);
5701#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005702#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00005703 int fds[2];
5704 int res;
Barry Warsaw53699e91996-12-10 23:23:01 +00005705 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005706 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00005707 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005708 if (res != 0)
5709 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005710 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005711#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00005712 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005713 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00005714 BOOL ok;
Barry Warsaw53699e91996-12-10 23:23:01 +00005715 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005716 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00005717 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00005718 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005719 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00005720 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
5721 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005722 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005723#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005724#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005725}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005726#endif /* HAVE_PIPE */
5727
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005728
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005729#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005730PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005731"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005732Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005733
Barry Warsaw53699e91996-12-10 23:23:01 +00005734static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005735posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005736{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005737 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005738 int mode = 0666;
5739 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005740 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005741 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005742 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005743 res = mkfifo(filename, mode);
5744 Py_END_ALLOW_THREADS
5745 if (res < 0)
5746 return posix_error();
5747 Py_INCREF(Py_None);
5748 return Py_None;
5749}
5750#endif
5751
5752
Neal Norwitz11690112002-07-30 01:08:28 +00005753#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005754PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005755"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005756Create a filesystem node (file, device special file or named pipe)\n\
5757named filename. mode specifies both the permissions to use and the\n\
5758type of node to be created, being combined (bitwise OR) with one of\n\
5759S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005760device defines the newly created device special file (probably using\n\
5761os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005762
5763
5764static PyObject *
5765posix_mknod(PyObject *self, PyObject *args)
5766{
5767 char *filename;
5768 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005769 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005770 int res;
Martin v. Löwisd631ebe2002-11-02 17:42:33 +00005771 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005772 return NULL;
5773 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005774 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00005775 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005776 if (res < 0)
5777 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005778 Py_INCREF(Py_None);
5779 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005780}
5781#endif
5782
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005783#ifdef HAVE_DEVICE_MACROS
5784PyDoc_STRVAR(posix_major__doc__,
5785"major(device) -> major number\n\
5786Extracts a device major number from a raw device number.");
5787
5788static PyObject *
5789posix_major(PyObject *self, PyObject *args)
5790{
5791 int device;
5792 if (!PyArg_ParseTuple(args, "i:major", &device))
5793 return NULL;
5794 return PyInt_FromLong((long)major(device));
5795}
5796
5797PyDoc_STRVAR(posix_minor__doc__,
5798"minor(device) -> minor number\n\
5799Extracts a device minor number from a raw device number.");
5800
5801static PyObject *
5802posix_minor(PyObject *self, PyObject *args)
5803{
5804 int device;
5805 if (!PyArg_ParseTuple(args, "i:minor", &device))
5806 return NULL;
5807 return PyInt_FromLong((long)minor(device));
5808}
5809
5810PyDoc_STRVAR(posix_makedev__doc__,
5811"makedev(major, minor) -> device number\n\
5812Composes a raw device number from the major and minor device numbers.");
5813
5814static PyObject *
5815posix_makedev(PyObject *self, PyObject *args)
5816{
5817 int major, minor;
5818 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
5819 return NULL;
5820 return PyInt_FromLong((long)makedev(major, minor));
5821}
5822#endif /* device macros */
5823
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005824
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005825#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005826PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005827"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005828Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005829
Barry Warsaw53699e91996-12-10 23:23:01 +00005830static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005831posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005832{
5833 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005834 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005835 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005836 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005837
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005838 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005839 return NULL;
5840
5841#if !defined(HAVE_LARGEFILE_SUPPORT)
5842 length = PyInt_AsLong(lenobj);
5843#else
5844 length = PyLong_Check(lenobj) ?
5845 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
5846#endif
5847 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005848 return NULL;
5849
Barry Warsaw53699e91996-12-10 23:23:01 +00005850 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005851 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00005852 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005853 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005854 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005855 return NULL;
5856 }
Barry Warsaw53699e91996-12-10 23:23:01 +00005857 Py_INCREF(Py_None);
5858 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005859}
5860#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005861
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005862#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005863PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005864"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005865Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005866
Fred Drake762e2061999-08-26 17:23:54 +00005867/* Save putenv() parameters as values here, so we can collect them when they
5868 * get re-set with another call for the same key. */
5869static PyObject *posix_putenv_garbage;
5870
Tim Peters5aa91602002-01-30 05:46:57 +00005871static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005872posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005873{
5874 char *s1, *s2;
5875 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00005876 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00005877 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005878
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005879 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005880 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00005881
5882#if defined(PYOS_OS2)
5883 if (stricmp(s1, "BEGINLIBPATH") == 0) {
5884 APIRET rc;
5885
Guido van Rossumd48f2521997-12-05 22:19:34 +00005886 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
5887 if (rc != NO_ERROR)
5888 return os2_error(rc);
5889
5890 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
5891 APIRET rc;
5892
Guido van Rossumd48f2521997-12-05 22:19:34 +00005893 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
5894 if (rc != NO_ERROR)
5895 return os2_error(rc);
5896 } else {
5897#endif
5898
Fred Drake762e2061999-08-26 17:23:54 +00005899 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00005900 len = strlen(s1) + strlen(s2) + 2;
5901 /* len includes space for a trailing \0; the size arg to
5902 PyString_FromStringAndSize does not count that */
5903 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00005904 if (newstr == NULL)
5905 return PyErr_NoMemory();
5906 new = PyString_AS_STRING(newstr);
Tim Petersc8996f52001-12-03 20:41:00 +00005907 PyOS_snprintf(new, len, "%s=%s", s1, s2);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005908 if (putenv(new)) {
Neal Norwitz4adc9ab2003-02-10 03:10:43 +00005909 Py_DECREF(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005910 posix_error();
5911 return NULL;
5912 }
Fred Drake762e2061999-08-26 17:23:54 +00005913 /* Install the first arg and newstr in posix_putenv_garbage;
5914 * this will cause previous value to be collected. This has to
5915 * happen after the real putenv() call because the old value
5916 * was still accessible until then. */
5917 if (PyDict_SetItem(posix_putenv_garbage,
5918 PyTuple_GET_ITEM(args, 0), newstr)) {
5919 /* really not much we can do; just leak */
5920 PyErr_Clear();
5921 }
5922 else {
5923 Py_DECREF(newstr);
5924 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005925
5926#if defined(PYOS_OS2)
5927 }
5928#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005929 Py_INCREF(Py_None);
5930 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005931}
Guido van Rossumb6a47161997-09-15 22:54:34 +00005932#endif /* putenv */
5933
Guido van Rossumc524d952001-10-19 01:31:59 +00005934#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005935PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005936"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005937Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00005938
5939static PyObject *
5940posix_unsetenv(PyObject *self, PyObject *args)
5941{
5942 char *s1;
5943
5944 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
5945 return NULL;
5946
5947 unsetenv(s1);
5948
5949 /* Remove the key from posix_putenv_garbage;
5950 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00005951 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00005952 * old value was still accessible until then.
5953 */
5954 if (PyDict_DelItem(posix_putenv_garbage,
5955 PyTuple_GET_ITEM(args, 0))) {
5956 /* really not much we can do; just leak */
5957 PyErr_Clear();
5958 }
5959
5960 Py_INCREF(Py_None);
5961 return Py_None;
5962}
5963#endif /* unsetenv */
5964
Guido van Rossumb6a47161997-09-15 22:54:34 +00005965#ifdef HAVE_STRERROR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005966PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005967"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005968Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005969
Guido van Rossumf68d8e52001-04-14 17:55:09 +00005970static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005971posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00005972{
5973 int code;
5974 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005975 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00005976 return NULL;
5977 message = strerror(code);
5978 if (message == NULL) {
5979 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00005980 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005981 return NULL;
5982 }
5983 return PyString_FromString(message);
5984}
5985#endif /* strerror */
5986
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005987
Guido van Rossumc9641791998-08-04 15:26:23 +00005988#ifdef HAVE_SYS_WAIT_H
5989
Fred Drake106c1a02002-04-23 15:58:02 +00005990#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005991PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005992"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005993Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00005994
5995static PyObject *
5996posix_WCOREDUMP(PyObject *self, PyObject *args)
5997{
5998#ifdef UNION_WAIT
5999 union wait status;
6000#define status_i (status.w_status)
6001#else
6002 int status;
6003#define status_i status
6004#endif
6005 status_i = 0;
6006
6007 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &status_i))
6008 {
6009 return NULL;
6010 }
6011
6012 return PyBool_FromLong(WCOREDUMP(status));
6013#undef status_i
6014}
6015#endif /* WCOREDUMP */
6016
6017#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006018PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006019"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006020Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006021job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00006022
6023static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006024posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00006025{
6026#ifdef UNION_WAIT
6027 union wait status;
6028#define status_i (status.w_status)
6029#else
6030 int status;
6031#define status_i status
6032#endif
6033 status_i = 0;
6034
6035 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &status_i))
6036 {
6037 return NULL;
6038 }
6039
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006040 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006041#undef status_i
6042}
6043#endif /* WIFCONTINUED */
6044
Guido van Rossumc9641791998-08-04 15:26:23 +00006045#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006046PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006047"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006048Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006049
6050static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006051posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006052{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006053#ifdef UNION_WAIT
6054 union wait status;
6055#define status_i (status.w_status)
6056#else
6057 int status;
6058#define status_i status
6059#endif
6060 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006061
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006062 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00006063 {
6064 return NULL;
6065 }
Tim Peters5aa91602002-01-30 05:46:57 +00006066
Fred Drake106c1a02002-04-23 15:58:02 +00006067 return PyBool_FromLong(WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006068#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00006069}
6070#endif /* WIFSTOPPED */
6071
6072#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006073PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006074"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006075Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006076
6077static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006078posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006079{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006080#ifdef UNION_WAIT
6081 union wait status;
6082#define status_i (status.w_status)
6083#else
6084 int status;
6085#define status_i status
6086#endif
6087 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006088
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006089 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00006090 {
6091 return NULL;
6092 }
Tim Peters5aa91602002-01-30 05:46:57 +00006093
Fred Drake106c1a02002-04-23 15:58:02 +00006094 return PyBool_FromLong(WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006095#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00006096}
6097#endif /* WIFSIGNALED */
6098
6099#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006100PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006101"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006102Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006103system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006104
6105static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006106posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006107{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006108#ifdef UNION_WAIT
6109 union wait status;
6110#define status_i (status.w_status)
6111#else
6112 int status;
6113#define status_i status
6114#endif
6115 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006116
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006117 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00006118 {
6119 return NULL;
6120 }
Tim Peters5aa91602002-01-30 05:46:57 +00006121
Fred Drake106c1a02002-04-23 15:58:02 +00006122 return PyBool_FromLong(WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006123#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00006124}
6125#endif /* WIFEXITED */
6126
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006127#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006128PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006129"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006130Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006131
6132static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006133posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006134{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006135#ifdef UNION_WAIT
6136 union wait status;
6137#define status_i (status.w_status)
6138#else
6139 int status;
6140#define status_i status
6141#endif
6142 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006143
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006144 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00006145 {
6146 return NULL;
6147 }
Tim Peters5aa91602002-01-30 05:46:57 +00006148
Guido van Rossumc9641791998-08-04 15:26:23 +00006149 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006150#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00006151}
6152#endif /* WEXITSTATUS */
6153
6154#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006155PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006156"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006157Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006158value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006159
6160static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006161posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006162{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006163#ifdef UNION_WAIT
6164 union wait status;
6165#define status_i (status.w_status)
6166#else
6167 int status;
6168#define status_i status
6169#endif
6170 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006171
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006172 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00006173 {
6174 return NULL;
6175 }
Tim Peters5aa91602002-01-30 05:46:57 +00006176
Guido van Rossumc9641791998-08-04 15:26:23 +00006177 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006178#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00006179}
6180#endif /* WTERMSIG */
6181
6182#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006183PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006184"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006185Return the signal that stopped the process that provided\n\
6186the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006187
6188static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006189posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006190{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006191#ifdef UNION_WAIT
6192 union wait status;
6193#define status_i (status.w_status)
6194#else
6195 int status;
6196#define status_i status
6197#endif
6198 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006199
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006200 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00006201 {
6202 return NULL;
6203 }
Tim Peters5aa91602002-01-30 05:46:57 +00006204
Guido van Rossumc9641791998-08-04 15:26:23 +00006205 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006206#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00006207}
6208#endif /* WSTOPSIG */
6209
6210#endif /* HAVE_SYS_WAIT_H */
6211
6212
Guido van Rossum94f6f721999-01-06 18:42:14 +00006213#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00006214#ifdef _SCO_DS
6215/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
6216 needed definitions in sys/statvfs.h */
6217#define _SVID3
6218#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006219#include <sys/statvfs.h>
6220
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006221static PyObject*
6222_pystatvfs_fromstructstatvfs(struct statvfs st) {
6223 PyObject *v = PyStructSequence_New(&StatVFSResultType);
6224 if (v == NULL)
6225 return NULL;
6226
6227#if !defined(HAVE_LARGEFILE_SUPPORT)
6228 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6229 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
6230 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
6231 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
6232 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
6233 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
6234 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
6235 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
6236 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6237 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6238#else
6239 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6240 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00006241 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006242 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00006243 PyStructSequence_SET_ITEM(v, 3,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006244 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006245 PyStructSequence_SET_ITEM(v, 4,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006246 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00006247 PyStructSequence_SET_ITEM(v, 5,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006248 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00006249 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006250 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00006251 PyStructSequence_SET_ITEM(v, 7,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006252 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006253 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6254 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6255#endif
6256
6257 return v;
6258}
6259
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006260PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006261"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006262Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006263
6264static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006265posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006266{
6267 int fd, res;
6268 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006269
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006270 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006271 return NULL;
6272 Py_BEGIN_ALLOW_THREADS
6273 res = fstatvfs(fd, &st);
6274 Py_END_ALLOW_THREADS
6275 if (res != 0)
6276 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006277
6278 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006279}
6280#endif /* HAVE_FSTATVFS */
6281
6282
6283#if defined(HAVE_STATVFS)
6284#include <sys/statvfs.h>
6285
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006286PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006287"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006288Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006289
6290static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006291posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006292{
6293 char *path;
6294 int res;
6295 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006296 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006297 return NULL;
6298 Py_BEGIN_ALLOW_THREADS
6299 res = statvfs(path, &st);
6300 Py_END_ALLOW_THREADS
6301 if (res != 0)
6302 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006303
6304 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006305}
6306#endif /* HAVE_STATVFS */
6307
6308
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006309#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006310PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006311"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006312Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00006313The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006314or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006315
6316static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006317posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006318{
6319 PyObject *result = NULL;
6320 char *dir = NULL;
6321 char *pfx = NULL;
6322 char *name;
6323
6324 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
6325 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00006326
6327 if (PyErr_Warn(PyExc_RuntimeWarning,
6328 "tempnam is a potential security risk to your program") < 0)
6329 return NULL;
6330
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006331#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00006332 name = _tempnam(dir, pfx);
6333#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006334 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00006335#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006336 if (name == NULL)
6337 return PyErr_NoMemory();
6338 result = PyString_FromString(name);
6339 free(name);
6340 return result;
6341}
Guido van Rossumd371ff11999-01-25 16:12:23 +00006342#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006343
6344
6345#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006346PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006347"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006348Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006349
6350static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006351posix_tmpfile(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006352{
6353 FILE *fp;
6354
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006355 fp = tmpfile();
6356 if (fp == NULL)
6357 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00006358 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006359}
6360#endif
6361
6362
6363#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006364PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006365"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006366Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006367
6368static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006369posix_tmpnam(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006370{
6371 char buffer[L_tmpnam];
6372 char *name;
6373
Skip Montanaro95618b52001-08-18 18:52:10 +00006374 if (PyErr_Warn(PyExc_RuntimeWarning,
6375 "tmpnam is a potential security risk to your program") < 0)
6376 return NULL;
6377
Greg Wardb48bc172000-03-01 21:51:56 +00006378#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006379 name = tmpnam_r(buffer);
6380#else
6381 name = tmpnam(buffer);
6382#endif
6383 if (name == NULL) {
6384 PyErr_SetObject(PyExc_OSError,
6385 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00006386#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006387 "unexpected NULL from tmpnam_r"
6388#else
6389 "unexpected NULL from tmpnam"
6390#endif
6391 ));
6392 return NULL;
6393 }
6394 return PyString_FromString(buffer);
6395}
6396#endif
6397
6398
Fred Drakec9680921999-12-13 16:37:25 +00006399/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
6400 * It maps strings representing configuration variable names to
6401 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00006402 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00006403 * rarely-used constants. There are three separate tables that use
6404 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00006405 *
6406 * This code is always included, even if none of the interfaces that
6407 * need it are included. The #if hackery needed to avoid it would be
6408 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00006409 */
6410struct constdef {
6411 char *name;
6412 long value;
6413};
6414
Fred Drake12c6e2d1999-12-14 21:25:03 +00006415static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006416conv_confname(PyObject *arg, int *valuep, struct constdef *table,
6417 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006418{
6419 if (PyInt_Check(arg)) {
6420 *valuep = PyInt_AS_LONG(arg);
6421 return 1;
6422 }
6423 if (PyString_Check(arg)) {
6424 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00006425 size_t lo = 0;
6426 size_t mid;
6427 size_t hi = tablesize;
6428 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006429 char *confname = PyString_AS_STRING(arg);
6430 while (lo < hi) {
6431 mid = (lo + hi) / 2;
6432 cmp = strcmp(confname, table[mid].name);
6433 if (cmp < 0)
6434 hi = mid;
6435 else if (cmp > 0)
6436 lo = mid + 1;
6437 else {
6438 *valuep = table[mid].value;
6439 return 1;
6440 }
6441 }
6442 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
6443 }
6444 else
6445 PyErr_SetString(PyExc_TypeError,
6446 "configuration names must be strings or integers");
6447 return 0;
6448}
6449
6450
6451#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
6452static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006453#ifdef _PC_ABI_AIO_XFER_MAX
6454 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
6455#endif
6456#ifdef _PC_ABI_ASYNC_IO
6457 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
6458#endif
Fred Drakec9680921999-12-13 16:37:25 +00006459#ifdef _PC_ASYNC_IO
6460 {"PC_ASYNC_IO", _PC_ASYNC_IO},
6461#endif
6462#ifdef _PC_CHOWN_RESTRICTED
6463 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
6464#endif
6465#ifdef _PC_FILESIZEBITS
6466 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
6467#endif
6468#ifdef _PC_LAST
6469 {"PC_LAST", _PC_LAST},
6470#endif
6471#ifdef _PC_LINK_MAX
6472 {"PC_LINK_MAX", _PC_LINK_MAX},
6473#endif
6474#ifdef _PC_MAX_CANON
6475 {"PC_MAX_CANON", _PC_MAX_CANON},
6476#endif
6477#ifdef _PC_MAX_INPUT
6478 {"PC_MAX_INPUT", _PC_MAX_INPUT},
6479#endif
6480#ifdef _PC_NAME_MAX
6481 {"PC_NAME_MAX", _PC_NAME_MAX},
6482#endif
6483#ifdef _PC_NO_TRUNC
6484 {"PC_NO_TRUNC", _PC_NO_TRUNC},
6485#endif
6486#ifdef _PC_PATH_MAX
6487 {"PC_PATH_MAX", _PC_PATH_MAX},
6488#endif
6489#ifdef _PC_PIPE_BUF
6490 {"PC_PIPE_BUF", _PC_PIPE_BUF},
6491#endif
6492#ifdef _PC_PRIO_IO
6493 {"PC_PRIO_IO", _PC_PRIO_IO},
6494#endif
6495#ifdef _PC_SOCK_MAXBUF
6496 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
6497#endif
6498#ifdef _PC_SYNC_IO
6499 {"PC_SYNC_IO", _PC_SYNC_IO},
6500#endif
6501#ifdef _PC_VDISABLE
6502 {"PC_VDISABLE", _PC_VDISABLE},
6503#endif
6504};
6505
Fred Drakec9680921999-12-13 16:37:25 +00006506static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006507conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006508{
6509 return conv_confname(arg, valuep, posix_constants_pathconf,
6510 sizeof(posix_constants_pathconf)
6511 / sizeof(struct constdef));
6512}
6513#endif
6514
6515#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006516PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006517"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006518Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006519If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006520
6521static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006522posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006523{
6524 PyObject *result = NULL;
6525 int name, fd;
6526
Fred Drake12c6e2d1999-12-14 21:25:03 +00006527 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
6528 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00006529 long limit;
6530
6531 errno = 0;
6532 limit = fpathconf(fd, name);
6533 if (limit == -1 && errno != 0)
6534 posix_error();
6535 else
6536 result = PyInt_FromLong(limit);
6537 }
6538 return result;
6539}
6540#endif
6541
6542
6543#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006544PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006545"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006546Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006547If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006548
6549static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006550posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006551{
6552 PyObject *result = NULL;
6553 int name;
6554 char *path;
6555
6556 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
6557 conv_path_confname, &name)) {
6558 long limit;
6559
6560 errno = 0;
6561 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006562 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00006563 if (errno == EINVAL)
6564 /* could be a path or name problem */
6565 posix_error();
6566 else
6567 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006568 }
Fred Drakec9680921999-12-13 16:37:25 +00006569 else
6570 result = PyInt_FromLong(limit);
6571 }
6572 return result;
6573}
6574#endif
6575
6576#ifdef HAVE_CONFSTR
6577static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006578#ifdef _CS_ARCHITECTURE
6579 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
6580#endif
6581#ifdef _CS_HOSTNAME
6582 {"CS_HOSTNAME", _CS_HOSTNAME},
6583#endif
6584#ifdef _CS_HW_PROVIDER
6585 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
6586#endif
6587#ifdef _CS_HW_SERIAL
6588 {"CS_HW_SERIAL", _CS_HW_SERIAL},
6589#endif
6590#ifdef _CS_INITTAB_NAME
6591 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
6592#endif
Fred Drakec9680921999-12-13 16:37:25 +00006593#ifdef _CS_LFS64_CFLAGS
6594 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
6595#endif
6596#ifdef _CS_LFS64_LDFLAGS
6597 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
6598#endif
6599#ifdef _CS_LFS64_LIBS
6600 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
6601#endif
6602#ifdef _CS_LFS64_LINTFLAGS
6603 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
6604#endif
6605#ifdef _CS_LFS_CFLAGS
6606 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
6607#endif
6608#ifdef _CS_LFS_LDFLAGS
6609 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
6610#endif
6611#ifdef _CS_LFS_LIBS
6612 {"CS_LFS_LIBS", _CS_LFS_LIBS},
6613#endif
6614#ifdef _CS_LFS_LINTFLAGS
6615 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
6616#endif
Fred Draked86ed291999-12-15 15:34:33 +00006617#ifdef _CS_MACHINE
6618 {"CS_MACHINE", _CS_MACHINE},
6619#endif
Fred Drakec9680921999-12-13 16:37:25 +00006620#ifdef _CS_PATH
6621 {"CS_PATH", _CS_PATH},
6622#endif
Fred Draked86ed291999-12-15 15:34:33 +00006623#ifdef _CS_RELEASE
6624 {"CS_RELEASE", _CS_RELEASE},
6625#endif
6626#ifdef _CS_SRPC_DOMAIN
6627 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
6628#endif
6629#ifdef _CS_SYSNAME
6630 {"CS_SYSNAME", _CS_SYSNAME},
6631#endif
6632#ifdef _CS_VERSION
6633 {"CS_VERSION", _CS_VERSION},
6634#endif
Fred Drakec9680921999-12-13 16:37:25 +00006635#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
6636 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
6637#endif
6638#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
6639 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
6640#endif
6641#ifdef _CS_XBS5_ILP32_OFF32_LIBS
6642 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
6643#endif
6644#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
6645 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
6646#endif
6647#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
6648 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
6649#endif
6650#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
6651 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
6652#endif
6653#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
6654 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
6655#endif
6656#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
6657 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
6658#endif
6659#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
6660 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
6661#endif
6662#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
6663 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
6664#endif
6665#ifdef _CS_XBS5_LP64_OFF64_LIBS
6666 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
6667#endif
6668#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
6669 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
6670#endif
6671#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
6672 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
6673#endif
6674#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
6675 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
6676#endif
6677#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
6678 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
6679#endif
6680#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
6681 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
6682#endif
Fred Draked86ed291999-12-15 15:34:33 +00006683#ifdef _MIPS_CS_AVAIL_PROCESSORS
6684 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
6685#endif
6686#ifdef _MIPS_CS_BASE
6687 {"MIPS_CS_BASE", _MIPS_CS_BASE},
6688#endif
6689#ifdef _MIPS_CS_HOSTID
6690 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
6691#endif
6692#ifdef _MIPS_CS_HW_NAME
6693 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
6694#endif
6695#ifdef _MIPS_CS_NUM_PROCESSORS
6696 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
6697#endif
6698#ifdef _MIPS_CS_OSREL_MAJ
6699 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
6700#endif
6701#ifdef _MIPS_CS_OSREL_MIN
6702 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
6703#endif
6704#ifdef _MIPS_CS_OSREL_PATCH
6705 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
6706#endif
6707#ifdef _MIPS_CS_OS_NAME
6708 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
6709#endif
6710#ifdef _MIPS_CS_OS_PROVIDER
6711 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
6712#endif
6713#ifdef _MIPS_CS_PROCESSORS
6714 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
6715#endif
6716#ifdef _MIPS_CS_SERIAL
6717 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
6718#endif
6719#ifdef _MIPS_CS_VENDOR
6720 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
6721#endif
Fred Drakec9680921999-12-13 16:37:25 +00006722};
6723
6724static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006725conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006726{
6727 return conv_confname(arg, valuep, posix_constants_confstr,
6728 sizeof(posix_constants_confstr)
6729 / sizeof(struct constdef));
6730}
6731
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006732PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006733"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006734Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006735
6736static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006737posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006738{
6739 PyObject *result = NULL;
6740 int name;
6741 char buffer[64];
6742
6743 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
6744 int len = confstr(name, buffer, sizeof(buffer));
6745
Fred Drakec9680921999-12-13 16:37:25 +00006746 errno = 0;
6747 if (len == 0) {
6748 if (errno != 0)
6749 posix_error();
6750 else
6751 result = PyString_FromString("");
6752 }
6753 else {
6754 if (len >= sizeof(buffer)) {
6755 result = PyString_FromStringAndSize(NULL, len);
6756 if (result != NULL)
6757 confstr(name, PyString_AS_STRING(result), len+1);
6758 }
6759 else
6760 result = PyString_FromString(buffer);
6761 }
6762 }
6763 return result;
6764}
6765#endif
6766
6767
6768#ifdef HAVE_SYSCONF
6769static struct constdef posix_constants_sysconf[] = {
6770#ifdef _SC_2_CHAR_TERM
6771 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
6772#endif
6773#ifdef _SC_2_C_BIND
6774 {"SC_2_C_BIND", _SC_2_C_BIND},
6775#endif
6776#ifdef _SC_2_C_DEV
6777 {"SC_2_C_DEV", _SC_2_C_DEV},
6778#endif
6779#ifdef _SC_2_C_VERSION
6780 {"SC_2_C_VERSION", _SC_2_C_VERSION},
6781#endif
6782#ifdef _SC_2_FORT_DEV
6783 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
6784#endif
6785#ifdef _SC_2_FORT_RUN
6786 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
6787#endif
6788#ifdef _SC_2_LOCALEDEF
6789 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
6790#endif
6791#ifdef _SC_2_SW_DEV
6792 {"SC_2_SW_DEV", _SC_2_SW_DEV},
6793#endif
6794#ifdef _SC_2_UPE
6795 {"SC_2_UPE", _SC_2_UPE},
6796#endif
6797#ifdef _SC_2_VERSION
6798 {"SC_2_VERSION", _SC_2_VERSION},
6799#endif
Fred Draked86ed291999-12-15 15:34:33 +00006800#ifdef _SC_ABI_ASYNCHRONOUS_IO
6801 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
6802#endif
6803#ifdef _SC_ACL
6804 {"SC_ACL", _SC_ACL},
6805#endif
Fred Drakec9680921999-12-13 16:37:25 +00006806#ifdef _SC_AIO_LISTIO_MAX
6807 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
6808#endif
Fred Drakec9680921999-12-13 16:37:25 +00006809#ifdef _SC_AIO_MAX
6810 {"SC_AIO_MAX", _SC_AIO_MAX},
6811#endif
6812#ifdef _SC_AIO_PRIO_DELTA_MAX
6813 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
6814#endif
6815#ifdef _SC_ARG_MAX
6816 {"SC_ARG_MAX", _SC_ARG_MAX},
6817#endif
6818#ifdef _SC_ASYNCHRONOUS_IO
6819 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
6820#endif
6821#ifdef _SC_ATEXIT_MAX
6822 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
6823#endif
Fred Draked86ed291999-12-15 15:34:33 +00006824#ifdef _SC_AUDIT
6825 {"SC_AUDIT", _SC_AUDIT},
6826#endif
Fred Drakec9680921999-12-13 16:37:25 +00006827#ifdef _SC_AVPHYS_PAGES
6828 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
6829#endif
6830#ifdef _SC_BC_BASE_MAX
6831 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
6832#endif
6833#ifdef _SC_BC_DIM_MAX
6834 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
6835#endif
6836#ifdef _SC_BC_SCALE_MAX
6837 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
6838#endif
6839#ifdef _SC_BC_STRING_MAX
6840 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
6841#endif
Fred Draked86ed291999-12-15 15:34:33 +00006842#ifdef _SC_CAP
6843 {"SC_CAP", _SC_CAP},
6844#endif
Fred Drakec9680921999-12-13 16:37:25 +00006845#ifdef _SC_CHARCLASS_NAME_MAX
6846 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
6847#endif
6848#ifdef _SC_CHAR_BIT
6849 {"SC_CHAR_BIT", _SC_CHAR_BIT},
6850#endif
6851#ifdef _SC_CHAR_MAX
6852 {"SC_CHAR_MAX", _SC_CHAR_MAX},
6853#endif
6854#ifdef _SC_CHAR_MIN
6855 {"SC_CHAR_MIN", _SC_CHAR_MIN},
6856#endif
6857#ifdef _SC_CHILD_MAX
6858 {"SC_CHILD_MAX", _SC_CHILD_MAX},
6859#endif
6860#ifdef _SC_CLK_TCK
6861 {"SC_CLK_TCK", _SC_CLK_TCK},
6862#endif
6863#ifdef _SC_COHER_BLKSZ
6864 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
6865#endif
6866#ifdef _SC_COLL_WEIGHTS_MAX
6867 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
6868#endif
6869#ifdef _SC_DCACHE_ASSOC
6870 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
6871#endif
6872#ifdef _SC_DCACHE_BLKSZ
6873 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
6874#endif
6875#ifdef _SC_DCACHE_LINESZ
6876 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
6877#endif
6878#ifdef _SC_DCACHE_SZ
6879 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
6880#endif
6881#ifdef _SC_DCACHE_TBLKSZ
6882 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
6883#endif
6884#ifdef _SC_DELAYTIMER_MAX
6885 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
6886#endif
6887#ifdef _SC_EQUIV_CLASS_MAX
6888 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
6889#endif
6890#ifdef _SC_EXPR_NEST_MAX
6891 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
6892#endif
6893#ifdef _SC_FSYNC
6894 {"SC_FSYNC", _SC_FSYNC},
6895#endif
6896#ifdef _SC_GETGR_R_SIZE_MAX
6897 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
6898#endif
6899#ifdef _SC_GETPW_R_SIZE_MAX
6900 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
6901#endif
6902#ifdef _SC_ICACHE_ASSOC
6903 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
6904#endif
6905#ifdef _SC_ICACHE_BLKSZ
6906 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
6907#endif
6908#ifdef _SC_ICACHE_LINESZ
6909 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
6910#endif
6911#ifdef _SC_ICACHE_SZ
6912 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
6913#endif
Fred Draked86ed291999-12-15 15:34:33 +00006914#ifdef _SC_INF
6915 {"SC_INF", _SC_INF},
6916#endif
Fred Drakec9680921999-12-13 16:37:25 +00006917#ifdef _SC_INT_MAX
6918 {"SC_INT_MAX", _SC_INT_MAX},
6919#endif
6920#ifdef _SC_INT_MIN
6921 {"SC_INT_MIN", _SC_INT_MIN},
6922#endif
6923#ifdef _SC_IOV_MAX
6924 {"SC_IOV_MAX", _SC_IOV_MAX},
6925#endif
Fred Draked86ed291999-12-15 15:34:33 +00006926#ifdef _SC_IP_SECOPTS
6927 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
6928#endif
Fred Drakec9680921999-12-13 16:37:25 +00006929#ifdef _SC_JOB_CONTROL
6930 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
6931#endif
Fred Draked86ed291999-12-15 15:34:33 +00006932#ifdef _SC_KERN_POINTERS
6933 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
6934#endif
6935#ifdef _SC_KERN_SIM
6936 {"SC_KERN_SIM", _SC_KERN_SIM},
6937#endif
Fred Drakec9680921999-12-13 16:37:25 +00006938#ifdef _SC_LINE_MAX
6939 {"SC_LINE_MAX", _SC_LINE_MAX},
6940#endif
6941#ifdef _SC_LOGIN_NAME_MAX
6942 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
6943#endif
6944#ifdef _SC_LOGNAME_MAX
6945 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
6946#endif
6947#ifdef _SC_LONG_BIT
6948 {"SC_LONG_BIT", _SC_LONG_BIT},
6949#endif
Fred Draked86ed291999-12-15 15:34:33 +00006950#ifdef _SC_MAC
6951 {"SC_MAC", _SC_MAC},
6952#endif
Fred Drakec9680921999-12-13 16:37:25 +00006953#ifdef _SC_MAPPED_FILES
6954 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
6955#endif
6956#ifdef _SC_MAXPID
6957 {"SC_MAXPID", _SC_MAXPID},
6958#endif
6959#ifdef _SC_MB_LEN_MAX
6960 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
6961#endif
6962#ifdef _SC_MEMLOCK
6963 {"SC_MEMLOCK", _SC_MEMLOCK},
6964#endif
6965#ifdef _SC_MEMLOCK_RANGE
6966 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
6967#endif
6968#ifdef _SC_MEMORY_PROTECTION
6969 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
6970#endif
6971#ifdef _SC_MESSAGE_PASSING
6972 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
6973#endif
Fred Draked86ed291999-12-15 15:34:33 +00006974#ifdef _SC_MMAP_FIXED_ALIGNMENT
6975 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
6976#endif
Fred Drakec9680921999-12-13 16:37:25 +00006977#ifdef _SC_MQ_OPEN_MAX
6978 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
6979#endif
6980#ifdef _SC_MQ_PRIO_MAX
6981 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
6982#endif
Fred Draked86ed291999-12-15 15:34:33 +00006983#ifdef _SC_NACLS_MAX
6984 {"SC_NACLS_MAX", _SC_NACLS_MAX},
6985#endif
Fred Drakec9680921999-12-13 16:37:25 +00006986#ifdef _SC_NGROUPS_MAX
6987 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
6988#endif
6989#ifdef _SC_NL_ARGMAX
6990 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
6991#endif
6992#ifdef _SC_NL_LANGMAX
6993 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
6994#endif
6995#ifdef _SC_NL_MSGMAX
6996 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
6997#endif
6998#ifdef _SC_NL_NMAX
6999 {"SC_NL_NMAX", _SC_NL_NMAX},
7000#endif
7001#ifdef _SC_NL_SETMAX
7002 {"SC_NL_SETMAX", _SC_NL_SETMAX},
7003#endif
7004#ifdef _SC_NL_TEXTMAX
7005 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
7006#endif
7007#ifdef _SC_NPROCESSORS_CONF
7008 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
7009#endif
7010#ifdef _SC_NPROCESSORS_ONLN
7011 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
7012#endif
Fred Draked86ed291999-12-15 15:34:33 +00007013#ifdef _SC_NPROC_CONF
7014 {"SC_NPROC_CONF", _SC_NPROC_CONF},
7015#endif
7016#ifdef _SC_NPROC_ONLN
7017 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
7018#endif
Fred Drakec9680921999-12-13 16:37:25 +00007019#ifdef _SC_NZERO
7020 {"SC_NZERO", _SC_NZERO},
7021#endif
7022#ifdef _SC_OPEN_MAX
7023 {"SC_OPEN_MAX", _SC_OPEN_MAX},
7024#endif
7025#ifdef _SC_PAGESIZE
7026 {"SC_PAGESIZE", _SC_PAGESIZE},
7027#endif
7028#ifdef _SC_PAGE_SIZE
7029 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
7030#endif
7031#ifdef _SC_PASS_MAX
7032 {"SC_PASS_MAX", _SC_PASS_MAX},
7033#endif
7034#ifdef _SC_PHYS_PAGES
7035 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
7036#endif
7037#ifdef _SC_PII
7038 {"SC_PII", _SC_PII},
7039#endif
7040#ifdef _SC_PII_INTERNET
7041 {"SC_PII_INTERNET", _SC_PII_INTERNET},
7042#endif
7043#ifdef _SC_PII_INTERNET_DGRAM
7044 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
7045#endif
7046#ifdef _SC_PII_INTERNET_STREAM
7047 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
7048#endif
7049#ifdef _SC_PII_OSI
7050 {"SC_PII_OSI", _SC_PII_OSI},
7051#endif
7052#ifdef _SC_PII_OSI_CLTS
7053 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
7054#endif
7055#ifdef _SC_PII_OSI_COTS
7056 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
7057#endif
7058#ifdef _SC_PII_OSI_M
7059 {"SC_PII_OSI_M", _SC_PII_OSI_M},
7060#endif
7061#ifdef _SC_PII_SOCKET
7062 {"SC_PII_SOCKET", _SC_PII_SOCKET},
7063#endif
7064#ifdef _SC_PII_XTI
7065 {"SC_PII_XTI", _SC_PII_XTI},
7066#endif
7067#ifdef _SC_POLL
7068 {"SC_POLL", _SC_POLL},
7069#endif
7070#ifdef _SC_PRIORITIZED_IO
7071 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
7072#endif
7073#ifdef _SC_PRIORITY_SCHEDULING
7074 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
7075#endif
7076#ifdef _SC_REALTIME_SIGNALS
7077 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
7078#endif
7079#ifdef _SC_RE_DUP_MAX
7080 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
7081#endif
7082#ifdef _SC_RTSIG_MAX
7083 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
7084#endif
7085#ifdef _SC_SAVED_IDS
7086 {"SC_SAVED_IDS", _SC_SAVED_IDS},
7087#endif
7088#ifdef _SC_SCHAR_MAX
7089 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
7090#endif
7091#ifdef _SC_SCHAR_MIN
7092 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
7093#endif
7094#ifdef _SC_SELECT
7095 {"SC_SELECT", _SC_SELECT},
7096#endif
7097#ifdef _SC_SEMAPHORES
7098 {"SC_SEMAPHORES", _SC_SEMAPHORES},
7099#endif
7100#ifdef _SC_SEM_NSEMS_MAX
7101 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
7102#endif
7103#ifdef _SC_SEM_VALUE_MAX
7104 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
7105#endif
7106#ifdef _SC_SHARED_MEMORY_OBJECTS
7107 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
7108#endif
7109#ifdef _SC_SHRT_MAX
7110 {"SC_SHRT_MAX", _SC_SHRT_MAX},
7111#endif
7112#ifdef _SC_SHRT_MIN
7113 {"SC_SHRT_MIN", _SC_SHRT_MIN},
7114#endif
7115#ifdef _SC_SIGQUEUE_MAX
7116 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
7117#endif
7118#ifdef _SC_SIGRT_MAX
7119 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
7120#endif
7121#ifdef _SC_SIGRT_MIN
7122 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
7123#endif
Fred Draked86ed291999-12-15 15:34:33 +00007124#ifdef _SC_SOFTPOWER
7125 {"SC_SOFTPOWER", _SC_SOFTPOWER},
7126#endif
Fred Drakec9680921999-12-13 16:37:25 +00007127#ifdef _SC_SPLIT_CACHE
7128 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
7129#endif
7130#ifdef _SC_SSIZE_MAX
7131 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
7132#endif
7133#ifdef _SC_STACK_PROT
7134 {"SC_STACK_PROT", _SC_STACK_PROT},
7135#endif
7136#ifdef _SC_STREAM_MAX
7137 {"SC_STREAM_MAX", _SC_STREAM_MAX},
7138#endif
7139#ifdef _SC_SYNCHRONIZED_IO
7140 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
7141#endif
7142#ifdef _SC_THREADS
7143 {"SC_THREADS", _SC_THREADS},
7144#endif
7145#ifdef _SC_THREAD_ATTR_STACKADDR
7146 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
7147#endif
7148#ifdef _SC_THREAD_ATTR_STACKSIZE
7149 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
7150#endif
7151#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
7152 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
7153#endif
7154#ifdef _SC_THREAD_KEYS_MAX
7155 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
7156#endif
7157#ifdef _SC_THREAD_PRIORITY_SCHEDULING
7158 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
7159#endif
7160#ifdef _SC_THREAD_PRIO_INHERIT
7161 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
7162#endif
7163#ifdef _SC_THREAD_PRIO_PROTECT
7164 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
7165#endif
7166#ifdef _SC_THREAD_PROCESS_SHARED
7167 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
7168#endif
7169#ifdef _SC_THREAD_SAFE_FUNCTIONS
7170 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
7171#endif
7172#ifdef _SC_THREAD_STACK_MIN
7173 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
7174#endif
7175#ifdef _SC_THREAD_THREADS_MAX
7176 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
7177#endif
7178#ifdef _SC_TIMERS
7179 {"SC_TIMERS", _SC_TIMERS},
7180#endif
7181#ifdef _SC_TIMER_MAX
7182 {"SC_TIMER_MAX", _SC_TIMER_MAX},
7183#endif
7184#ifdef _SC_TTY_NAME_MAX
7185 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
7186#endif
7187#ifdef _SC_TZNAME_MAX
7188 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
7189#endif
7190#ifdef _SC_T_IOV_MAX
7191 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
7192#endif
7193#ifdef _SC_UCHAR_MAX
7194 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
7195#endif
7196#ifdef _SC_UINT_MAX
7197 {"SC_UINT_MAX", _SC_UINT_MAX},
7198#endif
7199#ifdef _SC_UIO_MAXIOV
7200 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
7201#endif
7202#ifdef _SC_ULONG_MAX
7203 {"SC_ULONG_MAX", _SC_ULONG_MAX},
7204#endif
7205#ifdef _SC_USHRT_MAX
7206 {"SC_USHRT_MAX", _SC_USHRT_MAX},
7207#endif
7208#ifdef _SC_VERSION
7209 {"SC_VERSION", _SC_VERSION},
7210#endif
7211#ifdef _SC_WORD_BIT
7212 {"SC_WORD_BIT", _SC_WORD_BIT},
7213#endif
7214#ifdef _SC_XBS5_ILP32_OFF32
7215 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
7216#endif
7217#ifdef _SC_XBS5_ILP32_OFFBIG
7218 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
7219#endif
7220#ifdef _SC_XBS5_LP64_OFF64
7221 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
7222#endif
7223#ifdef _SC_XBS5_LPBIG_OFFBIG
7224 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
7225#endif
7226#ifdef _SC_XOPEN_CRYPT
7227 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
7228#endif
7229#ifdef _SC_XOPEN_ENH_I18N
7230 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
7231#endif
7232#ifdef _SC_XOPEN_LEGACY
7233 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
7234#endif
7235#ifdef _SC_XOPEN_REALTIME
7236 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
7237#endif
7238#ifdef _SC_XOPEN_REALTIME_THREADS
7239 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
7240#endif
7241#ifdef _SC_XOPEN_SHM
7242 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
7243#endif
7244#ifdef _SC_XOPEN_UNIX
7245 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
7246#endif
7247#ifdef _SC_XOPEN_VERSION
7248 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
7249#endif
7250#ifdef _SC_XOPEN_XCU_VERSION
7251 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
7252#endif
7253#ifdef _SC_XOPEN_XPG2
7254 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
7255#endif
7256#ifdef _SC_XOPEN_XPG3
7257 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
7258#endif
7259#ifdef _SC_XOPEN_XPG4
7260 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
7261#endif
7262};
7263
7264static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007265conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007266{
7267 return conv_confname(arg, valuep, posix_constants_sysconf,
7268 sizeof(posix_constants_sysconf)
7269 / sizeof(struct constdef));
7270}
7271
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007272PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007273"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007274Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007275
7276static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007277posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007278{
7279 PyObject *result = NULL;
7280 int name;
7281
7282 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
7283 int value;
7284
7285 errno = 0;
7286 value = sysconf(name);
7287 if (value == -1 && errno != 0)
7288 posix_error();
7289 else
7290 result = PyInt_FromLong(value);
7291 }
7292 return result;
7293}
7294#endif
7295
7296
Fred Drakebec628d1999-12-15 18:31:10 +00007297/* This code is used to ensure that the tables of configuration value names
7298 * are in sorted order as required by conv_confname(), and also to build the
7299 * the exported dictionaries that are used to publish information about the
7300 * names available on the host platform.
7301 *
7302 * Sorting the table at runtime ensures that the table is properly ordered
7303 * when used, even for platforms we're not able to test on. It also makes
7304 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00007305 */
Fred Drakebec628d1999-12-15 18:31:10 +00007306
7307static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007308cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00007309{
7310 const struct constdef *c1 =
7311 (const struct constdef *) v1;
7312 const struct constdef *c2 =
7313 (const struct constdef *) v2;
7314
7315 return strcmp(c1->name, c2->name);
7316}
7317
7318static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007319setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00007320 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007321{
Fred Drakebec628d1999-12-15 18:31:10 +00007322 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00007323 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00007324
7325 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
7326 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00007327 if (d == NULL)
7328 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007329
Barry Warsaw3155db32000-04-13 15:20:40 +00007330 for (i=0; i < tablesize; ++i) {
7331 PyObject *o = PyInt_FromLong(table[i].value);
7332 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
7333 Py_XDECREF(o);
7334 Py_DECREF(d);
7335 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007336 }
Barry Warsaw3155db32000-04-13 15:20:40 +00007337 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00007338 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00007339 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00007340}
7341
Fred Drakebec628d1999-12-15 18:31:10 +00007342/* Return -1 on failure, 0 on success. */
7343static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007344setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007345{
7346#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00007347 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00007348 sizeof(posix_constants_pathconf)
7349 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007350 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007351 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007352#endif
7353#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00007354 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00007355 sizeof(posix_constants_confstr)
7356 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007357 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007358 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007359#endif
7360#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00007361 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00007362 sizeof(posix_constants_sysconf)
7363 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007364 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007365 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007366#endif
Fred Drakebec628d1999-12-15 18:31:10 +00007367 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00007368}
Fred Draked86ed291999-12-15 15:34:33 +00007369
7370
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007371PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007372"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007373Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007374in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007375
7376static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007377posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007378{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007379 abort();
7380 /*NOTREACHED*/
7381 Py_FatalError("abort() called from Python code didn't abort!");
7382 return NULL;
7383}
Fred Drakebec628d1999-12-15 18:31:10 +00007384
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007385#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007386PyDoc_STRVAR(win32_startfile__doc__,
7387"startfile(filepath) - Start a file with its associated application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007388\n\
7389This acts like double-clicking the file in Explorer, or giving the file\n\
7390name as an argument to the DOS \"start\" command: the file is opened\n\
7391with whatever application (if any) its extension is associated.\n\
7392\n\
7393startfile returns as soon as the associated application is launched.\n\
7394There is no option to wait for the application to close, and no way\n\
7395to retrieve the application's exit status.\n\
7396\n\
7397The filepath is relative to the current directory. If you want to use\n\
7398an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007399the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00007400
7401static PyObject *
7402win32_startfile(PyObject *self, PyObject *args)
7403{
7404 char *filepath;
7405 HINSTANCE rc;
Georg Brandl402b53d2005-09-14 20:51:40 +00007406 if (!PyArg_ParseTuple(args, "et:startfile",
7407 Py_FileSystemDefaultEncoding, &filepath))
Tim Petersf58a7aa2000-09-22 10:05:54 +00007408 return NULL;
7409 Py_BEGIN_ALLOW_THREADS
7410 rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
7411 Py_END_ALLOW_THREADS
Georg Brandle9f8ec92005-09-25 06:16:40 +00007412 if (rc <= (HINSTANCE)32) {
7413 PyObject *errval = win32_error("startfile", filepath);
7414 PyMem_Free(filepath);
7415 return errval;
7416 }
7417 PyMem_Free(filepath);
Tim Petersf58a7aa2000-09-22 10:05:54 +00007418 Py_INCREF(Py_None);
7419 return Py_None;
7420}
7421#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007422
Martin v. Löwis438b5342002-12-27 10:16:42 +00007423#ifdef HAVE_GETLOADAVG
7424PyDoc_STRVAR(posix_getloadavg__doc__,
7425"getloadavg() -> (float, float, float)\n\n\
7426Return the number of processes in the system run queue averaged over\n\
7427the last 1, 5, and 15 minutes or raises OSError if the load average\n\
7428was unobtainable");
7429
7430static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007431posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00007432{
7433 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00007434 if (getloadavg(loadavg, 3)!=3) {
7435 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
7436 return NULL;
7437 } else
7438 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
7439}
7440#endif
7441
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007442#ifdef MS_WINDOWS
7443
7444PyDoc_STRVAR(win32_urandom__doc__,
7445"urandom(n) -> str\n\n\
7446Return a string of n random bytes suitable for cryptographic use.");
7447
7448typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
7449 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
7450 DWORD dwFlags );
7451typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
7452 BYTE *pbBuffer );
7453
7454static CRYPTGENRANDOM pCryptGenRandom = NULL;
7455static HCRYPTPROV hCryptProv = 0;
7456
Tim Peters4ad82172004-08-30 17:02:04 +00007457static PyObject*
7458win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007459{
Tim Petersd3115382004-08-30 17:36:46 +00007460 int howMany;
7461 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007462
Tim Peters4ad82172004-08-30 17:02:04 +00007463 /* Read arguments */
Tim Peters9b279a82004-08-30 17:10:53 +00007464 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
Tim Peters4ad82172004-08-30 17:02:04 +00007465 return NULL;
Tim Peters51eba612004-08-30 17:08:02 +00007466 if (howMany < 0)
7467 return PyErr_Format(PyExc_ValueError,
7468 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007469
Tim Peters4ad82172004-08-30 17:02:04 +00007470 if (hCryptProv == 0) {
7471 HINSTANCE hAdvAPI32 = NULL;
7472 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007473
Tim Peters4ad82172004-08-30 17:02:04 +00007474 /* Obtain handle to the DLL containing CryptoAPI
7475 This should not fail */
7476 hAdvAPI32 = GetModuleHandle("advapi32.dll");
7477 if(hAdvAPI32 == NULL)
7478 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007479
Tim Peters4ad82172004-08-30 17:02:04 +00007480 /* Obtain pointers to the CryptoAPI functions
7481 This will fail on some early versions of Win95 */
7482 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
7483 hAdvAPI32,
7484 "CryptAcquireContextA");
7485 if (pCryptAcquireContext == NULL)
7486 return PyErr_Format(PyExc_NotImplementedError,
7487 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007488
Tim Peters4ad82172004-08-30 17:02:04 +00007489 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
7490 hAdvAPI32, "CryptGenRandom");
7491 if (pCryptAcquireContext == NULL)
7492 return PyErr_Format(PyExc_NotImplementedError,
7493 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007494
Tim Peters4ad82172004-08-30 17:02:04 +00007495 /* Acquire context */
7496 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
7497 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
7498 return win32_error("CryptAcquireContext", NULL);
7499 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007500
Tim Peters4ad82172004-08-30 17:02:04 +00007501 /* Allocate bytes */
Tim Petersd3115382004-08-30 17:36:46 +00007502 result = PyString_FromStringAndSize(NULL, howMany);
7503 if (result != NULL) {
7504 /* Get random data */
7505 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
7506 PyString_AS_STRING(result))) {
7507 Py_DECREF(result);
7508 return win32_error("CryptGenRandom", NULL);
7509 }
Tim Peters4ad82172004-08-30 17:02:04 +00007510 }
Tim Petersd3115382004-08-30 17:36:46 +00007511 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007512}
7513#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007514
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007515static PyMethodDef posix_methods[] = {
7516 {"access", posix_access, METH_VARARGS, posix_access__doc__},
7517#ifdef HAVE_TTYNAME
7518 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
7519#endif
7520 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
7521 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007522#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007523 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007524#endif /* HAVE_CHOWN */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007525#ifdef HAVE_LCHOWN
7526 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
7527#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00007528#ifdef HAVE_CHROOT
7529 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
7530#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007531#ifdef HAVE_CTERMID
Neal Norwitze241ce82003-02-17 18:17:05 +00007532 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007533#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00007534#ifdef HAVE_GETCWD
Neal Norwitze241ce82003-02-17 18:17:05 +00007535 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Walter Dörwald3b918c32002-11-21 20:18:46 +00007536#ifdef Py_USING_UNICODE
Neal Norwitze241ce82003-02-17 18:17:05 +00007537 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00007538#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00007539#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007540#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007541 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007542#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007543 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
7544 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
7545 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007546#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007547 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007548#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007549#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007550 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007551#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007552 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
7553 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
7554 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007555 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007556#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007557 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007558#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007559#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007560 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007561#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007562 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007563#ifdef HAVE_UNAME
Neal Norwitze241ce82003-02-17 18:17:05 +00007564 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007565#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007566 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
7567 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
7568 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007569#ifdef HAVE_TIMES
Neal Norwitze241ce82003-02-17 18:17:05 +00007570 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007571#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007572 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007573#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007574 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
7575 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007576#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00007577#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007578 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
7579 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00007580#if defined(PYOS_OS2)
7581 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
7582 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
7583#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00007584#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007585#ifdef HAVE_FORK1
Neal Norwitze241ce82003-02-17 18:17:05 +00007586 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007587#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007588#ifdef HAVE_FORK
Neal Norwitze241ce82003-02-17 18:17:05 +00007589 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007590#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007591#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Neal Norwitze241ce82003-02-17 18:17:05 +00007592 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007593#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007594#ifdef HAVE_FORKPTY
Neal Norwitze241ce82003-02-17 18:17:05 +00007595 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00007596#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007597#ifdef HAVE_GETEGID
Neal Norwitze241ce82003-02-17 18:17:05 +00007598 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007599#endif /* HAVE_GETEGID */
7600#ifdef HAVE_GETEUID
Neal Norwitze241ce82003-02-17 18:17:05 +00007601 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007602#endif /* HAVE_GETEUID */
7603#ifdef HAVE_GETGID
Neal Norwitze241ce82003-02-17 18:17:05 +00007604 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007605#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00007606#ifdef HAVE_GETGROUPS
Neal Norwitze241ce82003-02-17 18:17:05 +00007607 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007608#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007609 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007610#ifdef HAVE_GETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00007611 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007612#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007613#ifdef HAVE_GETPPID
Neal Norwitze241ce82003-02-17 18:17:05 +00007614 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007615#endif /* HAVE_GETPPID */
7616#ifdef HAVE_GETUID
Neal Norwitze241ce82003-02-17 18:17:05 +00007617 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007618#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007619#ifdef HAVE_GETLOGIN
Neal Norwitze241ce82003-02-17 18:17:05 +00007620 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00007621#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00007622#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007623 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007624#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007625#ifdef HAVE_KILLPG
7626 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
7627#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00007628#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007629 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00007630#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007631#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007632 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007633#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00007634 {"popen2", win32_popen2, METH_VARARGS},
7635 {"popen3", win32_popen3, METH_VARARGS},
7636 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00007637 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007638#else
7639#if defined(PYOS_OS2) && defined(PYCC_GCC)
7640 {"popen2", os2emx_popen2, METH_VARARGS},
7641 {"popen3", os2emx_popen3, METH_VARARGS},
7642 {"popen4", os2emx_popen4, METH_VARARGS},
7643#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00007644#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007645#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007646#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007647 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007648#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007649#ifdef HAVE_SETEUID
7650 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
7651#endif /* HAVE_SETEUID */
7652#ifdef HAVE_SETEGID
7653 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
7654#endif /* HAVE_SETEGID */
7655#ifdef HAVE_SETREUID
7656 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
7657#endif /* HAVE_SETREUID */
7658#ifdef HAVE_SETREGID
7659 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
7660#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007661#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007662 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007663#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007664#ifdef HAVE_SETGROUPS
7665 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
7666#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00007667#ifdef HAVE_GETPGID
7668 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
7669#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007670#ifdef HAVE_SETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00007671 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007672#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007673#ifdef HAVE_WAIT
Neal Norwitze241ce82003-02-17 18:17:05 +00007674 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007675#endif /* HAVE_WAIT */
Tim Petersab034fa2002-02-01 11:27:43 +00007676#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007677 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007678#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007679#ifdef HAVE_GETSID
7680 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
7681#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007682#ifdef HAVE_SETSID
Neal Norwitze241ce82003-02-17 18:17:05 +00007683 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007684#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007685#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007686 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007687#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007688#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007689 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007690#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007691#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007692 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007693#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007694 {"open", posix_open, METH_VARARGS, posix_open__doc__},
7695 {"close", posix_close, METH_VARARGS, posix_close__doc__},
7696 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
7697 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
7698 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
7699 {"read", posix_read, METH_VARARGS, posix_read__doc__},
7700 {"write", posix_write, METH_VARARGS, posix_write__doc__},
7701 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
7702 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00007703 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007704#ifdef HAVE_PIPE
Neal Norwitze241ce82003-02-17 18:17:05 +00007705 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007706#endif
7707#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007708 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007709#endif
Neal Norwitz11690112002-07-30 01:08:28 +00007710#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007711 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
7712#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007713#ifdef HAVE_DEVICE_MACROS
7714 {"major", posix_major, METH_VARARGS, posix_major__doc__},
7715 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
7716 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
7717#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007718#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007719 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007720#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007721#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007722 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007723#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007724#ifdef HAVE_UNSETENV
7725 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
7726#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00007727#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007728 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00007729#endif
Fred Drake4d1e64b2002-04-15 19:40:07 +00007730#ifdef HAVE_FCHDIR
7731 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
7732#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00007733#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007734 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007735#endif
7736#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007737 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007738#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00007739#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00007740#ifdef WCOREDUMP
7741 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
7742#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007743#ifdef WIFCONTINUED
7744 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
7745#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00007746#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007747 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007748#endif /* WIFSTOPPED */
7749#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007750 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007751#endif /* WIFSIGNALED */
7752#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007753 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007754#endif /* WIFEXITED */
7755#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007756 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007757#endif /* WEXITSTATUS */
7758#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007759 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007760#endif /* WTERMSIG */
7761#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007762 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007763#endif /* WSTOPSIG */
7764#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007765#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007766 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007767#endif
7768#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007769 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007770#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00007771#ifdef HAVE_TMPFILE
Neal Norwitze241ce82003-02-17 18:17:05 +00007772 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007773#endif
7774#ifdef HAVE_TEMPNAM
7775 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
7776#endif
7777#ifdef HAVE_TMPNAM
Neal Norwitze241ce82003-02-17 18:17:05 +00007778 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007779#endif
Fred Drakec9680921999-12-13 16:37:25 +00007780#ifdef HAVE_CONFSTR
7781 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
7782#endif
7783#ifdef HAVE_SYSCONF
7784 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
7785#endif
7786#ifdef HAVE_FPATHCONF
7787 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
7788#endif
7789#ifdef HAVE_PATHCONF
7790 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
7791#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007792 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007793#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00007794 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
7795#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007796#ifdef HAVE_GETLOADAVG
Neal Norwitze241ce82003-02-17 18:17:05 +00007797 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00007798#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007799 #ifdef MS_WINDOWS
7800 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
7801 #endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007802 {NULL, NULL} /* Sentinel */
7803};
7804
7805
Barry Warsaw4a342091996-12-19 23:50:02 +00007806static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007807ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00007808{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007809 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00007810}
7811
Guido van Rossumd48f2521997-12-05 22:19:34 +00007812#if defined(PYOS_OS2)
7813/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007814static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007815{
7816 APIRET rc;
7817 ULONG values[QSV_MAX+1];
7818 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00007819 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00007820
7821 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00007822 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007823 Py_END_ALLOW_THREADS
7824
7825 if (rc != NO_ERROR) {
7826 os2_error(rc);
7827 return -1;
7828 }
7829
Fred Drake4d1e64b2002-04-15 19:40:07 +00007830 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
7831 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
7832 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
7833 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
7834 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
7835 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
7836 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007837
7838 switch (values[QSV_VERSION_MINOR]) {
7839 case 0: ver = "2.00"; break;
7840 case 10: ver = "2.10"; break;
7841 case 11: ver = "2.11"; break;
7842 case 30: ver = "3.00"; break;
7843 case 40: ver = "4.00"; break;
7844 case 50: ver = "5.00"; break;
7845 default:
Tim Peters885d4572001-11-28 20:27:42 +00007846 PyOS_snprintf(tmp, sizeof(tmp),
7847 "%d-%d", values[QSV_VERSION_MAJOR],
7848 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007849 ver = &tmp[0];
7850 }
7851
7852 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007853 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007854 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007855
7856 /* Add Indicator of Which Drive was Used to Boot the System */
7857 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
7858 tmp[1] = ':';
7859 tmp[2] = '\0';
7860
Fred Drake4d1e64b2002-04-15 19:40:07 +00007861 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007862}
7863#endif
7864
Barry Warsaw4a342091996-12-19 23:50:02 +00007865static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007866all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00007867{
Guido van Rossum94f6f721999-01-06 18:42:14 +00007868#ifdef F_OK
7869 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007870#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007871#ifdef R_OK
7872 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007873#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007874#ifdef W_OK
7875 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007876#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007877#ifdef X_OK
7878 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007879#endif
Fred Drakec9680921999-12-13 16:37:25 +00007880#ifdef NGROUPS_MAX
7881 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
7882#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007883#ifdef TMP_MAX
7884 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
7885#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007886#ifdef WCONTINUED
7887 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
7888#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007889#ifdef WNOHANG
7890 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007891#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007892#ifdef WUNTRACED
7893 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
7894#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007895#ifdef O_RDONLY
7896 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
7897#endif
7898#ifdef O_WRONLY
7899 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
7900#endif
7901#ifdef O_RDWR
7902 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
7903#endif
7904#ifdef O_NDELAY
7905 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
7906#endif
7907#ifdef O_NONBLOCK
7908 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
7909#endif
7910#ifdef O_APPEND
7911 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
7912#endif
7913#ifdef O_DSYNC
7914 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
7915#endif
7916#ifdef O_RSYNC
7917 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
7918#endif
7919#ifdef O_SYNC
7920 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
7921#endif
7922#ifdef O_NOCTTY
7923 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
7924#endif
7925#ifdef O_CREAT
7926 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
7927#endif
7928#ifdef O_EXCL
7929 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
7930#endif
7931#ifdef O_TRUNC
7932 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
7933#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00007934#ifdef O_BINARY
7935 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
7936#endif
7937#ifdef O_TEXT
7938 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
7939#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007940#ifdef O_LARGEFILE
7941 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
7942#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00007943#ifdef O_SHLOCK
7944 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
7945#endif
7946#ifdef O_EXLOCK
7947 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
7948#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007949
Tim Peters5aa91602002-01-30 05:46:57 +00007950/* MS Windows */
7951#ifdef O_NOINHERIT
7952 /* Don't inherit in child processes. */
7953 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
7954#endif
7955#ifdef _O_SHORT_LIVED
7956 /* Optimize for short life (keep in memory). */
7957 /* MS forgot to define this one with a non-underscore form too. */
7958 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
7959#endif
7960#ifdef O_TEMPORARY
7961 /* Automatically delete when last handle is closed. */
7962 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
7963#endif
7964#ifdef O_RANDOM
7965 /* Optimize for random access. */
7966 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
7967#endif
7968#ifdef O_SEQUENTIAL
7969 /* Optimize for sequential access. */
7970 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
7971#endif
7972
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007973/* GNU extensions. */
7974#ifdef O_DIRECT
7975 /* Direct disk access. */
7976 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
7977#endif
7978#ifdef O_DIRECTORY
7979 /* Must be a directory. */
7980 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
7981#endif
7982#ifdef O_NOFOLLOW
7983 /* Do not follow links. */
7984 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
7985#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00007986
Barry Warsaw5676bd12003-01-07 20:57:09 +00007987 /* These come from sysexits.h */
7988#ifdef EX_OK
7989 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007990#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007991#ifdef EX_USAGE
7992 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007993#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007994#ifdef EX_DATAERR
7995 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007996#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00007997#ifdef EX_NOINPUT
7998 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00007999#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008000#ifdef EX_NOUSER
8001 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008002#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008003#ifdef EX_NOHOST
8004 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008005#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008006#ifdef EX_UNAVAILABLE
8007 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008008#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008009#ifdef EX_SOFTWARE
8010 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008011#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008012#ifdef EX_OSERR
8013 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008014#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008015#ifdef EX_OSFILE
8016 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008017#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008018#ifdef EX_CANTCREAT
8019 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008020#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008021#ifdef EX_IOERR
8022 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008023#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008024#ifdef EX_TEMPFAIL
8025 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008026#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008027#ifdef EX_PROTOCOL
8028 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008029#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008030#ifdef EX_NOPERM
8031 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008032#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008033#ifdef EX_CONFIG
8034 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008035#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008036#ifdef EX_NOTFOUND
8037 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008038#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008039
Guido van Rossum246bc171999-02-01 23:54:31 +00008040#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008041#if defined(PYOS_OS2) && defined(PYCC_GCC)
8042 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
8043 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
8044 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
8045 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
8046 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
8047 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
8048 if (ins(d, "P_PM", (long)P_PM)) return -1;
8049 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
8050 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
8051 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
8052 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
8053 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
8054 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
8055 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
8056 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
8057 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
8058 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
8059 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
8060 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
8061 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
8062#else
Guido van Rossum7d385291999-02-16 19:38:04 +00008063 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
8064 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
8065 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
8066 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
8067 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00008068#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008069#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00008070
Guido van Rossumd48f2521997-12-05 22:19:34 +00008071#if defined(PYOS_OS2)
8072 if (insertvalues(d)) return -1;
8073#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008074 return 0;
8075}
8076
8077
Tim Peters5aa91602002-01-30 05:46:57 +00008078#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008079#define INITFUNC initnt
8080#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008081
8082#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008083#define INITFUNC initos2
8084#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008085
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008086#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008087#define INITFUNC initposix
8088#define MODNAME "posix"
8089#endif
8090
Mark Hammondfe51c6d2002-08-02 02:27:13 +00008091PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008092INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00008093{
Fred Drake4d1e64b2002-04-15 19:40:07 +00008094 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00008095
Fred Drake4d1e64b2002-04-15 19:40:07 +00008096 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008097 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00008098 posix__doc__);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00008099 if (m == NULL)
8100 return;
Tim Peters5aa91602002-01-30 05:46:57 +00008101
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008102 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008103 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00008104 Py_XINCREF(v);
8105 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008106 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00008107 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00008108
Fred Drake4d1e64b2002-04-15 19:40:07 +00008109 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00008110 return;
8111
Fred Drake4d1e64b2002-04-15 19:40:07 +00008112 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00008113 return;
8114
Fred Drake4d1e64b2002-04-15 19:40:07 +00008115 Py_INCREF(PyExc_OSError);
8116 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00008117
Guido van Rossumb3d39562000-01-31 18:41:26 +00008118#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00008119 if (posix_putenv_garbage == NULL)
8120 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00008121#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008122
Guido van Rossum14648392001-12-08 18:02:58 +00008123 stat_result_desc.name = MODNAME ".stat_result";
Martin v. Löwisf607bda2002-10-16 18:27:39 +00008124 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
8125 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
8126 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008127 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00008128 structseq_new = StatResultType.tp_new;
8129 StatResultType.tp_new = statresult_new;
Fred Drake4d1e64b2002-04-15 19:40:07 +00008130 Py_INCREF((PyObject*) &StatResultType);
8131 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008132
Guido van Rossum14648392001-12-08 18:02:58 +00008133 statvfs_result_desc.name = MODNAME ".statvfs_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008134 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Fred Drake4d1e64b2002-04-15 19:40:07 +00008135 Py_INCREF((PyObject*) &StatVFSResultType);
8136 PyModule_AddObject(m, "statvfs_result",
8137 (PyObject*) &StatVFSResultType);
Guido van Rossumb6775db1994-08-01 11:34:53 +00008138}