blob: 3c28424fd3d01aee9874ae9fec28201ba0eb1f07 [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
Thomas Wouters68bc4f92006-03-01 01:05:10 +000016#define PY_SSIZE_T_CLEAN
17
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000018#include "Python.h"
19#include "structseq.h"
20
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000021#if defined(__VMS)
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000022# include <unixio.h>
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000023#endif /* defined(__VMS) */
24
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000025PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000026"This module provides access to operating system functionality that is\n\
27standardized by the C Standard and the POSIX standard (a thinly\n\
28disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000029corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000030
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000031#ifndef Py_USING_UNICODE
32/* This is used in signatures of functions. */
33#define Py_UNICODE void
34#endif
35
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000036#if defined(PYOS_OS2)
37#define INCL_DOS
38#define INCL_DOSERRORS
39#define INCL_DOSPROCESS
40#define INCL_NOPMAPI
41#include <os2.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000042#if defined(PYCC_GCC)
43#include <ctype.h>
44#include <io.h>
45#include <stdio.h>
46#include <process.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000047#endif
Andrew MacIntyreda4d6cb2004-03-29 11:53:38 +000048#include "osdefs.h"
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000049#endif
50
Guido van Rossumb6775db1994-08-01 11:34:53 +000051#include <sys/types.h>
52#include <sys/stat.h>
Guido van Rossuma6535fd2001-10-18 19:44:10 +000053
Guido van Rossum36bc6801995-06-14 22:54:23 +000054#ifdef HAVE_SYS_WAIT_H
55#include <sys/wait.h> /* For WNOHANG */
56#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000057
Guido van Rossuma376cc51996-12-05 23:43:35 +000058#include <signal.h>
Guido van Rossuma376cc51996-12-05 23:43:35 +000059
Guido van Rossumb6775db1994-08-01 11:34:53 +000060#ifdef HAVE_FCNTL_H
61#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000062#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000063
Guido van Rossuma6535fd2001-10-18 19:44:10 +000064#ifdef HAVE_GRP_H
65#include <grp.h>
66#endif
67
Barry Warsaw5676bd12003-01-07 20:57:09 +000068#ifdef HAVE_SYSEXITS_H
69#include <sysexits.h>
70#endif /* HAVE_SYSEXITS_H */
71
Anthony Baxter8a560de2004-10-13 15:30:56 +000072#ifdef HAVE_SYS_LOADAVG_H
73#include <sys/loadavg.h>
74#endif
75
Guido van Rossuma4916fa1996-05-23 22:58:55 +000076/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +000077/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000078#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000079#include <process.h>
80#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +000081#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +000082#define HAVE_GETCWD 1
83#define HAVE_OPENDIR 1
84#define HAVE_SYSTEM 1
85#if defined(__OS2__)
86#define HAVE_EXECV 1
87#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +000088#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +000089#include <process.h>
90#else
91#ifdef __BORLANDC__ /* Borland compiler */
92#define HAVE_EXECV 1
93#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +000094#define HAVE_OPENDIR 1
95#define HAVE_PIPE 1
96#define HAVE_POPEN 1
97#define HAVE_SYSTEM 1
98#define HAVE_WAIT 1
99#else
100#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000101#define HAVE_GETCWD 1
Guido van Rossuma1065681999-01-25 23:20:23 +0000102#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000103#define HAVE_EXECV 1
104#define HAVE_PIPE 1
105#define HAVE_POPEN 1
106#define HAVE_SYSTEM 1
Tim Petersab034fa2002-02-01 11:27:43 +0000107#define HAVE_CWAIT 1
Tim Peters11b23062003-04-23 02:39:17 +0000108#define HAVE_FSYNC 1
109#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000110#else
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000111#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
112/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000113#else /* all other compilers */
114/* Unix functions that the configure script doesn't check for */
115#define HAVE_EXECV 1
116#define HAVE_FORK 1
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000117#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
118#define HAVE_FORK1 1
119#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000120#define HAVE_GETCWD 1
121#define HAVE_GETEGID 1
122#define HAVE_GETEUID 1
123#define HAVE_GETGID 1
124#define HAVE_GETPPID 1
125#define HAVE_GETUID 1
126#define HAVE_KILL 1
127#define HAVE_OPENDIR 1
128#define HAVE_PIPE 1
Martin v. Löwis212ede62003-09-20 11:20:30 +0000129#ifndef __rtems__
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000130#define HAVE_POPEN 1
Martin v. Löwis212ede62003-09-20 11:20:30 +0000131#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000132#define HAVE_SYSTEM 1
133#define HAVE_WAIT 1
Guido van Rossumd371ff11999-01-25 16:12:23 +0000134#define HAVE_TTYNAME 1
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000135#endif /* PYOS_OS2 && PYCC_GCC && __VMS */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000136#endif /* _MSC_VER */
137#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000138#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000139#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000140
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000141#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000142
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000143#if defined(__sgi)&&_COMPILER_VERSION>=700
144/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
145 (default) */
146extern char *ctermid_r(char *);
147#endif
148
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000149#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000150#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000151extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000152#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000153#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000154extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000155#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000156extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000157#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000158#endif
159#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000160extern int chdir(char *);
161extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000162#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000163extern int chdir(const char *);
164extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000165#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000166#ifdef __BORLANDC__
167extern int chmod(const char *, int);
168#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000169extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000170#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000171extern int chown(const char *, uid_t, gid_t);
172extern char *getcwd(char *, int);
173extern char *strerror(int);
174extern int link(const char *, const char *);
175extern int rename(const char *, const char *);
176extern int stat(const char *, struct stat *);
177extern int unlink(const char *);
178extern int pclose(FILE *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000179#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000180extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000181#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000182#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000183extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000184#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000185#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000186
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000187#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000188
Guido van Rossumb6775db1994-08-01 11:34:53 +0000189#ifdef HAVE_UTIME_H
190#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000191#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000192
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000193#ifdef HAVE_SYS_UTIME_H
194#include <sys/utime.h>
195#define HAVE_UTIME_H /* pretend we do for the rest of this file */
196#endif /* HAVE_SYS_UTIME_H */
197
Guido van Rossumb6775db1994-08-01 11:34:53 +0000198#ifdef HAVE_SYS_TIMES_H
199#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000200#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000201
202#ifdef HAVE_SYS_PARAM_H
203#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000204#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000205
206#ifdef HAVE_SYS_UTSNAME_H
207#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000208#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000209
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000210#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000211#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000212#define NAMLEN(dirent) strlen((dirent)->d_name)
213#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000214#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000215#include <direct.h>
216#define NAMLEN(dirent) strlen((dirent)->d_name)
217#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000218#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000219#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000220#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000221#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000222#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000223#endif
224#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000225#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000226#endif
227#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000228#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000229#endif
230#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000231
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000232#ifdef _MSC_VER
Guido van Rossumb6775db1994-08-01 11:34:53 +0000233#include <direct.h>
234#include <io.h>
235#include <process.h>
Tim Petersbc2e10e2002-03-03 23:17:02 +0000236#include "osdefs.h"
Martin v. Löwisdc3883f2004-08-29 15:46:35 +0000237#define _WIN32_WINNT 0x0400 /* Needed for CryptoAPI on some systems */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000238#include <windows.h>
Tim Petersee66d0c2002-07-15 16:10:55 +0000239#include <shellapi.h> /* for ShellExecute() */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000240#define popen _popen
Guido van Rossum794d8131994-08-23 13:48:48 +0000241#define pclose _pclose
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000242#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000243
Guido van Rossumd48f2521997-12-05 22:19:34 +0000244#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000245#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000246#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000247
Tim Petersbc2e10e2002-03-03 23:17:02 +0000248#ifndef MAXPATHLEN
249#define MAXPATHLEN 1024
250#endif /* MAXPATHLEN */
251
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000252#ifdef UNION_WAIT
253/* Emulate some macros on systems that have a union instead of macros */
254
255#ifndef WIFEXITED
256#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
257#endif
258
259#ifndef WEXITSTATUS
260#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
261#endif
262
263#ifndef WTERMSIG
264#define WTERMSIG(u_wait) ((u_wait).w_termsig)
265#endif
266
267#endif /* UNION_WAIT */
268
Greg Wardb48bc172000-03-01 21:51:56 +0000269/* Don't use the "_r" form if we don't need it (also, won't have a
270 prototype for it, at least on Solaris -- maybe others as well?). */
271#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
272#define USE_CTERMID_R
273#endif
274
275#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
276#define USE_TMPNAM_R
277#endif
278
Fred Drake699f3522000-06-29 21:12:41 +0000279/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000280#undef STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000281#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwis14694662006-02-03 12:54:16 +0000282# define STAT win32_stat
283# define FSTAT win32_fstat
284# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000285#else
286# define STAT stat
287# define FSTAT fstat
288# define STRUCT_STAT struct stat
289#endif
290
Tim Peters11b23062003-04-23 02:39:17 +0000291#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000292#include <sys/mkdev.h>
293#else
294#if defined(MAJOR_IN_SYSMACROS)
295#include <sys/sysmacros.h>
296#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000297#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
298#include <sys/mkdev.h>
299#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000300#endif
Fred Drake699f3522000-06-29 21:12:41 +0000301
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000302/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000303#ifdef WITH_NEXT_FRAMEWORK
304/* On Darwin/MacOSX a shared library or framework has no access to
305** environ directly, we must obtain it with _NSGetEnviron().
306*/
307#include <crt_externs.h>
308static char **environ;
309#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000310extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000311#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000312
Barry Warsaw53699e91996-12-10 23:23:01 +0000313static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000314convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000315{
Barry Warsaw53699e91996-12-10 23:23:01 +0000316 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000317 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000318 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000319 if (d == NULL)
320 return NULL;
Jack Jansenea0c3822002-08-01 21:57:49 +0000321#ifdef WITH_NEXT_FRAMEWORK
322 if (environ == NULL)
323 environ = *_NSGetEnviron();
324#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000325 if (environ == NULL)
326 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000327 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000328 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000329 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000330 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000331 char *p = strchr(*e, '=');
332 if (p == NULL)
333 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000334 k = PyString_FromStringAndSize(*e, (int)(p-*e));
335 if (k == NULL) {
336 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000337 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000338 }
339 v = PyString_FromString(p+1);
340 if (v == NULL) {
341 PyErr_Clear();
342 Py_DECREF(k);
343 continue;
344 }
345 if (PyDict_GetItem(d, k) == NULL) {
346 if (PyDict_SetItem(d, k, v) != 0)
347 PyErr_Clear();
348 }
349 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000350 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000351 }
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000352#if defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000353 {
354 APIRET rc;
355 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
356
357 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000358 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000359 PyObject *v = PyString_FromString(buffer);
360 PyDict_SetItemString(d, "BEGINLIBPATH", v);
361 Py_DECREF(v);
362 }
363 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
364 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
365 PyObject *v = PyString_FromString(buffer);
366 PyDict_SetItemString(d, "ENDLIBPATH", v);
367 Py_DECREF(v);
368 }
369 }
370#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000371 return d;
372}
373
374
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000375/* Set a POSIX-specific error from errno, and return NULL */
376
Barry Warsawd58d7641998-07-23 16:14:40 +0000377static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000378posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000379{
Barry Warsawca74da41999-02-09 19:31:45 +0000380 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000381}
Barry Warsawd58d7641998-07-23 16:14:40 +0000382static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000383posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000384{
Barry Warsawca74da41999-02-09 19:31:45 +0000385 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000386}
387
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000388#ifdef Py_WIN_WIDE_FILENAMES
389static PyObject *
390posix_error_with_unicode_filename(Py_UNICODE* name)
391{
392 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
393}
394#endif /* Py_WIN_WIDE_FILENAMES */
395
396
Mark Hammondef8b6542001-05-13 08:04:26 +0000397static PyObject *
398posix_error_with_allocated_filename(char* name)
399{
400 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
401 PyMem_Free(name);
402 return rc;
403}
404
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000405#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000406static PyObject *
407win32_error(char* function, char* filename)
408{
Mark Hammond33a6da92000-08-15 00:46:38 +0000409 /* XXX We should pass the function name along in the future.
410 (_winreg.c also wants to pass the function name.)
Tim Peters5aa91602002-01-30 05:46:57 +0000411 This would however require an additional param to the
Mark Hammond33a6da92000-08-15 00:46:38 +0000412 Windows error object, which is non-trivial.
413 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000414 errno = GetLastError();
415 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000416 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000417 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000418 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000419}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000420
421#ifdef Py_WIN_WIDE_FILENAMES
422static PyObject *
423win32_error_unicode(char* function, Py_UNICODE* filename)
424{
425 /* XXX - see win32_error for comments on 'function' */
426 errno = GetLastError();
427 if (filename)
428 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
429 else
430 return PyErr_SetFromWindowsErr(errno);
431}
432
433static PyObject *_PyUnicode_FromFileSystemEncodedObject(register PyObject *obj)
434{
435 /* XXX Perhaps we should make this API an alias of
436 PyObject_Unicode() instead ?! */
437 if (PyUnicode_CheckExact(obj)) {
438 Py_INCREF(obj);
439 return obj;
440 }
441 if (PyUnicode_Check(obj)) {
442 /* For a Unicode subtype that's not a Unicode object,
443 return a true Unicode object with the same data. */
444 return PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(obj),
445 PyUnicode_GET_SIZE(obj));
446 }
Tim Peters11b23062003-04-23 02:39:17 +0000447 return PyUnicode_FromEncodedObject(obj,
448 Py_FileSystemDefaultEncoding,
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000449 "strict");
450}
451
452#endif /* Py_WIN_WIDE_FILENAMES */
453
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000454#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000455
Guido van Rossumd48f2521997-12-05 22:19:34 +0000456#if defined(PYOS_OS2)
457/**********************************************************************
458 * Helper Function to Trim and Format OS/2 Messages
459 **********************************************************************/
460 static void
461os2_formatmsg(char *msgbuf, int msglen, char *reason)
462{
463 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
464
465 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
466 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
467
Neal Norwitz30b5c5d2005-12-19 06:05:18 +0000468 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
Guido van Rossumd48f2521997-12-05 22:19:34 +0000469 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
470 }
471
472 /* Add Optional Reason Text */
473 if (reason) {
474 strcat(msgbuf, " : ");
475 strcat(msgbuf, reason);
476 }
477}
478
479/**********************************************************************
480 * Decode an OS/2 Operating System Error Code
481 *
482 * A convenience function to lookup an OS/2 error code and return a
483 * text message we can use to raise a Python exception.
484 *
485 * Notes:
486 * The messages for errors returned from the OS/2 kernel reside in
487 * the file OSO001.MSG in the \OS2 directory hierarchy.
488 *
489 **********************************************************************/
490 static char *
491os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
492{
493 APIRET rc;
494 ULONG msglen;
495
496 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
497 Py_BEGIN_ALLOW_THREADS
498 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
499 errorcode, "oso001.msg", &msglen);
500 Py_END_ALLOW_THREADS
501
502 if (rc == NO_ERROR)
503 os2_formatmsg(msgbuf, msglen, reason);
504 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000505 PyOS_snprintf(msgbuf, msgbuflen,
Tim Peters885d4572001-11-28 20:27:42 +0000506 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000507
508 return msgbuf;
509}
510
511/* Set an OS/2-specific error and return NULL. OS/2 kernel
512 errors are not in a global variable e.g. 'errno' nor are
513 they congruent with posix error numbers. */
514
515static PyObject * os2_error(int code)
516{
517 char text[1024];
518 PyObject *v;
519
520 os2_strerror(text, sizeof(text), code, "");
521
522 v = Py_BuildValue("(is)", code, text);
523 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000524 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000525 Py_DECREF(v);
526 }
527 return NULL; /* Signal to Python that an Exception is Pending */
528}
529
530#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000531
532/* POSIX generic methods */
533
Barry Warsaw53699e91996-12-10 23:23:01 +0000534static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000535posix_fildes(PyObject *fdobj, int (*func)(int))
536{
537 int fd;
538 int res;
539 fd = PyObject_AsFileDescriptor(fdobj);
540 if (fd < 0)
541 return NULL;
542 Py_BEGIN_ALLOW_THREADS
543 res = (*func)(fd);
544 Py_END_ALLOW_THREADS
545 if (res < 0)
546 return posix_error();
547 Py_INCREF(Py_None);
548 return Py_None;
549}
Guido van Rossum21142a01999-01-08 21:05:37 +0000550
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000551#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters11b23062003-04-23 02:39:17 +0000552static int
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000553unicode_file_names(void)
554{
555 static int canusewide = -1;
556 if (canusewide == -1) {
Tim Peters11b23062003-04-23 02:39:17 +0000557 /* As per doc for ::GetVersion(), this is the correct test for
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000558 the Windows NT family. */
559 canusewide = (GetVersion() < 0x80000000) ? 1 : 0;
560 }
561 return canusewide;
562}
563#endif
Tim Peters11b23062003-04-23 02:39:17 +0000564
Guido van Rossum21142a01999-01-08 21:05:37 +0000565static PyObject *
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000566posix_1str(PyObject *args, char *format, int (*func)(const char*),
567 char *wformat, int (*wfunc)(const Py_UNICODE*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000568{
Mark Hammondef8b6542001-05-13 08:04:26 +0000569 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000570 int res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000571#ifdef Py_WIN_WIDE_FILENAMES
572 if (unicode_file_names()) {
573 PyUnicodeObject *po;
574 if (PyArg_ParseTuple(args, wformat, &po)) {
575 Py_BEGIN_ALLOW_THREADS
576 /* PyUnicode_AS_UNICODE OK without thread
577 lock as it is a simple dereference. */
578 res = (*wfunc)(PyUnicode_AS_UNICODE(po));
579 Py_END_ALLOW_THREADS
580 if (res < 0)
Mark Hammondd3890362002-10-03 07:24:48 +0000581 return posix_error_with_unicode_filename(PyUnicode_AS_UNICODE(po));
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000582 Py_INCREF(Py_None);
583 return Py_None;
584 }
585 /* Drop the argument parsing error as narrow
586 strings are also valid. */
587 PyErr_Clear();
588 }
589#else
590 /* Platforms that don't support Unicode filenames
591 shouldn't be passing these extra params */
592 assert(wformat==NULL && wfunc == NULL);
593#endif
594
Tim Peters5aa91602002-01-30 05:46:57 +0000595 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000596 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000597 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000598 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000599 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000600 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000601 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000602 return posix_error_with_allocated_filename(path1);
603 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000604 Py_INCREF(Py_None);
605 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000606}
607
Barry Warsaw53699e91996-12-10 23:23:01 +0000608static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000609posix_2str(PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000610 char *format,
611 int (*func)(const char *, const char *),
612 char *wformat,
613 int (*wfunc)(const Py_UNICODE *, const Py_UNICODE *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000614{
Mark Hammondef8b6542001-05-13 08:04:26 +0000615 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000616 int res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000617#ifdef Py_WIN_WIDE_FILENAMES
618 if (unicode_file_names()) {
619 PyObject *po1;
620 PyObject *po2;
621 if (PyArg_ParseTuple(args, wformat, &po1, &po2)) {
622 if (PyUnicode_Check(po1) || PyUnicode_Check(po2)) {
623 PyObject *wpath1;
624 PyObject *wpath2;
625 wpath1 = _PyUnicode_FromFileSystemEncodedObject(po1);
626 wpath2 = _PyUnicode_FromFileSystemEncodedObject(po2);
627 if (!wpath1 || !wpath2) {
628 Py_XDECREF(wpath1);
629 Py_XDECREF(wpath2);
630 return NULL;
631 }
632 Py_BEGIN_ALLOW_THREADS
633 /* PyUnicode_AS_UNICODE OK without thread
634 lock as it is a simple dereference. */
635 res = (*wfunc)(PyUnicode_AS_UNICODE(wpath1),
636 PyUnicode_AS_UNICODE(wpath2));
637 Py_END_ALLOW_THREADS
638 Py_XDECREF(wpath1);
639 Py_XDECREF(wpath2);
640 if (res != 0)
641 return posix_error();
642 Py_INCREF(Py_None);
643 return Py_None;
644 }
645 /* Else flow through as neither is Unicode. */
646 }
647 /* Drop the argument parsing error as narrow
648 strings are also valid. */
649 PyErr_Clear();
650 }
651#else
652 /* Platforms that don't support Unicode filenames
653 shouldn't be passing these extra params */
654 assert(wformat==NULL && wfunc == NULL);
655#endif
656
Mark Hammondef8b6542001-05-13 08:04:26 +0000657 if (!PyArg_ParseTuple(args, format,
Tim Peters5aa91602002-01-30 05:46:57 +0000658 Py_FileSystemDefaultEncoding, &path1,
Mark Hammondef8b6542001-05-13 08:04:26 +0000659 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000660 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000661 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000662 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000663 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000664 PyMem_Free(path1);
665 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000666 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000667 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000668 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000669 Py_INCREF(Py_None);
670 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000671}
672
Martin v. Löwis14694662006-02-03 12:54:16 +0000673#ifdef MS_WINDOWS
674/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
675 - time stamps are restricted to second resolution
676 - file modification times suffer from forth-and-back conversions between
677 UTC and local time
678 Therefore, we implement our own stat, based on the Win32 API directly.
679*/
680#define HAVE_STAT_NSEC 1
681
682struct win32_stat{
683 int st_dev;
684 __int64 st_ino;
685 unsigned short st_mode;
686 int st_nlink;
687 int st_uid;
688 int st_gid;
689 int st_rdev;
690 __int64 st_size;
691 int st_atime;
692 int st_atime_nsec;
693 int st_mtime;
694 int st_mtime_nsec;
695 int st_ctime;
696 int st_ctime_nsec;
697};
698
699static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
700
701static void
702FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, int *time_out, int* nsec_out)
703{
704 /* XXX endianness */
705 __int64 in = *(__int64*)in_ptr;
706 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
707 /* XXX Win32 supports time stamps past 2038; we currently don't */
708 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, int);
709}
710
711/* Below, we *know* that ugo+r is 0444 */
712#if _S_IREAD != 0400
713#error Unsupported C library
714#endif
715static int
716attributes_to_mode(DWORD attr)
717{
718 int m = 0;
719 if (attr & FILE_ATTRIBUTE_DIRECTORY)
720 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
721 else
722 m |= _S_IFREG;
723 if (attr & FILE_ATTRIBUTE_READONLY)
724 m |= 0444;
725 else
726 m |= 0666;
727 return m;
728}
729
730static int
731attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *result)
732{
733 memset(result, 0, sizeof(*result));
734 result->st_mode = attributes_to_mode(info->dwFileAttributes);
735 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
736 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
737 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
738 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
739
740 return 0;
741}
742
743static int
744win32_stat(const char* path, struct win32_stat *result)
745{
746 WIN32_FILE_ATTRIBUTE_DATA info;
747 int code;
748 char *dot;
749 /* XXX not supported on Win95 and NT 3.x */
750 if (!GetFileAttributesExA(path, GetFileExInfoStandard, &info)) {
751 /* Protocol violation: we explicitly clear errno, instead of
752 setting it to a POSIX error. Callers should use GetLastError. */
753 errno = 0;
754 return -1;
755 }
756 code = attribute_data_to_stat(&info, result);
757 if (code != 0)
758 return code;
759 /* Set S_IFEXEC if it is an .exe, .bat, ... */
760 dot = strrchr(path, '.');
761 if (dot) {
762 if (stricmp(dot, ".bat") == 0 ||
763 stricmp(dot, ".cmd") == 0 ||
764 stricmp(dot, ".exe") == 0 ||
765 stricmp(dot, ".com") == 0)
766 result->st_mode |= 0111;
767 }
768 return code;
769}
770
771static int
772win32_wstat(const wchar_t* path, struct win32_stat *result)
773{
774 int code;
775 const wchar_t *dot;
776 WIN32_FILE_ATTRIBUTE_DATA info;
777 /* XXX not supported on Win95 and NT 3.x */
778 if (!GetFileAttributesExW(path, GetFileExInfoStandard, &info)) {
779 /* Protocol violation: we explicitly clear errno, instead of
780 setting it to a POSIX error. Callers should use GetLastError. */
781 errno = 0;
782 return -1;
783 }
784 code = attribute_data_to_stat(&info, result);
785 if (code < 0)
786 return code;
787 /* Set IFEXEC if it is an .exe, .bat, ... */
788 dot = wcsrchr(path, '.');
789 if (dot) {
790 if (_wcsicmp(dot, L".bat") == 0 ||
791 _wcsicmp(dot, L".cmd") == 0 ||
792 _wcsicmp(dot, L".exe") == 0 ||
793 _wcsicmp(dot, L".com") == 0)
794 result->st_mode |= 0111;
795 }
796 return code;
797}
798
799static int
800win32_fstat(int file_number, struct win32_stat *result)
801{
802 BY_HANDLE_FILE_INFORMATION info;
803 HANDLE h;
804 int type;
805
806 h = (HANDLE)_get_osfhandle(file_number);
807
808 /* Protocol violation: we explicitly clear errno, instead of
809 setting it to a POSIX error. Callers should use GetLastError. */
810 errno = 0;
811
812 if (h == INVALID_HANDLE_VALUE) {
813 /* This is really a C library error (invalid file handle).
814 We set the Win32 error to the closes one matching. */
815 SetLastError(ERROR_INVALID_HANDLE);
816 return -1;
817 }
818 memset(result, 0, sizeof(*result));
819
820 type = GetFileType(h);
821 if (type == FILE_TYPE_UNKNOWN) {
822 DWORD error = GetLastError();
823 if (error != 0) {
824 return -1;
825 }
826 /* else: valid but unknown file */
827 }
828
829 if (type != FILE_TYPE_DISK) {
830 if (type == FILE_TYPE_CHAR)
831 result->st_mode = _S_IFCHR;
832 else if (type == FILE_TYPE_PIPE)
833 result->st_mode = _S_IFIFO;
834 return 0;
835 }
836
837 if (!GetFileInformationByHandle(h, &info)) {
838 return -1;
839 }
840
841 /* similar to stat() */
842 result->st_mode = attributes_to_mode(info.dwFileAttributes);
843 result->st_size = (((__int64)info.nFileSizeHigh)<<32) + info.nFileSizeLow;
844 FILE_TIME_to_time_t_nsec(&info.ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
845 FILE_TIME_to_time_t_nsec(&info.ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
846 FILE_TIME_to_time_t_nsec(&info.ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
847 /* specific to fstat() */
848 result->st_nlink = info.nNumberOfLinks;
849 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
850 return 0;
851}
852
853#endif /* MS_WINDOWS */
854
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000855PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000856"stat_result: Result from stat or lstat.\n\n\
857This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +0000858 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000859or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
860\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +0000861Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
862or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000863\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000864See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000865
866static PyStructSequence_Field stat_result_fields[] = {
867 {"st_mode", "protection bits"},
868 {"st_ino", "inode"},
869 {"st_dev", "device"},
870 {"st_nlink", "number of hard links"},
871 {"st_uid", "user ID of owner"},
872 {"st_gid", "group ID of owner"},
873 {"st_size", "total size, in bytes"},
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000874 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
875 {NULL, "integer time of last access"},
876 {NULL, "integer time of last modification"},
877 {NULL, "integer time of last change"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000878 {"st_atime", "time of last access"},
879 {"st_mtime", "time of last modification"},
880 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000881#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000882 {"st_blksize", "blocksize for filesystem I/O"},
883#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000884#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000885 {"st_blocks", "number of blocks allocated"},
886#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000887#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000888 {"st_rdev", "device type (if inode device)"},
889#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +0000890#ifdef HAVE_STRUCT_STAT_ST_FLAGS
891 {"st_flags", "user defined flags for file"},
892#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +0000893#ifdef HAVE_STRUCT_STAT_ST_GEN
894 {"st_gen", "generation number"},
895#endif
896#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
897 {"st_birthtime", "time of creation"},
898#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000899 {0}
900};
901
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000902#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000903#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000904#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000905#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000906#endif
907
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000908#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000909#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
910#else
911#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
912#endif
913
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000914#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000915#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
916#else
917#define ST_RDEV_IDX ST_BLOCKS_IDX
918#endif
919
Hye-Shik Chang5f937a72005-06-02 13:09:30 +0000920#ifdef HAVE_STRUCT_STAT_ST_FLAGS
921#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
922#else
923#define ST_FLAGS_IDX ST_RDEV_IDX
924#endif
925
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +0000926#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +0000927#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +0000928#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +0000929#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +0000930#endif
931
932#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
933#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
934#else
935#define ST_BIRTHTIME_IDX ST_GEN_IDX
936#endif
937
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000938static PyStructSequence_Desc stat_result_desc = {
939 "stat_result", /* name */
940 stat_result__doc__, /* doc */
941 stat_result_fields,
942 10
943};
944
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000945PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000946"statvfs_result: Result from statvfs or fstatvfs.\n\n\
947This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +0000948 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000949or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000950\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000951See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000952
953static PyStructSequence_Field statvfs_result_fields[] = {
954 {"f_bsize", },
955 {"f_frsize", },
956 {"f_blocks", },
957 {"f_bfree", },
958 {"f_bavail", },
959 {"f_files", },
960 {"f_ffree", },
961 {"f_favail", },
962 {"f_flag", },
963 {"f_namemax",},
964 {0}
965};
966
967static PyStructSequence_Desc statvfs_result_desc = {
968 "statvfs_result", /* name */
969 statvfs_result__doc__, /* doc */
970 statvfs_result_fields,
971 10
972};
973
974static PyTypeObject StatResultType;
975static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000976static newfunc structseq_new;
977
978static PyObject *
979statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
980{
981 PyStructSequence *result;
982 int i;
983
984 result = (PyStructSequence*)structseq_new(type, args, kwds);
985 if (!result)
986 return NULL;
987 /* If we have been initialized from a tuple,
988 st_?time might be set to None. Initialize it
989 from the int slots. */
990 for (i = 7; i <= 9; i++) {
991 if (result->ob_item[i+3] == Py_None) {
992 Py_DECREF(Py_None);
993 Py_INCREF(result->ob_item[i]);
994 result->ob_item[i+3] = result->ob_item[i];
995 }
996 }
997 return (PyObject*)result;
998}
999
1000
1001
1002/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001003static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001004
1005PyDoc_STRVAR(stat_float_times__doc__,
1006"stat_float_times([newval]) -> oldval\n\n\
1007Determine whether os.[lf]stat represents time stamps as float objects.\n\
1008If newval is True, future calls to stat() return floats, if it is False,\n\
1009future calls return ints. \n\
1010If newval is omitted, return the current setting.\n");
1011
1012static PyObject*
1013stat_float_times(PyObject* self, PyObject *args)
1014{
1015 int newval = -1;
1016 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1017 return NULL;
1018 if (newval == -1)
1019 /* Return old value */
1020 return PyBool_FromLong(_stat_float_times);
1021 _stat_float_times = newval;
1022 Py_INCREF(Py_None);
1023 return Py_None;
1024}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001025
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001026static void
1027fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1028{
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001029 PyObject *fval,*ival;
1030#if SIZEOF_TIME_T > SIZEOF_LONG
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00001031 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001032#else
1033 ival = PyInt_FromLong((long)sec);
1034#endif
1035 if (_stat_float_times) {
1036 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1037 } else {
1038 fval = ival;
1039 Py_INCREF(fval);
1040 }
1041 PyStructSequence_SET_ITEM(v, index, ival);
1042 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001043}
1044
Tim Peters5aa91602002-01-30 05:46:57 +00001045/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001046 (used by posix_stat() and posix_fstat()) */
1047static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001048_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001049{
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001050 unsigned long ansec, mnsec, cnsec;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001051 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +00001052 if (v == NULL)
1053 return NULL;
1054
Martin v. Löwis14694662006-02-03 12:54:16 +00001055 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001056#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001057 PyStructSequence_SET_ITEM(v, 1,
Martin v. Löwis14694662006-02-03 12:54:16 +00001058 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001059#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001060 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001061#endif
1062#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +00001063 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwis14694662006-02-03 12:54:16 +00001064 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001065#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001066 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001067#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001068 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st->st_nlink));
1069 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st->st_uid));
1070 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001071#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001072 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwis14694662006-02-03 12:54:16 +00001073 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001074#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001075 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001076#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001077
Martin v. Löwis14694662006-02-03 12:54:16 +00001078#if defined(HAVE_STAT_TV_NSEC)
1079 ansec = st->st_atim.tv_nsec;
1080 mnsec = st->st_mtim.tv_nsec;
1081 cnsec = st->st_ctim.tv_nsec;
1082#elif defined(HAVE_STAT_TV_NSEC2)
1083 ansec = st->st_atimespec.tv_nsec;
1084 mnsec = st->st_mtimespec.tv_nsec;
1085 cnsec = st->st_ctimespec.tv_nsec;
1086#elif defined(HAVE_STAT_NSEC)
1087 ansec = st->st_atime_nsec;
1088 mnsec = st->st_mtime_nsec;
1089 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001090#else
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001091 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001092#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001093 fill_time(v, 7, st->st_atime, ansec);
1094 fill_time(v, 8, st->st_mtime, mnsec);
1095 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001096
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001097#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +00001098 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001099 PyInt_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001100#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001101#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +00001102 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001103 PyInt_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001104#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001105#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001106 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001107 PyInt_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001108#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001109#ifdef HAVE_STRUCT_STAT_ST_GEN
1110 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001111 PyInt_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001112#endif
1113#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1114 {
1115 PyObject *val;
1116 unsigned long bsec,bnsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001117 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001118#ifdef HAVE_STAT_TV_NSEC2
Hye-Shik Changd69e0342006-02-19 16:22:22 +00001119 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001120#else
1121 bnsec = 0;
1122#endif
1123 if (_stat_float_times) {
1124 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1125 } else {
1126 val = PyInt_FromLong((long)bsec);
1127 }
1128 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1129 val);
1130 }
1131#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001132#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1133 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001134 PyInt_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001135#endif
Fred Drake699f3522000-06-29 21:12:41 +00001136
1137 if (PyErr_Occurred()) {
1138 Py_DECREF(v);
1139 return NULL;
1140 }
1141
1142 return v;
1143}
1144
Martin v. Löwisd8948722004-06-02 09:57:56 +00001145#ifdef MS_WINDOWS
1146
1147/* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
1148 where / can be used in place of \ and the trailing slash is optional.
1149 Both SERVER and SHARE must have at least one character.
1150*/
1151
1152#define ISSLASHA(c) ((c) == '\\' || (c) == '/')
1153#define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
1154#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
1155
Tim Peters4ad82172004-08-30 17:02:04 +00001156static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001157IsUNCRootA(char *path, int pathlen)
1158{
1159 #define ISSLASH ISSLASHA
1160
1161 int i, share;
1162
1163 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1164 /* minimum UNCRoot is \\x\y */
1165 return FALSE;
1166 for (i = 2; i < pathlen ; i++)
1167 if (ISSLASH(path[i])) break;
1168 if (i == 2 || i == pathlen)
1169 /* do not allow \\\SHARE or \\SERVER */
1170 return FALSE;
1171 share = i+1;
1172 for (i = share; i < pathlen; i++)
1173 if (ISSLASH(path[i])) break;
1174 return (i != share && (i == pathlen || i == pathlen-1));
1175
1176 #undef ISSLASH
1177}
1178
1179#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters4ad82172004-08-30 17:02:04 +00001180static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001181IsUNCRootW(Py_UNICODE *path, int pathlen)
1182{
1183 #define ISSLASH ISSLASHW
1184
1185 int i, share;
1186
1187 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1188 /* minimum UNCRoot is \\x\y */
1189 return FALSE;
1190 for (i = 2; i < pathlen ; i++)
1191 if (ISSLASH(path[i])) break;
1192 if (i == 2 || i == pathlen)
1193 /* do not allow \\\SHARE or \\SERVER */
1194 return FALSE;
1195 share = i+1;
1196 for (i = share; i < pathlen; i++)
1197 if (ISSLASH(path[i])) break;
1198 return (i != share && (i == pathlen || i == pathlen-1));
1199
1200 #undef ISSLASH
1201}
1202#endif /* Py_WIN_WIDE_FILENAMES */
1203#endif /* MS_WINDOWS */
1204
Barry Warsaw53699e91996-12-10 23:23:01 +00001205static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001206posix_do_stat(PyObject *self, PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001207 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001208#ifdef __VMS
1209 int (*statfunc)(const char *, STRUCT_STAT *, ...),
1210#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001211 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001212#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001213 char *wformat,
1214 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001215{
Fred Drake699f3522000-06-29 21:12:41 +00001216 STRUCT_STAT st;
Tim Peters500bd032001-12-19 19:05:01 +00001217 char *path = NULL; /* pass this to stat; do not free() it */
1218 char *pathfree = NULL; /* this memory must be free'd */
Guido van Rossumff4949e1992-08-05 19:58:53 +00001219 int res;
Martin v. Löwis14694662006-02-03 12:54:16 +00001220 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001221
1222#ifdef Py_WIN_WIDE_FILENAMES
1223 /* If on wide-character-capable OS see if argument
1224 is Unicode and if so use wide API. */
1225 if (unicode_file_names()) {
1226 PyUnicodeObject *po;
1227 if (PyArg_ParseTuple(args, wformat, &po)) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001228 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
1229
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001230 Py_BEGIN_ALLOW_THREADS
1231 /* PyUnicode_AS_UNICODE result OK without
1232 thread lock as it is a simple dereference. */
1233 res = wstatfunc(wpath, &st);
1234 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001235
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001236 if (res != 0)
Martin v. Löwis14694662006-02-03 12:54:16 +00001237 return win32_error_unicode("stat", wpath);
1238 return _pystat_fromstructstat(&st);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001239 }
1240 /* Drop the argument parsing error as narrow strings
1241 are also valid. */
1242 PyErr_Clear();
1243 }
1244#endif
1245
Tim Peters5aa91602002-01-30 05:46:57 +00001246 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +00001247 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001248 return NULL;
Tim Peters500bd032001-12-19 19:05:01 +00001249 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +00001250
Barry Warsaw53699e91996-12-10 23:23:01 +00001251 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001252 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00001253 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001254
1255 if (res != 0) {
1256#ifdef MS_WINDOWS
1257 result = win32_error("stat", pathfree);
1258#else
1259 result = posix_error_with_filename(pathfree);
1260#endif
1261 }
1262 else
1263 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001264
Tim Peters500bd032001-12-19 19:05:01 +00001265 PyMem_Free(pathfree);
Martin v. Löwis14694662006-02-03 12:54:16 +00001266 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001267}
1268
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001269/* POSIX methods */
1270
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001271PyDoc_STRVAR(posix_access__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001272"access(path, mode) -> 1 if granted, 0 otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001273Use the real uid/gid to test for access to a path. Note that most\n\
1274operations will use the effective uid/gid, therefore this routine can\n\
1275be used in a suid/sgid environment to test if the invoking user has the\n\
1276specified access to the path. The mode argument can be F_OK to test\n\
1277existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001278
1279static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001280posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001281{
Guido van Rossum015f22a1999-01-06 22:52:38 +00001282 char *path;
1283 int mode;
1284 int res;
1285
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001286#ifdef Py_WIN_WIDE_FILENAMES
1287 if (unicode_file_names()) {
1288 PyUnicodeObject *po;
1289 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1290 Py_BEGIN_ALLOW_THREADS
1291 /* PyUnicode_AS_UNICODE OK without thread lock as
1292 it is a simple dereference. */
1293 res = _waccess(PyUnicode_AS_UNICODE(po), mode);
1294 Py_END_ALLOW_THREADS
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001295 return PyBool_FromLong(res == 0);
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001296 }
1297 /* Drop the argument parsing error as narrow strings
1298 are also valid. */
1299 PyErr_Clear();
1300 }
1301#endif
Martin v. Löwisb60ae992005-03-08 09:10:29 +00001302 if (!PyArg_ParseTuple(args, "eti:access",
1303 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +00001304 return NULL;
1305 Py_BEGIN_ALLOW_THREADS
1306 res = access(path, mode);
1307 Py_END_ALLOW_THREADS
Neal Norwitz24b3c222005-09-19 06:43:44 +00001308 PyMem_Free(path);
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001309 return PyBool_FromLong(res == 0);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001310}
1311
Guido van Rossumd371ff11999-01-25 16:12:23 +00001312#ifndef F_OK
1313#define F_OK 0
1314#endif
1315#ifndef R_OK
1316#define R_OK 4
1317#endif
1318#ifndef W_OK
1319#define W_OK 2
1320#endif
1321#ifndef X_OK
1322#define X_OK 1
1323#endif
1324
1325#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001326PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001327"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001328Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001329
1330static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001331posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001332{
Guido van Rossum94f6f721999-01-06 18:42:14 +00001333 int id;
1334 char *ret;
1335
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001336 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +00001337 return NULL;
1338
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001339#if defined(__VMS)
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +00001340 /* file descriptor 0 only, the default input device (stdin) */
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001341 if (id == 0) {
1342 ret = ttyname();
1343 }
1344 else {
1345 ret = NULL;
1346 }
1347#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00001348 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001349#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001350 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001351 return posix_error();
1352 return PyString_FromString(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001353}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001354#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001355
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001356#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001357PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001358"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001359Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001360
1361static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001362posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001363{
1364 char *ret;
1365 char buffer[L_ctermid];
1366
Greg Wardb48bc172000-03-01 21:51:56 +00001367#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001368 ret = ctermid_r(buffer);
1369#else
1370 ret = ctermid(buffer);
1371#endif
1372 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001373 return posix_error();
1374 return PyString_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001375}
1376#endif
1377
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001378PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001379"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001380Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001381
Barry Warsaw53699e91996-12-10 23:23:01 +00001382static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001383posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001384{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001385#ifdef MS_WINDOWS
1386 return posix_1str(args, "et:chdir", chdir, "U:chdir", _wchdir);
1387#elif defined(PYOS_OS2) && defined(PYCC_GCC)
1388 return posix_1str(args, "et:chdir", _chdir2, NULL, NULL);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001389#elif defined(__VMS)
Tim Peters11b23062003-04-23 02:39:17 +00001390 return posix_1str(args, "et:chdir", (int (*)(const char *))chdir,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001391 NULL, NULL);
1392#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001393 return posix_1str(args, "et:chdir", chdir, NULL, NULL);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001394#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001395}
1396
Fred Drake4d1e64b2002-04-15 19:40:07 +00001397#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001398PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001399"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001400Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001401opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001402
1403static PyObject *
1404posix_fchdir(PyObject *self, PyObject *fdobj)
1405{
1406 return posix_fildes(fdobj, fchdir);
1407}
1408#endif /* HAVE_FCHDIR */
1409
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001410
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001411PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001412"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001413Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001414
Barry Warsaw53699e91996-12-10 23:23:01 +00001415static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001416posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001417{
Mark Hammondef8b6542001-05-13 08:04:26 +00001418 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +00001419 int i;
1420 int res;
Mark Hammond817c9292003-12-03 01:22:38 +00001421#ifdef Py_WIN_WIDE_FILENAMES
1422 if (unicode_file_names()) {
1423 PyUnicodeObject *po;
1424 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1425 Py_BEGIN_ALLOW_THREADS
1426 res = _wchmod(PyUnicode_AS_UNICODE(po), i);
1427 Py_END_ALLOW_THREADS
1428 if (res < 0)
1429 return posix_error_with_unicode_filename(
1430 PyUnicode_AS_UNICODE(po));
1431 Py_INCREF(Py_None);
1432 return Py_None;
1433 }
1434 /* Drop the argument parsing error as narrow strings
1435 are also valid. */
1436 PyErr_Clear();
1437 }
1438#endif /* Py_WIN_WIDE_FILENAMES */
1439 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
Mark Hammondef8b6542001-05-13 08:04:26 +00001440 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +00001441 return NULL;
1442 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +00001443 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001444 Py_END_ALLOW_THREADS
1445 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001446 return posix_error_with_allocated_filename(path);
1447 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001448 Py_INCREF(Py_None);
1449 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001450}
1451
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001452
Martin v. Löwis244edc82001-10-04 22:44:26 +00001453#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001454PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001455"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001456Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00001457
1458static PyObject *
1459posix_chroot(PyObject *self, PyObject *args)
1460{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001461 return posix_1str(args, "et:chroot", chroot, NULL, NULL);
Martin v. Löwis244edc82001-10-04 22:44:26 +00001462}
1463#endif
1464
Guido van Rossum21142a01999-01-08 21:05:37 +00001465#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001466PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001467"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001468force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001469
1470static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001471posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001472{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001473 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001474}
1475#endif /* HAVE_FSYNC */
1476
1477#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00001478
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00001479#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00001480extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1481#endif
1482
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001483PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001484"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00001485force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001486 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001487
1488static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001489posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001490{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001491 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001492}
1493#endif /* HAVE_FDATASYNC */
1494
1495
Fredrik Lundh10723342000-07-10 16:38:09 +00001496#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001497PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001498"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001499Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001500
Barry Warsaw53699e91996-12-10 23:23:01 +00001501static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001502posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001503{
Mark Hammondef8b6542001-05-13 08:04:26 +00001504 char *path = NULL;
Fredrik Lundh44328e62000-07-10 15:59:30 +00001505 int uid, gid;
1506 int res;
Tim Peters5aa91602002-01-30 05:46:57 +00001507 if (!PyArg_ParseTuple(args, "etii:chown",
1508 Py_FileSystemDefaultEncoding, &path,
Mark Hammondef8b6542001-05-13 08:04:26 +00001509 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +00001510 return NULL;
1511 Py_BEGIN_ALLOW_THREADS
1512 res = chown(path, (uid_t) uid, (gid_t) gid);
1513 Py_END_ALLOW_THREADS
1514 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001515 return posix_error_with_allocated_filename(path);
1516 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +00001517 Py_INCREF(Py_None);
1518 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001519}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001520#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001521
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001522#ifdef HAVE_LCHOWN
1523PyDoc_STRVAR(posix_lchown__doc__,
1524"lchown(path, uid, gid)\n\n\
1525Change the owner and group id of path to the numeric uid and gid.\n\
1526This function will not follow symbolic links.");
1527
1528static PyObject *
1529posix_lchown(PyObject *self, PyObject *args)
1530{
1531 char *path = NULL;
1532 int uid, gid;
1533 int res;
1534 if (!PyArg_ParseTuple(args, "etii:lchown",
1535 Py_FileSystemDefaultEncoding, &path,
1536 &uid, &gid))
1537 return NULL;
1538 Py_BEGIN_ALLOW_THREADS
1539 res = lchown(path, (uid_t) uid, (gid_t) gid);
1540 Py_END_ALLOW_THREADS
Tim Peters11b23062003-04-23 02:39:17 +00001541 if (res < 0)
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001542 return posix_error_with_allocated_filename(path);
1543 PyMem_Free(path);
1544 Py_INCREF(Py_None);
1545 return Py_None;
1546}
1547#endif /* HAVE_LCHOWN */
1548
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001549
Guido van Rossum36bc6801995-06-14 22:54:23 +00001550#ifdef HAVE_GETCWD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001551PyDoc_STRVAR(posix_getcwd__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001552"getcwd() -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001553Return a string representing the current working directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001554
Barry Warsaw53699e91996-12-10 23:23:01 +00001555static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001556posix_getcwd(PyObject *self, PyObject *noargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001557{
1558 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +00001559 char *res;
Neal Norwitze241ce82003-02-17 18:17:05 +00001560
Barry Warsaw53699e91996-12-10 23:23:01 +00001561 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001562#if defined(PYOS_OS2) && defined(PYCC_GCC)
1563 res = _getcwd2(buf, sizeof buf);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001564#else
Guido van Rossumff4949e1992-08-05 19:58:53 +00001565 res = getcwd(buf, sizeof buf);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001566#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001567 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001568 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001569 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001570 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001571}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001572
Walter Dörwald3b918c32002-11-21 20:18:46 +00001573#ifdef Py_USING_UNICODE
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001574PyDoc_STRVAR(posix_getcwdu__doc__,
1575"getcwdu() -> path\n\n\
1576Return a unicode string representing the current working directory.");
1577
1578static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001579posix_getcwdu(PyObject *self, PyObject *noargs)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001580{
1581 char buf[1026];
1582 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001583
1584#ifdef Py_WIN_WIDE_FILENAMES
1585 if (unicode_file_names()) {
1586 wchar_t *wres;
1587 wchar_t wbuf[1026];
1588 Py_BEGIN_ALLOW_THREADS
1589 wres = _wgetcwd(wbuf, sizeof wbuf/ sizeof wbuf[0]);
1590 Py_END_ALLOW_THREADS
1591 if (wres == NULL)
1592 return posix_error();
1593 return PyUnicode_FromWideChar(wbuf, wcslen(wbuf));
1594 }
1595#endif
1596
1597 Py_BEGIN_ALLOW_THREADS
1598#if defined(PYOS_OS2) && defined(PYCC_GCC)
1599 res = _getcwd2(buf, sizeof buf);
1600#else
1601 res = getcwd(buf, sizeof buf);
1602#endif
1603 Py_END_ALLOW_THREADS
1604 if (res == NULL)
1605 return posix_error();
1606 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
1607}
Guido van Rossum36bc6801995-06-14 22:54:23 +00001608#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00001609#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001610
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001611
Guido van Rossumb6775db1994-08-01 11:34:53 +00001612#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001613PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001614"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001615Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001616
Barry Warsaw53699e91996-12-10 23:23:01 +00001617static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001618posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001619{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001620 return posix_2str(args, "etet:link", link, NULL, NULL);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001621}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001622#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001623
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001624
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001625PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001626"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001627Return a list containing the names of the entries in the directory.\n\
1628\n\
1629 path: path of directory to list\n\
1630\n\
1631The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001632entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001633
Barry Warsaw53699e91996-12-10 23:23:01 +00001634static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001635posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001636{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001637 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001638 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001639#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001640
Barry Warsaw53699e91996-12-10 23:23:01 +00001641 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001642 HANDLE hFindFile;
Georg Brandl622927b2006-03-07 12:48:03 +00001643 BOOL result;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001644 WIN32_FIND_DATA FileData;
Mark Hammondef8b6542001-05-13 08:04:26 +00001645 /* MAX_PATH characters could mean a bigger encoded string */
1646 char namebuf[MAX_PATH*2+5];
1647 char *bufptr = namebuf;
Martin v. Löwis18e16552006-02-15 17:27:45 +00001648 Py_ssize_t len = sizeof(namebuf)/sizeof(namebuf[0]);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001649
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001650#ifdef Py_WIN_WIDE_FILENAMES
1651 /* If on wide-character-capable OS see if argument
1652 is Unicode and if so use wide API. */
1653 if (unicode_file_names()) {
1654 PyUnicodeObject *po;
1655 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
1656 WIN32_FIND_DATAW wFileData;
1657 Py_UNICODE wnamebuf[MAX_PATH*2+5];
1658 Py_UNICODE wch;
1659 wcsncpy(wnamebuf, PyUnicode_AS_UNICODE(po), MAX_PATH);
1660 wnamebuf[MAX_PATH] = L'\0';
1661 len = wcslen(wnamebuf);
1662 wch = (len > 0) ? wnamebuf[len-1] : L'\0';
1663 if (wch != L'/' && wch != L'\\' && wch != L':')
1664 wnamebuf[len++] = L'/';
1665 wcscpy(wnamebuf + len, L"*.*");
1666 if ((d = PyList_New(0)) == NULL)
1667 return NULL;
1668 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
1669 if (hFindFile == INVALID_HANDLE_VALUE) {
1670 errno = GetLastError();
1671 if (errno == ERROR_FILE_NOT_FOUND) {
1672 return d;
1673 }
1674 Py_DECREF(d);
1675 return win32_error_unicode("FindFirstFileW", wnamebuf);
1676 }
1677 do {
1678 if (wFileData.cFileName[0] == L'.' &&
1679 (wFileData.cFileName[1] == L'\0' ||
1680 wFileData.cFileName[1] == L'.' &&
1681 wFileData.cFileName[2] == L'\0'))
1682 continue;
1683 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
1684 if (v == NULL) {
1685 Py_DECREF(d);
1686 d = NULL;
1687 break;
1688 }
1689 if (PyList_Append(d, v) != 0) {
1690 Py_DECREF(v);
1691 Py_DECREF(d);
1692 d = NULL;
1693 break;
1694 }
1695 Py_DECREF(v);
Georg Brandl622927b2006-03-07 12:48:03 +00001696 Py_BEGIN_ALLOW_THREADS
1697 result = FindNextFileW(hFindFile, &wFileData);
1698 Py_END_ALLOW_THREADS
1699 } while (result == TRUE);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001700
1701 if (FindClose(hFindFile) == FALSE) {
1702 Py_DECREF(d);
1703 return win32_error_unicode("FindClose", wnamebuf);
1704 }
1705 return d;
1706 }
1707 /* Drop the argument parsing error as narrow strings
1708 are also valid. */
1709 PyErr_Clear();
1710 }
1711#endif
1712
Tim Peters5aa91602002-01-30 05:46:57 +00001713 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001714 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +00001715 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +00001716 if (len > 0) {
1717 char ch = namebuf[len-1];
1718 if (ch != SEP && ch != ALTSEP && ch != ':')
1719 namebuf[len++] = '/';
1720 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001721 strcpy(namebuf + len, "*.*");
1722
Barry Warsaw53699e91996-12-10 23:23:01 +00001723 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001724 return NULL;
1725
1726 hFindFile = FindFirstFile(namebuf, &FileData);
1727 if (hFindFile == INVALID_HANDLE_VALUE) {
1728 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +00001729 if (errno == ERROR_FILE_NOT_FOUND)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001730 return d;
1731 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00001732 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001733 }
1734 do {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001735 if (FileData.cFileName[0] == '.' &&
1736 (FileData.cFileName[1] == '\0' ||
1737 FileData.cFileName[1] == '.' &&
1738 FileData.cFileName[2] == '\0'))
1739 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001740 v = PyString_FromString(FileData.cFileName);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001741 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001742 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 if (PyList_Append(d, v) != 0) {
1747 Py_DECREF(v);
1748 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001749 d = NULL;
1750 break;
1751 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001752 Py_DECREF(v);
Georg Brandl622927b2006-03-07 12:48:03 +00001753 Py_BEGIN_ALLOW_THREADS
1754 result = FindNextFile(hFindFile, &FileData);
1755 Py_END_ALLOW_THREADS
1756 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001757
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001758 if (FindClose(hFindFile) == FALSE) {
1759 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00001760 return win32_error("FindClose", namebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001761 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001762
1763 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001764
Tim Peters0bb44a42000-09-15 07:44:49 +00001765#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001766
1767#ifndef MAX_PATH
1768#define MAX_PATH CCHMAXPATH
1769#endif
1770 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00001771 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001772 PyObject *d, *v;
1773 char namebuf[MAX_PATH+5];
1774 HDIR hdir = 1;
1775 ULONG srchcnt = 1;
1776 FILEFINDBUF3 ep;
1777 APIRET rc;
1778
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001779 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001780 return NULL;
1781 if (len >= MAX_PATH) {
1782 PyErr_SetString(PyExc_ValueError, "path too long");
1783 return NULL;
1784 }
1785 strcpy(namebuf, name);
1786 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001787 if (*pt == ALTSEP)
1788 *pt = SEP;
1789 if (namebuf[len-1] != SEP)
1790 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001791 strcpy(namebuf + len, "*.*");
1792
1793 if ((d = PyList_New(0)) == NULL)
1794 return NULL;
1795
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001796 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
1797 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001798 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001799 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
1800 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
1801 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001802
1803 if (rc != NO_ERROR) {
1804 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001805 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001806 }
1807
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001808 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001809 do {
1810 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001811 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001812 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001813
1814 strcpy(namebuf, ep.achName);
1815
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001816 /* Leave Case of Name Alone -- In Native Form */
1817 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001818
1819 v = PyString_FromString(namebuf);
1820 if (v == NULL) {
1821 Py_DECREF(d);
1822 d = NULL;
1823 break;
1824 }
1825 if (PyList_Append(d, v) != 0) {
1826 Py_DECREF(v);
1827 Py_DECREF(d);
1828 d = NULL;
1829 break;
1830 }
1831 Py_DECREF(v);
1832 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1833 }
1834
1835 return d;
1836#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001837
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001838 char *name = NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001839 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001840 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001841 struct dirent *ep;
Just van Rossum96b1c902003-03-03 17:32:15 +00001842 int arg_is_unicode = 1;
1843
1844 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
1845 arg_is_unicode = 0;
1846 PyErr_Clear();
1847 }
1848 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001849 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001850 if ((dirp = opendir(name)) == NULL) {
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001851 return posix_error_with_allocated_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001852 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001853 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001854 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001855 PyMem_Free(name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001856 return NULL;
1857 }
Georg Brandl622927b2006-03-07 12:48:03 +00001858 for (;;) {
1859 Py_BEGIN_ALLOW_THREADS
1860 ep = readdir(dirp);
1861 Py_END_ALLOW_THREADS
1862 if (ep == NULL)
1863 break;
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001864 if (ep->d_name[0] == '.' &&
1865 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001866 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001867 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001868 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001869 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001870 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001871 d = NULL;
1872 break;
1873 }
Just van Rossum46c97842003-02-25 21:42:15 +00001874#ifdef Py_USING_UNICODE
Just van Rossum96b1c902003-03-03 17:32:15 +00001875 if (arg_is_unicode) {
Just van Rossum46c97842003-02-25 21:42:15 +00001876 PyObject *w;
1877
1878 w = PyUnicode_FromEncodedObject(v,
Tim Peters11b23062003-04-23 02:39:17 +00001879 Py_FileSystemDefaultEncoding,
Just van Rossum46c97842003-02-25 21:42:15 +00001880 "strict");
Just van Rossum6a421832003-03-04 19:30:44 +00001881 if (w != NULL) {
1882 Py_DECREF(v);
1883 v = w;
1884 }
1885 else {
1886 /* fall back to the original byte string, as
1887 discussed in patch #683592 */
1888 PyErr_Clear();
Just van Rossum46c97842003-02-25 21:42:15 +00001889 }
Just van Rossum46c97842003-02-25 21:42:15 +00001890 }
1891#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001892 if (PyList_Append(d, v) != 0) {
1893 Py_DECREF(v);
1894 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001895 d = NULL;
1896 break;
1897 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001898 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001899 }
1900 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001901 PyMem_Free(name);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001902
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001903 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001904
Tim Peters0bb44a42000-09-15 07:44:49 +00001905#endif /* which OS */
1906} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001907
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001908#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00001909/* A helper function for abspath on win32 */
1910static PyObject *
1911posix__getfullpathname(PyObject *self, PyObject *args)
1912{
1913 /* assume encoded strings wont more than double no of chars */
1914 char inbuf[MAX_PATH*2];
1915 char *inbufp = inbuf;
Tim Peters67d70eb2006-03-01 04:35:45 +00001916 Py_ssize_t insize = sizeof(inbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00001917 char outbuf[MAX_PATH*2];
1918 char *temp;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001919#ifdef Py_WIN_WIDE_FILENAMES
1920 if (unicode_file_names()) {
1921 PyUnicodeObject *po;
1922 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
1923 Py_UNICODE woutbuf[MAX_PATH*2];
1924 Py_UNICODE *wtemp;
Tim Peters11b23062003-04-23 02:39:17 +00001925 if (!GetFullPathNameW(PyUnicode_AS_UNICODE(po),
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001926 sizeof(woutbuf)/sizeof(woutbuf[0]),
1927 woutbuf, &wtemp))
1928 return win32_error("GetFullPathName", "");
1929 return PyUnicode_FromUnicode(woutbuf, wcslen(woutbuf));
1930 }
1931 /* Drop the argument parsing error as narrow strings
1932 are also valid. */
1933 PyErr_Clear();
1934 }
1935#endif
Tim Peters5aa91602002-01-30 05:46:57 +00001936 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
1937 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00001938 &insize))
1939 return NULL;
1940 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
1941 outbuf, &temp))
1942 return win32_error("GetFullPathName", inbuf);
Martin v. Löwis969297f2004-06-15 18:49:58 +00001943 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
1944 return PyUnicode_Decode(outbuf, strlen(outbuf),
1945 Py_FileSystemDefaultEncoding, NULL);
1946 }
Mark Hammondef8b6542001-05-13 08:04:26 +00001947 return PyString_FromString(outbuf);
1948} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001949#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00001950
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001951PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001952"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001953Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001954
Barry Warsaw53699e91996-12-10 23:23:01 +00001955static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001956posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001957{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001958 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00001959 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001960 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001961
1962#ifdef Py_WIN_WIDE_FILENAMES
1963 if (unicode_file_names()) {
1964 PyUnicodeObject *po;
Mark Hammond05107b62003-02-19 04:08:27 +00001965 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001966 Py_BEGIN_ALLOW_THREADS
1967 /* PyUnicode_AS_UNICODE OK without thread lock as
1968 it is a simple dereference. */
1969 res = _wmkdir(PyUnicode_AS_UNICODE(po));
1970 Py_END_ALLOW_THREADS
1971 if (res < 0)
1972 return posix_error();
1973 Py_INCREF(Py_None);
1974 return Py_None;
1975 }
1976 /* Drop the argument parsing error as narrow strings
1977 are also valid. */
1978 PyErr_Clear();
1979 }
1980#endif
1981
Tim Peters5aa91602002-01-30 05:46:57 +00001982 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001983 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001984 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001985 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001986#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001987 res = mkdir(path);
1988#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001989 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001990#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001991 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001992 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001993 return posix_error_with_allocated_filename(path);
1994 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001995 Py_INCREF(Py_None);
1996 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001997}
1998
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001999
Guido van Rossumb6775db1994-08-01 11:34:53 +00002000#ifdef HAVE_NICE
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002001#if defined(HAVE_BROKEN_NICE) && defined(HAVE_SYS_RESOURCE_H)
2002#if defined(HAVE_GETPRIORITY) && !defined(PRIO_PROCESS)
2003#include <sys/resource.h>
2004#endif
2005#endif
2006
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002007PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002008"nice(inc) -> new_priority\n\n\
2009Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002010
Barry Warsaw53699e91996-12-10 23:23:01 +00002011static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002012posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002013{
2014 int increment, value;
2015
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002016 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00002017 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002018
2019 /* There are two flavours of 'nice': one that returns the new
2020 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002021 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2022 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002023
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002024 If we are of the nice family that returns the new priority, we
2025 need to clear errno before the call, and check if errno is filled
2026 before calling posix_error() on a returnvalue of -1, because the
2027 -1 may be the actual new priority! */
2028
2029 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002030 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002031#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002032 if (value == 0)
2033 value = getpriority(PRIO_PROCESS, 0);
2034#endif
2035 if (value == -1 && errno != 0)
2036 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00002037 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002038 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002039}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002040#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002041
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002042
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002043PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002044"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002045Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002046
Barry Warsaw53699e91996-12-10 23:23:01 +00002047static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002048posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002049{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002050#ifdef MS_WINDOWS
2051 return posix_2str(args, "etet:rename", rename, "OO:rename", _wrename);
2052#else
2053 return posix_2str(args, "etet:rename", rename, NULL, NULL);
2054#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002055}
2056
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002057
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002058PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002059"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002060Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002061
Barry Warsaw53699e91996-12-10 23:23:01 +00002062static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002063posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002064{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002065#ifdef MS_WINDOWS
2066 return posix_1str(args, "et:rmdir", rmdir, "U:rmdir", _wrmdir);
2067#else
2068 return posix_1str(args, "et:rmdir", rmdir, NULL, NULL);
2069#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002070}
2071
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002072
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002073PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002074"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002075Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002076
Barry Warsaw53699e91996-12-10 23:23:01 +00002077static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002078posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002079{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002080#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00002081 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002082#else
2083 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
2084#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002085}
2086
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002087
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002088#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002089PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002090"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002091Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002092
Barry Warsaw53699e91996-12-10 23:23:01 +00002093static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002094posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002095{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002096 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002097 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002098 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002099 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002100 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002101 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00002102 Py_END_ALLOW_THREADS
2103 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002104}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002105#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002106
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002107
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002108PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002109"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002110Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002111
Barry Warsaw53699e91996-12-10 23:23:01 +00002112static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002113posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002114{
2115 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002116 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002117 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00002118 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002119 if (i < 0)
2120 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002121 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002122}
2123
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002124
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002125PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002126"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002127Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002128
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002129PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002130"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002131Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002132
Barry Warsaw53699e91996-12-10 23:23:01 +00002133static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002134posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002135{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002136#ifdef MS_WINDOWS
2137 return posix_1str(args, "et:remove", unlink, "U:remove", _wunlink);
2138#else
2139 return posix_1str(args, "et:remove", unlink, NULL, NULL);
2140#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002141}
2142
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002143
Guido van Rossumb6775db1994-08-01 11:34:53 +00002144#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002145PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002146"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002147Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002148
Barry Warsaw53699e91996-12-10 23:23:01 +00002149static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002150posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002151{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002152 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002153 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00002154
Barry Warsaw53699e91996-12-10 23:23:01 +00002155 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002156 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00002157 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002158 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002159 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002160 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00002161 u.sysname,
2162 u.nodename,
2163 u.release,
2164 u.version,
2165 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002166}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002167#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002168
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002169static int
2170extract_time(PyObject *t, long* sec, long* usec)
2171{
2172 long intval;
2173 if (PyFloat_Check(t)) {
2174 double tval = PyFloat_AsDouble(t);
2175 PyObject *intobj = t->ob_type->tp_as_number->nb_int(t);
2176 if (!intobj)
2177 return -1;
2178 intval = PyInt_AsLong(intobj);
2179 Py_DECREF(intobj);
Michael W. Hudsonb8963812005-07-05 15:21:58 +00002180 if (intval == -1 && PyErr_Occurred())
2181 return -1;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002182 *sec = intval;
Tim Peters96940cf2002-09-10 15:37:28 +00002183 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002184 if (*usec < 0)
2185 /* If rounding gave us a negative number,
2186 truncate. */
2187 *usec = 0;
2188 return 0;
2189 }
2190 intval = PyInt_AsLong(t);
2191 if (intval == -1 && PyErr_Occurred())
2192 return -1;
2193 *sec = intval;
2194 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00002195 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002196}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002197
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002198PyDoc_STRVAR(posix_utime__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002199"utime(path, (atime, utime))\n\
2200utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00002201Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002202second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002203
Barry Warsaw53699e91996-12-10 23:23:01 +00002204static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002205posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002206{
Neal Norwitz2adf2102004-06-09 01:46:02 +00002207 char *path = NULL;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002208 long atime, mtime, ausec, musec;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002209 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002210 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002211
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002212#if defined(HAVE_UTIMES)
2213 struct timeval buf[2];
2214#define ATIME buf[0].tv_sec
2215#define MTIME buf[1].tv_sec
2216#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002217/* XXX should define struct utimbuf instead, above */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002218 struct utimbuf buf;
2219#define ATIME buf.actime
2220#define MTIME buf.modtime
2221#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002222#else /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002223 time_t buf[2];
2224#define ATIME buf[0]
2225#define MTIME buf[1]
2226#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002227#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002228
Mark Hammond817c9292003-12-03 01:22:38 +00002229 int have_unicode_filename = 0;
2230#ifdef Py_WIN_WIDE_FILENAMES
2231 PyUnicodeObject *obwpath;
2232 wchar_t *wpath;
2233 if (unicode_file_names()) {
2234 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
2235 wpath = PyUnicode_AS_UNICODE(obwpath);
2236 have_unicode_filename = 1;
2237 } else
2238 /* Drop the argument parsing error as narrow strings
2239 are also valid. */
2240 PyErr_Clear();
2241 }
2242#endif /* Py_WIN_WIDE_FILENAMES */
2243
2244 if (!have_unicode_filename && \
Hye-Shik Chang2b2c9732004-01-04 13:54:25 +00002245 !PyArg_ParseTuple(args, "etO:utime",
2246 Py_FileSystemDefaultEncoding, &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002247 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002248 if (arg == Py_None) {
2249 /* optional time values not given */
2250 Py_BEGIN_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002251#ifdef Py_WIN_WIDE_FILENAMES
2252 if (have_unicode_filename)
2253 res = _wutime(wpath, NULL);
2254 else
2255#endif /* Py_WIN_WIDE_FILENAMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002256 res = utime(path, NULL);
2257 Py_END_ALLOW_THREADS
2258 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002259 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00002260 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002261 "utime() arg 2 must be a tuple (atime, mtime)");
Neal Norwitz96652712004-06-06 20:40:27 +00002262 PyMem_Free(path);
Barry Warsaw3cef8562000-05-01 16:17:24 +00002263 return NULL;
2264 }
2265 else {
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002266 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Neal Norwitz96652712004-06-06 20:40:27 +00002267 &atime, &ausec) == -1) {
2268 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002269 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002270 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002271 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Neal Norwitz96652712004-06-06 20:40:27 +00002272 &mtime, &musec) == -1) {
2273 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002274 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002275 }
Barry Warsaw3cef8562000-05-01 16:17:24 +00002276 ATIME = atime;
2277 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002278#ifdef HAVE_UTIMES
2279 buf[0].tv_usec = ausec;
2280 buf[1].tv_usec = musec;
2281 Py_BEGIN_ALLOW_THREADS
2282 res = utimes(path, buf);
2283 Py_END_ALLOW_THREADS
2284#else
Barry Warsaw3cef8562000-05-01 16:17:24 +00002285 Py_BEGIN_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002286#ifdef Py_WIN_WIDE_FILENAMES
2287 if (have_unicode_filename)
Tim Peters4ad82172004-08-30 17:02:04 +00002288 /* utime is OK with utimbuf, but _wutime insists
2289 on _utimbuf (the msvc headers assert the
Mark Hammond817c9292003-12-03 01:22:38 +00002290 underscore version is ansi) */
2291 res = _wutime(wpath, (struct _utimbuf *)UTIME_ARG);
2292 else
2293#endif /* Py_WIN_WIDE_FILENAMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002294 res = utime(path, UTIME_ARG);
2295 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002296#endif /* HAVE_UTIMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002297 }
Mark Hammond2d5914b2004-05-04 08:10:37 +00002298 if (res < 0) {
2299#ifdef Py_WIN_WIDE_FILENAMES
Neal Norwitz2adf2102004-06-09 01:46:02 +00002300 if (have_unicode_filename)
Mark Hammond2d5914b2004-05-04 08:10:37 +00002301 return posix_error_with_unicode_filename(wpath);
2302#endif /* Py_WIN_WIDE_FILENAMES */
Neal Norwitz96652712004-06-06 20:40:27 +00002303 return posix_error_with_allocated_filename(path);
Mark Hammond2d5914b2004-05-04 08:10:37 +00002304 }
Neal Norwitz96652712004-06-06 20:40:27 +00002305 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002306 Py_INCREF(Py_None);
2307 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002308#undef UTIME_ARG
2309#undef ATIME
2310#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002311}
2312
Guido van Rossum85e3b011991-06-03 12:42:10 +00002313
Guido van Rossum3b066191991-06-04 19:40:25 +00002314/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002315
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002316PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002317"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002318Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002319
Barry Warsaw53699e91996-12-10 23:23:01 +00002320static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002321posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002322{
2323 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002324 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002325 return NULL;
2326 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00002327 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002328}
2329
Martin v. Löwis114619e2002-10-07 06:44:21 +00002330#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
2331static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00002332free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00002333{
Martin v. Löwis725507b2006-03-07 12:08:51 +00002334 Py_ssize_t i;
Martin v. Löwis114619e2002-10-07 06:44:21 +00002335 for (i = 0; i < count; i++)
2336 PyMem_Free(array[i]);
2337 PyMem_DEL(array);
2338}
2339#endif
2340
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002341
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002342#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002343PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002344"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002345Execute an executable path with arguments, replacing current process.\n\
2346\n\
2347 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002348 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002349
Barry Warsaw53699e91996-12-10 23:23:01 +00002350static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002351posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002352{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002353 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002354 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002355 char **argvlist;
Martin v. Löwis725507b2006-03-07 12:08:51 +00002356 Py_ssize_t i, argc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002357 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002358
Guido van Rossum89b33251993-10-22 14:26:06 +00002359 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00002360 argv is a list or tuple of strings. */
2361
Martin v. Löwis114619e2002-10-07 06:44:21 +00002362 if (!PyArg_ParseTuple(args, "etO:execv",
2363 Py_FileSystemDefaultEncoding,
2364 &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002365 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002366 if (PyList_Check(argv)) {
2367 argc = PyList_Size(argv);
2368 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002369 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002370 else if (PyTuple_Check(argv)) {
2371 argc = PyTuple_Size(argv);
2372 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002373 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002374 else {
Fred Drake661ea262000-10-24 19:57:45 +00002375 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002376 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002377 return NULL;
2378 }
2379
Barry Warsaw53699e91996-12-10 23:23:01 +00002380 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002381 if (argvlist == NULL) {
2382 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002383 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002384 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002385 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002386 if (!PyArg_Parse((*getitem)(argv, i), "et",
2387 Py_FileSystemDefaultEncoding,
2388 &argvlist[i])) {
2389 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00002390 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002391 "execv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002392 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002393 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00002394
Guido van Rossum85e3b011991-06-03 12:42:10 +00002395 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002396 }
2397 argvlist[argc] = NULL;
2398
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002399 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002400
Guido van Rossum85e3b011991-06-03 12:42:10 +00002401 /* If we get here it's definitely an error */
2402
Martin v. Löwis114619e2002-10-07 06:44:21 +00002403 free_string_array(argvlist, argc);
2404 PyMem_Free(path);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002405 return posix_error();
2406}
2407
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002408
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002409PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002410"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002411Execute a path with arguments and environment, replacing current process.\n\
2412\n\
2413 path: path of executable file\n\
2414 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002415 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002416
Barry Warsaw53699e91996-12-10 23:23:01 +00002417static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002418posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002419{
2420 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002421 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002422 char **argvlist;
2423 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002424 PyObject *key, *val, *keys=NULL, *vals=NULL;
Martin v. Löwis725507b2006-03-07 12:08:51 +00002425 Py_ssize_t i, pos, argc, envc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002426 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002427 int lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002428
2429 /* execve has three arguments: (path, argv, env), where
2430 argv is a list or tuple of strings and env is a dictionary
2431 like posix.environ. */
2432
Martin v. Löwis114619e2002-10-07 06:44:21 +00002433 if (!PyArg_ParseTuple(args, "etOO:execve",
2434 Py_FileSystemDefaultEncoding,
2435 &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002436 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002437 if (PyList_Check(argv)) {
2438 argc = PyList_Size(argv);
2439 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002440 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002441 else if (PyTuple_Check(argv)) {
2442 argc = PyTuple_Size(argv);
2443 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002444 }
2445 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002446 PyErr_SetString(PyExc_TypeError,
2447 "execve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002448 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002449 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002450 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002451 PyErr_SetString(PyExc_TypeError,
2452 "execve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002453 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002454 }
2455
Barry Warsaw53699e91996-12-10 23:23:01 +00002456 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002457 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002458 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002459 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002460 }
2461 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002462 if (!PyArg_Parse((*getitem)(argv, i),
Martin v. Löwis114619e2002-10-07 06:44:21 +00002463 "et;execve() arg 2 must contain only strings",
Guido van Rossum1e700d22002-10-16 16:52:11 +00002464 Py_FileSystemDefaultEncoding,
Barry Warsaw43d68b81996-12-19 22:10:44 +00002465 &argvlist[i]))
2466 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002467 lastarg = i;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002468 goto fail_1;
2469 }
2470 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002471 lastarg = argc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002472 argvlist[argc] = NULL;
2473
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002474 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002475 if (i < 0)
2476 goto fail_1;
Barry Warsaw53699e91996-12-10 23:23:01 +00002477 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002478 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002479 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002480 goto fail_1;
2481 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002482 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002483 keys = PyMapping_Keys(env);
2484 vals = PyMapping_Values(env);
2485 if (!keys || !vals)
2486 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002487 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2488 PyErr_SetString(PyExc_TypeError,
2489 "execve(): env.keys() or env.values() is not a list");
2490 goto fail_2;
2491 }
Tim Peters5aa91602002-01-30 05:46:57 +00002492
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002493 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002494 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002495 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002496
2497 key = PyList_GetItem(keys, pos);
2498 val = PyList_GetItem(vals, pos);
2499 if (!key || !val)
2500 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002501
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002502 if (!PyArg_Parse(
2503 key,
2504 "s;execve() arg 3 contains a non-string key",
2505 &k) ||
2506 !PyArg_Parse(
2507 val,
2508 "s;execve() arg 3 contains a non-string value",
2509 &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00002510 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002511 goto fail_2;
2512 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00002513
2514#if defined(PYOS_OS2)
2515 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
2516 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
2517#endif
Tim Petersc8996f52001-12-03 20:41:00 +00002518 len = PyString_Size(key) + PyString_Size(val) + 2;
2519 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002520 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002521 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002522 goto fail_2;
2523 }
Tim Petersc8996f52001-12-03 20:41:00 +00002524 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002525 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00002526#if defined(PYOS_OS2)
2527 }
2528#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002529 }
2530 envlist[envc] = 0;
2531
2532 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00002533
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002534 /* If we get here it's definitely an error */
2535
2536 (void) posix_error();
2537
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002538 fail_2:
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002539 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00002540 PyMem_DEL(envlist[envc]);
2541 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002542 fail_1:
2543 free_string_array(argvlist, lastarg);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002544 Py_XDECREF(vals);
2545 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002546 fail_0:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002547 PyMem_Free(path);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002548 return NULL;
2549}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002550#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002551
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002552
Guido van Rossuma1065681999-01-25 23:20:23 +00002553#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002554PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002555"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002556Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002557\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002558 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002559 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002560 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002561
2562static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002563posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002564{
2565 char *path;
2566 PyObject *argv;
2567 char **argvlist;
2568 int mode, i, argc;
Tim Peters79248aa2001-08-29 21:37:10 +00002569 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002570 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00002571
2572 /* spawnv has three arguments: (mode, path, argv), where
2573 argv is a list or tuple of strings. */
2574
Martin v. Löwis114619e2002-10-07 06:44:21 +00002575 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
2576 Py_FileSystemDefaultEncoding,
2577 &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00002578 return NULL;
2579 if (PyList_Check(argv)) {
2580 argc = PyList_Size(argv);
2581 getitem = PyList_GetItem;
2582 }
2583 else if (PyTuple_Check(argv)) {
2584 argc = PyTuple_Size(argv);
2585 getitem = PyTuple_GetItem;
2586 }
2587 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002588 PyErr_SetString(PyExc_TypeError,
2589 "spawnv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002590 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002591 return NULL;
2592 }
2593
2594 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002595 if (argvlist == NULL) {
2596 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002597 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002598 }
Guido van Rossuma1065681999-01-25 23:20:23 +00002599 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002600 if (!PyArg_Parse((*getitem)(argv, i), "et",
2601 Py_FileSystemDefaultEncoding,
2602 &argvlist[i])) {
2603 free_string_array(argvlist, i);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002604 PyErr_SetString(
2605 PyExc_TypeError,
2606 "spawnv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002607 PyMem_Free(path);
Fred Drake137507e2000-06-01 02:02:46 +00002608 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00002609 }
2610 }
2611 argvlist[argc] = NULL;
2612
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002613#if defined(PYOS_OS2) && defined(PYCC_GCC)
2614 Py_BEGIN_ALLOW_THREADS
2615 spawnval = spawnv(mode, path, argvlist);
2616 Py_END_ALLOW_THREADS
2617#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002618 if (mode == _OLD_P_OVERLAY)
2619 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00002620
Tim Peters25059d32001-12-07 20:35:43 +00002621 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002622 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00002623 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002624#endif
Tim Peters5aa91602002-01-30 05:46:57 +00002625
Martin v. Löwis114619e2002-10-07 06:44:21 +00002626 free_string_array(argvlist, argc);
2627 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002628
Fred Drake699f3522000-06-29 21:12:41 +00002629 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002630 return posix_error();
2631 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002632#if SIZEOF_LONG == SIZEOF_VOID_P
2633 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002634#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00002635 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002636#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002637}
2638
2639
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002640PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002641"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002642Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002643\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002644 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002645 path: path of executable file\n\
2646 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002647 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002648
2649static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002650posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002651{
2652 char *path;
2653 PyObject *argv, *env;
2654 char **argvlist;
2655 char **envlist;
2656 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
2657 int mode, i, pos, argc, envc;
Tim Peters79248aa2001-08-29 21:37:10 +00002658 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002659 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002660 int lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002661
2662 /* spawnve has four arguments: (mode, path, argv, env), where
2663 argv is a list or tuple of strings and env is a dictionary
2664 like posix.environ. */
2665
Martin v. Löwis114619e2002-10-07 06:44:21 +00002666 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
2667 Py_FileSystemDefaultEncoding,
2668 &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00002669 return NULL;
2670 if (PyList_Check(argv)) {
2671 argc = PyList_Size(argv);
2672 getitem = PyList_GetItem;
2673 }
2674 else if (PyTuple_Check(argv)) {
2675 argc = PyTuple_Size(argv);
2676 getitem = PyTuple_GetItem;
2677 }
2678 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002679 PyErr_SetString(PyExc_TypeError,
2680 "spawnve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002681 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002682 }
2683 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002684 PyErr_SetString(PyExc_TypeError,
2685 "spawnve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002686 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002687 }
2688
2689 argvlist = PyMem_NEW(char *, argc+1);
2690 if (argvlist == NULL) {
2691 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002692 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002693 }
2694 for (i = 0; i < argc; i++) {
2695 if (!PyArg_Parse((*getitem)(argv, i),
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002696 "et;spawnve() arg 2 must contain only strings",
Martin v. Löwis114619e2002-10-07 06:44:21 +00002697 Py_FileSystemDefaultEncoding,
Guido van Rossuma1065681999-01-25 23:20:23 +00002698 &argvlist[i]))
2699 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002700 lastarg = i;
Guido van Rossuma1065681999-01-25 23:20:23 +00002701 goto fail_1;
2702 }
2703 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002704 lastarg = argc;
Guido van Rossuma1065681999-01-25 23:20:23 +00002705 argvlist[argc] = NULL;
2706
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002707 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002708 if (i < 0)
2709 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00002710 envlist = PyMem_NEW(char *, i + 1);
2711 if (envlist == NULL) {
2712 PyErr_NoMemory();
2713 goto fail_1;
2714 }
2715 envc = 0;
2716 keys = PyMapping_Keys(env);
2717 vals = PyMapping_Values(env);
2718 if (!keys || !vals)
2719 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002720 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2721 PyErr_SetString(PyExc_TypeError,
2722 "spawnve(): env.keys() or env.values() is not a list");
2723 goto fail_2;
2724 }
Tim Peters5aa91602002-01-30 05:46:57 +00002725
Guido van Rossuma1065681999-01-25 23:20:23 +00002726 for (pos = 0; pos < i; pos++) {
2727 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002728 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00002729
2730 key = PyList_GetItem(keys, pos);
2731 val = PyList_GetItem(vals, pos);
2732 if (!key || !val)
2733 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002734
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002735 if (!PyArg_Parse(
2736 key,
2737 "s;spawnve() arg 3 contains a non-string key",
2738 &k) ||
2739 !PyArg_Parse(
2740 val,
2741 "s;spawnve() arg 3 contains a non-string value",
2742 &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00002743 {
2744 goto fail_2;
2745 }
Tim Petersc8996f52001-12-03 20:41:00 +00002746 len = PyString_Size(key) + PyString_Size(val) + 2;
2747 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00002748 if (p == NULL) {
2749 PyErr_NoMemory();
2750 goto fail_2;
2751 }
Tim Petersc8996f52001-12-03 20:41:00 +00002752 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00002753 envlist[envc++] = p;
2754 }
2755 envlist[envc] = 0;
2756
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002757#if defined(PYOS_OS2) && defined(PYCC_GCC)
2758 Py_BEGIN_ALLOW_THREADS
2759 spawnval = spawnve(mode, path, argvlist, envlist);
2760 Py_END_ALLOW_THREADS
2761#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002762 if (mode == _OLD_P_OVERLAY)
2763 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00002764
2765 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002766 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00002767 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002768#endif
Tim Peters25059d32001-12-07 20:35:43 +00002769
Fred Drake699f3522000-06-29 21:12:41 +00002770 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002771 (void) posix_error();
2772 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002773#if SIZEOF_LONG == SIZEOF_VOID_P
2774 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002775#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00002776 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002777#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002778
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002779 fail_2:
Guido van Rossuma1065681999-01-25 23:20:23 +00002780 while (--envc >= 0)
2781 PyMem_DEL(envlist[envc]);
2782 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002783 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002784 free_string_array(argvlist, lastarg);
Guido van Rossuma1065681999-01-25 23:20:23 +00002785 Py_XDECREF(vals);
2786 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002787 fail_0:
2788 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002789 return res;
2790}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00002791
2792/* OS/2 supports spawnvp & spawnvpe natively */
2793#if defined(PYOS_OS2)
2794PyDoc_STRVAR(posix_spawnvp__doc__,
2795"spawnvp(mode, file, args)\n\n\
2796Execute the program 'file' in a new process, using the environment\n\
2797search path to find the file.\n\
2798\n\
2799 mode: mode of process creation\n\
2800 file: executable file name\n\
2801 args: tuple or list of strings");
2802
2803static PyObject *
2804posix_spawnvp(PyObject *self, PyObject *args)
2805{
2806 char *path;
2807 PyObject *argv;
2808 char **argvlist;
2809 int mode, i, argc;
2810 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002811 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00002812
2813 /* spawnvp has three arguments: (mode, path, argv), where
2814 argv is a list or tuple of strings. */
2815
2816 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
2817 Py_FileSystemDefaultEncoding,
2818 &path, &argv))
2819 return NULL;
2820 if (PyList_Check(argv)) {
2821 argc = PyList_Size(argv);
2822 getitem = PyList_GetItem;
2823 }
2824 else if (PyTuple_Check(argv)) {
2825 argc = PyTuple_Size(argv);
2826 getitem = PyTuple_GetItem;
2827 }
2828 else {
2829 PyErr_SetString(PyExc_TypeError,
2830 "spawnvp() arg 2 must be a tuple or list");
2831 PyMem_Free(path);
2832 return NULL;
2833 }
2834
2835 argvlist = PyMem_NEW(char *, argc+1);
2836 if (argvlist == NULL) {
2837 PyMem_Free(path);
2838 return PyErr_NoMemory();
2839 }
2840 for (i = 0; i < argc; i++) {
2841 if (!PyArg_Parse((*getitem)(argv, i), "et",
2842 Py_FileSystemDefaultEncoding,
2843 &argvlist[i])) {
2844 free_string_array(argvlist, i);
2845 PyErr_SetString(
2846 PyExc_TypeError,
2847 "spawnvp() arg 2 must contain only strings");
2848 PyMem_Free(path);
2849 return NULL;
2850 }
2851 }
2852 argvlist[argc] = NULL;
2853
2854 Py_BEGIN_ALLOW_THREADS
2855#if defined(PYCC_GCC)
2856 spawnval = spawnvp(mode, path, argvlist);
2857#else
2858 spawnval = _spawnvp(mode, path, argvlist);
2859#endif
2860 Py_END_ALLOW_THREADS
2861
2862 free_string_array(argvlist, argc);
2863 PyMem_Free(path);
2864
2865 if (spawnval == -1)
2866 return posix_error();
2867 else
2868 return Py_BuildValue("l", (long) spawnval);
2869}
2870
2871
2872PyDoc_STRVAR(posix_spawnvpe__doc__,
2873"spawnvpe(mode, file, args, env)\n\n\
2874Execute the program 'file' in a new process, using the environment\n\
2875search path to find the file.\n\
2876\n\
2877 mode: mode of process creation\n\
2878 file: executable file name\n\
2879 args: tuple or list of arguments\n\
2880 env: dictionary of strings mapping to strings");
2881
2882static PyObject *
2883posix_spawnvpe(PyObject *self, PyObject *args)
2884{
2885 char *path;
2886 PyObject *argv, *env;
2887 char **argvlist;
2888 char **envlist;
2889 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
2890 int mode, i, pos, argc, envc;
2891 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002892 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00002893 int lastarg = 0;
2894
2895 /* spawnvpe has four arguments: (mode, path, argv, env), where
2896 argv is a list or tuple of strings and env is a dictionary
2897 like posix.environ. */
2898
2899 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
2900 Py_FileSystemDefaultEncoding,
2901 &path, &argv, &env))
2902 return NULL;
2903 if (PyList_Check(argv)) {
2904 argc = PyList_Size(argv);
2905 getitem = PyList_GetItem;
2906 }
2907 else if (PyTuple_Check(argv)) {
2908 argc = PyTuple_Size(argv);
2909 getitem = PyTuple_GetItem;
2910 }
2911 else {
2912 PyErr_SetString(PyExc_TypeError,
2913 "spawnvpe() arg 2 must be a tuple or list");
2914 goto fail_0;
2915 }
2916 if (!PyMapping_Check(env)) {
2917 PyErr_SetString(PyExc_TypeError,
2918 "spawnvpe() arg 3 must be a mapping object");
2919 goto fail_0;
2920 }
2921
2922 argvlist = PyMem_NEW(char *, argc+1);
2923 if (argvlist == NULL) {
2924 PyErr_NoMemory();
2925 goto fail_0;
2926 }
2927 for (i = 0; i < argc; i++) {
2928 if (!PyArg_Parse((*getitem)(argv, i),
2929 "et;spawnvpe() arg 2 must contain only strings",
2930 Py_FileSystemDefaultEncoding,
2931 &argvlist[i]))
2932 {
2933 lastarg = i;
2934 goto fail_1;
2935 }
2936 }
2937 lastarg = argc;
2938 argvlist[argc] = NULL;
2939
2940 i = PyMapping_Size(env);
2941 if (i < 0)
2942 goto fail_1;
2943 envlist = PyMem_NEW(char *, i + 1);
2944 if (envlist == NULL) {
2945 PyErr_NoMemory();
2946 goto fail_1;
2947 }
2948 envc = 0;
2949 keys = PyMapping_Keys(env);
2950 vals = PyMapping_Values(env);
2951 if (!keys || !vals)
2952 goto fail_2;
2953 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2954 PyErr_SetString(PyExc_TypeError,
2955 "spawnvpe(): env.keys() or env.values() is not a list");
2956 goto fail_2;
2957 }
2958
2959 for (pos = 0; pos < i; pos++) {
2960 char *p, *k, *v;
2961 size_t len;
2962
2963 key = PyList_GetItem(keys, pos);
2964 val = PyList_GetItem(vals, pos);
2965 if (!key || !val)
2966 goto fail_2;
2967
2968 if (!PyArg_Parse(
2969 key,
2970 "s;spawnvpe() arg 3 contains a non-string key",
2971 &k) ||
2972 !PyArg_Parse(
2973 val,
2974 "s;spawnvpe() arg 3 contains a non-string value",
2975 &v))
2976 {
2977 goto fail_2;
2978 }
2979 len = PyString_Size(key) + PyString_Size(val) + 2;
2980 p = PyMem_NEW(char, len);
2981 if (p == NULL) {
2982 PyErr_NoMemory();
2983 goto fail_2;
2984 }
2985 PyOS_snprintf(p, len, "%s=%s", k, v);
2986 envlist[envc++] = p;
2987 }
2988 envlist[envc] = 0;
2989
2990 Py_BEGIN_ALLOW_THREADS
2991#if defined(PYCC_GCC)
2992 spawnval = spawnve(mode, path, argvlist, envlist);
2993#else
2994 spawnval = _spawnve(mode, path, argvlist, envlist);
2995#endif
2996 Py_END_ALLOW_THREADS
2997
2998 if (spawnval == -1)
2999 (void) posix_error();
3000 else
3001 res = Py_BuildValue("l", (long) spawnval);
3002
3003 fail_2:
3004 while (--envc >= 0)
3005 PyMem_DEL(envlist[envc]);
3006 PyMem_DEL(envlist);
3007 fail_1:
3008 free_string_array(argvlist, lastarg);
3009 Py_XDECREF(vals);
3010 Py_XDECREF(keys);
3011 fail_0:
3012 PyMem_Free(path);
3013 return res;
3014}
3015#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003016#endif /* HAVE_SPAWNV */
3017
3018
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003019#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003020PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003021"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003022Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3023\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003024Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003025
3026static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003027posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003028{
Neal Norwitze241ce82003-02-17 18:17:05 +00003029 int pid = fork1();
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003030 if (pid == -1)
3031 return posix_error();
3032 PyOS_AfterFork();
3033 return PyInt_FromLong((long)pid);
3034}
3035#endif
3036
3037
Guido van Rossumad0ee831995-03-01 10:34:45 +00003038#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003039PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003040"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003041Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003042Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003043
Barry Warsaw53699e91996-12-10 23:23:01 +00003044static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003045posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003046{
Neal Norwitze241ce82003-02-17 18:17:05 +00003047 int pid = fork();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003048 if (pid == -1)
3049 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003050 if (pid == 0)
3051 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00003052 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003053}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003054#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003055
Neal Norwitzb59798b2003-03-21 01:43:31 +00003056/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00003057/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3058#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00003059#define DEV_PTY_FILE "/dev/ptc"
3060#define HAVE_DEV_PTMX
3061#else
3062#define DEV_PTY_FILE "/dev/ptmx"
3063#endif
3064
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003065#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003066#ifdef HAVE_PTY_H
3067#include <pty.h>
3068#else
3069#ifdef HAVE_LIBUTIL_H
3070#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00003071#endif /* HAVE_LIBUTIL_H */
3072#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00003073#ifdef HAVE_STROPTS_H
3074#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003075#endif
3076#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003077
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003078#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003079PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003080"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003081Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003082
3083static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003084posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003085{
3086 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003087#ifndef HAVE_OPENPTY
3088 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003089#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003090#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003091 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003092#ifdef sun
3093 extern char *ptsname();
3094#endif
3095#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00003096
Thomas Wouters70c21a12000-07-14 14:28:33 +00003097#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00003098 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
3099 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003100#elif defined(HAVE__GETPTY)
Thomas Wouters70c21a12000-07-14 14:28:33 +00003101 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
3102 if (slave_name == NULL)
3103 return posix_error();
3104
3105 slave_fd = open(slave_name, O_RDWR);
3106 if (slave_fd < 0)
3107 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003108#else
Neal Norwitzb59798b2003-03-21 01:43:31 +00003109 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003110 if (master_fd < 0)
3111 return posix_error();
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003112 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003113 /* change permission of slave */
3114 if (grantpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003115 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003116 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003117 }
3118 /* unlock slave */
3119 if (unlockpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003120 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003121 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003122 }
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003123 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003124 slave_name = ptsname(master_fd); /* get name of slave */
3125 if (slave_name == NULL)
3126 return posix_error();
3127 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
3128 if (slave_fd < 0)
3129 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003130#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003131 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
3132 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00003133#ifndef __hpux
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003134 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00003135#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003136#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00003137#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00003138
Fred Drake8cef4cf2000-06-28 16:40:38 +00003139 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00003140
Fred Drake8cef4cf2000-06-28 16:40:38 +00003141}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003142#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003143
3144#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003145PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003146"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00003147Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
3148Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003149To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003150
3151static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003152posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003153{
Neal Norwitz24b3c222005-09-19 06:43:44 +00003154 int master_fd = -1, pid;
Tim Peters5aa91602002-01-30 05:46:57 +00003155
Fred Drake8cef4cf2000-06-28 16:40:38 +00003156 pid = forkpty(&master_fd, NULL, NULL, NULL);
3157 if (pid == -1)
3158 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003159 if (pid == 0)
3160 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00003161 return Py_BuildValue("(ii)", pid, master_fd);
3162}
3163#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003164
Guido van Rossumad0ee831995-03-01 10:34:45 +00003165#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003166PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003167"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003168Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003169
Barry Warsaw53699e91996-12-10 23:23:01 +00003170static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003171posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003172{
Barry Warsaw53699e91996-12-10 23:23:01 +00003173 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003174}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003175#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003176
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003177
Guido van Rossumad0ee831995-03-01 10:34:45 +00003178#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003179PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003180"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003181Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003182
Barry Warsaw53699e91996-12-10 23:23:01 +00003183static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003184posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003185{
Barry Warsaw53699e91996-12-10 23:23:01 +00003186 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003187}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003188#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003189
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003190
Guido van Rossumad0ee831995-03-01 10:34:45 +00003191#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003192PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003193"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003194Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003195
Barry Warsaw53699e91996-12-10 23:23:01 +00003196static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003197posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003198{
Barry Warsaw53699e91996-12-10 23:23:01 +00003199 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003200}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003201#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003202
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003203
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003204PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003205"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003206Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003207
Barry Warsaw53699e91996-12-10 23:23:01 +00003208static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003209posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003210{
Barry Warsaw53699e91996-12-10 23:23:01 +00003211 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003212}
3213
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003214
Fred Drakec9680921999-12-13 16:37:25 +00003215#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003216PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003217"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003218Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00003219
3220static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003221posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00003222{
3223 PyObject *result = NULL;
3224
Fred Drakec9680921999-12-13 16:37:25 +00003225#ifdef NGROUPS_MAX
3226#define MAX_GROUPS NGROUPS_MAX
3227#else
3228 /* defined to be 16 on Solaris7, so this should be a small number */
3229#define MAX_GROUPS 64
3230#endif
3231 gid_t grouplist[MAX_GROUPS];
3232 int n;
3233
3234 n = getgroups(MAX_GROUPS, grouplist);
3235 if (n < 0)
3236 posix_error();
3237 else {
3238 result = PyList_New(n);
3239 if (result != NULL) {
Fred Drakec9680921999-12-13 16:37:25 +00003240 int i;
3241 for (i = 0; i < n; ++i) {
Neal Norwitze241ce82003-02-17 18:17:05 +00003242 PyObject *o = PyInt_FromLong((long)grouplist[i]);
Fred Drakec9680921999-12-13 16:37:25 +00003243 if (o == NULL) {
3244 Py_DECREF(result);
3245 result = NULL;
3246 break;
3247 }
3248 PyList_SET_ITEM(result, i, o);
3249 }
3250 }
3251 }
Neal Norwitze241ce82003-02-17 18:17:05 +00003252
Fred Drakec9680921999-12-13 16:37:25 +00003253 return result;
3254}
3255#endif
3256
Martin v. Löwis606edc12002-06-13 21:09:11 +00003257#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003258PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003259"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003260Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00003261
3262static PyObject *
3263posix_getpgid(PyObject *self, PyObject *args)
3264{
3265 int pid, pgid;
3266 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
3267 return NULL;
3268 pgid = getpgid(pid);
3269 if (pgid < 0)
3270 return posix_error();
3271 return PyInt_FromLong((long)pgid);
3272}
3273#endif /* HAVE_GETPGID */
3274
3275
Guido van Rossumb6775db1994-08-01 11:34:53 +00003276#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003277PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003278"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003279Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003280
Barry Warsaw53699e91996-12-10 23:23:01 +00003281static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003282posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00003283{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003284#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00003285 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003286#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00003287 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003288#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00003289}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003290#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00003291
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003292
Guido van Rossumb6775db1994-08-01 11:34:53 +00003293#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003294PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003295"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003296Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003297
Barry Warsaw53699e91996-12-10 23:23:01 +00003298static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003299posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003300{
Guido van Rossum64933891994-10-20 21:56:42 +00003301#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00003302 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003303#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003304 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003305#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00003306 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003307 Py_INCREF(Py_None);
3308 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003309}
3310
Guido van Rossumb6775db1994-08-01 11:34:53 +00003311#endif /* HAVE_SETPGRP */
3312
Guido van Rossumad0ee831995-03-01 10:34:45 +00003313#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003314PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003315"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003316Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003317
Barry Warsaw53699e91996-12-10 23:23:01 +00003318static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003319posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003320{
Barry Warsaw53699e91996-12-10 23:23:01 +00003321 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003322}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003323#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003324
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003325
Fred Drake12c6e2d1999-12-14 21:25:03 +00003326#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003327PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003328"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003329Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00003330
3331static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003332posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00003333{
Neal Norwitze241ce82003-02-17 18:17:05 +00003334 PyObject *result = NULL;
Fred Drakea30680b2000-12-06 21:24:28 +00003335 char *name;
3336 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00003337
Fred Drakea30680b2000-12-06 21:24:28 +00003338 errno = 0;
3339 name = getlogin();
3340 if (name == NULL) {
3341 if (errno)
3342 posix_error();
3343 else
3344 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00003345 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00003346 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00003347 else
3348 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00003349 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00003350
Fred Drake12c6e2d1999-12-14 21:25:03 +00003351 return result;
3352}
3353#endif
3354
Guido van Rossumad0ee831995-03-01 10:34:45 +00003355#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003356PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003357"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003358Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003359
Barry Warsaw53699e91996-12-10 23:23:01 +00003360static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003361posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003362{
Barry Warsaw53699e91996-12-10 23:23:01 +00003363 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003364}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003365#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003366
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003367
Guido van Rossumad0ee831995-03-01 10:34:45 +00003368#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003369PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003370"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003371Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003372
Barry Warsaw53699e91996-12-10 23:23:01 +00003373static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003374posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003375{
3376 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003377 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00003378 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003379#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003380 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
3381 APIRET rc;
3382 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003383 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003384
3385 } else if (sig == XCPT_SIGNAL_KILLPROC) {
3386 APIRET rc;
3387 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003388 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003389
3390 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003391 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003392#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00003393 if (kill(pid, sig) == -1)
3394 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003395#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003396 Py_INCREF(Py_None);
3397 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003398}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003399#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003400
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003401#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003402PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003403"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003404Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003405
3406static PyObject *
3407posix_killpg(PyObject *self, PyObject *args)
3408{
3409 int pgid, sig;
3410 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
3411 return NULL;
3412 if (killpg(pgid, sig) == -1)
3413 return posix_error();
3414 Py_INCREF(Py_None);
3415 return Py_None;
3416}
3417#endif
3418
Guido van Rossumc0125471996-06-28 18:55:32 +00003419#ifdef HAVE_PLOCK
3420
3421#ifdef HAVE_SYS_LOCK_H
3422#include <sys/lock.h>
3423#endif
3424
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003425PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003426"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003427Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003428
Barry Warsaw53699e91996-12-10 23:23:01 +00003429static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003430posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00003431{
3432 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003433 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00003434 return NULL;
3435 if (plock(op) == -1)
3436 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003437 Py_INCREF(Py_None);
3438 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00003439}
3440#endif
3441
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003442
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003443#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003444PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003445"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003446Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003447
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003448#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003449#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003450static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003451async_system(const char *command)
3452{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003453 char errormsg[256], args[1024];
3454 RESULTCODES rcodes;
3455 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003456
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003457 char *shell = getenv("COMSPEC");
3458 if (!shell)
3459 shell = "cmd";
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003460
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003461 /* avoid overflowing the argument buffer */
3462 if (strlen(shell) + 3 + strlen(command) >= 1024)
3463 return ERROR_NOT_ENOUGH_MEMORY
3464
3465 args[0] = '\0';
3466 strcat(args, shell);
3467 strcat(args, "/c ");
3468 strcat(args, command);
3469
3470 /* execute asynchronously, inheriting the environment */
3471 rc = DosExecPgm(errormsg,
3472 sizeof(errormsg),
3473 EXEC_ASYNC,
3474 args,
3475 NULL,
3476 &rcodes,
3477 shell);
3478 return rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003479}
3480
Guido van Rossumd48f2521997-12-05 22:19:34 +00003481static FILE *
3482popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003483{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003484 int oldfd, tgtfd;
3485 HFILE pipeh[2];
3486 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003487
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003488 /* mode determines which of stdin or stdout is reconnected to
3489 * the pipe to the child
3490 */
3491 if (strchr(mode, 'r') != NULL) {
3492 tgt_fd = 1; /* stdout */
3493 } else if (strchr(mode, 'w')) {
3494 tgt_fd = 0; /* stdin */
3495 } else {
3496 *err = ERROR_INVALID_ACCESS;
3497 return NULL;
3498 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003499
Andrew MacIntyrea3be2582004-12-18 09:51:05 +00003500 /* setup the pipe */
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003501 if ((rc = DosCreatePipe(&pipeh[0], &pipeh[1], pipesize)) != NO_ERROR) {
3502 *err = rc;
3503 return NULL;
3504 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003505
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003506 /* prevent other threads accessing stdio */
3507 DosEnterCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003508
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003509 /* reconnect stdio and execute child */
3510 oldfd = dup(tgtfd);
3511 close(tgtfd);
3512 if (dup2(pipeh[tgtfd], tgtfd) == 0) {
3513 DosClose(pipeh[tgtfd]);
3514 rc = async_system(command);
3515 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003516
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003517 /* restore stdio */
3518 dup2(oldfd, tgtfd);
3519 close(oldfd);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003520
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003521 /* allow other threads access to stdio */
3522 DosExitCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003523
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003524 /* if execution of child was successful return file stream */
3525 if (rc == NO_ERROR)
3526 return fdopen(pipeh[1 - tgtfd], mode);
3527 else {
3528 DosClose(pipeh[1 - tgtfd]);
3529 *err = rc;
3530 return NULL;
3531 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003532}
3533
3534static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003535posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003536{
3537 char *name;
3538 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00003539 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003540 FILE *fp;
3541 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003542 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003543 return NULL;
3544 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00003545 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003546 Py_END_ALLOW_THREADS
3547 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003548 return os2_error(err);
3549
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003550 f = PyFile_FromFile(fp, name, mode, fclose);
3551 if (f != NULL)
3552 PyFile_SetBufSize(f, bufsize);
3553 return f;
3554}
3555
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003556#elif defined(PYCC_GCC)
3557
3558/* standard posix version of popen() support */
3559static PyObject *
3560posix_popen(PyObject *self, PyObject *args)
3561{
3562 char *name;
3563 char *mode = "r";
3564 int bufsize = -1;
3565 FILE *fp;
3566 PyObject *f;
3567 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
3568 return NULL;
3569 Py_BEGIN_ALLOW_THREADS
3570 fp = popen(name, mode);
3571 Py_END_ALLOW_THREADS
3572 if (fp == NULL)
3573 return posix_error();
3574 f = PyFile_FromFile(fp, name, mode, pclose);
3575 if (f != NULL)
3576 PyFile_SetBufSize(f, bufsize);
3577 return f;
3578}
3579
3580/* fork() under OS/2 has lots'o'warts
3581 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
3582 * most of this code is a ripoff of the win32 code, but using the
3583 * capabilities of EMX's C library routines
3584 */
3585
3586/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
3587#define POPEN_1 1
3588#define POPEN_2 2
3589#define POPEN_3 3
3590#define POPEN_4 4
3591
3592static PyObject *_PyPopen(char *, int, int, int);
3593static int _PyPclose(FILE *file);
3594
3595/*
3596 * Internal dictionary mapping popen* file pointers to process handles,
3597 * for use when retrieving the process exit code. See _PyPclose() below
3598 * for more information on this dictionary's use.
3599 */
3600static PyObject *_PyPopenProcs = NULL;
3601
3602/* os2emx version of popen2()
3603 *
3604 * The result of this function is a pipe (file) connected to the
3605 * process's stdin, and a pipe connected to the process's stdout.
3606 */
3607
3608static PyObject *
3609os2emx_popen2(PyObject *self, PyObject *args)
3610{
3611 PyObject *f;
3612 int tm=0;
3613
3614 char *cmdstring;
3615 char *mode = "t";
3616 int bufsize = -1;
3617 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
3618 return NULL;
3619
3620 if (*mode == 't')
3621 tm = O_TEXT;
3622 else if (*mode != 'b') {
3623 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3624 return NULL;
3625 } else
3626 tm = O_BINARY;
3627
3628 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
3629
3630 return f;
3631}
3632
3633/*
3634 * Variation on os2emx.popen2
3635 *
3636 * The result of this function is 3 pipes - the process's stdin,
3637 * stdout and stderr
3638 */
3639
3640static PyObject *
3641os2emx_popen3(PyObject *self, PyObject *args)
3642{
3643 PyObject *f;
3644 int tm = 0;
3645
3646 char *cmdstring;
3647 char *mode = "t";
3648 int bufsize = -1;
3649 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
3650 return NULL;
3651
3652 if (*mode == 't')
3653 tm = O_TEXT;
3654 else if (*mode != 'b') {
3655 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3656 return NULL;
3657 } else
3658 tm = O_BINARY;
3659
3660 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
3661
3662 return f;
3663}
3664
3665/*
3666 * Variation on os2emx.popen2
3667 *
Tim Peters11b23062003-04-23 02:39:17 +00003668 * The result of this function is 2 pipes - the processes stdin,
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003669 * and stdout+stderr combined as a single pipe.
3670 */
3671
3672static PyObject *
3673os2emx_popen4(PyObject *self, PyObject *args)
3674{
3675 PyObject *f;
3676 int tm = 0;
3677
3678 char *cmdstring;
3679 char *mode = "t";
3680 int bufsize = -1;
3681 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
3682 return NULL;
3683
3684 if (*mode == 't')
3685 tm = O_TEXT;
3686 else if (*mode != 'b') {
3687 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3688 return NULL;
3689 } else
3690 tm = O_BINARY;
3691
3692 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
3693
3694 return f;
3695}
3696
3697/* a couple of structures for convenient handling of multiple
3698 * file handles and pipes
3699 */
3700struct file_ref
3701{
3702 int handle;
3703 int flags;
3704};
3705
3706struct pipe_ref
3707{
3708 int rd;
3709 int wr;
3710};
3711
3712/* The following code is derived from the win32 code */
3713
3714static PyObject *
3715_PyPopen(char *cmdstring, int mode, int n, int bufsize)
3716{
3717 struct file_ref stdio[3];
3718 struct pipe_ref p_fd[3];
3719 FILE *p_s[3];
3720 int file_count, i, pipe_err, pipe_pid;
3721 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
3722 PyObject *f, *p_f[3];
3723
3724 /* file modes for subsequent fdopen's on pipe handles */
3725 if (mode == O_TEXT)
3726 {
3727 rd_mode = "rt";
3728 wr_mode = "wt";
3729 }
3730 else
3731 {
3732 rd_mode = "rb";
3733 wr_mode = "wb";
3734 }
3735
3736 /* prepare shell references */
3737 if ((shell = getenv("EMXSHELL")) == NULL)
3738 if ((shell = getenv("COMSPEC")) == NULL)
3739 {
3740 errno = ENOENT;
3741 return posix_error();
3742 }
3743
3744 sh_name = _getname(shell);
3745 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
3746 opt = "/c";
3747 else
3748 opt = "-c";
3749
3750 /* save current stdio fds + their flags, and set not inheritable */
3751 i = pipe_err = 0;
3752 while (pipe_err >= 0 && i < 3)
3753 {
3754 pipe_err = stdio[i].handle = dup(i);
3755 stdio[i].flags = fcntl(i, F_GETFD, 0);
3756 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
3757 i++;
3758 }
3759 if (pipe_err < 0)
3760 {
3761 /* didn't get them all saved - clean up and bail out */
3762 int saved_err = errno;
3763 while (i-- > 0)
3764 {
3765 close(stdio[i].handle);
3766 }
3767 errno = saved_err;
3768 return posix_error();
3769 }
3770
3771 /* create pipe ends */
3772 file_count = 2;
3773 if (n == POPEN_3)
3774 file_count = 3;
3775 i = pipe_err = 0;
3776 while ((pipe_err == 0) && (i < file_count))
3777 pipe_err = pipe((int *)&p_fd[i++]);
3778 if (pipe_err < 0)
3779 {
3780 /* didn't get them all made - clean up and bail out */
3781 while (i-- > 0)
3782 {
3783 close(p_fd[i].wr);
3784 close(p_fd[i].rd);
3785 }
3786 errno = EPIPE;
3787 return posix_error();
3788 }
3789
3790 /* change the actual standard IO streams over temporarily,
3791 * making the retained pipe ends non-inheritable
3792 */
3793 pipe_err = 0;
3794
3795 /* - stdin */
3796 if (dup2(p_fd[0].rd, 0) == 0)
3797 {
3798 close(p_fd[0].rd);
3799 i = fcntl(p_fd[0].wr, F_GETFD, 0);
3800 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
3801 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
3802 {
3803 close(p_fd[0].wr);
3804 pipe_err = -1;
3805 }
3806 }
3807 else
3808 {
3809 pipe_err = -1;
3810 }
3811
3812 /* - stdout */
3813 if (pipe_err == 0)
3814 {
3815 if (dup2(p_fd[1].wr, 1) == 1)
3816 {
3817 close(p_fd[1].wr);
3818 i = fcntl(p_fd[1].rd, F_GETFD, 0);
3819 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
3820 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
3821 {
3822 close(p_fd[1].rd);
3823 pipe_err = -1;
3824 }
3825 }
3826 else
3827 {
3828 pipe_err = -1;
3829 }
3830 }
3831
3832 /* - stderr, as required */
3833 if (pipe_err == 0)
3834 switch (n)
3835 {
3836 case POPEN_3:
3837 {
3838 if (dup2(p_fd[2].wr, 2) == 2)
3839 {
3840 close(p_fd[2].wr);
3841 i = fcntl(p_fd[2].rd, F_GETFD, 0);
3842 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
3843 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
3844 {
3845 close(p_fd[2].rd);
3846 pipe_err = -1;
3847 }
3848 }
3849 else
3850 {
3851 pipe_err = -1;
3852 }
3853 break;
3854 }
3855
3856 case POPEN_4:
3857 {
3858 if (dup2(1, 2) != 2)
3859 {
3860 pipe_err = -1;
3861 }
3862 break;
3863 }
3864 }
3865
3866 /* spawn the child process */
3867 if (pipe_err == 0)
3868 {
3869 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
3870 if (pipe_pid == -1)
3871 {
3872 pipe_err = -1;
3873 }
3874 else
3875 {
3876 /* save the PID into the FILE structure
3877 * NOTE: this implementation doesn't actually
3878 * take advantage of this, but do it for
3879 * completeness - AIM Apr01
3880 */
3881 for (i = 0; i < file_count; i++)
3882 p_s[i]->_pid = pipe_pid;
3883 }
3884 }
3885
3886 /* reset standard IO to normal */
3887 for (i = 0; i < 3; i++)
3888 {
3889 dup2(stdio[i].handle, i);
3890 fcntl(i, F_SETFD, stdio[i].flags);
3891 close(stdio[i].handle);
3892 }
3893
3894 /* if any remnant problems, clean up and bail out */
3895 if (pipe_err < 0)
3896 {
3897 for (i = 0; i < 3; i++)
3898 {
3899 close(p_fd[i].rd);
3900 close(p_fd[i].wr);
3901 }
3902 errno = EPIPE;
3903 return posix_error_with_filename(cmdstring);
3904 }
3905
3906 /* build tuple of file objects to return */
3907 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
3908 PyFile_SetBufSize(p_f[0], bufsize);
3909 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
3910 PyFile_SetBufSize(p_f[1], bufsize);
3911 if (n == POPEN_3)
3912 {
3913 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
3914 PyFile_SetBufSize(p_f[0], bufsize);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00003915 f = PyTuple_Pack(3, p_f[0], p_f[1], p_f[2]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003916 }
3917 else
Raymond Hettinger8ae46892003-10-12 19:09:37 +00003918 f = PyTuple_Pack(2, p_f[0], p_f[1]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003919
3920 /*
3921 * Insert the files we've created into the process dictionary
3922 * all referencing the list with the process handle and the
3923 * initial number of files (see description below in _PyPclose).
3924 * Since if _PyPclose later tried to wait on a process when all
3925 * handles weren't closed, it could create a deadlock with the
3926 * child, we spend some energy here to try to ensure that we
3927 * either insert all file handles into the dictionary or none
3928 * at all. It's a little clumsy with the various popen modes
3929 * and variable number of files involved.
3930 */
3931 if (!_PyPopenProcs)
3932 {
3933 _PyPopenProcs = PyDict_New();
3934 }
3935
3936 if (_PyPopenProcs)
3937 {
3938 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
3939 int ins_rc[3];
3940
3941 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
3942 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
3943
3944 procObj = PyList_New(2);
3945 pidObj = PyInt_FromLong((long) pipe_pid);
3946 intObj = PyInt_FromLong((long) file_count);
3947
3948 if (procObj && pidObj && intObj)
3949 {
3950 PyList_SetItem(procObj, 0, pidObj);
3951 PyList_SetItem(procObj, 1, intObj);
3952
3953 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
3954 if (fileObj[0])
3955 {
3956 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
3957 fileObj[0],
3958 procObj);
3959 }
3960 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
3961 if (fileObj[1])
3962 {
3963 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
3964 fileObj[1],
3965 procObj);
3966 }
3967 if (file_count >= 3)
3968 {
3969 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
3970 if (fileObj[2])
3971 {
3972 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
3973 fileObj[2],
3974 procObj);
3975 }
3976 }
3977
3978 if (ins_rc[0] < 0 || !fileObj[0] ||
3979 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
3980 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
3981 {
3982 /* Something failed - remove any dictionary
3983 * entries that did make it.
3984 */
3985 if (!ins_rc[0] && fileObj[0])
3986 {
3987 PyDict_DelItem(_PyPopenProcs,
3988 fileObj[0]);
3989 }
3990 if (!ins_rc[1] && fileObj[1])
3991 {
3992 PyDict_DelItem(_PyPopenProcs,
3993 fileObj[1]);
3994 }
3995 if (!ins_rc[2] && fileObj[2])
3996 {
3997 PyDict_DelItem(_PyPopenProcs,
3998 fileObj[2]);
3999 }
4000 }
4001 }
Tim Peters11b23062003-04-23 02:39:17 +00004002
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004003 /*
4004 * Clean up our localized references for the dictionary keys
4005 * and value since PyDict_SetItem will Py_INCREF any copies
4006 * that got placed in the dictionary.
4007 */
4008 Py_XDECREF(procObj);
4009 Py_XDECREF(fileObj[0]);
4010 Py_XDECREF(fileObj[1]);
4011 Py_XDECREF(fileObj[2]);
4012 }
4013
4014 /* Child is launched. */
4015 return f;
4016}
4017
4018/*
4019 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4020 * exit code for the child process and return as a result of the close.
4021 *
4022 * This function uses the _PyPopenProcs dictionary in order to map the
4023 * input file pointer to information about the process that was
4024 * originally created by the popen* call that created the file pointer.
4025 * The dictionary uses the file pointer as a key (with one entry
4026 * inserted for each file returned by the original popen* call) and a
4027 * single list object as the value for all files from a single call.
4028 * The list object contains the Win32 process handle at [0], and a file
4029 * count at [1], which is initialized to the total number of file
4030 * handles using that list.
4031 *
4032 * This function closes whichever handle it is passed, and decrements
4033 * the file count in the dictionary for the process handle pointed to
4034 * by this file. On the last close (when the file count reaches zero),
4035 * this function will wait for the child process and then return its
4036 * exit code as the result of the close() operation. This permits the
4037 * files to be closed in any order - it is always the close() of the
4038 * final handle that will return the exit code.
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004039 *
4040 * NOTE: This function is currently called with the GIL released.
4041 * hence we use the GILState API to manage our state.
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004042 */
4043
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004044static int _PyPclose(FILE *file)
4045{
4046 int result;
4047 int exit_code;
4048 int pipe_pid;
4049 PyObject *procObj, *pidObj, *intObj, *fileObj;
4050 int file_count;
4051#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004052 PyGILState_STATE state;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004053#endif
4054
4055 /* Close the file handle first, to ensure it can't block the
4056 * child from exiting if it's the last handle.
4057 */
4058 result = fclose(file);
4059
4060#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004061 state = PyGILState_Ensure();
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004062#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004063 if (_PyPopenProcs)
4064 {
4065 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4066 (procObj = PyDict_GetItem(_PyPopenProcs,
4067 fileObj)) != NULL &&
4068 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
4069 (intObj = PyList_GetItem(procObj,1)) != NULL)
4070 {
4071 pipe_pid = (int) PyInt_AsLong(pidObj);
4072 file_count = (int) PyInt_AsLong(intObj);
4073
4074 if (file_count > 1)
4075 {
4076 /* Still other files referencing process */
4077 file_count--;
4078 PyList_SetItem(procObj,1,
4079 PyInt_FromLong((long) file_count));
4080 }
4081 else
4082 {
4083 /* Last file for this process */
4084 if (result != EOF &&
4085 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
4086 {
4087 /* extract exit status */
4088 if (WIFEXITED(exit_code))
4089 {
4090 result = WEXITSTATUS(exit_code);
4091 }
4092 else
4093 {
4094 errno = EPIPE;
4095 result = -1;
4096 }
4097 }
4098 else
4099 {
4100 /* Indicate failure - this will cause the file object
4101 * to raise an I/O error and translate the last
4102 * error code from errno. We do have a problem with
4103 * last errors that overlap the normal errno table,
4104 * but that's a consistent problem with the file object.
4105 */
4106 result = -1;
4107 }
4108 }
4109
4110 /* Remove this file pointer from dictionary */
4111 PyDict_DelItem(_PyPopenProcs, fileObj);
4112
4113 if (PyDict_Size(_PyPopenProcs) == 0)
4114 {
4115 Py_DECREF(_PyPopenProcs);
4116 _PyPopenProcs = NULL;
4117 }
4118
4119 } /* if object retrieval ok */
4120
4121 Py_XDECREF(fileObj);
4122 } /* if _PyPopenProcs */
4123
4124#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004125 PyGILState_Release(state);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004126#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004127 return result;
4128}
4129
4130#endif /* PYCC_??? */
4131
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004132#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004133
4134/*
4135 * Portable 'popen' replacement for Win32.
4136 *
4137 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
4138 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00004139 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004140 */
4141
4142#include <malloc.h>
4143#include <io.h>
4144#include <fcntl.h>
4145
4146/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
4147#define POPEN_1 1
4148#define POPEN_2 2
4149#define POPEN_3 3
4150#define POPEN_4 4
4151
4152static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004153static int _PyPclose(FILE *file);
4154
4155/*
4156 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00004157 * for use when retrieving the process exit code. See _PyPclose() below
4158 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004159 */
4160static PyObject *_PyPopenProcs = NULL;
4161
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004162
4163/* popen that works from a GUI.
4164 *
4165 * The result of this function is a pipe (file) connected to the
4166 * processes stdin or stdout, depending on the requested mode.
4167 */
4168
4169static PyObject *
4170posix_popen(PyObject *self, PyObject *args)
4171{
Raymond Hettingerb5cb6652003-09-01 22:25:41 +00004172 PyObject *f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004173 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004174
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004175 char *cmdstring;
4176 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004177 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004178 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004179 return NULL;
4180
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004181 if (*mode == 'r')
4182 tm = _O_RDONLY;
4183 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00004184 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004185 return NULL;
4186 } else
4187 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00004188
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004189 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004190 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004191 return NULL;
4192 }
4193
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004194 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004195 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004196 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004197 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004198 else
4199 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
4200
4201 return f;
4202}
4203
4204/* Variation on win32pipe.popen
4205 *
4206 * The result of this function is a pipe (file) connected to the
4207 * process's stdin, and a pipe connected to the process's stdout.
4208 */
4209
4210static PyObject *
4211win32_popen2(PyObject *self, PyObject *args)
4212{
4213 PyObject *f;
4214 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00004215
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004216 char *cmdstring;
4217 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004218 int bufsize = -1;
4219 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004220 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004221
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004222 if (*mode == 't')
4223 tm = _O_TEXT;
4224 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004225 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004226 return NULL;
4227 } else
4228 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004229
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004230 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004231 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004232 return NULL;
4233 }
4234
4235 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00004236
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004237 return f;
4238}
4239
4240/*
4241 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004242 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004243 * The result of this function is 3 pipes - the process's stdin,
4244 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004245 */
4246
4247static PyObject *
4248win32_popen3(PyObject *self, PyObject *args)
4249{
4250 PyObject *f;
4251 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004252
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004253 char *cmdstring;
4254 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004255 int bufsize = -1;
4256 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004257 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004258
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004259 if (*mode == 't')
4260 tm = _O_TEXT;
4261 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004262 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004263 return NULL;
4264 } else
4265 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004266
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004267 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004268 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004269 return NULL;
4270 }
4271
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004272 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00004273
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004274 return f;
4275}
4276
4277/*
4278 * Variation on win32pipe.popen
4279 *
Tim Peters5aa91602002-01-30 05:46:57 +00004280 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004281 * and stdout+stderr combined as a single pipe.
4282 */
4283
4284static PyObject *
4285win32_popen4(PyObject *self, PyObject *args)
4286{
4287 PyObject *f;
4288 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004289
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004290 char *cmdstring;
4291 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004292 int bufsize = -1;
4293 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004294 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004295
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004296 if (*mode == 't')
4297 tm = _O_TEXT;
4298 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004299 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004300 return NULL;
4301 } else
4302 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004303
4304 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004305 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004306 return NULL;
4307 }
4308
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004309 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004310
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004311 return f;
4312}
4313
Mark Hammond08501372001-01-31 07:30:29 +00004314static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00004315_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004316 HANDLE hStdin,
4317 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00004318 HANDLE hStderr,
4319 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004320{
4321 PROCESS_INFORMATION piProcInfo;
4322 STARTUPINFO siStartInfo;
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004323 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004324 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00004325 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004326 int i;
Martin v. Löwis18e16552006-02-15 17:27:45 +00004327 Py_ssize_t x;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004328
4329 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00004330 char *comshell;
4331
Tim Peters92e4dd82002-10-05 01:47:34 +00004332 s1 = (char *)alloca(i);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004333 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
Martin v. Löwis18e16552006-02-15 17:27:45 +00004334 /* x < i, so x fits into an integer */
4335 return (int)x;
Tim Peters402d5982001-08-27 06:37:48 +00004336
4337 /* Explicitly check if we are using COMMAND.COM. If we are
4338 * then use the w9xpopen hack.
4339 */
4340 comshell = s1 + x;
4341 while (comshell >= s1 && *comshell != '\\')
4342 --comshell;
4343 ++comshell;
4344
4345 if (GetVersion() < 0x80000000 &&
4346 _stricmp(comshell, "command.com") != 0) {
4347 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004348 x = i + strlen(s3) + strlen(cmdstring) + 1;
Tim Peters92e4dd82002-10-05 01:47:34 +00004349 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004350 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00004351 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004352 }
4353 else {
4354 /*
Tim Peters402d5982001-08-27 06:37:48 +00004355 * Oh gag, we're on Win9x or using COMMAND.COM. Use
4356 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004357 */
Mark Hammond08501372001-01-31 07:30:29 +00004358 char modulepath[_MAX_PATH];
4359 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004360 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
4361 for (i = x = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004362 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004363 x = i+1;
4364 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00004365 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00004366 strncat(modulepath,
4367 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00004368 (sizeof(modulepath)/sizeof(modulepath[0]))
4369 -strlen(modulepath));
4370 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00004371 /* Eeek - file-not-found - possibly an embedding
4372 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00004373 */
Tim Peters5aa91602002-01-30 05:46:57 +00004374 strncpy(modulepath,
4375 Py_GetExecPrefix(),
Mark Hammond08501372001-01-31 07:30:29 +00004376 sizeof(modulepath)/sizeof(modulepath[0]));
4377 if (modulepath[strlen(modulepath)-1] != '\\')
4378 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00004379 strncat(modulepath,
4380 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00004381 (sizeof(modulepath)/sizeof(modulepath[0]))
4382 -strlen(modulepath));
4383 /* No where else to look - raise an easily identifiable
4384 error, rather than leaving Windows to report
4385 "file not found" - as the user is probably blissfully
4386 unaware this shim EXE is used, and it will confuse them.
4387 (well, it confused me for a while ;-)
4388 */
4389 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00004390 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00004391 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00004392 "for popen to work with your shell "
4393 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00004394 szConsoleSpawn);
4395 return FALSE;
4396 }
4397 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004398 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00004399 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004400 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00004401
Tim Peters92e4dd82002-10-05 01:47:34 +00004402 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004403 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004404 /* To maintain correct argument passing semantics,
4405 we pass the command-line as it stands, and allow
4406 quoting to be applied. w9xpopen.exe will then
4407 use its argv vector, and re-quote the necessary
4408 args for the ultimate child process.
4409 */
Tim Peters75cdad52001-11-28 22:07:30 +00004410 PyOS_snprintf(
4411 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004412 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004413 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004414 s1,
4415 s3,
4416 cmdstring);
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004417 /* Not passing CREATE_NEW_CONSOLE has been known to
Tim Peters11b23062003-04-23 02:39:17 +00004418 cause random failures on win9x. Specifically a
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004419 dialog:
4420 "Your program accessed mem currently in use at xxx"
4421 and a hopeful warning about the stability of your
4422 system.
4423 Cost is Ctrl+C wont kill children, but anyone
4424 who cares can have a go!
4425 */
4426 dwProcessFlags |= CREATE_NEW_CONSOLE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004427 }
4428 }
4429
4430 /* Could be an else here to try cmd.exe / command.com in the path
4431 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00004432 else {
Tim Peters402d5982001-08-27 06:37:48 +00004433 PyErr_SetString(PyExc_RuntimeError,
4434 "Cannot locate a COMSPEC environment variable to "
4435 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00004436 return FALSE;
4437 }
Tim Peters5aa91602002-01-30 05:46:57 +00004438
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004439 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
4440 siStartInfo.cb = sizeof(STARTUPINFO);
4441 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
4442 siStartInfo.hStdInput = hStdin;
4443 siStartInfo.hStdOutput = hStdout;
4444 siStartInfo.hStdError = hStderr;
4445 siStartInfo.wShowWindow = SW_HIDE;
4446
4447 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004448 s2,
4449 NULL,
4450 NULL,
4451 TRUE,
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004452 dwProcessFlags,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004453 NULL,
4454 NULL,
4455 &siStartInfo,
4456 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004457 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004458 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004459
Mark Hammondb37a3732000-08-14 04:47:33 +00004460 /* Return process handle */
4461 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004462 return TRUE;
4463 }
Tim Peters402d5982001-08-27 06:37:48 +00004464 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004465 return FALSE;
4466}
4467
4468/* The following code is based off of KB: Q190351 */
4469
4470static PyObject *
4471_PyPopen(char *cmdstring, int mode, int n)
4472{
4473 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
4474 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00004475 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00004476
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004477 SECURITY_ATTRIBUTES saAttr;
4478 BOOL fSuccess;
4479 int fd1, fd2, fd3;
4480 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00004481 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004482 PyObject *f;
4483
4484 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
4485 saAttr.bInheritHandle = TRUE;
4486 saAttr.lpSecurityDescriptor = NULL;
4487
4488 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
4489 return win32_error("CreatePipe", NULL);
4490
4491 /* Create new output read handle and the input write handle. Set
4492 * the inheritance properties to FALSE. Otherwise, the child inherits
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00004493 * these handles; resulting in non-closeable handles to the pipes
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004494 * being created. */
4495 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004496 GetCurrentProcess(), &hChildStdinWrDup, 0,
4497 FALSE,
4498 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004499 if (!fSuccess)
4500 return win32_error("DuplicateHandle", NULL);
4501
4502 /* Close the inheritable version of ChildStdin
4503 that we're using. */
4504 CloseHandle(hChildStdinWr);
4505
4506 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
4507 return win32_error("CreatePipe", NULL);
4508
4509 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004510 GetCurrentProcess(), &hChildStdoutRdDup, 0,
4511 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004512 if (!fSuccess)
4513 return win32_error("DuplicateHandle", NULL);
4514
4515 /* Close the inheritable version of ChildStdout
4516 that we're using. */
4517 CloseHandle(hChildStdoutRd);
4518
4519 if (n != POPEN_4) {
4520 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
4521 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004522 fSuccess = DuplicateHandle(GetCurrentProcess(),
4523 hChildStderrRd,
4524 GetCurrentProcess(),
4525 &hChildStderrRdDup, 0,
4526 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004527 if (!fSuccess)
4528 return win32_error("DuplicateHandle", NULL);
4529 /* Close the inheritable version of ChildStdErr that we're using. */
4530 CloseHandle(hChildStderrRd);
4531 }
Tim Peters5aa91602002-01-30 05:46:57 +00004532
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004533 switch (n) {
4534 case POPEN_1:
4535 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
4536 case _O_WRONLY | _O_TEXT:
4537 /* Case for writing to child Stdin in text mode. */
Martin v. Löwis18e16552006-02-15 17:27:45 +00004538 fd1 = _open_osfhandle((intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004539 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004540 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004541 PyFile_SetBufSize(f, 0);
4542 /* We don't care about these pipes anymore, so close them. */
4543 CloseHandle(hChildStdoutRdDup);
4544 CloseHandle(hChildStderrRdDup);
4545 break;
4546
4547 case _O_RDONLY | _O_TEXT:
4548 /* Case for reading from child Stdout in text mode. */
Martin v. Löwis18e16552006-02-15 17:27:45 +00004549 fd1 = _open_osfhandle((intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004550 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004551 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004552 PyFile_SetBufSize(f, 0);
4553 /* We don't care about these pipes anymore, so close them. */
4554 CloseHandle(hChildStdinWrDup);
4555 CloseHandle(hChildStderrRdDup);
4556 break;
4557
4558 case _O_RDONLY | _O_BINARY:
4559 /* Case for readinig from child Stdout in binary mode. */
Martin v. Löwis18e16552006-02-15 17:27:45 +00004560 fd1 = _open_osfhandle((intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004561 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004562 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004563 PyFile_SetBufSize(f, 0);
4564 /* We don't care about these pipes anymore, so close them. */
4565 CloseHandle(hChildStdinWrDup);
4566 CloseHandle(hChildStderrRdDup);
4567 break;
4568
4569 case _O_WRONLY | _O_BINARY:
4570 /* Case for writing to child Stdin in binary mode. */
Martin v. Löwis18e16552006-02-15 17:27:45 +00004571 fd1 = _open_osfhandle((intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004572 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004573 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004574 PyFile_SetBufSize(f, 0);
4575 /* We don't care about these pipes anymore, so close them. */
4576 CloseHandle(hChildStdoutRdDup);
4577 CloseHandle(hChildStderrRdDup);
4578 break;
4579 }
Mark Hammondb37a3732000-08-14 04:47:33 +00004580 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004581 break;
Tim Peters5aa91602002-01-30 05:46:57 +00004582
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004583 case POPEN_2:
4584 case POPEN_4:
4585 {
4586 char *m1, *m2;
4587 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00004588
Tim Peters7dca21e2002-08-19 00:42:29 +00004589 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004590 m1 = "r";
4591 m2 = "w";
4592 } else {
4593 m1 = "rb";
4594 m2 = "wb";
4595 }
4596
Martin v. Löwis18e16552006-02-15 17:27:45 +00004597 fd1 = _open_osfhandle((intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004598 f1 = _fdopen(fd1, m2);
Martin v. Löwis18e16552006-02-15 17:27:45 +00004599 fd2 = _open_osfhandle((intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004600 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004601 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004602 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00004603 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004604 PyFile_SetBufSize(p2, 0);
4605
4606 if (n != 4)
4607 CloseHandle(hChildStderrRdDup);
4608
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004609 f = PyTuple_Pack(2,p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00004610 Py_XDECREF(p1);
4611 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00004612 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004613 break;
4614 }
Tim Peters5aa91602002-01-30 05:46:57 +00004615
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004616 case POPEN_3:
4617 {
4618 char *m1, *m2;
4619 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00004620
Tim Peters7dca21e2002-08-19 00:42:29 +00004621 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004622 m1 = "r";
4623 m2 = "w";
4624 } else {
4625 m1 = "rb";
4626 m2 = "wb";
4627 }
4628
Martin v. Löwis18e16552006-02-15 17:27:45 +00004629 fd1 = _open_osfhandle((intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004630 f1 = _fdopen(fd1, m2);
Martin v. Löwis18e16552006-02-15 17:27:45 +00004631 fd2 = _open_osfhandle((intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004632 f2 = _fdopen(fd2, m1);
Martin v. Löwis18e16552006-02-15 17:27:45 +00004633 fd3 = _open_osfhandle((intptr_t)hChildStderrRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004634 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004635 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00004636 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
4637 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004638 PyFile_SetBufSize(p1, 0);
4639 PyFile_SetBufSize(p2, 0);
4640 PyFile_SetBufSize(p3, 0);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004641 f = PyTuple_Pack(3,p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00004642 Py_XDECREF(p1);
4643 Py_XDECREF(p2);
4644 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00004645 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004646 break;
4647 }
4648 }
4649
4650 if (n == POPEN_4) {
4651 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004652 hChildStdinRd,
4653 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004654 hChildStdoutWr,
4655 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004656 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004657 }
4658 else {
4659 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004660 hChildStdinRd,
4661 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004662 hChildStderrWr,
4663 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004664 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004665 }
4666
Mark Hammondb37a3732000-08-14 04:47:33 +00004667 /*
4668 * Insert the files we've created into the process dictionary
4669 * all referencing the list with the process handle and the
4670 * initial number of files (see description below in _PyPclose).
4671 * Since if _PyPclose later tried to wait on a process when all
4672 * handles weren't closed, it could create a deadlock with the
4673 * child, we spend some energy here to try to ensure that we
4674 * either insert all file handles into the dictionary or none
4675 * at all. It's a little clumsy with the various popen modes
4676 * and variable number of files involved.
4677 */
4678 if (!_PyPopenProcs) {
4679 _PyPopenProcs = PyDict_New();
4680 }
4681
4682 if (_PyPopenProcs) {
4683 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
4684 int ins_rc[3];
4685
4686 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4687 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4688
4689 procObj = PyList_New(2);
4690 hProcessObj = PyLong_FromVoidPtr(hProcess);
4691 intObj = PyInt_FromLong(file_count);
4692
4693 if (procObj && hProcessObj && intObj) {
4694 PyList_SetItem(procObj,0,hProcessObj);
4695 PyList_SetItem(procObj,1,intObj);
4696
4697 fileObj[0] = PyLong_FromVoidPtr(f1);
4698 if (fileObj[0]) {
4699 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4700 fileObj[0],
4701 procObj);
4702 }
4703 if (file_count >= 2) {
4704 fileObj[1] = PyLong_FromVoidPtr(f2);
4705 if (fileObj[1]) {
4706 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4707 fileObj[1],
4708 procObj);
4709 }
4710 }
4711 if (file_count >= 3) {
4712 fileObj[2] = PyLong_FromVoidPtr(f3);
4713 if (fileObj[2]) {
4714 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4715 fileObj[2],
4716 procObj);
4717 }
4718 }
4719
4720 if (ins_rc[0] < 0 || !fileObj[0] ||
4721 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4722 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
4723 /* Something failed - remove any dictionary
4724 * entries that did make it.
4725 */
4726 if (!ins_rc[0] && fileObj[0]) {
4727 PyDict_DelItem(_PyPopenProcs,
4728 fileObj[0]);
4729 }
4730 if (!ins_rc[1] && fileObj[1]) {
4731 PyDict_DelItem(_PyPopenProcs,
4732 fileObj[1]);
4733 }
4734 if (!ins_rc[2] && fileObj[2]) {
4735 PyDict_DelItem(_PyPopenProcs,
4736 fileObj[2]);
4737 }
4738 }
4739 }
Tim Peters5aa91602002-01-30 05:46:57 +00004740
Mark Hammondb37a3732000-08-14 04:47:33 +00004741 /*
4742 * Clean up our localized references for the dictionary keys
4743 * and value since PyDict_SetItem will Py_INCREF any copies
4744 * that got placed in the dictionary.
4745 */
4746 Py_XDECREF(procObj);
4747 Py_XDECREF(fileObj[0]);
4748 Py_XDECREF(fileObj[1]);
4749 Py_XDECREF(fileObj[2]);
4750 }
4751
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004752 /* Child is launched. Close the parents copy of those pipe
4753 * handles that only the child should have open. You need to
4754 * make sure that no handles to the write end of the output pipe
4755 * are maintained in this process or else the pipe will not close
4756 * when the child process exits and the ReadFile will hang. */
4757
4758 if (!CloseHandle(hChildStdinRd))
4759 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004760
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004761 if (!CloseHandle(hChildStdoutWr))
4762 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004763
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004764 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
4765 return win32_error("CloseHandle", NULL);
4766
4767 return f;
4768}
Fredrik Lundh56055a42000-07-23 19:47:12 +00004769
4770/*
4771 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4772 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00004773 *
4774 * This function uses the _PyPopenProcs dictionary in order to map the
4775 * input file pointer to information about the process that was
4776 * originally created by the popen* call that created the file pointer.
4777 * The dictionary uses the file pointer as a key (with one entry
4778 * inserted for each file returned by the original popen* call) and a
4779 * single list object as the value for all files from a single call.
4780 * The list object contains the Win32 process handle at [0], and a file
4781 * count at [1], which is initialized to the total number of file
4782 * handles using that list.
4783 *
4784 * This function closes whichever handle it is passed, and decrements
4785 * the file count in the dictionary for the process handle pointed to
4786 * by this file. On the last close (when the file count reaches zero),
4787 * this function will wait for the child process and then return its
4788 * exit code as the result of the close() operation. This permits the
4789 * files to be closed in any order - it is always the close() of the
4790 * final handle that will return the exit code.
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004791 *
4792 * NOTE: This function is currently called with the GIL released.
4793 * hence we use the GILState API to manage our state.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004794 */
Tim Peters736aa322000-09-01 06:51:24 +00004795
Fredrik Lundh56055a42000-07-23 19:47:12 +00004796static int _PyPclose(FILE *file)
4797{
Fredrik Lundh20318932000-07-26 17:29:12 +00004798 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004799 DWORD exit_code;
4800 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00004801 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
4802 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00004803#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004804 PyGILState_STATE state;
Tim Peters736aa322000-09-01 06:51:24 +00004805#endif
4806
Fredrik Lundh20318932000-07-26 17:29:12 +00004807 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00004808 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00004809 */
4810 result = fclose(file);
Tim Peters736aa322000-09-01 06:51:24 +00004811#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004812 state = PyGILState_Ensure();
Tim Peters736aa322000-09-01 06:51:24 +00004813#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00004814 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00004815 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4816 (procObj = PyDict_GetItem(_PyPopenProcs,
4817 fileObj)) != NULL &&
4818 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
4819 (intObj = PyList_GetItem(procObj,1)) != NULL) {
4820
4821 hProcess = PyLong_AsVoidPtr(hProcessObj);
4822 file_count = PyInt_AsLong(intObj);
4823
4824 if (file_count > 1) {
4825 /* Still other files referencing process */
4826 file_count--;
4827 PyList_SetItem(procObj,1,
4828 PyInt_FromLong(file_count));
4829 } else {
4830 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00004831 if (result != EOF &&
4832 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
4833 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00004834 /* Possible truncation here in 16-bit environments, but
4835 * real exit codes are just the lower byte in any event.
4836 */
4837 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004838 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00004839 /* Indicate failure - this will cause the file object
4840 * to raise an I/O error and translate the last Win32
4841 * error code from errno. We do have a problem with
4842 * last errors that overlap the normal errno table,
4843 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004844 */
Fredrik Lundh20318932000-07-26 17:29:12 +00004845 if (result != EOF) {
4846 /* If the error wasn't from the fclose(), then
4847 * set errno for the file object error handling.
4848 */
4849 errno = GetLastError();
4850 }
4851 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004852 }
4853
4854 /* Free up the native handle at this point */
4855 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00004856 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00004857
Mark Hammondb37a3732000-08-14 04:47:33 +00004858 /* Remove this file pointer from dictionary */
4859 PyDict_DelItem(_PyPopenProcs, fileObj);
4860
4861 if (PyDict_Size(_PyPopenProcs) == 0) {
4862 Py_DECREF(_PyPopenProcs);
4863 _PyPopenProcs = NULL;
4864 }
4865
4866 } /* if object retrieval ok */
4867
4868 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004869 } /* if _PyPopenProcs */
4870
Tim Peters736aa322000-09-01 06:51:24 +00004871#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004872 PyGILState_Release(state);
Tim Peters736aa322000-09-01 06:51:24 +00004873#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00004874 return result;
4875}
Tim Peters9acdd3a2000-09-01 19:26:36 +00004876
4877#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00004878static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004879posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00004880{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004881 char *name;
4882 char *mode = "r";
4883 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00004884 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00004885 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004886 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00004887 return NULL;
Martin v. Löwis9ad853b2003-10-31 10:01:53 +00004888 /* Strip mode of binary or text modifiers */
4889 if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
4890 mode = "r";
4891 else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
4892 mode = "w";
Barry Warsaw53699e91996-12-10 23:23:01 +00004893 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004894 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004895 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00004896 if (fp == NULL)
4897 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004898 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004899 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00004900 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004901 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00004902}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004903
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004904#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004905#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00004906
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004907
Guido van Rossumb6775db1994-08-01 11:34:53 +00004908#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004909PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004910"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004911Set the current process's user id.");
4912
Barry Warsaw53699e91996-12-10 23:23:01 +00004913static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004914posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004915{
4916 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004917 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004918 return NULL;
4919 if (setuid(uid) < 0)
4920 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004921 Py_INCREF(Py_None);
4922 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004923}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004924#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004925
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004926
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004927#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004928PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004929"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004930Set the current process's effective user id.");
4931
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004932static PyObject *
4933posix_seteuid (PyObject *self, PyObject *args)
4934{
4935 int euid;
4936 if (!PyArg_ParseTuple(args, "i", &euid)) {
4937 return NULL;
4938 } else if (seteuid(euid) < 0) {
4939 return posix_error();
4940 } else {
4941 Py_INCREF(Py_None);
4942 return Py_None;
4943 }
4944}
4945#endif /* HAVE_SETEUID */
4946
4947#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004948PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004949"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004950Set the current process's effective group id.");
4951
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004952static PyObject *
4953posix_setegid (PyObject *self, PyObject *args)
4954{
4955 int egid;
4956 if (!PyArg_ParseTuple(args, "i", &egid)) {
4957 return NULL;
4958 } else if (setegid(egid) < 0) {
4959 return posix_error();
4960 } else {
4961 Py_INCREF(Py_None);
4962 return Py_None;
4963 }
4964}
4965#endif /* HAVE_SETEGID */
4966
4967#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004968PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004969"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004970Set the current process's real and effective user ids.");
4971
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004972static PyObject *
4973posix_setreuid (PyObject *self, PyObject *args)
4974{
4975 int ruid, euid;
4976 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
4977 return NULL;
4978 } else if (setreuid(ruid, euid) < 0) {
4979 return posix_error();
4980 } else {
4981 Py_INCREF(Py_None);
4982 return Py_None;
4983 }
4984}
4985#endif /* HAVE_SETREUID */
4986
4987#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004988PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004989"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004990Set the current process's real and effective group ids.");
4991
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004992static PyObject *
4993posix_setregid (PyObject *self, PyObject *args)
4994{
4995 int rgid, egid;
4996 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
4997 return NULL;
4998 } else if (setregid(rgid, egid) < 0) {
4999 return posix_error();
5000 } else {
5001 Py_INCREF(Py_None);
5002 return Py_None;
5003 }
5004}
5005#endif /* HAVE_SETREGID */
5006
Guido van Rossumb6775db1994-08-01 11:34:53 +00005007#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005008PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005009"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005010Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005011
Barry Warsaw53699e91996-12-10 23:23:01 +00005012static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005013posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005014{
5015 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005016 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005017 return NULL;
5018 if (setgid(gid) < 0)
5019 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005020 Py_INCREF(Py_None);
5021 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005022}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005023#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005024
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005025#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005026PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005027"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005028Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005029
5030static PyObject *
5031posix_setgroups(PyObject *self, PyObject *args)
5032{
5033 PyObject *groups;
5034 int i, len;
5035 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00005036
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005037 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
5038 return NULL;
5039 if (!PySequence_Check(groups)) {
5040 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
5041 return NULL;
5042 }
5043 len = PySequence_Size(groups);
5044 if (len > MAX_GROUPS) {
5045 PyErr_SetString(PyExc_ValueError, "too many groups");
5046 return NULL;
5047 }
5048 for(i = 0; i < len; i++) {
5049 PyObject *elem;
5050 elem = PySequence_GetItem(groups, i);
5051 if (!elem)
5052 return NULL;
5053 if (!PyInt_Check(elem)) {
Georg Brandla13c2442005-11-22 19:30:31 +00005054 if (!PyLong_Check(elem)) {
5055 PyErr_SetString(PyExc_TypeError,
5056 "groups must be integers");
5057 Py_DECREF(elem);
5058 return NULL;
5059 } else {
5060 unsigned long x = PyLong_AsUnsignedLong(elem);
5061 if (PyErr_Occurred()) {
5062 PyErr_SetString(PyExc_TypeError,
5063 "group id too big");
5064 Py_DECREF(elem);
5065 return NULL;
5066 }
5067 grouplist[i] = x;
5068 /* read back the value to see if it fitted in gid_t */
5069 if (grouplist[i] != x) {
5070 PyErr_SetString(PyExc_TypeError,
5071 "group id too big");
5072 Py_DECREF(elem);
5073 return NULL;
5074 }
5075 }
5076 } else {
5077 long x = PyInt_AsLong(elem);
5078 grouplist[i] = x;
5079 if (grouplist[i] != x) {
5080 PyErr_SetString(PyExc_TypeError,
5081 "group id too big");
5082 Py_DECREF(elem);
5083 return NULL;
5084 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005085 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005086 Py_DECREF(elem);
5087 }
5088
5089 if (setgroups(len, grouplist) < 0)
5090 return posix_error();
5091 Py_INCREF(Py_None);
5092 return Py_None;
5093}
5094#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005095
Guido van Rossumb6775db1994-08-01 11:34:53 +00005096#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005097PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005098"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005099Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005100
Barry Warsaw53699e91996-12-10 23:23:01 +00005101static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005102posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005103{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005104 int pid, options;
5105#ifdef UNION_WAIT
5106 union wait status;
5107#define status_i (status.w_status)
5108#else
5109 int status;
5110#define status_i status
5111#endif
5112 status_i = 0;
5113
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005114 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00005115 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005116 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00005117 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00005118 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00005119 if (pid == -1)
5120 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00005121 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005122 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00005123}
5124
Tim Petersab034fa2002-02-01 11:27:43 +00005125#elif defined(HAVE_CWAIT)
5126
5127/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005128PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005129"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005130"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00005131
5132static PyObject *
5133posix_waitpid(PyObject *self, PyObject *args)
5134{
Martin v. Löwis18e16552006-02-15 17:27:45 +00005135 intptr_t pid;
5136 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00005137
5138 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
5139 return NULL;
5140 Py_BEGIN_ALLOW_THREADS
5141 pid = _cwait(&status, pid, options);
5142 Py_END_ALLOW_THREADS
5143 if (pid == -1)
5144 return posix_error();
5145 else
5146 /* shift the status left a byte so this is more like the
5147 POSIX waitpid */
5148 return Py_BuildValue("ii", pid, status << 8);
5149}
5150#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005151
Guido van Rossumad0ee831995-03-01 10:34:45 +00005152#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005153PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005154"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005155Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005156
Barry Warsaw53699e91996-12-10 23:23:01 +00005157static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005158posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00005159{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005160 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005161#ifdef UNION_WAIT
5162 union wait status;
5163#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00005164#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005165 int status;
5166#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00005167#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00005168
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005169 status_i = 0;
5170 Py_BEGIN_ALLOW_THREADS
5171 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00005172 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00005173 if (pid == -1)
5174 return posix_error();
5175 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005176 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005177#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00005178}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005179#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005180
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005181
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005182PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005183"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005184Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005185
Barry Warsaw53699e91996-12-10 23:23:01 +00005186static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005187posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005188{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005189#ifdef HAVE_LSTAT
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005190 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005191#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005192#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00005193 return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005194#else
5195 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
5196#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005197#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005198}
5199
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005200
Guido van Rossumb6775db1994-08-01 11:34:53 +00005201#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005202PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005203"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005204Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005205
Barry Warsaw53699e91996-12-10 23:23:01 +00005206static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005207posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005208{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005209 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00005210 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005211 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005212 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005213 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005214 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00005215 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00005216 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005217 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00005218 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00005219 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005220}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005221#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005222
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005223
Guido van Rossumb6775db1994-08-01 11:34:53 +00005224#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005225PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005226"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00005227Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005228
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005229static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005230posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005231{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005232 return posix_2str(args, "etet:symlink", symlink, NULL, NULL);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005233}
5234#endif /* HAVE_SYMLINK */
5235
5236
5237#ifdef HAVE_TIMES
5238#ifndef HZ
5239#define HZ 60 /* Universal constant :-) */
5240#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00005241
Guido van Rossumd48f2521997-12-05 22:19:34 +00005242#if defined(PYCC_VACPP) && defined(PYOS_OS2)
5243static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005244system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005245{
5246 ULONG value = 0;
5247
5248 Py_BEGIN_ALLOW_THREADS
5249 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
5250 Py_END_ALLOW_THREADS
5251
5252 return value;
5253}
5254
5255static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005256posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005257{
Guido van Rossumd48f2521997-12-05 22:19:34 +00005258 /* Currently Only Uptime is Provided -- Others Later */
5259 return Py_BuildValue("ddddd",
5260 (double)0 /* t.tms_utime / HZ */,
5261 (double)0 /* t.tms_stime / HZ */,
5262 (double)0 /* t.tms_cutime / HZ */,
5263 (double)0 /* t.tms_cstime / HZ */,
5264 (double)system_uptime() / 1000);
5265}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005266#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00005267static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005268posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00005269{
5270 struct tms t;
5271 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +00005272 errno = 0;
5273 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00005274 if (c == (clock_t) -1)
5275 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005276 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00005277 (double)t.tms_utime / HZ,
5278 (double)t.tms_stime / HZ,
5279 (double)t.tms_cutime / HZ,
5280 (double)t.tms_cstime / HZ,
5281 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00005282}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005283#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005284#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005285
5286
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005287#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005288#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00005289static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005290posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005291{
5292 FILETIME create, exit, kernel, user;
5293 HANDLE hProc;
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005294 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00005295 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
5296 /* The fields of a FILETIME structure are the hi and lo part
5297 of a 64-bit value expressed in 100 nanosecond units.
5298 1e7 is one second in such units; 1e-7 the inverse.
5299 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
5300 */
Barry Warsaw53699e91996-12-10 23:23:01 +00005301 return Py_BuildValue(
5302 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00005303 (double)(kernel.dwHighDateTime*429.4967296 +
5304 kernel.dwLowDateTime*1e-7),
5305 (double)(user.dwHighDateTime*429.4967296 +
5306 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00005307 (double)0,
5308 (double)0,
5309 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005310}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005311#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005312
5313#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005314PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005315"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005316Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005317#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005318
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005319
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00005320#ifdef HAVE_GETSID
5321PyDoc_STRVAR(posix_getsid__doc__,
5322"getsid(pid) -> sid\n\n\
5323Call the system call getsid().");
5324
5325static PyObject *
5326posix_getsid(PyObject *self, PyObject *args)
5327{
5328 int pid, sid;
5329 if (!PyArg_ParseTuple(args, "i:getsid", &pid))
5330 return NULL;
5331 sid = getsid(pid);
5332 if (sid < 0)
5333 return posix_error();
5334 return PyInt_FromLong((long)sid);
5335}
5336#endif /* HAVE_GETSID */
5337
5338
Guido van Rossumb6775db1994-08-01 11:34:53 +00005339#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005340PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005341"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005342Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005343
Barry Warsaw53699e91996-12-10 23:23:01 +00005344static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005345posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005346{
Guido van Rossum687dd131993-05-17 08:34:16 +00005347 if (setsid() < 0)
5348 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005349 Py_INCREF(Py_None);
5350 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005351}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005352#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005353
Guido van Rossumb6775db1994-08-01 11:34:53 +00005354#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005355PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005356"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005357Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005358
Barry Warsaw53699e91996-12-10 23:23:01 +00005359static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005360posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005361{
5362 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005363 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00005364 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005365 if (setpgid(pid, pgrp) < 0)
5366 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005367 Py_INCREF(Py_None);
5368 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005369}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005370#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005371
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005372
Guido van Rossumb6775db1994-08-01 11:34:53 +00005373#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005374PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005375"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005376Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005377
Barry Warsaw53699e91996-12-10 23:23:01 +00005378static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005379posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005380{
5381 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005382 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00005383 return NULL;
5384 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005385 if (pgid < 0)
5386 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005387 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00005388}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005389#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00005390
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005391
Guido van Rossumb6775db1994-08-01 11:34:53 +00005392#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005393PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005394"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005395Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005396
Barry Warsaw53699e91996-12-10 23:23:01 +00005397static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005398posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005399{
5400 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005401 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00005402 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005403 if (tcsetpgrp(fd, pgid) < 0)
5404 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00005405 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00005406 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00005407}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005408#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00005409
Guido van Rossum687dd131993-05-17 08:34:16 +00005410/* Functions acting on file descriptors */
5411
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005412PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005413"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005414Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005415
Barry Warsaw53699e91996-12-10 23:23:01 +00005416static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005417posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005418{
Mark Hammondef8b6542001-05-13 08:04:26 +00005419 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005420 int flag;
5421 int mode = 0777;
5422 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005423
5424#ifdef MS_WINDOWS
5425 if (unicode_file_names()) {
5426 PyUnicodeObject *po;
5427 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
5428 Py_BEGIN_ALLOW_THREADS
5429 /* PyUnicode_AS_UNICODE OK without thread
5430 lock as it is a simple dereference. */
5431 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
5432 Py_END_ALLOW_THREADS
5433 if (fd < 0)
5434 return posix_error();
5435 return PyInt_FromLong((long)fd);
5436 }
5437 /* Drop the argument parsing error as narrow strings
5438 are also valid. */
5439 PyErr_Clear();
5440 }
5441#endif
5442
Tim Peters5aa91602002-01-30 05:46:57 +00005443 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00005444 Py_FileSystemDefaultEncoding, &file,
5445 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00005446 return NULL;
5447
Barry Warsaw53699e91996-12-10 23:23:01 +00005448 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005449 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005450 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005451 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00005452 return posix_error_with_allocated_filename(file);
5453 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00005454 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005455}
5456
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005457
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005458PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005459"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005460Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005461
Barry Warsaw53699e91996-12-10 23:23:01 +00005462static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005463posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005464{
5465 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005466 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005467 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005468 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005469 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00005470 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005471 if (res < 0)
5472 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005473 Py_INCREF(Py_None);
5474 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005475}
5476
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005477
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005478PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005479"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005480Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005481
Barry Warsaw53699e91996-12-10 23:23:01 +00005482static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005483posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005484{
5485 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005486 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005487 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005488 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005489 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00005490 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005491 if (fd < 0)
5492 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005493 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005494}
5495
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005496
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005497PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00005498"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005499Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005500
Barry Warsaw53699e91996-12-10 23:23:01 +00005501static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005502posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005503{
5504 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005505 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00005506 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005507 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005508 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00005509 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005510 if (res < 0)
5511 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005512 Py_INCREF(Py_None);
5513 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005514}
5515
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005516
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005517PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005518"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005519Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005520
Barry Warsaw53699e91996-12-10 23:23:01 +00005521static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005522posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005523{
5524 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005525#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005526 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005527#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00005528 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005529#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005530 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005531 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00005532 return NULL;
5533#ifdef SEEK_SET
5534 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
5535 switch (how) {
5536 case 0: how = SEEK_SET; break;
5537 case 1: how = SEEK_CUR; break;
5538 case 2: how = SEEK_END; break;
5539 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005540#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005541
5542#if !defined(HAVE_LARGEFILE_SUPPORT)
5543 pos = PyInt_AsLong(posobj);
5544#else
5545 pos = PyLong_Check(posobj) ?
5546 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
5547#endif
5548 if (PyErr_Occurred())
5549 return NULL;
5550
Barry Warsaw53699e91996-12-10 23:23:01 +00005551 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005552#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00005553 res = _lseeki64(fd, pos, how);
5554#else
Guido van Rossum687dd131993-05-17 08:34:16 +00005555 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005556#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005557 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005558 if (res < 0)
5559 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00005560
5561#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00005562 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005563#else
5564 return PyLong_FromLongLong(res);
5565#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005566}
5567
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005568
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005569PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005570"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005571Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005572
Barry Warsaw53699e91996-12-10 23:23:01 +00005573static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005574posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005575{
Guido van Rossum8bac5461996-06-11 18:38:48 +00005576 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00005577 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005578 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005579 return NULL;
Michael W. Hudson9867ced2005-01-31 17:01:59 +00005580 if (size < 0) {
5581 errno = EINVAL;
5582 return posix_error();
5583 }
Barry Warsaw53699e91996-12-10 23:23:01 +00005584 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005585 if (buffer == NULL)
5586 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005587 Py_BEGIN_ALLOW_THREADS
5588 n = read(fd, PyString_AsString(buffer), size);
5589 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00005590 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005591 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00005592 return posix_error();
5593 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00005594 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00005595 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00005596 return buffer;
5597}
5598
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005599
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005600PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005601"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005602Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005603
Barry Warsaw53699e91996-12-10 23:23:01 +00005604static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005605posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005606{
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005607 int fd;
5608 Py_ssize_t size;
Guido van Rossum687dd131993-05-17 08:34:16 +00005609 char *buffer;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005610
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005611 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005612 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005613 Py_BEGIN_ALLOW_THREADS
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005614 size = write(fd, buffer, (size_t)size);
Barry Warsaw53699e91996-12-10 23:23:01 +00005615 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005616 if (size < 0)
5617 return posix_error();
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005618 return PyInt_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005619}
5620
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005621
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005622PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005623"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005624Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005625
Barry Warsaw53699e91996-12-10 23:23:01 +00005626static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005627posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005628{
5629 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00005630 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00005631 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005632 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005633 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005634#ifdef __VMS
5635 /* on OpenVMS we must ensure that all bytes are written to the file */
5636 fsync(fd);
5637#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005638 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00005639 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00005640 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00005641 if (res != 0) {
5642#ifdef MS_WINDOWS
5643 return win32_error("fstat", NULL);
5644#else
Guido van Rossum687dd131993-05-17 08:34:16 +00005645 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00005646#endif
5647 }
Tim Peters5aa91602002-01-30 05:46:57 +00005648
Martin v. Löwis14694662006-02-03 12:54:16 +00005649 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00005650}
5651
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005652
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005653PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005654"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005655Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005656
Barry Warsaw53699e91996-12-10 23:23:01 +00005657static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005658posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005659{
Guido van Rossum687dd131993-05-17 08:34:16 +00005660 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005661 char *mode = "r";
5662 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00005663 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00005664 PyObject *f;
5665 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00005666 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00005667
Thomas Heller1f043e22002-11-07 16:00:59 +00005668 if (mode[0] != 'r' && mode[0] != 'w' && mode[0] != 'a') {
5669 PyErr_Format(PyExc_ValueError,
5670 "invalid file mode '%s'", mode);
5671 return NULL;
5672 }
5673
Barry Warsaw53699e91996-12-10 23:23:01 +00005674 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005675 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005676 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005677 if (fp == NULL)
5678 return posix_error();
Guido van Rossumbd6be7a2002-09-15 18:45:46 +00005679 f = PyFile_FromFile(fp, "<fdopen>", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005680 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00005681 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005682 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00005683}
5684
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005685PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005686"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005687Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005688connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00005689
5690static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00005691posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00005692{
5693 int fd;
5694 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
5695 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005696 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00005697}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005698
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005699#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005700PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005701"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005702Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005703
Barry Warsaw53699e91996-12-10 23:23:01 +00005704static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005705posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00005706{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005707#if defined(PYOS_OS2)
5708 HFILE read, write;
5709 APIRET rc;
5710
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005711 Py_BEGIN_ALLOW_THREADS
5712 rc = DosCreatePipe( &read, &write, 4096);
5713 Py_END_ALLOW_THREADS
5714 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005715 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005716
5717 return Py_BuildValue("(ii)", read, write);
5718#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005719#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00005720 int fds[2];
5721 int res;
Barry Warsaw53699e91996-12-10 23:23:01 +00005722 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005723 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00005724 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005725 if (res != 0)
5726 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005727 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005728#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00005729 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005730 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00005731 BOOL ok;
Barry Warsaw53699e91996-12-10 23:23:01 +00005732 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005733 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00005734 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00005735 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005736 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00005737 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
5738 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005739 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005740#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005741#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005742}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005743#endif /* HAVE_PIPE */
5744
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005745
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005746#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005747PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005748"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005749Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005750
Barry Warsaw53699e91996-12-10 23:23:01 +00005751static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005752posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005753{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005754 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005755 int mode = 0666;
5756 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005757 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005758 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005759 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005760 res = mkfifo(filename, mode);
5761 Py_END_ALLOW_THREADS
5762 if (res < 0)
5763 return posix_error();
5764 Py_INCREF(Py_None);
5765 return Py_None;
5766}
5767#endif
5768
5769
Neal Norwitz11690112002-07-30 01:08:28 +00005770#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005771PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005772"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005773Create a filesystem node (file, device special file or named pipe)\n\
5774named filename. mode specifies both the permissions to use and the\n\
5775type of node to be created, being combined (bitwise OR) with one of\n\
5776S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005777device defines the newly created device special file (probably using\n\
5778os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005779
5780
5781static PyObject *
5782posix_mknod(PyObject *self, PyObject *args)
5783{
5784 char *filename;
5785 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005786 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005787 int res;
Martin v. Löwisd631ebe2002-11-02 17:42:33 +00005788 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005789 return NULL;
5790 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005791 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00005792 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005793 if (res < 0)
5794 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005795 Py_INCREF(Py_None);
5796 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005797}
5798#endif
5799
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005800#ifdef HAVE_DEVICE_MACROS
5801PyDoc_STRVAR(posix_major__doc__,
5802"major(device) -> major number\n\
5803Extracts a device major number from a raw device number.");
5804
5805static PyObject *
5806posix_major(PyObject *self, PyObject *args)
5807{
5808 int device;
5809 if (!PyArg_ParseTuple(args, "i:major", &device))
5810 return NULL;
5811 return PyInt_FromLong((long)major(device));
5812}
5813
5814PyDoc_STRVAR(posix_minor__doc__,
5815"minor(device) -> minor number\n\
5816Extracts a device minor number from a raw device number.");
5817
5818static PyObject *
5819posix_minor(PyObject *self, PyObject *args)
5820{
5821 int device;
5822 if (!PyArg_ParseTuple(args, "i:minor", &device))
5823 return NULL;
5824 return PyInt_FromLong((long)minor(device));
5825}
5826
5827PyDoc_STRVAR(posix_makedev__doc__,
5828"makedev(major, minor) -> device number\n\
5829Composes a raw device number from the major and minor device numbers.");
5830
5831static PyObject *
5832posix_makedev(PyObject *self, PyObject *args)
5833{
5834 int major, minor;
5835 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
5836 return NULL;
5837 return PyInt_FromLong((long)makedev(major, minor));
5838}
5839#endif /* device macros */
5840
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005841
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005842#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005843PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005844"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005845Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005846
Barry Warsaw53699e91996-12-10 23:23:01 +00005847static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005848posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005849{
5850 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005851 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005852 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005853 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005854
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005855 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005856 return NULL;
5857
5858#if !defined(HAVE_LARGEFILE_SUPPORT)
5859 length = PyInt_AsLong(lenobj);
5860#else
5861 length = PyLong_Check(lenobj) ?
5862 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
5863#endif
5864 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005865 return NULL;
5866
Barry Warsaw53699e91996-12-10 23:23:01 +00005867 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005868 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00005869 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005870 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005871 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005872 return NULL;
5873 }
Barry Warsaw53699e91996-12-10 23:23:01 +00005874 Py_INCREF(Py_None);
5875 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005876}
5877#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005878
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005879#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005880PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005881"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005882Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005883
Fred Drake762e2061999-08-26 17:23:54 +00005884/* Save putenv() parameters as values here, so we can collect them when they
5885 * get re-set with another call for the same key. */
5886static PyObject *posix_putenv_garbage;
5887
Tim Peters5aa91602002-01-30 05:46:57 +00005888static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005889posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005890{
5891 char *s1, *s2;
5892 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00005893 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00005894 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005895
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005896 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005897 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00005898
5899#if defined(PYOS_OS2)
5900 if (stricmp(s1, "BEGINLIBPATH") == 0) {
5901 APIRET rc;
5902
Guido van Rossumd48f2521997-12-05 22:19:34 +00005903 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
5904 if (rc != NO_ERROR)
5905 return os2_error(rc);
5906
5907 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
5908 APIRET rc;
5909
Guido van Rossumd48f2521997-12-05 22:19:34 +00005910 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
5911 if (rc != NO_ERROR)
5912 return os2_error(rc);
5913 } else {
5914#endif
5915
Fred Drake762e2061999-08-26 17:23:54 +00005916 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00005917 len = strlen(s1) + strlen(s2) + 2;
5918 /* len includes space for a trailing \0; the size arg to
5919 PyString_FromStringAndSize does not count that */
5920 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00005921 if (newstr == NULL)
5922 return PyErr_NoMemory();
5923 new = PyString_AS_STRING(newstr);
Tim Petersc8996f52001-12-03 20:41:00 +00005924 PyOS_snprintf(new, len, "%s=%s", s1, s2);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005925 if (putenv(new)) {
Neal Norwitz4adc9ab2003-02-10 03:10:43 +00005926 Py_DECREF(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005927 posix_error();
5928 return NULL;
5929 }
Fred Drake762e2061999-08-26 17:23:54 +00005930 /* Install the first arg and newstr in posix_putenv_garbage;
5931 * this will cause previous value to be collected. This has to
5932 * happen after the real putenv() call because the old value
5933 * was still accessible until then. */
5934 if (PyDict_SetItem(posix_putenv_garbage,
5935 PyTuple_GET_ITEM(args, 0), newstr)) {
5936 /* really not much we can do; just leak */
5937 PyErr_Clear();
5938 }
5939 else {
5940 Py_DECREF(newstr);
5941 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005942
5943#if defined(PYOS_OS2)
5944 }
5945#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005946 Py_INCREF(Py_None);
5947 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005948}
Guido van Rossumb6a47161997-09-15 22:54:34 +00005949#endif /* putenv */
5950
Guido van Rossumc524d952001-10-19 01:31:59 +00005951#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005952PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005953"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005954Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00005955
5956static PyObject *
5957posix_unsetenv(PyObject *self, PyObject *args)
5958{
5959 char *s1;
5960
5961 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
5962 return NULL;
5963
5964 unsetenv(s1);
5965
5966 /* Remove the key from posix_putenv_garbage;
5967 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00005968 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00005969 * old value was still accessible until then.
5970 */
5971 if (PyDict_DelItem(posix_putenv_garbage,
5972 PyTuple_GET_ITEM(args, 0))) {
5973 /* really not much we can do; just leak */
5974 PyErr_Clear();
5975 }
5976
5977 Py_INCREF(Py_None);
5978 return Py_None;
5979}
5980#endif /* unsetenv */
5981
Guido van Rossumb6a47161997-09-15 22:54:34 +00005982#ifdef HAVE_STRERROR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005983PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005984"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005985Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005986
Guido van Rossumf68d8e52001-04-14 17:55:09 +00005987static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005988posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00005989{
5990 int code;
5991 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005992 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00005993 return NULL;
5994 message = strerror(code);
5995 if (message == NULL) {
5996 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00005997 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005998 return NULL;
5999 }
6000 return PyString_FromString(message);
6001}
6002#endif /* strerror */
6003
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006004
Guido van Rossumc9641791998-08-04 15:26:23 +00006005#ifdef HAVE_SYS_WAIT_H
6006
Fred Drake106c1a02002-04-23 15:58:02 +00006007#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006008PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006009"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006010Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00006011
6012static PyObject *
6013posix_WCOREDUMP(PyObject *self, PyObject *args)
6014{
6015#ifdef UNION_WAIT
6016 union wait status;
6017#define status_i (status.w_status)
6018#else
6019 int status;
6020#define status_i status
6021#endif
6022 status_i = 0;
6023
6024 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &status_i))
6025 {
6026 return NULL;
6027 }
6028
6029 return PyBool_FromLong(WCOREDUMP(status));
6030#undef status_i
6031}
6032#endif /* WCOREDUMP */
6033
6034#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006035PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006036"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006037Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006038job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00006039
6040static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006041posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00006042{
6043#ifdef UNION_WAIT
6044 union wait status;
6045#define status_i (status.w_status)
6046#else
6047 int status;
6048#define status_i status
6049#endif
6050 status_i = 0;
6051
6052 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &status_i))
6053 {
6054 return NULL;
6055 }
6056
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006057 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006058#undef status_i
6059}
6060#endif /* WIFCONTINUED */
6061
Guido van Rossumc9641791998-08-04 15:26:23 +00006062#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006063PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006064"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006065Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006066
6067static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006068posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006069{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006070#ifdef UNION_WAIT
6071 union wait status;
6072#define status_i (status.w_status)
6073#else
6074 int status;
6075#define status_i status
6076#endif
6077 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006078
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006079 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00006080 {
6081 return NULL;
6082 }
Tim Peters5aa91602002-01-30 05:46:57 +00006083
Fred Drake106c1a02002-04-23 15:58:02 +00006084 return PyBool_FromLong(WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006085#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00006086}
6087#endif /* WIFSTOPPED */
6088
6089#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006090PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006091"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006092Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006093
6094static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006095posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006096{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006097#ifdef UNION_WAIT
6098 union wait status;
6099#define status_i (status.w_status)
6100#else
6101 int status;
6102#define status_i status
6103#endif
6104 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006105
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006106 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00006107 {
6108 return NULL;
6109 }
Tim Peters5aa91602002-01-30 05:46:57 +00006110
Fred Drake106c1a02002-04-23 15:58:02 +00006111 return PyBool_FromLong(WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006112#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00006113}
6114#endif /* WIFSIGNALED */
6115
6116#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006117PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006118"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006119Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006120system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006121
6122static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006123posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006124{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006125#ifdef UNION_WAIT
6126 union wait status;
6127#define status_i (status.w_status)
6128#else
6129 int status;
6130#define status_i status
6131#endif
6132 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006133
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006134 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00006135 {
6136 return NULL;
6137 }
Tim Peters5aa91602002-01-30 05:46:57 +00006138
Fred Drake106c1a02002-04-23 15:58:02 +00006139 return PyBool_FromLong(WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006140#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00006141}
6142#endif /* WIFEXITED */
6143
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006144#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006145PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006146"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006147Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006148
6149static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006150posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006151{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006152#ifdef UNION_WAIT
6153 union wait status;
6154#define status_i (status.w_status)
6155#else
6156 int status;
6157#define status_i status
6158#endif
6159 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006160
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006161 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00006162 {
6163 return NULL;
6164 }
Tim Peters5aa91602002-01-30 05:46:57 +00006165
Guido van Rossumc9641791998-08-04 15:26:23 +00006166 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006167#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00006168}
6169#endif /* WEXITSTATUS */
6170
6171#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006172PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006173"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006174Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006175value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006176
6177static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006178posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006179{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006180#ifdef UNION_WAIT
6181 union wait status;
6182#define status_i (status.w_status)
6183#else
6184 int status;
6185#define status_i status
6186#endif
6187 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006188
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006189 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00006190 {
6191 return NULL;
6192 }
Tim Peters5aa91602002-01-30 05:46:57 +00006193
Guido van Rossumc9641791998-08-04 15:26:23 +00006194 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006195#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00006196}
6197#endif /* WTERMSIG */
6198
6199#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006200PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006201"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006202Return the signal that stopped the process that provided\n\
6203the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006204
6205static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006206posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006207{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006208#ifdef UNION_WAIT
6209 union wait status;
6210#define status_i (status.w_status)
6211#else
6212 int status;
6213#define status_i status
6214#endif
6215 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006216
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006217 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00006218 {
6219 return NULL;
6220 }
Tim Peters5aa91602002-01-30 05:46:57 +00006221
Guido van Rossumc9641791998-08-04 15:26:23 +00006222 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006223#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00006224}
6225#endif /* WSTOPSIG */
6226
6227#endif /* HAVE_SYS_WAIT_H */
6228
6229
Guido van Rossum94f6f721999-01-06 18:42:14 +00006230#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00006231#ifdef _SCO_DS
6232/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
6233 needed definitions in sys/statvfs.h */
6234#define _SVID3
6235#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006236#include <sys/statvfs.h>
6237
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006238static PyObject*
6239_pystatvfs_fromstructstatvfs(struct statvfs st) {
6240 PyObject *v = PyStructSequence_New(&StatVFSResultType);
6241 if (v == NULL)
6242 return NULL;
6243
6244#if !defined(HAVE_LARGEFILE_SUPPORT)
6245 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6246 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
6247 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
6248 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
6249 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
6250 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
6251 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
6252 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
6253 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6254 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6255#else
6256 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6257 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00006258 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006259 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00006260 PyStructSequence_SET_ITEM(v, 3,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006261 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006262 PyStructSequence_SET_ITEM(v, 4,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006263 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00006264 PyStructSequence_SET_ITEM(v, 5,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006265 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00006266 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006267 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00006268 PyStructSequence_SET_ITEM(v, 7,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006269 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006270 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6271 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6272#endif
6273
6274 return v;
6275}
6276
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006277PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006278"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006279Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006280
6281static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006282posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006283{
6284 int fd, res;
6285 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006286
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006287 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006288 return NULL;
6289 Py_BEGIN_ALLOW_THREADS
6290 res = fstatvfs(fd, &st);
6291 Py_END_ALLOW_THREADS
6292 if (res != 0)
6293 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006294
6295 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006296}
6297#endif /* HAVE_FSTATVFS */
6298
6299
6300#if defined(HAVE_STATVFS)
6301#include <sys/statvfs.h>
6302
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006303PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006304"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006305Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006306
6307static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006308posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006309{
6310 char *path;
6311 int res;
6312 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006313 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006314 return NULL;
6315 Py_BEGIN_ALLOW_THREADS
6316 res = statvfs(path, &st);
6317 Py_END_ALLOW_THREADS
6318 if (res != 0)
6319 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006320
6321 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006322}
6323#endif /* HAVE_STATVFS */
6324
6325
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006326#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006327PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006328"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006329Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00006330The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006331or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006332
6333static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006334posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006335{
6336 PyObject *result = NULL;
6337 char *dir = NULL;
6338 char *pfx = NULL;
6339 char *name;
6340
6341 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
6342 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00006343
6344 if (PyErr_Warn(PyExc_RuntimeWarning,
6345 "tempnam is a potential security risk to your program") < 0)
6346 return NULL;
6347
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006348#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00006349 name = _tempnam(dir, pfx);
6350#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006351 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00006352#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006353 if (name == NULL)
6354 return PyErr_NoMemory();
6355 result = PyString_FromString(name);
6356 free(name);
6357 return result;
6358}
Guido van Rossumd371ff11999-01-25 16:12:23 +00006359#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006360
6361
6362#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006363PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006364"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006365Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006366
6367static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006368posix_tmpfile(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006369{
6370 FILE *fp;
6371
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006372 fp = tmpfile();
6373 if (fp == NULL)
6374 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00006375 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006376}
6377#endif
6378
6379
6380#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006381PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006382"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006383Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006384
6385static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006386posix_tmpnam(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006387{
6388 char buffer[L_tmpnam];
6389 char *name;
6390
Skip Montanaro95618b52001-08-18 18:52:10 +00006391 if (PyErr_Warn(PyExc_RuntimeWarning,
6392 "tmpnam is a potential security risk to your program") < 0)
6393 return NULL;
6394
Greg Wardb48bc172000-03-01 21:51:56 +00006395#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006396 name = tmpnam_r(buffer);
6397#else
6398 name = tmpnam(buffer);
6399#endif
6400 if (name == NULL) {
6401 PyErr_SetObject(PyExc_OSError,
6402 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00006403#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006404 "unexpected NULL from tmpnam_r"
6405#else
6406 "unexpected NULL from tmpnam"
6407#endif
6408 ));
6409 return NULL;
6410 }
6411 return PyString_FromString(buffer);
6412}
6413#endif
6414
6415
Fred Drakec9680921999-12-13 16:37:25 +00006416/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
6417 * It maps strings representing configuration variable names to
6418 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00006419 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00006420 * rarely-used constants. There are three separate tables that use
6421 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00006422 *
6423 * This code is always included, even if none of the interfaces that
6424 * need it are included. The #if hackery needed to avoid it would be
6425 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00006426 */
6427struct constdef {
6428 char *name;
6429 long value;
6430};
6431
Fred Drake12c6e2d1999-12-14 21:25:03 +00006432static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006433conv_confname(PyObject *arg, int *valuep, struct constdef *table,
6434 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006435{
6436 if (PyInt_Check(arg)) {
6437 *valuep = PyInt_AS_LONG(arg);
6438 return 1;
6439 }
6440 if (PyString_Check(arg)) {
6441 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00006442 size_t lo = 0;
6443 size_t mid;
6444 size_t hi = tablesize;
6445 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006446 char *confname = PyString_AS_STRING(arg);
6447 while (lo < hi) {
6448 mid = (lo + hi) / 2;
6449 cmp = strcmp(confname, table[mid].name);
6450 if (cmp < 0)
6451 hi = mid;
6452 else if (cmp > 0)
6453 lo = mid + 1;
6454 else {
6455 *valuep = table[mid].value;
6456 return 1;
6457 }
6458 }
6459 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
6460 }
6461 else
6462 PyErr_SetString(PyExc_TypeError,
6463 "configuration names must be strings or integers");
6464 return 0;
6465}
6466
6467
6468#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
6469static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006470#ifdef _PC_ABI_AIO_XFER_MAX
6471 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
6472#endif
6473#ifdef _PC_ABI_ASYNC_IO
6474 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
6475#endif
Fred Drakec9680921999-12-13 16:37:25 +00006476#ifdef _PC_ASYNC_IO
6477 {"PC_ASYNC_IO", _PC_ASYNC_IO},
6478#endif
6479#ifdef _PC_CHOWN_RESTRICTED
6480 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
6481#endif
6482#ifdef _PC_FILESIZEBITS
6483 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
6484#endif
6485#ifdef _PC_LAST
6486 {"PC_LAST", _PC_LAST},
6487#endif
6488#ifdef _PC_LINK_MAX
6489 {"PC_LINK_MAX", _PC_LINK_MAX},
6490#endif
6491#ifdef _PC_MAX_CANON
6492 {"PC_MAX_CANON", _PC_MAX_CANON},
6493#endif
6494#ifdef _PC_MAX_INPUT
6495 {"PC_MAX_INPUT", _PC_MAX_INPUT},
6496#endif
6497#ifdef _PC_NAME_MAX
6498 {"PC_NAME_MAX", _PC_NAME_MAX},
6499#endif
6500#ifdef _PC_NO_TRUNC
6501 {"PC_NO_TRUNC", _PC_NO_TRUNC},
6502#endif
6503#ifdef _PC_PATH_MAX
6504 {"PC_PATH_MAX", _PC_PATH_MAX},
6505#endif
6506#ifdef _PC_PIPE_BUF
6507 {"PC_PIPE_BUF", _PC_PIPE_BUF},
6508#endif
6509#ifdef _PC_PRIO_IO
6510 {"PC_PRIO_IO", _PC_PRIO_IO},
6511#endif
6512#ifdef _PC_SOCK_MAXBUF
6513 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
6514#endif
6515#ifdef _PC_SYNC_IO
6516 {"PC_SYNC_IO", _PC_SYNC_IO},
6517#endif
6518#ifdef _PC_VDISABLE
6519 {"PC_VDISABLE", _PC_VDISABLE},
6520#endif
6521};
6522
Fred Drakec9680921999-12-13 16:37:25 +00006523static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006524conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006525{
6526 return conv_confname(arg, valuep, posix_constants_pathconf,
6527 sizeof(posix_constants_pathconf)
6528 / sizeof(struct constdef));
6529}
6530#endif
6531
6532#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006533PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006534"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006535Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006536If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006537
6538static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006539posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006540{
6541 PyObject *result = NULL;
6542 int name, fd;
6543
Fred Drake12c6e2d1999-12-14 21:25:03 +00006544 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
6545 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00006546 long limit;
6547
6548 errno = 0;
6549 limit = fpathconf(fd, name);
6550 if (limit == -1 && errno != 0)
6551 posix_error();
6552 else
6553 result = PyInt_FromLong(limit);
6554 }
6555 return result;
6556}
6557#endif
6558
6559
6560#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006561PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006562"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006563Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006564If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006565
6566static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006567posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006568{
6569 PyObject *result = NULL;
6570 int name;
6571 char *path;
6572
6573 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
6574 conv_path_confname, &name)) {
6575 long limit;
6576
6577 errno = 0;
6578 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006579 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00006580 if (errno == EINVAL)
6581 /* could be a path or name problem */
6582 posix_error();
6583 else
6584 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006585 }
Fred Drakec9680921999-12-13 16:37:25 +00006586 else
6587 result = PyInt_FromLong(limit);
6588 }
6589 return result;
6590}
6591#endif
6592
6593#ifdef HAVE_CONFSTR
6594static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006595#ifdef _CS_ARCHITECTURE
6596 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
6597#endif
6598#ifdef _CS_HOSTNAME
6599 {"CS_HOSTNAME", _CS_HOSTNAME},
6600#endif
6601#ifdef _CS_HW_PROVIDER
6602 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
6603#endif
6604#ifdef _CS_HW_SERIAL
6605 {"CS_HW_SERIAL", _CS_HW_SERIAL},
6606#endif
6607#ifdef _CS_INITTAB_NAME
6608 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
6609#endif
Fred Drakec9680921999-12-13 16:37:25 +00006610#ifdef _CS_LFS64_CFLAGS
6611 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
6612#endif
6613#ifdef _CS_LFS64_LDFLAGS
6614 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
6615#endif
6616#ifdef _CS_LFS64_LIBS
6617 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
6618#endif
6619#ifdef _CS_LFS64_LINTFLAGS
6620 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
6621#endif
6622#ifdef _CS_LFS_CFLAGS
6623 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
6624#endif
6625#ifdef _CS_LFS_LDFLAGS
6626 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
6627#endif
6628#ifdef _CS_LFS_LIBS
6629 {"CS_LFS_LIBS", _CS_LFS_LIBS},
6630#endif
6631#ifdef _CS_LFS_LINTFLAGS
6632 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
6633#endif
Fred Draked86ed291999-12-15 15:34:33 +00006634#ifdef _CS_MACHINE
6635 {"CS_MACHINE", _CS_MACHINE},
6636#endif
Fred Drakec9680921999-12-13 16:37:25 +00006637#ifdef _CS_PATH
6638 {"CS_PATH", _CS_PATH},
6639#endif
Fred Draked86ed291999-12-15 15:34:33 +00006640#ifdef _CS_RELEASE
6641 {"CS_RELEASE", _CS_RELEASE},
6642#endif
6643#ifdef _CS_SRPC_DOMAIN
6644 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
6645#endif
6646#ifdef _CS_SYSNAME
6647 {"CS_SYSNAME", _CS_SYSNAME},
6648#endif
6649#ifdef _CS_VERSION
6650 {"CS_VERSION", _CS_VERSION},
6651#endif
Fred Drakec9680921999-12-13 16:37:25 +00006652#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
6653 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
6654#endif
6655#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
6656 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
6657#endif
6658#ifdef _CS_XBS5_ILP32_OFF32_LIBS
6659 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
6660#endif
6661#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
6662 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
6663#endif
6664#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
6665 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
6666#endif
6667#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
6668 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
6669#endif
6670#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
6671 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
6672#endif
6673#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
6674 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
6675#endif
6676#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
6677 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
6678#endif
6679#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
6680 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
6681#endif
6682#ifdef _CS_XBS5_LP64_OFF64_LIBS
6683 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
6684#endif
6685#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
6686 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
6687#endif
6688#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
6689 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
6690#endif
6691#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
6692 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
6693#endif
6694#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
6695 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
6696#endif
6697#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
6698 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
6699#endif
Fred Draked86ed291999-12-15 15:34:33 +00006700#ifdef _MIPS_CS_AVAIL_PROCESSORS
6701 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
6702#endif
6703#ifdef _MIPS_CS_BASE
6704 {"MIPS_CS_BASE", _MIPS_CS_BASE},
6705#endif
6706#ifdef _MIPS_CS_HOSTID
6707 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
6708#endif
6709#ifdef _MIPS_CS_HW_NAME
6710 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
6711#endif
6712#ifdef _MIPS_CS_NUM_PROCESSORS
6713 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
6714#endif
6715#ifdef _MIPS_CS_OSREL_MAJ
6716 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
6717#endif
6718#ifdef _MIPS_CS_OSREL_MIN
6719 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
6720#endif
6721#ifdef _MIPS_CS_OSREL_PATCH
6722 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
6723#endif
6724#ifdef _MIPS_CS_OS_NAME
6725 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
6726#endif
6727#ifdef _MIPS_CS_OS_PROVIDER
6728 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
6729#endif
6730#ifdef _MIPS_CS_PROCESSORS
6731 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
6732#endif
6733#ifdef _MIPS_CS_SERIAL
6734 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
6735#endif
6736#ifdef _MIPS_CS_VENDOR
6737 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
6738#endif
Fred Drakec9680921999-12-13 16:37:25 +00006739};
6740
6741static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006742conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006743{
6744 return conv_confname(arg, valuep, posix_constants_confstr,
6745 sizeof(posix_constants_confstr)
6746 / sizeof(struct constdef));
6747}
6748
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006749PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006750"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006751Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006752
6753static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006754posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006755{
6756 PyObject *result = NULL;
6757 int name;
6758 char buffer[64];
6759
6760 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
6761 int len = confstr(name, buffer, sizeof(buffer));
6762
Fred Drakec9680921999-12-13 16:37:25 +00006763 errno = 0;
6764 if (len == 0) {
6765 if (errno != 0)
6766 posix_error();
6767 else
6768 result = PyString_FromString("");
6769 }
6770 else {
6771 if (len >= sizeof(buffer)) {
6772 result = PyString_FromStringAndSize(NULL, len);
6773 if (result != NULL)
6774 confstr(name, PyString_AS_STRING(result), len+1);
6775 }
6776 else
6777 result = PyString_FromString(buffer);
6778 }
6779 }
6780 return result;
6781}
6782#endif
6783
6784
6785#ifdef HAVE_SYSCONF
6786static struct constdef posix_constants_sysconf[] = {
6787#ifdef _SC_2_CHAR_TERM
6788 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
6789#endif
6790#ifdef _SC_2_C_BIND
6791 {"SC_2_C_BIND", _SC_2_C_BIND},
6792#endif
6793#ifdef _SC_2_C_DEV
6794 {"SC_2_C_DEV", _SC_2_C_DEV},
6795#endif
6796#ifdef _SC_2_C_VERSION
6797 {"SC_2_C_VERSION", _SC_2_C_VERSION},
6798#endif
6799#ifdef _SC_2_FORT_DEV
6800 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
6801#endif
6802#ifdef _SC_2_FORT_RUN
6803 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
6804#endif
6805#ifdef _SC_2_LOCALEDEF
6806 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
6807#endif
6808#ifdef _SC_2_SW_DEV
6809 {"SC_2_SW_DEV", _SC_2_SW_DEV},
6810#endif
6811#ifdef _SC_2_UPE
6812 {"SC_2_UPE", _SC_2_UPE},
6813#endif
6814#ifdef _SC_2_VERSION
6815 {"SC_2_VERSION", _SC_2_VERSION},
6816#endif
Fred Draked86ed291999-12-15 15:34:33 +00006817#ifdef _SC_ABI_ASYNCHRONOUS_IO
6818 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
6819#endif
6820#ifdef _SC_ACL
6821 {"SC_ACL", _SC_ACL},
6822#endif
Fred Drakec9680921999-12-13 16:37:25 +00006823#ifdef _SC_AIO_LISTIO_MAX
6824 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
6825#endif
Fred Drakec9680921999-12-13 16:37:25 +00006826#ifdef _SC_AIO_MAX
6827 {"SC_AIO_MAX", _SC_AIO_MAX},
6828#endif
6829#ifdef _SC_AIO_PRIO_DELTA_MAX
6830 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
6831#endif
6832#ifdef _SC_ARG_MAX
6833 {"SC_ARG_MAX", _SC_ARG_MAX},
6834#endif
6835#ifdef _SC_ASYNCHRONOUS_IO
6836 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
6837#endif
6838#ifdef _SC_ATEXIT_MAX
6839 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
6840#endif
Fred Draked86ed291999-12-15 15:34:33 +00006841#ifdef _SC_AUDIT
6842 {"SC_AUDIT", _SC_AUDIT},
6843#endif
Fred Drakec9680921999-12-13 16:37:25 +00006844#ifdef _SC_AVPHYS_PAGES
6845 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
6846#endif
6847#ifdef _SC_BC_BASE_MAX
6848 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
6849#endif
6850#ifdef _SC_BC_DIM_MAX
6851 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
6852#endif
6853#ifdef _SC_BC_SCALE_MAX
6854 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
6855#endif
6856#ifdef _SC_BC_STRING_MAX
6857 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
6858#endif
Fred Draked86ed291999-12-15 15:34:33 +00006859#ifdef _SC_CAP
6860 {"SC_CAP", _SC_CAP},
6861#endif
Fred Drakec9680921999-12-13 16:37:25 +00006862#ifdef _SC_CHARCLASS_NAME_MAX
6863 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
6864#endif
6865#ifdef _SC_CHAR_BIT
6866 {"SC_CHAR_BIT", _SC_CHAR_BIT},
6867#endif
6868#ifdef _SC_CHAR_MAX
6869 {"SC_CHAR_MAX", _SC_CHAR_MAX},
6870#endif
6871#ifdef _SC_CHAR_MIN
6872 {"SC_CHAR_MIN", _SC_CHAR_MIN},
6873#endif
6874#ifdef _SC_CHILD_MAX
6875 {"SC_CHILD_MAX", _SC_CHILD_MAX},
6876#endif
6877#ifdef _SC_CLK_TCK
6878 {"SC_CLK_TCK", _SC_CLK_TCK},
6879#endif
6880#ifdef _SC_COHER_BLKSZ
6881 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
6882#endif
6883#ifdef _SC_COLL_WEIGHTS_MAX
6884 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
6885#endif
6886#ifdef _SC_DCACHE_ASSOC
6887 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
6888#endif
6889#ifdef _SC_DCACHE_BLKSZ
6890 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
6891#endif
6892#ifdef _SC_DCACHE_LINESZ
6893 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
6894#endif
6895#ifdef _SC_DCACHE_SZ
6896 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
6897#endif
6898#ifdef _SC_DCACHE_TBLKSZ
6899 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
6900#endif
6901#ifdef _SC_DELAYTIMER_MAX
6902 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
6903#endif
6904#ifdef _SC_EQUIV_CLASS_MAX
6905 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
6906#endif
6907#ifdef _SC_EXPR_NEST_MAX
6908 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
6909#endif
6910#ifdef _SC_FSYNC
6911 {"SC_FSYNC", _SC_FSYNC},
6912#endif
6913#ifdef _SC_GETGR_R_SIZE_MAX
6914 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
6915#endif
6916#ifdef _SC_GETPW_R_SIZE_MAX
6917 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
6918#endif
6919#ifdef _SC_ICACHE_ASSOC
6920 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
6921#endif
6922#ifdef _SC_ICACHE_BLKSZ
6923 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
6924#endif
6925#ifdef _SC_ICACHE_LINESZ
6926 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
6927#endif
6928#ifdef _SC_ICACHE_SZ
6929 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
6930#endif
Fred Draked86ed291999-12-15 15:34:33 +00006931#ifdef _SC_INF
6932 {"SC_INF", _SC_INF},
6933#endif
Fred Drakec9680921999-12-13 16:37:25 +00006934#ifdef _SC_INT_MAX
6935 {"SC_INT_MAX", _SC_INT_MAX},
6936#endif
6937#ifdef _SC_INT_MIN
6938 {"SC_INT_MIN", _SC_INT_MIN},
6939#endif
6940#ifdef _SC_IOV_MAX
6941 {"SC_IOV_MAX", _SC_IOV_MAX},
6942#endif
Fred Draked86ed291999-12-15 15:34:33 +00006943#ifdef _SC_IP_SECOPTS
6944 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
6945#endif
Fred Drakec9680921999-12-13 16:37:25 +00006946#ifdef _SC_JOB_CONTROL
6947 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
6948#endif
Fred Draked86ed291999-12-15 15:34:33 +00006949#ifdef _SC_KERN_POINTERS
6950 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
6951#endif
6952#ifdef _SC_KERN_SIM
6953 {"SC_KERN_SIM", _SC_KERN_SIM},
6954#endif
Fred Drakec9680921999-12-13 16:37:25 +00006955#ifdef _SC_LINE_MAX
6956 {"SC_LINE_MAX", _SC_LINE_MAX},
6957#endif
6958#ifdef _SC_LOGIN_NAME_MAX
6959 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
6960#endif
6961#ifdef _SC_LOGNAME_MAX
6962 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
6963#endif
6964#ifdef _SC_LONG_BIT
6965 {"SC_LONG_BIT", _SC_LONG_BIT},
6966#endif
Fred Draked86ed291999-12-15 15:34:33 +00006967#ifdef _SC_MAC
6968 {"SC_MAC", _SC_MAC},
6969#endif
Fred Drakec9680921999-12-13 16:37:25 +00006970#ifdef _SC_MAPPED_FILES
6971 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
6972#endif
6973#ifdef _SC_MAXPID
6974 {"SC_MAXPID", _SC_MAXPID},
6975#endif
6976#ifdef _SC_MB_LEN_MAX
6977 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
6978#endif
6979#ifdef _SC_MEMLOCK
6980 {"SC_MEMLOCK", _SC_MEMLOCK},
6981#endif
6982#ifdef _SC_MEMLOCK_RANGE
6983 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
6984#endif
6985#ifdef _SC_MEMORY_PROTECTION
6986 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
6987#endif
6988#ifdef _SC_MESSAGE_PASSING
6989 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
6990#endif
Fred Draked86ed291999-12-15 15:34:33 +00006991#ifdef _SC_MMAP_FIXED_ALIGNMENT
6992 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
6993#endif
Fred Drakec9680921999-12-13 16:37:25 +00006994#ifdef _SC_MQ_OPEN_MAX
6995 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
6996#endif
6997#ifdef _SC_MQ_PRIO_MAX
6998 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
6999#endif
Fred Draked86ed291999-12-15 15:34:33 +00007000#ifdef _SC_NACLS_MAX
7001 {"SC_NACLS_MAX", _SC_NACLS_MAX},
7002#endif
Fred Drakec9680921999-12-13 16:37:25 +00007003#ifdef _SC_NGROUPS_MAX
7004 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
7005#endif
7006#ifdef _SC_NL_ARGMAX
7007 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
7008#endif
7009#ifdef _SC_NL_LANGMAX
7010 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
7011#endif
7012#ifdef _SC_NL_MSGMAX
7013 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
7014#endif
7015#ifdef _SC_NL_NMAX
7016 {"SC_NL_NMAX", _SC_NL_NMAX},
7017#endif
7018#ifdef _SC_NL_SETMAX
7019 {"SC_NL_SETMAX", _SC_NL_SETMAX},
7020#endif
7021#ifdef _SC_NL_TEXTMAX
7022 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
7023#endif
7024#ifdef _SC_NPROCESSORS_CONF
7025 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
7026#endif
7027#ifdef _SC_NPROCESSORS_ONLN
7028 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
7029#endif
Fred Draked86ed291999-12-15 15:34:33 +00007030#ifdef _SC_NPROC_CONF
7031 {"SC_NPROC_CONF", _SC_NPROC_CONF},
7032#endif
7033#ifdef _SC_NPROC_ONLN
7034 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
7035#endif
Fred Drakec9680921999-12-13 16:37:25 +00007036#ifdef _SC_NZERO
7037 {"SC_NZERO", _SC_NZERO},
7038#endif
7039#ifdef _SC_OPEN_MAX
7040 {"SC_OPEN_MAX", _SC_OPEN_MAX},
7041#endif
7042#ifdef _SC_PAGESIZE
7043 {"SC_PAGESIZE", _SC_PAGESIZE},
7044#endif
7045#ifdef _SC_PAGE_SIZE
7046 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
7047#endif
7048#ifdef _SC_PASS_MAX
7049 {"SC_PASS_MAX", _SC_PASS_MAX},
7050#endif
7051#ifdef _SC_PHYS_PAGES
7052 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
7053#endif
7054#ifdef _SC_PII
7055 {"SC_PII", _SC_PII},
7056#endif
7057#ifdef _SC_PII_INTERNET
7058 {"SC_PII_INTERNET", _SC_PII_INTERNET},
7059#endif
7060#ifdef _SC_PII_INTERNET_DGRAM
7061 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
7062#endif
7063#ifdef _SC_PII_INTERNET_STREAM
7064 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
7065#endif
7066#ifdef _SC_PII_OSI
7067 {"SC_PII_OSI", _SC_PII_OSI},
7068#endif
7069#ifdef _SC_PII_OSI_CLTS
7070 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
7071#endif
7072#ifdef _SC_PII_OSI_COTS
7073 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
7074#endif
7075#ifdef _SC_PII_OSI_M
7076 {"SC_PII_OSI_M", _SC_PII_OSI_M},
7077#endif
7078#ifdef _SC_PII_SOCKET
7079 {"SC_PII_SOCKET", _SC_PII_SOCKET},
7080#endif
7081#ifdef _SC_PII_XTI
7082 {"SC_PII_XTI", _SC_PII_XTI},
7083#endif
7084#ifdef _SC_POLL
7085 {"SC_POLL", _SC_POLL},
7086#endif
7087#ifdef _SC_PRIORITIZED_IO
7088 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
7089#endif
7090#ifdef _SC_PRIORITY_SCHEDULING
7091 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
7092#endif
7093#ifdef _SC_REALTIME_SIGNALS
7094 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
7095#endif
7096#ifdef _SC_RE_DUP_MAX
7097 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
7098#endif
7099#ifdef _SC_RTSIG_MAX
7100 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
7101#endif
7102#ifdef _SC_SAVED_IDS
7103 {"SC_SAVED_IDS", _SC_SAVED_IDS},
7104#endif
7105#ifdef _SC_SCHAR_MAX
7106 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
7107#endif
7108#ifdef _SC_SCHAR_MIN
7109 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
7110#endif
7111#ifdef _SC_SELECT
7112 {"SC_SELECT", _SC_SELECT},
7113#endif
7114#ifdef _SC_SEMAPHORES
7115 {"SC_SEMAPHORES", _SC_SEMAPHORES},
7116#endif
7117#ifdef _SC_SEM_NSEMS_MAX
7118 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
7119#endif
7120#ifdef _SC_SEM_VALUE_MAX
7121 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
7122#endif
7123#ifdef _SC_SHARED_MEMORY_OBJECTS
7124 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
7125#endif
7126#ifdef _SC_SHRT_MAX
7127 {"SC_SHRT_MAX", _SC_SHRT_MAX},
7128#endif
7129#ifdef _SC_SHRT_MIN
7130 {"SC_SHRT_MIN", _SC_SHRT_MIN},
7131#endif
7132#ifdef _SC_SIGQUEUE_MAX
7133 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
7134#endif
7135#ifdef _SC_SIGRT_MAX
7136 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
7137#endif
7138#ifdef _SC_SIGRT_MIN
7139 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
7140#endif
Fred Draked86ed291999-12-15 15:34:33 +00007141#ifdef _SC_SOFTPOWER
7142 {"SC_SOFTPOWER", _SC_SOFTPOWER},
7143#endif
Fred Drakec9680921999-12-13 16:37:25 +00007144#ifdef _SC_SPLIT_CACHE
7145 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
7146#endif
7147#ifdef _SC_SSIZE_MAX
7148 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
7149#endif
7150#ifdef _SC_STACK_PROT
7151 {"SC_STACK_PROT", _SC_STACK_PROT},
7152#endif
7153#ifdef _SC_STREAM_MAX
7154 {"SC_STREAM_MAX", _SC_STREAM_MAX},
7155#endif
7156#ifdef _SC_SYNCHRONIZED_IO
7157 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
7158#endif
7159#ifdef _SC_THREADS
7160 {"SC_THREADS", _SC_THREADS},
7161#endif
7162#ifdef _SC_THREAD_ATTR_STACKADDR
7163 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
7164#endif
7165#ifdef _SC_THREAD_ATTR_STACKSIZE
7166 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
7167#endif
7168#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
7169 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
7170#endif
7171#ifdef _SC_THREAD_KEYS_MAX
7172 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
7173#endif
7174#ifdef _SC_THREAD_PRIORITY_SCHEDULING
7175 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
7176#endif
7177#ifdef _SC_THREAD_PRIO_INHERIT
7178 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
7179#endif
7180#ifdef _SC_THREAD_PRIO_PROTECT
7181 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
7182#endif
7183#ifdef _SC_THREAD_PROCESS_SHARED
7184 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
7185#endif
7186#ifdef _SC_THREAD_SAFE_FUNCTIONS
7187 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
7188#endif
7189#ifdef _SC_THREAD_STACK_MIN
7190 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
7191#endif
7192#ifdef _SC_THREAD_THREADS_MAX
7193 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
7194#endif
7195#ifdef _SC_TIMERS
7196 {"SC_TIMERS", _SC_TIMERS},
7197#endif
7198#ifdef _SC_TIMER_MAX
7199 {"SC_TIMER_MAX", _SC_TIMER_MAX},
7200#endif
7201#ifdef _SC_TTY_NAME_MAX
7202 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
7203#endif
7204#ifdef _SC_TZNAME_MAX
7205 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
7206#endif
7207#ifdef _SC_T_IOV_MAX
7208 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
7209#endif
7210#ifdef _SC_UCHAR_MAX
7211 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
7212#endif
7213#ifdef _SC_UINT_MAX
7214 {"SC_UINT_MAX", _SC_UINT_MAX},
7215#endif
7216#ifdef _SC_UIO_MAXIOV
7217 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
7218#endif
7219#ifdef _SC_ULONG_MAX
7220 {"SC_ULONG_MAX", _SC_ULONG_MAX},
7221#endif
7222#ifdef _SC_USHRT_MAX
7223 {"SC_USHRT_MAX", _SC_USHRT_MAX},
7224#endif
7225#ifdef _SC_VERSION
7226 {"SC_VERSION", _SC_VERSION},
7227#endif
7228#ifdef _SC_WORD_BIT
7229 {"SC_WORD_BIT", _SC_WORD_BIT},
7230#endif
7231#ifdef _SC_XBS5_ILP32_OFF32
7232 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
7233#endif
7234#ifdef _SC_XBS5_ILP32_OFFBIG
7235 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
7236#endif
7237#ifdef _SC_XBS5_LP64_OFF64
7238 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
7239#endif
7240#ifdef _SC_XBS5_LPBIG_OFFBIG
7241 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
7242#endif
7243#ifdef _SC_XOPEN_CRYPT
7244 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
7245#endif
7246#ifdef _SC_XOPEN_ENH_I18N
7247 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
7248#endif
7249#ifdef _SC_XOPEN_LEGACY
7250 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
7251#endif
7252#ifdef _SC_XOPEN_REALTIME
7253 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
7254#endif
7255#ifdef _SC_XOPEN_REALTIME_THREADS
7256 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
7257#endif
7258#ifdef _SC_XOPEN_SHM
7259 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
7260#endif
7261#ifdef _SC_XOPEN_UNIX
7262 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
7263#endif
7264#ifdef _SC_XOPEN_VERSION
7265 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
7266#endif
7267#ifdef _SC_XOPEN_XCU_VERSION
7268 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
7269#endif
7270#ifdef _SC_XOPEN_XPG2
7271 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
7272#endif
7273#ifdef _SC_XOPEN_XPG3
7274 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
7275#endif
7276#ifdef _SC_XOPEN_XPG4
7277 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
7278#endif
7279};
7280
7281static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007282conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007283{
7284 return conv_confname(arg, valuep, posix_constants_sysconf,
7285 sizeof(posix_constants_sysconf)
7286 / sizeof(struct constdef));
7287}
7288
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007289PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007290"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007291Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007292
7293static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007294posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007295{
7296 PyObject *result = NULL;
7297 int name;
7298
7299 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
7300 int value;
7301
7302 errno = 0;
7303 value = sysconf(name);
7304 if (value == -1 && errno != 0)
7305 posix_error();
7306 else
7307 result = PyInt_FromLong(value);
7308 }
7309 return result;
7310}
7311#endif
7312
7313
Fred Drakebec628d1999-12-15 18:31:10 +00007314/* This code is used to ensure that the tables of configuration value names
7315 * are in sorted order as required by conv_confname(), and also to build the
7316 * the exported dictionaries that are used to publish information about the
7317 * names available on the host platform.
7318 *
7319 * Sorting the table at runtime ensures that the table is properly ordered
7320 * when used, even for platforms we're not able to test on. It also makes
7321 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00007322 */
Fred Drakebec628d1999-12-15 18:31:10 +00007323
7324static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007325cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00007326{
7327 const struct constdef *c1 =
7328 (const struct constdef *) v1;
7329 const struct constdef *c2 =
7330 (const struct constdef *) v2;
7331
7332 return strcmp(c1->name, c2->name);
7333}
7334
7335static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007336setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00007337 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007338{
Fred Drakebec628d1999-12-15 18:31:10 +00007339 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00007340 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00007341
7342 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
7343 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00007344 if (d == NULL)
7345 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007346
Barry Warsaw3155db32000-04-13 15:20:40 +00007347 for (i=0; i < tablesize; ++i) {
7348 PyObject *o = PyInt_FromLong(table[i].value);
7349 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
7350 Py_XDECREF(o);
7351 Py_DECREF(d);
7352 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007353 }
Barry Warsaw3155db32000-04-13 15:20:40 +00007354 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00007355 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00007356 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00007357}
7358
Fred Drakebec628d1999-12-15 18:31:10 +00007359/* Return -1 on failure, 0 on success. */
7360static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007361setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007362{
7363#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00007364 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00007365 sizeof(posix_constants_pathconf)
7366 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007367 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007368 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007369#endif
7370#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00007371 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00007372 sizeof(posix_constants_confstr)
7373 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007374 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007375 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007376#endif
7377#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00007378 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00007379 sizeof(posix_constants_sysconf)
7380 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007381 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007382 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007383#endif
Fred Drakebec628d1999-12-15 18:31:10 +00007384 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00007385}
Fred Draked86ed291999-12-15 15:34:33 +00007386
7387
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007388PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007389"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007390Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007391in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007392
7393static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007394posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007395{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007396 abort();
7397 /*NOTREACHED*/
7398 Py_FatalError("abort() called from Python code didn't abort!");
7399 return NULL;
7400}
Fred Drakebec628d1999-12-15 18:31:10 +00007401
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007402#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007403PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00007404"startfile(filepath [, operation]) - Start a file with its associated\n\
7405application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007406\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00007407When \"operation\" is not specified or \"open\", this acts like\n\
7408double-clicking the file in Explorer, or giving the file name as an\n\
7409argument to the DOS \"start\" command: the file is opened with whatever\n\
7410application (if any) its extension is associated.\n\
7411When another \"operation\" is given, it specifies what should be done with\n\
7412the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007413\n\
7414startfile returns as soon as the associated application is launched.\n\
7415There is no option to wait for the application to close, and no way\n\
7416to retrieve the application's exit status.\n\
7417\n\
7418The filepath is relative to the current directory. If you want to use\n\
7419an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007420the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00007421
7422static PyObject *
7423win32_startfile(PyObject *self, PyObject *args)
7424{
7425 char *filepath;
Georg Brandlf4f44152006-02-18 22:29:33 +00007426 char *operation = NULL;
Tim Petersf58a7aa2000-09-22 10:05:54 +00007427 HINSTANCE rc;
Georg Brandlf4f44152006-02-18 22:29:33 +00007428 if (!PyArg_ParseTuple(args, "et|s:startfile",
7429 Py_FileSystemDefaultEncoding, &filepath,
7430 &operation))
Tim Petersf58a7aa2000-09-22 10:05:54 +00007431 return NULL;
7432 Py_BEGIN_ALLOW_THREADS
Georg Brandlf4f44152006-02-18 22:29:33 +00007433 rc = ShellExecute((HWND)0, operation, filepath,
7434 NULL, NULL, SW_SHOWNORMAL);
Tim Petersf58a7aa2000-09-22 10:05:54 +00007435 Py_END_ALLOW_THREADS
Georg Brandle9f8ec92005-09-25 06:16:40 +00007436 if (rc <= (HINSTANCE)32) {
7437 PyObject *errval = win32_error("startfile", filepath);
7438 PyMem_Free(filepath);
7439 return errval;
7440 }
7441 PyMem_Free(filepath);
Tim Petersf58a7aa2000-09-22 10:05:54 +00007442 Py_INCREF(Py_None);
7443 return Py_None;
7444}
7445#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007446
Martin v. Löwis438b5342002-12-27 10:16:42 +00007447#ifdef HAVE_GETLOADAVG
7448PyDoc_STRVAR(posix_getloadavg__doc__,
7449"getloadavg() -> (float, float, float)\n\n\
7450Return the number of processes in the system run queue averaged over\n\
7451the last 1, 5, and 15 minutes or raises OSError if the load average\n\
7452was unobtainable");
7453
7454static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007455posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00007456{
7457 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00007458 if (getloadavg(loadavg, 3)!=3) {
7459 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
7460 return NULL;
7461 } else
7462 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
7463}
7464#endif
7465
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007466#ifdef MS_WINDOWS
7467
7468PyDoc_STRVAR(win32_urandom__doc__,
7469"urandom(n) -> str\n\n\
7470Return a string of n random bytes suitable for cryptographic use.");
7471
7472typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
7473 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
7474 DWORD dwFlags );
7475typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
7476 BYTE *pbBuffer );
7477
7478static CRYPTGENRANDOM pCryptGenRandom = NULL;
7479static HCRYPTPROV hCryptProv = 0;
7480
Tim Peters4ad82172004-08-30 17:02:04 +00007481static PyObject*
7482win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007483{
Tim Petersd3115382004-08-30 17:36:46 +00007484 int howMany;
7485 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007486
Tim Peters4ad82172004-08-30 17:02:04 +00007487 /* Read arguments */
Tim Peters9b279a82004-08-30 17:10:53 +00007488 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
Tim Peters4ad82172004-08-30 17:02:04 +00007489 return NULL;
Tim Peters51eba612004-08-30 17:08:02 +00007490 if (howMany < 0)
7491 return PyErr_Format(PyExc_ValueError,
7492 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007493
Tim Peters4ad82172004-08-30 17:02:04 +00007494 if (hCryptProv == 0) {
7495 HINSTANCE hAdvAPI32 = NULL;
7496 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007497
Tim Peters4ad82172004-08-30 17:02:04 +00007498 /* Obtain handle to the DLL containing CryptoAPI
7499 This should not fail */
7500 hAdvAPI32 = GetModuleHandle("advapi32.dll");
7501 if(hAdvAPI32 == NULL)
7502 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007503
Tim Peters4ad82172004-08-30 17:02:04 +00007504 /* Obtain pointers to the CryptoAPI functions
7505 This will fail on some early versions of Win95 */
7506 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
7507 hAdvAPI32,
7508 "CryptAcquireContextA");
7509 if (pCryptAcquireContext == NULL)
7510 return PyErr_Format(PyExc_NotImplementedError,
7511 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007512
Tim Peters4ad82172004-08-30 17:02:04 +00007513 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
7514 hAdvAPI32, "CryptGenRandom");
7515 if (pCryptAcquireContext == NULL)
7516 return PyErr_Format(PyExc_NotImplementedError,
7517 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007518
Tim Peters4ad82172004-08-30 17:02:04 +00007519 /* Acquire context */
7520 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
7521 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
7522 return win32_error("CryptAcquireContext", NULL);
7523 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007524
Tim Peters4ad82172004-08-30 17:02:04 +00007525 /* Allocate bytes */
Tim Petersd3115382004-08-30 17:36:46 +00007526 result = PyString_FromStringAndSize(NULL, howMany);
7527 if (result != NULL) {
7528 /* Get random data */
7529 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
7530 PyString_AS_STRING(result))) {
7531 Py_DECREF(result);
7532 return win32_error("CryptGenRandom", NULL);
7533 }
Tim Peters4ad82172004-08-30 17:02:04 +00007534 }
Tim Petersd3115382004-08-30 17:36:46 +00007535 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007536}
7537#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007538
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007539static PyMethodDef posix_methods[] = {
7540 {"access", posix_access, METH_VARARGS, posix_access__doc__},
7541#ifdef HAVE_TTYNAME
7542 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
7543#endif
7544 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
7545 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007546#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007547 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007548#endif /* HAVE_CHOWN */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007549#ifdef HAVE_LCHOWN
7550 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
7551#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00007552#ifdef HAVE_CHROOT
7553 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
7554#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007555#ifdef HAVE_CTERMID
Neal Norwitze241ce82003-02-17 18:17:05 +00007556 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007557#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00007558#ifdef HAVE_GETCWD
Neal Norwitze241ce82003-02-17 18:17:05 +00007559 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Walter Dörwald3b918c32002-11-21 20:18:46 +00007560#ifdef Py_USING_UNICODE
Neal Norwitze241ce82003-02-17 18:17:05 +00007561 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00007562#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00007563#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007564#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007565 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007566#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007567 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
7568 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
7569 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007570#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007571 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007572#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007573#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007574 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007575#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007576 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
7577 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
7578 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007579 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007580#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007581 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007582#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007583#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007584 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007585#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007586 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007587#ifdef HAVE_UNAME
Neal Norwitze241ce82003-02-17 18:17:05 +00007588 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007589#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007590 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
7591 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
7592 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007593#ifdef HAVE_TIMES
Neal Norwitze241ce82003-02-17 18:17:05 +00007594 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007595#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007596 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007597#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007598 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
7599 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007600#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00007601#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007602 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
7603 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00007604#if defined(PYOS_OS2)
7605 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
7606 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
7607#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00007608#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007609#ifdef HAVE_FORK1
Neal Norwitze241ce82003-02-17 18:17:05 +00007610 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007611#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007612#ifdef HAVE_FORK
Neal Norwitze241ce82003-02-17 18:17:05 +00007613 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007614#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007615#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Neal Norwitze241ce82003-02-17 18:17:05 +00007616 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007617#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007618#ifdef HAVE_FORKPTY
Neal Norwitze241ce82003-02-17 18:17:05 +00007619 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00007620#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007621#ifdef HAVE_GETEGID
Neal Norwitze241ce82003-02-17 18:17:05 +00007622 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007623#endif /* HAVE_GETEGID */
7624#ifdef HAVE_GETEUID
Neal Norwitze241ce82003-02-17 18:17:05 +00007625 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007626#endif /* HAVE_GETEUID */
7627#ifdef HAVE_GETGID
Neal Norwitze241ce82003-02-17 18:17:05 +00007628 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007629#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00007630#ifdef HAVE_GETGROUPS
Neal Norwitze241ce82003-02-17 18:17:05 +00007631 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007632#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007633 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007634#ifdef HAVE_GETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00007635 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007636#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007637#ifdef HAVE_GETPPID
Neal Norwitze241ce82003-02-17 18:17:05 +00007638 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007639#endif /* HAVE_GETPPID */
7640#ifdef HAVE_GETUID
Neal Norwitze241ce82003-02-17 18:17:05 +00007641 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007642#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007643#ifdef HAVE_GETLOGIN
Neal Norwitze241ce82003-02-17 18:17:05 +00007644 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00007645#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00007646#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007647 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007648#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007649#ifdef HAVE_KILLPG
7650 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
7651#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00007652#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007653 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00007654#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007655#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007656 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007657#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00007658 {"popen2", win32_popen2, METH_VARARGS},
7659 {"popen3", win32_popen3, METH_VARARGS},
7660 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00007661 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007662#else
7663#if defined(PYOS_OS2) && defined(PYCC_GCC)
7664 {"popen2", os2emx_popen2, METH_VARARGS},
7665 {"popen3", os2emx_popen3, METH_VARARGS},
7666 {"popen4", os2emx_popen4, METH_VARARGS},
7667#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00007668#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007669#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007670#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007671 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007672#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007673#ifdef HAVE_SETEUID
7674 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
7675#endif /* HAVE_SETEUID */
7676#ifdef HAVE_SETEGID
7677 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
7678#endif /* HAVE_SETEGID */
7679#ifdef HAVE_SETREUID
7680 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
7681#endif /* HAVE_SETREUID */
7682#ifdef HAVE_SETREGID
7683 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
7684#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007685#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007686 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007687#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007688#ifdef HAVE_SETGROUPS
7689 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
7690#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00007691#ifdef HAVE_GETPGID
7692 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
7693#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007694#ifdef HAVE_SETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00007695 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007696#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007697#ifdef HAVE_WAIT
Neal Norwitze241ce82003-02-17 18:17:05 +00007698 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007699#endif /* HAVE_WAIT */
Tim Petersab034fa2002-02-01 11:27:43 +00007700#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007701 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007702#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007703#ifdef HAVE_GETSID
7704 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
7705#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007706#ifdef HAVE_SETSID
Neal Norwitze241ce82003-02-17 18:17:05 +00007707 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007708#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007709#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007710 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007711#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007712#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007713 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007714#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007715#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007716 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007717#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007718 {"open", posix_open, METH_VARARGS, posix_open__doc__},
7719 {"close", posix_close, METH_VARARGS, posix_close__doc__},
7720 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
7721 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
7722 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
7723 {"read", posix_read, METH_VARARGS, posix_read__doc__},
7724 {"write", posix_write, METH_VARARGS, posix_write__doc__},
7725 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
7726 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00007727 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007728#ifdef HAVE_PIPE
Neal Norwitze241ce82003-02-17 18:17:05 +00007729 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007730#endif
7731#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007732 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007733#endif
Neal Norwitz11690112002-07-30 01:08:28 +00007734#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007735 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
7736#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007737#ifdef HAVE_DEVICE_MACROS
7738 {"major", posix_major, METH_VARARGS, posix_major__doc__},
7739 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
7740 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
7741#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007742#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007743 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007744#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007745#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007746 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007747#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007748#ifdef HAVE_UNSETENV
7749 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
7750#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00007751#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007752 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00007753#endif
Fred Drake4d1e64b2002-04-15 19:40:07 +00007754#ifdef HAVE_FCHDIR
7755 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
7756#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00007757#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007758 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007759#endif
7760#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007761 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007762#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00007763#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00007764#ifdef WCOREDUMP
7765 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
7766#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007767#ifdef WIFCONTINUED
7768 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
7769#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00007770#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007771 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007772#endif /* WIFSTOPPED */
7773#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007774 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007775#endif /* WIFSIGNALED */
7776#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007777 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007778#endif /* WIFEXITED */
7779#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007780 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007781#endif /* WEXITSTATUS */
7782#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007783 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007784#endif /* WTERMSIG */
7785#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007786 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007787#endif /* WSTOPSIG */
7788#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007789#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007790 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007791#endif
7792#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007793 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007794#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00007795#ifdef HAVE_TMPFILE
Neal Norwitze241ce82003-02-17 18:17:05 +00007796 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007797#endif
7798#ifdef HAVE_TEMPNAM
7799 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
7800#endif
7801#ifdef HAVE_TMPNAM
Neal Norwitze241ce82003-02-17 18:17:05 +00007802 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007803#endif
Fred Drakec9680921999-12-13 16:37:25 +00007804#ifdef HAVE_CONFSTR
7805 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
7806#endif
7807#ifdef HAVE_SYSCONF
7808 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
7809#endif
7810#ifdef HAVE_FPATHCONF
7811 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
7812#endif
7813#ifdef HAVE_PATHCONF
7814 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
7815#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007816 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007817#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00007818 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
7819#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007820#ifdef HAVE_GETLOADAVG
Neal Norwitze241ce82003-02-17 18:17:05 +00007821 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00007822#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007823 #ifdef MS_WINDOWS
7824 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
7825 #endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007826 {NULL, NULL} /* Sentinel */
7827};
7828
7829
Barry Warsaw4a342091996-12-19 23:50:02 +00007830static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007831ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00007832{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007833 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00007834}
7835
Guido van Rossumd48f2521997-12-05 22:19:34 +00007836#if defined(PYOS_OS2)
7837/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007838static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007839{
7840 APIRET rc;
7841 ULONG values[QSV_MAX+1];
7842 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00007843 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00007844
7845 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00007846 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007847 Py_END_ALLOW_THREADS
7848
7849 if (rc != NO_ERROR) {
7850 os2_error(rc);
7851 return -1;
7852 }
7853
Fred Drake4d1e64b2002-04-15 19:40:07 +00007854 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
7855 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
7856 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
7857 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
7858 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
7859 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
7860 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007861
7862 switch (values[QSV_VERSION_MINOR]) {
7863 case 0: ver = "2.00"; break;
7864 case 10: ver = "2.10"; break;
7865 case 11: ver = "2.11"; break;
7866 case 30: ver = "3.00"; break;
7867 case 40: ver = "4.00"; break;
7868 case 50: ver = "5.00"; break;
7869 default:
Tim Peters885d4572001-11-28 20:27:42 +00007870 PyOS_snprintf(tmp, sizeof(tmp),
7871 "%d-%d", values[QSV_VERSION_MAJOR],
7872 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007873 ver = &tmp[0];
7874 }
7875
7876 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007877 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007878 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007879
7880 /* Add Indicator of Which Drive was Used to Boot the System */
7881 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
7882 tmp[1] = ':';
7883 tmp[2] = '\0';
7884
Fred Drake4d1e64b2002-04-15 19:40:07 +00007885 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007886}
7887#endif
7888
Barry Warsaw4a342091996-12-19 23:50:02 +00007889static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007890all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00007891{
Guido van Rossum94f6f721999-01-06 18:42:14 +00007892#ifdef F_OK
7893 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007894#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007895#ifdef R_OK
7896 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007897#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007898#ifdef W_OK
7899 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007900#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007901#ifdef X_OK
7902 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007903#endif
Fred Drakec9680921999-12-13 16:37:25 +00007904#ifdef NGROUPS_MAX
7905 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
7906#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007907#ifdef TMP_MAX
7908 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
7909#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007910#ifdef WCONTINUED
7911 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
7912#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007913#ifdef WNOHANG
7914 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007915#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007916#ifdef WUNTRACED
7917 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
7918#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007919#ifdef O_RDONLY
7920 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
7921#endif
7922#ifdef O_WRONLY
7923 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
7924#endif
7925#ifdef O_RDWR
7926 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
7927#endif
7928#ifdef O_NDELAY
7929 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
7930#endif
7931#ifdef O_NONBLOCK
7932 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
7933#endif
7934#ifdef O_APPEND
7935 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
7936#endif
7937#ifdef O_DSYNC
7938 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
7939#endif
7940#ifdef O_RSYNC
7941 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
7942#endif
7943#ifdef O_SYNC
7944 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
7945#endif
7946#ifdef O_NOCTTY
7947 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
7948#endif
7949#ifdef O_CREAT
7950 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
7951#endif
7952#ifdef O_EXCL
7953 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
7954#endif
7955#ifdef O_TRUNC
7956 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
7957#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00007958#ifdef O_BINARY
7959 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
7960#endif
7961#ifdef O_TEXT
7962 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
7963#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007964#ifdef O_LARGEFILE
7965 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
7966#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00007967#ifdef O_SHLOCK
7968 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
7969#endif
7970#ifdef O_EXLOCK
7971 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
7972#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007973
Tim Peters5aa91602002-01-30 05:46:57 +00007974/* MS Windows */
7975#ifdef O_NOINHERIT
7976 /* Don't inherit in child processes. */
7977 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
7978#endif
7979#ifdef _O_SHORT_LIVED
7980 /* Optimize for short life (keep in memory). */
7981 /* MS forgot to define this one with a non-underscore form too. */
7982 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
7983#endif
7984#ifdef O_TEMPORARY
7985 /* Automatically delete when last handle is closed. */
7986 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
7987#endif
7988#ifdef O_RANDOM
7989 /* Optimize for random access. */
7990 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
7991#endif
7992#ifdef O_SEQUENTIAL
7993 /* Optimize for sequential access. */
7994 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
7995#endif
7996
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007997/* GNU extensions. */
7998#ifdef O_DIRECT
7999 /* Direct disk access. */
8000 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
8001#endif
8002#ifdef O_DIRECTORY
8003 /* Must be a directory. */
8004 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
8005#endif
8006#ifdef O_NOFOLLOW
8007 /* Do not follow links. */
8008 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
8009#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00008010
Barry Warsaw5676bd12003-01-07 20:57:09 +00008011 /* These come from sysexits.h */
8012#ifdef EX_OK
8013 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008014#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008015#ifdef EX_USAGE
8016 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008017#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008018#ifdef EX_DATAERR
8019 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008020#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008021#ifdef EX_NOINPUT
8022 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008023#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008024#ifdef EX_NOUSER
8025 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008026#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008027#ifdef EX_NOHOST
8028 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008029#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008030#ifdef EX_UNAVAILABLE
8031 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008032#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008033#ifdef EX_SOFTWARE
8034 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008035#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008036#ifdef EX_OSERR
8037 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008038#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008039#ifdef EX_OSFILE
8040 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008041#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008042#ifdef EX_CANTCREAT
8043 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008044#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008045#ifdef EX_IOERR
8046 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008047#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008048#ifdef EX_TEMPFAIL
8049 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008050#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008051#ifdef EX_PROTOCOL
8052 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008053#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008054#ifdef EX_NOPERM
8055 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008056#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008057#ifdef EX_CONFIG
8058 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008059#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008060#ifdef EX_NOTFOUND
8061 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008062#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008063
Guido van Rossum246bc171999-02-01 23:54:31 +00008064#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008065#if defined(PYOS_OS2) && defined(PYCC_GCC)
8066 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
8067 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
8068 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
8069 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
8070 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
8071 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
8072 if (ins(d, "P_PM", (long)P_PM)) return -1;
8073 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
8074 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
8075 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
8076 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
8077 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
8078 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
8079 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
8080 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
8081 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
8082 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
8083 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
8084 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
8085 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
8086#else
Guido van Rossum7d385291999-02-16 19:38:04 +00008087 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
8088 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
8089 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
8090 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
8091 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00008092#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008093#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00008094
Guido van Rossumd48f2521997-12-05 22:19:34 +00008095#if defined(PYOS_OS2)
8096 if (insertvalues(d)) return -1;
8097#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008098 return 0;
8099}
8100
8101
Tim Peters5aa91602002-01-30 05:46:57 +00008102#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008103#define INITFUNC initnt
8104#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008105
8106#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008107#define INITFUNC initos2
8108#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008109
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008110#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008111#define INITFUNC initposix
8112#define MODNAME "posix"
8113#endif
8114
Mark Hammondfe51c6d2002-08-02 02:27:13 +00008115PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008116INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00008117{
Fred Drake4d1e64b2002-04-15 19:40:07 +00008118 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00008119
Fred Drake4d1e64b2002-04-15 19:40:07 +00008120 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008121 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00008122 posix__doc__);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00008123 if (m == NULL)
8124 return;
Tim Peters5aa91602002-01-30 05:46:57 +00008125
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008126 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008127 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00008128 Py_XINCREF(v);
8129 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008130 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00008131 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00008132
Fred Drake4d1e64b2002-04-15 19:40:07 +00008133 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00008134 return;
8135
Fred Drake4d1e64b2002-04-15 19:40:07 +00008136 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00008137 return;
8138
Fred Drake4d1e64b2002-04-15 19:40:07 +00008139 Py_INCREF(PyExc_OSError);
8140 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00008141
Guido van Rossumb3d39562000-01-31 18:41:26 +00008142#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00008143 if (posix_putenv_garbage == NULL)
8144 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00008145#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008146
Guido van Rossum14648392001-12-08 18:02:58 +00008147 stat_result_desc.name = MODNAME ".stat_result";
Martin v. Löwisf607bda2002-10-16 18:27:39 +00008148 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
8149 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
8150 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008151 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00008152 structseq_new = StatResultType.tp_new;
8153 StatResultType.tp_new = statresult_new;
Fred Drake4d1e64b2002-04-15 19:40:07 +00008154 Py_INCREF((PyObject*) &StatResultType);
8155 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008156
Guido van Rossum14648392001-12-08 18:02:58 +00008157 statvfs_result_desc.name = MODNAME ".statvfs_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008158 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Fred Drake4d1e64b2002-04-15 19:40:07 +00008159 Py_INCREF((PyObject*) &StatVFSResultType);
8160 PyModule_AddObject(m, "statvfs_result",
8161 (PyObject*) &StatVFSResultType);
Guido van Rossumb6775db1994-08-01 11:34:53 +00008162}