blob: 1fbc3530088ec9c58539f1b1227d1879e0714621 [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;
Martin v. Löwise920f0d2006-03-07 23:59:33 +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 {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00001678 /* Skip over . and .. */
1679 if (wcscmp(wFileData.cFileName, L".") != 0 &&
1680 wcscmp(wFileData.cFileName, L"..") != 0) {
1681 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
1682 if (v == NULL) {
1683 Py_DECREF(d);
1684 d = NULL;
1685 break;
1686 }
1687 if (PyList_Append(d, v) != 0) {
1688 Py_DECREF(v);
1689 Py_DECREF(d);
1690 d = NULL;
1691 break;
1692 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001693 Py_DECREF(v);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001694 }
Georg Brandl622927b2006-03-07 12:48:03 +00001695 Py_BEGIN_ALLOW_THREADS
1696 result = FindNextFileW(hFindFile, &wFileData);
1697 Py_END_ALLOW_THREADS
1698 } while (result == TRUE);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001699
1700 if (FindClose(hFindFile) == FALSE) {
1701 Py_DECREF(d);
1702 return win32_error_unicode("FindClose", wnamebuf);
1703 }
1704 return d;
1705 }
1706 /* Drop the argument parsing error as narrow strings
1707 are also valid. */
1708 PyErr_Clear();
1709 }
1710#endif
1711
Tim Peters5aa91602002-01-30 05:46:57 +00001712 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001713 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +00001714 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +00001715 if (len > 0) {
1716 char ch = namebuf[len-1];
1717 if (ch != SEP && ch != ALTSEP && ch != ':')
1718 namebuf[len++] = '/';
1719 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001720 strcpy(namebuf + len, "*.*");
1721
Barry Warsaw53699e91996-12-10 23:23:01 +00001722 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001723 return NULL;
1724
1725 hFindFile = FindFirstFile(namebuf, &FileData);
1726 if (hFindFile == INVALID_HANDLE_VALUE) {
1727 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +00001728 if (errno == ERROR_FILE_NOT_FOUND)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001729 return d;
1730 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00001731 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001732 }
1733 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00001734 /* Skip over . and .. */
1735 if (strcmp(FileData.cFileName, ".") != 0 &&
1736 strcmp(FileData.cFileName, "..") != 0) {
1737 v = PyString_FromString(FileData.cFileName);
1738 if (v == NULL) {
1739 Py_DECREF(d);
1740 d = NULL;
1741 break;
1742 }
1743 if (PyList_Append(d, v) != 0) {
1744 Py_DECREF(v);
1745 Py_DECREF(d);
1746 d = NULL;
1747 break;
1748 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001749 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001750 }
Georg Brandl622927b2006-03-07 12:48:03 +00001751 Py_BEGIN_ALLOW_THREADS
1752 result = FindNextFile(hFindFile, &FileData);
1753 Py_END_ALLOW_THREADS
1754 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001755
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001756 if (FindClose(hFindFile) == FALSE) {
1757 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00001758 return win32_error("FindClose", namebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001759 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001760
1761 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001762
Tim Peters0bb44a42000-09-15 07:44:49 +00001763#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001764
1765#ifndef MAX_PATH
1766#define MAX_PATH CCHMAXPATH
1767#endif
1768 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00001769 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001770 PyObject *d, *v;
1771 char namebuf[MAX_PATH+5];
1772 HDIR hdir = 1;
1773 ULONG srchcnt = 1;
1774 FILEFINDBUF3 ep;
1775 APIRET rc;
1776
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001777 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001778 return NULL;
1779 if (len >= MAX_PATH) {
1780 PyErr_SetString(PyExc_ValueError, "path too long");
1781 return NULL;
1782 }
1783 strcpy(namebuf, name);
1784 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001785 if (*pt == ALTSEP)
1786 *pt = SEP;
1787 if (namebuf[len-1] != SEP)
1788 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001789 strcpy(namebuf + len, "*.*");
1790
1791 if ((d = PyList_New(0)) == NULL)
1792 return NULL;
1793
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001794 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
1795 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001796 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001797 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
1798 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
1799 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001800
1801 if (rc != NO_ERROR) {
1802 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001803 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001804 }
1805
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001806 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001807 do {
1808 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001809 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001810 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001811
1812 strcpy(namebuf, ep.achName);
1813
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001814 /* Leave Case of Name Alone -- In Native Form */
1815 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001816
1817 v = PyString_FromString(namebuf);
1818 if (v == NULL) {
1819 Py_DECREF(d);
1820 d = NULL;
1821 break;
1822 }
1823 if (PyList_Append(d, v) != 0) {
1824 Py_DECREF(v);
1825 Py_DECREF(d);
1826 d = NULL;
1827 break;
1828 }
1829 Py_DECREF(v);
1830 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1831 }
1832
1833 return d;
1834#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001835
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001836 char *name = NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001837 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001838 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001839 struct dirent *ep;
Just van Rossum96b1c902003-03-03 17:32:15 +00001840 int arg_is_unicode = 1;
1841
1842 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
1843 arg_is_unicode = 0;
1844 PyErr_Clear();
1845 }
1846 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001847 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001848 if ((dirp = opendir(name)) == NULL) {
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001849 return posix_error_with_allocated_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001850 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001851 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001852 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001853 PyMem_Free(name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001854 return NULL;
1855 }
Georg Brandl622927b2006-03-07 12:48:03 +00001856 for (;;) {
1857 Py_BEGIN_ALLOW_THREADS
1858 ep = readdir(dirp);
1859 Py_END_ALLOW_THREADS
1860 if (ep == NULL)
1861 break;
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001862 if (ep->d_name[0] == '.' &&
1863 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001864 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001865 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001866 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001867 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001868 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001869 d = NULL;
1870 break;
1871 }
Just van Rossum46c97842003-02-25 21:42:15 +00001872#ifdef Py_USING_UNICODE
Just van Rossum96b1c902003-03-03 17:32:15 +00001873 if (arg_is_unicode) {
Just van Rossum46c97842003-02-25 21:42:15 +00001874 PyObject *w;
1875
1876 w = PyUnicode_FromEncodedObject(v,
Tim Peters11b23062003-04-23 02:39:17 +00001877 Py_FileSystemDefaultEncoding,
Just van Rossum46c97842003-02-25 21:42:15 +00001878 "strict");
Just van Rossum6a421832003-03-04 19:30:44 +00001879 if (w != NULL) {
1880 Py_DECREF(v);
1881 v = w;
1882 }
1883 else {
1884 /* fall back to the original byte string, as
1885 discussed in patch #683592 */
1886 PyErr_Clear();
Just van Rossum46c97842003-02-25 21:42:15 +00001887 }
Just van Rossum46c97842003-02-25 21:42:15 +00001888 }
1889#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001890 if (PyList_Append(d, v) != 0) {
1891 Py_DECREF(v);
1892 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001893 d = NULL;
1894 break;
1895 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001896 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001897 }
1898 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001899 PyMem_Free(name);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001900
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001901 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001902
Tim Peters0bb44a42000-09-15 07:44:49 +00001903#endif /* which OS */
1904} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001905
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001906#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00001907/* A helper function for abspath on win32 */
1908static PyObject *
1909posix__getfullpathname(PyObject *self, PyObject *args)
1910{
1911 /* assume encoded strings wont more than double no of chars */
1912 char inbuf[MAX_PATH*2];
1913 char *inbufp = inbuf;
Tim Peters67d70eb2006-03-01 04:35:45 +00001914 Py_ssize_t insize = sizeof(inbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00001915 char outbuf[MAX_PATH*2];
1916 char *temp;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001917#ifdef Py_WIN_WIDE_FILENAMES
1918 if (unicode_file_names()) {
1919 PyUnicodeObject *po;
1920 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
1921 Py_UNICODE woutbuf[MAX_PATH*2];
1922 Py_UNICODE *wtemp;
Tim Peters11b23062003-04-23 02:39:17 +00001923 if (!GetFullPathNameW(PyUnicode_AS_UNICODE(po),
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001924 sizeof(woutbuf)/sizeof(woutbuf[0]),
1925 woutbuf, &wtemp))
1926 return win32_error("GetFullPathName", "");
1927 return PyUnicode_FromUnicode(woutbuf, wcslen(woutbuf));
1928 }
1929 /* Drop the argument parsing error as narrow strings
1930 are also valid. */
1931 PyErr_Clear();
1932 }
1933#endif
Tim Peters5aa91602002-01-30 05:46:57 +00001934 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
1935 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00001936 &insize))
1937 return NULL;
1938 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
1939 outbuf, &temp))
1940 return win32_error("GetFullPathName", inbuf);
Martin v. Löwis969297f2004-06-15 18:49:58 +00001941 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
1942 return PyUnicode_Decode(outbuf, strlen(outbuf),
1943 Py_FileSystemDefaultEncoding, NULL);
1944 }
Mark Hammondef8b6542001-05-13 08:04:26 +00001945 return PyString_FromString(outbuf);
1946} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001947#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00001948
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001949PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001950"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001951Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001952
Barry Warsaw53699e91996-12-10 23:23:01 +00001953static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001954posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001955{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001956 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00001957 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001958 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001959
1960#ifdef Py_WIN_WIDE_FILENAMES
1961 if (unicode_file_names()) {
1962 PyUnicodeObject *po;
Mark Hammond05107b62003-02-19 04:08:27 +00001963 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001964 Py_BEGIN_ALLOW_THREADS
1965 /* PyUnicode_AS_UNICODE OK without thread lock as
1966 it is a simple dereference. */
1967 res = _wmkdir(PyUnicode_AS_UNICODE(po));
1968 Py_END_ALLOW_THREADS
1969 if (res < 0)
1970 return posix_error();
1971 Py_INCREF(Py_None);
1972 return Py_None;
1973 }
1974 /* Drop the argument parsing error as narrow strings
1975 are also valid. */
1976 PyErr_Clear();
1977 }
1978#endif
1979
Tim Peters5aa91602002-01-30 05:46:57 +00001980 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001981 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001982 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001983 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001984#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001985 res = mkdir(path);
1986#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001987 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001988#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001989 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001990 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001991 return posix_error_with_allocated_filename(path);
1992 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001993 Py_INCREF(Py_None);
1994 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001995}
1996
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001997
Guido van Rossumb6775db1994-08-01 11:34:53 +00001998#ifdef HAVE_NICE
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001999#if defined(HAVE_BROKEN_NICE) && defined(HAVE_SYS_RESOURCE_H)
2000#if defined(HAVE_GETPRIORITY) && !defined(PRIO_PROCESS)
2001#include <sys/resource.h>
2002#endif
2003#endif
2004
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002005PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002006"nice(inc) -> new_priority\n\n\
2007Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002008
Barry Warsaw53699e91996-12-10 23:23:01 +00002009static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002010posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002011{
2012 int increment, value;
2013
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002014 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00002015 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002016
2017 /* There are two flavours of 'nice': one that returns the new
2018 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002019 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2020 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002021
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002022 If we are of the nice family that returns the new priority, we
2023 need to clear errno before the call, and check if errno is filled
2024 before calling posix_error() on a returnvalue of -1, because the
2025 -1 may be the actual new priority! */
2026
2027 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002028 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002029#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002030 if (value == 0)
2031 value = getpriority(PRIO_PROCESS, 0);
2032#endif
2033 if (value == -1 && errno != 0)
2034 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00002035 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002036 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002037}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002038#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002039
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002040
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002041PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002042"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002043Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002044
Barry Warsaw53699e91996-12-10 23:23:01 +00002045static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002046posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002047{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002048#ifdef MS_WINDOWS
2049 return posix_2str(args, "etet:rename", rename, "OO:rename", _wrename);
2050#else
2051 return posix_2str(args, "etet:rename", rename, NULL, NULL);
2052#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002053}
2054
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002055
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002056PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002057"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002058Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002059
Barry Warsaw53699e91996-12-10 23:23:01 +00002060static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002061posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002062{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002063#ifdef MS_WINDOWS
2064 return posix_1str(args, "et:rmdir", rmdir, "U:rmdir", _wrmdir);
2065#else
2066 return posix_1str(args, "et:rmdir", rmdir, NULL, NULL);
2067#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002068}
2069
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002070
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002071PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002072"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002073Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002074
Barry Warsaw53699e91996-12-10 23:23:01 +00002075static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002076posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002077{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002078#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00002079 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002080#else
2081 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
2082#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002083}
2084
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002085
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002086#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002087PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002088"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002089Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002090
Barry Warsaw53699e91996-12-10 23:23:01 +00002091static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002092posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002093{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002094 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002095 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002096 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002097 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002098 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002099 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00002100 Py_END_ALLOW_THREADS
2101 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002102}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002103#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002104
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002105
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002106PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002107"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002108Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002109
Barry Warsaw53699e91996-12-10 23:23:01 +00002110static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002111posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002112{
2113 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002114 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002115 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00002116 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002117 if (i < 0)
2118 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002119 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002120}
2121
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002122
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002123PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002124"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002125Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002126
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002127PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002128"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002129Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002130
Barry Warsaw53699e91996-12-10 23:23:01 +00002131static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002132posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002133{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002134#ifdef MS_WINDOWS
2135 return posix_1str(args, "et:remove", unlink, "U:remove", _wunlink);
2136#else
2137 return posix_1str(args, "et:remove", unlink, NULL, NULL);
2138#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002139}
2140
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002141
Guido van Rossumb6775db1994-08-01 11:34:53 +00002142#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002143PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002144"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002145Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002146
Barry Warsaw53699e91996-12-10 23:23:01 +00002147static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002148posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002149{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002150 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002151 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00002152
Barry Warsaw53699e91996-12-10 23:23:01 +00002153 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002154 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00002155 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002156 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002157 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002158 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00002159 u.sysname,
2160 u.nodename,
2161 u.release,
2162 u.version,
2163 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002164}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002165#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002166
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002167static int
2168extract_time(PyObject *t, long* sec, long* usec)
2169{
2170 long intval;
2171 if (PyFloat_Check(t)) {
2172 double tval = PyFloat_AsDouble(t);
2173 PyObject *intobj = t->ob_type->tp_as_number->nb_int(t);
2174 if (!intobj)
2175 return -1;
2176 intval = PyInt_AsLong(intobj);
2177 Py_DECREF(intobj);
Michael W. Hudsonb8963812005-07-05 15:21:58 +00002178 if (intval == -1 && PyErr_Occurred())
2179 return -1;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002180 *sec = intval;
Tim Peters96940cf2002-09-10 15:37:28 +00002181 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002182 if (*usec < 0)
2183 /* If rounding gave us a negative number,
2184 truncate. */
2185 *usec = 0;
2186 return 0;
2187 }
2188 intval = PyInt_AsLong(t);
2189 if (intval == -1 && PyErr_Occurred())
2190 return -1;
2191 *sec = intval;
2192 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00002193 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002194}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002195
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002196PyDoc_STRVAR(posix_utime__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002197"utime(path, (atime, utime))\n\
2198utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00002199Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002200second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002201
Barry Warsaw53699e91996-12-10 23:23:01 +00002202static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002203posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002204{
Neal Norwitz2adf2102004-06-09 01:46:02 +00002205 char *path = NULL;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002206 long atime, mtime, ausec, musec;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002207 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002208 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002209
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002210#if defined(HAVE_UTIMES)
2211 struct timeval buf[2];
2212#define ATIME buf[0].tv_sec
2213#define MTIME buf[1].tv_sec
2214#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002215/* XXX should define struct utimbuf instead, above */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002216 struct utimbuf buf;
2217#define ATIME buf.actime
2218#define MTIME buf.modtime
2219#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002220#else /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002221 time_t buf[2];
2222#define ATIME buf[0]
2223#define MTIME buf[1]
2224#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002225#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002226
Mark Hammond817c9292003-12-03 01:22:38 +00002227 int have_unicode_filename = 0;
2228#ifdef Py_WIN_WIDE_FILENAMES
2229 PyUnicodeObject *obwpath;
2230 wchar_t *wpath;
2231 if (unicode_file_names()) {
2232 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
2233 wpath = PyUnicode_AS_UNICODE(obwpath);
2234 have_unicode_filename = 1;
2235 } else
2236 /* Drop the argument parsing error as narrow strings
2237 are also valid. */
2238 PyErr_Clear();
2239 }
2240#endif /* Py_WIN_WIDE_FILENAMES */
2241
2242 if (!have_unicode_filename && \
Hye-Shik Chang2b2c9732004-01-04 13:54:25 +00002243 !PyArg_ParseTuple(args, "etO:utime",
2244 Py_FileSystemDefaultEncoding, &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002245 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002246 if (arg == Py_None) {
2247 /* optional time values not given */
2248 Py_BEGIN_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002249#ifdef Py_WIN_WIDE_FILENAMES
2250 if (have_unicode_filename)
2251 res = _wutime(wpath, NULL);
2252 else
2253#endif /* Py_WIN_WIDE_FILENAMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002254 res = utime(path, NULL);
2255 Py_END_ALLOW_THREADS
2256 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002257 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00002258 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002259 "utime() arg 2 must be a tuple (atime, mtime)");
Neal Norwitz96652712004-06-06 20:40:27 +00002260 PyMem_Free(path);
Barry Warsaw3cef8562000-05-01 16:17:24 +00002261 return NULL;
2262 }
2263 else {
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002264 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Neal Norwitz96652712004-06-06 20:40:27 +00002265 &atime, &ausec) == -1) {
2266 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002267 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002268 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002269 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Neal Norwitz96652712004-06-06 20:40:27 +00002270 &mtime, &musec) == -1) {
2271 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002272 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002273 }
Barry Warsaw3cef8562000-05-01 16:17:24 +00002274 ATIME = atime;
2275 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002276#ifdef HAVE_UTIMES
2277 buf[0].tv_usec = ausec;
2278 buf[1].tv_usec = musec;
2279 Py_BEGIN_ALLOW_THREADS
2280 res = utimes(path, buf);
2281 Py_END_ALLOW_THREADS
2282#else
Barry Warsaw3cef8562000-05-01 16:17:24 +00002283 Py_BEGIN_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002284#ifdef Py_WIN_WIDE_FILENAMES
2285 if (have_unicode_filename)
Tim Peters4ad82172004-08-30 17:02:04 +00002286 /* utime is OK with utimbuf, but _wutime insists
2287 on _utimbuf (the msvc headers assert the
Mark Hammond817c9292003-12-03 01:22:38 +00002288 underscore version is ansi) */
2289 res = _wutime(wpath, (struct _utimbuf *)UTIME_ARG);
2290 else
2291#endif /* Py_WIN_WIDE_FILENAMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002292 res = utime(path, UTIME_ARG);
2293 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002294#endif /* HAVE_UTIMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002295 }
Mark Hammond2d5914b2004-05-04 08:10:37 +00002296 if (res < 0) {
2297#ifdef Py_WIN_WIDE_FILENAMES
Neal Norwitz2adf2102004-06-09 01:46:02 +00002298 if (have_unicode_filename)
Mark Hammond2d5914b2004-05-04 08:10:37 +00002299 return posix_error_with_unicode_filename(wpath);
2300#endif /* Py_WIN_WIDE_FILENAMES */
Neal Norwitz96652712004-06-06 20:40:27 +00002301 return posix_error_with_allocated_filename(path);
Mark Hammond2d5914b2004-05-04 08:10:37 +00002302 }
Neal Norwitz96652712004-06-06 20:40:27 +00002303 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002304 Py_INCREF(Py_None);
2305 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002306#undef UTIME_ARG
2307#undef ATIME
2308#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002309}
2310
Guido van Rossum85e3b011991-06-03 12:42:10 +00002311
Guido van Rossum3b066191991-06-04 19:40:25 +00002312/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002313
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002314PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002315"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002316Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002317
Barry Warsaw53699e91996-12-10 23:23:01 +00002318static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002319posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002320{
2321 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002322 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002323 return NULL;
2324 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00002325 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002326}
2327
Martin v. Löwis114619e2002-10-07 06:44:21 +00002328#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
2329static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00002330free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00002331{
Martin v. Löwis725507b2006-03-07 12:08:51 +00002332 Py_ssize_t i;
Martin v. Löwis114619e2002-10-07 06:44:21 +00002333 for (i = 0; i < count; i++)
2334 PyMem_Free(array[i]);
2335 PyMem_DEL(array);
2336}
2337#endif
2338
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002339
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002340#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002341PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002342"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002343Execute an executable path with arguments, replacing current process.\n\
2344\n\
2345 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002346 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002347
Barry Warsaw53699e91996-12-10 23:23:01 +00002348static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002349posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002350{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002351 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002352 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002353 char **argvlist;
Martin v. Löwis725507b2006-03-07 12:08:51 +00002354 Py_ssize_t i, argc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002355 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002356
Guido van Rossum89b33251993-10-22 14:26:06 +00002357 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00002358 argv is a list or tuple of strings. */
2359
Martin v. Löwis114619e2002-10-07 06:44:21 +00002360 if (!PyArg_ParseTuple(args, "etO:execv",
2361 Py_FileSystemDefaultEncoding,
2362 &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002363 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002364 if (PyList_Check(argv)) {
2365 argc = PyList_Size(argv);
2366 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002367 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002368 else if (PyTuple_Check(argv)) {
2369 argc = PyTuple_Size(argv);
2370 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002371 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002372 else {
Fred Drake661ea262000-10-24 19:57:45 +00002373 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002374 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002375 return NULL;
2376 }
2377
Barry Warsaw53699e91996-12-10 23:23:01 +00002378 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002379 if (argvlist == NULL) {
2380 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002381 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002382 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002383 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002384 if (!PyArg_Parse((*getitem)(argv, i), "et",
2385 Py_FileSystemDefaultEncoding,
2386 &argvlist[i])) {
2387 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00002388 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002389 "execv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002390 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002391 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00002392
Guido van Rossum85e3b011991-06-03 12:42:10 +00002393 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002394 }
2395 argvlist[argc] = NULL;
2396
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002397 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002398
Guido van Rossum85e3b011991-06-03 12:42:10 +00002399 /* If we get here it's definitely an error */
2400
Martin v. Löwis114619e2002-10-07 06:44:21 +00002401 free_string_array(argvlist, argc);
2402 PyMem_Free(path);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002403 return posix_error();
2404}
2405
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002406
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002407PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002408"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002409Execute a path with arguments and environment, replacing current process.\n\
2410\n\
2411 path: path of executable file\n\
2412 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002413 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002414
Barry Warsaw53699e91996-12-10 23:23:01 +00002415static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002416posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002417{
2418 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002419 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002420 char **argvlist;
2421 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002422 PyObject *key, *val, *keys=NULL, *vals=NULL;
Martin v. Löwis725507b2006-03-07 12:08:51 +00002423 Py_ssize_t i, pos, argc, envc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002424 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002425 int lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002426
2427 /* execve has three arguments: (path, argv, env), where
2428 argv is a list or tuple of strings and env is a dictionary
2429 like posix.environ. */
2430
Martin v. Löwis114619e2002-10-07 06:44:21 +00002431 if (!PyArg_ParseTuple(args, "etOO:execve",
2432 Py_FileSystemDefaultEncoding,
2433 &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002434 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002435 if (PyList_Check(argv)) {
2436 argc = PyList_Size(argv);
2437 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002438 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002439 else if (PyTuple_Check(argv)) {
2440 argc = PyTuple_Size(argv);
2441 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002442 }
2443 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002444 PyErr_SetString(PyExc_TypeError,
2445 "execve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002446 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002447 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002448 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002449 PyErr_SetString(PyExc_TypeError,
2450 "execve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002451 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002452 }
2453
Barry Warsaw53699e91996-12-10 23:23:01 +00002454 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002455 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002456 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002457 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002458 }
2459 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002460 if (!PyArg_Parse((*getitem)(argv, i),
Martin v. Löwis114619e2002-10-07 06:44:21 +00002461 "et;execve() arg 2 must contain only strings",
Guido van Rossum1e700d22002-10-16 16:52:11 +00002462 Py_FileSystemDefaultEncoding,
Barry Warsaw43d68b81996-12-19 22:10:44 +00002463 &argvlist[i]))
2464 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002465 lastarg = i;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002466 goto fail_1;
2467 }
2468 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002469 lastarg = argc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002470 argvlist[argc] = NULL;
2471
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002472 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002473 if (i < 0)
2474 goto fail_1;
Barry Warsaw53699e91996-12-10 23:23:01 +00002475 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002476 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002477 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002478 goto fail_1;
2479 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002480 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002481 keys = PyMapping_Keys(env);
2482 vals = PyMapping_Values(env);
2483 if (!keys || !vals)
2484 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002485 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2486 PyErr_SetString(PyExc_TypeError,
2487 "execve(): env.keys() or env.values() is not a list");
2488 goto fail_2;
2489 }
Tim Peters5aa91602002-01-30 05:46:57 +00002490
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002491 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002492 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002493 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002494
2495 key = PyList_GetItem(keys, pos);
2496 val = PyList_GetItem(vals, pos);
2497 if (!key || !val)
2498 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002499
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002500 if (!PyArg_Parse(
2501 key,
2502 "s;execve() arg 3 contains a non-string key",
2503 &k) ||
2504 !PyArg_Parse(
2505 val,
2506 "s;execve() arg 3 contains a non-string value",
2507 &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00002508 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002509 goto fail_2;
2510 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00002511
2512#if defined(PYOS_OS2)
2513 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
2514 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
2515#endif
Tim Petersc8996f52001-12-03 20:41:00 +00002516 len = PyString_Size(key) + PyString_Size(val) + 2;
2517 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002518 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002519 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002520 goto fail_2;
2521 }
Tim Petersc8996f52001-12-03 20:41:00 +00002522 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002523 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00002524#if defined(PYOS_OS2)
2525 }
2526#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002527 }
2528 envlist[envc] = 0;
2529
2530 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00002531
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002532 /* If we get here it's definitely an error */
2533
2534 (void) posix_error();
2535
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002536 fail_2:
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002537 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00002538 PyMem_DEL(envlist[envc]);
2539 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002540 fail_1:
2541 free_string_array(argvlist, lastarg);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002542 Py_XDECREF(vals);
2543 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002544 fail_0:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002545 PyMem_Free(path);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002546 return NULL;
2547}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002548#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002549
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002550
Guido van Rossuma1065681999-01-25 23:20:23 +00002551#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002552PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002553"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002554Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002555\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002556 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002557 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002558 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002559
2560static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002561posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002562{
2563 char *path;
2564 PyObject *argv;
2565 char **argvlist;
2566 int mode, i, argc;
Tim Peters79248aa2001-08-29 21:37:10 +00002567 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002568 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00002569
2570 /* spawnv has three arguments: (mode, path, argv), where
2571 argv is a list or tuple of strings. */
2572
Martin v. Löwis114619e2002-10-07 06:44:21 +00002573 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
2574 Py_FileSystemDefaultEncoding,
2575 &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00002576 return NULL;
2577 if (PyList_Check(argv)) {
2578 argc = PyList_Size(argv);
2579 getitem = PyList_GetItem;
2580 }
2581 else if (PyTuple_Check(argv)) {
2582 argc = PyTuple_Size(argv);
2583 getitem = PyTuple_GetItem;
2584 }
2585 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002586 PyErr_SetString(PyExc_TypeError,
2587 "spawnv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002588 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002589 return NULL;
2590 }
2591
2592 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002593 if (argvlist == NULL) {
2594 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002595 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002596 }
Guido van Rossuma1065681999-01-25 23:20:23 +00002597 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002598 if (!PyArg_Parse((*getitem)(argv, i), "et",
2599 Py_FileSystemDefaultEncoding,
2600 &argvlist[i])) {
2601 free_string_array(argvlist, i);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002602 PyErr_SetString(
2603 PyExc_TypeError,
2604 "spawnv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002605 PyMem_Free(path);
Fred Drake137507e2000-06-01 02:02:46 +00002606 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00002607 }
2608 }
2609 argvlist[argc] = NULL;
2610
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002611#if defined(PYOS_OS2) && defined(PYCC_GCC)
2612 Py_BEGIN_ALLOW_THREADS
2613 spawnval = spawnv(mode, path, argvlist);
2614 Py_END_ALLOW_THREADS
2615#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002616 if (mode == _OLD_P_OVERLAY)
2617 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00002618
Tim Peters25059d32001-12-07 20:35:43 +00002619 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002620 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00002621 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002622#endif
Tim Peters5aa91602002-01-30 05:46:57 +00002623
Martin v. Löwis114619e2002-10-07 06:44:21 +00002624 free_string_array(argvlist, argc);
2625 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002626
Fred Drake699f3522000-06-29 21:12:41 +00002627 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002628 return posix_error();
2629 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002630#if SIZEOF_LONG == SIZEOF_VOID_P
2631 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002632#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00002633 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002634#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002635}
2636
2637
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002638PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002639"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002640Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002641\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002642 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002643 path: path of executable file\n\
2644 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002645 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002646
2647static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002648posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002649{
2650 char *path;
2651 PyObject *argv, *env;
2652 char **argvlist;
2653 char **envlist;
2654 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
2655 int mode, i, pos, argc, envc;
Tim Peters79248aa2001-08-29 21:37:10 +00002656 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002657 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002658 int lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002659
2660 /* spawnve has four arguments: (mode, path, argv, env), where
2661 argv is a list or tuple of strings and env is a dictionary
2662 like posix.environ. */
2663
Martin v. Löwis114619e2002-10-07 06:44:21 +00002664 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
2665 Py_FileSystemDefaultEncoding,
2666 &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00002667 return NULL;
2668 if (PyList_Check(argv)) {
2669 argc = PyList_Size(argv);
2670 getitem = PyList_GetItem;
2671 }
2672 else if (PyTuple_Check(argv)) {
2673 argc = PyTuple_Size(argv);
2674 getitem = PyTuple_GetItem;
2675 }
2676 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002677 PyErr_SetString(PyExc_TypeError,
2678 "spawnve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002679 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002680 }
2681 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002682 PyErr_SetString(PyExc_TypeError,
2683 "spawnve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002684 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002685 }
2686
2687 argvlist = PyMem_NEW(char *, argc+1);
2688 if (argvlist == NULL) {
2689 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002690 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002691 }
2692 for (i = 0; i < argc; i++) {
2693 if (!PyArg_Parse((*getitem)(argv, i),
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002694 "et;spawnve() arg 2 must contain only strings",
Martin v. Löwis114619e2002-10-07 06:44:21 +00002695 Py_FileSystemDefaultEncoding,
Guido van Rossuma1065681999-01-25 23:20:23 +00002696 &argvlist[i]))
2697 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002698 lastarg = i;
Guido van Rossuma1065681999-01-25 23:20:23 +00002699 goto fail_1;
2700 }
2701 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002702 lastarg = argc;
Guido van Rossuma1065681999-01-25 23:20:23 +00002703 argvlist[argc] = NULL;
2704
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002705 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002706 if (i < 0)
2707 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00002708 envlist = PyMem_NEW(char *, i + 1);
2709 if (envlist == NULL) {
2710 PyErr_NoMemory();
2711 goto fail_1;
2712 }
2713 envc = 0;
2714 keys = PyMapping_Keys(env);
2715 vals = PyMapping_Values(env);
2716 if (!keys || !vals)
2717 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002718 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2719 PyErr_SetString(PyExc_TypeError,
2720 "spawnve(): env.keys() or env.values() is not a list");
2721 goto fail_2;
2722 }
Tim Peters5aa91602002-01-30 05:46:57 +00002723
Guido van Rossuma1065681999-01-25 23:20:23 +00002724 for (pos = 0; pos < i; pos++) {
2725 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002726 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00002727
2728 key = PyList_GetItem(keys, pos);
2729 val = PyList_GetItem(vals, pos);
2730 if (!key || !val)
2731 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002732
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002733 if (!PyArg_Parse(
2734 key,
2735 "s;spawnve() arg 3 contains a non-string key",
2736 &k) ||
2737 !PyArg_Parse(
2738 val,
2739 "s;spawnve() arg 3 contains a non-string value",
2740 &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00002741 {
2742 goto fail_2;
2743 }
Tim Petersc8996f52001-12-03 20:41:00 +00002744 len = PyString_Size(key) + PyString_Size(val) + 2;
2745 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00002746 if (p == NULL) {
2747 PyErr_NoMemory();
2748 goto fail_2;
2749 }
Tim Petersc8996f52001-12-03 20:41:00 +00002750 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00002751 envlist[envc++] = p;
2752 }
2753 envlist[envc] = 0;
2754
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002755#if defined(PYOS_OS2) && defined(PYCC_GCC)
2756 Py_BEGIN_ALLOW_THREADS
2757 spawnval = spawnve(mode, path, argvlist, envlist);
2758 Py_END_ALLOW_THREADS
2759#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002760 if (mode == _OLD_P_OVERLAY)
2761 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00002762
2763 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002764 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00002765 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002766#endif
Tim Peters25059d32001-12-07 20:35:43 +00002767
Fred Drake699f3522000-06-29 21:12:41 +00002768 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002769 (void) posix_error();
2770 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002771#if SIZEOF_LONG == SIZEOF_VOID_P
2772 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002773#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00002774 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002775#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002776
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002777 fail_2:
Guido van Rossuma1065681999-01-25 23:20:23 +00002778 while (--envc >= 0)
2779 PyMem_DEL(envlist[envc]);
2780 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002781 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002782 free_string_array(argvlist, lastarg);
Guido van Rossuma1065681999-01-25 23:20:23 +00002783 Py_XDECREF(vals);
2784 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002785 fail_0:
2786 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002787 return res;
2788}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00002789
2790/* OS/2 supports spawnvp & spawnvpe natively */
2791#if defined(PYOS_OS2)
2792PyDoc_STRVAR(posix_spawnvp__doc__,
2793"spawnvp(mode, file, args)\n\n\
2794Execute the program 'file' in a new process, using the environment\n\
2795search path to find the file.\n\
2796\n\
2797 mode: mode of process creation\n\
2798 file: executable file name\n\
2799 args: tuple or list of strings");
2800
2801static PyObject *
2802posix_spawnvp(PyObject *self, PyObject *args)
2803{
2804 char *path;
2805 PyObject *argv;
2806 char **argvlist;
2807 int mode, i, argc;
2808 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002809 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00002810
2811 /* spawnvp has three arguments: (mode, path, argv), where
2812 argv is a list or tuple of strings. */
2813
2814 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
2815 Py_FileSystemDefaultEncoding,
2816 &path, &argv))
2817 return NULL;
2818 if (PyList_Check(argv)) {
2819 argc = PyList_Size(argv);
2820 getitem = PyList_GetItem;
2821 }
2822 else if (PyTuple_Check(argv)) {
2823 argc = PyTuple_Size(argv);
2824 getitem = PyTuple_GetItem;
2825 }
2826 else {
2827 PyErr_SetString(PyExc_TypeError,
2828 "spawnvp() arg 2 must be a tuple or list");
2829 PyMem_Free(path);
2830 return NULL;
2831 }
2832
2833 argvlist = PyMem_NEW(char *, argc+1);
2834 if (argvlist == NULL) {
2835 PyMem_Free(path);
2836 return PyErr_NoMemory();
2837 }
2838 for (i = 0; i < argc; i++) {
2839 if (!PyArg_Parse((*getitem)(argv, i), "et",
2840 Py_FileSystemDefaultEncoding,
2841 &argvlist[i])) {
2842 free_string_array(argvlist, i);
2843 PyErr_SetString(
2844 PyExc_TypeError,
2845 "spawnvp() arg 2 must contain only strings");
2846 PyMem_Free(path);
2847 return NULL;
2848 }
2849 }
2850 argvlist[argc] = NULL;
2851
2852 Py_BEGIN_ALLOW_THREADS
2853#if defined(PYCC_GCC)
2854 spawnval = spawnvp(mode, path, argvlist);
2855#else
2856 spawnval = _spawnvp(mode, path, argvlist);
2857#endif
2858 Py_END_ALLOW_THREADS
2859
2860 free_string_array(argvlist, argc);
2861 PyMem_Free(path);
2862
2863 if (spawnval == -1)
2864 return posix_error();
2865 else
2866 return Py_BuildValue("l", (long) spawnval);
2867}
2868
2869
2870PyDoc_STRVAR(posix_spawnvpe__doc__,
2871"spawnvpe(mode, file, args, env)\n\n\
2872Execute the program 'file' in a new process, using the environment\n\
2873search path to find the file.\n\
2874\n\
2875 mode: mode of process creation\n\
2876 file: executable file name\n\
2877 args: tuple or list of arguments\n\
2878 env: dictionary of strings mapping to strings");
2879
2880static PyObject *
2881posix_spawnvpe(PyObject *self, PyObject *args)
2882{
2883 char *path;
2884 PyObject *argv, *env;
2885 char **argvlist;
2886 char **envlist;
2887 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
2888 int mode, i, pos, argc, envc;
2889 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002890 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00002891 int lastarg = 0;
2892
2893 /* spawnvpe has four arguments: (mode, path, argv, env), where
2894 argv is a list or tuple of strings and env is a dictionary
2895 like posix.environ. */
2896
2897 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
2898 Py_FileSystemDefaultEncoding,
2899 &path, &argv, &env))
2900 return NULL;
2901 if (PyList_Check(argv)) {
2902 argc = PyList_Size(argv);
2903 getitem = PyList_GetItem;
2904 }
2905 else if (PyTuple_Check(argv)) {
2906 argc = PyTuple_Size(argv);
2907 getitem = PyTuple_GetItem;
2908 }
2909 else {
2910 PyErr_SetString(PyExc_TypeError,
2911 "spawnvpe() arg 2 must be a tuple or list");
2912 goto fail_0;
2913 }
2914 if (!PyMapping_Check(env)) {
2915 PyErr_SetString(PyExc_TypeError,
2916 "spawnvpe() arg 3 must be a mapping object");
2917 goto fail_0;
2918 }
2919
2920 argvlist = PyMem_NEW(char *, argc+1);
2921 if (argvlist == NULL) {
2922 PyErr_NoMemory();
2923 goto fail_0;
2924 }
2925 for (i = 0; i < argc; i++) {
2926 if (!PyArg_Parse((*getitem)(argv, i),
2927 "et;spawnvpe() arg 2 must contain only strings",
2928 Py_FileSystemDefaultEncoding,
2929 &argvlist[i]))
2930 {
2931 lastarg = i;
2932 goto fail_1;
2933 }
2934 }
2935 lastarg = argc;
2936 argvlist[argc] = NULL;
2937
2938 i = PyMapping_Size(env);
2939 if (i < 0)
2940 goto fail_1;
2941 envlist = PyMem_NEW(char *, i + 1);
2942 if (envlist == NULL) {
2943 PyErr_NoMemory();
2944 goto fail_1;
2945 }
2946 envc = 0;
2947 keys = PyMapping_Keys(env);
2948 vals = PyMapping_Values(env);
2949 if (!keys || !vals)
2950 goto fail_2;
2951 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2952 PyErr_SetString(PyExc_TypeError,
2953 "spawnvpe(): env.keys() or env.values() is not a list");
2954 goto fail_2;
2955 }
2956
2957 for (pos = 0; pos < i; pos++) {
2958 char *p, *k, *v;
2959 size_t len;
2960
2961 key = PyList_GetItem(keys, pos);
2962 val = PyList_GetItem(vals, pos);
2963 if (!key || !val)
2964 goto fail_2;
2965
2966 if (!PyArg_Parse(
2967 key,
2968 "s;spawnvpe() arg 3 contains a non-string key",
2969 &k) ||
2970 !PyArg_Parse(
2971 val,
2972 "s;spawnvpe() arg 3 contains a non-string value",
2973 &v))
2974 {
2975 goto fail_2;
2976 }
2977 len = PyString_Size(key) + PyString_Size(val) + 2;
2978 p = PyMem_NEW(char, len);
2979 if (p == NULL) {
2980 PyErr_NoMemory();
2981 goto fail_2;
2982 }
2983 PyOS_snprintf(p, len, "%s=%s", k, v);
2984 envlist[envc++] = p;
2985 }
2986 envlist[envc] = 0;
2987
2988 Py_BEGIN_ALLOW_THREADS
2989#if defined(PYCC_GCC)
2990 spawnval = spawnve(mode, path, argvlist, envlist);
2991#else
2992 spawnval = _spawnve(mode, path, argvlist, envlist);
2993#endif
2994 Py_END_ALLOW_THREADS
2995
2996 if (spawnval == -1)
2997 (void) posix_error();
2998 else
2999 res = Py_BuildValue("l", (long) spawnval);
3000
3001 fail_2:
3002 while (--envc >= 0)
3003 PyMem_DEL(envlist[envc]);
3004 PyMem_DEL(envlist);
3005 fail_1:
3006 free_string_array(argvlist, lastarg);
3007 Py_XDECREF(vals);
3008 Py_XDECREF(keys);
3009 fail_0:
3010 PyMem_Free(path);
3011 return res;
3012}
3013#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003014#endif /* HAVE_SPAWNV */
3015
3016
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003017#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003018PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003019"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003020Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3021\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003022Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003023
3024static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003025posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003026{
Neal Norwitze241ce82003-02-17 18:17:05 +00003027 int pid = fork1();
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003028 if (pid == -1)
3029 return posix_error();
3030 PyOS_AfterFork();
3031 return PyInt_FromLong((long)pid);
3032}
3033#endif
3034
3035
Guido van Rossumad0ee831995-03-01 10:34:45 +00003036#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003037PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003038"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003039Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003040Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003041
Barry Warsaw53699e91996-12-10 23:23:01 +00003042static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003043posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003044{
Neal Norwitze241ce82003-02-17 18:17:05 +00003045 int pid = fork();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003046 if (pid == -1)
3047 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003048 if (pid == 0)
3049 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00003050 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003051}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003052#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003053
Neal Norwitzb59798b2003-03-21 01:43:31 +00003054/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00003055/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3056#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00003057#define DEV_PTY_FILE "/dev/ptc"
3058#define HAVE_DEV_PTMX
3059#else
3060#define DEV_PTY_FILE "/dev/ptmx"
3061#endif
3062
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003063#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003064#ifdef HAVE_PTY_H
3065#include <pty.h>
3066#else
3067#ifdef HAVE_LIBUTIL_H
3068#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00003069#endif /* HAVE_LIBUTIL_H */
3070#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00003071#ifdef HAVE_STROPTS_H
3072#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003073#endif
3074#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003075
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003076#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003077PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003078"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003079Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003080
3081static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003082posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003083{
3084 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003085#ifndef HAVE_OPENPTY
3086 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003087#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003088#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003089 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003090#ifdef sun
3091 extern char *ptsname();
3092#endif
3093#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00003094
Thomas Wouters70c21a12000-07-14 14:28:33 +00003095#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00003096 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
3097 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003098#elif defined(HAVE__GETPTY)
Thomas Wouters70c21a12000-07-14 14:28:33 +00003099 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
3100 if (slave_name == NULL)
3101 return posix_error();
3102
3103 slave_fd = open(slave_name, O_RDWR);
3104 if (slave_fd < 0)
3105 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003106#else
Neal Norwitzb59798b2003-03-21 01:43:31 +00003107 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003108 if (master_fd < 0)
3109 return posix_error();
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003110 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003111 /* change permission of slave */
3112 if (grantpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003113 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003114 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003115 }
3116 /* unlock slave */
3117 if (unlockpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003118 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003119 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003120 }
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003121 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003122 slave_name = ptsname(master_fd); /* get name of slave */
3123 if (slave_name == NULL)
3124 return posix_error();
3125 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
3126 if (slave_fd < 0)
3127 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003128#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003129 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
3130 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00003131#ifndef __hpux
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003132 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00003133#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003134#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00003135#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00003136
Fred Drake8cef4cf2000-06-28 16:40:38 +00003137 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00003138
Fred Drake8cef4cf2000-06-28 16:40:38 +00003139}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003140#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003141
3142#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003143PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003144"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00003145Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
3146Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003147To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003148
3149static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003150posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003151{
Neal Norwitz24b3c222005-09-19 06:43:44 +00003152 int master_fd = -1, pid;
Tim Peters5aa91602002-01-30 05:46:57 +00003153
Fred Drake8cef4cf2000-06-28 16:40:38 +00003154 pid = forkpty(&master_fd, NULL, NULL, NULL);
3155 if (pid == -1)
3156 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003157 if (pid == 0)
3158 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00003159 return Py_BuildValue("(ii)", pid, master_fd);
3160}
3161#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003162
Guido van Rossumad0ee831995-03-01 10:34:45 +00003163#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003164PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003165"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003166Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003167
Barry Warsaw53699e91996-12-10 23:23:01 +00003168static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003169posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003170{
Barry Warsaw53699e91996-12-10 23:23:01 +00003171 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003172}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003173#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003174
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003175
Guido van Rossumad0ee831995-03-01 10:34:45 +00003176#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003177PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003178"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003179Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003180
Barry Warsaw53699e91996-12-10 23:23:01 +00003181static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003182posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003183{
Barry Warsaw53699e91996-12-10 23:23:01 +00003184 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003185}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003186#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003187
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003188
Guido van Rossumad0ee831995-03-01 10:34:45 +00003189#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003190PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003191"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003192Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003193
Barry Warsaw53699e91996-12-10 23:23:01 +00003194static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003195posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003196{
Barry Warsaw53699e91996-12-10 23:23:01 +00003197 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003198}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003199#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003200
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003201
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003202PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003203"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003204Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003205
Barry Warsaw53699e91996-12-10 23:23:01 +00003206static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003207posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003208{
Barry Warsaw53699e91996-12-10 23:23:01 +00003209 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003210}
3211
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003212
Fred Drakec9680921999-12-13 16:37:25 +00003213#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003214PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003215"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003216Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00003217
3218static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003219posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00003220{
3221 PyObject *result = NULL;
3222
Fred Drakec9680921999-12-13 16:37:25 +00003223#ifdef NGROUPS_MAX
3224#define MAX_GROUPS NGROUPS_MAX
3225#else
3226 /* defined to be 16 on Solaris7, so this should be a small number */
3227#define MAX_GROUPS 64
3228#endif
3229 gid_t grouplist[MAX_GROUPS];
3230 int n;
3231
3232 n = getgroups(MAX_GROUPS, grouplist);
3233 if (n < 0)
3234 posix_error();
3235 else {
3236 result = PyList_New(n);
3237 if (result != NULL) {
Fred Drakec9680921999-12-13 16:37:25 +00003238 int i;
3239 for (i = 0; i < n; ++i) {
Neal Norwitze241ce82003-02-17 18:17:05 +00003240 PyObject *o = PyInt_FromLong((long)grouplist[i]);
Fred Drakec9680921999-12-13 16:37:25 +00003241 if (o == NULL) {
3242 Py_DECREF(result);
3243 result = NULL;
3244 break;
3245 }
3246 PyList_SET_ITEM(result, i, o);
3247 }
3248 }
3249 }
Neal Norwitze241ce82003-02-17 18:17:05 +00003250
Fred Drakec9680921999-12-13 16:37:25 +00003251 return result;
3252}
3253#endif
3254
Martin v. Löwis606edc12002-06-13 21:09:11 +00003255#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003256PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003257"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003258Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00003259
3260static PyObject *
3261posix_getpgid(PyObject *self, PyObject *args)
3262{
3263 int pid, pgid;
3264 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
3265 return NULL;
3266 pgid = getpgid(pid);
3267 if (pgid < 0)
3268 return posix_error();
3269 return PyInt_FromLong((long)pgid);
3270}
3271#endif /* HAVE_GETPGID */
3272
3273
Guido van Rossumb6775db1994-08-01 11:34:53 +00003274#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003275PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003276"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003277Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003278
Barry Warsaw53699e91996-12-10 23:23:01 +00003279static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003280posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00003281{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003282#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00003283 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003284#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00003285 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003286#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00003287}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003288#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00003289
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003290
Guido van Rossumb6775db1994-08-01 11:34:53 +00003291#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003292PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003293"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003294Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003295
Barry Warsaw53699e91996-12-10 23:23:01 +00003296static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003297posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003298{
Guido van Rossum64933891994-10-20 21:56:42 +00003299#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00003300 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003301#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003302 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003303#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00003304 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003305 Py_INCREF(Py_None);
3306 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003307}
3308
Guido van Rossumb6775db1994-08-01 11:34:53 +00003309#endif /* HAVE_SETPGRP */
3310
Guido van Rossumad0ee831995-03-01 10:34:45 +00003311#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003312PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003313"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003314Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003315
Barry Warsaw53699e91996-12-10 23:23:01 +00003316static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003317posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003318{
Barry Warsaw53699e91996-12-10 23:23:01 +00003319 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003320}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003321#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003322
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003323
Fred Drake12c6e2d1999-12-14 21:25:03 +00003324#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003325PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003326"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003327Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00003328
3329static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003330posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00003331{
Neal Norwitze241ce82003-02-17 18:17:05 +00003332 PyObject *result = NULL;
Fred Drakea30680b2000-12-06 21:24:28 +00003333 char *name;
3334 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00003335
Fred Drakea30680b2000-12-06 21:24:28 +00003336 errno = 0;
3337 name = getlogin();
3338 if (name == NULL) {
3339 if (errno)
3340 posix_error();
3341 else
3342 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00003343 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00003344 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00003345 else
3346 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00003347 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00003348
Fred Drake12c6e2d1999-12-14 21:25:03 +00003349 return result;
3350}
3351#endif
3352
Guido van Rossumad0ee831995-03-01 10:34:45 +00003353#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003354PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003355"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003356Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003357
Barry Warsaw53699e91996-12-10 23:23:01 +00003358static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003359posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003360{
Barry Warsaw53699e91996-12-10 23:23:01 +00003361 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003362}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003363#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003364
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003365
Guido van Rossumad0ee831995-03-01 10:34:45 +00003366#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003367PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003368"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003369Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003370
Barry Warsaw53699e91996-12-10 23:23:01 +00003371static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003372posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003373{
3374 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003375 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00003376 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003377#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003378 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
3379 APIRET rc;
3380 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003381 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003382
3383 } else if (sig == XCPT_SIGNAL_KILLPROC) {
3384 APIRET rc;
3385 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003386 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003387
3388 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003389 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003390#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00003391 if (kill(pid, sig) == -1)
3392 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003393#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003394 Py_INCREF(Py_None);
3395 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003396}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003397#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003398
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003399#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003400PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003401"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003402Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003403
3404static PyObject *
3405posix_killpg(PyObject *self, PyObject *args)
3406{
3407 int pgid, sig;
3408 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
3409 return NULL;
3410 if (killpg(pgid, sig) == -1)
3411 return posix_error();
3412 Py_INCREF(Py_None);
3413 return Py_None;
3414}
3415#endif
3416
Guido van Rossumc0125471996-06-28 18:55:32 +00003417#ifdef HAVE_PLOCK
3418
3419#ifdef HAVE_SYS_LOCK_H
3420#include <sys/lock.h>
3421#endif
3422
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003423PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003424"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003425Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003426
Barry Warsaw53699e91996-12-10 23:23:01 +00003427static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003428posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00003429{
3430 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003431 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00003432 return NULL;
3433 if (plock(op) == -1)
3434 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003435 Py_INCREF(Py_None);
3436 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00003437}
3438#endif
3439
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003440
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003441#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003442PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003443"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003444Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003445
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003446#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003447#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003448static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003449async_system(const char *command)
3450{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003451 char errormsg[256], args[1024];
3452 RESULTCODES rcodes;
3453 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003454
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003455 char *shell = getenv("COMSPEC");
3456 if (!shell)
3457 shell = "cmd";
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003458
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003459 /* avoid overflowing the argument buffer */
3460 if (strlen(shell) + 3 + strlen(command) >= 1024)
3461 return ERROR_NOT_ENOUGH_MEMORY
3462
3463 args[0] = '\0';
3464 strcat(args, shell);
3465 strcat(args, "/c ");
3466 strcat(args, command);
3467
3468 /* execute asynchronously, inheriting the environment */
3469 rc = DosExecPgm(errormsg,
3470 sizeof(errormsg),
3471 EXEC_ASYNC,
3472 args,
3473 NULL,
3474 &rcodes,
3475 shell);
3476 return rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003477}
3478
Guido van Rossumd48f2521997-12-05 22:19:34 +00003479static FILE *
3480popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003481{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003482 int oldfd, tgtfd;
3483 HFILE pipeh[2];
3484 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003485
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003486 /* mode determines which of stdin or stdout is reconnected to
3487 * the pipe to the child
3488 */
3489 if (strchr(mode, 'r') != NULL) {
3490 tgt_fd = 1; /* stdout */
3491 } else if (strchr(mode, 'w')) {
3492 tgt_fd = 0; /* stdin */
3493 } else {
3494 *err = ERROR_INVALID_ACCESS;
3495 return NULL;
3496 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003497
Andrew MacIntyrea3be2582004-12-18 09:51:05 +00003498 /* setup the pipe */
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003499 if ((rc = DosCreatePipe(&pipeh[0], &pipeh[1], pipesize)) != NO_ERROR) {
3500 *err = rc;
3501 return NULL;
3502 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003503
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003504 /* prevent other threads accessing stdio */
3505 DosEnterCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003506
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003507 /* reconnect stdio and execute child */
3508 oldfd = dup(tgtfd);
3509 close(tgtfd);
3510 if (dup2(pipeh[tgtfd], tgtfd) == 0) {
3511 DosClose(pipeh[tgtfd]);
3512 rc = async_system(command);
3513 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003514
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003515 /* restore stdio */
3516 dup2(oldfd, tgtfd);
3517 close(oldfd);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003518
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003519 /* allow other threads access to stdio */
3520 DosExitCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003521
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003522 /* if execution of child was successful return file stream */
3523 if (rc == NO_ERROR)
3524 return fdopen(pipeh[1 - tgtfd], mode);
3525 else {
3526 DosClose(pipeh[1 - tgtfd]);
3527 *err = rc;
3528 return NULL;
3529 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003530}
3531
3532static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003533posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003534{
3535 char *name;
3536 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00003537 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003538 FILE *fp;
3539 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003540 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003541 return NULL;
3542 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00003543 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003544 Py_END_ALLOW_THREADS
3545 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003546 return os2_error(err);
3547
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003548 f = PyFile_FromFile(fp, name, mode, fclose);
3549 if (f != NULL)
3550 PyFile_SetBufSize(f, bufsize);
3551 return f;
3552}
3553
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003554#elif defined(PYCC_GCC)
3555
3556/* standard posix version of popen() support */
3557static PyObject *
3558posix_popen(PyObject *self, PyObject *args)
3559{
3560 char *name;
3561 char *mode = "r";
3562 int bufsize = -1;
3563 FILE *fp;
3564 PyObject *f;
3565 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
3566 return NULL;
3567 Py_BEGIN_ALLOW_THREADS
3568 fp = popen(name, mode);
3569 Py_END_ALLOW_THREADS
3570 if (fp == NULL)
3571 return posix_error();
3572 f = PyFile_FromFile(fp, name, mode, pclose);
3573 if (f != NULL)
3574 PyFile_SetBufSize(f, bufsize);
3575 return f;
3576}
3577
3578/* fork() under OS/2 has lots'o'warts
3579 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
3580 * most of this code is a ripoff of the win32 code, but using the
3581 * capabilities of EMX's C library routines
3582 */
3583
3584/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
3585#define POPEN_1 1
3586#define POPEN_2 2
3587#define POPEN_3 3
3588#define POPEN_4 4
3589
3590static PyObject *_PyPopen(char *, int, int, int);
3591static int _PyPclose(FILE *file);
3592
3593/*
3594 * Internal dictionary mapping popen* file pointers to process handles,
3595 * for use when retrieving the process exit code. See _PyPclose() below
3596 * for more information on this dictionary's use.
3597 */
3598static PyObject *_PyPopenProcs = NULL;
3599
3600/* os2emx version of popen2()
3601 *
3602 * The result of this function is a pipe (file) connected to the
3603 * process's stdin, and a pipe connected to the process's stdout.
3604 */
3605
3606static PyObject *
3607os2emx_popen2(PyObject *self, PyObject *args)
3608{
3609 PyObject *f;
3610 int tm=0;
3611
3612 char *cmdstring;
3613 char *mode = "t";
3614 int bufsize = -1;
3615 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
3616 return NULL;
3617
3618 if (*mode == 't')
3619 tm = O_TEXT;
3620 else if (*mode != 'b') {
3621 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3622 return NULL;
3623 } else
3624 tm = O_BINARY;
3625
3626 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
3627
3628 return f;
3629}
3630
3631/*
3632 * Variation on os2emx.popen2
3633 *
3634 * The result of this function is 3 pipes - the process's stdin,
3635 * stdout and stderr
3636 */
3637
3638static PyObject *
3639os2emx_popen3(PyObject *self, PyObject *args)
3640{
3641 PyObject *f;
3642 int tm = 0;
3643
3644 char *cmdstring;
3645 char *mode = "t";
3646 int bufsize = -1;
3647 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
3648 return NULL;
3649
3650 if (*mode == 't')
3651 tm = O_TEXT;
3652 else if (*mode != 'b') {
3653 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3654 return NULL;
3655 } else
3656 tm = O_BINARY;
3657
3658 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
3659
3660 return f;
3661}
3662
3663/*
3664 * Variation on os2emx.popen2
3665 *
Tim Peters11b23062003-04-23 02:39:17 +00003666 * The result of this function is 2 pipes - the processes stdin,
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003667 * and stdout+stderr combined as a single pipe.
3668 */
3669
3670static PyObject *
3671os2emx_popen4(PyObject *self, PyObject *args)
3672{
3673 PyObject *f;
3674 int tm = 0;
3675
3676 char *cmdstring;
3677 char *mode = "t";
3678 int bufsize = -1;
3679 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
3680 return NULL;
3681
3682 if (*mode == 't')
3683 tm = O_TEXT;
3684 else if (*mode != 'b') {
3685 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3686 return NULL;
3687 } else
3688 tm = O_BINARY;
3689
3690 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
3691
3692 return f;
3693}
3694
3695/* a couple of structures for convenient handling of multiple
3696 * file handles and pipes
3697 */
3698struct file_ref
3699{
3700 int handle;
3701 int flags;
3702};
3703
3704struct pipe_ref
3705{
3706 int rd;
3707 int wr;
3708};
3709
3710/* The following code is derived from the win32 code */
3711
3712static PyObject *
3713_PyPopen(char *cmdstring, int mode, int n, int bufsize)
3714{
3715 struct file_ref stdio[3];
3716 struct pipe_ref p_fd[3];
3717 FILE *p_s[3];
3718 int file_count, i, pipe_err, pipe_pid;
3719 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
3720 PyObject *f, *p_f[3];
3721
3722 /* file modes for subsequent fdopen's on pipe handles */
3723 if (mode == O_TEXT)
3724 {
3725 rd_mode = "rt";
3726 wr_mode = "wt";
3727 }
3728 else
3729 {
3730 rd_mode = "rb";
3731 wr_mode = "wb";
3732 }
3733
3734 /* prepare shell references */
3735 if ((shell = getenv("EMXSHELL")) == NULL)
3736 if ((shell = getenv("COMSPEC")) == NULL)
3737 {
3738 errno = ENOENT;
3739 return posix_error();
3740 }
3741
3742 sh_name = _getname(shell);
3743 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
3744 opt = "/c";
3745 else
3746 opt = "-c";
3747
3748 /* save current stdio fds + their flags, and set not inheritable */
3749 i = pipe_err = 0;
3750 while (pipe_err >= 0 && i < 3)
3751 {
3752 pipe_err = stdio[i].handle = dup(i);
3753 stdio[i].flags = fcntl(i, F_GETFD, 0);
3754 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
3755 i++;
3756 }
3757 if (pipe_err < 0)
3758 {
3759 /* didn't get them all saved - clean up and bail out */
3760 int saved_err = errno;
3761 while (i-- > 0)
3762 {
3763 close(stdio[i].handle);
3764 }
3765 errno = saved_err;
3766 return posix_error();
3767 }
3768
3769 /* create pipe ends */
3770 file_count = 2;
3771 if (n == POPEN_3)
3772 file_count = 3;
3773 i = pipe_err = 0;
3774 while ((pipe_err == 0) && (i < file_count))
3775 pipe_err = pipe((int *)&p_fd[i++]);
3776 if (pipe_err < 0)
3777 {
3778 /* didn't get them all made - clean up and bail out */
3779 while (i-- > 0)
3780 {
3781 close(p_fd[i].wr);
3782 close(p_fd[i].rd);
3783 }
3784 errno = EPIPE;
3785 return posix_error();
3786 }
3787
3788 /* change the actual standard IO streams over temporarily,
3789 * making the retained pipe ends non-inheritable
3790 */
3791 pipe_err = 0;
3792
3793 /* - stdin */
3794 if (dup2(p_fd[0].rd, 0) == 0)
3795 {
3796 close(p_fd[0].rd);
3797 i = fcntl(p_fd[0].wr, F_GETFD, 0);
3798 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
3799 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
3800 {
3801 close(p_fd[0].wr);
3802 pipe_err = -1;
3803 }
3804 }
3805 else
3806 {
3807 pipe_err = -1;
3808 }
3809
3810 /* - stdout */
3811 if (pipe_err == 0)
3812 {
3813 if (dup2(p_fd[1].wr, 1) == 1)
3814 {
3815 close(p_fd[1].wr);
3816 i = fcntl(p_fd[1].rd, F_GETFD, 0);
3817 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
3818 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
3819 {
3820 close(p_fd[1].rd);
3821 pipe_err = -1;
3822 }
3823 }
3824 else
3825 {
3826 pipe_err = -1;
3827 }
3828 }
3829
3830 /* - stderr, as required */
3831 if (pipe_err == 0)
3832 switch (n)
3833 {
3834 case POPEN_3:
3835 {
3836 if (dup2(p_fd[2].wr, 2) == 2)
3837 {
3838 close(p_fd[2].wr);
3839 i = fcntl(p_fd[2].rd, F_GETFD, 0);
3840 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
3841 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
3842 {
3843 close(p_fd[2].rd);
3844 pipe_err = -1;
3845 }
3846 }
3847 else
3848 {
3849 pipe_err = -1;
3850 }
3851 break;
3852 }
3853
3854 case POPEN_4:
3855 {
3856 if (dup2(1, 2) != 2)
3857 {
3858 pipe_err = -1;
3859 }
3860 break;
3861 }
3862 }
3863
3864 /* spawn the child process */
3865 if (pipe_err == 0)
3866 {
3867 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
3868 if (pipe_pid == -1)
3869 {
3870 pipe_err = -1;
3871 }
3872 else
3873 {
3874 /* save the PID into the FILE structure
3875 * NOTE: this implementation doesn't actually
3876 * take advantage of this, but do it for
3877 * completeness - AIM Apr01
3878 */
3879 for (i = 0; i < file_count; i++)
3880 p_s[i]->_pid = pipe_pid;
3881 }
3882 }
3883
3884 /* reset standard IO to normal */
3885 for (i = 0; i < 3; i++)
3886 {
3887 dup2(stdio[i].handle, i);
3888 fcntl(i, F_SETFD, stdio[i].flags);
3889 close(stdio[i].handle);
3890 }
3891
3892 /* if any remnant problems, clean up and bail out */
3893 if (pipe_err < 0)
3894 {
3895 for (i = 0; i < 3; i++)
3896 {
3897 close(p_fd[i].rd);
3898 close(p_fd[i].wr);
3899 }
3900 errno = EPIPE;
3901 return posix_error_with_filename(cmdstring);
3902 }
3903
3904 /* build tuple of file objects to return */
3905 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
3906 PyFile_SetBufSize(p_f[0], bufsize);
3907 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
3908 PyFile_SetBufSize(p_f[1], bufsize);
3909 if (n == POPEN_3)
3910 {
3911 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
3912 PyFile_SetBufSize(p_f[0], bufsize);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00003913 f = PyTuple_Pack(3, p_f[0], p_f[1], p_f[2]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003914 }
3915 else
Raymond Hettinger8ae46892003-10-12 19:09:37 +00003916 f = PyTuple_Pack(2, p_f[0], p_f[1]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003917
3918 /*
3919 * Insert the files we've created into the process dictionary
3920 * all referencing the list with the process handle and the
3921 * initial number of files (see description below in _PyPclose).
3922 * Since if _PyPclose later tried to wait on a process when all
3923 * handles weren't closed, it could create a deadlock with the
3924 * child, we spend some energy here to try to ensure that we
3925 * either insert all file handles into the dictionary or none
3926 * at all. It's a little clumsy with the various popen modes
3927 * and variable number of files involved.
3928 */
3929 if (!_PyPopenProcs)
3930 {
3931 _PyPopenProcs = PyDict_New();
3932 }
3933
3934 if (_PyPopenProcs)
3935 {
3936 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
3937 int ins_rc[3];
3938
3939 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
3940 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
3941
3942 procObj = PyList_New(2);
3943 pidObj = PyInt_FromLong((long) pipe_pid);
3944 intObj = PyInt_FromLong((long) file_count);
3945
3946 if (procObj && pidObj && intObj)
3947 {
3948 PyList_SetItem(procObj, 0, pidObj);
3949 PyList_SetItem(procObj, 1, intObj);
3950
3951 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
3952 if (fileObj[0])
3953 {
3954 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
3955 fileObj[0],
3956 procObj);
3957 }
3958 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
3959 if (fileObj[1])
3960 {
3961 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
3962 fileObj[1],
3963 procObj);
3964 }
3965 if (file_count >= 3)
3966 {
3967 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
3968 if (fileObj[2])
3969 {
3970 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
3971 fileObj[2],
3972 procObj);
3973 }
3974 }
3975
3976 if (ins_rc[0] < 0 || !fileObj[0] ||
3977 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
3978 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
3979 {
3980 /* Something failed - remove any dictionary
3981 * entries that did make it.
3982 */
3983 if (!ins_rc[0] && fileObj[0])
3984 {
3985 PyDict_DelItem(_PyPopenProcs,
3986 fileObj[0]);
3987 }
3988 if (!ins_rc[1] && fileObj[1])
3989 {
3990 PyDict_DelItem(_PyPopenProcs,
3991 fileObj[1]);
3992 }
3993 if (!ins_rc[2] && fileObj[2])
3994 {
3995 PyDict_DelItem(_PyPopenProcs,
3996 fileObj[2]);
3997 }
3998 }
3999 }
Tim Peters11b23062003-04-23 02:39:17 +00004000
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004001 /*
4002 * Clean up our localized references for the dictionary keys
4003 * and value since PyDict_SetItem will Py_INCREF any copies
4004 * that got placed in the dictionary.
4005 */
4006 Py_XDECREF(procObj);
4007 Py_XDECREF(fileObj[0]);
4008 Py_XDECREF(fileObj[1]);
4009 Py_XDECREF(fileObj[2]);
4010 }
4011
4012 /* Child is launched. */
4013 return f;
4014}
4015
4016/*
4017 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4018 * exit code for the child process and return as a result of the close.
4019 *
4020 * This function uses the _PyPopenProcs dictionary in order to map the
4021 * input file pointer to information about the process that was
4022 * originally created by the popen* call that created the file pointer.
4023 * The dictionary uses the file pointer as a key (with one entry
4024 * inserted for each file returned by the original popen* call) and a
4025 * single list object as the value for all files from a single call.
4026 * The list object contains the Win32 process handle at [0], and a file
4027 * count at [1], which is initialized to the total number of file
4028 * handles using that list.
4029 *
4030 * This function closes whichever handle it is passed, and decrements
4031 * the file count in the dictionary for the process handle pointed to
4032 * by this file. On the last close (when the file count reaches zero),
4033 * this function will wait for the child process and then return its
4034 * exit code as the result of the close() operation. This permits the
4035 * files to be closed in any order - it is always the close() of the
4036 * final handle that will return the exit code.
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004037 *
4038 * NOTE: This function is currently called with the GIL released.
4039 * hence we use the GILState API to manage our state.
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004040 */
4041
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004042static int _PyPclose(FILE *file)
4043{
4044 int result;
4045 int exit_code;
4046 int pipe_pid;
4047 PyObject *procObj, *pidObj, *intObj, *fileObj;
4048 int file_count;
4049#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004050 PyGILState_STATE state;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004051#endif
4052
4053 /* Close the file handle first, to ensure it can't block the
4054 * child from exiting if it's the last handle.
4055 */
4056 result = fclose(file);
4057
4058#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004059 state = PyGILState_Ensure();
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004060#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004061 if (_PyPopenProcs)
4062 {
4063 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4064 (procObj = PyDict_GetItem(_PyPopenProcs,
4065 fileObj)) != NULL &&
4066 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
4067 (intObj = PyList_GetItem(procObj,1)) != NULL)
4068 {
4069 pipe_pid = (int) PyInt_AsLong(pidObj);
4070 file_count = (int) PyInt_AsLong(intObj);
4071
4072 if (file_count > 1)
4073 {
4074 /* Still other files referencing process */
4075 file_count--;
4076 PyList_SetItem(procObj,1,
4077 PyInt_FromLong((long) file_count));
4078 }
4079 else
4080 {
4081 /* Last file for this process */
4082 if (result != EOF &&
4083 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
4084 {
4085 /* extract exit status */
4086 if (WIFEXITED(exit_code))
4087 {
4088 result = WEXITSTATUS(exit_code);
4089 }
4090 else
4091 {
4092 errno = EPIPE;
4093 result = -1;
4094 }
4095 }
4096 else
4097 {
4098 /* Indicate failure - this will cause the file object
4099 * to raise an I/O error and translate the last
4100 * error code from errno. We do have a problem with
4101 * last errors that overlap the normal errno table,
4102 * but that's a consistent problem with the file object.
4103 */
4104 result = -1;
4105 }
4106 }
4107
4108 /* Remove this file pointer from dictionary */
4109 PyDict_DelItem(_PyPopenProcs, fileObj);
4110
4111 if (PyDict_Size(_PyPopenProcs) == 0)
4112 {
4113 Py_DECREF(_PyPopenProcs);
4114 _PyPopenProcs = NULL;
4115 }
4116
4117 } /* if object retrieval ok */
4118
4119 Py_XDECREF(fileObj);
4120 } /* if _PyPopenProcs */
4121
4122#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004123 PyGILState_Release(state);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004124#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004125 return result;
4126}
4127
4128#endif /* PYCC_??? */
4129
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004130#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004131
4132/*
4133 * Portable 'popen' replacement for Win32.
4134 *
4135 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
4136 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00004137 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004138 */
4139
4140#include <malloc.h>
4141#include <io.h>
4142#include <fcntl.h>
4143
4144/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
4145#define POPEN_1 1
4146#define POPEN_2 2
4147#define POPEN_3 3
4148#define POPEN_4 4
4149
4150static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004151static int _PyPclose(FILE *file);
4152
4153/*
4154 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00004155 * for use when retrieving the process exit code. See _PyPclose() below
4156 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004157 */
4158static PyObject *_PyPopenProcs = NULL;
4159
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004160
4161/* popen that works from a GUI.
4162 *
4163 * The result of this function is a pipe (file) connected to the
4164 * processes stdin or stdout, depending on the requested mode.
4165 */
4166
4167static PyObject *
4168posix_popen(PyObject *self, PyObject *args)
4169{
Raymond Hettingerb5cb6652003-09-01 22:25:41 +00004170 PyObject *f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004171 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004172
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004173 char *cmdstring;
4174 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004175 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004176 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004177 return NULL;
4178
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004179 if (*mode == 'r')
4180 tm = _O_RDONLY;
4181 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00004182 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004183 return NULL;
4184 } else
4185 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00004186
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004187 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004188 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004189 return NULL;
4190 }
4191
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004192 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004193 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004194 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004195 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004196 else
4197 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
4198
4199 return f;
4200}
4201
4202/* Variation on win32pipe.popen
4203 *
4204 * The result of this function is a pipe (file) connected to the
4205 * process's stdin, and a pipe connected to the process's stdout.
4206 */
4207
4208static PyObject *
4209win32_popen2(PyObject *self, PyObject *args)
4210{
4211 PyObject *f;
4212 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00004213
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004214 char *cmdstring;
4215 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004216 int bufsize = -1;
4217 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004218 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004219
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004220 if (*mode == 't')
4221 tm = _O_TEXT;
4222 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004223 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004224 return NULL;
4225 } else
4226 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004227
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004228 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004229 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004230 return NULL;
4231 }
4232
4233 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00004234
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004235 return f;
4236}
4237
4238/*
4239 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004240 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004241 * The result of this function is 3 pipes - the process's stdin,
4242 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004243 */
4244
4245static PyObject *
4246win32_popen3(PyObject *self, PyObject *args)
4247{
4248 PyObject *f;
4249 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004250
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004251 char *cmdstring;
4252 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004253 int bufsize = -1;
4254 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004255 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004256
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004257 if (*mode == 't')
4258 tm = _O_TEXT;
4259 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004260 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004261 return NULL;
4262 } else
4263 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004264
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004265 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004266 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004267 return NULL;
4268 }
4269
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004270 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00004271
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004272 return f;
4273}
4274
4275/*
4276 * Variation on win32pipe.popen
4277 *
Tim Peters5aa91602002-01-30 05:46:57 +00004278 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004279 * and stdout+stderr combined as a single pipe.
4280 */
4281
4282static PyObject *
4283win32_popen4(PyObject *self, PyObject *args)
4284{
4285 PyObject *f;
4286 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004287
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004288 char *cmdstring;
4289 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004290 int bufsize = -1;
4291 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004292 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004293
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004294 if (*mode == 't')
4295 tm = _O_TEXT;
4296 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004297 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004298 return NULL;
4299 } else
4300 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004301
4302 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004303 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004304 return NULL;
4305 }
4306
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004307 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004308
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004309 return f;
4310}
4311
Mark Hammond08501372001-01-31 07:30:29 +00004312static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00004313_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004314 HANDLE hStdin,
4315 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00004316 HANDLE hStderr,
4317 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004318{
4319 PROCESS_INFORMATION piProcInfo;
4320 STARTUPINFO siStartInfo;
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004321 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004322 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00004323 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004324 int i;
Martin v. Löwis18e16552006-02-15 17:27:45 +00004325 Py_ssize_t x;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004326
4327 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00004328 char *comshell;
4329
Tim Peters92e4dd82002-10-05 01:47:34 +00004330 s1 = (char *)alloca(i);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004331 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
Martin v. Löwis18e16552006-02-15 17:27:45 +00004332 /* x < i, so x fits into an integer */
4333 return (int)x;
Tim Peters402d5982001-08-27 06:37:48 +00004334
4335 /* Explicitly check if we are using COMMAND.COM. If we are
4336 * then use the w9xpopen hack.
4337 */
4338 comshell = s1 + x;
4339 while (comshell >= s1 && *comshell != '\\')
4340 --comshell;
4341 ++comshell;
4342
4343 if (GetVersion() < 0x80000000 &&
4344 _stricmp(comshell, "command.com") != 0) {
4345 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004346 x = i + strlen(s3) + strlen(cmdstring) + 1;
Tim Peters92e4dd82002-10-05 01:47:34 +00004347 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004348 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00004349 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004350 }
4351 else {
4352 /*
Tim Peters402d5982001-08-27 06:37:48 +00004353 * Oh gag, we're on Win9x or using COMMAND.COM. Use
4354 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004355 */
Mark Hammond08501372001-01-31 07:30:29 +00004356 char modulepath[_MAX_PATH];
4357 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004358 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
4359 for (i = x = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004360 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004361 x = i+1;
4362 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00004363 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00004364 strncat(modulepath,
4365 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00004366 (sizeof(modulepath)/sizeof(modulepath[0]))
4367 -strlen(modulepath));
4368 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00004369 /* Eeek - file-not-found - possibly an embedding
4370 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00004371 */
Tim Peters5aa91602002-01-30 05:46:57 +00004372 strncpy(modulepath,
4373 Py_GetExecPrefix(),
Mark Hammond08501372001-01-31 07:30:29 +00004374 sizeof(modulepath)/sizeof(modulepath[0]));
4375 if (modulepath[strlen(modulepath)-1] != '\\')
4376 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00004377 strncat(modulepath,
4378 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00004379 (sizeof(modulepath)/sizeof(modulepath[0]))
4380 -strlen(modulepath));
4381 /* No where else to look - raise an easily identifiable
4382 error, rather than leaving Windows to report
4383 "file not found" - as the user is probably blissfully
4384 unaware this shim EXE is used, and it will confuse them.
4385 (well, it confused me for a while ;-)
4386 */
4387 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00004388 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00004389 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00004390 "for popen to work with your shell "
4391 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00004392 szConsoleSpawn);
4393 return FALSE;
4394 }
4395 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004396 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00004397 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004398 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00004399
Tim Peters92e4dd82002-10-05 01:47:34 +00004400 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004401 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004402 /* To maintain correct argument passing semantics,
4403 we pass the command-line as it stands, and allow
4404 quoting to be applied. w9xpopen.exe will then
4405 use its argv vector, and re-quote the necessary
4406 args for the ultimate child process.
4407 */
Tim Peters75cdad52001-11-28 22:07:30 +00004408 PyOS_snprintf(
4409 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004410 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004411 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004412 s1,
4413 s3,
4414 cmdstring);
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004415 /* Not passing CREATE_NEW_CONSOLE has been known to
Tim Peters11b23062003-04-23 02:39:17 +00004416 cause random failures on win9x. Specifically a
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004417 dialog:
4418 "Your program accessed mem currently in use at xxx"
4419 and a hopeful warning about the stability of your
4420 system.
4421 Cost is Ctrl+C wont kill children, but anyone
4422 who cares can have a go!
4423 */
4424 dwProcessFlags |= CREATE_NEW_CONSOLE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004425 }
4426 }
4427
4428 /* Could be an else here to try cmd.exe / command.com in the path
4429 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00004430 else {
Tim Peters402d5982001-08-27 06:37:48 +00004431 PyErr_SetString(PyExc_RuntimeError,
4432 "Cannot locate a COMSPEC environment variable to "
4433 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00004434 return FALSE;
4435 }
Tim Peters5aa91602002-01-30 05:46:57 +00004436
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004437 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
4438 siStartInfo.cb = sizeof(STARTUPINFO);
4439 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
4440 siStartInfo.hStdInput = hStdin;
4441 siStartInfo.hStdOutput = hStdout;
4442 siStartInfo.hStdError = hStderr;
4443 siStartInfo.wShowWindow = SW_HIDE;
4444
4445 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004446 s2,
4447 NULL,
4448 NULL,
4449 TRUE,
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004450 dwProcessFlags,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004451 NULL,
4452 NULL,
4453 &siStartInfo,
4454 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004455 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004456 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004457
Mark Hammondb37a3732000-08-14 04:47:33 +00004458 /* Return process handle */
4459 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004460 return TRUE;
4461 }
Tim Peters402d5982001-08-27 06:37:48 +00004462 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004463 return FALSE;
4464}
4465
4466/* The following code is based off of KB: Q190351 */
4467
4468static PyObject *
4469_PyPopen(char *cmdstring, int mode, int n)
4470{
4471 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
4472 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00004473 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00004474
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004475 SECURITY_ATTRIBUTES saAttr;
4476 BOOL fSuccess;
4477 int fd1, fd2, fd3;
4478 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00004479 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004480 PyObject *f;
4481
4482 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
4483 saAttr.bInheritHandle = TRUE;
4484 saAttr.lpSecurityDescriptor = NULL;
4485
4486 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
4487 return win32_error("CreatePipe", NULL);
4488
4489 /* Create new output read handle and the input write handle. Set
4490 * the inheritance properties to FALSE. Otherwise, the child inherits
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00004491 * these handles; resulting in non-closeable handles to the pipes
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004492 * being created. */
4493 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004494 GetCurrentProcess(), &hChildStdinWrDup, 0,
4495 FALSE,
4496 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004497 if (!fSuccess)
4498 return win32_error("DuplicateHandle", NULL);
4499
4500 /* Close the inheritable version of ChildStdin
4501 that we're using. */
4502 CloseHandle(hChildStdinWr);
4503
4504 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
4505 return win32_error("CreatePipe", NULL);
4506
4507 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004508 GetCurrentProcess(), &hChildStdoutRdDup, 0,
4509 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004510 if (!fSuccess)
4511 return win32_error("DuplicateHandle", NULL);
4512
4513 /* Close the inheritable version of ChildStdout
4514 that we're using. */
4515 CloseHandle(hChildStdoutRd);
4516
4517 if (n != POPEN_4) {
4518 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
4519 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004520 fSuccess = DuplicateHandle(GetCurrentProcess(),
4521 hChildStderrRd,
4522 GetCurrentProcess(),
4523 &hChildStderrRdDup, 0,
4524 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004525 if (!fSuccess)
4526 return win32_error("DuplicateHandle", NULL);
4527 /* Close the inheritable version of ChildStdErr that we're using. */
4528 CloseHandle(hChildStderrRd);
4529 }
Tim Peters5aa91602002-01-30 05:46:57 +00004530
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004531 switch (n) {
4532 case POPEN_1:
4533 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
4534 case _O_WRONLY | _O_TEXT:
4535 /* Case for writing to child Stdin in text mode. */
Martin v. Löwis18e16552006-02-15 17:27:45 +00004536 fd1 = _open_osfhandle((intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004537 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004538 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004539 PyFile_SetBufSize(f, 0);
4540 /* We don't care about these pipes anymore, so close them. */
4541 CloseHandle(hChildStdoutRdDup);
4542 CloseHandle(hChildStderrRdDup);
4543 break;
4544
4545 case _O_RDONLY | _O_TEXT:
4546 /* Case for reading from child Stdout in text mode. */
Martin v. Löwis18e16552006-02-15 17:27:45 +00004547 fd1 = _open_osfhandle((intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004548 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004549 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004550 PyFile_SetBufSize(f, 0);
4551 /* We don't care about these pipes anymore, so close them. */
4552 CloseHandle(hChildStdinWrDup);
4553 CloseHandle(hChildStderrRdDup);
4554 break;
4555
4556 case _O_RDONLY | _O_BINARY:
4557 /* Case for readinig from child Stdout in binary mode. */
Martin v. Löwis18e16552006-02-15 17:27:45 +00004558 fd1 = _open_osfhandle((intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004559 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004560 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004561 PyFile_SetBufSize(f, 0);
4562 /* We don't care about these pipes anymore, so close them. */
4563 CloseHandle(hChildStdinWrDup);
4564 CloseHandle(hChildStderrRdDup);
4565 break;
4566
4567 case _O_WRONLY | _O_BINARY:
4568 /* Case for writing to child Stdin in binary mode. */
Martin v. Löwis18e16552006-02-15 17:27:45 +00004569 fd1 = _open_osfhandle((intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004570 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004571 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004572 PyFile_SetBufSize(f, 0);
4573 /* We don't care about these pipes anymore, so close them. */
4574 CloseHandle(hChildStdoutRdDup);
4575 CloseHandle(hChildStderrRdDup);
4576 break;
4577 }
Mark Hammondb37a3732000-08-14 04:47:33 +00004578 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004579 break;
Tim Peters5aa91602002-01-30 05:46:57 +00004580
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004581 case POPEN_2:
4582 case POPEN_4:
4583 {
4584 char *m1, *m2;
4585 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00004586
Tim Peters7dca21e2002-08-19 00:42:29 +00004587 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004588 m1 = "r";
4589 m2 = "w";
4590 } else {
4591 m1 = "rb";
4592 m2 = "wb";
4593 }
4594
Martin v. Löwis18e16552006-02-15 17:27:45 +00004595 fd1 = _open_osfhandle((intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004596 f1 = _fdopen(fd1, m2);
Martin v. Löwis18e16552006-02-15 17:27:45 +00004597 fd2 = _open_osfhandle((intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004598 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004599 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004600 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00004601 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004602 PyFile_SetBufSize(p2, 0);
4603
4604 if (n != 4)
4605 CloseHandle(hChildStderrRdDup);
4606
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004607 f = PyTuple_Pack(2,p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00004608 Py_XDECREF(p1);
4609 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00004610 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004611 break;
4612 }
Tim Peters5aa91602002-01-30 05:46:57 +00004613
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004614 case POPEN_3:
4615 {
4616 char *m1, *m2;
4617 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00004618
Tim Peters7dca21e2002-08-19 00:42:29 +00004619 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004620 m1 = "r";
4621 m2 = "w";
4622 } else {
4623 m1 = "rb";
4624 m2 = "wb";
4625 }
4626
Martin v. Löwis18e16552006-02-15 17:27:45 +00004627 fd1 = _open_osfhandle((intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004628 f1 = _fdopen(fd1, m2);
Martin v. Löwis18e16552006-02-15 17:27:45 +00004629 fd2 = _open_osfhandle((intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004630 f2 = _fdopen(fd2, m1);
Martin v. Löwis18e16552006-02-15 17:27:45 +00004631 fd3 = _open_osfhandle((intptr_t)hChildStderrRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004632 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004633 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00004634 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
4635 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004636 PyFile_SetBufSize(p1, 0);
4637 PyFile_SetBufSize(p2, 0);
4638 PyFile_SetBufSize(p3, 0);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004639 f = PyTuple_Pack(3,p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00004640 Py_XDECREF(p1);
4641 Py_XDECREF(p2);
4642 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00004643 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004644 break;
4645 }
4646 }
4647
4648 if (n == POPEN_4) {
4649 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004650 hChildStdinRd,
4651 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004652 hChildStdoutWr,
4653 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004654 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004655 }
4656 else {
4657 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004658 hChildStdinRd,
4659 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004660 hChildStderrWr,
4661 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004662 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004663 }
4664
Mark Hammondb37a3732000-08-14 04:47:33 +00004665 /*
4666 * Insert the files we've created into the process dictionary
4667 * all referencing the list with the process handle and the
4668 * initial number of files (see description below in _PyPclose).
4669 * Since if _PyPclose later tried to wait on a process when all
4670 * handles weren't closed, it could create a deadlock with the
4671 * child, we spend some energy here to try to ensure that we
4672 * either insert all file handles into the dictionary or none
4673 * at all. It's a little clumsy with the various popen modes
4674 * and variable number of files involved.
4675 */
4676 if (!_PyPopenProcs) {
4677 _PyPopenProcs = PyDict_New();
4678 }
4679
4680 if (_PyPopenProcs) {
4681 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
4682 int ins_rc[3];
4683
4684 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4685 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4686
4687 procObj = PyList_New(2);
4688 hProcessObj = PyLong_FromVoidPtr(hProcess);
4689 intObj = PyInt_FromLong(file_count);
4690
4691 if (procObj && hProcessObj && intObj) {
4692 PyList_SetItem(procObj,0,hProcessObj);
4693 PyList_SetItem(procObj,1,intObj);
4694
4695 fileObj[0] = PyLong_FromVoidPtr(f1);
4696 if (fileObj[0]) {
4697 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4698 fileObj[0],
4699 procObj);
4700 }
4701 if (file_count >= 2) {
4702 fileObj[1] = PyLong_FromVoidPtr(f2);
4703 if (fileObj[1]) {
4704 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4705 fileObj[1],
4706 procObj);
4707 }
4708 }
4709 if (file_count >= 3) {
4710 fileObj[2] = PyLong_FromVoidPtr(f3);
4711 if (fileObj[2]) {
4712 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4713 fileObj[2],
4714 procObj);
4715 }
4716 }
4717
4718 if (ins_rc[0] < 0 || !fileObj[0] ||
4719 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4720 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
4721 /* Something failed - remove any dictionary
4722 * entries that did make it.
4723 */
4724 if (!ins_rc[0] && fileObj[0]) {
4725 PyDict_DelItem(_PyPopenProcs,
4726 fileObj[0]);
4727 }
4728 if (!ins_rc[1] && fileObj[1]) {
4729 PyDict_DelItem(_PyPopenProcs,
4730 fileObj[1]);
4731 }
4732 if (!ins_rc[2] && fileObj[2]) {
4733 PyDict_DelItem(_PyPopenProcs,
4734 fileObj[2]);
4735 }
4736 }
4737 }
Tim Peters5aa91602002-01-30 05:46:57 +00004738
Mark Hammondb37a3732000-08-14 04:47:33 +00004739 /*
4740 * Clean up our localized references for the dictionary keys
4741 * and value since PyDict_SetItem will Py_INCREF any copies
4742 * that got placed in the dictionary.
4743 */
4744 Py_XDECREF(procObj);
4745 Py_XDECREF(fileObj[0]);
4746 Py_XDECREF(fileObj[1]);
4747 Py_XDECREF(fileObj[2]);
4748 }
4749
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004750 /* Child is launched. Close the parents copy of those pipe
4751 * handles that only the child should have open. You need to
4752 * make sure that no handles to the write end of the output pipe
4753 * are maintained in this process or else the pipe will not close
4754 * when the child process exits and the ReadFile will hang. */
4755
4756 if (!CloseHandle(hChildStdinRd))
4757 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004758
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004759 if (!CloseHandle(hChildStdoutWr))
4760 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004761
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004762 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
4763 return win32_error("CloseHandle", NULL);
4764
4765 return f;
4766}
Fredrik Lundh56055a42000-07-23 19:47:12 +00004767
4768/*
4769 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4770 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00004771 *
4772 * This function uses the _PyPopenProcs dictionary in order to map the
4773 * input file pointer to information about the process that was
4774 * originally created by the popen* call that created the file pointer.
4775 * The dictionary uses the file pointer as a key (with one entry
4776 * inserted for each file returned by the original popen* call) and a
4777 * single list object as the value for all files from a single call.
4778 * The list object contains the Win32 process handle at [0], and a file
4779 * count at [1], which is initialized to the total number of file
4780 * handles using that list.
4781 *
4782 * This function closes whichever handle it is passed, and decrements
4783 * the file count in the dictionary for the process handle pointed to
4784 * by this file. On the last close (when the file count reaches zero),
4785 * this function will wait for the child process and then return its
4786 * exit code as the result of the close() operation. This permits the
4787 * files to be closed in any order - it is always the close() of the
4788 * final handle that will return the exit code.
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004789 *
4790 * NOTE: This function is currently called with the GIL released.
4791 * hence we use the GILState API to manage our state.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004792 */
Tim Peters736aa322000-09-01 06:51:24 +00004793
Fredrik Lundh56055a42000-07-23 19:47:12 +00004794static int _PyPclose(FILE *file)
4795{
Fredrik Lundh20318932000-07-26 17:29:12 +00004796 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004797 DWORD exit_code;
4798 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00004799 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
4800 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00004801#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004802 PyGILState_STATE state;
Tim Peters736aa322000-09-01 06:51:24 +00004803#endif
4804
Fredrik Lundh20318932000-07-26 17:29:12 +00004805 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00004806 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00004807 */
4808 result = fclose(file);
Tim Peters736aa322000-09-01 06:51:24 +00004809#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004810 state = PyGILState_Ensure();
Tim Peters736aa322000-09-01 06:51:24 +00004811#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00004812 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00004813 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4814 (procObj = PyDict_GetItem(_PyPopenProcs,
4815 fileObj)) != NULL &&
4816 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
4817 (intObj = PyList_GetItem(procObj,1)) != NULL) {
4818
4819 hProcess = PyLong_AsVoidPtr(hProcessObj);
4820 file_count = PyInt_AsLong(intObj);
4821
4822 if (file_count > 1) {
4823 /* Still other files referencing process */
4824 file_count--;
4825 PyList_SetItem(procObj,1,
4826 PyInt_FromLong(file_count));
4827 } else {
4828 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00004829 if (result != EOF &&
4830 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
4831 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00004832 /* Possible truncation here in 16-bit environments, but
4833 * real exit codes are just the lower byte in any event.
4834 */
4835 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004836 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00004837 /* Indicate failure - this will cause the file object
4838 * to raise an I/O error and translate the last Win32
4839 * error code from errno. We do have a problem with
4840 * last errors that overlap the normal errno table,
4841 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004842 */
Fredrik Lundh20318932000-07-26 17:29:12 +00004843 if (result != EOF) {
4844 /* If the error wasn't from the fclose(), then
4845 * set errno for the file object error handling.
4846 */
4847 errno = GetLastError();
4848 }
4849 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004850 }
4851
4852 /* Free up the native handle at this point */
4853 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00004854 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00004855
Mark Hammondb37a3732000-08-14 04:47:33 +00004856 /* Remove this file pointer from dictionary */
4857 PyDict_DelItem(_PyPopenProcs, fileObj);
4858
4859 if (PyDict_Size(_PyPopenProcs) == 0) {
4860 Py_DECREF(_PyPopenProcs);
4861 _PyPopenProcs = NULL;
4862 }
4863
4864 } /* if object retrieval ok */
4865
4866 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004867 } /* if _PyPopenProcs */
4868
Tim Peters736aa322000-09-01 06:51:24 +00004869#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004870 PyGILState_Release(state);
Tim Peters736aa322000-09-01 06:51:24 +00004871#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00004872 return result;
4873}
Tim Peters9acdd3a2000-09-01 19:26:36 +00004874
4875#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00004876static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004877posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00004878{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004879 char *name;
4880 char *mode = "r";
4881 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00004882 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00004883 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004884 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00004885 return NULL;
Martin v. Löwis9ad853b2003-10-31 10:01:53 +00004886 /* Strip mode of binary or text modifiers */
4887 if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
4888 mode = "r";
4889 else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
4890 mode = "w";
Barry Warsaw53699e91996-12-10 23:23:01 +00004891 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004892 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004893 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00004894 if (fp == NULL)
4895 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004896 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004897 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00004898 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004899 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00004900}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004901
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004902#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004903#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00004904
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004905
Guido van Rossumb6775db1994-08-01 11:34:53 +00004906#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004907PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004908"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004909Set the current process's user id.");
4910
Barry Warsaw53699e91996-12-10 23:23:01 +00004911static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004912posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004913{
4914 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004915 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004916 return NULL;
4917 if (setuid(uid) < 0)
4918 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004919 Py_INCREF(Py_None);
4920 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004921}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004922#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004923
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004924
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004925#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004926PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004927"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004928Set the current process's effective user id.");
4929
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004930static PyObject *
4931posix_seteuid (PyObject *self, PyObject *args)
4932{
4933 int euid;
4934 if (!PyArg_ParseTuple(args, "i", &euid)) {
4935 return NULL;
4936 } else if (seteuid(euid) < 0) {
4937 return posix_error();
4938 } else {
4939 Py_INCREF(Py_None);
4940 return Py_None;
4941 }
4942}
4943#endif /* HAVE_SETEUID */
4944
4945#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004946PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004947"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004948Set the current process's effective group id.");
4949
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004950static PyObject *
4951posix_setegid (PyObject *self, PyObject *args)
4952{
4953 int egid;
4954 if (!PyArg_ParseTuple(args, "i", &egid)) {
4955 return NULL;
4956 } else if (setegid(egid) < 0) {
4957 return posix_error();
4958 } else {
4959 Py_INCREF(Py_None);
4960 return Py_None;
4961 }
4962}
4963#endif /* HAVE_SETEGID */
4964
4965#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004966PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004967"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004968Set the current process's real and effective user ids.");
4969
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004970static PyObject *
4971posix_setreuid (PyObject *self, PyObject *args)
4972{
4973 int ruid, euid;
4974 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
4975 return NULL;
4976 } else if (setreuid(ruid, euid) < 0) {
4977 return posix_error();
4978 } else {
4979 Py_INCREF(Py_None);
4980 return Py_None;
4981 }
4982}
4983#endif /* HAVE_SETREUID */
4984
4985#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004986PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004987"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004988Set the current process's real and effective group ids.");
4989
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004990static PyObject *
4991posix_setregid (PyObject *self, PyObject *args)
4992{
4993 int rgid, egid;
4994 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
4995 return NULL;
4996 } else if (setregid(rgid, egid) < 0) {
4997 return posix_error();
4998 } else {
4999 Py_INCREF(Py_None);
5000 return Py_None;
5001 }
5002}
5003#endif /* HAVE_SETREGID */
5004
Guido van Rossumb6775db1994-08-01 11:34:53 +00005005#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005006PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005007"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005008Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005009
Barry Warsaw53699e91996-12-10 23:23:01 +00005010static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005011posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005012{
5013 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005014 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005015 return NULL;
5016 if (setgid(gid) < 0)
5017 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005018 Py_INCREF(Py_None);
5019 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005020}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005021#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005022
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005023#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005024PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005025"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005026Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005027
5028static PyObject *
5029posix_setgroups(PyObject *self, PyObject *args)
5030{
5031 PyObject *groups;
5032 int i, len;
5033 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00005034
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005035 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
5036 return NULL;
5037 if (!PySequence_Check(groups)) {
5038 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
5039 return NULL;
5040 }
5041 len = PySequence_Size(groups);
5042 if (len > MAX_GROUPS) {
5043 PyErr_SetString(PyExc_ValueError, "too many groups");
5044 return NULL;
5045 }
5046 for(i = 0; i < len; i++) {
5047 PyObject *elem;
5048 elem = PySequence_GetItem(groups, i);
5049 if (!elem)
5050 return NULL;
5051 if (!PyInt_Check(elem)) {
Georg Brandla13c2442005-11-22 19:30:31 +00005052 if (!PyLong_Check(elem)) {
5053 PyErr_SetString(PyExc_TypeError,
5054 "groups must be integers");
5055 Py_DECREF(elem);
5056 return NULL;
5057 } else {
5058 unsigned long x = PyLong_AsUnsignedLong(elem);
5059 if (PyErr_Occurred()) {
5060 PyErr_SetString(PyExc_TypeError,
5061 "group id too big");
5062 Py_DECREF(elem);
5063 return NULL;
5064 }
5065 grouplist[i] = x;
5066 /* read back the value to see if it fitted in gid_t */
5067 if (grouplist[i] != x) {
5068 PyErr_SetString(PyExc_TypeError,
5069 "group id too big");
5070 Py_DECREF(elem);
5071 return NULL;
5072 }
5073 }
5074 } else {
5075 long x = PyInt_AsLong(elem);
5076 grouplist[i] = x;
5077 if (grouplist[i] != x) {
5078 PyErr_SetString(PyExc_TypeError,
5079 "group id too big");
5080 Py_DECREF(elem);
5081 return NULL;
5082 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005083 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005084 Py_DECREF(elem);
5085 }
5086
5087 if (setgroups(len, grouplist) < 0)
5088 return posix_error();
5089 Py_INCREF(Py_None);
5090 return Py_None;
5091}
5092#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005093
Guido van Rossumb6775db1994-08-01 11:34:53 +00005094#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005095PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005096"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005097Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005098
Barry Warsaw53699e91996-12-10 23:23:01 +00005099static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005100posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005101{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005102 int pid, options;
5103#ifdef UNION_WAIT
5104 union wait status;
5105#define status_i (status.w_status)
5106#else
5107 int status;
5108#define status_i status
5109#endif
5110 status_i = 0;
5111
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005112 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00005113 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005114 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00005115 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00005116 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00005117 if (pid == -1)
5118 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00005119 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005120 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00005121}
5122
Tim Petersab034fa2002-02-01 11:27:43 +00005123#elif defined(HAVE_CWAIT)
5124
5125/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005126PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005127"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005128"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00005129
5130static PyObject *
5131posix_waitpid(PyObject *self, PyObject *args)
5132{
Martin v. Löwis18e16552006-02-15 17:27:45 +00005133 intptr_t pid;
5134 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00005135
5136 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
5137 return NULL;
5138 Py_BEGIN_ALLOW_THREADS
5139 pid = _cwait(&status, pid, options);
5140 Py_END_ALLOW_THREADS
5141 if (pid == -1)
5142 return posix_error();
5143 else
5144 /* shift the status left a byte so this is more like the
5145 POSIX waitpid */
5146 return Py_BuildValue("ii", pid, status << 8);
5147}
5148#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005149
Guido van Rossumad0ee831995-03-01 10:34:45 +00005150#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005151PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005152"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005153Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005154
Barry Warsaw53699e91996-12-10 23:23:01 +00005155static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005156posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00005157{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005158 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005159#ifdef UNION_WAIT
5160 union wait status;
5161#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00005162#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005163 int status;
5164#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00005165#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00005166
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005167 status_i = 0;
5168 Py_BEGIN_ALLOW_THREADS
5169 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00005170 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00005171 if (pid == -1)
5172 return posix_error();
5173 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005174 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005175#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00005176}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005177#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005178
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005179
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005180PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005181"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005182Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005183
Barry Warsaw53699e91996-12-10 23:23:01 +00005184static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005185posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005186{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005187#ifdef HAVE_LSTAT
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005188 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005189#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005190#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00005191 return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005192#else
5193 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
5194#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005195#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005196}
5197
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005198
Guido van Rossumb6775db1994-08-01 11:34:53 +00005199#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005200PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005201"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005202Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005203
Barry Warsaw53699e91996-12-10 23:23:01 +00005204static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005205posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005206{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005207 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00005208 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005209 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005210 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005211 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005212 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00005213 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00005214 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005215 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00005216 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00005217 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005218}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005219#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005220
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005221
Guido van Rossumb6775db1994-08-01 11:34:53 +00005222#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005223PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005224"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00005225Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005226
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005227static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005228posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005229{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005230 return posix_2str(args, "etet:symlink", symlink, NULL, NULL);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005231}
5232#endif /* HAVE_SYMLINK */
5233
5234
5235#ifdef HAVE_TIMES
5236#ifndef HZ
5237#define HZ 60 /* Universal constant :-) */
5238#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00005239
Guido van Rossumd48f2521997-12-05 22:19:34 +00005240#if defined(PYCC_VACPP) && defined(PYOS_OS2)
5241static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005242system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005243{
5244 ULONG value = 0;
5245
5246 Py_BEGIN_ALLOW_THREADS
5247 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
5248 Py_END_ALLOW_THREADS
5249
5250 return value;
5251}
5252
5253static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005254posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005255{
Guido van Rossumd48f2521997-12-05 22:19:34 +00005256 /* Currently Only Uptime is Provided -- Others Later */
5257 return Py_BuildValue("ddddd",
5258 (double)0 /* t.tms_utime / HZ */,
5259 (double)0 /* t.tms_stime / HZ */,
5260 (double)0 /* t.tms_cutime / HZ */,
5261 (double)0 /* t.tms_cstime / HZ */,
5262 (double)system_uptime() / 1000);
5263}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005264#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00005265static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005266posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00005267{
5268 struct tms t;
5269 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +00005270 errno = 0;
5271 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00005272 if (c == (clock_t) -1)
5273 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005274 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00005275 (double)t.tms_utime / HZ,
5276 (double)t.tms_stime / HZ,
5277 (double)t.tms_cutime / HZ,
5278 (double)t.tms_cstime / HZ,
5279 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00005280}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005281#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005282#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005283
5284
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005285#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005286#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00005287static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005288posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005289{
5290 FILETIME create, exit, kernel, user;
5291 HANDLE hProc;
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005292 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00005293 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
5294 /* The fields of a FILETIME structure are the hi and lo part
5295 of a 64-bit value expressed in 100 nanosecond units.
5296 1e7 is one second in such units; 1e-7 the inverse.
5297 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
5298 */
Barry Warsaw53699e91996-12-10 23:23:01 +00005299 return Py_BuildValue(
5300 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00005301 (double)(kernel.dwHighDateTime*429.4967296 +
5302 kernel.dwLowDateTime*1e-7),
5303 (double)(user.dwHighDateTime*429.4967296 +
5304 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00005305 (double)0,
5306 (double)0,
5307 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005308}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005309#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005310
5311#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005312PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005313"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005314Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005315#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005316
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005317
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00005318#ifdef HAVE_GETSID
5319PyDoc_STRVAR(posix_getsid__doc__,
5320"getsid(pid) -> sid\n\n\
5321Call the system call getsid().");
5322
5323static PyObject *
5324posix_getsid(PyObject *self, PyObject *args)
5325{
5326 int pid, sid;
5327 if (!PyArg_ParseTuple(args, "i:getsid", &pid))
5328 return NULL;
5329 sid = getsid(pid);
5330 if (sid < 0)
5331 return posix_error();
5332 return PyInt_FromLong((long)sid);
5333}
5334#endif /* HAVE_GETSID */
5335
5336
Guido van Rossumb6775db1994-08-01 11:34:53 +00005337#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005338PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005339"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005340Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005341
Barry Warsaw53699e91996-12-10 23:23:01 +00005342static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005343posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005344{
Guido van Rossum687dd131993-05-17 08:34:16 +00005345 if (setsid() < 0)
5346 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005347 Py_INCREF(Py_None);
5348 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005349}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005350#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005351
Guido van Rossumb6775db1994-08-01 11:34:53 +00005352#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005353PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005354"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005355Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005356
Barry Warsaw53699e91996-12-10 23:23:01 +00005357static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005358posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005359{
5360 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005361 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00005362 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005363 if (setpgid(pid, pgrp) < 0)
5364 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005365 Py_INCREF(Py_None);
5366 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005367}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005368#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005369
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005370
Guido van Rossumb6775db1994-08-01 11:34:53 +00005371#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005372PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005373"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005374Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005375
Barry Warsaw53699e91996-12-10 23:23:01 +00005376static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005377posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005378{
5379 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005380 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00005381 return NULL;
5382 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005383 if (pgid < 0)
5384 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005385 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00005386}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005387#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00005388
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005389
Guido van Rossumb6775db1994-08-01 11:34:53 +00005390#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005391PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005392"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005393Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005394
Barry Warsaw53699e91996-12-10 23:23:01 +00005395static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005396posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005397{
5398 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005399 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00005400 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005401 if (tcsetpgrp(fd, pgid) < 0)
5402 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00005403 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00005404 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00005405}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005406#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00005407
Guido van Rossum687dd131993-05-17 08:34:16 +00005408/* Functions acting on file descriptors */
5409
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005410PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005411"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005412Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005413
Barry Warsaw53699e91996-12-10 23:23:01 +00005414static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005415posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005416{
Mark Hammondef8b6542001-05-13 08:04:26 +00005417 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005418 int flag;
5419 int mode = 0777;
5420 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005421
5422#ifdef MS_WINDOWS
5423 if (unicode_file_names()) {
5424 PyUnicodeObject *po;
5425 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
5426 Py_BEGIN_ALLOW_THREADS
5427 /* PyUnicode_AS_UNICODE OK without thread
5428 lock as it is a simple dereference. */
5429 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
5430 Py_END_ALLOW_THREADS
5431 if (fd < 0)
5432 return posix_error();
5433 return PyInt_FromLong((long)fd);
5434 }
5435 /* Drop the argument parsing error as narrow strings
5436 are also valid. */
5437 PyErr_Clear();
5438 }
5439#endif
5440
Tim Peters5aa91602002-01-30 05:46:57 +00005441 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00005442 Py_FileSystemDefaultEncoding, &file,
5443 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00005444 return NULL;
5445
Barry Warsaw53699e91996-12-10 23:23:01 +00005446 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005447 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005448 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005449 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00005450 return posix_error_with_allocated_filename(file);
5451 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00005452 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005453}
5454
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005455
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005456PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005457"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005458Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005459
Barry Warsaw53699e91996-12-10 23:23:01 +00005460static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005461posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005462{
5463 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005464 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005465 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005466 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005467 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00005468 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005469 if (res < 0)
5470 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005471 Py_INCREF(Py_None);
5472 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005473}
5474
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005475
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005476PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005477"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005478Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005479
Barry Warsaw53699e91996-12-10 23:23:01 +00005480static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005481posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005482{
5483 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005484 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005485 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005486 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005487 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00005488 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005489 if (fd < 0)
5490 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005491 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005492}
5493
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005494
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005495PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00005496"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005497Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005498
Barry Warsaw53699e91996-12-10 23:23:01 +00005499static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005500posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005501{
5502 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005503 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00005504 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005505 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005506 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00005507 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005508 if (res < 0)
5509 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005510 Py_INCREF(Py_None);
5511 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005512}
5513
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005514
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005515PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005516"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005517Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005518
Barry Warsaw53699e91996-12-10 23:23:01 +00005519static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005520posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005521{
5522 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005523#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005524 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005525#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00005526 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005527#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005528 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005529 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00005530 return NULL;
5531#ifdef SEEK_SET
5532 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
5533 switch (how) {
5534 case 0: how = SEEK_SET; break;
5535 case 1: how = SEEK_CUR; break;
5536 case 2: how = SEEK_END; break;
5537 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005538#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005539
5540#if !defined(HAVE_LARGEFILE_SUPPORT)
5541 pos = PyInt_AsLong(posobj);
5542#else
5543 pos = PyLong_Check(posobj) ?
5544 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
5545#endif
5546 if (PyErr_Occurred())
5547 return NULL;
5548
Barry Warsaw53699e91996-12-10 23:23:01 +00005549 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005550#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00005551 res = _lseeki64(fd, pos, how);
5552#else
Guido van Rossum687dd131993-05-17 08:34:16 +00005553 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005554#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005555 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005556 if (res < 0)
5557 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00005558
5559#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00005560 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005561#else
5562 return PyLong_FromLongLong(res);
5563#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005564}
5565
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005566
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005567PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005568"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005569Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005570
Barry Warsaw53699e91996-12-10 23:23:01 +00005571static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005572posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005573{
Guido van Rossum8bac5461996-06-11 18:38:48 +00005574 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00005575 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005576 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005577 return NULL;
Michael W. Hudson9867ced2005-01-31 17:01:59 +00005578 if (size < 0) {
5579 errno = EINVAL;
5580 return posix_error();
5581 }
Barry Warsaw53699e91996-12-10 23:23:01 +00005582 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005583 if (buffer == NULL)
5584 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005585 Py_BEGIN_ALLOW_THREADS
5586 n = read(fd, PyString_AsString(buffer), size);
5587 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00005588 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005589 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00005590 return posix_error();
5591 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00005592 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00005593 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00005594 return buffer;
5595}
5596
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005597
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005598PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005599"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005600Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005601
Barry Warsaw53699e91996-12-10 23:23:01 +00005602static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005603posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005604{
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005605 int fd;
5606 Py_ssize_t size;
Guido van Rossum687dd131993-05-17 08:34:16 +00005607 char *buffer;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005608
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005609 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005610 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005611 Py_BEGIN_ALLOW_THREADS
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005612 size = write(fd, buffer, (size_t)size);
Barry Warsaw53699e91996-12-10 23:23:01 +00005613 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005614 if (size < 0)
5615 return posix_error();
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005616 return PyInt_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005617}
5618
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005619
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005620PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005621"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005622Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005623
Barry Warsaw53699e91996-12-10 23:23:01 +00005624static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005625posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005626{
5627 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00005628 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00005629 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005630 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005631 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005632#ifdef __VMS
5633 /* on OpenVMS we must ensure that all bytes are written to the file */
5634 fsync(fd);
5635#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005636 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00005637 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00005638 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00005639 if (res != 0) {
5640#ifdef MS_WINDOWS
5641 return win32_error("fstat", NULL);
5642#else
Guido van Rossum687dd131993-05-17 08:34:16 +00005643 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00005644#endif
5645 }
Tim Peters5aa91602002-01-30 05:46:57 +00005646
Martin v. Löwis14694662006-02-03 12:54:16 +00005647 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00005648}
5649
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005650
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005651PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005652"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005653Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005654
Barry Warsaw53699e91996-12-10 23:23:01 +00005655static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005656posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005657{
Guido van Rossum687dd131993-05-17 08:34:16 +00005658 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005659 char *mode = "r";
5660 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00005661 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00005662 PyObject *f;
5663 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00005664 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00005665
Thomas Heller1f043e22002-11-07 16:00:59 +00005666 if (mode[0] != 'r' && mode[0] != 'w' && mode[0] != 'a') {
5667 PyErr_Format(PyExc_ValueError,
5668 "invalid file mode '%s'", mode);
5669 return NULL;
5670 }
5671
Barry Warsaw53699e91996-12-10 23:23:01 +00005672 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005673 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005674 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005675 if (fp == NULL)
5676 return posix_error();
Guido van Rossumbd6be7a2002-09-15 18:45:46 +00005677 f = PyFile_FromFile(fp, "<fdopen>", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005678 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00005679 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005680 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00005681}
5682
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005683PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005684"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005685Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005686connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00005687
5688static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00005689posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00005690{
5691 int fd;
5692 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
5693 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005694 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00005695}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005696
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005697#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005698PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005699"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005700Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005701
Barry Warsaw53699e91996-12-10 23:23:01 +00005702static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005703posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00005704{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005705#if defined(PYOS_OS2)
5706 HFILE read, write;
5707 APIRET rc;
5708
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005709 Py_BEGIN_ALLOW_THREADS
5710 rc = DosCreatePipe( &read, &write, 4096);
5711 Py_END_ALLOW_THREADS
5712 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005713 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005714
5715 return Py_BuildValue("(ii)", read, write);
5716#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005717#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00005718 int fds[2];
5719 int res;
Barry Warsaw53699e91996-12-10 23:23:01 +00005720 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005721 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00005722 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005723 if (res != 0)
5724 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005725 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005726#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00005727 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005728 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00005729 BOOL ok;
Barry Warsaw53699e91996-12-10 23:23:01 +00005730 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005731 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00005732 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00005733 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005734 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00005735 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
5736 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005737 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005738#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005739#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005740}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005741#endif /* HAVE_PIPE */
5742
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005743
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005744#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005745PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005746"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005747Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005748
Barry Warsaw53699e91996-12-10 23:23:01 +00005749static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005750posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005751{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005752 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005753 int mode = 0666;
5754 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005755 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005756 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005757 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005758 res = mkfifo(filename, mode);
5759 Py_END_ALLOW_THREADS
5760 if (res < 0)
5761 return posix_error();
5762 Py_INCREF(Py_None);
5763 return Py_None;
5764}
5765#endif
5766
5767
Neal Norwitz11690112002-07-30 01:08:28 +00005768#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005769PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005770"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005771Create a filesystem node (file, device special file or named pipe)\n\
5772named filename. mode specifies both the permissions to use and the\n\
5773type of node to be created, being combined (bitwise OR) with one of\n\
5774S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005775device defines the newly created device special file (probably using\n\
5776os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005777
5778
5779static PyObject *
5780posix_mknod(PyObject *self, PyObject *args)
5781{
5782 char *filename;
5783 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005784 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005785 int res;
Martin v. Löwisd631ebe2002-11-02 17:42:33 +00005786 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005787 return NULL;
5788 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005789 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00005790 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005791 if (res < 0)
5792 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005793 Py_INCREF(Py_None);
5794 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005795}
5796#endif
5797
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005798#ifdef HAVE_DEVICE_MACROS
5799PyDoc_STRVAR(posix_major__doc__,
5800"major(device) -> major number\n\
5801Extracts a device major number from a raw device number.");
5802
5803static PyObject *
5804posix_major(PyObject *self, PyObject *args)
5805{
5806 int device;
5807 if (!PyArg_ParseTuple(args, "i:major", &device))
5808 return NULL;
5809 return PyInt_FromLong((long)major(device));
5810}
5811
5812PyDoc_STRVAR(posix_minor__doc__,
5813"minor(device) -> minor number\n\
5814Extracts a device minor number from a raw device number.");
5815
5816static PyObject *
5817posix_minor(PyObject *self, PyObject *args)
5818{
5819 int device;
5820 if (!PyArg_ParseTuple(args, "i:minor", &device))
5821 return NULL;
5822 return PyInt_FromLong((long)minor(device));
5823}
5824
5825PyDoc_STRVAR(posix_makedev__doc__,
5826"makedev(major, minor) -> device number\n\
5827Composes a raw device number from the major and minor device numbers.");
5828
5829static PyObject *
5830posix_makedev(PyObject *self, PyObject *args)
5831{
5832 int major, minor;
5833 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
5834 return NULL;
5835 return PyInt_FromLong((long)makedev(major, minor));
5836}
5837#endif /* device macros */
5838
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005839
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005840#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005841PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005842"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005843Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005844
Barry Warsaw53699e91996-12-10 23:23:01 +00005845static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005846posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005847{
5848 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005849 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005850 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005851 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005852
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005853 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005854 return NULL;
5855
5856#if !defined(HAVE_LARGEFILE_SUPPORT)
5857 length = PyInt_AsLong(lenobj);
5858#else
5859 length = PyLong_Check(lenobj) ?
5860 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
5861#endif
5862 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005863 return NULL;
5864
Barry Warsaw53699e91996-12-10 23:23:01 +00005865 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005866 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00005867 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005868 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005869 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005870 return NULL;
5871 }
Barry Warsaw53699e91996-12-10 23:23:01 +00005872 Py_INCREF(Py_None);
5873 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005874}
5875#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005876
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005877#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005878PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005879"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005880Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005881
Fred Drake762e2061999-08-26 17:23:54 +00005882/* Save putenv() parameters as values here, so we can collect them when they
5883 * get re-set with another call for the same key. */
5884static PyObject *posix_putenv_garbage;
5885
Tim Peters5aa91602002-01-30 05:46:57 +00005886static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005887posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005888{
5889 char *s1, *s2;
5890 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00005891 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00005892 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005893
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005894 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005895 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00005896
5897#if defined(PYOS_OS2)
5898 if (stricmp(s1, "BEGINLIBPATH") == 0) {
5899 APIRET rc;
5900
Guido van Rossumd48f2521997-12-05 22:19:34 +00005901 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
5902 if (rc != NO_ERROR)
5903 return os2_error(rc);
5904
5905 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
5906 APIRET rc;
5907
Guido van Rossumd48f2521997-12-05 22:19:34 +00005908 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
5909 if (rc != NO_ERROR)
5910 return os2_error(rc);
5911 } else {
5912#endif
5913
Fred Drake762e2061999-08-26 17:23:54 +00005914 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00005915 len = strlen(s1) + strlen(s2) + 2;
5916 /* len includes space for a trailing \0; the size arg to
5917 PyString_FromStringAndSize does not count that */
5918 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00005919 if (newstr == NULL)
5920 return PyErr_NoMemory();
5921 new = PyString_AS_STRING(newstr);
Tim Petersc8996f52001-12-03 20:41:00 +00005922 PyOS_snprintf(new, len, "%s=%s", s1, s2);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005923 if (putenv(new)) {
Neal Norwitz4adc9ab2003-02-10 03:10:43 +00005924 Py_DECREF(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005925 posix_error();
5926 return NULL;
5927 }
Fred Drake762e2061999-08-26 17:23:54 +00005928 /* Install the first arg and newstr in posix_putenv_garbage;
5929 * this will cause previous value to be collected. This has to
5930 * happen after the real putenv() call because the old value
5931 * was still accessible until then. */
5932 if (PyDict_SetItem(posix_putenv_garbage,
5933 PyTuple_GET_ITEM(args, 0), newstr)) {
5934 /* really not much we can do; just leak */
5935 PyErr_Clear();
5936 }
5937 else {
5938 Py_DECREF(newstr);
5939 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005940
5941#if defined(PYOS_OS2)
5942 }
5943#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005944 Py_INCREF(Py_None);
5945 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005946}
Guido van Rossumb6a47161997-09-15 22:54:34 +00005947#endif /* putenv */
5948
Guido van Rossumc524d952001-10-19 01:31:59 +00005949#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005950PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005951"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005952Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00005953
5954static PyObject *
5955posix_unsetenv(PyObject *self, PyObject *args)
5956{
5957 char *s1;
5958
5959 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
5960 return NULL;
5961
5962 unsetenv(s1);
5963
5964 /* Remove the key from posix_putenv_garbage;
5965 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00005966 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00005967 * old value was still accessible until then.
5968 */
5969 if (PyDict_DelItem(posix_putenv_garbage,
5970 PyTuple_GET_ITEM(args, 0))) {
5971 /* really not much we can do; just leak */
5972 PyErr_Clear();
5973 }
5974
5975 Py_INCREF(Py_None);
5976 return Py_None;
5977}
5978#endif /* unsetenv */
5979
Guido van Rossumb6a47161997-09-15 22:54:34 +00005980#ifdef HAVE_STRERROR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005981PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005982"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005983Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005984
Guido van Rossumf68d8e52001-04-14 17:55:09 +00005985static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005986posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00005987{
5988 int code;
5989 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005990 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00005991 return NULL;
5992 message = strerror(code);
5993 if (message == NULL) {
5994 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00005995 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005996 return NULL;
5997 }
5998 return PyString_FromString(message);
5999}
6000#endif /* strerror */
6001
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006002
Guido van Rossumc9641791998-08-04 15:26:23 +00006003#ifdef HAVE_SYS_WAIT_H
6004
Fred Drake106c1a02002-04-23 15:58:02 +00006005#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006006PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006007"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006008Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00006009
6010static PyObject *
6011posix_WCOREDUMP(PyObject *self, PyObject *args)
6012{
6013#ifdef UNION_WAIT
6014 union wait status;
6015#define status_i (status.w_status)
6016#else
6017 int status;
6018#define status_i status
6019#endif
6020 status_i = 0;
6021
6022 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &status_i))
6023 {
6024 return NULL;
6025 }
6026
6027 return PyBool_FromLong(WCOREDUMP(status));
6028#undef status_i
6029}
6030#endif /* WCOREDUMP */
6031
6032#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006033PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006034"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006035Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006036job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00006037
6038static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006039posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00006040{
6041#ifdef UNION_WAIT
6042 union wait status;
6043#define status_i (status.w_status)
6044#else
6045 int status;
6046#define status_i status
6047#endif
6048 status_i = 0;
6049
6050 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &status_i))
6051 {
6052 return NULL;
6053 }
6054
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006055 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006056#undef status_i
6057}
6058#endif /* WIFCONTINUED */
6059
Guido van Rossumc9641791998-08-04 15:26:23 +00006060#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006061PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006062"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006063Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006064
6065static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006066posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006067{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006068#ifdef UNION_WAIT
6069 union wait status;
6070#define status_i (status.w_status)
6071#else
6072 int status;
6073#define status_i status
6074#endif
6075 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006076
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006077 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00006078 {
6079 return NULL;
6080 }
Tim Peters5aa91602002-01-30 05:46:57 +00006081
Fred Drake106c1a02002-04-23 15:58:02 +00006082 return PyBool_FromLong(WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006083#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00006084}
6085#endif /* WIFSTOPPED */
6086
6087#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006088PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006089"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006090Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006091
6092static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006093posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006094{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006095#ifdef UNION_WAIT
6096 union wait status;
6097#define status_i (status.w_status)
6098#else
6099 int status;
6100#define status_i status
6101#endif
6102 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006103
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006104 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00006105 {
6106 return NULL;
6107 }
Tim Peters5aa91602002-01-30 05:46:57 +00006108
Fred Drake106c1a02002-04-23 15:58:02 +00006109 return PyBool_FromLong(WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006110#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00006111}
6112#endif /* WIFSIGNALED */
6113
6114#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006115PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006116"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006117Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006118system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006119
6120static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006121posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006122{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006123#ifdef UNION_WAIT
6124 union wait status;
6125#define status_i (status.w_status)
6126#else
6127 int status;
6128#define status_i status
6129#endif
6130 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006131
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006132 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00006133 {
6134 return NULL;
6135 }
Tim Peters5aa91602002-01-30 05:46:57 +00006136
Fred Drake106c1a02002-04-23 15:58:02 +00006137 return PyBool_FromLong(WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006138#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00006139}
6140#endif /* WIFEXITED */
6141
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006142#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006143PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006144"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006145Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006146
6147static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006148posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006149{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006150#ifdef UNION_WAIT
6151 union wait status;
6152#define status_i (status.w_status)
6153#else
6154 int status;
6155#define status_i status
6156#endif
6157 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006158
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006159 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00006160 {
6161 return NULL;
6162 }
Tim Peters5aa91602002-01-30 05:46:57 +00006163
Guido van Rossumc9641791998-08-04 15:26:23 +00006164 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006165#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00006166}
6167#endif /* WEXITSTATUS */
6168
6169#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006170PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006171"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006172Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006173value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006174
6175static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006176posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006177{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006178#ifdef UNION_WAIT
6179 union wait status;
6180#define status_i (status.w_status)
6181#else
6182 int status;
6183#define status_i status
6184#endif
6185 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006186
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006187 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00006188 {
6189 return NULL;
6190 }
Tim Peters5aa91602002-01-30 05:46:57 +00006191
Guido van Rossumc9641791998-08-04 15:26:23 +00006192 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006193#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00006194}
6195#endif /* WTERMSIG */
6196
6197#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006198PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006199"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006200Return the signal that stopped the process that provided\n\
6201the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006202
6203static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006204posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006205{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006206#ifdef UNION_WAIT
6207 union wait status;
6208#define status_i (status.w_status)
6209#else
6210 int status;
6211#define status_i status
6212#endif
6213 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006214
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006215 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00006216 {
6217 return NULL;
6218 }
Tim Peters5aa91602002-01-30 05:46:57 +00006219
Guido van Rossumc9641791998-08-04 15:26:23 +00006220 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006221#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00006222}
6223#endif /* WSTOPSIG */
6224
6225#endif /* HAVE_SYS_WAIT_H */
6226
6227
Guido van Rossum94f6f721999-01-06 18:42:14 +00006228#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00006229#ifdef _SCO_DS
6230/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
6231 needed definitions in sys/statvfs.h */
6232#define _SVID3
6233#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006234#include <sys/statvfs.h>
6235
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006236static PyObject*
6237_pystatvfs_fromstructstatvfs(struct statvfs st) {
6238 PyObject *v = PyStructSequence_New(&StatVFSResultType);
6239 if (v == NULL)
6240 return NULL;
6241
6242#if !defined(HAVE_LARGEFILE_SUPPORT)
6243 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6244 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
6245 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
6246 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
6247 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
6248 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
6249 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
6250 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
6251 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6252 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6253#else
6254 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6255 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00006256 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006257 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00006258 PyStructSequence_SET_ITEM(v, 3,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006259 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006260 PyStructSequence_SET_ITEM(v, 4,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006261 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00006262 PyStructSequence_SET_ITEM(v, 5,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006263 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00006264 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006265 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00006266 PyStructSequence_SET_ITEM(v, 7,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006267 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006268 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6269 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6270#endif
6271
6272 return v;
6273}
6274
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006275PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006276"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006277Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006278
6279static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006280posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006281{
6282 int fd, res;
6283 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006284
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006285 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006286 return NULL;
6287 Py_BEGIN_ALLOW_THREADS
6288 res = fstatvfs(fd, &st);
6289 Py_END_ALLOW_THREADS
6290 if (res != 0)
6291 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006292
6293 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006294}
6295#endif /* HAVE_FSTATVFS */
6296
6297
6298#if defined(HAVE_STATVFS)
6299#include <sys/statvfs.h>
6300
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006301PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006302"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006303Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006304
6305static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006306posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006307{
6308 char *path;
6309 int res;
6310 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006311 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006312 return NULL;
6313 Py_BEGIN_ALLOW_THREADS
6314 res = statvfs(path, &st);
6315 Py_END_ALLOW_THREADS
6316 if (res != 0)
6317 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006318
6319 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006320}
6321#endif /* HAVE_STATVFS */
6322
6323
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006324#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006325PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006326"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006327Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00006328The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006329or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006330
6331static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006332posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006333{
6334 PyObject *result = NULL;
6335 char *dir = NULL;
6336 char *pfx = NULL;
6337 char *name;
6338
6339 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
6340 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00006341
6342 if (PyErr_Warn(PyExc_RuntimeWarning,
6343 "tempnam is a potential security risk to your program") < 0)
6344 return NULL;
6345
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006346#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00006347 name = _tempnam(dir, pfx);
6348#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006349 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00006350#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006351 if (name == NULL)
6352 return PyErr_NoMemory();
6353 result = PyString_FromString(name);
6354 free(name);
6355 return result;
6356}
Guido van Rossumd371ff11999-01-25 16:12:23 +00006357#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006358
6359
6360#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006361PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006362"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006363Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006364
6365static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006366posix_tmpfile(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006367{
6368 FILE *fp;
6369
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006370 fp = tmpfile();
6371 if (fp == NULL)
6372 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00006373 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006374}
6375#endif
6376
6377
6378#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006379PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006380"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006381Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006382
6383static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006384posix_tmpnam(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006385{
6386 char buffer[L_tmpnam];
6387 char *name;
6388
Skip Montanaro95618b52001-08-18 18:52:10 +00006389 if (PyErr_Warn(PyExc_RuntimeWarning,
6390 "tmpnam is a potential security risk to your program") < 0)
6391 return NULL;
6392
Greg Wardb48bc172000-03-01 21:51:56 +00006393#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006394 name = tmpnam_r(buffer);
6395#else
6396 name = tmpnam(buffer);
6397#endif
6398 if (name == NULL) {
6399 PyErr_SetObject(PyExc_OSError,
6400 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00006401#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006402 "unexpected NULL from tmpnam_r"
6403#else
6404 "unexpected NULL from tmpnam"
6405#endif
6406 ));
6407 return NULL;
6408 }
6409 return PyString_FromString(buffer);
6410}
6411#endif
6412
6413
Fred Drakec9680921999-12-13 16:37:25 +00006414/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
6415 * It maps strings representing configuration variable names to
6416 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00006417 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00006418 * rarely-used constants. There are three separate tables that use
6419 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00006420 *
6421 * This code is always included, even if none of the interfaces that
6422 * need it are included. The #if hackery needed to avoid it would be
6423 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00006424 */
6425struct constdef {
6426 char *name;
6427 long value;
6428};
6429
Fred Drake12c6e2d1999-12-14 21:25:03 +00006430static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006431conv_confname(PyObject *arg, int *valuep, struct constdef *table,
6432 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006433{
6434 if (PyInt_Check(arg)) {
6435 *valuep = PyInt_AS_LONG(arg);
6436 return 1;
6437 }
6438 if (PyString_Check(arg)) {
6439 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00006440 size_t lo = 0;
6441 size_t mid;
6442 size_t hi = tablesize;
6443 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006444 char *confname = PyString_AS_STRING(arg);
6445 while (lo < hi) {
6446 mid = (lo + hi) / 2;
6447 cmp = strcmp(confname, table[mid].name);
6448 if (cmp < 0)
6449 hi = mid;
6450 else if (cmp > 0)
6451 lo = mid + 1;
6452 else {
6453 *valuep = table[mid].value;
6454 return 1;
6455 }
6456 }
6457 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
6458 }
6459 else
6460 PyErr_SetString(PyExc_TypeError,
6461 "configuration names must be strings or integers");
6462 return 0;
6463}
6464
6465
6466#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
6467static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006468#ifdef _PC_ABI_AIO_XFER_MAX
6469 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
6470#endif
6471#ifdef _PC_ABI_ASYNC_IO
6472 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
6473#endif
Fred Drakec9680921999-12-13 16:37:25 +00006474#ifdef _PC_ASYNC_IO
6475 {"PC_ASYNC_IO", _PC_ASYNC_IO},
6476#endif
6477#ifdef _PC_CHOWN_RESTRICTED
6478 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
6479#endif
6480#ifdef _PC_FILESIZEBITS
6481 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
6482#endif
6483#ifdef _PC_LAST
6484 {"PC_LAST", _PC_LAST},
6485#endif
6486#ifdef _PC_LINK_MAX
6487 {"PC_LINK_MAX", _PC_LINK_MAX},
6488#endif
6489#ifdef _PC_MAX_CANON
6490 {"PC_MAX_CANON", _PC_MAX_CANON},
6491#endif
6492#ifdef _PC_MAX_INPUT
6493 {"PC_MAX_INPUT", _PC_MAX_INPUT},
6494#endif
6495#ifdef _PC_NAME_MAX
6496 {"PC_NAME_MAX", _PC_NAME_MAX},
6497#endif
6498#ifdef _PC_NO_TRUNC
6499 {"PC_NO_TRUNC", _PC_NO_TRUNC},
6500#endif
6501#ifdef _PC_PATH_MAX
6502 {"PC_PATH_MAX", _PC_PATH_MAX},
6503#endif
6504#ifdef _PC_PIPE_BUF
6505 {"PC_PIPE_BUF", _PC_PIPE_BUF},
6506#endif
6507#ifdef _PC_PRIO_IO
6508 {"PC_PRIO_IO", _PC_PRIO_IO},
6509#endif
6510#ifdef _PC_SOCK_MAXBUF
6511 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
6512#endif
6513#ifdef _PC_SYNC_IO
6514 {"PC_SYNC_IO", _PC_SYNC_IO},
6515#endif
6516#ifdef _PC_VDISABLE
6517 {"PC_VDISABLE", _PC_VDISABLE},
6518#endif
6519};
6520
Fred Drakec9680921999-12-13 16:37:25 +00006521static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006522conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006523{
6524 return conv_confname(arg, valuep, posix_constants_pathconf,
6525 sizeof(posix_constants_pathconf)
6526 / sizeof(struct constdef));
6527}
6528#endif
6529
6530#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006531PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006532"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006533Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006534If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006535
6536static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006537posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006538{
6539 PyObject *result = NULL;
6540 int name, fd;
6541
Fred Drake12c6e2d1999-12-14 21:25:03 +00006542 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
6543 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00006544 long limit;
6545
6546 errno = 0;
6547 limit = fpathconf(fd, name);
6548 if (limit == -1 && errno != 0)
6549 posix_error();
6550 else
6551 result = PyInt_FromLong(limit);
6552 }
6553 return result;
6554}
6555#endif
6556
6557
6558#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006559PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006560"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006561Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006562If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006563
6564static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006565posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006566{
6567 PyObject *result = NULL;
6568 int name;
6569 char *path;
6570
6571 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
6572 conv_path_confname, &name)) {
6573 long limit;
6574
6575 errno = 0;
6576 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006577 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00006578 if (errno == EINVAL)
6579 /* could be a path or name problem */
6580 posix_error();
6581 else
6582 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006583 }
Fred Drakec9680921999-12-13 16:37:25 +00006584 else
6585 result = PyInt_FromLong(limit);
6586 }
6587 return result;
6588}
6589#endif
6590
6591#ifdef HAVE_CONFSTR
6592static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006593#ifdef _CS_ARCHITECTURE
6594 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
6595#endif
6596#ifdef _CS_HOSTNAME
6597 {"CS_HOSTNAME", _CS_HOSTNAME},
6598#endif
6599#ifdef _CS_HW_PROVIDER
6600 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
6601#endif
6602#ifdef _CS_HW_SERIAL
6603 {"CS_HW_SERIAL", _CS_HW_SERIAL},
6604#endif
6605#ifdef _CS_INITTAB_NAME
6606 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
6607#endif
Fred Drakec9680921999-12-13 16:37:25 +00006608#ifdef _CS_LFS64_CFLAGS
6609 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
6610#endif
6611#ifdef _CS_LFS64_LDFLAGS
6612 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
6613#endif
6614#ifdef _CS_LFS64_LIBS
6615 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
6616#endif
6617#ifdef _CS_LFS64_LINTFLAGS
6618 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
6619#endif
6620#ifdef _CS_LFS_CFLAGS
6621 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
6622#endif
6623#ifdef _CS_LFS_LDFLAGS
6624 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
6625#endif
6626#ifdef _CS_LFS_LIBS
6627 {"CS_LFS_LIBS", _CS_LFS_LIBS},
6628#endif
6629#ifdef _CS_LFS_LINTFLAGS
6630 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
6631#endif
Fred Draked86ed291999-12-15 15:34:33 +00006632#ifdef _CS_MACHINE
6633 {"CS_MACHINE", _CS_MACHINE},
6634#endif
Fred Drakec9680921999-12-13 16:37:25 +00006635#ifdef _CS_PATH
6636 {"CS_PATH", _CS_PATH},
6637#endif
Fred Draked86ed291999-12-15 15:34:33 +00006638#ifdef _CS_RELEASE
6639 {"CS_RELEASE", _CS_RELEASE},
6640#endif
6641#ifdef _CS_SRPC_DOMAIN
6642 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
6643#endif
6644#ifdef _CS_SYSNAME
6645 {"CS_SYSNAME", _CS_SYSNAME},
6646#endif
6647#ifdef _CS_VERSION
6648 {"CS_VERSION", _CS_VERSION},
6649#endif
Fred Drakec9680921999-12-13 16:37:25 +00006650#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
6651 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
6652#endif
6653#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
6654 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
6655#endif
6656#ifdef _CS_XBS5_ILP32_OFF32_LIBS
6657 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
6658#endif
6659#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
6660 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
6661#endif
6662#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
6663 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
6664#endif
6665#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
6666 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
6667#endif
6668#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
6669 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
6670#endif
6671#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
6672 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
6673#endif
6674#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
6675 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
6676#endif
6677#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
6678 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
6679#endif
6680#ifdef _CS_XBS5_LP64_OFF64_LIBS
6681 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
6682#endif
6683#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
6684 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
6685#endif
6686#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
6687 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
6688#endif
6689#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
6690 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
6691#endif
6692#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
6693 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
6694#endif
6695#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
6696 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
6697#endif
Fred Draked86ed291999-12-15 15:34:33 +00006698#ifdef _MIPS_CS_AVAIL_PROCESSORS
6699 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
6700#endif
6701#ifdef _MIPS_CS_BASE
6702 {"MIPS_CS_BASE", _MIPS_CS_BASE},
6703#endif
6704#ifdef _MIPS_CS_HOSTID
6705 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
6706#endif
6707#ifdef _MIPS_CS_HW_NAME
6708 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
6709#endif
6710#ifdef _MIPS_CS_NUM_PROCESSORS
6711 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
6712#endif
6713#ifdef _MIPS_CS_OSREL_MAJ
6714 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
6715#endif
6716#ifdef _MIPS_CS_OSREL_MIN
6717 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
6718#endif
6719#ifdef _MIPS_CS_OSREL_PATCH
6720 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
6721#endif
6722#ifdef _MIPS_CS_OS_NAME
6723 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
6724#endif
6725#ifdef _MIPS_CS_OS_PROVIDER
6726 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
6727#endif
6728#ifdef _MIPS_CS_PROCESSORS
6729 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
6730#endif
6731#ifdef _MIPS_CS_SERIAL
6732 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
6733#endif
6734#ifdef _MIPS_CS_VENDOR
6735 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
6736#endif
Fred Drakec9680921999-12-13 16:37:25 +00006737};
6738
6739static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006740conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006741{
6742 return conv_confname(arg, valuep, posix_constants_confstr,
6743 sizeof(posix_constants_confstr)
6744 / sizeof(struct constdef));
6745}
6746
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006747PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006748"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006749Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006750
6751static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006752posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006753{
6754 PyObject *result = NULL;
6755 int name;
6756 char buffer[64];
6757
6758 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
6759 int len = confstr(name, buffer, sizeof(buffer));
6760
Fred Drakec9680921999-12-13 16:37:25 +00006761 errno = 0;
6762 if (len == 0) {
6763 if (errno != 0)
6764 posix_error();
6765 else
6766 result = PyString_FromString("");
6767 }
6768 else {
6769 if (len >= sizeof(buffer)) {
6770 result = PyString_FromStringAndSize(NULL, len);
6771 if (result != NULL)
6772 confstr(name, PyString_AS_STRING(result), len+1);
6773 }
6774 else
6775 result = PyString_FromString(buffer);
6776 }
6777 }
6778 return result;
6779}
6780#endif
6781
6782
6783#ifdef HAVE_SYSCONF
6784static struct constdef posix_constants_sysconf[] = {
6785#ifdef _SC_2_CHAR_TERM
6786 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
6787#endif
6788#ifdef _SC_2_C_BIND
6789 {"SC_2_C_BIND", _SC_2_C_BIND},
6790#endif
6791#ifdef _SC_2_C_DEV
6792 {"SC_2_C_DEV", _SC_2_C_DEV},
6793#endif
6794#ifdef _SC_2_C_VERSION
6795 {"SC_2_C_VERSION", _SC_2_C_VERSION},
6796#endif
6797#ifdef _SC_2_FORT_DEV
6798 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
6799#endif
6800#ifdef _SC_2_FORT_RUN
6801 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
6802#endif
6803#ifdef _SC_2_LOCALEDEF
6804 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
6805#endif
6806#ifdef _SC_2_SW_DEV
6807 {"SC_2_SW_DEV", _SC_2_SW_DEV},
6808#endif
6809#ifdef _SC_2_UPE
6810 {"SC_2_UPE", _SC_2_UPE},
6811#endif
6812#ifdef _SC_2_VERSION
6813 {"SC_2_VERSION", _SC_2_VERSION},
6814#endif
Fred Draked86ed291999-12-15 15:34:33 +00006815#ifdef _SC_ABI_ASYNCHRONOUS_IO
6816 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
6817#endif
6818#ifdef _SC_ACL
6819 {"SC_ACL", _SC_ACL},
6820#endif
Fred Drakec9680921999-12-13 16:37:25 +00006821#ifdef _SC_AIO_LISTIO_MAX
6822 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
6823#endif
Fred Drakec9680921999-12-13 16:37:25 +00006824#ifdef _SC_AIO_MAX
6825 {"SC_AIO_MAX", _SC_AIO_MAX},
6826#endif
6827#ifdef _SC_AIO_PRIO_DELTA_MAX
6828 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
6829#endif
6830#ifdef _SC_ARG_MAX
6831 {"SC_ARG_MAX", _SC_ARG_MAX},
6832#endif
6833#ifdef _SC_ASYNCHRONOUS_IO
6834 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
6835#endif
6836#ifdef _SC_ATEXIT_MAX
6837 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
6838#endif
Fred Draked86ed291999-12-15 15:34:33 +00006839#ifdef _SC_AUDIT
6840 {"SC_AUDIT", _SC_AUDIT},
6841#endif
Fred Drakec9680921999-12-13 16:37:25 +00006842#ifdef _SC_AVPHYS_PAGES
6843 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
6844#endif
6845#ifdef _SC_BC_BASE_MAX
6846 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
6847#endif
6848#ifdef _SC_BC_DIM_MAX
6849 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
6850#endif
6851#ifdef _SC_BC_SCALE_MAX
6852 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
6853#endif
6854#ifdef _SC_BC_STRING_MAX
6855 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
6856#endif
Fred Draked86ed291999-12-15 15:34:33 +00006857#ifdef _SC_CAP
6858 {"SC_CAP", _SC_CAP},
6859#endif
Fred Drakec9680921999-12-13 16:37:25 +00006860#ifdef _SC_CHARCLASS_NAME_MAX
6861 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
6862#endif
6863#ifdef _SC_CHAR_BIT
6864 {"SC_CHAR_BIT", _SC_CHAR_BIT},
6865#endif
6866#ifdef _SC_CHAR_MAX
6867 {"SC_CHAR_MAX", _SC_CHAR_MAX},
6868#endif
6869#ifdef _SC_CHAR_MIN
6870 {"SC_CHAR_MIN", _SC_CHAR_MIN},
6871#endif
6872#ifdef _SC_CHILD_MAX
6873 {"SC_CHILD_MAX", _SC_CHILD_MAX},
6874#endif
6875#ifdef _SC_CLK_TCK
6876 {"SC_CLK_TCK", _SC_CLK_TCK},
6877#endif
6878#ifdef _SC_COHER_BLKSZ
6879 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
6880#endif
6881#ifdef _SC_COLL_WEIGHTS_MAX
6882 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
6883#endif
6884#ifdef _SC_DCACHE_ASSOC
6885 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
6886#endif
6887#ifdef _SC_DCACHE_BLKSZ
6888 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
6889#endif
6890#ifdef _SC_DCACHE_LINESZ
6891 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
6892#endif
6893#ifdef _SC_DCACHE_SZ
6894 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
6895#endif
6896#ifdef _SC_DCACHE_TBLKSZ
6897 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
6898#endif
6899#ifdef _SC_DELAYTIMER_MAX
6900 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
6901#endif
6902#ifdef _SC_EQUIV_CLASS_MAX
6903 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
6904#endif
6905#ifdef _SC_EXPR_NEST_MAX
6906 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
6907#endif
6908#ifdef _SC_FSYNC
6909 {"SC_FSYNC", _SC_FSYNC},
6910#endif
6911#ifdef _SC_GETGR_R_SIZE_MAX
6912 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
6913#endif
6914#ifdef _SC_GETPW_R_SIZE_MAX
6915 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
6916#endif
6917#ifdef _SC_ICACHE_ASSOC
6918 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
6919#endif
6920#ifdef _SC_ICACHE_BLKSZ
6921 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
6922#endif
6923#ifdef _SC_ICACHE_LINESZ
6924 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
6925#endif
6926#ifdef _SC_ICACHE_SZ
6927 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
6928#endif
Fred Draked86ed291999-12-15 15:34:33 +00006929#ifdef _SC_INF
6930 {"SC_INF", _SC_INF},
6931#endif
Fred Drakec9680921999-12-13 16:37:25 +00006932#ifdef _SC_INT_MAX
6933 {"SC_INT_MAX", _SC_INT_MAX},
6934#endif
6935#ifdef _SC_INT_MIN
6936 {"SC_INT_MIN", _SC_INT_MIN},
6937#endif
6938#ifdef _SC_IOV_MAX
6939 {"SC_IOV_MAX", _SC_IOV_MAX},
6940#endif
Fred Draked86ed291999-12-15 15:34:33 +00006941#ifdef _SC_IP_SECOPTS
6942 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
6943#endif
Fred Drakec9680921999-12-13 16:37:25 +00006944#ifdef _SC_JOB_CONTROL
6945 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
6946#endif
Fred Draked86ed291999-12-15 15:34:33 +00006947#ifdef _SC_KERN_POINTERS
6948 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
6949#endif
6950#ifdef _SC_KERN_SIM
6951 {"SC_KERN_SIM", _SC_KERN_SIM},
6952#endif
Fred Drakec9680921999-12-13 16:37:25 +00006953#ifdef _SC_LINE_MAX
6954 {"SC_LINE_MAX", _SC_LINE_MAX},
6955#endif
6956#ifdef _SC_LOGIN_NAME_MAX
6957 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
6958#endif
6959#ifdef _SC_LOGNAME_MAX
6960 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
6961#endif
6962#ifdef _SC_LONG_BIT
6963 {"SC_LONG_BIT", _SC_LONG_BIT},
6964#endif
Fred Draked86ed291999-12-15 15:34:33 +00006965#ifdef _SC_MAC
6966 {"SC_MAC", _SC_MAC},
6967#endif
Fred Drakec9680921999-12-13 16:37:25 +00006968#ifdef _SC_MAPPED_FILES
6969 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
6970#endif
6971#ifdef _SC_MAXPID
6972 {"SC_MAXPID", _SC_MAXPID},
6973#endif
6974#ifdef _SC_MB_LEN_MAX
6975 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
6976#endif
6977#ifdef _SC_MEMLOCK
6978 {"SC_MEMLOCK", _SC_MEMLOCK},
6979#endif
6980#ifdef _SC_MEMLOCK_RANGE
6981 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
6982#endif
6983#ifdef _SC_MEMORY_PROTECTION
6984 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
6985#endif
6986#ifdef _SC_MESSAGE_PASSING
6987 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
6988#endif
Fred Draked86ed291999-12-15 15:34:33 +00006989#ifdef _SC_MMAP_FIXED_ALIGNMENT
6990 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
6991#endif
Fred Drakec9680921999-12-13 16:37:25 +00006992#ifdef _SC_MQ_OPEN_MAX
6993 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
6994#endif
6995#ifdef _SC_MQ_PRIO_MAX
6996 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
6997#endif
Fred Draked86ed291999-12-15 15:34:33 +00006998#ifdef _SC_NACLS_MAX
6999 {"SC_NACLS_MAX", _SC_NACLS_MAX},
7000#endif
Fred Drakec9680921999-12-13 16:37:25 +00007001#ifdef _SC_NGROUPS_MAX
7002 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
7003#endif
7004#ifdef _SC_NL_ARGMAX
7005 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
7006#endif
7007#ifdef _SC_NL_LANGMAX
7008 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
7009#endif
7010#ifdef _SC_NL_MSGMAX
7011 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
7012#endif
7013#ifdef _SC_NL_NMAX
7014 {"SC_NL_NMAX", _SC_NL_NMAX},
7015#endif
7016#ifdef _SC_NL_SETMAX
7017 {"SC_NL_SETMAX", _SC_NL_SETMAX},
7018#endif
7019#ifdef _SC_NL_TEXTMAX
7020 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
7021#endif
7022#ifdef _SC_NPROCESSORS_CONF
7023 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
7024#endif
7025#ifdef _SC_NPROCESSORS_ONLN
7026 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
7027#endif
Fred Draked86ed291999-12-15 15:34:33 +00007028#ifdef _SC_NPROC_CONF
7029 {"SC_NPROC_CONF", _SC_NPROC_CONF},
7030#endif
7031#ifdef _SC_NPROC_ONLN
7032 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
7033#endif
Fred Drakec9680921999-12-13 16:37:25 +00007034#ifdef _SC_NZERO
7035 {"SC_NZERO", _SC_NZERO},
7036#endif
7037#ifdef _SC_OPEN_MAX
7038 {"SC_OPEN_MAX", _SC_OPEN_MAX},
7039#endif
7040#ifdef _SC_PAGESIZE
7041 {"SC_PAGESIZE", _SC_PAGESIZE},
7042#endif
7043#ifdef _SC_PAGE_SIZE
7044 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
7045#endif
7046#ifdef _SC_PASS_MAX
7047 {"SC_PASS_MAX", _SC_PASS_MAX},
7048#endif
7049#ifdef _SC_PHYS_PAGES
7050 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
7051#endif
7052#ifdef _SC_PII
7053 {"SC_PII", _SC_PII},
7054#endif
7055#ifdef _SC_PII_INTERNET
7056 {"SC_PII_INTERNET", _SC_PII_INTERNET},
7057#endif
7058#ifdef _SC_PII_INTERNET_DGRAM
7059 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
7060#endif
7061#ifdef _SC_PII_INTERNET_STREAM
7062 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
7063#endif
7064#ifdef _SC_PII_OSI
7065 {"SC_PII_OSI", _SC_PII_OSI},
7066#endif
7067#ifdef _SC_PII_OSI_CLTS
7068 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
7069#endif
7070#ifdef _SC_PII_OSI_COTS
7071 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
7072#endif
7073#ifdef _SC_PII_OSI_M
7074 {"SC_PII_OSI_M", _SC_PII_OSI_M},
7075#endif
7076#ifdef _SC_PII_SOCKET
7077 {"SC_PII_SOCKET", _SC_PII_SOCKET},
7078#endif
7079#ifdef _SC_PII_XTI
7080 {"SC_PII_XTI", _SC_PII_XTI},
7081#endif
7082#ifdef _SC_POLL
7083 {"SC_POLL", _SC_POLL},
7084#endif
7085#ifdef _SC_PRIORITIZED_IO
7086 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
7087#endif
7088#ifdef _SC_PRIORITY_SCHEDULING
7089 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
7090#endif
7091#ifdef _SC_REALTIME_SIGNALS
7092 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
7093#endif
7094#ifdef _SC_RE_DUP_MAX
7095 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
7096#endif
7097#ifdef _SC_RTSIG_MAX
7098 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
7099#endif
7100#ifdef _SC_SAVED_IDS
7101 {"SC_SAVED_IDS", _SC_SAVED_IDS},
7102#endif
7103#ifdef _SC_SCHAR_MAX
7104 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
7105#endif
7106#ifdef _SC_SCHAR_MIN
7107 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
7108#endif
7109#ifdef _SC_SELECT
7110 {"SC_SELECT", _SC_SELECT},
7111#endif
7112#ifdef _SC_SEMAPHORES
7113 {"SC_SEMAPHORES", _SC_SEMAPHORES},
7114#endif
7115#ifdef _SC_SEM_NSEMS_MAX
7116 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
7117#endif
7118#ifdef _SC_SEM_VALUE_MAX
7119 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
7120#endif
7121#ifdef _SC_SHARED_MEMORY_OBJECTS
7122 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
7123#endif
7124#ifdef _SC_SHRT_MAX
7125 {"SC_SHRT_MAX", _SC_SHRT_MAX},
7126#endif
7127#ifdef _SC_SHRT_MIN
7128 {"SC_SHRT_MIN", _SC_SHRT_MIN},
7129#endif
7130#ifdef _SC_SIGQUEUE_MAX
7131 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
7132#endif
7133#ifdef _SC_SIGRT_MAX
7134 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
7135#endif
7136#ifdef _SC_SIGRT_MIN
7137 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
7138#endif
Fred Draked86ed291999-12-15 15:34:33 +00007139#ifdef _SC_SOFTPOWER
7140 {"SC_SOFTPOWER", _SC_SOFTPOWER},
7141#endif
Fred Drakec9680921999-12-13 16:37:25 +00007142#ifdef _SC_SPLIT_CACHE
7143 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
7144#endif
7145#ifdef _SC_SSIZE_MAX
7146 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
7147#endif
7148#ifdef _SC_STACK_PROT
7149 {"SC_STACK_PROT", _SC_STACK_PROT},
7150#endif
7151#ifdef _SC_STREAM_MAX
7152 {"SC_STREAM_MAX", _SC_STREAM_MAX},
7153#endif
7154#ifdef _SC_SYNCHRONIZED_IO
7155 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
7156#endif
7157#ifdef _SC_THREADS
7158 {"SC_THREADS", _SC_THREADS},
7159#endif
7160#ifdef _SC_THREAD_ATTR_STACKADDR
7161 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
7162#endif
7163#ifdef _SC_THREAD_ATTR_STACKSIZE
7164 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
7165#endif
7166#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
7167 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
7168#endif
7169#ifdef _SC_THREAD_KEYS_MAX
7170 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
7171#endif
7172#ifdef _SC_THREAD_PRIORITY_SCHEDULING
7173 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
7174#endif
7175#ifdef _SC_THREAD_PRIO_INHERIT
7176 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
7177#endif
7178#ifdef _SC_THREAD_PRIO_PROTECT
7179 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
7180#endif
7181#ifdef _SC_THREAD_PROCESS_SHARED
7182 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
7183#endif
7184#ifdef _SC_THREAD_SAFE_FUNCTIONS
7185 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
7186#endif
7187#ifdef _SC_THREAD_STACK_MIN
7188 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
7189#endif
7190#ifdef _SC_THREAD_THREADS_MAX
7191 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
7192#endif
7193#ifdef _SC_TIMERS
7194 {"SC_TIMERS", _SC_TIMERS},
7195#endif
7196#ifdef _SC_TIMER_MAX
7197 {"SC_TIMER_MAX", _SC_TIMER_MAX},
7198#endif
7199#ifdef _SC_TTY_NAME_MAX
7200 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
7201#endif
7202#ifdef _SC_TZNAME_MAX
7203 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
7204#endif
7205#ifdef _SC_T_IOV_MAX
7206 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
7207#endif
7208#ifdef _SC_UCHAR_MAX
7209 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
7210#endif
7211#ifdef _SC_UINT_MAX
7212 {"SC_UINT_MAX", _SC_UINT_MAX},
7213#endif
7214#ifdef _SC_UIO_MAXIOV
7215 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
7216#endif
7217#ifdef _SC_ULONG_MAX
7218 {"SC_ULONG_MAX", _SC_ULONG_MAX},
7219#endif
7220#ifdef _SC_USHRT_MAX
7221 {"SC_USHRT_MAX", _SC_USHRT_MAX},
7222#endif
7223#ifdef _SC_VERSION
7224 {"SC_VERSION", _SC_VERSION},
7225#endif
7226#ifdef _SC_WORD_BIT
7227 {"SC_WORD_BIT", _SC_WORD_BIT},
7228#endif
7229#ifdef _SC_XBS5_ILP32_OFF32
7230 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
7231#endif
7232#ifdef _SC_XBS5_ILP32_OFFBIG
7233 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
7234#endif
7235#ifdef _SC_XBS5_LP64_OFF64
7236 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
7237#endif
7238#ifdef _SC_XBS5_LPBIG_OFFBIG
7239 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
7240#endif
7241#ifdef _SC_XOPEN_CRYPT
7242 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
7243#endif
7244#ifdef _SC_XOPEN_ENH_I18N
7245 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
7246#endif
7247#ifdef _SC_XOPEN_LEGACY
7248 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
7249#endif
7250#ifdef _SC_XOPEN_REALTIME
7251 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
7252#endif
7253#ifdef _SC_XOPEN_REALTIME_THREADS
7254 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
7255#endif
7256#ifdef _SC_XOPEN_SHM
7257 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
7258#endif
7259#ifdef _SC_XOPEN_UNIX
7260 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
7261#endif
7262#ifdef _SC_XOPEN_VERSION
7263 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
7264#endif
7265#ifdef _SC_XOPEN_XCU_VERSION
7266 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
7267#endif
7268#ifdef _SC_XOPEN_XPG2
7269 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
7270#endif
7271#ifdef _SC_XOPEN_XPG3
7272 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
7273#endif
7274#ifdef _SC_XOPEN_XPG4
7275 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
7276#endif
7277};
7278
7279static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007280conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007281{
7282 return conv_confname(arg, valuep, posix_constants_sysconf,
7283 sizeof(posix_constants_sysconf)
7284 / sizeof(struct constdef));
7285}
7286
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007287PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007288"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007289Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007290
7291static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007292posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007293{
7294 PyObject *result = NULL;
7295 int name;
7296
7297 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
7298 int value;
7299
7300 errno = 0;
7301 value = sysconf(name);
7302 if (value == -1 && errno != 0)
7303 posix_error();
7304 else
7305 result = PyInt_FromLong(value);
7306 }
7307 return result;
7308}
7309#endif
7310
7311
Fred Drakebec628d1999-12-15 18:31:10 +00007312/* This code is used to ensure that the tables of configuration value names
7313 * are in sorted order as required by conv_confname(), and also to build the
7314 * the exported dictionaries that are used to publish information about the
7315 * names available on the host platform.
7316 *
7317 * Sorting the table at runtime ensures that the table is properly ordered
7318 * when used, even for platforms we're not able to test on. It also makes
7319 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00007320 */
Fred Drakebec628d1999-12-15 18:31:10 +00007321
7322static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007323cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00007324{
7325 const struct constdef *c1 =
7326 (const struct constdef *) v1;
7327 const struct constdef *c2 =
7328 (const struct constdef *) v2;
7329
7330 return strcmp(c1->name, c2->name);
7331}
7332
7333static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007334setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00007335 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007336{
Fred Drakebec628d1999-12-15 18:31:10 +00007337 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00007338 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00007339
7340 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
7341 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00007342 if (d == NULL)
7343 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007344
Barry Warsaw3155db32000-04-13 15:20:40 +00007345 for (i=0; i < tablesize; ++i) {
7346 PyObject *o = PyInt_FromLong(table[i].value);
7347 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
7348 Py_XDECREF(o);
7349 Py_DECREF(d);
7350 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007351 }
Barry Warsaw3155db32000-04-13 15:20:40 +00007352 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00007353 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00007354 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00007355}
7356
Fred Drakebec628d1999-12-15 18:31:10 +00007357/* Return -1 on failure, 0 on success. */
7358static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007359setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007360{
7361#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00007362 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00007363 sizeof(posix_constants_pathconf)
7364 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007365 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007366 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007367#endif
7368#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00007369 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00007370 sizeof(posix_constants_confstr)
7371 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007372 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007373 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007374#endif
7375#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00007376 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00007377 sizeof(posix_constants_sysconf)
7378 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007379 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007380 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007381#endif
Fred Drakebec628d1999-12-15 18:31:10 +00007382 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00007383}
Fred Draked86ed291999-12-15 15:34:33 +00007384
7385
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007386PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007387"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007388Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007389in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007390
7391static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007392posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007393{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007394 abort();
7395 /*NOTREACHED*/
7396 Py_FatalError("abort() called from Python code didn't abort!");
7397 return NULL;
7398}
Fred Drakebec628d1999-12-15 18:31:10 +00007399
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007400#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007401PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00007402"startfile(filepath [, operation]) - Start a file with its associated\n\
7403application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007404\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00007405When \"operation\" is not specified or \"open\", this acts like\n\
7406double-clicking the file in Explorer, or giving the file name as an\n\
7407argument to the DOS \"start\" command: the file is opened with whatever\n\
7408application (if any) its extension is associated.\n\
7409When another \"operation\" is given, it specifies what should be done with\n\
7410the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007411\n\
7412startfile returns as soon as the associated application is launched.\n\
7413There is no option to wait for the application to close, and no way\n\
7414to retrieve the application's exit status.\n\
7415\n\
7416The filepath is relative to the current directory. If you want to use\n\
7417an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007418the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00007419
7420static PyObject *
7421win32_startfile(PyObject *self, PyObject *args)
7422{
7423 char *filepath;
Georg Brandlf4f44152006-02-18 22:29:33 +00007424 char *operation = NULL;
Tim Petersf58a7aa2000-09-22 10:05:54 +00007425 HINSTANCE rc;
Georg Brandlf4f44152006-02-18 22:29:33 +00007426 if (!PyArg_ParseTuple(args, "et|s:startfile",
7427 Py_FileSystemDefaultEncoding, &filepath,
7428 &operation))
Tim Petersf58a7aa2000-09-22 10:05:54 +00007429 return NULL;
7430 Py_BEGIN_ALLOW_THREADS
Georg Brandlf4f44152006-02-18 22:29:33 +00007431 rc = ShellExecute((HWND)0, operation, filepath,
7432 NULL, NULL, SW_SHOWNORMAL);
Tim Petersf58a7aa2000-09-22 10:05:54 +00007433 Py_END_ALLOW_THREADS
Georg Brandle9f8ec92005-09-25 06:16:40 +00007434 if (rc <= (HINSTANCE)32) {
7435 PyObject *errval = win32_error("startfile", filepath);
7436 PyMem_Free(filepath);
7437 return errval;
7438 }
7439 PyMem_Free(filepath);
Tim Petersf58a7aa2000-09-22 10:05:54 +00007440 Py_INCREF(Py_None);
7441 return Py_None;
7442}
7443#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007444
Martin v. Löwis438b5342002-12-27 10:16:42 +00007445#ifdef HAVE_GETLOADAVG
7446PyDoc_STRVAR(posix_getloadavg__doc__,
7447"getloadavg() -> (float, float, float)\n\n\
7448Return the number of processes in the system run queue averaged over\n\
7449the last 1, 5, and 15 minutes or raises OSError if the load average\n\
7450was unobtainable");
7451
7452static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007453posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00007454{
7455 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00007456 if (getloadavg(loadavg, 3)!=3) {
7457 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
7458 return NULL;
7459 } else
7460 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
7461}
7462#endif
7463
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007464#ifdef MS_WINDOWS
7465
7466PyDoc_STRVAR(win32_urandom__doc__,
7467"urandom(n) -> str\n\n\
7468Return a string of n random bytes suitable for cryptographic use.");
7469
7470typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
7471 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
7472 DWORD dwFlags );
7473typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
7474 BYTE *pbBuffer );
7475
7476static CRYPTGENRANDOM pCryptGenRandom = NULL;
7477static HCRYPTPROV hCryptProv = 0;
7478
Tim Peters4ad82172004-08-30 17:02:04 +00007479static PyObject*
7480win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007481{
Tim Petersd3115382004-08-30 17:36:46 +00007482 int howMany;
7483 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007484
Tim Peters4ad82172004-08-30 17:02:04 +00007485 /* Read arguments */
Tim Peters9b279a82004-08-30 17:10:53 +00007486 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
Tim Peters4ad82172004-08-30 17:02:04 +00007487 return NULL;
Tim Peters51eba612004-08-30 17:08:02 +00007488 if (howMany < 0)
7489 return PyErr_Format(PyExc_ValueError,
7490 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007491
Tim Peters4ad82172004-08-30 17:02:04 +00007492 if (hCryptProv == 0) {
7493 HINSTANCE hAdvAPI32 = NULL;
7494 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007495
Tim Peters4ad82172004-08-30 17:02:04 +00007496 /* Obtain handle to the DLL containing CryptoAPI
7497 This should not fail */
7498 hAdvAPI32 = GetModuleHandle("advapi32.dll");
7499 if(hAdvAPI32 == NULL)
7500 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007501
Tim Peters4ad82172004-08-30 17:02:04 +00007502 /* Obtain pointers to the CryptoAPI functions
7503 This will fail on some early versions of Win95 */
7504 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
7505 hAdvAPI32,
7506 "CryptAcquireContextA");
7507 if (pCryptAcquireContext == NULL)
7508 return PyErr_Format(PyExc_NotImplementedError,
7509 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007510
Tim Peters4ad82172004-08-30 17:02:04 +00007511 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
7512 hAdvAPI32, "CryptGenRandom");
7513 if (pCryptAcquireContext == NULL)
7514 return PyErr_Format(PyExc_NotImplementedError,
7515 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007516
Tim Peters4ad82172004-08-30 17:02:04 +00007517 /* Acquire context */
7518 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
7519 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
7520 return win32_error("CryptAcquireContext", NULL);
7521 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007522
Tim Peters4ad82172004-08-30 17:02:04 +00007523 /* Allocate bytes */
Tim Petersd3115382004-08-30 17:36:46 +00007524 result = PyString_FromStringAndSize(NULL, howMany);
7525 if (result != NULL) {
7526 /* Get random data */
7527 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
7528 PyString_AS_STRING(result))) {
7529 Py_DECREF(result);
7530 return win32_error("CryptGenRandom", NULL);
7531 }
Tim Peters4ad82172004-08-30 17:02:04 +00007532 }
Tim Petersd3115382004-08-30 17:36:46 +00007533 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007534}
7535#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007536
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007537static PyMethodDef posix_methods[] = {
7538 {"access", posix_access, METH_VARARGS, posix_access__doc__},
7539#ifdef HAVE_TTYNAME
7540 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
7541#endif
7542 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
7543 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007544#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007545 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007546#endif /* HAVE_CHOWN */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007547#ifdef HAVE_LCHOWN
7548 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
7549#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00007550#ifdef HAVE_CHROOT
7551 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
7552#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007553#ifdef HAVE_CTERMID
Neal Norwitze241ce82003-02-17 18:17:05 +00007554 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007555#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00007556#ifdef HAVE_GETCWD
Neal Norwitze241ce82003-02-17 18:17:05 +00007557 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Walter Dörwald3b918c32002-11-21 20:18:46 +00007558#ifdef Py_USING_UNICODE
Neal Norwitze241ce82003-02-17 18:17:05 +00007559 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00007560#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00007561#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007562#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007563 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007564#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007565 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
7566 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
7567 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007568#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007569 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007570#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007571#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007572 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007573#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007574 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
7575 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
7576 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007577 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007578#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007579 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007580#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007581#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007582 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007583#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007584 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007585#ifdef HAVE_UNAME
Neal Norwitze241ce82003-02-17 18:17:05 +00007586 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007587#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007588 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
7589 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
7590 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007591#ifdef HAVE_TIMES
Neal Norwitze241ce82003-02-17 18:17:05 +00007592 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007593#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007594 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007595#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007596 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
7597 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007598#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00007599#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007600 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
7601 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00007602#if defined(PYOS_OS2)
7603 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
7604 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
7605#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00007606#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007607#ifdef HAVE_FORK1
Neal Norwitze241ce82003-02-17 18:17:05 +00007608 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007609#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007610#ifdef HAVE_FORK
Neal Norwitze241ce82003-02-17 18:17:05 +00007611 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007612#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007613#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Neal Norwitze241ce82003-02-17 18:17:05 +00007614 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007615#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007616#ifdef HAVE_FORKPTY
Neal Norwitze241ce82003-02-17 18:17:05 +00007617 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00007618#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007619#ifdef HAVE_GETEGID
Neal Norwitze241ce82003-02-17 18:17:05 +00007620 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007621#endif /* HAVE_GETEGID */
7622#ifdef HAVE_GETEUID
Neal Norwitze241ce82003-02-17 18:17:05 +00007623 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007624#endif /* HAVE_GETEUID */
7625#ifdef HAVE_GETGID
Neal Norwitze241ce82003-02-17 18:17:05 +00007626 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007627#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00007628#ifdef HAVE_GETGROUPS
Neal Norwitze241ce82003-02-17 18:17:05 +00007629 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007630#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007631 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007632#ifdef HAVE_GETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00007633 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007634#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007635#ifdef HAVE_GETPPID
Neal Norwitze241ce82003-02-17 18:17:05 +00007636 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007637#endif /* HAVE_GETPPID */
7638#ifdef HAVE_GETUID
Neal Norwitze241ce82003-02-17 18:17:05 +00007639 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007640#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007641#ifdef HAVE_GETLOGIN
Neal Norwitze241ce82003-02-17 18:17:05 +00007642 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00007643#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00007644#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007645 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007646#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007647#ifdef HAVE_KILLPG
7648 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
7649#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00007650#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007651 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00007652#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007653#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007654 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007655#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00007656 {"popen2", win32_popen2, METH_VARARGS},
7657 {"popen3", win32_popen3, METH_VARARGS},
7658 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00007659 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007660#else
7661#if defined(PYOS_OS2) && defined(PYCC_GCC)
7662 {"popen2", os2emx_popen2, METH_VARARGS},
7663 {"popen3", os2emx_popen3, METH_VARARGS},
7664 {"popen4", os2emx_popen4, METH_VARARGS},
7665#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00007666#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007667#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007668#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007669 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007670#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007671#ifdef HAVE_SETEUID
7672 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
7673#endif /* HAVE_SETEUID */
7674#ifdef HAVE_SETEGID
7675 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
7676#endif /* HAVE_SETEGID */
7677#ifdef HAVE_SETREUID
7678 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
7679#endif /* HAVE_SETREUID */
7680#ifdef HAVE_SETREGID
7681 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
7682#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007683#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007684 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007685#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007686#ifdef HAVE_SETGROUPS
7687 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
7688#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00007689#ifdef HAVE_GETPGID
7690 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
7691#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007692#ifdef HAVE_SETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00007693 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007694#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007695#ifdef HAVE_WAIT
Neal Norwitze241ce82003-02-17 18:17:05 +00007696 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007697#endif /* HAVE_WAIT */
Tim Petersab034fa2002-02-01 11:27:43 +00007698#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007699 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007700#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007701#ifdef HAVE_GETSID
7702 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
7703#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007704#ifdef HAVE_SETSID
Neal Norwitze241ce82003-02-17 18:17:05 +00007705 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007706#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007707#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007708 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007709#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007710#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007711 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007712#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007713#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007714 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007715#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007716 {"open", posix_open, METH_VARARGS, posix_open__doc__},
7717 {"close", posix_close, METH_VARARGS, posix_close__doc__},
7718 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
7719 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
7720 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
7721 {"read", posix_read, METH_VARARGS, posix_read__doc__},
7722 {"write", posix_write, METH_VARARGS, posix_write__doc__},
7723 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
7724 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00007725 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007726#ifdef HAVE_PIPE
Neal Norwitze241ce82003-02-17 18:17:05 +00007727 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007728#endif
7729#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007730 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007731#endif
Neal Norwitz11690112002-07-30 01:08:28 +00007732#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007733 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
7734#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007735#ifdef HAVE_DEVICE_MACROS
7736 {"major", posix_major, METH_VARARGS, posix_major__doc__},
7737 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
7738 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
7739#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007740#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007741 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007742#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007743#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007744 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007745#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007746#ifdef HAVE_UNSETENV
7747 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
7748#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00007749#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007750 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00007751#endif
Fred Drake4d1e64b2002-04-15 19:40:07 +00007752#ifdef HAVE_FCHDIR
7753 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
7754#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00007755#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007756 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007757#endif
7758#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007759 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007760#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00007761#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00007762#ifdef WCOREDUMP
7763 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
7764#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007765#ifdef WIFCONTINUED
7766 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
7767#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00007768#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007769 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007770#endif /* WIFSTOPPED */
7771#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007772 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007773#endif /* WIFSIGNALED */
7774#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007775 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007776#endif /* WIFEXITED */
7777#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007778 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007779#endif /* WEXITSTATUS */
7780#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007781 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007782#endif /* WTERMSIG */
7783#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007784 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007785#endif /* WSTOPSIG */
7786#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007787#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007788 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007789#endif
7790#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007791 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007792#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00007793#ifdef HAVE_TMPFILE
Neal Norwitze241ce82003-02-17 18:17:05 +00007794 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007795#endif
7796#ifdef HAVE_TEMPNAM
7797 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
7798#endif
7799#ifdef HAVE_TMPNAM
Neal Norwitze241ce82003-02-17 18:17:05 +00007800 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007801#endif
Fred Drakec9680921999-12-13 16:37:25 +00007802#ifdef HAVE_CONFSTR
7803 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
7804#endif
7805#ifdef HAVE_SYSCONF
7806 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
7807#endif
7808#ifdef HAVE_FPATHCONF
7809 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
7810#endif
7811#ifdef HAVE_PATHCONF
7812 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
7813#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007814 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007815#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00007816 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
7817#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007818#ifdef HAVE_GETLOADAVG
Neal Norwitze241ce82003-02-17 18:17:05 +00007819 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00007820#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007821 #ifdef MS_WINDOWS
7822 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
7823 #endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007824 {NULL, NULL} /* Sentinel */
7825};
7826
7827
Barry Warsaw4a342091996-12-19 23:50:02 +00007828static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007829ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00007830{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007831 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00007832}
7833
Guido van Rossumd48f2521997-12-05 22:19:34 +00007834#if defined(PYOS_OS2)
7835/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007836static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007837{
7838 APIRET rc;
7839 ULONG values[QSV_MAX+1];
7840 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00007841 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00007842
7843 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00007844 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007845 Py_END_ALLOW_THREADS
7846
7847 if (rc != NO_ERROR) {
7848 os2_error(rc);
7849 return -1;
7850 }
7851
Fred Drake4d1e64b2002-04-15 19:40:07 +00007852 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
7853 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
7854 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
7855 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
7856 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
7857 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
7858 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007859
7860 switch (values[QSV_VERSION_MINOR]) {
7861 case 0: ver = "2.00"; break;
7862 case 10: ver = "2.10"; break;
7863 case 11: ver = "2.11"; break;
7864 case 30: ver = "3.00"; break;
7865 case 40: ver = "4.00"; break;
7866 case 50: ver = "5.00"; break;
7867 default:
Tim Peters885d4572001-11-28 20:27:42 +00007868 PyOS_snprintf(tmp, sizeof(tmp),
7869 "%d-%d", values[QSV_VERSION_MAJOR],
7870 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007871 ver = &tmp[0];
7872 }
7873
7874 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007875 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007876 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007877
7878 /* Add Indicator of Which Drive was Used to Boot the System */
7879 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
7880 tmp[1] = ':';
7881 tmp[2] = '\0';
7882
Fred Drake4d1e64b2002-04-15 19:40:07 +00007883 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007884}
7885#endif
7886
Barry Warsaw4a342091996-12-19 23:50:02 +00007887static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007888all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00007889{
Guido van Rossum94f6f721999-01-06 18:42:14 +00007890#ifdef F_OK
7891 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007892#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007893#ifdef R_OK
7894 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007895#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007896#ifdef W_OK
7897 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007898#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007899#ifdef X_OK
7900 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007901#endif
Fred Drakec9680921999-12-13 16:37:25 +00007902#ifdef NGROUPS_MAX
7903 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
7904#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007905#ifdef TMP_MAX
7906 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
7907#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007908#ifdef WCONTINUED
7909 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
7910#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007911#ifdef WNOHANG
7912 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007913#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007914#ifdef WUNTRACED
7915 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
7916#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007917#ifdef O_RDONLY
7918 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
7919#endif
7920#ifdef O_WRONLY
7921 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
7922#endif
7923#ifdef O_RDWR
7924 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
7925#endif
7926#ifdef O_NDELAY
7927 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
7928#endif
7929#ifdef O_NONBLOCK
7930 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
7931#endif
7932#ifdef O_APPEND
7933 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
7934#endif
7935#ifdef O_DSYNC
7936 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
7937#endif
7938#ifdef O_RSYNC
7939 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
7940#endif
7941#ifdef O_SYNC
7942 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
7943#endif
7944#ifdef O_NOCTTY
7945 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
7946#endif
7947#ifdef O_CREAT
7948 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
7949#endif
7950#ifdef O_EXCL
7951 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
7952#endif
7953#ifdef O_TRUNC
7954 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
7955#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00007956#ifdef O_BINARY
7957 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
7958#endif
7959#ifdef O_TEXT
7960 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
7961#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007962#ifdef O_LARGEFILE
7963 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
7964#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00007965#ifdef O_SHLOCK
7966 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
7967#endif
7968#ifdef O_EXLOCK
7969 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
7970#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007971
Tim Peters5aa91602002-01-30 05:46:57 +00007972/* MS Windows */
7973#ifdef O_NOINHERIT
7974 /* Don't inherit in child processes. */
7975 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
7976#endif
7977#ifdef _O_SHORT_LIVED
7978 /* Optimize for short life (keep in memory). */
7979 /* MS forgot to define this one with a non-underscore form too. */
7980 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
7981#endif
7982#ifdef O_TEMPORARY
7983 /* Automatically delete when last handle is closed. */
7984 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
7985#endif
7986#ifdef O_RANDOM
7987 /* Optimize for random access. */
7988 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
7989#endif
7990#ifdef O_SEQUENTIAL
7991 /* Optimize for sequential access. */
7992 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
7993#endif
7994
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007995/* GNU extensions. */
7996#ifdef O_DIRECT
7997 /* Direct disk access. */
7998 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
7999#endif
8000#ifdef O_DIRECTORY
8001 /* Must be a directory. */
8002 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
8003#endif
8004#ifdef O_NOFOLLOW
8005 /* Do not follow links. */
8006 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
8007#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00008008
Barry Warsaw5676bd12003-01-07 20:57:09 +00008009 /* These come from sysexits.h */
8010#ifdef EX_OK
8011 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008012#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008013#ifdef EX_USAGE
8014 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008015#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008016#ifdef EX_DATAERR
8017 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008018#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008019#ifdef EX_NOINPUT
8020 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008021#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008022#ifdef EX_NOUSER
8023 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008024#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008025#ifdef EX_NOHOST
8026 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008027#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008028#ifdef EX_UNAVAILABLE
8029 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008030#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008031#ifdef EX_SOFTWARE
8032 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008033#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008034#ifdef EX_OSERR
8035 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008036#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008037#ifdef EX_OSFILE
8038 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008039#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008040#ifdef EX_CANTCREAT
8041 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008042#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008043#ifdef EX_IOERR
8044 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008045#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008046#ifdef EX_TEMPFAIL
8047 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008048#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008049#ifdef EX_PROTOCOL
8050 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008051#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008052#ifdef EX_NOPERM
8053 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008054#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008055#ifdef EX_CONFIG
8056 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008057#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008058#ifdef EX_NOTFOUND
8059 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008060#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008061
Guido van Rossum246bc171999-02-01 23:54:31 +00008062#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008063#if defined(PYOS_OS2) && defined(PYCC_GCC)
8064 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
8065 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
8066 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
8067 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
8068 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
8069 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
8070 if (ins(d, "P_PM", (long)P_PM)) return -1;
8071 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
8072 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
8073 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
8074 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
8075 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
8076 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
8077 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
8078 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
8079 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
8080 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
8081 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
8082 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
8083 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
8084#else
Guido van Rossum7d385291999-02-16 19:38:04 +00008085 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
8086 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
8087 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
8088 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
8089 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00008090#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008091#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00008092
Guido van Rossumd48f2521997-12-05 22:19:34 +00008093#if defined(PYOS_OS2)
8094 if (insertvalues(d)) return -1;
8095#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008096 return 0;
8097}
8098
8099
Tim Peters5aa91602002-01-30 05:46:57 +00008100#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008101#define INITFUNC initnt
8102#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008103
8104#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008105#define INITFUNC initos2
8106#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008107
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008108#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008109#define INITFUNC initposix
8110#define MODNAME "posix"
8111#endif
8112
Mark Hammondfe51c6d2002-08-02 02:27:13 +00008113PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008114INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00008115{
Fred Drake4d1e64b2002-04-15 19:40:07 +00008116 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00008117
Fred Drake4d1e64b2002-04-15 19:40:07 +00008118 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008119 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00008120 posix__doc__);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00008121 if (m == NULL)
8122 return;
Tim Peters5aa91602002-01-30 05:46:57 +00008123
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008124 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008125 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00008126 Py_XINCREF(v);
8127 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008128 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00008129 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00008130
Fred Drake4d1e64b2002-04-15 19:40:07 +00008131 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00008132 return;
8133
Fred Drake4d1e64b2002-04-15 19:40:07 +00008134 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00008135 return;
8136
Fred Drake4d1e64b2002-04-15 19:40:07 +00008137 Py_INCREF(PyExc_OSError);
8138 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00008139
Guido van Rossumb3d39562000-01-31 18:41:26 +00008140#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00008141 if (posix_putenv_garbage == NULL)
8142 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00008143#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008144
Guido van Rossum14648392001-12-08 18:02:58 +00008145 stat_result_desc.name = MODNAME ".stat_result";
Martin v. Löwisf607bda2002-10-16 18:27:39 +00008146 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
8147 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
8148 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008149 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00008150 structseq_new = StatResultType.tp_new;
8151 StatResultType.tp_new = statresult_new;
Fred Drake4d1e64b2002-04-15 19:40:07 +00008152 Py_INCREF((PyObject*) &StatResultType);
8153 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008154
Guido van Rossum14648392001-12-08 18:02:58 +00008155 statvfs_result_desc.name = MODNAME ".statvfs_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008156 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Fred Drake4d1e64b2002-04-15 19:40:07 +00008157 Py_INCREF((PyObject*) &StatVFSResultType);
8158 PyModule_AddObject(m, "statvfs_result",
8159 (PyObject*) &StatVFSResultType);
Guido van Rossumb6775db1994-08-01 11:34:53 +00008160}