blob: efe5074135ad75064409f6d578756051c0e14851 [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;
1643 WIN32_FIND_DATA FileData;
Mark Hammondef8b6542001-05-13 08:04:26 +00001644 /* MAX_PATH characters could mean a bigger encoded string */
1645 char namebuf[MAX_PATH*2+5];
1646 char *bufptr = namebuf;
Martin v. Löwis18e16552006-02-15 17:27:45 +00001647 Py_ssize_t len = sizeof(namebuf)/sizeof(namebuf[0]);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001648
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001649#ifdef Py_WIN_WIDE_FILENAMES
1650 /* If on wide-character-capable OS see if argument
1651 is Unicode and if so use wide API. */
1652 if (unicode_file_names()) {
1653 PyUnicodeObject *po;
1654 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
1655 WIN32_FIND_DATAW wFileData;
1656 Py_UNICODE wnamebuf[MAX_PATH*2+5];
1657 Py_UNICODE wch;
1658 wcsncpy(wnamebuf, PyUnicode_AS_UNICODE(po), MAX_PATH);
1659 wnamebuf[MAX_PATH] = L'\0';
1660 len = wcslen(wnamebuf);
1661 wch = (len > 0) ? wnamebuf[len-1] : L'\0';
1662 if (wch != L'/' && wch != L'\\' && wch != L':')
1663 wnamebuf[len++] = L'/';
1664 wcscpy(wnamebuf + len, L"*.*");
1665 if ((d = PyList_New(0)) == NULL)
1666 return NULL;
1667 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
1668 if (hFindFile == INVALID_HANDLE_VALUE) {
1669 errno = GetLastError();
1670 if (errno == ERROR_FILE_NOT_FOUND) {
1671 return d;
1672 }
1673 Py_DECREF(d);
1674 return win32_error_unicode("FindFirstFileW", wnamebuf);
1675 }
1676 do {
1677 if (wFileData.cFileName[0] == L'.' &&
1678 (wFileData.cFileName[1] == L'\0' ||
1679 wFileData.cFileName[1] == L'.' &&
1680 wFileData.cFileName[2] == L'\0'))
1681 continue;
1682 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
1683 if (v == NULL) {
1684 Py_DECREF(d);
1685 d = NULL;
1686 break;
1687 }
1688 if (PyList_Append(d, v) != 0) {
1689 Py_DECREF(v);
1690 Py_DECREF(d);
1691 d = NULL;
1692 break;
1693 }
1694 Py_DECREF(v);
1695 } while (FindNextFileW(hFindFile, &wFileData) == TRUE);
1696
1697 if (FindClose(hFindFile) == FALSE) {
1698 Py_DECREF(d);
1699 return win32_error_unicode("FindClose", wnamebuf);
1700 }
1701 return d;
1702 }
1703 /* Drop the argument parsing error as narrow strings
1704 are also valid. */
1705 PyErr_Clear();
1706 }
1707#endif
1708
Tim Peters5aa91602002-01-30 05:46:57 +00001709 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001710 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +00001711 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +00001712 if (len > 0) {
1713 char ch = namebuf[len-1];
1714 if (ch != SEP && ch != ALTSEP && ch != ':')
1715 namebuf[len++] = '/';
1716 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001717 strcpy(namebuf + len, "*.*");
1718
Barry Warsaw53699e91996-12-10 23:23:01 +00001719 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001720 return NULL;
1721
1722 hFindFile = FindFirstFile(namebuf, &FileData);
1723 if (hFindFile == INVALID_HANDLE_VALUE) {
1724 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +00001725 if (errno == ERROR_FILE_NOT_FOUND)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001726 return d;
1727 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00001728 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001729 }
1730 do {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001731 if (FileData.cFileName[0] == '.' &&
1732 (FileData.cFileName[1] == '\0' ||
1733 FileData.cFileName[1] == '.' &&
1734 FileData.cFileName[2] == '\0'))
1735 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001736 v = PyString_FromString(FileData.cFileName);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001737 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001738 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001739 d = NULL;
1740 break;
1741 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001742 if (PyList_Append(d, v) != 0) {
1743 Py_DECREF(v);
1744 Py_DECREF(d);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001745 d = NULL;
1746 break;
1747 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001748 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001749 } while (FindNextFile(hFindFile, &FileData) == TRUE);
1750
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001751 if (FindClose(hFindFile) == FALSE) {
1752 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00001753 return win32_error("FindClose", namebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001754 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001755
1756 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001757
Tim Peters0bb44a42000-09-15 07:44:49 +00001758#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001759
1760#ifndef MAX_PATH
1761#define MAX_PATH CCHMAXPATH
1762#endif
1763 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00001764 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001765 PyObject *d, *v;
1766 char namebuf[MAX_PATH+5];
1767 HDIR hdir = 1;
1768 ULONG srchcnt = 1;
1769 FILEFINDBUF3 ep;
1770 APIRET rc;
1771
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001772 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001773 return NULL;
1774 if (len >= MAX_PATH) {
1775 PyErr_SetString(PyExc_ValueError, "path too long");
1776 return NULL;
1777 }
1778 strcpy(namebuf, name);
1779 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001780 if (*pt == ALTSEP)
1781 *pt = SEP;
1782 if (namebuf[len-1] != SEP)
1783 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001784 strcpy(namebuf + len, "*.*");
1785
1786 if ((d = PyList_New(0)) == NULL)
1787 return NULL;
1788
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001789 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
1790 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001791 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001792 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
1793 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
1794 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001795
1796 if (rc != NO_ERROR) {
1797 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001798 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001799 }
1800
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001801 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001802 do {
1803 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001804 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001805 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001806
1807 strcpy(namebuf, ep.achName);
1808
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001809 /* Leave Case of Name Alone -- In Native Form */
1810 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001811
1812 v = PyString_FromString(namebuf);
1813 if (v == NULL) {
1814 Py_DECREF(d);
1815 d = NULL;
1816 break;
1817 }
1818 if (PyList_Append(d, v) != 0) {
1819 Py_DECREF(v);
1820 Py_DECREF(d);
1821 d = NULL;
1822 break;
1823 }
1824 Py_DECREF(v);
1825 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1826 }
1827
1828 return d;
1829#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001830
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001831 char *name = NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001832 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001833 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001834 struct dirent *ep;
Just van Rossum96b1c902003-03-03 17:32:15 +00001835 int arg_is_unicode = 1;
1836
1837 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
1838 arg_is_unicode = 0;
1839 PyErr_Clear();
1840 }
1841 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001842 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001843 if ((dirp = opendir(name)) == NULL) {
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001844 return posix_error_with_allocated_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001845 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001846 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001847 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001848 PyMem_Free(name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001849 return NULL;
1850 }
1851 while ((ep = readdir(dirp)) != NULL) {
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001852 if (ep->d_name[0] == '.' &&
1853 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001854 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001855 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001856 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001857 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001858 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001859 d = NULL;
1860 break;
1861 }
Just van Rossum46c97842003-02-25 21:42:15 +00001862#ifdef Py_USING_UNICODE
Just van Rossum96b1c902003-03-03 17:32:15 +00001863 if (arg_is_unicode) {
Just van Rossum46c97842003-02-25 21:42:15 +00001864 PyObject *w;
1865
1866 w = PyUnicode_FromEncodedObject(v,
Tim Peters11b23062003-04-23 02:39:17 +00001867 Py_FileSystemDefaultEncoding,
Just van Rossum46c97842003-02-25 21:42:15 +00001868 "strict");
Just van Rossum6a421832003-03-04 19:30:44 +00001869 if (w != NULL) {
1870 Py_DECREF(v);
1871 v = w;
1872 }
1873 else {
1874 /* fall back to the original byte string, as
1875 discussed in patch #683592 */
1876 PyErr_Clear();
Just van Rossum46c97842003-02-25 21:42:15 +00001877 }
Just van Rossum46c97842003-02-25 21:42:15 +00001878 }
1879#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001880 if (PyList_Append(d, v) != 0) {
1881 Py_DECREF(v);
1882 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001883 d = NULL;
1884 break;
1885 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001886 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001887 }
1888 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001889 PyMem_Free(name);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001890
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001891 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001892
Tim Peters0bb44a42000-09-15 07:44:49 +00001893#endif /* which OS */
1894} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001895
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001896#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00001897/* A helper function for abspath on win32 */
1898static PyObject *
1899posix__getfullpathname(PyObject *self, PyObject *args)
1900{
1901 /* assume encoded strings wont more than double no of chars */
1902 char inbuf[MAX_PATH*2];
1903 char *inbufp = inbuf;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00001904 Py_ssize_t insize;
Mark Hammondef8b6542001-05-13 08:04:26 +00001905 char outbuf[MAX_PATH*2];
1906 char *temp;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001907#ifdef Py_WIN_WIDE_FILENAMES
1908 if (unicode_file_names()) {
1909 PyUnicodeObject *po;
1910 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
1911 Py_UNICODE woutbuf[MAX_PATH*2];
1912 Py_UNICODE *wtemp;
Tim Peters11b23062003-04-23 02:39:17 +00001913 if (!GetFullPathNameW(PyUnicode_AS_UNICODE(po),
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001914 sizeof(woutbuf)/sizeof(woutbuf[0]),
1915 woutbuf, &wtemp))
1916 return win32_error("GetFullPathName", "");
1917 return PyUnicode_FromUnicode(woutbuf, wcslen(woutbuf));
1918 }
1919 /* Drop the argument parsing error as narrow strings
1920 are also valid. */
1921 PyErr_Clear();
1922 }
1923#endif
Thomas Wouters68bc4f92006-03-01 01:05:10 +00001924 /* XXX(twouters) Why use 'et#' here at all? insize isn't used */
Tim Peters5aa91602002-01-30 05:46:57 +00001925 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
1926 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00001927 &insize))
1928 return NULL;
1929 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
1930 outbuf, &temp))
1931 return win32_error("GetFullPathName", inbuf);
Martin v. Löwis969297f2004-06-15 18:49:58 +00001932 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
1933 return PyUnicode_Decode(outbuf, strlen(outbuf),
1934 Py_FileSystemDefaultEncoding, NULL);
1935 }
Mark Hammondef8b6542001-05-13 08:04:26 +00001936 return PyString_FromString(outbuf);
1937} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001938#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00001939
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001940PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001941"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001942Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001943
Barry Warsaw53699e91996-12-10 23:23:01 +00001944static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001945posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001946{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001947 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00001948 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001949 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001950
1951#ifdef Py_WIN_WIDE_FILENAMES
1952 if (unicode_file_names()) {
1953 PyUnicodeObject *po;
Mark Hammond05107b62003-02-19 04:08:27 +00001954 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001955 Py_BEGIN_ALLOW_THREADS
1956 /* PyUnicode_AS_UNICODE OK without thread lock as
1957 it is a simple dereference. */
1958 res = _wmkdir(PyUnicode_AS_UNICODE(po));
1959 Py_END_ALLOW_THREADS
1960 if (res < 0)
1961 return posix_error();
1962 Py_INCREF(Py_None);
1963 return Py_None;
1964 }
1965 /* Drop the argument parsing error as narrow strings
1966 are also valid. */
1967 PyErr_Clear();
1968 }
1969#endif
1970
Tim Peters5aa91602002-01-30 05:46:57 +00001971 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001972 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001973 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001974 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001975#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001976 res = mkdir(path);
1977#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001978 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001979#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001980 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001981 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001982 return posix_error_with_allocated_filename(path);
1983 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001984 Py_INCREF(Py_None);
1985 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001986}
1987
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001988
Guido van Rossumb6775db1994-08-01 11:34:53 +00001989#ifdef HAVE_NICE
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001990#if defined(HAVE_BROKEN_NICE) && defined(HAVE_SYS_RESOURCE_H)
1991#if defined(HAVE_GETPRIORITY) && !defined(PRIO_PROCESS)
1992#include <sys/resource.h>
1993#endif
1994#endif
1995
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001996PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001997"nice(inc) -> new_priority\n\n\
1998Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001999
Barry Warsaw53699e91996-12-10 23:23:01 +00002000static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002001posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002002{
2003 int increment, value;
2004
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002005 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00002006 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002007
2008 /* There are two flavours of 'nice': one that returns the new
2009 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002010 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2011 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002012
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002013 If we are of the nice family that returns the new priority, we
2014 need to clear errno before the call, and check if errno is filled
2015 before calling posix_error() on a returnvalue of -1, because the
2016 -1 may be the actual new priority! */
2017
2018 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002019 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002020#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002021 if (value == 0)
2022 value = getpriority(PRIO_PROCESS, 0);
2023#endif
2024 if (value == -1 && errno != 0)
2025 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00002026 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002027 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002028}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002029#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002030
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002031
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002032PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002033"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002034Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002035
Barry Warsaw53699e91996-12-10 23:23:01 +00002036static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002037posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002038{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002039#ifdef MS_WINDOWS
2040 return posix_2str(args, "etet:rename", rename, "OO:rename", _wrename);
2041#else
2042 return posix_2str(args, "etet:rename", rename, NULL, NULL);
2043#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002044}
2045
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002046
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002047PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002048"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002049Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002050
Barry Warsaw53699e91996-12-10 23:23:01 +00002051static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002052posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002053{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002054#ifdef MS_WINDOWS
2055 return posix_1str(args, "et:rmdir", rmdir, "U:rmdir", _wrmdir);
2056#else
2057 return posix_1str(args, "et:rmdir", rmdir, NULL, NULL);
2058#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002059}
2060
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002061
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002062PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002063"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002064Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002065
Barry Warsaw53699e91996-12-10 23:23:01 +00002066static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002067posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002068{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002069#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00002070 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002071#else
2072 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
2073#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002074}
2075
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002076
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002077#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002078PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002079"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002080Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002081
Barry Warsaw53699e91996-12-10 23:23:01 +00002082static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002083posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002084{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002085 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002086 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002087 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002088 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002089 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002090 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00002091 Py_END_ALLOW_THREADS
2092 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002093}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002094#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002095
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002096
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002097PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002098"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002099Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002100
Barry Warsaw53699e91996-12-10 23:23:01 +00002101static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002102posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002103{
2104 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002105 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002106 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00002107 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002108 if (i < 0)
2109 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002110 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002111}
2112
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002113
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002114PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002115"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002116Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002117
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002118PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002119"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002120Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002121
Barry Warsaw53699e91996-12-10 23:23:01 +00002122static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002123posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002124{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002125#ifdef MS_WINDOWS
2126 return posix_1str(args, "et:remove", unlink, "U:remove", _wunlink);
2127#else
2128 return posix_1str(args, "et:remove", unlink, NULL, NULL);
2129#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002130}
2131
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002132
Guido van Rossumb6775db1994-08-01 11:34:53 +00002133#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002134PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002135"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002136Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002137
Barry Warsaw53699e91996-12-10 23:23:01 +00002138static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002139posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002140{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002141 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002142 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00002143
Barry Warsaw53699e91996-12-10 23:23:01 +00002144 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002145 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00002146 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002147 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002148 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002149 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00002150 u.sysname,
2151 u.nodename,
2152 u.release,
2153 u.version,
2154 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002155}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002156#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002157
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002158static int
2159extract_time(PyObject *t, long* sec, long* usec)
2160{
2161 long intval;
2162 if (PyFloat_Check(t)) {
2163 double tval = PyFloat_AsDouble(t);
2164 PyObject *intobj = t->ob_type->tp_as_number->nb_int(t);
2165 if (!intobj)
2166 return -1;
2167 intval = PyInt_AsLong(intobj);
2168 Py_DECREF(intobj);
Michael W. Hudsonb8963812005-07-05 15:21:58 +00002169 if (intval == -1 && PyErr_Occurred())
2170 return -1;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002171 *sec = intval;
Tim Peters96940cf2002-09-10 15:37:28 +00002172 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002173 if (*usec < 0)
2174 /* If rounding gave us a negative number,
2175 truncate. */
2176 *usec = 0;
2177 return 0;
2178 }
2179 intval = PyInt_AsLong(t);
2180 if (intval == -1 && PyErr_Occurred())
2181 return -1;
2182 *sec = intval;
2183 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00002184 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002185}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002186
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002187PyDoc_STRVAR(posix_utime__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002188"utime(path, (atime, utime))\n\
2189utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00002190Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002191second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002192
Barry Warsaw53699e91996-12-10 23:23:01 +00002193static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002194posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002195{
Neal Norwitz2adf2102004-06-09 01:46:02 +00002196 char *path = NULL;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002197 long atime, mtime, ausec, musec;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002198 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002199 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002200
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002201#if defined(HAVE_UTIMES)
2202 struct timeval buf[2];
2203#define ATIME buf[0].tv_sec
2204#define MTIME buf[1].tv_sec
2205#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002206/* XXX should define struct utimbuf instead, above */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002207 struct utimbuf buf;
2208#define ATIME buf.actime
2209#define MTIME buf.modtime
2210#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002211#else /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002212 time_t buf[2];
2213#define ATIME buf[0]
2214#define MTIME buf[1]
2215#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002216#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002217
Mark Hammond817c9292003-12-03 01:22:38 +00002218 int have_unicode_filename = 0;
2219#ifdef Py_WIN_WIDE_FILENAMES
2220 PyUnicodeObject *obwpath;
2221 wchar_t *wpath;
2222 if (unicode_file_names()) {
2223 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
2224 wpath = PyUnicode_AS_UNICODE(obwpath);
2225 have_unicode_filename = 1;
2226 } else
2227 /* Drop the argument parsing error as narrow strings
2228 are also valid. */
2229 PyErr_Clear();
2230 }
2231#endif /* Py_WIN_WIDE_FILENAMES */
2232
2233 if (!have_unicode_filename && \
Hye-Shik Chang2b2c9732004-01-04 13:54:25 +00002234 !PyArg_ParseTuple(args, "etO:utime",
2235 Py_FileSystemDefaultEncoding, &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002236 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002237 if (arg == Py_None) {
2238 /* optional time values not given */
2239 Py_BEGIN_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002240#ifdef Py_WIN_WIDE_FILENAMES
2241 if (have_unicode_filename)
2242 res = _wutime(wpath, NULL);
2243 else
2244#endif /* Py_WIN_WIDE_FILENAMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002245 res = utime(path, NULL);
2246 Py_END_ALLOW_THREADS
2247 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002248 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00002249 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002250 "utime() arg 2 must be a tuple (atime, mtime)");
Neal Norwitz96652712004-06-06 20:40:27 +00002251 PyMem_Free(path);
Barry Warsaw3cef8562000-05-01 16:17:24 +00002252 return NULL;
2253 }
2254 else {
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002255 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Neal Norwitz96652712004-06-06 20:40:27 +00002256 &atime, &ausec) == -1) {
2257 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002258 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002259 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002260 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Neal Norwitz96652712004-06-06 20:40:27 +00002261 &mtime, &musec) == -1) {
2262 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002263 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002264 }
Barry Warsaw3cef8562000-05-01 16:17:24 +00002265 ATIME = atime;
2266 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002267#ifdef HAVE_UTIMES
2268 buf[0].tv_usec = ausec;
2269 buf[1].tv_usec = musec;
2270 Py_BEGIN_ALLOW_THREADS
2271 res = utimes(path, buf);
2272 Py_END_ALLOW_THREADS
2273#else
Barry Warsaw3cef8562000-05-01 16:17:24 +00002274 Py_BEGIN_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002275#ifdef Py_WIN_WIDE_FILENAMES
2276 if (have_unicode_filename)
Tim Peters4ad82172004-08-30 17:02:04 +00002277 /* utime is OK with utimbuf, but _wutime insists
2278 on _utimbuf (the msvc headers assert the
Mark Hammond817c9292003-12-03 01:22:38 +00002279 underscore version is ansi) */
2280 res = _wutime(wpath, (struct _utimbuf *)UTIME_ARG);
2281 else
2282#endif /* Py_WIN_WIDE_FILENAMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002283 res = utime(path, UTIME_ARG);
2284 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002285#endif /* HAVE_UTIMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002286 }
Mark Hammond2d5914b2004-05-04 08:10:37 +00002287 if (res < 0) {
2288#ifdef Py_WIN_WIDE_FILENAMES
Neal Norwitz2adf2102004-06-09 01:46:02 +00002289 if (have_unicode_filename)
Mark Hammond2d5914b2004-05-04 08:10:37 +00002290 return posix_error_with_unicode_filename(wpath);
2291#endif /* Py_WIN_WIDE_FILENAMES */
Neal Norwitz96652712004-06-06 20:40:27 +00002292 return posix_error_with_allocated_filename(path);
Mark Hammond2d5914b2004-05-04 08:10:37 +00002293 }
Neal Norwitz96652712004-06-06 20:40:27 +00002294 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002295 Py_INCREF(Py_None);
2296 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002297#undef UTIME_ARG
2298#undef ATIME
2299#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002300}
2301
Guido van Rossum85e3b011991-06-03 12:42:10 +00002302
Guido van Rossum3b066191991-06-04 19:40:25 +00002303/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002304
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002305PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002306"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002307Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002308
Barry Warsaw53699e91996-12-10 23:23:01 +00002309static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002310posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002311{
2312 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002313 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002314 return NULL;
2315 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00002316 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002317}
2318
Martin v. Löwis114619e2002-10-07 06:44:21 +00002319#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
2320static void
2321free_string_array(char **array, int count)
2322{
2323 int i;
2324 for (i = 0; i < count; i++)
2325 PyMem_Free(array[i]);
2326 PyMem_DEL(array);
2327}
2328#endif
2329
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002330
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002331#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002332PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002333"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002334Execute an executable path with arguments, replacing current process.\n\
2335\n\
2336 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002337 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002338
Barry Warsaw53699e91996-12-10 23:23:01 +00002339static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002340posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002341{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002342 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002343 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002344 char **argvlist;
2345 int i, argc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002346 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002347
Guido van Rossum89b33251993-10-22 14:26:06 +00002348 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00002349 argv is a list or tuple of strings. */
2350
Martin v. Löwis114619e2002-10-07 06:44:21 +00002351 if (!PyArg_ParseTuple(args, "etO:execv",
2352 Py_FileSystemDefaultEncoding,
2353 &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002354 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002355 if (PyList_Check(argv)) {
2356 argc = PyList_Size(argv);
2357 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002358 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002359 else if (PyTuple_Check(argv)) {
2360 argc = PyTuple_Size(argv);
2361 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002362 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002363 else {
Fred Drake661ea262000-10-24 19:57:45 +00002364 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002365 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002366 return NULL;
2367 }
2368
Barry Warsaw53699e91996-12-10 23:23:01 +00002369 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002370 if (argvlist == NULL) {
2371 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002372 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002373 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002374 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002375 if (!PyArg_Parse((*getitem)(argv, i), "et",
2376 Py_FileSystemDefaultEncoding,
2377 &argvlist[i])) {
2378 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00002379 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002380 "execv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002381 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002382 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00002383
Guido van Rossum85e3b011991-06-03 12:42:10 +00002384 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002385 }
2386 argvlist[argc] = NULL;
2387
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002388 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002389
Guido van Rossum85e3b011991-06-03 12:42:10 +00002390 /* If we get here it's definitely an error */
2391
Martin v. Löwis114619e2002-10-07 06:44:21 +00002392 free_string_array(argvlist, argc);
2393 PyMem_Free(path);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002394 return posix_error();
2395}
2396
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002397
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002398PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002399"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002400Execute a path with arguments and environment, replacing current process.\n\
2401\n\
2402 path: path of executable file\n\
2403 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002404 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002405
Barry Warsaw53699e91996-12-10 23:23:01 +00002406static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002407posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002408{
2409 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002410 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002411 char **argvlist;
2412 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002413 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002414 int i, pos, argc, envc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002415 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002416 int lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002417
2418 /* execve has three arguments: (path, argv, env), where
2419 argv is a list or tuple of strings and env is a dictionary
2420 like posix.environ. */
2421
Martin v. Löwis114619e2002-10-07 06:44:21 +00002422 if (!PyArg_ParseTuple(args, "etOO:execve",
2423 Py_FileSystemDefaultEncoding,
2424 &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002425 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002426 if (PyList_Check(argv)) {
2427 argc = PyList_Size(argv);
2428 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002429 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002430 else if (PyTuple_Check(argv)) {
2431 argc = PyTuple_Size(argv);
2432 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002433 }
2434 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002435 PyErr_SetString(PyExc_TypeError,
2436 "execve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002437 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002438 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002439 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002440 PyErr_SetString(PyExc_TypeError,
2441 "execve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002442 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002443 }
2444
Barry Warsaw53699e91996-12-10 23:23:01 +00002445 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002446 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002447 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002448 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002449 }
2450 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002451 if (!PyArg_Parse((*getitem)(argv, i),
Martin v. Löwis114619e2002-10-07 06:44:21 +00002452 "et;execve() arg 2 must contain only strings",
Guido van Rossum1e700d22002-10-16 16:52:11 +00002453 Py_FileSystemDefaultEncoding,
Barry Warsaw43d68b81996-12-19 22:10:44 +00002454 &argvlist[i]))
2455 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002456 lastarg = i;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002457 goto fail_1;
2458 }
2459 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002460 lastarg = argc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002461 argvlist[argc] = NULL;
2462
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002463 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002464 if (i < 0)
2465 goto fail_1;
Barry Warsaw53699e91996-12-10 23:23:01 +00002466 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002467 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002468 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002469 goto fail_1;
2470 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002471 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002472 keys = PyMapping_Keys(env);
2473 vals = PyMapping_Values(env);
2474 if (!keys || !vals)
2475 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002476 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2477 PyErr_SetString(PyExc_TypeError,
2478 "execve(): env.keys() or env.values() is not a list");
2479 goto fail_2;
2480 }
Tim Peters5aa91602002-01-30 05:46:57 +00002481
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002482 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002483 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002484 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002485
2486 key = PyList_GetItem(keys, pos);
2487 val = PyList_GetItem(vals, pos);
2488 if (!key || !val)
2489 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002490
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002491 if (!PyArg_Parse(
2492 key,
2493 "s;execve() arg 3 contains a non-string key",
2494 &k) ||
2495 !PyArg_Parse(
2496 val,
2497 "s;execve() arg 3 contains a non-string value",
2498 &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00002499 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002500 goto fail_2;
2501 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00002502
2503#if defined(PYOS_OS2)
2504 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
2505 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
2506#endif
Tim Petersc8996f52001-12-03 20:41:00 +00002507 len = PyString_Size(key) + PyString_Size(val) + 2;
2508 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002509 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002510 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002511 goto fail_2;
2512 }
Tim Petersc8996f52001-12-03 20:41:00 +00002513 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002514 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00002515#if defined(PYOS_OS2)
2516 }
2517#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002518 }
2519 envlist[envc] = 0;
2520
2521 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00002522
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002523 /* If we get here it's definitely an error */
2524
2525 (void) posix_error();
2526
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002527 fail_2:
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002528 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00002529 PyMem_DEL(envlist[envc]);
2530 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002531 fail_1:
2532 free_string_array(argvlist, lastarg);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002533 Py_XDECREF(vals);
2534 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002535 fail_0:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002536 PyMem_Free(path);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002537 return NULL;
2538}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002539#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002540
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002541
Guido van Rossuma1065681999-01-25 23:20:23 +00002542#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002543PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002544"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002545Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002546\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002547 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002548 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002549 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002550
2551static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002552posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002553{
2554 char *path;
2555 PyObject *argv;
2556 char **argvlist;
2557 int mode, i, argc;
Tim Peters79248aa2001-08-29 21:37:10 +00002558 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002559 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00002560
2561 /* spawnv has three arguments: (mode, path, argv), where
2562 argv is a list or tuple of strings. */
2563
Martin v. Löwis114619e2002-10-07 06:44:21 +00002564 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
2565 Py_FileSystemDefaultEncoding,
2566 &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00002567 return NULL;
2568 if (PyList_Check(argv)) {
2569 argc = PyList_Size(argv);
2570 getitem = PyList_GetItem;
2571 }
2572 else if (PyTuple_Check(argv)) {
2573 argc = PyTuple_Size(argv);
2574 getitem = PyTuple_GetItem;
2575 }
2576 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002577 PyErr_SetString(PyExc_TypeError,
2578 "spawnv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002579 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002580 return NULL;
2581 }
2582
2583 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002584 if (argvlist == NULL) {
2585 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002586 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002587 }
Guido van Rossuma1065681999-01-25 23:20:23 +00002588 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002589 if (!PyArg_Parse((*getitem)(argv, i), "et",
2590 Py_FileSystemDefaultEncoding,
2591 &argvlist[i])) {
2592 free_string_array(argvlist, i);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002593 PyErr_SetString(
2594 PyExc_TypeError,
2595 "spawnv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002596 PyMem_Free(path);
Fred Drake137507e2000-06-01 02:02:46 +00002597 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00002598 }
2599 }
2600 argvlist[argc] = NULL;
2601
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002602#if defined(PYOS_OS2) && defined(PYCC_GCC)
2603 Py_BEGIN_ALLOW_THREADS
2604 spawnval = spawnv(mode, path, argvlist);
2605 Py_END_ALLOW_THREADS
2606#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002607 if (mode == _OLD_P_OVERLAY)
2608 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00002609
Tim Peters25059d32001-12-07 20:35:43 +00002610 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002611 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00002612 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002613#endif
Tim Peters5aa91602002-01-30 05:46:57 +00002614
Martin v. Löwis114619e2002-10-07 06:44:21 +00002615 free_string_array(argvlist, argc);
2616 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002617
Fred Drake699f3522000-06-29 21:12:41 +00002618 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002619 return posix_error();
2620 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002621#if SIZEOF_LONG == SIZEOF_VOID_P
2622 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002623#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00002624 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002625#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002626}
2627
2628
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002629PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002630"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002631Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002632\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002633 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002634 path: path of executable file\n\
2635 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002636 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002637
2638static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002639posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002640{
2641 char *path;
2642 PyObject *argv, *env;
2643 char **argvlist;
2644 char **envlist;
2645 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
2646 int mode, i, pos, argc, envc;
Tim Peters79248aa2001-08-29 21:37:10 +00002647 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002648 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002649 int lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002650
2651 /* spawnve has four arguments: (mode, path, argv, env), where
2652 argv is a list or tuple of strings and env is a dictionary
2653 like posix.environ. */
2654
Martin v. Löwis114619e2002-10-07 06:44:21 +00002655 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
2656 Py_FileSystemDefaultEncoding,
2657 &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00002658 return NULL;
2659 if (PyList_Check(argv)) {
2660 argc = PyList_Size(argv);
2661 getitem = PyList_GetItem;
2662 }
2663 else if (PyTuple_Check(argv)) {
2664 argc = PyTuple_Size(argv);
2665 getitem = PyTuple_GetItem;
2666 }
2667 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002668 PyErr_SetString(PyExc_TypeError,
2669 "spawnve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002670 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002671 }
2672 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002673 PyErr_SetString(PyExc_TypeError,
2674 "spawnve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002675 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002676 }
2677
2678 argvlist = PyMem_NEW(char *, argc+1);
2679 if (argvlist == NULL) {
2680 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002681 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002682 }
2683 for (i = 0; i < argc; i++) {
2684 if (!PyArg_Parse((*getitem)(argv, i),
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002685 "et;spawnve() arg 2 must contain only strings",
Martin v. Löwis114619e2002-10-07 06:44:21 +00002686 Py_FileSystemDefaultEncoding,
Guido van Rossuma1065681999-01-25 23:20:23 +00002687 &argvlist[i]))
2688 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002689 lastarg = i;
Guido van Rossuma1065681999-01-25 23:20:23 +00002690 goto fail_1;
2691 }
2692 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002693 lastarg = argc;
Guido van Rossuma1065681999-01-25 23:20:23 +00002694 argvlist[argc] = NULL;
2695
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002696 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002697 if (i < 0)
2698 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00002699 envlist = PyMem_NEW(char *, i + 1);
2700 if (envlist == NULL) {
2701 PyErr_NoMemory();
2702 goto fail_1;
2703 }
2704 envc = 0;
2705 keys = PyMapping_Keys(env);
2706 vals = PyMapping_Values(env);
2707 if (!keys || !vals)
2708 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002709 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2710 PyErr_SetString(PyExc_TypeError,
2711 "spawnve(): env.keys() or env.values() is not a list");
2712 goto fail_2;
2713 }
Tim Peters5aa91602002-01-30 05:46:57 +00002714
Guido van Rossuma1065681999-01-25 23:20:23 +00002715 for (pos = 0; pos < i; pos++) {
2716 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002717 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00002718
2719 key = PyList_GetItem(keys, pos);
2720 val = PyList_GetItem(vals, pos);
2721 if (!key || !val)
2722 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002723
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002724 if (!PyArg_Parse(
2725 key,
2726 "s;spawnve() arg 3 contains a non-string key",
2727 &k) ||
2728 !PyArg_Parse(
2729 val,
2730 "s;spawnve() arg 3 contains a non-string value",
2731 &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00002732 {
2733 goto fail_2;
2734 }
Tim Petersc8996f52001-12-03 20:41:00 +00002735 len = PyString_Size(key) + PyString_Size(val) + 2;
2736 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00002737 if (p == NULL) {
2738 PyErr_NoMemory();
2739 goto fail_2;
2740 }
Tim Petersc8996f52001-12-03 20:41:00 +00002741 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00002742 envlist[envc++] = p;
2743 }
2744 envlist[envc] = 0;
2745
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002746#if defined(PYOS_OS2) && defined(PYCC_GCC)
2747 Py_BEGIN_ALLOW_THREADS
2748 spawnval = spawnve(mode, path, argvlist, envlist);
2749 Py_END_ALLOW_THREADS
2750#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002751 if (mode == _OLD_P_OVERLAY)
2752 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00002753
2754 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002755 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00002756 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002757#endif
Tim Peters25059d32001-12-07 20:35:43 +00002758
Fred Drake699f3522000-06-29 21:12:41 +00002759 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002760 (void) posix_error();
2761 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002762#if SIZEOF_LONG == SIZEOF_VOID_P
2763 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002764#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00002765 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002766#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002767
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002768 fail_2:
Guido van Rossuma1065681999-01-25 23:20:23 +00002769 while (--envc >= 0)
2770 PyMem_DEL(envlist[envc]);
2771 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002772 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002773 free_string_array(argvlist, lastarg);
Guido van Rossuma1065681999-01-25 23:20:23 +00002774 Py_XDECREF(vals);
2775 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002776 fail_0:
2777 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002778 return res;
2779}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00002780
2781/* OS/2 supports spawnvp & spawnvpe natively */
2782#if defined(PYOS_OS2)
2783PyDoc_STRVAR(posix_spawnvp__doc__,
2784"spawnvp(mode, file, args)\n\n\
2785Execute the program 'file' in a new process, using the environment\n\
2786search path to find the file.\n\
2787\n\
2788 mode: mode of process creation\n\
2789 file: executable file name\n\
2790 args: tuple or list of strings");
2791
2792static PyObject *
2793posix_spawnvp(PyObject *self, PyObject *args)
2794{
2795 char *path;
2796 PyObject *argv;
2797 char **argvlist;
2798 int mode, i, argc;
2799 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002800 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00002801
2802 /* spawnvp has three arguments: (mode, path, argv), where
2803 argv is a list or tuple of strings. */
2804
2805 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
2806 Py_FileSystemDefaultEncoding,
2807 &path, &argv))
2808 return NULL;
2809 if (PyList_Check(argv)) {
2810 argc = PyList_Size(argv);
2811 getitem = PyList_GetItem;
2812 }
2813 else if (PyTuple_Check(argv)) {
2814 argc = PyTuple_Size(argv);
2815 getitem = PyTuple_GetItem;
2816 }
2817 else {
2818 PyErr_SetString(PyExc_TypeError,
2819 "spawnvp() arg 2 must be a tuple or list");
2820 PyMem_Free(path);
2821 return NULL;
2822 }
2823
2824 argvlist = PyMem_NEW(char *, argc+1);
2825 if (argvlist == NULL) {
2826 PyMem_Free(path);
2827 return PyErr_NoMemory();
2828 }
2829 for (i = 0; i < argc; i++) {
2830 if (!PyArg_Parse((*getitem)(argv, i), "et",
2831 Py_FileSystemDefaultEncoding,
2832 &argvlist[i])) {
2833 free_string_array(argvlist, i);
2834 PyErr_SetString(
2835 PyExc_TypeError,
2836 "spawnvp() arg 2 must contain only strings");
2837 PyMem_Free(path);
2838 return NULL;
2839 }
2840 }
2841 argvlist[argc] = NULL;
2842
2843 Py_BEGIN_ALLOW_THREADS
2844#if defined(PYCC_GCC)
2845 spawnval = spawnvp(mode, path, argvlist);
2846#else
2847 spawnval = _spawnvp(mode, path, argvlist);
2848#endif
2849 Py_END_ALLOW_THREADS
2850
2851 free_string_array(argvlist, argc);
2852 PyMem_Free(path);
2853
2854 if (spawnval == -1)
2855 return posix_error();
2856 else
2857 return Py_BuildValue("l", (long) spawnval);
2858}
2859
2860
2861PyDoc_STRVAR(posix_spawnvpe__doc__,
2862"spawnvpe(mode, file, args, env)\n\n\
2863Execute the program 'file' in a new process, using the environment\n\
2864search path to find the file.\n\
2865\n\
2866 mode: mode of process creation\n\
2867 file: executable file name\n\
2868 args: tuple or list of arguments\n\
2869 env: dictionary of strings mapping to strings");
2870
2871static PyObject *
2872posix_spawnvpe(PyObject *self, PyObject *args)
2873{
2874 char *path;
2875 PyObject *argv, *env;
2876 char **argvlist;
2877 char **envlist;
2878 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
2879 int mode, i, pos, argc, envc;
2880 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002881 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00002882 int lastarg = 0;
2883
2884 /* spawnvpe has four arguments: (mode, path, argv, env), where
2885 argv is a list or tuple of strings and env is a dictionary
2886 like posix.environ. */
2887
2888 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
2889 Py_FileSystemDefaultEncoding,
2890 &path, &argv, &env))
2891 return NULL;
2892 if (PyList_Check(argv)) {
2893 argc = PyList_Size(argv);
2894 getitem = PyList_GetItem;
2895 }
2896 else if (PyTuple_Check(argv)) {
2897 argc = PyTuple_Size(argv);
2898 getitem = PyTuple_GetItem;
2899 }
2900 else {
2901 PyErr_SetString(PyExc_TypeError,
2902 "spawnvpe() arg 2 must be a tuple or list");
2903 goto fail_0;
2904 }
2905 if (!PyMapping_Check(env)) {
2906 PyErr_SetString(PyExc_TypeError,
2907 "spawnvpe() arg 3 must be a mapping object");
2908 goto fail_0;
2909 }
2910
2911 argvlist = PyMem_NEW(char *, argc+1);
2912 if (argvlist == NULL) {
2913 PyErr_NoMemory();
2914 goto fail_0;
2915 }
2916 for (i = 0; i < argc; i++) {
2917 if (!PyArg_Parse((*getitem)(argv, i),
2918 "et;spawnvpe() arg 2 must contain only strings",
2919 Py_FileSystemDefaultEncoding,
2920 &argvlist[i]))
2921 {
2922 lastarg = i;
2923 goto fail_1;
2924 }
2925 }
2926 lastarg = argc;
2927 argvlist[argc] = NULL;
2928
2929 i = PyMapping_Size(env);
2930 if (i < 0)
2931 goto fail_1;
2932 envlist = PyMem_NEW(char *, i + 1);
2933 if (envlist == NULL) {
2934 PyErr_NoMemory();
2935 goto fail_1;
2936 }
2937 envc = 0;
2938 keys = PyMapping_Keys(env);
2939 vals = PyMapping_Values(env);
2940 if (!keys || !vals)
2941 goto fail_2;
2942 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2943 PyErr_SetString(PyExc_TypeError,
2944 "spawnvpe(): env.keys() or env.values() is not a list");
2945 goto fail_2;
2946 }
2947
2948 for (pos = 0; pos < i; pos++) {
2949 char *p, *k, *v;
2950 size_t len;
2951
2952 key = PyList_GetItem(keys, pos);
2953 val = PyList_GetItem(vals, pos);
2954 if (!key || !val)
2955 goto fail_2;
2956
2957 if (!PyArg_Parse(
2958 key,
2959 "s;spawnvpe() arg 3 contains a non-string key",
2960 &k) ||
2961 !PyArg_Parse(
2962 val,
2963 "s;spawnvpe() arg 3 contains a non-string value",
2964 &v))
2965 {
2966 goto fail_2;
2967 }
2968 len = PyString_Size(key) + PyString_Size(val) + 2;
2969 p = PyMem_NEW(char, len);
2970 if (p == NULL) {
2971 PyErr_NoMemory();
2972 goto fail_2;
2973 }
2974 PyOS_snprintf(p, len, "%s=%s", k, v);
2975 envlist[envc++] = p;
2976 }
2977 envlist[envc] = 0;
2978
2979 Py_BEGIN_ALLOW_THREADS
2980#if defined(PYCC_GCC)
2981 spawnval = spawnve(mode, path, argvlist, envlist);
2982#else
2983 spawnval = _spawnve(mode, path, argvlist, envlist);
2984#endif
2985 Py_END_ALLOW_THREADS
2986
2987 if (spawnval == -1)
2988 (void) posix_error();
2989 else
2990 res = Py_BuildValue("l", (long) spawnval);
2991
2992 fail_2:
2993 while (--envc >= 0)
2994 PyMem_DEL(envlist[envc]);
2995 PyMem_DEL(envlist);
2996 fail_1:
2997 free_string_array(argvlist, lastarg);
2998 Py_XDECREF(vals);
2999 Py_XDECREF(keys);
3000 fail_0:
3001 PyMem_Free(path);
3002 return res;
3003}
3004#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003005#endif /* HAVE_SPAWNV */
3006
3007
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003008#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003009PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003010"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003011Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3012\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003013Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003014
3015static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003016posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003017{
Neal Norwitze241ce82003-02-17 18:17:05 +00003018 int pid = fork1();
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003019 if (pid == -1)
3020 return posix_error();
3021 PyOS_AfterFork();
3022 return PyInt_FromLong((long)pid);
3023}
3024#endif
3025
3026
Guido van Rossumad0ee831995-03-01 10:34:45 +00003027#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003028PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003029"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003030Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003031Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003032
Barry Warsaw53699e91996-12-10 23:23:01 +00003033static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003034posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003035{
Neal Norwitze241ce82003-02-17 18:17:05 +00003036 int pid = fork();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003037 if (pid == -1)
3038 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003039 if (pid == 0)
3040 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00003041 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003042}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003043#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003044
Neal Norwitzb59798b2003-03-21 01:43:31 +00003045/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00003046/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3047#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00003048#define DEV_PTY_FILE "/dev/ptc"
3049#define HAVE_DEV_PTMX
3050#else
3051#define DEV_PTY_FILE "/dev/ptmx"
3052#endif
3053
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003054#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003055#ifdef HAVE_PTY_H
3056#include <pty.h>
3057#else
3058#ifdef HAVE_LIBUTIL_H
3059#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00003060#endif /* HAVE_LIBUTIL_H */
3061#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00003062#ifdef HAVE_STROPTS_H
3063#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003064#endif
3065#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003066
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003067#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003068PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003069"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003070Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003071
3072static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003073posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003074{
3075 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003076#ifndef HAVE_OPENPTY
3077 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003078#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003079#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003080 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003081#ifdef sun
3082 extern char *ptsname();
3083#endif
3084#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00003085
Thomas Wouters70c21a12000-07-14 14:28:33 +00003086#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00003087 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
3088 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003089#elif defined(HAVE__GETPTY)
Thomas Wouters70c21a12000-07-14 14:28:33 +00003090 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
3091 if (slave_name == NULL)
3092 return posix_error();
3093
3094 slave_fd = open(slave_name, O_RDWR);
3095 if (slave_fd < 0)
3096 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003097#else
Neal Norwitzb59798b2003-03-21 01:43:31 +00003098 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003099 if (master_fd < 0)
3100 return posix_error();
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003101 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003102 /* change permission of slave */
3103 if (grantpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003104 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003105 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003106 }
3107 /* unlock slave */
3108 if (unlockpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003109 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003110 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003111 }
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003112 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003113 slave_name = ptsname(master_fd); /* get name of slave */
3114 if (slave_name == NULL)
3115 return posix_error();
3116 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
3117 if (slave_fd < 0)
3118 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003119#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003120 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
3121 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00003122#ifndef __hpux
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003123 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00003124#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003125#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00003126#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00003127
Fred Drake8cef4cf2000-06-28 16:40:38 +00003128 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00003129
Fred Drake8cef4cf2000-06-28 16:40:38 +00003130}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003131#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003132
3133#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003134PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003135"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00003136Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
3137Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003138To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003139
3140static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003141posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003142{
Neal Norwitz24b3c222005-09-19 06:43:44 +00003143 int master_fd = -1, pid;
Tim Peters5aa91602002-01-30 05:46:57 +00003144
Fred Drake8cef4cf2000-06-28 16:40:38 +00003145 pid = forkpty(&master_fd, NULL, NULL, NULL);
3146 if (pid == -1)
3147 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003148 if (pid == 0)
3149 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00003150 return Py_BuildValue("(ii)", pid, master_fd);
3151}
3152#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003153
Guido van Rossumad0ee831995-03-01 10:34:45 +00003154#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003155PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003156"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003157Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003158
Barry Warsaw53699e91996-12-10 23:23:01 +00003159static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003160posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003161{
Barry Warsaw53699e91996-12-10 23:23:01 +00003162 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003163}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003164#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003165
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003166
Guido van Rossumad0ee831995-03-01 10:34:45 +00003167#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003168PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003169"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003170Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003171
Barry Warsaw53699e91996-12-10 23:23:01 +00003172static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003173posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003174{
Barry Warsaw53699e91996-12-10 23:23:01 +00003175 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003176}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003177#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003178
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003179
Guido van Rossumad0ee831995-03-01 10:34:45 +00003180#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003181PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003182"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003183Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003184
Barry Warsaw53699e91996-12-10 23:23:01 +00003185static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003186posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003187{
Barry Warsaw53699e91996-12-10 23:23:01 +00003188 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003189}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003190#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003191
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003192
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003193PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003194"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003195Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003196
Barry Warsaw53699e91996-12-10 23:23:01 +00003197static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003198posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003199{
Barry Warsaw53699e91996-12-10 23:23:01 +00003200 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003201}
3202
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003203
Fred Drakec9680921999-12-13 16:37:25 +00003204#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003205PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003206"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003207Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00003208
3209static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003210posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00003211{
3212 PyObject *result = NULL;
3213
Fred Drakec9680921999-12-13 16:37:25 +00003214#ifdef NGROUPS_MAX
3215#define MAX_GROUPS NGROUPS_MAX
3216#else
3217 /* defined to be 16 on Solaris7, so this should be a small number */
3218#define MAX_GROUPS 64
3219#endif
3220 gid_t grouplist[MAX_GROUPS];
3221 int n;
3222
3223 n = getgroups(MAX_GROUPS, grouplist);
3224 if (n < 0)
3225 posix_error();
3226 else {
3227 result = PyList_New(n);
3228 if (result != NULL) {
Fred Drakec9680921999-12-13 16:37:25 +00003229 int i;
3230 for (i = 0; i < n; ++i) {
Neal Norwitze241ce82003-02-17 18:17:05 +00003231 PyObject *o = PyInt_FromLong((long)grouplist[i]);
Fred Drakec9680921999-12-13 16:37:25 +00003232 if (o == NULL) {
3233 Py_DECREF(result);
3234 result = NULL;
3235 break;
3236 }
3237 PyList_SET_ITEM(result, i, o);
3238 }
3239 }
3240 }
Neal Norwitze241ce82003-02-17 18:17:05 +00003241
Fred Drakec9680921999-12-13 16:37:25 +00003242 return result;
3243}
3244#endif
3245
Martin v. Löwis606edc12002-06-13 21:09:11 +00003246#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003247PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003248"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003249Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00003250
3251static PyObject *
3252posix_getpgid(PyObject *self, PyObject *args)
3253{
3254 int pid, pgid;
3255 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
3256 return NULL;
3257 pgid = getpgid(pid);
3258 if (pgid < 0)
3259 return posix_error();
3260 return PyInt_FromLong((long)pgid);
3261}
3262#endif /* HAVE_GETPGID */
3263
3264
Guido van Rossumb6775db1994-08-01 11:34:53 +00003265#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003266PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003267"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003268Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003269
Barry Warsaw53699e91996-12-10 23:23:01 +00003270static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003271posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00003272{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003273#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00003274 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003275#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00003276 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003277#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00003278}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003279#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00003280
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003281
Guido van Rossumb6775db1994-08-01 11:34:53 +00003282#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003283PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003284"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003285Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003286
Barry Warsaw53699e91996-12-10 23:23:01 +00003287static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003288posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003289{
Guido van Rossum64933891994-10-20 21:56:42 +00003290#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00003291 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003292#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003293 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003294#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00003295 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003296 Py_INCREF(Py_None);
3297 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003298}
3299
Guido van Rossumb6775db1994-08-01 11:34:53 +00003300#endif /* HAVE_SETPGRP */
3301
Guido van Rossumad0ee831995-03-01 10:34:45 +00003302#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003303PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003304"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003305Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003306
Barry Warsaw53699e91996-12-10 23:23:01 +00003307static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003308posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003309{
Barry Warsaw53699e91996-12-10 23:23:01 +00003310 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003311}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003312#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003313
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003314
Fred Drake12c6e2d1999-12-14 21:25:03 +00003315#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003316PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003317"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003318Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00003319
3320static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003321posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00003322{
Neal Norwitze241ce82003-02-17 18:17:05 +00003323 PyObject *result = NULL;
Fred Drakea30680b2000-12-06 21:24:28 +00003324 char *name;
3325 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00003326
Fred Drakea30680b2000-12-06 21:24:28 +00003327 errno = 0;
3328 name = getlogin();
3329 if (name == NULL) {
3330 if (errno)
3331 posix_error();
3332 else
3333 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00003334 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00003335 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00003336 else
3337 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00003338 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00003339
Fred Drake12c6e2d1999-12-14 21:25:03 +00003340 return result;
3341}
3342#endif
3343
Guido van Rossumad0ee831995-03-01 10:34:45 +00003344#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003345PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003346"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003347Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003348
Barry Warsaw53699e91996-12-10 23:23:01 +00003349static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003350posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003351{
Barry Warsaw53699e91996-12-10 23:23:01 +00003352 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003353}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003354#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003355
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003356
Guido van Rossumad0ee831995-03-01 10:34:45 +00003357#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003358PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003359"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003360Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003361
Barry Warsaw53699e91996-12-10 23:23:01 +00003362static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003363posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003364{
3365 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003366 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00003367 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003368#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003369 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
3370 APIRET rc;
3371 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003372 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003373
3374 } else if (sig == XCPT_SIGNAL_KILLPROC) {
3375 APIRET rc;
3376 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003377 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003378
3379 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003380 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003381#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00003382 if (kill(pid, sig) == -1)
3383 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003384#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003385 Py_INCREF(Py_None);
3386 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003387}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003388#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003389
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003390#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003391PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003392"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003393Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003394
3395static PyObject *
3396posix_killpg(PyObject *self, PyObject *args)
3397{
3398 int pgid, sig;
3399 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
3400 return NULL;
3401 if (killpg(pgid, sig) == -1)
3402 return posix_error();
3403 Py_INCREF(Py_None);
3404 return Py_None;
3405}
3406#endif
3407
Guido van Rossumc0125471996-06-28 18:55:32 +00003408#ifdef HAVE_PLOCK
3409
3410#ifdef HAVE_SYS_LOCK_H
3411#include <sys/lock.h>
3412#endif
3413
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003414PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003415"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003416Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003417
Barry Warsaw53699e91996-12-10 23:23:01 +00003418static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003419posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00003420{
3421 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003422 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00003423 return NULL;
3424 if (plock(op) == -1)
3425 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003426 Py_INCREF(Py_None);
3427 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00003428}
3429#endif
3430
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003431
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003432#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003433PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003434"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003435Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003436
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003437#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003438#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003439static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003440async_system(const char *command)
3441{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003442 char errormsg[256], args[1024];
3443 RESULTCODES rcodes;
3444 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003445
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003446 char *shell = getenv("COMSPEC");
3447 if (!shell)
3448 shell = "cmd";
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003449
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003450 /* avoid overflowing the argument buffer */
3451 if (strlen(shell) + 3 + strlen(command) >= 1024)
3452 return ERROR_NOT_ENOUGH_MEMORY
3453
3454 args[0] = '\0';
3455 strcat(args, shell);
3456 strcat(args, "/c ");
3457 strcat(args, command);
3458
3459 /* execute asynchronously, inheriting the environment */
3460 rc = DosExecPgm(errormsg,
3461 sizeof(errormsg),
3462 EXEC_ASYNC,
3463 args,
3464 NULL,
3465 &rcodes,
3466 shell);
3467 return rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003468}
3469
Guido van Rossumd48f2521997-12-05 22:19:34 +00003470static FILE *
3471popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003472{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003473 int oldfd, tgtfd;
3474 HFILE pipeh[2];
3475 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003476
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003477 /* mode determines which of stdin or stdout is reconnected to
3478 * the pipe to the child
3479 */
3480 if (strchr(mode, 'r') != NULL) {
3481 tgt_fd = 1; /* stdout */
3482 } else if (strchr(mode, 'w')) {
3483 tgt_fd = 0; /* stdin */
3484 } else {
3485 *err = ERROR_INVALID_ACCESS;
3486 return NULL;
3487 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003488
Andrew MacIntyrea3be2582004-12-18 09:51:05 +00003489 /* setup the pipe */
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003490 if ((rc = DosCreatePipe(&pipeh[0], &pipeh[1], pipesize)) != NO_ERROR) {
3491 *err = rc;
3492 return NULL;
3493 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003494
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003495 /* prevent other threads accessing stdio */
3496 DosEnterCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003497
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003498 /* reconnect stdio and execute child */
3499 oldfd = dup(tgtfd);
3500 close(tgtfd);
3501 if (dup2(pipeh[tgtfd], tgtfd) == 0) {
3502 DosClose(pipeh[tgtfd]);
3503 rc = async_system(command);
3504 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003505
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003506 /* restore stdio */
3507 dup2(oldfd, tgtfd);
3508 close(oldfd);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003509
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003510 /* allow other threads access to stdio */
3511 DosExitCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003512
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003513 /* if execution of child was successful return file stream */
3514 if (rc == NO_ERROR)
3515 return fdopen(pipeh[1 - tgtfd], mode);
3516 else {
3517 DosClose(pipeh[1 - tgtfd]);
3518 *err = rc;
3519 return NULL;
3520 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003521}
3522
3523static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003524posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003525{
3526 char *name;
3527 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00003528 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003529 FILE *fp;
3530 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003531 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003532 return NULL;
3533 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00003534 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003535 Py_END_ALLOW_THREADS
3536 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003537 return os2_error(err);
3538
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003539 f = PyFile_FromFile(fp, name, mode, fclose);
3540 if (f != NULL)
3541 PyFile_SetBufSize(f, bufsize);
3542 return f;
3543}
3544
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003545#elif defined(PYCC_GCC)
3546
3547/* standard posix version of popen() support */
3548static PyObject *
3549posix_popen(PyObject *self, PyObject *args)
3550{
3551 char *name;
3552 char *mode = "r";
3553 int bufsize = -1;
3554 FILE *fp;
3555 PyObject *f;
3556 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
3557 return NULL;
3558 Py_BEGIN_ALLOW_THREADS
3559 fp = popen(name, mode);
3560 Py_END_ALLOW_THREADS
3561 if (fp == NULL)
3562 return posix_error();
3563 f = PyFile_FromFile(fp, name, mode, pclose);
3564 if (f != NULL)
3565 PyFile_SetBufSize(f, bufsize);
3566 return f;
3567}
3568
3569/* fork() under OS/2 has lots'o'warts
3570 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
3571 * most of this code is a ripoff of the win32 code, but using the
3572 * capabilities of EMX's C library routines
3573 */
3574
3575/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
3576#define POPEN_1 1
3577#define POPEN_2 2
3578#define POPEN_3 3
3579#define POPEN_4 4
3580
3581static PyObject *_PyPopen(char *, int, int, int);
3582static int _PyPclose(FILE *file);
3583
3584/*
3585 * Internal dictionary mapping popen* file pointers to process handles,
3586 * for use when retrieving the process exit code. See _PyPclose() below
3587 * for more information on this dictionary's use.
3588 */
3589static PyObject *_PyPopenProcs = NULL;
3590
3591/* os2emx version of popen2()
3592 *
3593 * The result of this function is a pipe (file) connected to the
3594 * process's stdin, and a pipe connected to the process's stdout.
3595 */
3596
3597static PyObject *
3598os2emx_popen2(PyObject *self, PyObject *args)
3599{
3600 PyObject *f;
3601 int tm=0;
3602
3603 char *cmdstring;
3604 char *mode = "t";
3605 int bufsize = -1;
3606 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
3607 return NULL;
3608
3609 if (*mode == 't')
3610 tm = O_TEXT;
3611 else if (*mode != 'b') {
3612 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3613 return NULL;
3614 } else
3615 tm = O_BINARY;
3616
3617 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
3618
3619 return f;
3620}
3621
3622/*
3623 * Variation on os2emx.popen2
3624 *
3625 * The result of this function is 3 pipes - the process's stdin,
3626 * stdout and stderr
3627 */
3628
3629static PyObject *
3630os2emx_popen3(PyObject *self, PyObject *args)
3631{
3632 PyObject *f;
3633 int tm = 0;
3634
3635 char *cmdstring;
3636 char *mode = "t";
3637 int bufsize = -1;
3638 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
3639 return NULL;
3640
3641 if (*mode == 't')
3642 tm = O_TEXT;
3643 else if (*mode != 'b') {
3644 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3645 return NULL;
3646 } else
3647 tm = O_BINARY;
3648
3649 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
3650
3651 return f;
3652}
3653
3654/*
3655 * Variation on os2emx.popen2
3656 *
Tim Peters11b23062003-04-23 02:39:17 +00003657 * The result of this function is 2 pipes - the processes stdin,
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003658 * and stdout+stderr combined as a single pipe.
3659 */
3660
3661static PyObject *
3662os2emx_popen4(PyObject *self, PyObject *args)
3663{
3664 PyObject *f;
3665 int tm = 0;
3666
3667 char *cmdstring;
3668 char *mode = "t";
3669 int bufsize = -1;
3670 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
3671 return NULL;
3672
3673 if (*mode == 't')
3674 tm = O_TEXT;
3675 else if (*mode != 'b') {
3676 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3677 return NULL;
3678 } else
3679 tm = O_BINARY;
3680
3681 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
3682
3683 return f;
3684}
3685
3686/* a couple of structures for convenient handling of multiple
3687 * file handles and pipes
3688 */
3689struct file_ref
3690{
3691 int handle;
3692 int flags;
3693};
3694
3695struct pipe_ref
3696{
3697 int rd;
3698 int wr;
3699};
3700
3701/* The following code is derived from the win32 code */
3702
3703static PyObject *
3704_PyPopen(char *cmdstring, int mode, int n, int bufsize)
3705{
3706 struct file_ref stdio[3];
3707 struct pipe_ref p_fd[3];
3708 FILE *p_s[3];
3709 int file_count, i, pipe_err, pipe_pid;
3710 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
3711 PyObject *f, *p_f[3];
3712
3713 /* file modes for subsequent fdopen's on pipe handles */
3714 if (mode == O_TEXT)
3715 {
3716 rd_mode = "rt";
3717 wr_mode = "wt";
3718 }
3719 else
3720 {
3721 rd_mode = "rb";
3722 wr_mode = "wb";
3723 }
3724
3725 /* prepare shell references */
3726 if ((shell = getenv("EMXSHELL")) == NULL)
3727 if ((shell = getenv("COMSPEC")) == NULL)
3728 {
3729 errno = ENOENT;
3730 return posix_error();
3731 }
3732
3733 sh_name = _getname(shell);
3734 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
3735 opt = "/c";
3736 else
3737 opt = "-c";
3738
3739 /* save current stdio fds + their flags, and set not inheritable */
3740 i = pipe_err = 0;
3741 while (pipe_err >= 0 && i < 3)
3742 {
3743 pipe_err = stdio[i].handle = dup(i);
3744 stdio[i].flags = fcntl(i, F_GETFD, 0);
3745 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
3746 i++;
3747 }
3748 if (pipe_err < 0)
3749 {
3750 /* didn't get them all saved - clean up and bail out */
3751 int saved_err = errno;
3752 while (i-- > 0)
3753 {
3754 close(stdio[i].handle);
3755 }
3756 errno = saved_err;
3757 return posix_error();
3758 }
3759
3760 /* create pipe ends */
3761 file_count = 2;
3762 if (n == POPEN_3)
3763 file_count = 3;
3764 i = pipe_err = 0;
3765 while ((pipe_err == 0) && (i < file_count))
3766 pipe_err = pipe((int *)&p_fd[i++]);
3767 if (pipe_err < 0)
3768 {
3769 /* didn't get them all made - clean up and bail out */
3770 while (i-- > 0)
3771 {
3772 close(p_fd[i].wr);
3773 close(p_fd[i].rd);
3774 }
3775 errno = EPIPE;
3776 return posix_error();
3777 }
3778
3779 /* change the actual standard IO streams over temporarily,
3780 * making the retained pipe ends non-inheritable
3781 */
3782 pipe_err = 0;
3783
3784 /* - stdin */
3785 if (dup2(p_fd[0].rd, 0) == 0)
3786 {
3787 close(p_fd[0].rd);
3788 i = fcntl(p_fd[0].wr, F_GETFD, 0);
3789 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
3790 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
3791 {
3792 close(p_fd[0].wr);
3793 pipe_err = -1;
3794 }
3795 }
3796 else
3797 {
3798 pipe_err = -1;
3799 }
3800
3801 /* - stdout */
3802 if (pipe_err == 0)
3803 {
3804 if (dup2(p_fd[1].wr, 1) == 1)
3805 {
3806 close(p_fd[1].wr);
3807 i = fcntl(p_fd[1].rd, F_GETFD, 0);
3808 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
3809 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
3810 {
3811 close(p_fd[1].rd);
3812 pipe_err = -1;
3813 }
3814 }
3815 else
3816 {
3817 pipe_err = -1;
3818 }
3819 }
3820
3821 /* - stderr, as required */
3822 if (pipe_err == 0)
3823 switch (n)
3824 {
3825 case POPEN_3:
3826 {
3827 if (dup2(p_fd[2].wr, 2) == 2)
3828 {
3829 close(p_fd[2].wr);
3830 i = fcntl(p_fd[2].rd, F_GETFD, 0);
3831 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
3832 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
3833 {
3834 close(p_fd[2].rd);
3835 pipe_err = -1;
3836 }
3837 }
3838 else
3839 {
3840 pipe_err = -1;
3841 }
3842 break;
3843 }
3844
3845 case POPEN_4:
3846 {
3847 if (dup2(1, 2) != 2)
3848 {
3849 pipe_err = -1;
3850 }
3851 break;
3852 }
3853 }
3854
3855 /* spawn the child process */
3856 if (pipe_err == 0)
3857 {
3858 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
3859 if (pipe_pid == -1)
3860 {
3861 pipe_err = -1;
3862 }
3863 else
3864 {
3865 /* save the PID into the FILE structure
3866 * NOTE: this implementation doesn't actually
3867 * take advantage of this, but do it for
3868 * completeness - AIM Apr01
3869 */
3870 for (i = 0; i < file_count; i++)
3871 p_s[i]->_pid = pipe_pid;
3872 }
3873 }
3874
3875 /* reset standard IO to normal */
3876 for (i = 0; i < 3; i++)
3877 {
3878 dup2(stdio[i].handle, i);
3879 fcntl(i, F_SETFD, stdio[i].flags);
3880 close(stdio[i].handle);
3881 }
3882
3883 /* if any remnant problems, clean up and bail out */
3884 if (pipe_err < 0)
3885 {
3886 for (i = 0; i < 3; i++)
3887 {
3888 close(p_fd[i].rd);
3889 close(p_fd[i].wr);
3890 }
3891 errno = EPIPE;
3892 return posix_error_with_filename(cmdstring);
3893 }
3894
3895 /* build tuple of file objects to return */
3896 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
3897 PyFile_SetBufSize(p_f[0], bufsize);
3898 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
3899 PyFile_SetBufSize(p_f[1], bufsize);
3900 if (n == POPEN_3)
3901 {
3902 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
3903 PyFile_SetBufSize(p_f[0], bufsize);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00003904 f = PyTuple_Pack(3, p_f[0], p_f[1], p_f[2]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003905 }
3906 else
Raymond Hettinger8ae46892003-10-12 19:09:37 +00003907 f = PyTuple_Pack(2, p_f[0], p_f[1]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003908
3909 /*
3910 * Insert the files we've created into the process dictionary
3911 * all referencing the list with the process handle and the
3912 * initial number of files (see description below in _PyPclose).
3913 * Since if _PyPclose later tried to wait on a process when all
3914 * handles weren't closed, it could create a deadlock with the
3915 * child, we spend some energy here to try to ensure that we
3916 * either insert all file handles into the dictionary or none
3917 * at all. It's a little clumsy with the various popen modes
3918 * and variable number of files involved.
3919 */
3920 if (!_PyPopenProcs)
3921 {
3922 _PyPopenProcs = PyDict_New();
3923 }
3924
3925 if (_PyPopenProcs)
3926 {
3927 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
3928 int ins_rc[3];
3929
3930 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
3931 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
3932
3933 procObj = PyList_New(2);
3934 pidObj = PyInt_FromLong((long) pipe_pid);
3935 intObj = PyInt_FromLong((long) file_count);
3936
3937 if (procObj && pidObj && intObj)
3938 {
3939 PyList_SetItem(procObj, 0, pidObj);
3940 PyList_SetItem(procObj, 1, intObj);
3941
3942 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
3943 if (fileObj[0])
3944 {
3945 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
3946 fileObj[0],
3947 procObj);
3948 }
3949 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
3950 if (fileObj[1])
3951 {
3952 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
3953 fileObj[1],
3954 procObj);
3955 }
3956 if (file_count >= 3)
3957 {
3958 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
3959 if (fileObj[2])
3960 {
3961 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
3962 fileObj[2],
3963 procObj);
3964 }
3965 }
3966
3967 if (ins_rc[0] < 0 || !fileObj[0] ||
3968 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
3969 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
3970 {
3971 /* Something failed - remove any dictionary
3972 * entries that did make it.
3973 */
3974 if (!ins_rc[0] && fileObj[0])
3975 {
3976 PyDict_DelItem(_PyPopenProcs,
3977 fileObj[0]);
3978 }
3979 if (!ins_rc[1] && fileObj[1])
3980 {
3981 PyDict_DelItem(_PyPopenProcs,
3982 fileObj[1]);
3983 }
3984 if (!ins_rc[2] && fileObj[2])
3985 {
3986 PyDict_DelItem(_PyPopenProcs,
3987 fileObj[2]);
3988 }
3989 }
3990 }
Tim Peters11b23062003-04-23 02:39:17 +00003991
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003992 /*
3993 * Clean up our localized references for the dictionary keys
3994 * and value since PyDict_SetItem will Py_INCREF any copies
3995 * that got placed in the dictionary.
3996 */
3997 Py_XDECREF(procObj);
3998 Py_XDECREF(fileObj[0]);
3999 Py_XDECREF(fileObj[1]);
4000 Py_XDECREF(fileObj[2]);
4001 }
4002
4003 /* Child is launched. */
4004 return f;
4005}
4006
4007/*
4008 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4009 * exit code for the child process and return as a result of the close.
4010 *
4011 * This function uses the _PyPopenProcs dictionary in order to map the
4012 * input file pointer to information about the process that was
4013 * originally created by the popen* call that created the file pointer.
4014 * The dictionary uses the file pointer as a key (with one entry
4015 * inserted for each file returned by the original popen* call) and a
4016 * single list object as the value for all files from a single call.
4017 * The list object contains the Win32 process handle at [0], and a file
4018 * count at [1], which is initialized to the total number of file
4019 * handles using that list.
4020 *
4021 * This function closes whichever handle it is passed, and decrements
4022 * the file count in the dictionary for the process handle pointed to
4023 * by this file. On the last close (when the file count reaches zero),
4024 * this function will wait for the child process and then return its
4025 * exit code as the result of the close() operation. This permits the
4026 * files to be closed in any order - it is always the close() of the
4027 * final handle that will return the exit code.
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004028 *
4029 * NOTE: This function is currently called with the GIL released.
4030 * hence we use the GILState API to manage our state.
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004031 */
4032
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004033static int _PyPclose(FILE *file)
4034{
4035 int result;
4036 int exit_code;
4037 int pipe_pid;
4038 PyObject *procObj, *pidObj, *intObj, *fileObj;
4039 int file_count;
4040#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004041 PyGILState_STATE state;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004042#endif
4043
4044 /* Close the file handle first, to ensure it can't block the
4045 * child from exiting if it's the last handle.
4046 */
4047 result = fclose(file);
4048
4049#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004050 state = PyGILState_Ensure();
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004051#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004052 if (_PyPopenProcs)
4053 {
4054 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4055 (procObj = PyDict_GetItem(_PyPopenProcs,
4056 fileObj)) != NULL &&
4057 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
4058 (intObj = PyList_GetItem(procObj,1)) != NULL)
4059 {
4060 pipe_pid = (int) PyInt_AsLong(pidObj);
4061 file_count = (int) PyInt_AsLong(intObj);
4062
4063 if (file_count > 1)
4064 {
4065 /* Still other files referencing process */
4066 file_count--;
4067 PyList_SetItem(procObj,1,
4068 PyInt_FromLong((long) file_count));
4069 }
4070 else
4071 {
4072 /* Last file for this process */
4073 if (result != EOF &&
4074 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
4075 {
4076 /* extract exit status */
4077 if (WIFEXITED(exit_code))
4078 {
4079 result = WEXITSTATUS(exit_code);
4080 }
4081 else
4082 {
4083 errno = EPIPE;
4084 result = -1;
4085 }
4086 }
4087 else
4088 {
4089 /* Indicate failure - this will cause the file object
4090 * to raise an I/O error and translate the last
4091 * error code from errno. We do have a problem with
4092 * last errors that overlap the normal errno table,
4093 * but that's a consistent problem with the file object.
4094 */
4095 result = -1;
4096 }
4097 }
4098
4099 /* Remove this file pointer from dictionary */
4100 PyDict_DelItem(_PyPopenProcs, fileObj);
4101
4102 if (PyDict_Size(_PyPopenProcs) == 0)
4103 {
4104 Py_DECREF(_PyPopenProcs);
4105 _PyPopenProcs = NULL;
4106 }
4107
4108 } /* if object retrieval ok */
4109
4110 Py_XDECREF(fileObj);
4111 } /* if _PyPopenProcs */
4112
4113#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004114 PyGILState_Release(state);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004115#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004116 return result;
4117}
4118
4119#endif /* PYCC_??? */
4120
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004121#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004122
4123/*
4124 * Portable 'popen' replacement for Win32.
4125 *
4126 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
4127 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00004128 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004129 */
4130
4131#include <malloc.h>
4132#include <io.h>
4133#include <fcntl.h>
4134
4135/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
4136#define POPEN_1 1
4137#define POPEN_2 2
4138#define POPEN_3 3
4139#define POPEN_4 4
4140
4141static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004142static int _PyPclose(FILE *file);
4143
4144/*
4145 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00004146 * for use when retrieving the process exit code. See _PyPclose() below
4147 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004148 */
4149static PyObject *_PyPopenProcs = NULL;
4150
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004151
4152/* popen that works from a GUI.
4153 *
4154 * The result of this function is a pipe (file) connected to the
4155 * processes stdin or stdout, depending on the requested mode.
4156 */
4157
4158static PyObject *
4159posix_popen(PyObject *self, PyObject *args)
4160{
Raymond Hettingerb5cb6652003-09-01 22:25:41 +00004161 PyObject *f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004162 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004163
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004164 char *cmdstring;
4165 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004166 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004167 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004168 return NULL;
4169
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004170 if (*mode == 'r')
4171 tm = _O_RDONLY;
4172 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00004173 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004174 return NULL;
4175 } else
4176 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00004177
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004178 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004179 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004180 return NULL;
4181 }
4182
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004183 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004184 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004185 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004186 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004187 else
4188 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
4189
4190 return f;
4191}
4192
4193/* Variation on win32pipe.popen
4194 *
4195 * The result of this function is a pipe (file) connected to the
4196 * process's stdin, and a pipe connected to the process's stdout.
4197 */
4198
4199static PyObject *
4200win32_popen2(PyObject *self, PyObject *args)
4201{
4202 PyObject *f;
4203 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00004204
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004205 char *cmdstring;
4206 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004207 int bufsize = -1;
4208 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004209 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004210
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004211 if (*mode == 't')
4212 tm = _O_TEXT;
4213 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004214 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004215 return NULL;
4216 } else
4217 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004218
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004219 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004220 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004221 return NULL;
4222 }
4223
4224 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00004225
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004226 return f;
4227}
4228
4229/*
4230 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004231 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004232 * The result of this function is 3 pipes - the process's stdin,
4233 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004234 */
4235
4236static PyObject *
4237win32_popen3(PyObject *self, PyObject *args)
4238{
4239 PyObject *f;
4240 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004241
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004242 char *cmdstring;
4243 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004244 int bufsize = -1;
4245 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004246 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004247
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004248 if (*mode == 't')
4249 tm = _O_TEXT;
4250 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004251 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004252 return NULL;
4253 } else
4254 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004255
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004256 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004257 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004258 return NULL;
4259 }
4260
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004261 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00004262
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004263 return f;
4264}
4265
4266/*
4267 * Variation on win32pipe.popen
4268 *
Tim Peters5aa91602002-01-30 05:46:57 +00004269 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004270 * and stdout+stderr combined as a single pipe.
4271 */
4272
4273static PyObject *
4274win32_popen4(PyObject *self, PyObject *args)
4275{
4276 PyObject *f;
4277 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004278
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004279 char *cmdstring;
4280 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004281 int bufsize = -1;
4282 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004283 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004284
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004285 if (*mode == 't')
4286 tm = _O_TEXT;
4287 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004288 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004289 return NULL;
4290 } else
4291 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004292
4293 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004294 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004295 return NULL;
4296 }
4297
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004298 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004299
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004300 return f;
4301}
4302
Mark Hammond08501372001-01-31 07:30:29 +00004303static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00004304_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004305 HANDLE hStdin,
4306 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00004307 HANDLE hStderr,
4308 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004309{
4310 PROCESS_INFORMATION piProcInfo;
4311 STARTUPINFO siStartInfo;
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004312 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004313 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00004314 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004315 int i;
Martin v. Löwis18e16552006-02-15 17:27:45 +00004316 Py_ssize_t x;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004317
4318 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00004319 char *comshell;
4320
Tim Peters92e4dd82002-10-05 01:47:34 +00004321 s1 = (char *)alloca(i);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004322 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
Martin v. Löwis18e16552006-02-15 17:27:45 +00004323 /* x < i, so x fits into an integer */
4324 return (int)x;
Tim Peters402d5982001-08-27 06:37:48 +00004325
4326 /* Explicitly check if we are using COMMAND.COM. If we are
4327 * then use the w9xpopen hack.
4328 */
4329 comshell = s1 + x;
4330 while (comshell >= s1 && *comshell != '\\')
4331 --comshell;
4332 ++comshell;
4333
4334 if (GetVersion() < 0x80000000 &&
4335 _stricmp(comshell, "command.com") != 0) {
4336 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004337 x = i + strlen(s3) + strlen(cmdstring) + 1;
Tim Peters92e4dd82002-10-05 01:47:34 +00004338 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004339 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00004340 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004341 }
4342 else {
4343 /*
Tim Peters402d5982001-08-27 06:37:48 +00004344 * Oh gag, we're on Win9x or using COMMAND.COM. Use
4345 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004346 */
Mark Hammond08501372001-01-31 07:30:29 +00004347 char modulepath[_MAX_PATH];
4348 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004349 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
4350 for (i = x = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004351 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004352 x = i+1;
4353 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00004354 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00004355 strncat(modulepath,
4356 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00004357 (sizeof(modulepath)/sizeof(modulepath[0]))
4358 -strlen(modulepath));
4359 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00004360 /* Eeek - file-not-found - possibly an embedding
4361 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00004362 */
Tim Peters5aa91602002-01-30 05:46:57 +00004363 strncpy(modulepath,
4364 Py_GetExecPrefix(),
Mark Hammond08501372001-01-31 07:30:29 +00004365 sizeof(modulepath)/sizeof(modulepath[0]));
4366 if (modulepath[strlen(modulepath)-1] != '\\')
4367 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00004368 strncat(modulepath,
4369 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00004370 (sizeof(modulepath)/sizeof(modulepath[0]))
4371 -strlen(modulepath));
4372 /* No where else to look - raise an easily identifiable
4373 error, rather than leaving Windows to report
4374 "file not found" - as the user is probably blissfully
4375 unaware this shim EXE is used, and it will confuse them.
4376 (well, it confused me for a while ;-)
4377 */
4378 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00004379 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00004380 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00004381 "for popen to work with your shell "
4382 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00004383 szConsoleSpawn);
4384 return FALSE;
4385 }
4386 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004387 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00004388 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004389 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00004390
Tim Peters92e4dd82002-10-05 01:47:34 +00004391 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004392 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004393 /* To maintain correct argument passing semantics,
4394 we pass the command-line as it stands, and allow
4395 quoting to be applied. w9xpopen.exe will then
4396 use its argv vector, and re-quote the necessary
4397 args for the ultimate child process.
4398 */
Tim Peters75cdad52001-11-28 22:07:30 +00004399 PyOS_snprintf(
4400 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004401 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004402 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004403 s1,
4404 s3,
4405 cmdstring);
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004406 /* Not passing CREATE_NEW_CONSOLE has been known to
Tim Peters11b23062003-04-23 02:39:17 +00004407 cause random failures on win9x. Specifically a
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004408 dialog:
4409 "Your program accessed mem currently in use at xxx"
4410 and a hopeful warning about the stability of your
4411 system.
4412 Cost is Ctrl+C wont kill children, but anyone
4413 who cares can have a go!
4414 */
4415 dwProcessFlags |= CREATE_NEW_CONSOLE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004416 }
4417 }
4418
4419 /* Could be an else here to try cmd.exe / command.com in the path
4420 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00004421 else {
Tim Peters402d5982001-08-27 06:37:48 +00004422 PyErr_SetString(PyExc_RuntimeError,
4423 "Cannot locate a COMSPEC environment variable to "
4424 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00004425 return FALSE;
4426 }
Tim Peters5aa91602002-01-30 05:46:57 +00004427
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004428 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
4429 siStartInfo.cb = sizeof(STARTUPINFO);
4430 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
4431 siStartInfo.hStdInput = hStdin;
4432 siStartInfo.hStdOutput = hStdout;
4433 siStartInfo.hStdError = hStderr;
4434 siStartInfo.wShowWindow = SW_HIDE;
4435
4436 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004437 s2,
4438 NULL,
4439 NULL,
4440 TRUE,
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004441 dwProcessFlags,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004442 NULL,
4443 NULL,
4444 &siStartInfo,
4445 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004446 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004447 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004448
Mark Hammondb37a3732000-08-14 04:47:33 +00004449 /* Return process handle */
4450 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004451 return TRUE;
4452 }
Tim Peters402d5982001-08-27 06:37:48 +00004453 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004454 return FALSE;
4455}
4456
4457/* The following code is based off of KB: Q190351 */
4458
4459static PyObject *
4460_PyPopen(char *cmdstring, int mode, int n)
4461{
4462 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
4463 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00004464 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00004465
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004466 SECURITY_ATTRIBUTES saAttr;
4467 BOOL fSuccess;
4468 int fd1, fd2, fd3;
4469 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00004470 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004471 PyObject *f;
4472
4473 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
4474 saAttr.bInheritHandle = TRUE;
4475 saAttr.lpSecurityDescriptor = NULL;
4476
4477 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
4478 return win32_error("CreatePipe", NULL);
4479
4480 /* Create new output read handle and the input write handle. Set
4481 * the inheritance properties to FALSE. Otherwise, the child inherits
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00004482 * these handles; resulting in non-closeable handles to the pipes
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004483 * being created. */
4484 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004485 GetCurrentProcess(), &hChildStdinWrDup, 0,
4486 FALSE,
4487 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004488 if (!fSuccess)
4489 return win32_error("DuplicateHandle", NULL);
4490
4491 /* Close the inheritable version of ChildStdin
4492 that we're using. */
4493 CloseHandle(hChildStdinWr);
4494
4495 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
4496 return win32_error("CreatePipe", NULL);
4497
4498 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004499 GetCurrentProcess(), &hChildStdoutRdDup, 0,
4500 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004501 if (!fSuccess)
4502 return win32_error("DuplicateHandle", NULL);
4503
4504 /* Close the inheritable version of ChildStdout
4505 that we're using. */
4506 CloseHandle(hChildStdoutRd);
4507
4508 if (n != POPEN_4) {
4509 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
4510 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004511 fSuccess = DuplicateHandle(GetCurrentProcess(),
4512 hChildStderrRd,
4513 GetCurrentProcess(),
4514 &hChildStderrRdDup, 0,
4515 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004516 if (!fSuccess)
4517 return win32_error("DuplicateHandle", NULL);
4518 /* Close the inheritable version of ChildStdErr that we're using. */
4519 CloseHandle(hChildStderrRd);
4520 }
Tim Peters5aa91602002-01-30 05:46:57 +00004521
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004522 switch (n) {
4523 case POPEN_1:
4524 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
4525 case _O_WRONLY | _O_TEXT:
4526 /* Case for writing to child Stdin in text mode. */
Martin v. Löwis18e16552006-02-15 17:27:45 +00004527 fd1 = _open_osfhandle((intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004528 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004529 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004530 PyFile_SetBufSize(f, 0);
4531 /* We don't care about these pipes anymore, so close them. */
4532 CloseHandle(hChildStdoutRdDup);
4533 CloseHandle(hChildStderrRdDup);
4534 break;
4535
4536 case _O_RDONLY | _O_TEXT:
4537 /* Case for reading from child Stdout in text mode. */
Martin v. Löwis18e16552006-02-15 17:27:45 +00004538 fd1 = _open_osfhandle((intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004539 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004540 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004541 PyFile_SetBufSize(f, 0);
4542 /* We don't care about these pipes anymore, so close them. */
4543 CloseHandle(hChildStdinWrDup);
4544 CloseHandle(hChildStderrRdDup);
4545 break;
4546
4547 case _O_RDONLY | _O_BINARY:
4548 /* Case for readinig from child Stdout in binary mode. */
Martin v. Löwis18e16552006-02-15 17:27:45 +00004549 fd1 = _open_osfhandle((intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004550 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004551 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004552 PyFile_SetBufSize(f, 0);
4553 /* We don't care about these pipes anymore, so close them. */
4554 CloseHandle(hChildStdinWrDup);
4555 CloseHandle(hChildStderrRdDup);
4556 break;
4557
4558 case _O_WRONLY | _O_BINARY:
4559 /* Case for writing to child Stdin in binary mode. */
Martin v. Löwis18e16552006-02-15 17:27:45 +00004560 fd1 = _open_osfhandle((intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004561 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004562 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004563 PyFile_SetBufSize(f, 0);
4564 /* We don't care about these pipes anymore, so close them. */
4565 CloseHandle(hChildStdoutRdDup);
4566 CloseHandle(hChildStderrRdDup);
4567 break;
4568 }
Mark Hammondb37a3732000-08-14 04:47:33 +00004569 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004570 break;
Tim Peters5aa91602002-01-30 05:46:57 +00004571
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004572 case POPEN_2:
4573 case POPEN_4:
4574 {
4575 char *m1, *m2;
4576 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00004577
Tim Peters7dca21e2002-08-19 00:42:29 +00004578 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004579 m1 = "r";
4580 m2 = "w";
4581 } else {
4582 m1 = "rb";
4583 m2 = "wb";
4584 }
4585
Martin v. Löwis18e16552006-02-15 17:27:45 +00004586 fd1 = _open_osfhandle((intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004587 f1 = _fdopen(fd1, m2);
Martin v. Löwis18e16552006-02-15 17:27:45 +00004588 fd2 = _open_osfhandle((intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004589 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004590 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004591 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00004592 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004593 PyFile_SetBufSize(p2, 0);
4594
4595 if (n != 4)
4596 CloseHandle(hChildStderrRdDup);
4597
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004598 f = PyTuple_Pack(2,p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00004599 Py_XDECREF(p1);
4600 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00004601 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004602 break;
4603 }
Tim Peters5aa91602002-01-30 05:46:57 +00004604
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004605 case POPEN_3:
4606 {
4607 char *m1, *m2;
4608 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00004609
Tim Peters7dca21e2002-08-19 00:42:29 +00004610 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004611 m1 = "r";
4612 m2 = "w";
4613 } else {
4614 m1 = "rb";
4615 m2 = "wb";
4616 }
4617
Martin v. Löwis18e16552006-02-15 17:27:45 +00004618 fd1 = _open_osfhandle((intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004619 f1 = _fdopen(fd1, m2);
Martin v. Löwis18e16552006-02-15 17:27:45 +00004620 fd2 = _open_osfhandle((intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004621 f2 = _fdopen(fd2, m1);
Martin v. Löwis18e16552006-02-15 17:27:45 +00004622 fd3 = _open_osfhandle((intptr_t)hChildStderrRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004623 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004624 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00004625 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
4626 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004627 PyFile_SetBufSize(p1, 0);
4628 PyFile_SetBufSize(p2, 0);
4629 PyFile_SetBufSize(p3, 0);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004630 f = PyTuple_Pack(3,p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00004631 Py_XDECREF(p1);
4632 Py_XDECREF(p2);
4633 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00004634 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004635 break;
4636 }
4637 }
4638
4639 if (n == POPEN_4) {
4640 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004641 hChildStdinRd,
4642 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004643 hChildStdoutWr,
4644 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004645 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004646 }
4647 else {
4648 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004649 hChildStdinRd,
4650 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004651 hChildStderrWr,
4652 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004653 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004654 }
4655
Mark Hammondb37a3732000-08-14 04:47:33 +00004656 /*
4657 * Insert the files we've created into the process dictionary
4658 * all referencing the list with the process handle and the
4659 * initial number of files (see description below in _PyPclose).
4660 * Since if _PyPclose later tried to wait on a process when all
4661 * handles weren't closed, it could create a deadlock with the
4662 * child, we spend some energy here to try to ensure that we
4663 * either insert all file handles into the dictionary or none
4664 * at all. It's a little clumsy with the various popen modes
4665 * and variable number of files involved.
4666 */
4667 if (!_PyPopenProcs) {
4668 _PyPopenProcs = PyDict_New();
4669 }
4670
4671 if (_PyPopenProcs) {
4672 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
4673 int ins_rc[3];
4674
4675 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4676 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4677
4678 procObj = PyList_New(2);
4679 hProcessObj = PyLong_FromVoidPtr(hProcess);
4680 intObj = PyInt_FromLong(file_count);
4681
4682 if (procObj && hProcessObj && intObj) {
4683 PyList_SetItem(procObj,0,hProcessObj);
4684 PyList_SetItem(procObj,1,intObj);
4685
4686 fileObj[0] = PyLong_FromVoidPtr(f1);
4687 if (fileObj[0]) {
4688 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4689 fileObj[0],
4690 procObj);
4691 }
4692 if (file_count >= 2) {
4693 fileObj[1] = PyLong_FromVoidPtr(f2);
4694 if (fileObj[1]) {
4695 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4696 fileObj[1],
4697 procObj);
4698 }
4699 }
4700 if (file_count >= 3) {
4701 fileObj[2] = PyLong_FromVoidPtr(f3);
4702 if (fileObj[2]) {
4703 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4704 fileObj[2],
4705 procObj);
4706 }
4707 }
4708
4709 if (ins_rc[0] < 0 || !fileObj[0] ||
4710 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4711 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
4712 /* Something failed - remove any dictionary
4713 * entries that did make it.
4714 */
4715 if (!ins_rc[0] && fileObj[0]) {
4716 PyDict_DelItem(_PyPopenProcs,
4717 fileObj[0]);
4718 }
4719 if (!ins_rc[1] && fileObj[1]) {
4720 PyDict_DelItem(_PyPopenProcs,
4721 fileObj[1]);
4722 }
4723 if (!ins_rc[2] && fileObj[2]) {
4724 PyDict_DelItem(_PyPopenProcs,
4725 fileObj[2]);
4726 }
4727 }
4728 }
Tim Peters5aa91602002-01-30 05:46:57 +00004729
Mark Hammondb37a3732000-08-14 04:47:33 +00004730 /*
4731 * Clean up our localized references for the dictionary keys
4732 * and value since PyDict_SetItem will Py_INCREF any copies
4733 * that got placed in the dictionary.
4734 */
4735 Py_XDECREF(procObj);
4736 Py_XDECREF(fileObj[0]);
4737 Py_XDECREF(fileObj[1]);
4738 Py_XDECREF(fileObj[2]);
4739 }
4740
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004741 /* Child is launched. Close the parents copy of those pipe
4742 * handles that only the child should have open. You need to
4743 * make sure that no handles to the write end of the output pipe
4744 * are maintained in this process or else the pipe will not close
4745 * when the child process exits and the ReadFile will hang. */
4746
4747 if (!CloseHandle(hChildStdinRd))
4748 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004749
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004750 if (!CloseHandle(hChildStdoutWr))
4751 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004752
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004753 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
4754 return win32_error("CloseHandle", NULL);
4755
4756 return f;
4757}
Fredrik Lundh56055a42000-07-23 19:47:12 +00004758
4759/*
4760 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4761 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00004762 *
4763 * This function uses the _PyPopenProcs dictionary in order to map the
4764 * input file pointer to information about the process that was
4765 * originally created by the popen* call that created the file pointer.
4766 * The dictionary uses the file pointer as a key (with one entry
4767 * inserted for each file returned by the original popen* call) and a
4768 * single list object as the value for all files from a single call.
4769 * The list object contains the Win32 process handle at [0], and a file
4770 * count at [1], which is initialized to the total number of file
4771 * handles using that list.
4772 *
4773 * This function closes whichever handle it is passed, and decrements
4774 * the file count in the dictionary for the process handle pointed to
4775 * by this file. On the last close (when the file count reaches zero),
4776 * this function will wait for the child process and then return its
4777 * exit code as the result of the close() operation. This permits the
4778 * files to be closed in any order - it is always the close() of the
4779 * final handle that will return the exit code.
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004780 *
4781 * NOTE: This function is currently called with the GIL released.
4782 * hence we use the GILState API to manage our state.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004783 */
Tim Peters736aa322000-09-01 06:51:24 +00004784
Fredrik Lundh56055a42000-07-23 19:47:12 +00004785static int _PyPclose(FILE *file)
4786{
Fredrik Lundh20318932000-07-26 17:29:12 +00004787 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004788 DWORD exit_code;
4789 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00004790 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
4791 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00004792#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004793 PyGILState_STATE state;
Tim Peters736aa322000-09-01 06:51:24 +00004794#endif
4795
Fredrik Lundh20318932000-07-26 17:29:12 +00004796 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00004797 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00004798 */
4799 result = fclose(file);
Tim Peters736aa322000-09-01 06:51:24 +00004800#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004801 state = PyGILState_Ensure();
Tim Peters736aa322000-09-01 06:51:24 +00004802#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00004803 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00004804 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4805 (procObj = PyDict_GetItem(_PyPopenProcs,
4806 fileObj)) != NULL &&
4807 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
4808 (intObj = PyList_GetItem(procObj,1)) != NULL) {
4809
4810 hProcess = PyLong_AsVoidPtr(hProcessObj);
4811 file_count = PyInt_AsLong(intObj);
4812
4813 if (file_count > 1) {
4814 /* Still other files referencing process */
4815 file_count--;
4816 PyList_SetItem(procObj,1,
4817 PyInt_FromLong(file_count));
4818 } else {
4819 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00004820 if (result != EOF &&
4821 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
4822 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00004823 /* Possible truncation here in 16-bit environments, but
4824 * real exit codes are just the lower byte in any event.
4825 */
4826 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004827 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00004828 /* Indicate failure - this will cause the file object
4829 * to raise an I/O error and translate the last Win32
4830 * error code from errno. We do have a problem with
4831 * last errors that overlap the normal errno table,
4832 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004833 */
Fredrik Lundh20318932000-07-26 17:29:12 +00004834 if (result != EOF) {
4835 /* If the error wasn't from the fclose(), then
4836 * set errno for the file object error handling.
4837 */
4838 errno = GetLastError();
4839 }
4840 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004841 }
4842
4843 /* Free up the native handle at this point */
4844 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00004845 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00004846
Mark Hammondb37a3732000-08-14 04:47:33 +00004847 /* Remove this file pointer from dictionary */
4848 PyDict_DelItem(_PyPopenProcs, fileObj);
4849
4850 if (PyDict_Size(_PyPopenProcs) == 0) {
4851 Py_DECREF(_PyPopenProcs);
4852 _PyPopenProcs = NULL;
4853 }
4854
4855 } /* if object retrieval ok */
4856
4857 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004858 } /* if _PyPopenProcs */
4859
Tim Peters736aa322000-09-01 06:51:24 +00004860#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004861 PyGILState_Release(state);
Tim Peters736aa322000-09-01 06:51:24 +00004862#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00004863 return result;
4864}
Tim Peters9acdd3a2000-09-01 19:26:36 +00004865
4866#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00004867static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004868posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00004869{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004870 char *name;
4871 char *mode = "r";
4872 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00004873 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00004874 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004875 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00004876 return NULL;
Martin v. Löwis9ad853b2003-10-31 10:01:53 +00004877 /* Strip mode of binary or text modifiers */
4878 if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
4879 mode = "r";
4880 else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
4881 mode = "w";
Barry Warsaw53699e91996-12-10 23:23:01 +00004882 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004883 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004884 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00004885 if (fp == NULL)
4886 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004887 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004888 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00004889 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004890 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00004891}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004892
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004893#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004894#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00004895
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004896
Guido van Rossumb6775db1994-08-01 11:34:53 +00004897#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004898PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004899"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004900Set the current process's user id.");
4901
Barry Warsaw53699e91996-12-10 23:23:01 +00004902static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004903posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004904{
4905 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004906 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004907 return NULL;
4908 if (setuid(uid) < 0)
4909 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004910 Py_INCREF(Py_None);
4911 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004912}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004913#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004914
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004915
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004916#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004917PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004918"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004919Set the current process's effective user id.");
4920
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004921static PyObject *
4922posix_seteuid (PyObject *self, PyObject *args)
4923{
4924 int euid;
4925 if (!PyArg_ParseTuple(args, "i", &euid)) {
4926 return NULL;
4927 } else if (seteuid(euid) < 0) {
4928 return posix_error();
4929 } else {
4930 Py_INCREF(Py_None);
4931 return Py_None;
4932 }
4933}
4934#endif /* HAVE_SETEUID */
4935
4936#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004937PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004938"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004939Set the current process's effective group id.");
4940
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004941static PyObject *
4942posix_setegid (PyObject *self, PyObject *args)
4943{
4944 int egid;
4945 if (!PyArg_ParseTuple(args, "i", &egid)) {
4946 return NULL;
4947 } else if (setegid(egid) < 0) {
4948 return posix_error();
4949 } else {
4950 Py_INCREF(Py_None);
4951 return Py_None;
4952 }
4953}
4954#endif /* HAVE_SETEGID */
4955
4956#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004957PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004958"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004959Set the current process's real and effective user ids.");
4960
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004961static PyObject *
4962posix_setreuid (PyObject *self, PyObject *args)
4963{
4964 int ruid, euid;
4965 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
4966 return NULL;
4967 } else if (setreuid(ruid, euid) < 0) {
4968 return posix_error();
4969 } else {
4970 Py_INCREF(Py_None);
4971 return Py_None;
4972 }
4973}
4974#endif /* HAVE_SETREUID */
4975
4976#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004977PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004978"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004979Set the current process's real and effective group ids.");
4980
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004981static PyObject *
4982posix_setregid (PyObject *self, PyObject *args)
4983{
4984 int rgid, egid;
4985 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
4986 return NULL;
4987 } else if (setregid(rgid, egid) < 0) {
4988 return posix_error();
4989 } else {
4990 Py_INCREF(Py_None);
4991 return Py_None;
4992 }
4993}
4994#endif /* HAVE_SETREGID */
4995
Guido van Rossumb6775db1994-08-01 11:34:53 +00004996#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004997PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004998"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004999Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005000
Barry Warsaw53699e91996-12-10 23:23:01 +00005001static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005002posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005003{
5004 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005005 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005006 return NULL;
5007 if (setgid(gid) < 0)
5008 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005009 Py_INCREF(Py_None);
5010 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005011}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005012#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005013
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005014#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005015PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005016"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005017Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005018
5019static PyObject *
5020posix_setgroups(PyObject *self, PyObject *args)
5021{
5022 PyObject *groups;
5023 int i, len;
5024 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00005025
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005026 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
5027 return NULL;
5028 if (!PySequence_Check(groups)) {
5029 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
5030 return NULL;
5031 }
5032 len = PySequence_Size(groups);
5033 if (len > MAX_GROUPS) {
5034 PyErr_SetString(PyExc_ValueError, "too many groups");
5035 return NULL;
5036 }
5037 for(i = 0; i < len; i++) {
5038 PyObject *elem;
5039 elem = PySequence_GetItem(groups, i);
5040 if (!elem)
5041 return NULL;
5042 if (!PyInt_Check(elem)) {
Georg Brandla13c2442005-11-22 19:30:31 +00005043 if (!PyLong_Check(elem)) {
5044 PyErr_SetString(PyExc_TypeError,
5045 "groups must be integers");
5046 Py_DECREF(elem);
5047 return NULL;
5048 } else {
5049 unsigned long x = PyLong_AsUnsignedLong(elem);
5050 if (PyErr_Occurred()) {
5051 PyErr_SetString(PyExc_TypeError,
5052 "group id too big");
5053 Py_DECREF(elem);
5054 return NULL;
5055 }
5056 grouplist[i] = x;
5057 /* read back the value to see if it fitted in gid_t */
5058 if (grouplist[i] != x) {
5059 PyErr_SetString(PyExc_TypeError,
5060 "group id too big");
5061 Py_DECREF(elem);
5062 return NULL;
5063 }
5064 }
5065 } else {
5066 long x = PyInt_AsLong(elem);
5067 grouplist[i] = x;
5068 if (grouplist[i] != x) {
5069 PyErr_SetString(PyExc_TypeError,
5070 "group id too big");
5071 Py_DECREF(elem);
5072 return NULL;
5073 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005074 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005075 Py_DECREF(elem);
5076 }
5077
5078 if (setgroups(len, grouplist) < 0)
5079 return posix_error();
5080 Py_INCREF(Py_None);
5081 return Py_None;
5082}
5083#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005084
Guido van Rossumb6775db1994-08-01 11:34:53 +00005085#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005086PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005087"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005088Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005089
Barry Warsaw53699e91996-12-10 23:23:01 +00005090static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005091posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005092{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005093 int pid, options;
5094#ifdef UNION_WAIT
5095 union wait status;
5096#define status_i (status.w_status)
5097#else
5098 int status;
5099#define status_i status
5100#endif
5101 status_i = 0;
5102
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005103 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00005104 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005105 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00005106 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00005107 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00005108 if (pid == -1)
5109 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00005110 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005111 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00005112}
5113
Tim Petersab034fa2002-02-01 11:27:43 +00005114#elif defined(HAVE_CWAIT)
5115
5116/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005117PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005118"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005119"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00005120
5121static PyObject *
5122posix_waitpid(PyObject *self, PyObject *args)
5123{
Martin v. Löwis18e16552006-02-15 17:27:45 +00005124 intptr_t pid;
5125 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00005126
5127 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
5128 return NULL;
5129 Py_BEGIN_ALLOW_THREADS
5130 pid = _cwait(&status, pid, options);
5131 Py_END_ALLOW_THREADS
5132 if (pid == -1)
5133 return posix_error();
5134 else
5135 /* shift the status left a byte so this is more like the
5136 POSIX waitpid */
5137 return Py_BuildValue("ii", pid, status << 8);
5138}
5139#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005140
Guido van Rossumad0ee831995-03-01 10:34:45 +00005141#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005142PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005143"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005144Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005145
Barry Warsaw53699e91996-12-10 23:23:01 +00005146static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005147posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00005148{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005149 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005150#ifdef UNION_WAIT
5151 union wait status;
5152#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00005153#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005154 int status;
5155#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00005156#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00005157
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005158 status_i = 0;
5159 Py_BEGIN_ALLOW_THREADS
5160 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00005161 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00005162 if (pid == -1)
5163 return posix_error();
5164 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005165 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005166#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00005167}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005168#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005169
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005170
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005171PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005172"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005173Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005174
Barry Warsaw53699e91996-12-10 23:23:01 +00005175static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005176posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005177{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005178#ifdef HAVE_LSTAT
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005179 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005180#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005181#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00005182 return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005183#else
5184 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
5185#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005186#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005187}
5188
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005189
Guido van Rossumb6775db1994-08-01 11:34:53 +00005190#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005191PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005192"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005193Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005194
Barry Warsaw53699e91996-12-10 23:23:01 +00005195static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005196posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005197{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005198 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00005199 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005200 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005201 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005202 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005203 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00005204 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00005205 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005206 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00005207 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00005208 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005209}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005210#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005211
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005212
Guido van Rossumb6775db1994-08-01 11:34:53 +00005213#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005214PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005215"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00005216Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005217
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005218static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005219posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005220{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005221 return posix_2str(args, "etet:symlink", symlink, NULL, NULL);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005222}
5223#endif /* HAVE_SYMLINK */
5224
5225
5226#ifdef HAVE_TIMES
5227#ifndef HZ
5228#define HZ 60 /* Universal constant :-) */
5229#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00005230
Guido van Rossumd48f2521997-12-05 22:19:34 +00005231#if defined(PYCC_VACPP) && defined(PYOS_OS2)
5232static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005233system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005234{
5235 ULONG value = 0;
5236
5237 Py_BEGIN_ALLOW_THREADS
5238 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
5239 Py_END_ALLOW_THREADS
5240
5241 return value;
5242}
5243
5244static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005245posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005246{
Guido van Rossumd48f2521997-12-05 22:19:34 +00005247 /* Currently Only Uptime is Provided -- Others Later */
5248 return Py_BuildValue("ddddd",
5249 (double)0 /* t.tms_utime / HZ */,
5250 (double)0 /* t.tms_stime / HZ */,
5251 (double)0 /* t.tms_cutime / HZ */,
5252 (double)0 /* t.tms_cstime / HZ */,
5253 (double)system_uptime() / 1000);
5254}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005255#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00005256static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005257posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00005258{
5259 struct tms t;
5260 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +00005261 errno = 0;
5262 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00005263 if (c == (clock_t) -1)
5264 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005265 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00005266 (double)t.tms_utime / HZ,
5267 (double)t.tms_stime / HZ,
5268 (double)t.tms_cutime / HZ,
5269 (double)t.tms_cstime / HZ,
5270 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00005271}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005272#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005273#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005274
5275
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005276#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005277#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00005278static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005279posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005280{
5281 FILETIME create, exit, kernel, user;
5282 HANDLE hProc;
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005283 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00005284 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
5285 /* The fields of a FILETIME structure are the hi and lo part
5286 of a 64-bit value expressed in 100 nanosecond units.
5287 1e7 is one second in such units; 1e-7 the inverse.
5288 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
5289 */
Barry Warsaw53699e91996-12-10 23:23:01 +00005290 return Py_BuildValue(
5291 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00005292 (double)(kernel.dwHighDateTime*429.4967296 +
5293 kernel.dwLowDateTime*1e-7),
5294 (double)(user.dwHighDateTime*429.4967296 +
5295 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00005296 (double)0,
5297 (double)0,
5298 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005299}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005300#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005301
5302#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005303PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005304"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005305Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005306#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005307
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005308
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00005309#ifdef HAVE_GETSID
5310PyDoc_STRVAR(posix_getsid__doc__,
5311"getsid(pid) -> sid\n\n\
5312Call the system call getsid().");
5313
5314static PyObject *
5315posix_getsid(PyObject *self, PyObject *args)
5316{
5317 int pid, sid;
5318 if (!PyArg_ParseTuple(args, "i:getsid", &pid))
5319 return NULL;
5320 sid = getsid(pid);
5321 if (sid < 0)
5322 return posix_error();
5323 return PyInt_FromLong((long)sid);
5324}
5325#endif /* HAVE_GETSID */
5326
5327
Guido van Rossumb6775db1994-08-01 11:34:53 +00005328#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005329PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005330"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005331Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005332
Barry Warsaw53699e91996-12-10 23:23:01 +00005333static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005334posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005335{
Guido van Rossum687dd131993-05-17 08:34:16 +00005336 if (setsid() < 0)
5337 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005338 Py_INCREF(Py_None);
5339 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005340}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005341#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005342
Guido van Rossumb6775db1994-08-01 11:34:53 +00005343#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005344PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005345"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005346Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005347
Barry Warsaw53699e91996-12-10 23:23:01 +00005348static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005349posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005350{
5351 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005352 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00005353 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005354 if (setpgid(pid, pgrp) < 0)
5355 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005356 Py_INCREF(Py_None);
5357 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005358}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005359#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005360
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005361
Guido van Rossumb6775db1994-08-01 11:34:53 +00005362#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005363PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005364"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005365Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005366
Barry Warsaw53699e91996-12-10 23:23:01 +00005367static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005368posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005369{
5370 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005371 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00005372 return NULL;
5373 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005374 if (pgid < 0)
5375 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005376 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00005377}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005378#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00005379
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005380
Guido van Rossumb6775db1994-08-01 11:34:53 +00005381#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005382PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005383"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005384Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005385
Barry Warsaw53699e91996-12-10 23:23:01 +00005386static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005387posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005388{
5389 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005390 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00005391 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005392 if (tcsetpgrp(fd, pgid) < 0)
5393 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00005394 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00005395 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00005396}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005397#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00005398
Guido van Rossum687dd131993-05-17 08:34:16 +00005399/* Functions acting on file descriptors */
5400
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005401PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005402"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005403Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005404
Barry Warsaw53699e91996-12-10 23:23:01 +00005405static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005406posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005407{
Mark Hammondef8b6542001-05-13 08:04:26 +00005408 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005409 int flag;
5410 int mode = 0777;
5411 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005412
5413#ifdef MS_WINDOWS
5414 if (unicode_file_names()) {
5415 PyUnicodeObject *po;
5416 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
5417 Py_BEGIN_ALLOW_THREADS
5418 /* PyUnicode_AS_UNICODE OK without thread
5419 lock as it is a simple dereference. */
5420 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
5421 Py_END_ALLOW_THREADS
5422 if (fd < 0)
5423 return posix_error();
5424 return PyInt_FromLong((long)fd);
5425 }
5426 /* Drop the argument parsing error as narrow strings
5427 are also valid. */
5428 PyErr_Clear();
5429 }
5430#endif
5431
Tim Peters5aa91602002-01-30 05:46:57 +00005432 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00005433 Py_FileSystemDefaultEncoding, &file,
5434 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00005435 return NULL;
5436
Barry Warsaw53699e91996-12-10 23:23:01 +00005437 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005438 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005439 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005440 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00005441 return posix_error_with_allocated_filename(file);
5442 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00005443 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005444}
5445
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005446
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005447PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005448"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005449Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005450
Barry Warsaw53699e91996-12-10 23:23:01 +00005451static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005452posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005453{
5454 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005455 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005456 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005457 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005458 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00005459 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005460 if (res < 0)
5461 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005462 Py_INCREF(Py_None);
5463 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005464}
5465
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005466
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005467PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005468"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005469Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005470
Barry Warsaw53699e91996-12-10 23:23:01 +00005471static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005472posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005473{
5474 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005475 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005476 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005477 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005478 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00005479 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005480 if (fd < 0)
5481 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005482 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005483}
5484
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005485
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005486PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00005487"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005488Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005489
Barry Warsaw53699e91996-12-10 23:23:01 +00005490static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005491posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005492{
5493 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005494 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00005495 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005496 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005497 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00005498 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005499 if (res < 0)
5500 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005501 Py_INCREF(Py_None);
5502 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005503}
5504
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005505
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005506PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005507"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005508Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005509
Barry Warsaw53699e91996-12-10 23:23:01 +00005510static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005511posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005512{
5513 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005514#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005515 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005516#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00005517 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005518#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005519 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005520 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00005521 return NULL;
5522#ifdef SEEK_SET
5523 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
5524 switch (how) {
5525 case 0: how = SEEK_SET; break;
5526 case 1: how = SEEK_CUR; break;
5527 case 2: how = SEEK_END; break;
5528 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005529#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005530
5531#if !defined(HAVE_LARGEFILE_SUPPORT)
5532 pos = PyInt_AsLong(posobj);
5533#else
5534 pos = PyLong_Check(posobj) ?
5535 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
5536#endif
5537 if (PyErr_Occurred())
5538 return NULL;
5539
Barry Warsaw53699e91996-12-10 23:23:01 +00005540 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005541#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00005542 res = _lseeki64(fd, pos, how);
5543#else
Guido van Rossum687dd131993-05-17 08:34:16 +00005544 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005545#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005546 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005547 if (res < 0)
5548 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00005549
5550#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00005551 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005552#else
5553 return PyLong_FromLongLong(res);
5554#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005555}
5556
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005557
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005558PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005559"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005560Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005561
Barry Warsaw53699e91996-12-10 23:23:01 +00005562static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005563posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005564{
Guido van Rossum8bac5461996-06-11 18:38:48 +00005565 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00005566 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005567 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005568 return NULL;
Michael W. Hudson9867ced2005-01-31 17:01:59 +00005569 if (size < 0) {
5570 errno = EINVAL;
5571 return posix_error();
5572 }
Barry Warsaw53699e91996-12-10 23:23:01 +00005573 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005574 if (buffer == NULL)
5575 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005576 Py_BEGIN_ALLOW_THREADS
5577 n = read(fd, PyString_AsString(buffer), size);
5578 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00005579 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005580 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00005581 return posix_error();
5582 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00005583 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00005584 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00005585 return buffer;
5586}
5587
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005588
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005589PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005590"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005591Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005592
Barry Warsaw53699e91996-12-10 23:23:01 +00005593static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005594posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005595{
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005596 int fd;
5597 Py_ssize_t size;
Guido van Rossum687dd131993-05-17 08:34:16 +00005598 char *buffer;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005599
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005600 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005601 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005602 Py_BEGIN_ALLOW_THREADS
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005603 size = write(fd, buffer, (size_t)size);
Barry Warsaw53699e91996-12-10 23:23:01 +00005604 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005605 if (size < 0)
5606 return posix_error();
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005607 return PyInt_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005608}
5609
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005610
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005611PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005612"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005613Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005614
Barry Warsaw53699e91996-12-10 23:23:01 +00005615static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005616posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005617{
5618 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00005619 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00005620 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005621 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005622 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005623#ifdef __VMS
5624 /* on OpenVMS we must ensure that all bytes are written to the file */
5625 fsync(fd);
5626#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005627 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00005628 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00005629 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00005630 if (res != 0) {
5631#ifdef MS_WINDOWS
5632 return win32_error("fstat", NULL);
5633#else
Guido van Rossum687dd131993-05-17 08:34:16 +00005634 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00005635#endif
5636 }
Tim Peters5aa91602002-01-30 05:46:57 +00005637
Martin v. Löwis14694662006-02-03 12:54:16 +00005638 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00005639}
5640
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005641
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005642PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005643"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005644Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005645
Barry Warsaw53699e91996-12-10 23:23:01 +00005646static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005647posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005648{
Guido van Rossum687dd131993-05-17 08:34:16 +00005649 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005650 char *mode = "r";
5651 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00005652 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00005653 PyObject *f;
5654 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00005655 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00005656
Thomas Heller1f043e22002-11-07 16:00:59 +00005657 if (mode[0] != 'r' && mode[0] != 'w' && mode[0] != 'a') {
5658 PyErr_Format(PyExc_ValueError,
5659 "invalid file mode '%s'", mode);
5660 return NULL;
5661 }
5662
Barry Warsaw53699e91996-12-10 23:23:01 +00005663 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005664 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005665 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005666 if (fp == NULL)
5667 return posix_error();
Guido van Rossumbd6be7a2002-09-15 18:45:46 +00005668 f = PyFile_FromFile(fp, "<fdopen>", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005669 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00005670 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005671 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00005672}
5673
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005674PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005675"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005676Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005677connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00005678
5679static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00005680posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00005681{
5682 int fd;
5683 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
5684 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005685 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00005686}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005687
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005688#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005689PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005690"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005691Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005692
Barry Warsaw53699e91996-12-10 23:23:01 +00005693static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005694posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00005695{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005696#if defined(PYOS_OS2)
5697 HFILE read, write;
5698 APIRET rc;
5699
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005700 Py_BEGIN_ALLOW_THREADS
5701 rc = DosCreatePipe( &read, &write, 4096);
5702 Py_END_ALLOW_THREADS
5703 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005704 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005705
5706 return Py_BuildValue("(ii)", read, write);
5707#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005708#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00005709 int fds[2];
5710 int res;
Barry Warsaw53699e91996-12-10 23:23:01 +00005711 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005712 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00005713 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005714 if (res != 0)
5715 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005716 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005717#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00005718 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005719 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00005720 BOOL ok;
Barry Warsaw53699e91996-12-10 23:23:01 +00005721 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005722 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00005723 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00005724 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005725 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00005726 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
5727 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005728 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005729#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005730#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005731}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005732#endif /* HAVE_PIPE */
5733
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005734
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005735#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005736PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005737"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005738Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005739
Barry Warsaw53699e91996-12-10 23:23:01 +00005740static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005741posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005742{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005743 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005744 int mode = 0666;
5745 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005746 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005747 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005748 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005749 res = mkfifo(filename, mode);
5750 Py_END_ALLOW_THREADS
5751 if (res < 0)
5752 return posix_error();
5753 Py_INCREF(Py_None);
5754 return Py_None;
5755}
5756#endif
5757
5758
Neal Norwitz11690112002-07-30 01:08:28 +00005759#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005760PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005761"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005762Create a filesystem node (file, device special file or named pipe)\n\
5763named filename. mode specifies both the permissions to use and the\n\
5764type of node to be created, being combined (bitwise OR) with one of\n\
5765S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005766device defines the newly created device special file (probably using\n\
5767os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005768
5769
5770static PyObject *
5771posix_mknod(PyObject *self, PyObject *args)
5772{
5773 char *filename;
5774 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005775 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005776 int res;
Martin v. Löwisd631ebe2002-11-02 17:42:33 +00005777 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005778 return NULL;
5779 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005780 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00005781 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005782 if (res < 0)
5783 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005784 Py_INCREF(Py_None);
5785 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005786}
5787#endif
5788
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005789#ifdef HAVE_DEVICE_MACROS
5790PyDoc_STRVAR(posix_major__doc__,
5791"major(device) -> major number\n\
5792Extracts a device major number from a raw device number.");
5793
5794static PyObject *
5795posix_major(PyObject *self, PyObject *args)
5796{
5797 int device;
5798 if (!PyArg_ParseTuple(args, "i:major", &device))
5799 return NULL;
5800 return PyInt_FromLong((long)major(device));
5801}
5802
5803PyDoc_STRVAR(posix_minor__doc__,
5804"minor(device) -> minor number\n\
5805Extracts a device minor number from a raw device number.");
5806
5807static PyObject *
5808posix_minor(PyObject *self, PyObject *args)
5809{
5810 int device;
5811 if (!PyArg_ParseTuple(args, "i:minor", &device))
5812 return NULL;
5813 return PyInt_FromLong((long)minor(device));
5814}
5815
5816PyDoc_STRVAR(posix_makedev__doc__,
5817"makedev(major, minor) -> device number\n\
5818Composes a raw device number from the major and minor device numbers.");
5819
5820static PyObject *
5821posix_makedev(PyObject *self, PyObject *args)
5822{
5823 int major, minor;
5824 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
5825 return NULL;
5826 return PyInt_FromLong((long)makedev(major, minor));
5827}
5828#endif /* device macros */
5829
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005830
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005831#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005832PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005833"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005834Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005835
Barry Warsaw53699e91996-12-10 23:23:01 +00005836static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005837posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005838{
5839 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005840 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005841 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005842 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005843
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005844 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005845 return NULL;
5846
5847#if !defined(HAVE_LARGEFILE_SUPPORT)
5848 length = PyInt_AsLong(lenobj);
5849#else
5850 length = PyLong_Check(lenobj) ?
5851 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
5852#endif
5853 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005854 return NULL;
5855
Barry Warsaw53699e91996-12-10 23:23:01 +00005856 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005857 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00005858 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005859 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005860 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005861 return NULL;
5862 }
Barry Warsaw53699e91996-12-10 23:23:01 +00005863 Py_INCREF(Py_None);
5864 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005865}
5866#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005867
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005868#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005869PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005870"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005871Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005872
Fred Drake762e2061999-08-26 17:23:54 +00005873/* Save putenv() parameters as values here, so we can collect them when they
5874 * get re-set with another call for the same key. */
5875static PyObject *posix_putenv_garbage;
5876
Tim Peters5aa91602002-01-30 05:46:57 +00005877static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005878posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005879{
5880 char *s1, *s2;
5881 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00005882 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00005883 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005884
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005885 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005886 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00005887
5888#if defined(PYOS_OS2)
5889 if (stricmp(s1, "BEGINLIBPATH") == 0) {
5890 APIRET rc;
5891
Guido van Rossumd48f2521997-12-05 22:19:34 +00005892 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
5893 if (rc != NO_ERROR)
5894 return os2_error(rc);
5895
5896 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
5897 APIRET rc;
5898
Guido van Rossumd48f2521997-12-05 22:19:34 +00005899 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
5900 if (rc != NO_ERROR)
5901 return os2_error(rc);
5902 } else {
5903#endif
5904
Fred Drake762e2061999-08-26 17:23:54 +00005905 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00005906 len = strlen(s1) + strlen(s2) + 2;
5907 /* len includes space for a trailing \0; the size arg to
5908 PyString_FromStringAndSize does not count that */
5909 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00005910 if (newstr == NULL)
5911 return PyErr_NoMemory();
5912 new = PyString_AS_STRING(newstr);
Tim Petersc8996f52001-12-03 20:41:00 +00005913 PyOS_snprintf(new, len, "%s=%s", s1, s2);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005914 if (putenv(new)) {
Neal Norwitz4adc9ab2003-02-10 03:10:43 +00005915 Py_DECREF(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005916 posix_error();
5917 return NULL;
5918 }
Fred Drake762e2061999-08-26 17:23:54 +00005919 /* Install the first arg and newstr in posix_putenv_garbage;
5920 * this will cause previous value to be collected. This has to
5921 * happen after the real putenv() call because the old value
5922 * was still accessible until then. */
5923 if (PyDict_SetItem(posix_putenv_garbage,
5924 PyTuple_GET_ITEM(args, 0), newstr)) {
5925 /* really not much we can do; just leak */
5926 PyErr_Clear();
5927 }
5928 else {
5929 Py_DECREF(newstr);
5930 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005931
5932#if defined(PYOS_OS2)
5933 }
5934#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005935 Py_INCREF(Py_None);
5936 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005937}
Guido van Rossumb6a47161997-09-15 22:54:34 +00005938#endif /* putenv */
5939
Guido van Rossumc524d952001-10-19 01:31:59 +00005940#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005941PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005942"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005943Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00005944
5945static PyObject *
5946posix_unsetenv(PyObject *self, PyObject *args)
5947{
5948 char *s1;
5949
5950 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
5951 return NULL;
5952
5953 unsetenv(s1);
5954
5955 /* Remove the key from posix_putenv_garbage;
5956 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00005957 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00005958 * old value was still accessible until then.
5959 */
5960 if (PyDict_DelItem(posix_putenv_garbage,
5961 PyTuple_GET_ITEM(args, 0))) {
5962 /* really not much we can do; just leak */
5963 PyErr_Clear();
5964 }
5965
5966 Py_INCREF(Py_None);
5967 return Py_None;
5968}
5969#endif /* unsetenv */
5970
Guido van Rossumb6a47161997-09-15 22:54:34 +00005971#ifdef HAVE_STRERROR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005972PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005973"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005974Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005975
Guido van Rossumf68d8e52001-04-14 17:55:09 +00005976static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005977posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00005978{
5979 int code;
5980 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005981 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00005982 return NULL;
5983 message = strerror(code);
5984 if (message == NULL) {
5985 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00005986 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005987 return NULL;
5988 }
5989 return PyString_FromString(message);
5990}
5991#endif /* strerror */
5992
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005993
Guido van Rossumc9641791998-08-04 15:26:23 +00005994#ifdef HAVE_SYS_WAIT_H
5995
Fred Drake106c1a02002-04-23 15:58:02 +00005996#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005997PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005998"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005999Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00006000
6001static PyObject *
6002posix_WCOREDUMP(PyObject *self, PyObject *args)
6003{
6004#ifdef UNION_WAIT
6005 union wait status;
6006#define status_i (status.w_status)
6007#else
6008 int status;
6009#define status_i status
6010#endif
6011 status_i = 0;
6012
6013 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &status_i))
6014 {
6015 return NULL;
6016 }
6017
6018 return PyBool_FromLong(WCOREDUMP(status));
6019#undef status_i
6020}
6021#endif /* WCOREDUMP */
6022
6023#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006024PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006025"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006026Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006027job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00006028
6029static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006030posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00006031{
6032#ifdef UNION_WAIT
6033 union wait status;
6034#define status_i (status.w_status)
6035#else
6036 int status;
6037#define status_i status
6038#endif
6039 status_i = 0;
6040
6041 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &status_i))
6042 {
6043 return NULL;
6044 }
6045
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006046 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006047#undef status_i
6048}
6049#endif /* WIFCONTINUED */
6050
Guido van Rossumc9641791998-08-04 15:26:23 +00006051#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006052PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006053"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006054Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006055
6056static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006057posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006058{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006059#ifdef UNION_WAIT
6060 union wait status;
6061#define status_i (status.w_status)
6062#else
6063 int status;
6064#define status_i status
6065#endif
6066 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006067
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006068 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00006069 {
6070 return NULL;
6071 }
Tim Peters5aa91602002-01-30 05:46:57 +00006072
Fred Drake106c1a02002-04-23 15:58:02 +00006073 return PyBool_FromLong(WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006074#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00006075}
6076#endif /* WIFSTOPPED */
6077
6078#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006079PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006080"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006081Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006082
6083static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006084posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006085{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006086#ifdef UNION_WAIT
6087 union wait status;
6088#define status_i (status.w_status)
6089#else
6090 int status;
6091#define status_i status
6092#endif
6093 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006094
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006095 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00006096 {
6097 return NULL;
6098 }
Tim Peters5aa91602002-01-30 05:46:57 +00006099
Fred Drake106c1a02002-04-23 15:58:02 +00006100 return PyBool_FromLong(WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006101#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00006102}
6103#endif /* WIFSIGNALED */
6104
6105#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006106PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006107"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006108Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006109system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006110
6111static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006112posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006113{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006114#ifdef UNION_WAIT
6115 union wait status;
6116#define status_i (status.w_status)
6117#else
6118 int status;
6119#define status_i status
6120#endif
6121 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006122
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006123 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00006124 {
6125 return NULL;
6126 }
Tim Peters5aa91602002-01-30 05:46:57 +00006127
Fred Drake106c1a02002-04-23 15:58:02 +00006128 return PyBool_FromLong(WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006129#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00006130}
6131#endif /* WIFEXITED */
6132
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006133#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006134PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006135"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006136Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006137
6138static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006139posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006140{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006141#ifdef UNION_WAIT
6142 union wait status;
6143#define status_i (status.w_status)
6144#else
6145 int status;
6146#define status_i status
6147#endif
6148 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006149
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006150 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00006151 {
6152 return NULL;
6153 }
Tim Peters5aa91602002-01-30 05:46:57 +00006154
Guido van Rossumc9641791998-08-04 15:26:23 +00006155 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006156#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00006157}
6158#endif /* WEXITSTATUS */
6159
6160#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006161PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006162"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006163Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006164value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006165
6166static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006167posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006168{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006169#ifdef UNION_WAIT
6170 union wait status;
6171#define status_i (status.w_status)
6172#else
6173 int status;
6174#define status_i status
6175#endif
6176 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006177
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006178 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00006179 {
6180 return NULL;
6181 }
Tim Peters5aa91602002-01-30 05:46:57 +00006182
Guido van Rossumc9641791998-08-04 15:26:23 +00006183 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006184#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00006185}
6186#endif /* WTERMSIG */
6187
6188#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006189PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006190"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006191Return the signal that stopped the process that provided\n\
6192the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006193
6194static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006195posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006196{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006197#ifdef UNION_WAIT
6198 union wait status;
6199#define status_i (status.w_status)
6200#else
6201 int status;
6202#define status_i status
6203#endif
6204 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006205
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006206 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00006207 {
6208 return NULL;
6209 }
Tim Peters5aa91602002-01-30 05:46:57 +00006210
Guido van Rossumc9641791998-08-04 15:26:23 +00006211 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006212#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00006213}
6214#endif /* WSTOPSIG */
6215
6216#endif /* HAVE_SYS_WAIT_H */
6217
6218
Guido van Rossum94f6f721999-01-06 18:42:14 +00006219#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00006220#ifdef _SCO_DS
6221/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
6222 needed definitions in sys/statvfs.h */
6223#define _SVID3
6224#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006225#include <sys/statvfs.h>
6226
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006227static PyObject*
6228_pystatvfs_fromstructstatvfs(struct statvfs st) {
6229 PyObject *v = PyStructSequence_New(&StatVFSResultType);
6230 if (v == NULL)
6231 return NULL;
6232
6233#if !defined(HAVE_LARGEFILE_SUPPORT)
6234 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6235 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
6236 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
6237 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
6238 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
6239 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
6240 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
6241 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
6242 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6243 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6244#else
6245 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6246 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00006247 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006248 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00006249 PyStructSequence_SET_ITEM(v, 3,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006250 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006251 PyStructSequence_SET_ITEM(v, 4,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006252 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00006253 PyStructSequence_SET_ITEM(v, 5,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006254 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00006255 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006256 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00006257 PyStructSequence_SET_ITEM(v, 7,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006258 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006259 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6260 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6261#endif
6262
6263 return v;
6264}
6265
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006266PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006267"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006268Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006269
6270static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006271posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006272{
6273 int fd, res;
6274 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006275
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006276 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006277 return NULL;
6278 Py_BEGIN_ALLOW_THREADS
6279 res = fstatvfs(fd, &st);
6280 Py_END_ALLOW_THREADS
6281 if (res != 0)
6282 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006283
6284 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006285}
6286#endif /* HAVE_FSTATVFS */
6287
6288
6289#if defined(HAVE_STATVFS)
6290#include <sys/statvfs.h>
6291
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006292PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006293"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006294Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006295
6296static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006297posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006298{
6299 char *path;
6300 int res;
6301 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006302 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006303 return NULL;
6304 Py_BEGIN_ALLOW_THREADS
6305 res = statvfs(path, &st);
6306 Py_END_ALLOW_THREADS
6307 if (res != 0)
6308 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006309
6310 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006311}
6312#endif /* HAVE_STATVFS */
6313
6314
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006315#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006316PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006317"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006318Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00006319The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006320or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006321
6322static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006323posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006324{
6325 PyObject *result = NULL;
6326 char *dir = NULL;
6327 char *pfx = NULL;
6328 char *name;
6329
6330 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
6331 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00006332
6333 if (PyErr_Warn(PyExc_RuntimeWarning,
6334 "tempnam is a potential security risk to your program") < 0)
6335 return NULL;
6336
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006337#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00006338 name = _tempnam(dir, pfx);
6339#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006340 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00006341#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006342 if (name == NULL)
6343 return PyErr_NoMemory();
6344 result = PyString_FromString(name);
6345 free(name);
6346 return result;
6347}
Guido van Rossumd371ff11999-01-25 16:12:23 +00006348#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006349
6350
6351#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006352PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006353"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006354Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006355
6356static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006357posix_tmpfile(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006358{
6359 FILE *fp;
6360
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006361 fp = tmpfile();
6362 if (fp == NULL)
6363 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00006364 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006365}
6366#endif
6367
6368
6369#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006370PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006371"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006372Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006373
6374static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006375posix_tmpnam(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006376{
6377 char buffer[L_tmpnam];
6378 char *name;
6379
Skip Montanaro95618b52001-08-18 18:52:10 +00006380 if (PyErr_Warn(PyExc_RuntimeWarning,
6381 "tmpnam is a potential security risk to your program") < 0)
6382 return NULL;
6383
Greg Wardb48bc172000-03-01 21:51:56 +00006384#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006385 name = tmpnam_r(buffer);
6386#else
6387 name = tmpnam(buffer);
6388#endif
6389 if (name == NULL) {
6390 PyErr_SetObject(PyExc_OSError,
6391 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00006392#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006393 "unexpected NULL from tmpnam_r"
6394#else
6395 "unexpected NULL from tmpnam"
6396#endif
6397 ));
6398 return NULL;
6399 }
6400 return PyString_FromString(buffer);
6401}
6402#endif
6403
6404
Fred Drakec9680921999-12-13 16:37:25 +00006405/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
6406 * It maps strings representing configuration variable names to
6407 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00006408 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00006409 * rarely-used constants. There are three separate tables that use
6410 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00006411 *
6412 * This code is always included, even if none of the interfaces that
6413 * need it are included. The #if hackery needed to avoid it would be
6414 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00006415 */
6416struct constdef {
6417 char *name;
6418 long value;
6419};
6420
Fred Drake12c6e2d1999-12-14 21:25:03 +00006421static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006422conv_confname(PyObject *arg, int *valuep, struct constdef *table,
6423 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006424{
6425 if (PyInt_Check(arg)) {
6426 *valuep = PyInt_AS_LONG(arg);
6427 return 1;
6428 }
6429 if (PyString_Check(arg)) {
6430 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00006431 size_t lo = 0;
6432 size_t mid;
6433 size_t hi = tablesize;
6434 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006435 char *confname = PyString_AS_STRING(arg);
6436 while (lo < hi) {
6437 mid = (lo + hi) / 2;
6438 cmp = strcmp(confname, table[mid].name);
6439 if (cmp < 0)
6440 hi = mid;
6441 else if (cmp > 0)
6442 lo = mid + 1;
6443 else {
6444 *valuep = table[mid].value;
6445 return 1;
6446 }
6447 }
6448 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
6449 }
6450 else
6451 PyErr_SetString(PyExc_TypeError,
6452 "configuration names must be strings or integers");
6453 return 0;
6454}
6455
6456
6457#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
6458static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006459#ifdef _PC_ABI_AIO_XFER_MAX
6460 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
6461#endif
6462#ifdef _PC_ABI_ASYNC_IO
6463 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
6464#endif
Fred Drakec9680921999-12-13 16:37:25 +00006465#ifdef _PC_ASYNC_IO
6466 {"PC_ASYNC_IO", _PC_ASYNC_IO},
6467#endif
6468#ifdef _PC_CHOWN_RESTRICTED
6469 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
6470#endif
6471#ifdef _PC_FILESIZEBITS
6472 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
6473#endif
6474#ifdef _PC_LAST
6475 {"PC_LAST", _PC_LAST},
6476#endif
6477#ifdef _PC_LINK_MAX
6478 {"PC_LINK_MAX", _PC_LINK_MAX},
6479#endif
6480#ifdef _PC_MAX_CANON
6481 {"PC_MAX_CANON", _PC_MAX_CANON},
6482#endif
6483#ifdef _PC_MAX_INPUT
6484 {"PC_MAX_INPUT", _PC_MAX_INPUT},
6485#endif
6486#ifdef _PC_NAME_MAX
6487 {"PC_NAME_MAX", _PC_NAME_MAX},
6488#endif
6489#ifdef _PC_NO_TRUNC
6490 {"PC_NO_TRUNC", _PC_NO_TRUNC},
6491#endif
6492#ifdef _PC_PATH_MAX
6493 {"PC_PATH_MAX", _PC_PATH_MAX},
6494#endif
6495#ifdef _PC_PIPE_BUF
6496 {"PC_PIPE_BUF", _PC_PIPE_BUF},
6497#endif
6498#ifdef _PC_PRIO_IO
6499 {"PC_PRIO_IO", _PC_PRIO_IO},
6500#endif
6501#ifdef _PC_SOCK_MAXBUF
6502 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
6503#endif
6504#ifdef _PC_SYNC_IO
6505 {"PC_SYNC_IO", _PC_SYNC_IO},
6506#endif
6507#ifdef _PC_VDISABLE
6508 {"PC_VDISABLE", _PC_VDISABLE},
6509#endif
6510};
6511
Fred Drakec9680921999-12-13 16:37:25 +00006512static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006513conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006514{
6515 return conv_confname(arg, valuep, posix_constants_pathconf,
6516 sizeof(posix_constants_pathconf)
6517 / sizeof(struct constdef));
6518}
6519#endif
6520
6521#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006522PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006523"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006524Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006525If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006526
6527static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006528posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006529{
6530 PyObject *result = NULL;
6531 int name, fd;
6532
Fred Drake12c6e2d1999-12-14 21:25:03 +00006533 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
6534 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00006535 long limit;
6536
6537 errno = 0;
6538 limit = fpathconf(fd, name);
6539 if (limit == -1 && errno != 0)
6540 posix_error();
6541 else
6542 result = PyInt_FromLong(limit);
6543 }
6544 return result;
6545}
6546#endif
6547
6548
6549#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006550PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006551"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006552Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006553If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006554
6555static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006556posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006557{
6558 PyObject *result = NULL;
6559 int name;
6560 char *path;
6561
6562 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
6563 conv_path_confname, &name)) {
6564 long limit;
6565
6566 errno = 0;
6567 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006568 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00006569 if (errno == EINVAL)
6570 /* could be a path or name problem */
6571 posix_error();
6572 else
6573 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006574 }
Fred Drakec9680921999-12-13 16:37:25 +00006575 else
6576 result = PyInt_FromLong(limit);
6577 }
6578 return result;
6579}
6580#endif
6581
6582#ifdef HAVE_CONFSTR
6583static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006584#ifdef _CS_ARCHITECTURE
6585 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
6586#endif
6587#ifdef _CS_HOSTNAME
6588 {"CS_HOSTNAME", _CS_HOSTNAME},
6589#endif
6590#ifdef _CS_HW_PROVIDER
6591 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
6592#endif
6593#ifdef _CS_HW_SERIAL
6594 {"CS_HW_SERIAL", _CS_HW_SERIAL},
6595#endif
6596#ifdef _CS_INITTAB_NAME
6597 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
6598#endif
Fred Drakec9680921999-12-13 16:37:25 +00006599#ifdef _CS_LFS64_CFLAGS
6600 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
6601#endif
6602#ifdef _CS_LFS64_LDFLAGS
6603 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
6604#endif
6605#ifdef _CS_LFS64_LIBS
6606 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
6607#endif
6608#ifdef _CS_LFS64_LINTFLAGS
6609 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
6610#endif
6611#ifdef _CS_LFS_CFLAGS
6612 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
6613#endif
6614#ifdef _CS_LFS_LDFLAGS
6615 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
6616#endif
6617#ifdef _CS_LFS_LIBS
6618 {"CS_LFS_LIBS", _CS_LFS_LIBS},
6619#endif
6620#ifdef _CS_LFS_LINTFLAGS
6621 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
6622#endif
Fred Draked86ed291999-12-15 15:34:33 +00006623#ifdef _CS_MACHINE
6624 {"CS_MACHINE", _CS_MACHINE},
6625#endif
Fred Drakec9680921999-12-13 16:37:25 +00006626#ifdef _CS_PATH
6627 {"CS_PATH", _CS_PATH},
6628#endif
Fred Draked86ed291999-12-15 15:34:33 +00006629#ifdef _CS_RELEASE
6630 {"CS_RELEASE", _CS_RELEASE},
6631#endif
6632#ifdef _CS_SRPC_DOMAIN
6633 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
6634#endif
6635#ifdef _CS_SYSNAME
6636 {"CS_SYSNAME", _CS_SYSNAME},
6637#endif
6638#ifdef _CS_VERSION
6639 {"CS_VERSION", _CS_VERSION},
6640#endif
Fred Drakec9680921999-12-13 16:37:25 +00006641#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
6642 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
6643#endif
6644#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
6645 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
6646#endif
6647#ifdef _CS_XBS5_ILP32_OFF32_LIBS
6648 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
6649#endif
6650#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
6651 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
6652#endif
6653#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
6654 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
6655#endif
6656#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
6657 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
6658#endif
6659#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
6660 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
6661#endif
6662#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
6663 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
6664#endif
6665#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
6666 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
6667#endif
6668#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
6669 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
6670#endif
6671#ifdef _CS_XBS5_LP64_OFF64_LIBS
6672 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
6673#endif
6674#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
6675 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
6676#endif
6677#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
6678 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
6679#endif
6680#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
6681 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
6682#endif
6683#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
6684 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
6685#endif
6686#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
6687 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
6688#endif
Fred Draked86ed291999-12-15 15:34:33 +00006689#ifdef _MIPS_CS_AVAIL_PROCESSORS
6690 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
6691#endif
6692#ifdef _MIPS_CS_BASE
6693 {"MIPS_CS_BASE", _MIPS_CS_BASE},
6694#endif
6695#ifdef _MIPS_CS_HOSTID
6696 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
6697#endif
6698#ifdef _MIPS_CS_HW_NAME
6699 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
6700#endif
6701#ifdef _MIPS_CS_NUM_PROCESSORS
6702 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
6703#endif
6704#ifdef _MIPS_CS_OSREL_MAJ
6705 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
6706#endif
6707#ifdef _MIPS_CS_OSREL_MIN
6708 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
6709#endif
6710#ifdef _MIPS_CS_OSREL_PATCH
6711 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
6712#endif
6713#ifdef _MIPS_CS_OS_NAME
6714 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
6715#endif
6716#ifdef _MIPS_CS_OS_PROVIDER
6717 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
6718#endif
6719#ifdef _MIPS_CS_PROCESSORS
6720 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
6721#endif
6722#ifdef _MIPS_CS_SERIAL
6723 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
6724#endif
6725#ifdef _MIPS_CS_VENDOR
6726 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
6727#endif
Fred Drakec9680921999-12-13 16:37:25 +00006728};
6729
6730static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006731conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006732{
6733 return conv_confname(arg, valuep, posix_constants_confstr,
6734 sizeof(posix_constants_confstr)
6735 / sizeof(struct constdef));
6736}
6737
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006738PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006739"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006740Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006741
6742static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006743posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006744{
6745 PyObject *result = NULL;
6746 int name;
6747 char buffer[64];
6748
6749 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
6750 int len = confstr(name, buffer, sizeof(buffer));
6751
Fred Drakec9680921999-12-13 16:37:25 +00006752 errno = 0;
6753 if (len == 0) {
6754 if (errno != 0)
6755 posix_error();
6756 else
6757 result = PyString_FromString("");
6758 }
6759 else {
6760 if (len >= sizeof(buffer)) {
6761 result = PyString_FromStringAndSize(NULL, len);
6762 if (result != NULL)
6763 confstr(name, PyString_AS_STRING(result), len+1);
6764 }
6765 else
6766 result = PyString_FromString(buffer);
6767 }
6768 }
6769 return result;
6770}
6771#endif
6772
6773
6774#ifdef HAVE_SYSCONF
6775static struct constdef posix_constants_sysconf[] = {
6776#ifdef _SC_2_CHAR_TERM
6777 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
6778#endif
6779#ifdef _SC_2_C_BIND
6780 {"SC_2_C_BIND", _SC_2_C_BIND},
6781#endif
6782#ifdef _SC_2_C_DEV
6783 {"SC_2_C_DEV", _SC_2_C_DEV},
6784#endif
6785#ifdef _SC_2_C_VERSION
6786 {"SC_2_C_VERSION", _SC_2_C_VERSION},
6787#endif
6788#ifdef _SC_2_FORT_DEV
6789 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
6790#endif
6791#ifdef _SC_2_FORT_RUN
6792 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
6793#endif
6794#ifdef _SC_2_LOCALEDEF
6795 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
6796#endif
6797#ifdef _SC_2_SW_DEV
6798 {"SC_2_SW_DEV", _SC_2_SW_DEV},
6799#endif
6800#ifdef _SC_2_UPE
6801 {"SC_2_UPE", _SC_2_UPE},
6802#endif
6803#ifdef _SC_2_VERSION
6804 {"SC_2_VERSION", _SC_2_VERSION},
6805#endif
Fred Draked86ed291999-12-15 15:34:33 +00006806#ifdef _SC_ABI_ASYNCHRONOUS_IO
6807 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
6808#endif
6809#ifdef _SC_ACL
6810 {"SC_ACL", _SC_ACL},
6811#endif
Fred Drakec9680921999-12-13 16:37:25 +00006812#ifdef _SC_AIO_LISTIO_MAX
6813 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
6814#endif
Fred Drakec9680921999-12-13 16:37:25 +00006815#ifdef _SC_AIO_MAX
6816 {"SC_AIO_MAX", _SC_AIO_MAX},
6817#endif
6818#ifdef _SC_AIO_PRIO_DELTA_MAX
6819 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
6820#endif
6821#ifdef _SC_ARG_MAX
6822 {"SC_ARG_MAX", _SC_ARG_MAX},
6823#endif
6824#ifdef _SC_ASYNCHRONOUS_IO
6825 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
6826#endif
6827#ifdef _SC_ATEXIT_MAX
6828 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
6829#endif
Fred Draked86ed291999-12-15 15:34:33 +00006830#ifdef _SC_AUDIT
6831 {"SC_AUDIT", _SC_AUDIT},
6832#endif
Fred Drakec9680921999-12-13 16:37:25 +00006833#ifdef _SC_AVPHYS_PAGES
6834 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
6835#endif
6836#ifdef _SC_BC_BASE_MAX
6837 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
6838#endif
6839#ifdef _SC_BC_DIM_MAX
6840 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
6841#endif
6842#ifdef _SC_BC_SCALE_MAX
6843 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
6844#endif
6845#ifdef _SC_BC_STRING_MAX
6846 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
6847#endif
Fred Draked86ed291999-12-15 15:34:33 +00006848#ifdef _SC_CAP
6849 {"SC_CAP", _SC_CAP},
6850#endif
Fred Drakec9680921999-12-13 16:37:25 +00006851#ifdef _SC_CHARCLASS_NAME_MAX
6852 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
6853#endif
6854#ifdef _SC_CHAR_BIT
6855 {"SC_CHAR_BIT", _SC_CHAR_BIT},
6856#endif
6857#ifdef _SC_CHAR_MAX
6858 {"SC_CHAR_MAX", _SC_CHAR_MAX},
6859#endif
6860#ifdef _SC_CHAR_MIN
6861 {"SC_CHAR_MIN", _SC_CHAR_MIN},
6862#endif
6863#ifdef _SC_CHILD_MAX
6864 {"SC_CHILD_MAX", _SC_CHILD_MAX},
6865#endif
6866#ifdef _SC_CLK_TCK
6867 {"SC_CLK_TCK", _SC_CLK_TCK},
6868#endif
6869#ifdef _SC_COHER_BLKSZ
6870 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
6871#endif
6872#ifdef _SC_COLL_WEIGHTS_MAX
6873 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
6874#endif
6875#ifdef _SC_DCACHE_ASSOC
6876 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
6877#endif
6878#ifdef _SC_DCACHE_BLKSZ
6879 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
6880#endif
6881#ifdef _SC_DCACHE_LINESZ
6882 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
6883#endif
6884#ifdef _SC_DCACHE_SZ
6885 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
6886#endif
6887#ifdef _SC_DCACHE_TBLKSZ
6888 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
6889#endif
6890#ifdef _SC_DELAYTIMER_MAX
6891 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
6892#endif
6893#ifdef _SC_EQUIV_CLASS_MAX
6894 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
6895#endif
6896#ifdef _SC_EXPR_NEST_MAX
6897 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
6898#endif
6899#ifdef _SC_FSYNC
6900 {"SC_FSYNC", _SC_FSYNC},
6901#endif
6902#ifdef _SC_GETGR_R_SIZE_MAX
6903 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
6904#endif
6905#ifdef _SC_GETPW_R_SIZE_MAX
6906 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
6907#endif
6908#ifdef _SC_ICACHE_ASSOC
6909 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
6910#endif
6911#ifdef _SC_ICACHE_BLKSZ
6912 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
6913#endif
6914#ifdef _SC_ICACHE_LINESZ
6915 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
6916#endif
6917#ifdef _SC_ICACHE_SZ
6918 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
6919#endif
Fred Draked86ed291999-12-15 15:34:33 +00006920#ifdef _SC_INF
6921 {"SC_INF", _SC_INF},
6922#endif
Fred Drakec9680921999-12-13 16:37:25 +00006923#ifdef _SC_INT_MAX
6924 {"SC_INT_MAX", _SC_INT_MAX},
6925#endif
6926#ifdef _SC_INT_MIN
6927 {"SC_INT_MIN", _SC_INT_MIN},
6928#endif
6929#ifdef _SC_IOV_MAX
6930 {"SC_IOV_MAX", _SC_IOV_MAX},
6931#endif
Fred Draked86ed291999-12-15 15:34:33 +00006932#ifdef _SC_IP_SECOPTS
6933 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
6934#endif
Fred Drakec9680921999-12-13 16:37:25 +00006935#ifdef _SC_JOB_CONTROL
6936 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
6937#endif
Fred Draked86ed291999-12-15 15:34:33 +00006938#ifdef _SC_KERN_POINTERS
6939 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
6940#endif
6941#ifdef _SC_KERN_SIM
6942 {"SC_KERN_SIM", _SC_KERN_SIM},
6943#endif
Fred Drakec9680921999-12-13 16:37:25 +00006944#ifdef _SC_LINE_MAX
6945 {"SC_LINE_MAX", _SC_LINE_MAX},
6946#endif
6947#ifdef _SC_LOGIN_NAME_MAX
6948 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
6949#endif
6950#ifdef _SC_LOGNAME_MAX
6951 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
6952#endif
6953#ifdef _SC_LONG_BIT
6954 {"SC_LONG_BIT", _SC_LONG_BIT},
6955#endif
Fred Draked86ed291999-12-15 15:34:33 +00006956#ifdef _SC_MAC
6957 {"SC_MAC", _SC_MAC},
6958#endif
Fred Drakec9680921999-12-13 16:37:25 +00006959#ifdef _SC_MAPPED_FILES
6960 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
6961#endif
6962#ifdef _SC_MAXPID
6963 {"SC_MAXPID", _SC_MAXPID},
6964#endif
6965#ifdef _SC_MB_LEN_MAX
6966 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
6967#endif
6968#ifdef _SC_MEMLOCK
6969 {"SC_MEMLOCK", _SC_MEMLOCK},
6970#endif
6971#ifdef _SC_MEMLOCK_RANGE
6972 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
6973#endif
6974#ifdef _SC_MEMORY_PROTECTION
6975 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
6976#endif
6977#ifdef _SC_MESSAGE_PASSING
6978 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
6979#endif
Fred Draked86ed291999-12-15 15:34:33 +00006980#ifdef _SC_MMAP_FIXED_ALIGNMENT
6981 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
6982#endif
Fred Drakec9680921999-12-13 16:37:25 +00006983#ifdef _SC_MQ_OPEN_MAX
6984 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
6985#endif
6986#ifdef _SC_MQ_PRIO_MAX
6987 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
6988#endif
Fred Draked86ed291999-12-15 15:34:33 +00006989#ifdef _SC_NACLS_MAX
6990 {"SC_NACLS_MAX", _SC_NACLS_MAX},
6991#endif
Fred Drakec9680921999-12-13 16:37:25 +00006992#ifdef _SC_NGROUPS_MAX
6993 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
6994#endif
6995#ifdef _SC_NL_ARGMAX
6996 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
6997#endif
6998#ifdef _SC_NL_LANGMAX
6999 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
7000#endif
7001#ifdef _SC_NL_MSGMAX
7002 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
7003#endif
7004#ifdef _SC_NL_NMAX
7005 {"SC_NL_NMAX", _SC_NL_NMAX},
7006#endif
7007#ifdef _SC_NL_SETMAX
7008 {"SC_NL_SETMAX", _SC_NL_SETMAX},
7009#endif
7010#ifdef _SC_NL_TEXTMAX
7011 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
7012#endif
7013#ifdef _SC_NPROCESSORS_CONF
7014 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
7015#endif
7016#ifdef _SC_NPROCESSORS_ONLN
7017 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
7018#endif
Fred Draked86ed291999-12-15 15:34:33 +00007019#ifdef _SC_NPROC_CONF
7020 {"SC_NPROC_CONF", _SC_NPROC_CONF},
7021#endif
7022#ifdef _SC_NPROC_ONLN
7023 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
7024#endif
Fred Drakec9680921999-12-13 16:37:25 +00007025#ifdef _SC_NZERO
7026 {"SC_NZERO", _SC_NZERO},
7027#endif
7028#ifdef _SC_OPEN_MAX
7029 {"SC_OPEN_MAX", _SC_OPEN_MAX},
7030#endif
7031#ifdef _SC_PAGESIZE
7032 {"SC_PAGESIZE", _SC_PAGESIZE},
7033#endif
7034#ifdef _SC_PAGE_SIZE
7035 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
7036#endif
7037#ifdef _SC_PASS_MAX
7038 {"SC_PASS_MAX", _SC_PASS_MAX},
7039#endif
7040#ifdef _SC_PHYS_PAGES
7041 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
7042#endif
7043#ifdef _SC_PII
7044 {"SC_PII", _SC_PII},
7045#endif
7046#ifdef _SC_PII_INTERNET
7047 {"SC_PII_INTERNET", _SC_PII_INTERNET},
7048#endif
7049#ifdef _SC_PII_INTERNET_DGRAM
7050 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
7051#endif
7052#ifdef _SC_PII_INTERNET_STREAM
7053 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
7054#endif
7055#ifdef _SC_PII_OSI
7056 {"SC_PII_OSI", _SC_PII_OSI},
7057#endif
7058#ifdef _SC_PII_OSI_CLTS
7059 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
7060#endif
7061#ifdef _SC_PII_OSI_COTS
7062 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
7063#endif
7064#ifdef _SC_PII_OSI_M
7065 {"SC_PII_OSI_M", _SC_PII_OSI_M},
7066#endif
7067#ifdef _SC_PII_SOCKET
7068 {"SC_PII_SOCKET", _SC_PII_SOCKET},
7069#endif
7070#ifdef _SC_PII_XTI
7071 {"SC_PII_XTI", _SC_PII_XTI},
7072#endif
7073#ifdef _SC_POLL
7074 {"SC_POLL", _SC_POLL},
7075#endif
7076#ifdef _SC_PRIORITIZED_IO
7077 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
7078#endif
7079#ifdef _SC_PRIORITY_SCHEDULING
7080 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
7081#endif
7082#ifdef _SC_REALTIME_SIGNALS
7083 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
7084#endif
7085#ifdef _SC_RE_DUP_MAX
7086 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
7087#endif
7088#ifdef _SC_RTSIG_MAX
7089 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
7090#endif
7091#ifdef _SC_SAVED_IDS
7092 {"SC_SAVED_IDS", _SC_SAVED_IDS},
7093#endif
7094#ifdef _SC_SCHAR_MAX
7095 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
7096#endif
7097#ifdef _SC_SCHAR_MIN
7098 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
7099#endif
7100#ifdef _SC_SELECT
7101 {"SC_SELECT", _SC_SELECT},
7102#endif
7103#ifdef _SC_SEMAPHORES
7104 {"SC_SEMAPHORES", _SC_SEMAPHORES},
7105#endif
7106#ifdef _SC_SEM_NSEMS_MAX
7107 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
7108#endif
7109#ifdef _SC_SEM_VALUE_MAX
7110 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
7111#endif
7112#ifdef _SC_SHARED_MEMORY_OBJECTS
7113 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
7114#endif
7115#ifdef _SC_SHRT_MAX
7116 {"SC_SHRT_MAX", _SC_SHRT_MAX},
7117#endif
7118#ifdef _SC_SHRT_MIN
7119 {"SC_SHRT_MIN", _SC_SHRT_MIN},
7120#endif
7121#ifdef _SC_SIGQUEUE_MAX
7122 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
7123#endif
7124#ifdef _SC_SIGRT_MAX
7125 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
7126#endif
7127#ifdef _SC_SIGRT_MIN
7128 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
7129#endif
Fred Draked86ed291999-12-15 15:34:33 +00007130#ifdef _SC_SOFTPOWER
7131 {"SC_SOFTPOWER", _SC_SOFTPOWER},
7132#endif
Fred Drakec9680921999-12-13 16:37:25 +00007133#ifdef _SC_SPLIT_CACHE
7134 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
7135#endif
7136#ifdef _SC_SSIZE_MAX
7137 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
7138#endif
7139#ifdef _SC_STACK_PROT
7140 {"SC_STACK_PROT", _SC_STACK_PROT},
7141#endif
7142#ifdef _SC_STREAM_MAX
7143 {"SC_STREAM_MAX", _SC_STREAM_MAX},
7144#endif
7145#ifdef _SC_SYNCHRONIZED_IO
7146 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
7147#endif
7148#ifdef _SC_THREADS
7149 {"SC_THREADS", _SC_THREADS},
7150#endif
7151#ifdef _SC_THREAD_ATTR_STACKADDR
7152 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
7153#endif
7154#ifdef _SC_THREAD_ATTR_STACKSIZE
7155 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
7156#endif
7157#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
7158 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
7159#endif
7160#ifdef _SC_THREAD_KEYS_MAX
7161 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
7162#endif
7163#ifdef _SC_THREAD_PRIORITY_SCHEDULING
7164 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
7165#endif
7166#ifdef _SC_THREAD_PRIO_INHERIT
7167 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
7168#endif
7169#ifdef _SC_THREAD_PRIO_PROTECT
7170 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
7171#endif
7172#ifdef _SC_THREAD_PROCESS_SHARED
7173 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
7174#endif
7175#ifdef _SC_THREAD_SAFE_FUNCTIONS
7176 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
7177#endif
7178#ifdef _SC_THREAD_STACK_MIN
7179 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
7180#endif
7181#ifdef _SC_THREAD_THREADS_MAX
7182 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
7183#endif
7184#ifdef _SC_TIMERS
7185 {"SC_TIMERS", _SC_TIMERS},
7186#endif
7187#ifdef _SC_TIMER_MAX
7188 {"SC_TIMER_MAX", _SC_TIMER_MAX},
7189#endif
7190#ifdef _SC_TTY_NAME_MAX
7191 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
7192#endif
7193#ifdef _SC_TZNAME_MAX
7194 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
7195#endif
7196#ifdef _SC_T_IOV_MAX
7197 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
7198#endif
7199#ifdef _SC_UCHAR_MAX
7200 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
7201#endif
7202#ifdef _SC_UINT_MAX
7203 {"SC_UINT_MAX", _SC_UINT_MAX},
7204#endif
7205#ifdef _SC_UIO_MAXIOV
7206 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
7207#endif
7208#ifdef _SC_ULONG_MAX
7209 {"SC_ULONG_MAX", _SC_ULONG_MAX},
7210#endif
7211#ifdef _SC_USHRT_MAX
7212 {"SC_USHRT_MAX", _SC_USHRT_MAX},
7213#endif
7214#ifdef _SC_VERSION
7215 {"SC_VERSION", _SC_VERSION},
7216#endif
7217#ifdef _SC_WORD_BIT
7218 {"SC_WORD_BIT", _SC_WORD_BIT},
7219#endif
7220#ifdef _SC_XBS5_ILP32_OFF32
7221 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
7222#endif
7223#ifdef _SC_XBS5_ILP32_OFFBIG
7224 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
7225#endif
7226#ifdef _SC_XBS5_LP64_OFF64
7227 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
7228#endif
7229#ifdef _SC_XBS5_LPBIG_OFFBIG
7230 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
7231#endif
7232#ifdef _SC_XOPEN_CRYPT
7233 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
7234#endif
7235#ifdef _SC_XOPEN_ENH_I18N
7236 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
7237#endif
7238#ifdef _SC_XOPEN_LEGACY
7239 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
7240#endif
7241#ifdef _SC_XOPEN_REALTIME
7242 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
7243#endif
7244#ifdef _SC_XOPEN_REALTIME_THREADS
7245 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
7246#endif
7247#ifdef _SC_XOPEN_SHM
7248 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
7249#endif
7250#ifdef _SC_XOPEN_UNIX
7251 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
7252#endif
7253#ifdef _SC_XOPEN_VERSION
7254 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
7255#endif
7256#ifdef _SC_XOPEN_XCU_VERSION
7257 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
7258#endif
7259#ifdef _SC_XOPEN_XPG2
7260 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
7261#endif
7262#ifdef _SC_XOPEN_XPG3
7263 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
7264#endif
7265#ifdef _SC_XOPEN_XPG4
7266 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
7267#endif
7268};
7269
7270static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007271conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007272{
7273 return conv_confname(arg, valuep, posix_constants_sysconf,
7274 sizeof(posix_constants_sysconf)
7275 / sizeof(struct constdef));
7276}
7277
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007278PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007279"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007280Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007281
7282static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007283posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007284{
7285 PyObject *result = NULL;
7286 int name;
7287
7288 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
7289 int value;
7290
7291 errno = 0;
7292 value = sysconf(name);
7293 if (value == -1 && errno != 0)
7294 posix_error();
7295 else
7296 result = PyInt_FromLong(value);
7297 }
7298 return result;
7299}
7300#endif
7301
7302
Fred Drakebec628d1999-12-15 18:31:10 +00007303/* This code is used to ensure that the tables of configuration value names
7304 * are in sorted order as required by conv_confname(), and also to build the
7305 * the exported dictionaries that are used to publish information about the
7306 * names available on the host platform.
7307 *
7308 * Sorting the table at runtime ensures that the table is properly ordered
7309 * when used, even for platforms we're not able to test on. It also makes
7310 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00007311 */
Fred Drakebec628d1999-12-15 18:31:10 +00007312
7313static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007314cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00007315{
7316 const struct constdef *c1 =
7317 (const struct constdef *) v1;
7318 const struct constdef *c2 =
7319 (const struct constdef *) v2;
7320
7321 return strcmp(c1->name, c2->name);
7322}
7323
7324static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007325setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00007326 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007327{
Fred Drakebec628d1999-12-15 18:31:10 +00007328 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00007329 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00007330
7331 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
7332 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00007333 if (d == NULL)
7334 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007335
Barry Warsaw3155db32000-04-13 15:20:40 +00007336 for (i=0; i < tablesize; ++i) {
7337 PyObject *o = PyInt_FromLong(table[i].value);
7338 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
7339 Py_XDECREF(o);
7340 Py_DECREF(d);
7341 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007342 }
Barry Warsaw3155db32000-04-13 15:20:40 +00007343 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00007344 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00007345 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00007346}
7347
Fred Drakebec628d1999-12-15 18:31:10 +00007348/* Return -1 on failure, 0 on success. */
7349static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007350setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007351{
7352#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00007353 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00007354 sizeof(posix_constants_pathconf)
7355 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007356 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007357 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007358#endif
7359#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00007360 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00007361 sizeof(posix_constants_confstr)
7362 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007363 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007364 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007365#endif
7366#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00007367 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00007368 sizeof(posix_constants_sysconf)
7369 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007370 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007371 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007372#endif
Fred Drakebec628d1999-12-15 18:31:10 +00007373 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00007374}
Fred Draked86ed291999-12-15 15:34:33 +00007375
7376
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007377PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007378"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007379Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007380in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007381
7382static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007383posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007384{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007385 abort();
7386 /*NOTREACHED*/
7387 Py_FatalError("abort() called from Python code didn't abort!");
7388 return NULL;
7389}
Fred Drakebec628d1999-12-15 18:31:10 +00007390
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007391#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007392PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00007393"startfile(filepath [, operation]) - Start a file with its associated\n\
7394application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007395\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00007396When \"operation\" is not specified or \"open\", this acts like\n\
7397double-clicking the file in Explorer, or giving the file name as an\n\
7398argument to the DOS \"start\" command: the file is opened with whatever\n\
7399application (if any) its extension is associated.\n\
7400When another \"operation\" is given, it specifies what should be done with\n\
7401the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007402\n\
7403startfile returns as soon as the associated application is launched.\n\
7404There is no option to wait for the application to close, and no way\n\
7405to retrieve the application's exit status.\n\
7406\n\
7407The filepath is relative to the current directory. If you want to use\n\
7408an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007409the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00007410
7411static PyObject *
7412win32_startfile(PyObject *self, PyObject *args)
7413{
7414 char *filepath;
Georg Brandlf4f44152006-02-18 22:29:33 +00007415 char *operation = NULL;
Tim Petersf58a7aa2000-09-22 10:05:54 +00007416 HINSTANCE rc;
Georg Brandlf4f44152006-02-18 22:29:33 +00007417 if (!PyArg_ParseTuple(args, "et|s:startfile",
7418 Py_FileSystemDefaultEncoding, &filepath,
7419 &operation))
Tim Petersf58a7aa2000-09-22 10:05:54 +00007420 return NULL;
7421 Py_BEGIN_ALLOW_THREADS
Georg Brandlf4f44152006-02-18 22:29:33 +00007422 rc = ShellExecute((HWND)0, operation, filepath,
7423 NULL, NULL, SW_SHOWNORMAL);
Tim Petersf58a7aa2000-09-22 10:05:54 +00007424 Py_END_ALLOW_THREADS
Georg Brandle9f8ec92005-09-25 06:16:40 +00007425 if (rc <= (HINSTANCE)32) {
7426 PyObject *errval = win32_error("startfile", filepath);
7427 PyMem_Free(filepath);
7428 return errval;
7429 }
7430 PyMem_Free(filepath);
Tim Petersf58a7aa2000-09-22 10:05:54 +00007431 Py_INCREF(Py_None);
7432 return Py_None;
7433}
7434#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007435
Martin v. Löwis438b5342002-12-27 10:16:42 +00007436#ifdef HAVE_GETLOADAVG
7437PyDoc_STRVAR(posix_getloadavg__doc__,
7438"getloadavg() -> (float, float, float)\n\n\
7439Return the number of processes in the system run queue averaged over\n\
7440the last 1, 5, and 15 minutes or raises OSError if the load average\n\
7441was unobtainable");
7442
7443static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007444posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00007445{
7446 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00007447 if (getloadavg(loadavg, 3)!=3) {
7448 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
7449 return NULL;
7450 } else
7451 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
7452}
7453#endif
7454
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007455#ifdef MS_WINDOWS
7456
7457PyDoc_STRVAR(win32_urandom__doc__,
7458"urandom(n) -> str\n\n\
7459Return a string of n random bytes suitable for cryptographic use.");
7460
7461typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
7462 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
7463 DWORD dwFlags );
7464typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
7465 BYTE *pbBuffer );
7466
7467static CRYPTGENRANDOM pCryptGenRandom = NULL;
7468static HCRYPTPROV hCryptProv = 0;
7469
Tim Peters4ad82172004-08-30 17:02:04 +00007470static PyObject*
7471win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007472{
Tim Petersd3115382004-08-30 17:36:46 +00007473 int howMany;
7474 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007475
Tim Peters4ad82172004-08-30 17:02:04 +00007476 /* Read arguments */
Tim Peters9b279a82004-08-30 17:10:53 +00007477 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
Tim Peters4ad82172004-08-30 17:02:04 +00007478 return NULL;
Tim Peters51eba612004-08-30 17:08:02 +00007479 if (howMany < 0)
7480 return PyErr_Format(PyExc_ValueError,
7481 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007482
Tim Peters4ad82172004-08-30 17:02:04 +00007483 if (hCryptProv == 0) {
7484 HINSTANCE hAdvAPI32 = NULL;
7485 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007486
Tim Peters4ad82172004-08-30 17:02:04 +00007487 /* Obtain handle to the DLL containing CryptoAPI
7488 This should not fail */
7489 hAdvAPI32 = GetModuleHandle("advapi32.dll");
7490 if(hAdvAPI32 == NULL)
7491 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007492
Tim Peters4ad82172004-08-30 17:02:04 +00007493 /* Obtain pointers to the CryptoAPI functions
7494 This will fail on some early versions of Win95 */
7495 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
7496 hAdvAPI32,
7497 "CryptAcquireContextA");
7498 if (pCryptAcquireContext == NULL)
7499 return PyErr_Format(PyExc_NotImplementedError,
7500 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007501
Tim Peters4ad82172004-08-30 17:02:04 +00007502 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
7503 hAdvAPI32, "CryptGenRandom");
7504 if (pCryptAcquireContext == NULL)
7505 return PyErr_Format(PyExc_NotImplementedError,
7506 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007507
Tim Peters4ad82172004-08-30 17:02:04 +00007508 /* Acquire context */
7509 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
7510 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
7511 return win32_error("CryptAcquireContext", NULL);
7512 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007513
Tim Peters4ad82172004-08-30 17:02:04 +00007514 /* Allocate bytes */
Tim Petersd3115382004-08-30 17:36:46 +00007515 result = PyString_FromStringAndSize(NULL, howMany);
7516 if (result != NULL) {
7517 /* Get random data */
7518 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
7519 PyString_AS_STRING(result))) {
7520 Py_DECREF(result);
7521 return win32_error("CryptGenRandom", NULL);
7522 }
Tim Peters4ad82172004-08-30 17:02:04 +00007523 }
Tim Petersd3115382004-08-30 17:36:46 +00007524 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007525}
7526#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007527
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007528static PyMethodDef posix_methods[] = {
7529 {"access", posix_access, METH_VARARGS, posix_access__doc__},
7530#ifdef HAVE_TTYNAME
7531 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
7532#endif
7533 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
7534 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007535#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007536 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007537#endif /* HAVE_CHOWN */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007538#ifdef HAVE_LCHOWN
7539 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
7540#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00007541#ifdef HAVE_CHROOT
7542 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
7543#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007544#ifdef HAVE_CTERMID
Neal Norwitze241ce82003-02-17 18:17:05 +00007545 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007546#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00007547#ifdef HAVE_GETCWD
Neal Norwitze241ce82003-02-17 18:17:05 +00007548 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Walter Dörwald3b918c32002-11-21 20:18:46 +00007549#ifdef Py_USING_UNICODE
Neal Norwitze241ce82003-02-17 18:17:05 +00007550 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00007551#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00007552#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007553#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007554 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007555#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007556 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
7557 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
7558 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007559#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007560 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007561#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007562#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007563 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007564#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007565 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
7566 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
7567 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007568 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007569#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007570 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007571#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007572#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007573 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007574#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007575 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007576#ifdef HAVE_UNAME
Neal Norwitze241ce82003-02-17 18:17:05 +00007577 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007578#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007579 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
7580 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
7581 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007582#ifdef HAVE_TIMES
Neal Norwitze241ce82003-02-17 18:17:05 +00007583 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007584#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007585 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007586#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007587 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
7588 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007589#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00007590#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007591 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
7592 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00007593#if defined(PYOS_OS2)
7594 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
7595 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
7596#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00007597#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007598#ifdef HAVE_FORK1
Neal Norwitze241ce82003-02-17 18:17:05 +00007599 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007600#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007601#ifdef HAVE_FORK
Neal Norwitze241ce82003-02-17 18:17:05 +00007602 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007603#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007604#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Neal Norwitze241ce82003-02-17 18:17:05 +00007605 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007606#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007607#ifdef HAVE_FORKPTY
Neal Norwitze241ce82003-02-17 18:17:05 +00007608 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00007609#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007610#ifdef HAVE_GETEGID
Neal Norwitze241ce82003-02-17 18:17:05 +00007611 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007612#endif /* HAVE_GETEGID */
7613#ifdef HAVE_GETEUID
Neal Norwitze241ce82003-02-17 18:17:05 +00007614 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007615#endif /* HAVE_GETEUID */
7616#ifdef HAVE_GETGID
Neal Norwitze241ce82003-02-17 18:17:05 +00007617 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007618#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00007619#ifdef HAVE_GETGROUPS
Neal Norwitze241ce82003-02-17 18:17:05 +00007620 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007621#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007622 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007623#ifdef HAVE_GETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00007624 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007625#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007626#ifdef HAVE_GETPPID
Neal Norwitze241ce82003-02-17 18:17:05 +00007627 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007628#endif /* HAVE_GETPPID */
7629#ifdef HAVE_GETUID
Neal Norwitze241ce82003-02-17 18:17:05 +00007630 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007631#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007632#ifdef HAVE_GETLOGIN
Neal Norwitze241ce82003-02-17 18:17:05 +00007633 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00007634#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00007635#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007636 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007637#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007638#ifdef HAVE_KILLPG
7639 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
7640#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00007641#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007642 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00007643#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007644#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007645 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007646#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00007647 {"popen2", win32_popen2, METH_VARARGS},
7648 {"popen3", win32_popen3, METH_VARARGS},
7649 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00007650 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007651#else
7652#if defined(PYOS_OS2) && defined(PYCC_GCC)
7653 {"popen2", os2emx_popen2, METH_VARARGS},
7654 {"popen3", os2emx_popen3, METH_VARARGS},
7655 {"popen4", os2emx_popen4, METH_VARARGS},
7656#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00007657#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007658#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007659#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007660 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007661#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007662#ifdef HAVE_SETEUID
7663 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
7664#endif /* HAVE_SETEUID */
7665#ifdef HAVE_SETEGID
7666 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
7667#endif /* HAVE_SETEGID */
7668#ifdef HAVE_SETREUID
7669 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
7670#endif /* HAVE_SETREUID */
7671#ifdef HAVE_SETREGID
7672 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
7673#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007674#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007675 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007676#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007677#ifdef HAVE_SETGROUPS
7678 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
7679#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00007680#ifdef HAVE_GETPGID
7681 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
7682#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007683#ifdef HAVE_SETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00007684 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007685#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007686#ifdef HAVE_WAIT
Neal Norwitze241ce82003-02-17 18:17:05 +00007687 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007688#endif /* HAVE_WAIT */
Tim Petersab034fa2002-02-01 11:27:43 +00007689#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007690 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007691#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007692#ifdef HAVE_GETSID
7693 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
7694#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007695#ifdef HAVE_SETSID
Neal Norwitze241ce82003-02-17 18:17:05 +00007696 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007697#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007698#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007699 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007700#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007701#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007702 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007703#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007704#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007705 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007706#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007707 {"open", posix_open, METH_VARARGS, posix_open__doc__},
7708 {"close", posix_close, METH_VARARGS, posix_close__doc__},
7709 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
7710 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
7711 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
7712 {"read", posix_read, METH_VARARGS, posix_read__doc__},
7713 {"write", posix_write, METH_VARARGS, posix_write__doc__},
7714 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
7715 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00007716 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007717#ifdef HAVE_PIPE
Neal Norwitze241ce82003-02-17 18:17:05 +00007718 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007719#endif
7720#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007721 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007722#endif
Neal Norwitz11690112002-07-30 01:08:28 +00007723#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007724 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
7725#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007726#ifdef HAVE_DEVICE_MACROS
7727 {"major", posix_major, METH_VARARGS, posix_major__doc__},
7728 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
7729 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
7730#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007731#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007732 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007733#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007734#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007735 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007736#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007737#ifdef HAVE_UNSETENV
7738 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
7739#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00007740#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007741 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00007742#endif
Fred Drake4d1e64b2002-04-15 19:40:07 +00007743#ifdef HAVE_FCHDIR
7744 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
7745#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00007746#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007747 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007748#endif
7749#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007750 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007751#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00007752#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00007753#ifdef WCOREDUMP
7754 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
7755#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007756#ifdef WIFCONTINUED
7757 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
7758#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00007759#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007760 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007761#endif /* WIFSTOPPED */
7762#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007763 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007764#endif /* WIFSIGNALED */
7765#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007766 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007767#endif /* WIFEXITED */
7768#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007769 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007770#endif /* WEXITSTATUS */
7771#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007772 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007773#endif /* WTERMSIG */
7774#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007775 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007776#endif /* WSTOPSIG */
7777#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007778#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007779 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007780#endif
7781#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007782 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007783#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00007784#ifdef HAVE_TMPFILE
Neal Norwitze241ce82003-02-17 18:17:05 +00007785 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007786#endif
7787#ifdef HAVE_TEMPNAM
7788 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
7789#endif
7790#ifdef HAVE_TMPNAM
Neal Norwitze241ce82003-02-17 18:17:05 +00007791 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007792#endif
Fred Drakec9680921999-12-13 16:37:25 +00007793#ifdef HAVE_CONFSTR
7794 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
7795#endif
7796#ifdef HAVE_SYSCONF
7797 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
7798#endif
7799#ifdef HAVE_FPATHCONF
7800 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
7801#endif
7802#ifdef HAVE_PATHCONF
7803 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
7804#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007805 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007806#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00007807 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
7808#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007809#ifdef HAVE_GETLOADAVG
Neal Norwitze241ce82003-02-17 18:17:05 +00007810 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00007811#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007812 #ifdef MS_WINDOWS
7813 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
7814 #endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007815 {NULL, NULL} /* Sentinel */
7816};
7817
7818
Barry Warsaw4a342091996-12-19 23:50:02 +00007819static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007820ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00007821{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007822 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00007823}
7824
Guido van Rossumd48f2521997-12-05 22:19:34 +00007825#if defined(PYOS_OS2)
7826/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007827static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007828{
7829 APIRET rc;
7830 ULONG values[QSV_MAX+1];
7831 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00007832 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00007833
7834 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00007835 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007836 Py_END_ALLOW_THREADS
7837
7838 if (rc != NO_ERROR) {
7839 os2_error(rc);
7840 return -1;
7841 }
7842
Fred Drake4d1e64b2002-04-15 19:40:07 +00007843 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
7844 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
7845 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
7846 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
7847 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
7848 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
7849 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007850
7851 switch (values[QSV_VERSION_MINOR]) {
7852 case 0: ver = "2.00"; break;
7853 case 10: ver = "2.10"; break;
7854 case 11: ver = "2.11"; break;
7855 case 30: ver = "3.00"; break;
7856 case 40: ver = "4.00"; break;
7857 case 50: ver = "5.00"; break;
7858 default:
Tim Peters885d4572001-11-28 20:27:42 +00007859 PyOS_snprintf(tmp, sizeof(tmp),
7860 "%d-%d", values[QSV_VERSION_MAJOR],
7861 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007862 ver = &tmp[0];
7863 }
7864
7865 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007866 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007867 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007868
7869 /* Add Indicator of Which Drive was Used to Boot the System */
7870 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
7871 tmp[1] = ':';
7872 tmp[2] = '\0';
7873
Fred Drake4d1e64b2002-04-15 19:40:07 +00007874 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007875}
7876#endif
7877
Barry Warsaw4a342091996-12-19 23:50:02 +00007878static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007879all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00007880{
Guido van Rossum94f6f721999-01-06 18:42:14 +00007881#ifdef F_OK
7882 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007883#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007884#ifdef R_OK
7885 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007886#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007887#ifdef W_OK
7888 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007889#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007890#ifdef X_OK
7891 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007892#endif
Fred Drakec9680921999-12-13 16:37:25 +00007893#ifdef NGROUPS_MAX
7894 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
7895#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007896#ifdef TMP_MAX
7897 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
7898#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007899#ifdef WCONTINUED
7900 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
7901#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007902#ifdef WNOHANG
7903 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007904#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007905#ifdef WUNTRACED
7906 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
7907#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007908#ifdef O_RDONLY
7909 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
7910#endif
7911#ifdef O_WRONLY
7912 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
7913#endif
7914#ifdef O_RDWR
7915 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
7916#endif
7917#ifdef O_NDELAY
7918 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
7919#endif
7920#ifdef O_NONBLOCK
7921 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
7922#endif
7923#ifdef O_APPEND
7924 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
7925#endif
7926#ifdef O_DSYNC
7927 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
7928#endif
7929#ifdef O_RSYNC
7930 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
7931#endif
7932#ifdef O_SYNC
7933 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
7934#endif
7935#ifdef O_NOCTTY
7936 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
7937#endif
7938#ifdef O_CREAT
7939 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
7940#endif
7941#ifdef O_EXCL
7942 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
7943#endif
7944#ifdef O_TRUNC
7945 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
7946#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00007947#ifdef O_BINARY
7948 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
7949#endif
7950#ifdef O_TEXT
7951 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
7952#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007953#ifdef O_LARGEFILE
7954 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
7955#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00007956#ifdef O_SHLOCK
7957 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
7958#endif
7959#ifdef O_EXLOCK
7960 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
7961#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007962
Tim Peters5aa91602002-01-30 05:46:57 +00007963/* MS Windows */
7964#ifdef O_NOINHERIT
7965 /* Don't inherit in child processes. */
7966 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
7967#endif
7968#ifdef _O_SHORT_LIVED
7969 /* Optimize for short life (keep in memory). */
7970 /* MS forgot to define this one with a non-underscore form too. */
7971 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
7972#endif
7973#ifdef O_TEMPORARY
7974 /* Automatically delete when last handle is closed. */
7975 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
7976#endif
7977#ifdef O_RANDOM
7978 /* Optimize for random access. */
7979 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
7980#endif
7981#ifdef O_SEQUENTIAL
7982 /* Optimize for sequential access. */
7983 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
7984#endif
7985
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007986/* GNU extensions. */
7987#ifdef O_DIRECT
7988 /* Direct disk access. */
7989 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
7990#endif
7991#ifdef O_DIRECTORY
7992 /* Must be a directory. */
7993 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
7994#endif
7995#ifdef O_NOFOLLOW
7996 /* Do not follow links. */
7997 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
7998#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00007999
Barry Warsaw5676bd12003-01-07 20:57:09 +00008000 /* These come from sysexits.h */
8001#ifdef EX_OK
8002 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008003#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008004#ifdef EX_USAGE
8005 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008006#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008007#ifdef EX_DATAERR
8008 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008009#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008010#ifdef EX_NOINPUT
8011 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008012#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008013#ifdef EX_NOUSER
8014 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008015#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008016#ifdef EX_NOHOST
8017 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008018#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008019#ifdef EX_UNAVAILABLE
8020 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008021#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008022#ifdef EX_SOFTWARE
8023 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008024#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008025#ifdef EX_OSERR
8026 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008027#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008028#ifdef EX_OSFILE
8029 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008030#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008031#ifdef EX_CANTCREAT
8032 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008033#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008034#ifdef EX_IOERR
8035 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008036#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008037#ifdef EX_TEMPFAIL
8038 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008039#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008040#ifdef EX_PROTOCOL
8041 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008042#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008043#ifdef EX_NOPERM
8044 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008045#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008046#ifdef EX_CONFIG
8047 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008048#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008049#ifdef EX_NOTFOUND
8050 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008051#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008052
Guido van Rossum246bc171999-02-01 23:54:31 +00008053#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008054#if defined(PYOS_OS2) && defined(PYCC_GCC)
8055 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
8056 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
8057 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
8058 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
8059 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
8060 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
8061 if (ins(d, "P_PM", (long)P_PM)) return -1;
8062 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
8063 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
8064 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
8065 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
8066 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
8067 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
8068 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
8069 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
8070 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
8071 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
8072 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
8073 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
8074 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
8075#else
Guido van Rossum7d385291999-02-16 19:38:04 +00008076 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
8077 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
8078 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
8079 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
8080 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00008081#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008082#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00008083
Guido van Rossumd48f2521997-12-05 22:19:34 +00008084#if defined(PYOS_OS2)
8085 if (insertvalues(d)) return -1;
8086#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008087 return 0;
8088}
8089
8090
Tim Peters5aa91602002-01-30 05:46:57 +00008091#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008092#define INITFUNC initnt
8093#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008094
8095#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008096#define INITFUNC initos2
8097#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008098
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008099#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008100#define INITFUNC initposix
8101#define MODNAME "posix"
8102#endif
8103
Mark Hammondfe51c6d2002-08-02 02:27:13 +00008104PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008105INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00008106{
Fred Drake4d1e64b2002-04-15 19:40:07 +00008107 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00008108
Fred Drake4d1e64b2002-04-15 19:40:07 +00008109 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008110 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00008111 posix__doc__);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00008112 if (m == NULL)
8113 return;
Tim Peters5aa91602002-01-30 05:46:57 +00008114
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008115 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008116 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00008117 Py_XINCREF(v);
8118 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008119 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00008120 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00008121
Fred Drake4d1e64b2002-04-15 19:40:07 +00008122 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00008123 return;
8124
Fred Drake4d1e64b2002-04-15 19:40:07 +00008125 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00008126 return;
8127
Fred Drake4d1e64b2002-04-15 19:40:07 +00008128 Py_INCREF(PyExc_OSError);
8129 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00008130
Guido van Rossumb3d39562000-01-31 18:41:26 +00008131#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00008132 if (posix_putenv_garbage == NULL)
8133 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00008134#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008135
Guido van Rossum14648392001-12-08 18:02:58 +00008136 stat_result_desc.name = MODNAME ".stat_result";
Martin v. Löwisf607bda2002-10-16 18:27:39 +00008137 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
8138 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
8139 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008140 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00008141 structseq_new = StatResultType.tp_new;
8142 StatResultType.tp_new = statresult_new;
Fred Drake4d1e64b2002-04-15 19:40:07 +00008143 Py_INCREF((PyObject*) &StatResultType);
8144 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008145
Guido van Rossum14648392001-12-08 18:02:58 +00008146 statvfs_result_desc.name = MODNAME ".statvfs_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008147 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Fred Drake4d1e64b2002-04-15 19:40:07 +00008148 Py_INCREF((PyObject*) &StatVFSResultType);
8149 PyModule_AddObject(m, "statvfs_result",
8150 (PyObject*) &StatVFSResultType);
Guido van Rossumb6775db1994-08-01 11:34:53 +00008151}