blob: 6949c901b770c605b2990ec32d3cad2ca9f468f7 [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;
Tim Peters67d70eb2006-03-01 04:35:45 +00001904 Py_ssize_t insize = sizeof(inbuf);
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
Tim Peters5aa91602002-01-30 05:46:57 +00001924 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
1925 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00001926 &insize))
1927 return NULL;
1928 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
1929 outbuf, &temp))
1930 return win32_error("GetFullPathName", inbuf);
Martin v. Löwis969297f2004-06-15 18:49:58 +00001931 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
1932 return PyUnicode_Decode(outbuf, strlen(outbuf),
1933 Py_FileSystemDefaultEncoding, NULL);
1934 }
Mark Hammondef8b6542001-05-13 08:04:26 +00001935 return PyString_FromString(outbuf);
1936} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001937#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00001938
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001939PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001940"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001941Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001942
Barry Warsaw53699e91996-12-10 23:23:01 +00001943static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001944posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001945{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001946 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00001947 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001948 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001949
1950#ifdef Py_WIN_WIDE_FILENAMES
1951 if (unicode_file_names()) {
1952 PyUnicodeObject *po;
Mark Hammond05107b62003-02-19 04:08:27 +00001953 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001954 Py_BEGIN_ALLOW_THREADS
1955 /* PyUnicode_AS_UNICODE OK without thread lock as
1956 it is a simple dereference. */
1957 res = _wmkdir(PyUnicode_AS_UNICODE(po));
1958 Py_END_ALLOW_THREADS
1959 if (res < 0)
1960 return posix_error();
1961 Py_INCREF(Py_None);
1962 return Py_None;
1963 }
1964 /* Drop the argument parsing error as narrow strings
1965 are also valid. */
1966 PyErr_Clear();
1967 }
1968#endif
1969
Tim Peters5aa91602002-01-30 05:46:57 +00001970 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001971 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001972 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001973 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001974#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001975 res = mkdir(path);
1976#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001977 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001978#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001979 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001980 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001981 return posix_error_with_allocated_filename(path);
1982 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001983 Py_INCREF(Py_None);
1984 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001985}
1986
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001987
Guido van Rossumb6775db1994-08-01 11:34:53 +00001988#ifdef HAVE_NICE
Thomas Wouterse38b2f12001-07-11 22:35:31 +00001989#if defined(HAVE_BROKEN_NICE) && defined(HAVE_SYS_RESOURCE_H)
1990#if defined(HAVE_GETPRIORITY) && !defined(PRIO_PROCESS)
1991#include <sys/resource.h>
1992#endif
1993#endif
1994
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001995PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001996"nice(inc) -> new_priority\n\n\
1997Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001998
Barry Warsaw53699e91996-12-10 23:23:01 +00001999static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002000posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002001{
2002 int increment, value;
2003
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002004 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00002005 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002006
2007 /* There are two flavours of 'nice': one that returns the new
2008 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002009 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2010 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002011
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002012 If we are of the nice family that returns the new priority, we
2013 need to clear errno before the call, and check if errno is filled
2014 before calling posix_error() on a returnvalue of -1, because the
2015 -1 may be the actual new priority! */
2016
2017 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002018 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002019#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002020 if (value == 0)
2021 value = getpriority(PRIO_PROCESS, 0);
2022#endif
2023 if (value == -1 && errno != 0)
2024 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00002025 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002026 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002027}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002028#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002029
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002030
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002031PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002032"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002033Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002034
Barry Warsaw53699e91996-12-10 23:23:01 +00002035static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002036posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002037{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002038#ifdef MS_WINDOWS
2039 return posix_2str(args, "etet:rename", rename, "OO:rename", _wrename);
2040#else
2041 return posix_2str(args, "etet:rename", rename, NULL, NULL);
2042#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002043}
2044
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002045
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002046PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002047"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002048Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002049
Barry Warsaw53699e91996-12-10 23:23:01 +00002050static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002051posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002052{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002053#ifdef MS_WINDOWS
2054 return posix_1str(args, "et:rmdir", rmdir, "U:rmdir", _wrmdir);
2055#else
2056 return posix_1str(args, "et:rmdir", rmdir, NULL, NULL);
2057#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002058}
2059
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002060
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002061PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002062"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002063Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002064
Barry Warsaw53699e91996-12-10 23:23:01 +00002065static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002066posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002067{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002068#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00002069 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002070#else
2071 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
2072#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002073}
2074
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002075
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002076#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002077PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002078"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002079Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002080
Barry Warsaw53699e91996-12-10 23:23:01 +00002081static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002082posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002083{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002084 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002085 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002086 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002087 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002088 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002089 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00002090 Py_END_ALLOW_THREADS
2091 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002092}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002093#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002094
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002095
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002096PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002097"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002098Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002099
Barry Warsaw53699e91996-12-10 23:23:01 +00002100static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002101posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002102{
2103 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002104 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002105 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00002106 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002107 if (i < 0)
2108 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002109 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002110}
2111
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002112
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002113PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002114"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002115Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002116
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002117PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002118"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002119Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002120
Barry Warsaw53699e91996-12-10 23:23:01 +00002121static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002122posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002123{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002124#ifdef MS_WINDOWS
2125 return posix_1str(args, "et:remove", unlink, "U:remove", _wunlink);
2126#else
2127 return posix_1str(args, "et:remove", unlink, NULL, NULL);
2128#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002129}
2130
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002131
Guido van Rossumb6775db1994-08-01 11:34:53 +00002132#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002133PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002134"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002135Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002136
Barry Warsaw53699e91996-12-10 23:23:01 +00002137static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002138posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002139{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002140 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002141 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00002142
Barry Warsaw53699e91996-12-10 23:23:01 +00002143 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002144 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00002145 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002146 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002147 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002148 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00002149 u.sysname,
2150 u.nodename,
2151 u.release,
2152 u.version,
2153 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002154}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002155#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002156
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002157static int
2158extract_time(PyObject *t, long* sec, long* usec)
2159{
2160 long intval;
2161 if (PyFloat_Check(t)) {
2162 double tval = PyFloat_AsDouble(t);
2163 PyObject *intobj = t->ob_type->tp_as_number->nb_int(t);
2164 if (!intobj)
2165 return -1;
2166 intval = PyInt_AsLong(intobj);
2167 Py_DECREF(intobj);
Michael W. Hudsonb8963812005-07-05 15:21:58 +00002168 if (intval == -1 && PyErr_Occurred())
2169 return -1;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002170 *sec = intval;
Tim Peters96940cf2002-09-10 15:37:28 +00002171 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002172 if (*usec < 0)
2173 /* If rounding gave us a negative number,
2174 truncate. */
2175 *usec = 0;
2176 return 0;
2177 }
2178 intval = PyInt_AsLong(t);
2179 if (intval == -1 && PyErr_Occurred())
2180 return -1;
2181 *sec = intval;
2182 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00002183 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002184}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002185
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002186PyDoc_STRVAR(posix_utime__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002187"utime(path, (atime, utime))\n\
2188utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00002189Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002190second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002191
Barry Warsaw53699e91996-12-10 23:23:01 +00002192static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002193posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002194{
Neal Norwitz2adf2102004-06-09 01:46:02 +00002195 char *path = NULL;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002196 long atime, mtime, ausec, musec;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002197 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002198 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002199
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002200#if defined(HAVE_UTIMES)
2201 struct timeval buf[2];
2202#define ATIME buf[0].tv_sec
2203#define MTIME buf[1].tv_sec
2204#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002205/* XXX should define struct utimbuf instead, above */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002206 struct utimbuf buf;
2207#define ATIME buf.actime
2208#define MTIME buf.modtime
2209#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002210#else /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002211 time_t buf[2];
2212#define ATIME buf[0]
2213#define MTIME buf[1]
2214#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002215#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002216
Mark Hammond817c9292003-12-03 01:22:38 +00002217 int have_unicode_filename = 0;
2218#ifdef Py_WIN_WIDE_FILENAMES
2219 PyUnicodeObject *obwpath;
2220 wchar_t *wpath;
2221 if (unicode_file_names()) {
2222 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
2223 wpath = PyUnicode_AS_UNICODE(obwpath);
2224 have_unicode_filename = 1;
2225 } else
2226 /* Drop the argument parsing error as narrow strings
2227 are also valid. */
2228 PyErr_Clear();
2229 }
2230#endif /* Py_WIN_WIDE_FILENAMES */
2231
2232 if (!have_unicode_filename && \
Hye-Shik Chang2b2c9732004-01-04 13:54:25 +00002233 !PyArg_ParseTuple(args, "etO:utime",
2234 Py_FileSystemDefaultEncoding, &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002235 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002236 if (arg == Py_None) {
2237 /* optional time values not given */
2238 Py_BEGIN_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002239#ifdef Py_WIN_WIDE_FILENAMES
2240 if (have_unicode_filename)
2241 res = _wutime(wpath, NULL);
2242 else
2243#endif /* Py_WIN_WIDE_FILENAMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002244 res = utime(path, NULL);
2245 Py_END_ALLOW_THREADS
2246 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002247 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00002248 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002249 "utime() arg 2 must be a tuple (atime, mtime)");
Neal Norwitz96652712004-06-06 20:40:27 +00002250 PyMem_Free(path);
Barry Warsaw3cef8562000-05-01 16:17:24 +00002251 return NULL;
2252 }
2253 else {
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002254 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Neal Norwitz96652712004-06-06 20:40:27 +00002255 &atime, &ausec) == -1) {
2256 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002257 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002258 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002259 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Neal Norwitz96652712004-06-06 20:40:27 +00002260 &mtime, &musec) == -1) {
2261 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002262 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002263 }
Barry Warsaw3cef8562000-05-01 16:17:24 +00002264 ATIME = atime;
2265 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002266#ifdef HAVE_UTIMES
2267 buf[0].tv_usec = ausec;
2268 buf[1].tv_usec = musec;
2269 Py_BEGIN_ALLOW_THREADS
2270 res = utimes(path, buf);
2271 Py_END_ALLOW_THREADS
2272#else
Barry Warsaw3cef8562000-05-01 16:17:24 +00002273 Py_BEGIN_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002274#ifdef Py_WIN_WIDE_FILENAMES
2275 if (have_unicode_filename)
Tim Peters4ad82172004-08-30 17:02:04 +00002276 /* utime is OK with utimbuf, but _wutime insists
2277 on _utimbuf (the msvc headers assert the
Mark Hammond817c9292003-12-03 01:22:38 +00002278 underscore version is ansi) */
2279 res = _wutime(wpath, (struct _utimbuf *)UTIME_ARG);
2280 else
2281#endif /* Py_WIN_WIDE_FILENAMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002282 res = utime(path, UTIME_ARG);
2283 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002284#endif /* HAVE_UTIMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002285 }
Mark Hammond2d5914b2004-05-04 08:10:37 +00002286 if (res < 0) {
2287#ifdef Py_WIN_WIDE_FILENAMES
Neal Norwitz2adf2102004-06-09 01:46:02 +00002288 if (have_unicode_filename)
Mark Hammond2d5914b2004-05-04 08:10:37 +00002289 return posix_error_with_unicode_filename(wpath);
2290#endif /* Py_WIN_WIDE_FILENAMES */
Neal Norwitz96652712004-06-06 20:40:27 +00002291 return posix_error_with_allocated_filename(path);
Mark Hammond2d5914b2004-05-04 08:10:37 +00002292 }
Neal Norwitz96652712004-06-06 20:40:27 +00002293 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002294 Py_INCREF(Py_None);
2295 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002296#undef UTIME_ARG
2297#undef ATIME
2298#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002299}
2300
Guido van Rossum85e3b011991-06-03 12:42:10 +00002301
Guido van Rossum3b066191991-06-04 19:40:25 +00002302/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002303
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002304PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002305"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002306Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002307
Barry Warsaw53699e91996-12-10 23:23:01 +00002308static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002309posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002310{
2311 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002312 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002313 return NULL;
2314 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00002315 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002316}
2317
Martin v. Löwis114619e2002-10-07 06:44:21 +00002318#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
2319static void
2320free_string_array(char **array, int count)
2321{
2322 int i;
2323 for (i = 0; i < count; i++)
2324 PyMem_Free(array[i]);
2325 PyMem_DEL(array);
2326}
2327#endif
2328
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002329
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002330#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002331PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002332"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002333Execute an executable path with arguments, replacing current process.\n\
2334\n\
2335 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002336 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002337
Barry Warsaw53699e91996-12-10 23:23:01 +00002338static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002339posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002340{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002341 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002342 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002343 char **argvlist;
2344 int i, argc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002345 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002346
Guido van Rossum89b33251993-10-22 14:26:06 +00002347 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00002348 argv is a list or tuple of strings. */
2349
Martin v. Löwis114619e2002-10-07 06:44:21 +00002350 if (!PyArg_ParseTuple(args, "etO:execv",
2351 Py_FileSystemDefaultEncoding,
2352 &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002353 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002354 if (PyList_Check(argv)) {
2355 argc = PyList_Size(argv);
2356 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002357 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002358 else if (PyTuple_Check(argv)) {
2359 argc = PyTuple_Size(argv);
2360 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002361 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002362 else {
Fred Drake661ea262000-10-24 19:57:45 +00002363 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002364 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002365 return NULL;
2366 }
2367
Barry Warsaw53699e91996-12-10 23:23:01 +00002368 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002369 if (argvlist == NULL) {
2370 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002371 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002372 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002373 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002374 if (!PyArg_Parse((*getitem)(argv, i), "et",
2375 Py_FileSystemDefaultEncoding,
2376 &argvlist[i])) {
2377 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00002378 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002379 "execv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002380 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002381 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00002382
Guido van Rossum85e3b011991-06-03 12:42:10 +00002383 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002384 }
2385 argvlist[argc] = NULL;
2386
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002387 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002388
Guido van Rossum85e3b011991-06-03 12:42:10 +00002389 /* If we get here it's definitely an error */
2390
Martin v. Löwis114619e2002-10-07 06:44:21 +00002391 free_string_array(argvlist, argc);
2392 PyMem_Free(path);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002393 return posix_error();
2394}
2395
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002396
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002397PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002398"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002399Execute a path with arguments and environment, replacing current process.\n\
2400\n\
2401 path: path of executable file\n\
2402 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002403 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002404
Barry Warsaw53699e91996-12-10 23:23:01 +00002405static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002406posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002407{
2408 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002409 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002410 char **argvlist;
2411 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002412 PyObject *key, *val, *keys=NULL, *vals=NULL;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002413 int i, pos, argc, envc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002414 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002415 int lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002416
2417 /* execve has three arguments: (path, argv, env), where
2418 argv is a list or tuple of strings and env is a dictionary
2419 like posix.environ. */
2420
Martin v. Löwis114619e2002-10-07 06:44:21 +00002421 if (!PyArg_ParseTuple(args, "etOO:execve",
2422 Py_FileSystemDefaultEncoding,
2423 &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002424 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002425 if (PyList_Check(argv)) {
2426 argc = PyList_Size(argv);
2427 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002428 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002429 else if (PyTuple_Check(argv)) {
2430 argc = PyTuple_Size(argv);
2431 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002432 }
2433 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002434 PyErr_SetString(PyExc_TypeError,
2435 "execve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002436 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002437 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002438 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002439 PyErr_SetString(PyExc_TypeError,
2440 "execve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002441 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002442 }
2443
Barry Warsaw53699e91996-12-10 23:23:01 +00002444 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002445 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002446 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002447 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002448 }
2449 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002450 if (!PyArg_Parse((*getitem)(argv, i),
Martin v. Löwis114619e2002-10-07 06:44:21 +00002451 "et;execve() arg 2 must contain only strings",
Guido van Rossum1e700d22002-10-16 16:52:11 +00002452 Py_FileSystemDefaultEncoding,
Barry Warsaw43d68b81996-12-19 22:10:44 +00002453 &argvlist[i]))
2454 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002455 lastarg = i;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002456 goto fail_1;
2457 }
2458 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002459 lastarg = argc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002460 argvlist[argc] = NULL;
2461
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002462 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002463 if (i < 0)
2464 goto fail_1;
Barry Warsaw53699e91996-12-10 23:23:01 +00002465 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002466 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002467 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002468 goto fail_1;
2469 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002470 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002471 keys = PyMapping_Keys(env);
2472 vals = PyMapping_Values(env);
2473 if (!keys || !vals)
2474 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002475 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2476 PyErr_SetString(PyExc_TypeError,
2477 "execve(): env.keys() or env.values() is not a list");
2478 goto fail_2;
2479 }
Tim Peters5aa91602002-01-30 05:46:57 +00002480
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002481 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002482 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002483 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002484
2485 key = PyList_GetItem(keys, pos);
2486 val = PyList_GetItem(vals, pos);
2487 if (!key || !val)
2488 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002489
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002490 if (!PyArg_Parse(
2491 key,
2492 "s;execve() arg 3 contains a non-string key",
2493 &k) ||
2494 !PyArg_Parse(
2495 val,
2496 "s;execve() arg 3 contains a non-string value",
2497 &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00002498 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002499 goto fail_2;
2500 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00002501
2502#if defined(PYOS_OS2)
2503 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
2504 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
2505#endif
Tim Petersc8996f52001-12-03 20:41:00 +00002506 len = PyString_Size(key) + PyString_Size(val) + 2;
2507 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002508 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002509 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002510 goto fail_2;
2511 }
Tim Petersc8996f52001-12-03 20:41:00 +00002512 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002513 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00002514#if defined(PYOS_OS2)
2515 }
2516#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002517 }
2518 envlist[envc] = 0;
2519
2520 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00002521
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002522 /* If we get here it's definitely an error */
2523
2524 (void) posix_error();
2525
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002526 fail_2:
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002527 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00002528 PyMem_DEL(envlist[envc]);
2529 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002530 fail_1:
2531 free_string_array(argvlist, lastarg);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002532 Py_XDECREF(vals);
2533 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002534 fail_0:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002535 PyMem_Free(path);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002536 return NULL;
2537}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002538#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002539
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002540
Guido van Rossuma1065681999-01-25 23:20:23 +00002541#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002542PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002543"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002544Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002545\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002546 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002547 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002548 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002549
2550static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002551posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002552{
2553 char *path;
2554 PyObject *argv;
2555 char **argvlist;
2556 int mode, i, argc;
Tim Peters79248aa2001-08-29 21:37:10 +00002557 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002558 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00002559
2560 /* spawnv has three arguments: (mode, path, argv), where
2561 argv is a list or tuple of strings. */
2562
Martin v. Löwis114619e2002-10-07 06:44:21 +00002563 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
2564 Py_FileSystemDefaultEncoding,
2565 &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00002566 return NULL;
2567 if (PyList_Check(argv)) {
2568 argc = PyList_Size(argv);
2569 getitem = PyList_GetItem;
2570 }
2571 else if (PyTuple_Check(argv)) {
2572 argc = PyTuple_Size(argv);
2573 getitem = PyTuple_GetItem;
2574 }
2575 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002576 PyErr_SetString(PyExc_TypeError,
2577 "spawnv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002578 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002579 return NULL;
2580 }
2581
2582 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002583 if (argvlist == NULL) {
2584 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002585 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002586 }
Guido van Rossuma1065681999-01-25 23:20:23 +00002587 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002588 if (!PyArg_Parse((*getitem)(argv, i), "et",
2589 Py_FileSystemDefaultEncoding,
2590 &argvlist[i])) {
2591 free_string_array(argvlist, i);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002592 PyErr_SetString(
2593 PyExc_TypeError,
2594 "spawnv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002595 PyMem_Free(path);
Fred Drake137507e2000-06-01 02:02:46 +00002596 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00002597 }
2598 }
2599 argvlist[argc] = NULL;
2600
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002601#if defined(PYOS_OS2) && defined(PYCC_GCC)
2602 Py_BEGIN_ALLOW_THREADS
2603 spawnval = spawnv(mode, path, argvlist);
2604 Py_END_ALLOW_THREADS
2605#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002606 if (mode == _OLD_P_OVERLAY)
2607 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00002608
Tim Peters25059d32001-12-07 20:35:43 +00002609 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002610 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00002611 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002612#endif
Tim Peters5aa91602002-01-30 05:46:57 +00002613
Martin v. Löwis114619e2002-10-07 06:44:21 +00002614 free_string_array(argvlist, argc);
2615 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002616
Fred Drake699f3522000-06-29 21:12:41 +00002617 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002618 return posix_error();
2619 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002620#if SIZEOF_LONG == SIZEOF_VOID_P
2621 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002622#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00002623 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002624#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002625}
2626
2627
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002628PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002629"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002630Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002631\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002632 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002633 path: path of executable file\n\
2634 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002635 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002636
2637static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002638posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002639{
2640 char *path;
2641 PyObject *argv, *env;
2642 char **argvlist;
2643 char **envlist;
2644 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
2645 int mode, i, pos, argc, envc;
Tim Peters79248aa2001-08-29 21:37:10 +00002646 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002647 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002648 int lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002649
2650 /* spawnve has four arguments: (mode, path, argv, env), where
2651 argv is a list or tuple of strings and env is a dictionary
2652 like posix.environ. */
2653
Martin v. Löwis114619e2002-10-07 06:44:21 +00002654 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
2655 Py_FileSystemDefaultEncoding,
2656 &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00002657 return NULL;
2658 if (PyList_Check(argv)) {
2659 argc = PyList_Size(argv);
2660 getitem = PyList_GetItem;
2661 }
2662 else if (PyTuple_Check(argv)) {
2663 argc = PyTuple_Size(argv);
2664 getitem = PyTuple_GetItem;
2665 }
2666 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002667 PyErr_SetString(PyExc_TypeError,
2668 "spawnve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002669 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002670 }
2671 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002672 PyErr_SetString(PyExc_TypeError,
2673 "spawnve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002674 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002675 }
2676
2677 argvlist = PyMem_NEW(char *, argc+1);
2678 if (argvlist == NULL) {
2679 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002680 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002681 }
2682 for (i = 0; i < argc; i++) {
2683 if (!PyArg_Parse((*getitem)(argv, i),
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002684 "et;spawnve() arg 2 must contain only strings",
Martin v. Löwis114619e2002-10-07 06:44:21 +00002685 Py_FileSystemDefaultEncoding,
Guido van Rossuma1065681999-01-25 23:20:23 +00002686 &argvlist[i]))
2687 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002688 lastarg = i;
Guido van Rossuma1065681999-01-25 23:20:23 +00002689 goto fail_1;
2690 }
2691 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002692 lastarg = argc;
Guido van Rossuma1065681999-01-25 23:20:23 +00002693 argvlist[argc] = NULL;
2694
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002695 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002696 if (i < 0)
2697 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00002698 envlist = PyMem_NEW(char *, i + 1);
2699 if (envlist == NULL) {
2700 PyErr_NoMemory();
2701 goto fail_1;
2702 }
2703 envc = 0;
2704 keys = PyMapping_Keys(env);
2705 vals = PyMapping_Values(env);
2706 if (!keys || !vals)
2707 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002708 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2709 PyErr_SetString(PyExc_TypeError,
2710 "spawnve(): env.keys() or env.values() is not a list");
2711 goto fail_2;
2712 }
Tim Peters5aa91602002-01-30 05:46:57 +00002713
Guido van Rossuma1065681999-01-25 23:20:23 +00002714 for (pos = 0; pos < i; pos++) {
2715 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002716 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00002717
2718 key = PyList_GetItem(keys, pos);
2719 val = PyList_GetItem(vals, pos);
2720 if (!key || !val)
2721 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002722
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002723 if (!PyArg_Parse(
2724 key,
2725 "s;spawnve() arg 3 contains a non-string key",
2726 &k) ||
2727 !PyArg_Parse(
2728 val,
2729 "s;spawnve() arg 3 contains a non-string value",
2730 &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00002731 {
2732 goto fail_2;
2733 }
Tim Petersc8996f52001-12-03 20:41:00 +00002734 len = PyString_Size(key) + PyString_Size(val) + 2;
2735 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00002736 if (p == NULL) {
2737 PyErr_NoMemory();
2738 goto fail_2;
2739 }
Tim Petersc8996f52001-12-03 20:41:00 +00002740 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00002741 envlist[envc++] = p;
2742 }
2743 envlist[envc] = 0;
2744
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002745#if defined(PYOS_OS2) && defined(PYCC_GCC)
2746 Py_BEGIN_ALLOW_THREADS
2747 spawnval = spawnve(mode, path, argvlist, envlist);
2748 Py_END_ALLOW_THREADS
2749#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002750 if (mode == _OLD_P_OVERLAY)
2751 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00002752
2753 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002754 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00002755 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002756#endif
Tim Peters25059d32001-12-07 20:35:43 +00002757
Fred Drake699f3522000-06-29 21:12:41 +00002758 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002759 (void) posix_error();
2760 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002761#if SIZEOF_LONG == SIZEOF_VOID_P
2762 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002763#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00002764 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002765#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002766
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002767 fail_2:
Guido van Rossuma1065681999-01-25 23:20:23 +00002768 while (--envc >= 0)
2769 PyMem_DEL(envlist[envc]);
2770 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002771 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002772 free_string_array(argvlist, lastarg);
Guido van Rossuma1065681999-01-25 23:20:23 +00002773 Py_XDECREF(vals);
2774 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002775 fail_0:
2776 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002777 return res;
2778}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00002779
2780/* OS/2 supports spawnvp & spawnvpe natively */
2781#if defined(PYOS_OS2)
2782PyDoc_STRVAR(posix_spawnvp__doc__,
2783"spawnvp(mode, file, args)\n\n\
2784Execute the program 'file' in a new process, using the environment\n\
2785search path to find the file.\n\
2786\n\
2787 mode: mode of process creation\n\
2788 file: executable file name\n\
2789 args: tuple or list of strings");
2790
2791static PyObject *
2792posix_spawnvp(PyObject *self, PyObject *args)
2793{
2794 char *path;
2795 PyObject *argv;
2796 char **argvlist;
2797 int mode, i, argc;
2798 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002799 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00002800
2801 /* spawnvp has three arguments: (mode, path, argv), where
2802 argv is a list or tuple of strings. */
2803
2804 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
2805 Py_FileSystemDefaultEncoding,
2806 &path, &argv))
2807 return NULL;
2808 if (PyList_Check(argv)) {
2809 argc = PyList_Size(argv);
2810 getitem = PyList_GetItem;
2811 }
2812 else if (PyTuple_Check(argv)) {
2813 argc = PyTuple_Size(argv);
2814 getitem = PyTuple_GetItem;
2815 }
2816 else {
2817 PyErr_SetString(PyExc_TypeError,
2818 "spawnvp() arg 2 must be a tuple or list");
2819 PyMem_Free(path);
2820 return NULL;
2821 }
2822
2823 argvlist = PyMem_NEW(char *, argc+1);
2824 if (argvlist == NULL) {
2825 PyMem_Free(path);
2826 return PyErr_NoMemory();
2827 }
2828 for (i = 0; i < argc; i++) {
2829 if (!PyArg_Parse((*getitem)(argv, i), "et",
2830 Py_FileSystemDefaultEncoding,
2831 &argvlist[i])) {
2832 free_string_array(argvlist, i);
2833 PyErr_SetString(
2834 PyExc_TypeError,
2835 "spawnvp() arg 2 must contain only strings");
2836 PyMem_Free(path);
2837 return NULL;
2838 }
2839 }
2840 argvlist[argc] = NULL;
2841
2842 Py_BEGIN_ALLOW_THREADS
2843#if defined(PYCC_GCC)
2844 spawnval = spawnvp(mode, path, argvlist);
2845#else
2846 spawnval = _spawnvp(mode, path, argvlist);
2847#endif
2848 Py_END_ALLOW_THREADS
2849
2850 free_string_array(argvlist, argc);
2851 PyMem_Free(path);
2852
2853 if (spawnval == -1)
2854 return posix_error();
2855 else
2856 return Py_BuildValue("l", (long) spawnval);
2857}
2858
2859
2860PyDoc_STRVAR(posix_spawnvpe__doc__,
2861"spawnvpe(mode, file, args, env)\n\n\
2862Execute the program 'file' in a new process, using the environment\n\
2863search path to find the file.\n\
2864\n\
2865 mode: mode of process creation\n\
2866 file: executable file name\n\
2867 args: tuple or list of arguments\n\
2868 env: dictionary of strings mapping to strings");
2869
2870static PyObject *
2871posix_spawnvpe(PyObject *self, PyObject *args)
2872{
2873 char *path;
2874 PyObject *argv, *env;
2875 char **argvlist;
2876 char **envlist;
2877 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
2878 int mode, i, pos, argc, envc;
2879 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002880 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00002881 int lastarg = 0;
2882
2883 /* spawnvpe has four arguments: (mode, path, argv, env), where
2884 argv is a list or tuple of strings and env is a dictionary
2885 like posix.environ. */
2886
2887 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
2888 Py_FileSystemDefaultEncoding,
2889 &path, &argv, &env))
2890 return NULL;
2891 if (PyList_Check(argv)) {
2892 argc = PyList_Size(argv);
2893 getitem = PyList_GetItem;
2894 }
2895 else if (PyTuple_Check(argv)) {
2896 argc = PyTuple_Size(argv);
2897 getitem = PyTuple_GetItem;
2898 }
2899 else {
2900 PyErr_SetString(PyExc_TypeError,
2901 "spawnvpe() arg 2 must be a tuple or list");
2902 goto fail_0;
2903 }
2904 if (!PyMapping_Check(env)) {
2905 PyErr_SetString(PyExc_TypeError,
2906 "spawnvpe() arg 3 must be a mapping object");
2907 goto fail_0;
2908 }
2909
2910 argvlist = PyMem_NEW(char *, argc+1);
2911 if (argvlist == NULL) {
2912 PyErr_NoMemory();
2913 goto fail_0;
2914 }
2915 for (i = 0; i < argc; i++) {
2916 if (!PyArg_Parse((*getitem)(argv, i),
2917 "et;spawnvpe() arg 2 must contain only strings",
2918 Py_FileSystemDefaultEncoding,
2919 &argvlist[i]))
2920 {
2921 lastarg = i;
2922 goto fail_1;
2923 }
2924 }
2925 lastarg = argc;
2926 argvlist[argc] = NULL;
2927
2928 i = PyMapping_Size(env);
2929 if (i < 0)
2930 goto fail_1;
2931 envlist = PyMem_NEW(char *, i + 1);
2932 if (envlist == NULL) {
2933 PyErr_NoMemory();
2934 goto fail_1;
2935 }
2936 envc = 0;
2937 keys = PyMapping_Keys(env);
2938 vals = PyMapping_Values(env);
2939 if (!keys || !vals)
2940 goto fail_2;
2941 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2942 PyErr_SetString(PyExc_TypeError,
2943 "spawnvpe(): env.keys() or env.values() is not a list");
2944 goto fail_2;
2945 }
2946
2947 for (pos = 0; pos < i; pos++) {
2948 char *p, *k, *v;
2949 size_t len;
2950
2951 key = PyList_GetItem(keys, pos);
2952 val = PyList_GetItem(vals, pos);
2953 if (!key || !val)
2954 goto fail_2;
2955
2956 if (!PyArg_Parse(
2957 key,
2958 "s;spawnvpe() arg 3 contains a non-string key",
2959 &k) ||
2960 !PyArg_Parse(
2961 val,
2962 "s;spawnvpe() arg 3 contains a non-string value",
2963 &v))
2964 {
2965 goto fail_2;
2966 }
2967 len = PyString_Size(key) + PyString_Size(val) + 2;
2968 p = PyMem_NEW(char, len);
2969 if (p == NULL) {
2970 PyErr_NoMemory();
2971 goto fail_2;
2972 }
2973 PyOS_snprintf(p, len, "%s=%s", k, v);
2974 envlist[envc++] = p;
2975 }
2976 envlist[envc] = 0;
2977
2978 Py_BEGIN_ALLOW_THREADS
2979#if defined(PYCC_GCC)
2980 spawnval = spawnve(mode, path, argvlist, envlist);
2981#else
2982 spawnval = _spawnve(mode, path, argvlist, envlist);
2983#endif
2984 Py_END_ALLOW_THREADS
2985
2986 if (spawnval == -1)
2987 (void) posix_error();
2988 else
2989 res = Py_BuildValue("l", (long) spawnval);
2990
2991 fail_2:
2992 while (--envc >= 0)
2993 PyMem_DEL(envlist[envc]);
2994 PyMem_DEL(envlist);
2995 fail_1:
2996 free_string_array(argvlist, lastarg);
2997 Py_XDECREF(vals);
2998 Py_XDECREF(keys);
2999 fail_0:
3000 PyMem_Free(path);
3001 return res;
3002}
3003#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003004#endif /* HAVE_SPAWNV */
3005
3006
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003007#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003008PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003009"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003010Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3011\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003012Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003013
3014static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003015posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003016{
Neal Norwitze241ce82003-02-17 18:17:05 +00003017 int pid = fork1();
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003018 if (pid == -1)
3019 return posix_error();
3020 PyOS_AfterFork();
3021 return PyInt_FromLong((long)pid);
3022}
3023#endif
3024
3025
Guido van Rossumad0ee831995-03-01 10:34:45 +00003026#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003027PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003028"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003029Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003030Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003031
Barry Warsaw53699e91996-12-10 23:23:01 +00003032static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003033posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003034{
Neal Norwitze241ce82003-02-17 18:17:05 +00003035 int pid = fork();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003036 if (pid == -1)
3037 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003038 if (pid == 0)
3039 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00003040 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003041}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003042#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003043
Neal Norwitzb59798b2003-03-21 01:43:31 +00003044/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00003045/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3046#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00003047#define DEV_PTY_FILE "/dev/ptc"
3048#define HAVE_DEV_PTMX
3049#else
3050#define DEV_PTY_FILE "/dev/ptmx"
3051#endif
3052
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003053#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003054#ifdef HAVE_PTY_H
3055#include <pty.h>
3056#else
3057#ifdef HAVE_LIBUTIL_H
3058#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00003059#endif /* HAVE_LIBUTIL_H */
3060#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00003061#ifdef HAVE_STROPTS_H
3062#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003063#endif
3064#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003065
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003066#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003067PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003068"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003069Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003070
3071static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003072posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003073{
3074 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003075#ifndef HAVE_OPENPTY
3076 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003077#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003078#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003079 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003080#ifdef sun
3081 extern char *ptsname();
3082#endif
3083#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00003084
Thomas Wouters70c21a12000-07-14 14:28:33 +00003085#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00003086 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
3087 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003088#elif defined(HAVE__GETPTY)
Thomas Wouters70c21a12000-07-14 14:28:33 +00003089 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
3090 if (slave_name == NULL)
3091 return posix_error();
3092
3093 slave_fd = open(slave_name, O_RDWR);
3094 if (slave_fd < 0)
3095 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003096#else
Neal Norwitzb59798b2003-03-21 01:43:31 +00003097 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003098 if (master_fd < 0)
3099 return posix_error();
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003100 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003101 /* change permission of slave */
3102 if (grantpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003103 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003104 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003105 }
3106 /* unlock slave */
3107 if (unlockpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003108 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003109 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003110 }
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003111 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003112 slave_name = ptsname(master_fd); /* get name of slave */
3113 if (slave_name == NULL)
3114 return posix_error();
3115 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
3116 if (slave_fd < 0)
3117 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003118#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003119 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
3120 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00003121#ifndef __hpux
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003122 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00003123#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003124#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00003125#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00003126
Fred Drake8cef4cf2000-06-28 16:40:38 +00003127 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00003128
Fred Drake8cef4cf2000-06-28 16:40:38 +00003129}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003130#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003131
3132#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003133PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003134"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00003135Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
3136Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003137To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003138
3139static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003140posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003141{
Neal Norwitz24b3c222005-09-19 06:43:44 +00003142 int master_fd = -1, pid;
Tim Peters5aa91602002-01-30 05:46:57 +00003143
Fred Drake8cef4cf2000-06-28 16:40:38 +00003144 pid = forkpty(&master_fd, NULL, NULL, NULL);
3145 if (pid == -1)
3146 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003147 if (pid == 0)
3148 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00003149 return Py_BuildValue("(ii)", pid, master_fd);
3150}
3151#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003152
Guido van Rossumad0ee831995-03-01 10:34:45 +00003153#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003154PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003155"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003156Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003157
Barry Warsaw53699e91996-12-10 23:23:01 +00003158static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003159posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003160{
Barry Warsaw53699e91996-12-10 23:23:01 +00003161 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003162}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003163#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003164
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003165
Guido van Rossumad0ee831995-03-01 10:34:45 +00003166#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003167PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003168"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003169Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003170
Barry Warsaw53699e91996-12-10 23:23:01 +00003171static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003172posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003173{
Barry Warsaw53699e91996-12-10 23:23:01 +00003174 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003175}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003176#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003177
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003178
Guido van Rossumad0ee831995-03-01 10:34:45 +00003179#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003180PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003181"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003182Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003183
Barry Warsaw53699e91996-12-10 23:23:01 +00003184static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003185posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003186{
Barry Warsaw53699e91996-12-10 23:23:01 +00003187 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003188}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003189#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003190
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003191
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003192PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003193"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003194Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003195
Barry Warsaw53699e91996-12-10 23:23:01 +00003196static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003197posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003198{
Barry Warsaw53699e91996-12-10 23:23:01 +00003199 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003200}
3201
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003202
Fred Drakec9680921999-12-13 16:37:25 +00003203#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003204PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003205"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003206Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00003207
3208static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003209posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00003210{
3211 PyObject *result = NULL;
3212
Fred Drakec9680921999-12-13 16:37:25 +00003213#ifdef NGROUPS_MAX
3214#define MAX_GROUPS NGROUPS_MAX
3215#else
3216 /* defined to be 16 on Solaris7, so this should be a small number */
3217#define MAX_GROUPS 64
3218#endif
3219 gid_t grouplist[MAX_GROUPS];
3220 int n;
3221
3222 n = getgroups(MAX_GROUPS, grouplist);
3223 if (n < 0)
3224 posix_error();
3225 else {
3226 result = PyList_New(n);
3227 if (result != NULL) {
Fred Drakec9680921999-12-13 16:37:25 +00003228 int i;
3229 for (i = 0; i < n; ++i) {
Neal Norwitze241ce82003-02-17 18:17:05 +00003230 PyObject *o = PyInt_FromLong((long)grouplist[i]);
Fred Drakec9680921999-12-13 16:37:25 +00003231 if (o == NULL) {
3232 Py_DECREF(result);
3233 result = NULL;
3234 break;
3235 }
3236 PyList_SET_ITEM(result, i, o);
3237 }
3238 }
3239 }
Neal Norwitze241ce82003-02-17 18:17:05 +00003240
Fred Drakec9680921999-12-13 16:37:25 +00003241 return result;
3242}
3243#endif
3244
Martin v. Löwis606edc12002-06-13 21:09:11 +00003245#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003246PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003247"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003248Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00003249
3250static PyObject *
3251posix_getpgid(PyObject *self, PyObject *args)
3252{
3253 int pid, pgid;
3254 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
3255 return NULL;
3256 pgid = getpgid(pid);
3257 if (pgid < 0)
3258 return posix_error();
3259 return PyInt_FromLong((long)pgid);
3260}
3261#endif /* HAVE_GETPGID */
3262
3263
Guido van Rossumb6775db1994-08-01 11:34:53 +00003264#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003265PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003266"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003267Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003268
Barry Warsaw53699e91996-12-10 23:23:01 +00003269static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003270posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00003271{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003272#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00003273 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003274#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00003275 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003276#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00003277}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003278#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00003279
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003280
Guido van Rossumb6775db1994-08-01 11:34:53 +00003281#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003282PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003283"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003284Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003285
Barry Warsaw53699e91996-12-10 23:23:01 +00003286static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003287posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003288{
Guido van Rossum64933891994-10-20 21:56:42 +00003289#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00003290 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003291#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003292 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003293#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00003294 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003295 Py_INCREF(Py_None);
3296 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003297}
3298
Guido van Rossumb6775db1994-08-01 11:34:53 +00003299#endif /* HAVE_SETPGRP */
3300
Guido van Rossumad0ee831995-03-01 10:34:45 +00003301#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003302PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003303"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003304Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003305
Barry Warsaw53699e91996-12-10 23:23:01 +00003306static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003307posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003308{
Barry Warsaw53699e91996-12-10 23:23:01 +00003309 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003310}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003311#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003312
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003313
Fred Drake12c6e2d1999-12-14 21:25:03 +00003314#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003315PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003316"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003317Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00003318
3319static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003320posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00003321{
Neal Norwitze241ce82003-02-17 18:17:05 +00003322 PyObject *result = NULL;
Fred Drakea30680b2000-12-06 21:24:28 +00003323 char *name;
3324 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00003325
Fred Drakea30680b2000-12-06 21:24:28 +00003326 errno = 0;
3327 name = getlogin();
3328 if (name == NULL) {
3329 if (errno)
3330 posix_error();
3331 else
3332 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00003333 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00003334 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00003335 else
3336 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00003337 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00003338
Fred Drake12c6e2d1999-12-14 21:25:03 +00003339 return result;
3340}
3341#endif
3342
Guido van Rossumad0ee831995-03-01 10:34:45 +00003343#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003344PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003345"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003346Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003347
Barry Warsaw53699e91996-12-10 23:23:01 +00003348static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003349posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003350{
Barry Warsaw53699e91996-12-10 23:23:01 +00003351 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003352}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003353#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003354
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003355
Guido van Rossumad0ee831995-03-01 10:34:45 +00003356#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003357PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003358"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003359Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003360
Barry Warsaw53699e91996-12-10 23:23:01 +00003361static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003362posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003363{
3364 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003365 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00003366 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003367#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003368 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
3369 APIRET rc;
3370 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003371 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003372
3373 } else if (sig == XCPT_SIGNAL_KILLPROC) {
3374 APIRET rc;
3375 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003376 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003377
3378 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003379 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003380#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00003381 if (kill(pid, sig) == -1)
3382 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003383#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003384 Py_INCREF(Py_None);
3385 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003386}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003387#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003388
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003389#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003390PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003391"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003392Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003393
3394static PyObject *
3395posix_killpg(PyObject *self, PyObject *args)
3396{
3397 int pgid, sig;
3398 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
3399 return NULL;
3400 if (killpg(pgid, sig) == -1)
3401 return posix_error();
3402 Py_INCREF(Py_None);
3403 return Py_None;
3404}
3405#endif
3406
Guido van Rossumc0125471996-06-28 18:55:32 +00003407#ifdef HAVE_PLOCK
3408
3409#ifdef HAVE_SYS_LOCK_H
3410#include <sys/lock.h>
3411#endif
3412
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003413PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003414"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003415Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003416
Barry Warsaw53699e91996-12-10 23:23:01 +00003417static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003418posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00003419{
3420 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003421 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00003422 return NULL;
3423 if (plock(op) == -1)
3424 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003425 Py_INCREF(Py_None);
3426 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00003427}
3428#endif
3429
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003430
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003431#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003432PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003433"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003434Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003435
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003436#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003437#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003438static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003439async_system(const char *command)
3440{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003441 char errormsg[256], args[1024];
3442 RESULTCODES rcodes;
3443 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003444
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003445 char *shell = getenv("COMSPEC");
3446 if (!shell)
3447 shell = "cmd";
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003448
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003449 /* avoid overflowing the argument buffer */
3450 if (strlen(shell) + 3 + strlen(command) >= 1024)
3451 return ERROR_NOT_ENOUGH_MEMORY
3452
3453 args[0] = '\0';
3454 strcat(args, shell);
3455 strcat(args, "/c ");
3456 strcat(args, command);
3457
3458 /* execute asynchronously, inheriting the environment */
3459 rc = DosExecPgm(errormsg,
3460 sizeof(errormsg),
3461 EXEC_ASYNC,
3462 args,
3463 NULL,
3464 &rcodes,
3465 shell);
3466 return rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003467}
3468
Guido van Rossumd48f2521997-12-05 22:19:34 +00003469static FILE *
3470popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003471{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003472 int oldfd, tgtfd;
3473 HFILE pipeh[2];
3474 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003475
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003476 /* mode determines which of stdin or stdout is reconnected to
3477 * the pipe to the child
3478 */
3479 if (strchr(mode, 'r') != NULL) {
3480 tgt_fd = 1; /* stdout */
3481 } else if (strchr(mode, 'w')) {
3482 tgt_fd = 0; /* stdin */
3483 } else {
3484 *err = ERROR_INVALID_ACCESS;
3485 return NULL;
3486 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003487
Andrew MacIntyrea3be2582004-12-18 09:51:05 +00003488 /* setup the pipe */
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003489 if ((rc = DosCreatePipe(&pipeh[0], &pipeh[1], pipesize)) != NO_ERROR) {
3490 *err = rc;
3491 return NULL;
3492 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003493
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003494 /* prevent other threads accessing stdio */
3495 DosEnterCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003496
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003497 /* reconnect stdio and execute child */
3498 oldfd = dup(tgtfd);
3499 close(tgtfd);
3500 if (dup2(pipeh[tgtfd], tgtfd) == 0) {
3501 DosClose(pipeh[tgtfd]);
3502 rc = async_system(command);
3503 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003504
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003505 /* restore stdio */
3506 dup2(oldfd, tgtfd);
3507 close(oldfd);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003508
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003509 /* allow other threads access to stdio */
3510 DosExitCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003511
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003512 /* if execution of child was successful return file stream */
3513 if (rc == NO_ERROR)
3514 return fdopen(pipeh[1 - tgtfd], mode);
3515 else {
3516 DosClose(pipeh[1 - tgtfd]);
3517 *err = rc;
3518 return NULL;
3519 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003520}
3521
3522static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003523posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003524{
3525 char *name;
3526 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00003527 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003528 FILE *fp;
3529 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003530 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003531 return NULL;
3532 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00003533 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003534 Py_END_ALLOW_THREADS
3535 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003536 return os2_error(err);
3537
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003538 f = PyFile_FromFile(fp, name, mode, fclose);
3539 if (f != NULL)
3540 PyFile_SetBufSize(f, bufsize);
3541 return f;
3542}
3543
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003544#elif defined(PYCC_GCC)
3545
3546/* standard posix version of popen() support */
3547static PyObject *
3548posix_popen(PyObject *self, PyObject *args)
3549{
3550 char *name;
3551 char *mode = "r";
3552 int bufsize = -1;
3553 FILE *fp;
3554 PyObject *f;
3555 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
3556 return NULL;
3557 Py_BEGIN_ALLOW_THREADS
3558 fp = popen(name, mode);
3559 Py_END_ALLOW_THREADS
3560 if (fp == NULL)
3561 return posix_error();
3562 f = PyFile_FromFile(fp, name, mode, pclose);
3563 if (f != NULL)
3564 PyFile_SetBufSize(f, bufsize);
3565 return f;
3566}
3567
3568/* fork() under OS/2 has lots'o'warts
3569 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
3570 * most of this code is a ripoff of the win32 code, but using the
3571 * capabilities of EMX's C library routines
3572 */
3573
3574/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
3575#define POPEN_1 1
3576#define POPEN_2 2
3577#define POPEN_3 3
3578#define POPEN_4 4
3579
3580static PyObject *_PyPopen(char *, int, int, int);
3581static int _PyPclose(FILE *file);
3582
3583/*
3584 * Internal dictionary mapping popen* file pointers to process handles,
3585 * for use when retrieving the process exit code. See _PyPclose() below
3586 * for more information on this dictionary's use.
3587 */
3588static PyObject *_PyPopenProcs = NULL;
3589
3590/* os2emx version of popen2()
3591 *
3592 * The result of this function is a pipe (file) connected to the
3593 * process's stdin, and a pipe connected to the process's stdout.
3594 */
3595
3596static PyObject *
3597os2emx_popen2(PyObject *self, PyObject *args)
3598{
3599 PyObject *f;
3600 int tm=0;
3601
3602 char *cmdstring;
3603 char *mode = "t";
3604 int bufsize = -1;
3605 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
3606 return NULL;
3607
3608 if (*mode == 't')
3609 tm = O_TEXT;
3610 else if (*mode != 'b') {
3611 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3612 return NULL;
3613 } else
3614 tm = O_BINARY;
3615
3616 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
3617
3618 return f;
3619}
3620
3621/*
3622 * Variation on os2emx.popen2
3623 *
3624 * The result of this function is 3 pipes - the process's stdin,
3625 * stdout and stderr
3626 */
3627
3628static PyObject *
3629os2emx_popen3(PyObject *self, PyObject *args)
3630{
3631 PyObject *f;
3632 int tm = 0;
3633
3634 char *cmdstring;
3635 char *mode = "t";
3636 int bufsize = -1;
3637 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
3638 return NULL;
3639
3640 if (*mode == 't')
3641 tm = O_TEXT;
3642 else if (*mode != 'b') {
3643 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3644 return NULL;
3645 } else
3646 tm = O_BINARY;
3647
3648 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
3649
3650 return f;
3651}
3652
3653/*
3654 * Variation on os2emx.popen2
3655 *
Tim Peters11b23062003-04-23 02:39:17 +00003656 * The result of this function is 2 pipes - the processes stdin,
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003657 * and stdout+stderr combined as a single pipe.
3658 */
3659
3660static PyObject *
3661os2emx_popen4(PyObject *self, PyObject *args)
3662{
3663 PyObject *f;
3664 int tm = 0;
3665
3666 char *cmdstring;
3667 char *mode = "t";
3668 int bufsize = -1;
3669 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
3670 return NULL;
3671
3672 if (*mode == 't')
3673 tm = O_TEXT;
3674 else if (*mode != 'b') {
3675 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3676 return NULL;
3677 } else
3678 tm = O_BINARY;
3679
3680 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
3681
3682 return f;
3683}
3684
3685/* a couple of structures for convenient handling of multiple
3686 * file handles and pipes
3687 */
3688struct file_ref
3689{
3690 int handle;
3691 int flags;
3692};
3693
3694struct pipe_ref
3695{
3696 int rd;
3697 int wr;
3698};
3699
3700/* The following code is derived from the win32 code */
3701
3702static PyObject *
3703_PyPopen(char *cmdstring, int mode, int n, int bufsize)
3704{
3705 struct file_ref stdio[3];
3706 struct pipe_ref p_fd[3];
3707 FILE *p_s[3];
3708 int file_count, i, pipe_err, pipe_pid;
3709 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
3710 PyObject *f, *p_f[3];
3711
3712 /* file modes for subsequent fdopen's on pipe handles */
3713 if (mode == O_TEXT)
3714 {
3715 rd_mode = "rt";
3716 wr_mode = "wt";
3717 }
3718 else
3719 {
3720 rd_mode = "rb";
3721 wr_mode = "wb";
3722 }
3723
3724 /* prepare shell references */
3725 if ((shell = getenv("EMXSHELL")) == NULL)
3726 if ((shell = getenv("COMSPEC")) == NULL)
3727 {
3728 errno = ENOENT;
3729 return posix_error();
3730 }
3731
3732 sh_name = _getname(shell);
3733 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
3734 opt = "/c";
3735 else
3736 opt = "-c";
3737
3738 /* save current stdio fds + their flags, and set not inheritable */
3739 i = pipe_err = 0;
3740 while (pipe_err >= 0 && i < 3)
3741 {
3742 pipe_err = stdio[i].handle = dup(i);
3743 stdio[i].flags = fcntl(i, F_GETFD, 0);
3744 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
3745 i++;
3746 }
3747 if (pipe_err < 0)
3748 {
3749 /* didn't get them all saved - clean up and bail out */
3750 int saved_err = errno;
3751 while (i-- > 0)
3752 {
3753 close(stdio[i].handle);
3754 }
3755 errno = saved_err;
3756 return posix_error();
3757 }
3758
3759 /* create pipe ends */
3760 file_count = 2;
3761 if (n == POPEN_3)
3762 file_count = 3;
3763 i = pipe_err = 0;
3764 while ((pipe_err == 0) && (i < file_count))
3765 pipe_err = pipe((int *)&p_fd[i++]);
3766 if (pipe_err < 0)
3767 {
3768 /* didn't get them all made - clean up and bail out */
3769 while (i-- > 0)
3770 {
3771 close(p_fd[i].wr);
3772 close(p_fd[i].rd);
3773 }
3774 errno = EPIPE;
3775 return posix_error();
3776 }
3777
3778 /* change the actual standard IO streams over temporarily,
3779 * making the retained pipe ends non-inheritable
3780 */
3781 pipe_err = 0;
3782
3783 /* - stdin */
3784 if (dup2(p_fd[0].rd, 0) == 0)
3785 {
3786 close(p_fd[0].rd);
3787 i = fcntl(p_fd[0].wr, F_GETFD, 0);
3788 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
3789 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
3790 {
3791 close(p_fd[0].wr);
3792 pipe_err = -1;
3793 }
3794 }
3795 else
3796 {
3797 pipe_err = -1;
3798 }
3799
3800 /* - stdout */
3801 if (pipe_err == 0)
3802 {
3803 if (dup2(p_fd[1].wr, 1) == 1)
3804 {
3805 close(p_fd[1].wr);
3806 i = fcntl(p_fd[1].rd, F_GETFD, 0);
3807 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
3808 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
3809 {
3810 close(p_fd[1].rd);
3811 pipe_err = -1;
3812 }
3813 }
3814 else
3815 {
3816 pipe_err = -1;
3817 }
3818 }
3819
3820 /* - stderr, as required */
3821 if (pipe_err == 0)
3822 switch (n)
3823 {
3824 case POPEN_3:
3825 {
3826 if (dup2(p_fd[2].wr, 2) == 2)
3827 {
3828 close(p_fd[2].wr);
3829 i = fcntl(p_fd[2].rd, F_GETFD, 0);
3830 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
3831 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
3832 {
3833 close(p_fd[2].rd);
3834 pipe_err = -1;
3835 }
3836 }
3837 else
3838 {
3839 pipe_err = -1;
3840 }
3841 break;
3842 }
3843
3844 case POPEN_4:
3845 {
3846 if (dup2(1, 2) != 2)
3847 {
3848 pipe_err = -1;
3849 }
3850 break;
3851 }
3852 }
3853
3854 /* spawn the child process */
3855 if (pipe_err == 0)
3856 {
3857 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
3858 if (pipe_pid == -1)
3859 {
3860 pipe_err = -1;
3861 }
3862 else
3863 {
3864 /* save the PID into the FILE structure
3865 * NOTE: this implementation doesn't actually
3866 * take advantage of this, but do it for
3867 * completeness - AIM Apr01
3868 */
3869 for (i = 0; i < file_count; i++)
3870 p_s[i]->_pid = pipe_pid;
3871 }
3872 }
3873
3874 /* reset standard IO to normal */
3875 for (i = 0; i < 3; i++)
3876 {
3877 dup2(stdio[i].handle, i);
3878 fcntl(i, F_SETFD, stdio[i].flags);
3879 close(stdio[i].handle);
3880 }
3881
3882 /* if any remnant problems, clean up and bail out */
3883 if (pipe_err < 0)
3884 {
3885 for (i = 0; i < 3; i++)
3886 {
3887 close(p_fd[i].rd);
3888 close(p_fd[i].wr);
3889 }
3890 errno = EPIPE;
3891 return posix_error_with_filename(cmdstring);
3892 }
3893
3894 /* build tuple of file objects to return */
3895 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
3896 PyFile_SetBufSize(p_f[0], bufsize);
3897 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
3898 PyFile_SetBufSize(p_f[1], bufsize);
3899 if (n == POPEN_3)
3900 {
3901 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
3902 PyFile_SetBufSize(p_f[0], bufsize);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00003903 f = PyTuple_Pack(3, p_f[0], p_f[1], p_f[2]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003904 }
3905 else
Raymond Hettinger8ae46892003-10-12 19:09:37 +00003906 f = PyTuple_Pack(2, p_f[0], p_f[1]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003907
3908 /*
3909 * Insert the files we've created into the process dictionary
3910 * all referencing the list with the process handle and the
3911 * initial number of files (see description below in _PyPclose).
3912 * Since if _PyPclose later tried to wait on a process when all
3913 * handles weren't closed, it could create a deadlock with the
3914 * child, we spend some energy here to try to ensure that we
3915 * either insert all file handles into the dictionary or none
3916 * at all. It's a little clumsy with the various popen modes
3917 * and variable number of files involved.
3918 */
3919 if (!_PyPopenProcs)
3920 {
3921 _PyPopenProcs = PyDict_New();
3922 }
3923
3924 if (_PyPopenProcs)
3925 {
3926 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
3927 int ins_rc[3];
3928
3929 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
3930 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
3931
3932 procObj = PyList_New(2);
3933 pidObj = PyInt_FromLong((long) pipe_pid);
3934 intObj = PyInt_FromLong((long) file_count);
3935
3936 if (procObj && pidObj && intObj)
3937 {
3938 PyList_SetItem(procObj, 0, pidObj);
3939 PyList_SetItem(procObj, 1, intObj);
3940
3941 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
3942 if (fileObj[0])
3943 {
3944 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
3945 fileObj[0],
3946 procObj);
3947 }
3948 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
3949 if (fileObj[1])
3950 {
3951 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
3952 fileObj[1],
3953 procObj);
3954 }
3955 if (file_count >= 3)
3956 {
3957 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
3958 if (fileObj[2])
3959 {
3960 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
3961 fileObj[2],
3962 procObj);
3963 }
3964 }
3965
3966 if (ins_rc[0] < 0 || !fileObj[0] ||
3967 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
3968 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
3969 {
3970 /* Something failed - remove any dictionary
3971 * entries that did make it.
3972 */
3973 if (!ins_rc[0] && fileObj[0])
3974 {
3975 PyDict_DelItem(_PyPopenProcs,
3976 fileObj[0]);
3977 }
3978 if (!ins_rc[1] && fileObj[1])
3979 {
3980 PyDict_DelItem(_PyPopenProcs,
3981 fileObj[1]);
3982 }
3983 if (!ins_rc[2] && fileObj[2])
3984 {
3985 PyDict_DelItem(_PyPopenProcs,
3986 fileObj[2]);
3987 }
3988 }
3989 }
Tim Peters11b23062003-04-23 02:39:17 +00003990
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003991 /*
3992 * Clean up our localized references for the dictionary keys
3993 * and value since PyDict_SetItem will Py_INCREF any copies
3994 * that got placed in the dictionary.
3995 */
3996 Py_XDECREF(procObj);
3997 Py_XDECREF(fileObj[0]);
3998 Py_XDECREF(fileObj[1]);
3999 Py_XDECREF(fileObj[2]);
4000 }
4001
4002 /* Child is launched. */
4003 return f;
4004}
4005
4006/*
4007 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4008 * exit code for the child process and return as a result of the close.
4009 *
4010 * This function uses the _PyPopenProcs dictionary in order to map the
4011 * input file pointer to information about the process that was
4012 * originally created by the popen* call that created the file pointer.
4013 * The dictionary uses the file pointer as a key (with one entry
4014 * inserted for each file returned by the original popen* call) and a
4015 * single list object as the value for all files from a single call.
4016 * The list object contains the Win32 process handle at [0], and a file
4017 * count at [1], which is initialized to the total number of file
4018 * handles using that list.
4019 *
4020 * This function closes whichever handle it is passed, and decrements
4021 * the file count in the dictionary for the process handle pointed to
4022 * by this file. On the last close (when the file count reaches zero),
4023 * this function will wait for the child process and then return its
4024 * exit code as the result of the close() operation. This permits the
4025 * files to be closed in any order - it is always the close() of the
4026 * final handle that will return the exit code.
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004027 *
4028 * NOTE: This function is currently called with the GIL released.
4029 * hence we use the GILState API to manage our state.
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004030 */
4031
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004032static int _PyPclose(FILE *file)
4033{
4034 int result;
4035 int exit_code;
4036 int pipe_pid;
4037 PyObject *procObj, *pidObj, *intObj, *fileObj;
4038 int file_count;
4039#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004040 PyGILState_STATE state;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004041#endif
4042
4043 /* Close the file handle first, to ensure it can't block the
4044 * child from exiting if it's the last handle.
4045 */
4046 result = fclose(file);
4047
4048#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004049 state = PyGILState_Ensure();
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004050#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004051 if (_PyPopenProcs)
4052 {
4053 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4054 (procObj = PyDict_GetItem(_PyPopenProcs,
4055 fileObj)) != NULL &&
4056 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
4057 (intObj = PyList_GetItem(procObj,1)) != NULL)
4058 {
4059 pipe_pid = (int) PyInt_AsLong(pidObj);
4060 file_count = (int) PyInt_AsLong(intObj);
4061
4062 if (file_count > 1)
4063 {
4064 /* Still other files referencing process */
4065 file_count--;
4066 PyList_SetItem(procObj,1,
4067 PyInt_FromLong((long) file_count));
4068 }
4069 else
4070 {
4071 /* Last file for this process */
4072 if (result != EOF &&
4073 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
4074 {
4075 /* extract exit status */
4076 if (WIFEXITED(exit_code))
4077 {
4078 result = WEXITSTATUS(exit_code);
4079 }
4080 else
4081 {
4082 errno = EPIPE;
4083 result = -1;
4084 }
4085 }
4086 else
4087 {
4088 /* Indicate failure - this will cause the file object
4089 * to raise an I/O error and translate the last
4090 * error code from errno. We do have a problem with
4091 * last errors that overlap the normal errno table,
4092 * but that's a consistent problem with the file object.
4093 */
4094 result = -1;
4095 }
4096 }
4097
4098 /* Remove this file pointer from dictionary */
4099 PyDict_DelItem(_PyPopenProcs, fileObj);
4100
4101 if (PyDict_Size(_PyPopenProcs) == 0)
4102 {
4103 Py_DECREF(_PyPopenProcs);
4104 _PyPopenProcs = NULL;
4105 }
4106
4107 } /* if object retrieval ok */
4108
4109 Py_XDECREF(fileObj);
4110 } /* if _PyPopenProcs */
4111
4112#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004113 PyGILState_Release(state);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004114#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004115 return result;
4116}
4117
4118#endif /* PYCC_??? */
4119
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004120#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004121
4122/*
4123 * Portable 'popen' replacement for Win32.
4124 *
4125 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
4126 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00004127 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004128 */
4129
4130#include <malloc.h>
4131#include <io.h>
4132#include <fcntl.h>
4133
4134/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
4135#define POPEN_1 1
4136#define POPEN_2 2
4137#define POPEN_3 3
4138#define POPEN_4 4
4139
4140static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004141static int _PyPclose(FILE *file);
4142
4143/*
4144 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00004145 * for use when retrieving the process exit code. See _PyPclose() below
4146 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004147 */
4148static PyObject *_PyPopenProcs = NULL;
4149
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004150
4151/* popen that works from a GUI.
4152 *
4153 * The result of this function is a pipe (file) connected to the
4154 * processes stdin or stdout, depending on the requested mode.
4155 */
4156
4157static PyObject *
4158posix_popen(PyObject *self, PyObject *args)
4159{
Raymond Hettingerb5cb6652003-09-01 22:25:41 +00004160 PyObject *f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004161 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004162
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004163 char *cmdstring;
4164 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004165 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004166 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004167 return NULL;
4168
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004169 if (*mode == 'r')
4170 tm = _O_RDONLY;
4171 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00004172 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004173 return NULL;
4174 } else
4175 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00004176
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004177 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004178 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004179 return NULL;
4180 }
4181
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004182 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004183 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004184 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004185 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004186 else
4187 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
4188
4189 return f;
4190}
4191
4192/* Variation on win32pipe.popen
4193 *
4194 * The result of this function is a pipe (file) connected to the
4195 * process's stdin, and a pipe connected to the process's stdout.
4196 */
4197
4198static PyObject *
4199win32_popen2(PyObject *self, PyObject *args)
4200{
4201 PyObject *f;
4202 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00004203
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004204 char *cmdstring;
4205 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004206 int bufsize = -1;
4207 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004208 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004209
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004210 if (*mode == 't')
4211 tm = _O_TEXT;
4212 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004213 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004214 return NULL;
4215 } else
4216 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004217
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004218 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004219 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004220 return NULL;
4221 }
4222
4223 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00004224
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004225 return f;
4226}
4227
4228/*
4229 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004230 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004231 * The result of this function is 3 pipes - the process's stdin,
4232 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004233 */
4234
4235static PyObject *
4236win32_popen3(PyObject *self, PyObject *args)
4237{
4238 PyObject *f;
4239 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004240
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004241 char *cmdstring;
4242 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004243 int bufsize = -1;
4244 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004245 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004246
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004247 if (*mode == 't')
4248 tm = _O_TEXT;
4249 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004250 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004251 return NULL;
4252 } else
4253 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004254
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004255 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004256 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004257 return NULL;
4258 }
4259
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004260 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00004261
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004262 return f;
4263}
4264
4265/*
4266 * Variation on win32pipe.popen
4267 *
Tim Peters5aa91602002-01-30 05:46:57 +00004268 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004269 * and stdout+stderr combined as a single pipe.
4270 */
4271
4272static PyObject *
4273win32_popen4(PyObject *self, PyObject *args)
4274{
4275 PyObject *f;
4276 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004277
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004278 char *cmdstring;
4279 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004280 int bufsize = -1;
4281 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004282 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004283
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004284 if (*mode == 't')
4285 tm = _O_TEXT;
4286 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004287 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004288 return NULL;
4289 } else
4290 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004291
4292 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004293 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004294 return NULL;
4295 }
4296
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004297 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004298
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004299 return f;
4300}
4301
Mark Hammond08501372001-01-31 07:30:29 +00004302static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00004303_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004304 HANDLE hStdin,
4305 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00004306 HANDLE hStderr,
4307 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004308{
4309 PROCESS_INFORMATION piProcInfo;
4310 STARTUPINFO siStartInfo;
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004311 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004312 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00004313 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004314 int i;
Martin v. Löwis18e16552006-02-15 17:27:45 +00004315 Py_ssize_t x;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004316
4317 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00004318 char *comshell;
4319
Tim Peters92e4dd82002-10-05 01:47:34 +00004320 s1 = (char *)alloca(i);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004321 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
Martin v. Löwis18e16552006-02-15 17:27:45 +00004322 /* x < i, so x fits into an integer */
4323 return (int)x;
Tim Peters402d5982001-08-27 06:37:48 +00004324
4325 /* Explicitly check if we are using COMMAND.COM. If we are
4326 * then use the w9xpopen hack.
4327 */
4328 comshell = s1 + x;
4329 while (comshell >= s1 && *comshell != '\\')
4330 --comshell;
4331 ++comshell;
4332
4333 if (GetVersion() < 0x80000000 &&
4334 _stricmp(comshell, "command.com") != 0) {
4335 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004336 x = i + strlen(s3) + strlen(cmdstring) + 1;
Tim Peters92e4dd82002-10-05 01:47:34 +00004337 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004338 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00004339 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004340 }
4341 else {
4342 /*
Tim Peters402d5982001-08-27 06:37:48 +00004343 * Oh gag, we're on Win9x or using COMMAND.COM. Use
4344 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004345 */
Mark Hammond08501372001-01-31 07:30:29 +00004346 char modulepath[_MAX_PATH];
4347 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004348 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
4349 for (i = x = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004350 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004351 x = i+1;
4352 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00004353 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00004354 strncat(modulepath,
4355 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00004356 (sizeof(modulepath)/sizeof(modulepath[0]))
4357 -strlen(modulepath));
4358 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00004359 /* Eeek - file-not-found - possibly an embedding
4360 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00004361 */
Tim Peters5aa91602002-01-30 05:46:57 +00004362 strncpy(modulepath,
4363 Py_GetExecPrefix(),
Mark Hammond08501372001-01-31 07:30:29 +00004364 sizeof(modulepath)/sizeof(modulepath[0]));
4365 if (modulepath[strlen(modulepath)-1] != '\\')
4366 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00004367 strncat(modulepath,
4368 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00004369 (sizeof(modulepath)/sizeof(modulepath[0]))
4370 -strlen(modulepath));
4371 /* No where else to look - raise an easily identifiable
4372 error, rather than leaving Windows to report
4373 "file not found" - as the user is probably blissfully
4374 unaware this shim EXE is used, and it will confuse them.
4375 (well, it confused me for a while ;-)
4376 */
4377 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00004378 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00004379 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00004380 "for popen to work with your shell "
4381 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00004382 szConsoleSpawn);
4383 return FALSE;
4384 }
4385 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004386 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00004387 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004388 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00004389
Tim Peters92e4dd82002-10-05 01:47:34 +00004390 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004391 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004392 /* To maintain correct argument passing semantics,
4393 we pass the command-line as it stands, and allow
4394 quoting to be applied. w9xpopen.exe will then
4395 use its argv vector, and re-quote the necessary
4396 args for the ultimate child process.
4397 */
Tim Peters75cdad52001-11-28 22:07:30 +00004398 PyOS_snprintf(
4399 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004400 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004401 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004402 s1,
4403 s3,
4404 cmdstring);
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004405 /* Not passing CREATE_NEW_CONSOLE has been known to
Tim Peters11b23062003-04-23 02:39:17 +00004406 cause random failures on win9x. Specifically a
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004407 dialog:
4408 "Your program accessed mem currently in use at xxx"
4409 and a hopeful warning about the stability of your
4410 system.
4411 Cost is Ctrl+C wont kill children, but anyone
4412 who cares can have a go!
4413 */
4414 dwProcessFlags |= CREATE_NEW_CONSOLE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004415 }
4416 }
4417
4418 /* Could be an else here to try cmd.exe / command.com in the path
4419 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00004420 else {
Tim Peters402d5982001-08-27 06:37:48 +00004421 PyErr_SetString(PyExc_RuntimeError,
4422 "Cannot locate a COMSPEC environment variable to "
4423 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00004424 return FALSE;
4425 }
Tim Peters5aa91602002-01-30 05:46:57 +00004426
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004427 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
4428 siStartInfo.cb = sizeof(STARTUPINFO);
4429 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
4430 siStartInfo.hStdInput = hStdin;
4431 siStartInfo.hStdOutput = hStdout;
4432 siStartInfo.hStdError = hStderr;
4433 siStartInfo.wShowWindow = SW_HIDE;
4434
4435 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004436 s2,
4437 NULL,
4438 NULL,
4439 TRUE,
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004440 dwProcessFlags,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004441 NULL,
4442 NULL,
4443 &siStartInfo,
4444 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004445 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004446 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004447
Mark Hammondb37a3732000-08-14 04:47:33 +00004448 /* Return process handle */
4449 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004450 return TRUE;
4451 }
Tim Peters402d5982001-08-27 06:37:48 +00004452 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004453 return FALSE;
4454}
4455
4456/* The following code is based off of KB: Q190351 */
4457
4458static PyObject *
4459_PyPopen(char *cmdstring, int mode, int n)
4460{
4461 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
4462 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00004463 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00004464
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004465 SECURITY_ATTRIBUTES saAttr;
4466 BOOL fSuccess;
4467 int fd1, fd2, fd3;
4468 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00004469 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004470 PyObject *f;
4471
4472 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
4473 saAttr.bInheritHandle = TRUE;
4474 saAttr.lpSecurityDescriptor = NULL;
4475
4476 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
4477 return win32_error("CreatePipe", NULL);
4478
4479 /* Create new output read handle and the input write handle. Set
4480 * the inheritance properties to FALSE. Otherwise, the child inherits
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00004481 * these handles; resulting in non-closeable handles to the pipes
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004482 * being created. */
4483 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004484 GetCurrentProcess(), &hChildStdinWrDup, 0,
4485 FALSE,
4486 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004487 if (!fSuccess)
4488 return win32_error("DuplicateHandle", NULL);
4489
4490 /* Close the inheritable version of ChildStdin
4491 that we're using. */
4492 CloseHandle(hChildStdinWr);
4493
4494 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
4495 return win32_error("CreatePipe", NULL);
4496
4497 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004498 GetCurrentProcess(), &hChildStdoutRdDup, 0,
4499 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004500 if (!fSuccess)
4501 return win32_error("DuplicateHandle", NULL);
4502
4503 /* Close the inheritable version of ChildStdout
4504 that we're using. */
4505 CloseHandle(hChildStdoutRd);
4506
4507 if (n != POPEN_4) {
4508 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
4509 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004510 fSuccess = DuplicateHandle(GetCurrentProcess(),
4511 hChildStderrRd,
4512 GetCurrentProcess(),
4513 &hChildStderrRdDup, 0,
4514 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004515 if (!fSuccess)
4516 return win32_error("DuplicateHandle", NULL);
4517 /* Close the inheritable version of ChildStdErr that we're using. */
4518 CloseHandle(hChildStderrRd);
4519 }
Tim Peters5aa91602002-01-30 05:46:57 +00004520
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004521 switch (n) {
4522 case POPEN_1:
4523 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
4524 case _O_WRONLY | _O_TEXT:
4525 /* Case for writing to child Stdin in text mode. */
Martin v. Löwis18e16552006-02-15 17:27:45 +00004526 fd1 = _open_osfhandle((intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004527 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004528 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004529 PyFile_SetBufSize(f, 0);
4530 /* We don't care about these pipes anymore, so close them. */
4531 CloseHandle(hChildStdoutRdDup);
4532 CloseHandle(hChildStderrRdDup);
4533 break;
4534
4535 case _O_RDONLY | _O_TEXT:
4536 /* Case for reading from child Stdout in text mode. */
Martin v. Löwis18e16552006-02-15 17:27:45 +00004537 fd1 = _open_osfhandle((intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004538 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004539 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004540 PyFile_SetBufSize(f, 0);
4541 /* We don't care about these pipes anymore, so close them. */
4542 CloseHandle(hChildStdinWrDup);
4543 CloseHandle(hChildStderrRdDup);
4544 break;
4545
4546 case _O_RDONLY | _O_BINARY:
4547 /* Case for readinig from child Stdout in binary mode. */
Martin v. Löwis18e16552006-02-15 17:27:45 +00004548 fd1 = _open_osfhandle((intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004549 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004550 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004551 PyFile_SetBufSize(f, 0);
4552 /* We don't care about these pipes anymore, so close them. */
4553 CloseHandle(hChildStdinWrDup);
4554 CloseHandle(hChildStderrRdDup);
4555 break;
4556
4557 case _O_WRONLY | _O_BINARY:
4558 /* Case for writing to child Stdin in binary mode. */
Martin v. Löwis18e16552006-02-15 17:27:45 +00004559 fd1 = _open_osfhandle((intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004560 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004561 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004562 PyFile_SetBufSize(f, 0);
4563 /* We don't care about these pipes anymore, so close them. */
4564 CloseHandle(hChildStdoutRdDup);
4565 CloseHandle(hChildStderrRdDup);
4566 break;
4567 }
Mark Hammondb37a3732000-08-14 04:47:33 +00004568 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004569 break;
Tim Peters5aa91602002-01-30 05:46:57 +00004570
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004571 case POPEN_2:
4572 case POPEN_4:
4573 {
4574 char *m1, *m2;
4575 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00004576
Tim Peters7dca21e2002-08-19 00:42:29 +00004577 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004578 m1 = "r";
4579 m2 = "w";
4580 } else {
4581 m1 = "rb";
4582 m2 = "wb";
4583 }
4584
Martin v. Löwis18e16552006-02-15 17:27:45 +00004585 fd1 = _open_osfhandle((intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004586 f1 = _fdopen(fd1, m2);
Martin v. Löwis18e16552006-02-15 17:27:45 +00004587 fd2 = _open_osfhandle((intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004588 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004589 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004590 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00004591 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004592 PyFile_SetBufSize(p2, 0);
4593
4594 if (n != 4)
4595 CloseHandle(hChildStderrRdDup);
4596
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004597 f = PyTuple_Pack(2,p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00004598 Py_XDECREF(p1);
4599 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00004600 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004601 break;
4602 }
Tim Peters5aa91602002-01-30 05:46:57 +00004603
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004604 case POPEN_3:
4605 {
4606 char *m1, *m2;
4607 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00004608
Tim Peters7dca21e2002-08-19 00:42:29 +00004609 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004610 m1 = "r";
4611 m2 = "w";
4612 } else {
4613 m1 = "rb";
4614 m2 = "wb";
4615 }
4616
Martin v. Löwis18e16552006-02-15 17:27:45 +00004617 fd1 = _open_osfhandle((intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004618 f1 = _fdopen(fd1, m2);
Martin v. Löwis18e16552006-02-15 17:27:45 +00004619 fd2 = _open_osfhandle((intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004620 f2 = _fdopen(fd2, m1);
Martin v. Löwis18e16552006-02-15 17:27:45 +00004621 fd3 = _open_osfhandle((intptr_t)hChildStderrRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004622 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004623 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00004624 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
4625 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004626 PyFile_SetBufSize(p1, 0);
4627 PyFile_SetBufSize(p2, 0);
4628 PyFile_SetBufSize(p3, 0);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004629 f = PyTuple_Pack(3,p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00004630 Py_XDECREF(p1);
4631 Py_XDECREF(p2);
4632 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00004633 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004634 break;
4635 }
4636 }
4637
4638 if (n == POPEN_4) {
4639 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004640 hChildStdinRd,
4641 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004642 hChildStdoutWr,
4643 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004644 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004645 }
4646 else {
4647 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004648 hChildStdinRd,
4649 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004650 hChildStderrWr,
4651 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004652 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004653 }
4654
Mark Hammondb37a3732000-08-14 04:47:33 +00004655 /*
4656 * Insert the files we've created into the process dictionary
4657 * all referencing the list with the process handle and the
4658 * initial number of files (see description below in _PyPclose).
4659 * Since if _PyPclose later tried to wait on a process when all
4660 * handles weren't closed, it could create a deadlock with the
4661 * child, we spend some energy here to try to ensure that we
4662 * either insert all file handles into the dictionary or none
4663 * at all. It's a little clumsy with the various popen modes
4664 * and variable number of files involved.
4665 */
4666 if (!_PyPopenProcs) {
4667 _PyPopenProcs = PyDict_New();
4668 }
4669
4670 if (_PyPopenProcs) {
4671 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
4672 int ins_rc[3];
4673
4674 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4675 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4676
4677 procObj = PyList_New(2);
4678 hProcessObj = PyLong_FromVoidPtr(hProcess);
4679 intObj = PyInt_FromLong(file_count);
4680
4681 if (procObj && hProcessObj && intObj) {
4682 PyList_SetItem(procObj,0,hProcessObj);
4683 PyList_SetItem(procObj,1,intObj);
4684
4685 fileObj[0] = PyLong_FromVoidPtr(f1);
4686 if (fileObj[0]) {
4687 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4688 fileObj[0],
4689 procObj);
4690 }
4691 if (file_count >= 2) {
4692 fileObj[1] = PyLong_FromVoidPtr(f2);
4693 if (fileObj[1]) {
4694 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4695 fileObj[1],
4696 procObj);
4697 }
4698 }
4699 if (file_count >= 3) {
4700 fileObj[2] = PyLong_FromVoidPtr(f3);
4701 if (fileObj[2]) {
4702 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4703 fileObj[2],
4704 procObj);
4705 }
4706 }
4707
4708 if (ins_rc[0] < 0 || !fileObj[0] ||
4709 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4710 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
4711 /* Something failed - remove any dictionary
4712 * entries that did make it.
4713 */
4714 if (!ins_rc[0] && fileObj[0]) {
4715 PyDict_DelItem(_PyPopenProcs,
4716 fileObj[0]);
4717 }
4718 if (!ins_rc[1] && fileObj[1]) {
4719 PyDict_DelItem(_PyPopenProcs,
4720 fileObj[1]);
4721 }
4722 if (!ins_rc[2] && fileObj[2]) {
4723 PyDict_DelItem(_PyPopenProcs,
4724 fileObj[2]);
4725 }
4726 }
4727 }
Tim Peters5aa91602002-01-30 05:46:57 +00004728
Mark Hammondb37a3732000-08-14 04:47:33 +00004729 /*
4730 * Clean up our localized references for the dictionary keys
4731 * and value since PyDict_SetItem will Py_INCREF any copies
4732 * that got placed in the dictionary.
4733 */
4734 Py_XDECREF(procObj);
4735 Py_XDECREF(fileObj[0]);
4736 Py_XDECREF(fileObj[1]);
4737 Py_XDECREF(fileObj[2]);
4738 }
4739
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004740 /* Child is launched. Close the parents copy of those pipe
4741 * handles that only the child should have open. You need to
4742 * make sure that no handles to the write end of the output pipe
4743 * are maintained in this process or else the pipe will not close
4744 * when the child process exits and the ReadFile will hang. */
4745
4746 if (!CloseHandle(hChildStdinRd))
4747 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004748
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004749 if (!CloseHandle(hChildStdoutWr))
4750 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004751
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004752 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
4753 return win32_error("CloseHandle", NULL);
4754
4755 return f;
4756}
Fredrik Lundh56055a42000-07-23 19:47:12 +00004757
4758/*
4759 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4760 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00004761 *
4762 * This function uses the _PyPopenProcs dictionary in order to map the
4763 * input file pointer to information about the process that was
4764 * originally created by the popen* call that created the file pointer.
4765 * The dictionary uses the file pointer as a key (with one entry
4766 * inserted for each file returned by the original popen* call) and a
4767 * single list object as the value for all files from a single call.
4768 * The list object contains the Win32 process handle at [0], and a file
4769 * count at [1], which is initialized to the total number of file
4770 * handles using that list.
4771 *
4772 * This function closes whichever handle it is passed, and decrements
4773 * the file count in the dictionary for the process handle pointed to
4774 * by this file. On the last close (when the file count reaches zero),
4775 * this function will wait for the child process and then return its
4776 * exit code as the result of the close() operation. This permits the
4777 * files to be closed in any order - it is always the close() of the
4778 * final handle that will return the exit code.
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004779 *
4780 * NOTE: This function is currently called with the GIL released.
4781 * hence we use the GILState API to manage our state.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004782 */
Tim Peters736aa322000-09-01 06:51:24 +00004783
Fredrik Lundh56055a42000-07-23 19:47:12 +00004784static int _PyPclose(FILE *file)
4785{
Fredrik Lundh20318932000-07-26 17:29:12 +00004786 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004787 DWORD exit_code;
4788 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00004789 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
4790 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00004791#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004792 PyGILState_STATE state;
Tim Peters736aa322000-09-01 06:51:24 +00004793#endif
4794
Fredrik Lundh20318932000-07-26 17:29:12 +00004795 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00004796 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00004797 */
4798 result = fclose(file);
Tim Peters736aa322000-09-01 06:51:24 +00004799#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004800 state = PyGILState_Ensure();
Tim Peters736aa322000-09-01 06:51:24 +00004801#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00004802 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00004803 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4804 (procObj = PyDict_GetItem(_PyPopenProcs,
4805 fileObj)) != NULL &&
4806 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
4807 (intObj = PyList_GetItem(procObj,1)) != NULL) {
4808
4809 hProcess = PyLong_AsVoidPtr(hProcessObj);
4810 file_count = PyInt_AsLong(intObj);
4811
4812 if (file_count > 1) {
4813 /* Still other files referencing process */
4814 file_count--;
4815 PyList_SetItem(procObj,1,
4816 PyInt_FromLong(file_count));
4817 } else {
4818 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00004819 if (result != EOF &&
4820 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
4821 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00004822 /* Possible truncation here in 16-bit environments, but
4823 * real exit codes are just the lower byte in any event.
4824 */
4825 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004826 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00004827 /* Indicate failure - this will cause the file object
4828 * to raise an I/O error and translate the last Win32
4829 * error code from errno. We do have a problem with
4830 * last errors that overlap the normal errno table,
4831 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004832 */
Fredrik Lundh20318932000-07-26 17:29:12 +00004833 if (result != EOF) {
4834 /* If the error wasn't from the fclose(), then
4835 * set errno for the file object error handling.
4836 */
4837 errno = GetLastError();
4838 }
4839 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004840 }
4841
4842 /* Free up the native handle at this point */
4843 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00004844 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00004845
Mark Hammondb37a3732000-08-14 04:47:33 +00004846 /* Remove this file pointer from dictionary */
4847 PyDict_DelItem(_PyPopenProcs, fileObj);
4848
4849 if (PyDict_Size(_PyPopenProcs) == 0) {
4850 Py_DECREF(_PyPopenProcs);
4851 _PyPopenProcs = NULL;
4852 }
4853
4854 } /* if object retrieval ok */
4855
4856 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004857 } /* if _PyPopenProcs */
4858
Tim Peters736aa322000-09-01 06:51:24 +00004859#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004860 PyGILState_Release(state);
Tim Peters736aa322000-09-01 06:51:24 +00004861#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00004862 return result;
4863}
Tim Peters9acdd3a2000-09-01 19:26:36 +00004864
4865#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00004866static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004867posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00004868{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004869 char *name;
4870 char *mode = "r";
4871 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00004872 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00004873 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004874 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00004875 return NULL;
Martin v. Löwis9ad853b2003-10-31 10:01:53 +00004876 /* Strip mode of binary or text modifiers */
4877 if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
4878 mode = "r";
4879 else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
4880 mode = "w";
Barry Warsaw53699e91996-12-10 23:23:01 +00004881 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004882 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004883 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00004884 if (fp == NULL)
4885 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004886 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004887 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00004888 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004889 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00004890}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004891
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004892#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004893#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00004894
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004895
Guido van Rossumb6775db1994-08-01 11:34:53 +00004896#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004897PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004898"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004899Set the current process's user id.");
4900
Barry Warsaw53699e91996-12-10 23:23:01 +00004901static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004902posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004903{
4904 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004905 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004906 return NULL;
4907 if (setuid(uid) < 0)
4908 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004909 Py_INCREF(Py_None);
4910 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004911}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004912#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004913
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004914
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004915#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004916PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004917"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004918Set the current process's effective user id.");
4919
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004920static PyObject *
4921posix_seteuid (PyObject *self, PyObject *args)
4922{
4923 int euid;
4924 if (!PyArg_ParseTuple(args, "i", &euid)) {
4925 return NULL;
4926 } else if (seteuid(euid) < 0) {
4927 return posix_error();
4928 } else {
4929 Py_INCREF(Py_None);
4930 return Py_None;
4931 }
4932}
4933#endif /* HAVE_SETEUID */
4934
4935#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004936PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004937"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004938Set the current process's effective group id.");
4939
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004940static PyObject *
4941posix_setegid (PyObject *self, PyObject *args)
4942{
4943 int egid;
4944 if (!PyArg_ParseTuple(args, "i", &egid)) {
4945 return NULL;
4946 } else if (setegid(egid) < 0) {
4947 return posix_error();
4948 } else {
4949 Py_INCREF(Py_None);
4950 return Py_None;
4951 }
4952}
4953#endif /* HAVE_SETEGID */
4954
4955#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004956PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004957"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004958Set the current process's real and effective user ids.");
4959
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004960static PyObject *
4961posix_setreuid (PyObject *self, PyObject *args)
4962{
4963 int ruid, euid;
4964 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
4965 return NULL;
4966 } else if (setreuid(ruid, euid) < 0) {
4967 return posix_error();
4968 } else {
4969 Py_INCREF(Py_None);
4970 return Py_None;
4971 }
4972}
4973#endif /* HAVE_SETREUID */
4974
4975#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004976PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004977"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004978Set the current process's real and effective group ids.");
4979
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004980static PyObject *
4981posix_setregid (PyObject *self, PyObject *args)
4982{
4983 int rgid, egid;
4984 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
4985 return NULL;
4986 } else if (setregid(rgid, egid) < 0) {
4987 return posix_error();
4988 } else {
4989 Py_INCREF(Py_None);
4990 return Py_None;
4991 }
4992}
4993#endif /* HAVE_SETREGID */
4994
Guido van Rossumb6775db1994-08-01 11:34:53 +00004995#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004996PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004997"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004998Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004999
Barry Warsaw53699e91996-12-10 23:23:01 +00005000static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005001posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005002{
5003 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005004 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005005 return NULL;
5006 if (setgid(gid) < 0)
5007 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005008 Py_INCREF(Py_None);
5009 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005010}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005011#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005012
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005013#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005014PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005015"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005016Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005017
5018static PyObject *
5019posix_setgroups(PyObject *self, PyObject *args)
5020{
5021 PyObject *groups;
5022 int i, len;
5023 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00005024
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005025 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
5026 return NULL;
5027 if (!PySequence_Check(groups)) {
5028 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
5029 return NULL;
5030 }
5031 len = PySequence_Size(groups);
5032 if (len > MAX_GROUPS) {
5033 PyErr_SetString(PyExc_ValueError, "too many groups");
5034 return NULL;
5035 }
5036 for(i = 0; i < len; i++) {
5037 PyObject *elem;
5038 elem = PySequence_GetItem(groups, i);
5039 if (!elem)
5040 return NULL;
5041 if (!PyInt_Check(elem)) {
Georg Brandla13c2442005-11-22 19:30:31 +00005042 if (!PyLong_Check(elem)) {
5043 PyErr_SetString(PyExc_TypeError,
5044 "groups must be integers");
5045 Py_DECREF(elem);
5046 return NULL;
5047 } else {
5048 unsigned long x = PyLong_AsUnsignedLong(elem);
5049 if (PyErr_Occurred()) {
5050 PyErr_SetString(PyExc_TypeError,
5051 "group id too big");
5052 Py_DECREF(elem);
5053 return NULL;
5054 }
5055 grouplist[i] = x;
5056 /* read back the value to see if it fitted in gid_t */
5057 if (grouplist[i] != x) {
5058 PyErr_SetString(PyExc_TypeError,
5059 "group id too big");
5060 Py_DECREF(elem);
5061 return NULL;
5062 }
5063 }
5064 } else {
5065 long x = PyInt_AsLong(elem);
5066 grouplist[i] = x;
5067 if (grouplist[i] != x) {
5068 PyErr_SetString(PyExc_TypeError,
5069 "group id too big");
5070 Py_DECREF(elem);
5071 return NULL;
5072 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005073 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005074 Py_DECREF(elem);
5075 }
5076
5077 if (setgroups(len, grouplist) < 0)
5078 return posix_error();
5079 Py_INCREF(Py_None);
5080 return Py_None;
5081}
5082#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005083
Guido van Rossumb6775db1994-08-01 11:34:53 +00005084#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005085PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005086"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005087Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005088
Barry Warsaw53699e91996-12-10 23:23:01 +00005089static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005090posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005091{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005092 int pid, options;
5093#ifdef UNION_WAIT
5094 union wait status;
5095#define status_i (status.w_status)
5096#else
5097 int status;
5098#define status_i status
5099#endif
5100 status_i = 0;
5101
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005102 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00005103 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005104 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00005105 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00005106 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00005107 if (pid == -1)
5108 return posix_error();
Guido van Rossum21803b81992-08-09 12:55:27 +00005109 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005110 return Py_BuildValue("ii", pid, status_i);
Guido van Rossum21803b81992-08-09 12:55:27 +00005111}
5112
Tim Petersab034fa2002-02-01 11:27:43 +00005113#elif defined(HAVE_CWAIT)
5114
5115/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005116PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005117"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005118"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00005119
5120static PyObject *
5121posix_waitpid(PyObject *self, PyObject *args)
5122{
Martin v. Löwis18e16552006-02-15 17:27:45 +00005123 intptr_t pid;
5124 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00005125
5126 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
5127 return NULL;
5128 Py_BEGIN_ALLOW_THREADS
5129 pid = _cwait(&status, pid, options);
5130 Py_END_ALLOW_THREADS
5131 if (pid == -1)
5132 return posix_error();
5133 else
5134 /* shift the status left a byte so this is more like the
5135 POSIX waitpid */
5136 return Py_BuildValue("ii", pid, status << 8);
5137}
5138#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005139
Guido van Rossumad0ee831995-03-01 10:34:45 +00005140#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005141PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005142"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005143Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005144
Barry Warsaw53699e91996-12-10 23:23:01 +00005145static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005146posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00005147{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005148 int pid;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005149#ifdef UNION_WAIT
5150 union wait status;
5151#define status_i (status.w_status)
Guido van Rossumb9f866c1997-05-22 15:12:39 +00005152#else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005153 int status;
5154#define status_i status
Guido van Rossumb9f866c1997-05-22 15:12:39 +00005155#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00005156
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005157 status_i = 0;
5158 Py_BEGIN_ALLOW_THREADS
5159 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00005160 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00005161 if (pid == -1)
5162 return posix_error();
5163 else
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005164 return Py_BuildValue("ii", pid, status_i);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005165#undef status_i
Guido van Rossum85e3b011991-06-03 12:42:10 +00005166}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005167#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005168
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005169
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005170PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005171"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005172Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005173
Barry Warsaw53699e91996-12-10 23:23:01 +00005174static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005175posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005176{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005177#ifdef HAVE_LSTAT
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005178 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005179#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005180#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00005181 return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005182#else
5183 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
5184#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005185#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005186}
5187
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005188
Guido van Rossumb6775db1994-08-01 11:34:53 +00005189#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005190PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005191"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005192Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005193
Barry Warsaw53699e91996-12-10 23:23:01 +00005194static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005195posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005196{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005197 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00005198 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005199 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005200 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005201 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005202 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00005203 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00005204 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005205 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00005206 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00005207 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005208}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005209#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005210
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005211
Guido van Rossumb6775db1994-08-01 11:34:53 +00005212#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005213PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005214"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00005215Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005216
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005217static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005218posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005219{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005220 return posix_2str(args, "etet:symlink", symlink, NULL, NULL);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005221}
5222#endif /* HAVE_SYMLINK */
5223
5224
5225#ifdef HAVE_TIMES
5226#ifndef HZ
5227#define HZ 60 /* Universal constant :-) */
5228#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00005229
Guido van Rossumd48f2521997-12-05 22:19:34 +00005230#if defined(PYCC_VACPP) && defined(PYOS_OS2)
5231static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005232system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005233{
5234 ULONG value = 0;
5235
5236 Py_BEGIN_ALLOW_THREADS
5237 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
5238 Py_END_ALLOW_THREADS
5239
5240 return value;
5241}
5242
5243static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005244posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005245{
Guido van Rossumd48f2521997-12-05 22:19:34 +00005246 /* Currently Only Uptime is Provided -- Others Later */
5247 return Py_BuildValue("ddddd",
5248 (double)0 /* t.tms_utime / HZ */,
5249 (double)0 /* t.tms_stime / HZ */,
5250 (double)0 /* t.tms_cutime / HZ */,
5251 (double)0 /* t.tms_cstime / HZ */,
5252 (double)system_uptime() / 1000);
5253}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005254#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00005255static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005256posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00005257{
5258 struct tms t;
5259 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +00005260 errno = 0;
5261 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00005262 if (c == (clock_t) -1)
5263 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005264 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00005265 (double)t.tms_utime / HZ,
5266 (double)t.tms_stime / HZ,
5267 (double)t.tms_cutime / HZ,
5268 (double)t.tms_cstime / HZ,
5269 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00005270}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005271#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005272#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005273
5274
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005275#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005276#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00005277static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005278posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005279{
5280 FILETIME create, exit, kernel, user;
5281 HANDLE hProc;
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005282 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00005283 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
5284 /* The fields of a FILETIME structure are the hi and lo part
5285 of a 64-bit value expressed in 100 nanosecond units.
5286 1e7 is one second in such units; 1e-7 the inverse.
5287 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
5288 */
Barry Warsaw53699e91996-12-10 23:23:01 +00005289 return Py_BuildValue(
5290 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00005291 (double)(kernel.dwHighDateTime*429.4967296 +
5292 kernel.dwLowDateTime*1e-7),
5293 (double)(user.dwHighDateTime*429.4967296 +
5294 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00005295 (double)0,
5296 (double)0,
5297 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005298}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005299#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005300
5301#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005302PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005303"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005304Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005305#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005306
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005307
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00005308#ifdef HAVE_GETSID
5309PyDoc_STRVAR(posix_getsid__doc__,
5310"getsid(pid) -> sid\n\n\
5311Call the system call getsid().");
5312
5313static PyObject *
5314posix_getsid(PyObject *self, PyObject *args)
5315{
5316 int pid, sid;
5317 if (!PyArg_ParseTuple(args, "i:getsid", &pid))
5318 return NULL;
5319 sid = getsid(pid);
5320 if (sid < 0)
5321 return posix_error();
5322 return PyInt_FromLong((long)sid);
5323}
5324#endif /* HAVE_GETSID */
5325
5326
Guido van Rossumb6775db1994-08-01 11:34:53 +00005327#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005328PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005329"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005330Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005331
Barry Warsaw53699e91996-12-10 23:23:01 +00005332static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005333posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005334{
Guido van Rossum687dd131993-05-17 08:34:16 +00005335 if (setsid() < 0)
5336 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005337 Py_INCREF(Py_None);
5338 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005339}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005340#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005341
Guido van Rossumb6775db1994-08-01 11:34:53 +00005342#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005343PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005344"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005345Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005346
Barry Warsaw53699e91996-12-10 23:23:01 +00005347static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005348posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005349{
5350 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005351 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00005352 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005353 if (setpgid(pid, pgrp) < 0)
5354 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005355 Py_INCREF(Py_None);
5356 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005357}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005358#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005359
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005360
Guido van Rossumb6775db1994-08-01 11:34:53 +00005361#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005362PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005363"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005364Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005365
Barry Warsaw53699e91996-12-10 23:23:01 +00005366static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005367posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005368{
5369 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005370 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00005371 return NULL;
5372 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005373 if (pgid < 0)
5374 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005375 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00005376}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005377#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00005378
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005379
Guido van Rossumb6775db1994-08-01 11:34:53 +00005380#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005381PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005382"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005383Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005384
Barry Warsaw53699e91996-12-10 23:23:01 +00005385static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005386posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005387{
5388 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005389 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00005390 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005391 if (tcsetpgrp(fd, pgid) < 0)
5392 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00005393 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00005394 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00005395}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005396#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00005397
Guido van Rossum687dd131993-05-17 08:34:16 +00005398/* Functions acting on file descriptors */
5399
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005400PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005401"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005402Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005403
Barry Warsaw53699e91996-12-10 23:23:01 +00005404static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005405posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005406{
Mark Hammondef8b6542001-05-13 08:04:26 +00005407 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005408 int flag;
5409 int mode = 0777;
5410 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005411
5412#ifdef MS_WINDOWS
5413 if (unicode_file_names()) {
5414 PyUnicodeObject *po;
5415 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
5416 Py_BEGIN_ALLOW_THREADS
5417 /* PyUnicode_AS_UNICODE OK without thread
5418 lock as it is a simple dereference. */
5419 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
5420 Py_END_ALLOW_THREADS
5421 if (fd < 0)
5422 return posix_error();
5423 return PyInt_FromLong((long)fd);
5424 }
5425 /* Drop the argument parsing error as narrow strings
5426 are also valid. */
5427 PyErr_Clear();
5428 }
5429#endif
5430
Tim Peters5aa91602002-01-30 05:46:57 +00005431 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00005432 Py_FileSystemDefaultEncoding, &file,
5433 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00005434 return NULL;
5435
Barry Warsaw53699e91996-12-10 23:23:01 +00005436 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005437 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005438 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005439 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00005440 return posix_error_with_allocated_filename(file);
5441 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00005442 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005443}
5444
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005445
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005446PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005447"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005448Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005449
Barry Warsaw53699e91996-12-10 23:23:01 +00005450static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005451posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005452{
5453 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005454 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005455 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005456 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005457 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00005458 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005459 if (res < 0)
5460 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005461 Py_INCREF(Py_None);
5462 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005463}
5464
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005465
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005466PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005467"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005468Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005469
Barry Warsaw53699e91996-12-10 23:23:01 +00005470static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005471posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005472{
5473 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005474 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005475 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005476 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005477 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00005478 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005479 if (fd < 0)
5480 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005481 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005482}
5483
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005484
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005485PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00005486"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005487Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005488
Barry Warsaw53699e91996-12-10 23:23:01 +00005489static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005490posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005491{
5492 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005493 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00005494 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005495 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005496 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00005497 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005498 if (res < 0)
5499 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005500 Py_INCREF(Py_None);
5501 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005502}
5503
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005504
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005505PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005506"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005507Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005508
Barry Warsaw53699e91996-12-10 23:23:01 +00005509static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005510posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005511{
5512 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005513#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005514 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005515#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00005516 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005517#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005518 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005519 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00005520 return NULL;
5521#ifdef SEEK_SET
5522 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
5523 switch (how) {
5524 case 0: how = SEEK_SET; break;
5525 case 1: how = SEEK_CUR; break;
5526 case 2: how = SEEK_END; break;
5527 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005528#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005529
5530#if !defined(HAVE_LARGEFILE_SUPPORT)
5531 pos = PyInt_AsLong(posobj);
5532#else
5533 pos = PyLong_Check(posobj) ?
5534 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
5535#endif
5536 if (PyErr_Occurred())
5537 return NULL;
5538
Barry Warsaw53699e91996-12-10 23:23:01 +00005539 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005540#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00005541 res = _lseeki64(fd, pos, how);
5542#else
Guido van Rossum687dd131993-05-17 08:34:16 +00005543 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005544#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005545 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005546 if (res < 0)
5547 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00005548
5549#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00005550 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005551#else
5552 return PyLong_FromLongLong(res);
5553#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005554}
5555
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005556
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005557PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005558"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005559Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005560
Barry Warsaw53699e91996-12-10 23:23:01 +00005561static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005562posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005563{
Guido van Rossum8bac5461996-06-11 18:38:48 +00005564 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00005565 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005566 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005567 return NULL;
Michael W. Hudson9867ced2005-01-31 17:01:59 +00005568 if (size < 0) {
5569 errno = EINVAL;
5570 return posix_error();
5571 }
Barry Warsaw53699e91996-12-10 23:23:01 +00005572 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005573 if (buffer == NULL)
5574 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005575 Py_BEGIN_ALLOW_THREADS
5576 n = read(fd, PyString_AsString(buffer), size);
5577 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00005578 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005579 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00005580 return posix_error();
5581 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00005582 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00005583 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00005584 return buffer;
5585}
5586
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005587
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005588PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005589"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005590Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005591
Barry Warsaw53699e91996-12-10 23:23:01 +00005592static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005593posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005594{
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005595 int fd;
5596 Py_ssize_t size;
Guido van Rossum687dd131993-05-17 08:34:16 +00005597 char *buffer;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005598
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005599 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005600 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005601 Py_BEGIN_ALLOW_THREADS
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005602 size = write(fd, buffer, (size_t)size);
Barry Warsaw53699e91996-12-10 23:23:01 +00005603 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005604 if (size < 0)
5605 return posix_error();
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005606 return PyInt_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005607}
5608
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005609
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005610PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005611"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005612Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005613
Barry Warsaw53699e91996-12-10 23:23:01 +00005614static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005615posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005616{
5617 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00005618 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00005619 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005620 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005621 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005622#ifdef __VMS
5623 /* on OpenVMS we must ensure that all bytes are written to the file */
5624 fsync(fd);
5625#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005626 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00005627 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00005628 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00005629 if (res != 0) {
5630#ifdef MS_WINDOWS
5631 return win32_error("fstat", NULL);
5632#else
Guido van Rossum687dd131993-05-17 08:34:16 +00005633 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00005634#endif
5635 }
Tim Peters5aa91602002-01-30 05:46:57 +00005636
Martin v. Löwis14694662006-02-03 12:54:16 +00005637 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00005638}
5639
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005640
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005641PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005642"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005643Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005644
Barry Warsaw53699e91996-12-10 23:23:01 +00005645static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005646posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005647{
Guido van Rossum687dd131993-05-17 08:34:16 +00005648 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005649 char *mode = "r";
5650 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00005651 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00005652 PyObject *f;
5653 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00005654 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00005655
Thomas Heller1f043e22002-11-07 16:00:59 +00005656 if (mode[0] != 'r' && mode[0] != 'w' && mode[0] != 'a') {
5657 PyErr_Format(PyExc_ValueError,
5658 "invalid file mode '%s'", mode);
5659 return NULL;
5660 }
5661
Barry Warsaw53699e91996-12-10 23:23:01 +00005662 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005663 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005664 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005665 if (fp == NULL)
5666 return posix_error();
Guido van Rossumbd6be7a2002-09-15 18:45:46 +00005667 f = PyFile_FromFile(fp, "<fdopen>", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005668 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00005669 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005670 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00005671}
5672
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005673PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005674"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005675Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005676connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00005677
5678static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00005679posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00005680{
5681 int fd;
5682 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
5683 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005684 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00005685}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005686
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005687#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005688PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005689"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005690Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005691
Barry Warsaw53699e91996-12-10 23:23:01 +00005692static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005693posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00005694{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005695#if defined(PYOS_OS2)
5696 HFILE read, write;
5697 APIRET rc;
5698
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005699 Py_BEGIN_ALLOW_THREADS
5700 rc = DosCreatePipe( &read, &write, 4096);
5701 Py_END_ALLOW_THREADS
5702 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005703 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005704
5705 return Py_BuildValue("(ii)", read, write);
5706#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005707#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00005708 int fds[2];
5709 int res;
Barry Warsaw53699e91996-12-10 23:23:01 +00005710 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005711 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00005712 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005713 if (res != 0)
5714 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005715 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005716#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00005717 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005718 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00005719 BOOL ok;
Barry Warsaw53699e91996-12-10 23:23:01 +00005720 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005721 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00005722 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00005723 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005724 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00005725 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
5726 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005727 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005728#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005729#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005730}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005731#endif /* HAVE_PIPE */
5732
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005733
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005734#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005735PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005736"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005737Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005738
Barry Warsaw53699e91996-12-10 23:23:01 +00005739static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005740posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005741{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005742 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005743 int mode = 0666;
5744 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005745 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005746 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005747 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005748 res = mkfifo(filename, mode);
5749 Py_END_ALLOW_THREADS
5750 if (res < 0)
5751 return posix_error();
5752 Py_INCREF(Py_None);
5753 return Py_None;
5754}
5755#endif
5756
5757
Neal Norwitz11690112002-07-30 01:08:28 +00005758#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005759PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005760"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005761Create a filesystem node (file, device special file or named pipe)\n\
5762named filename. mode specifies both the permissions to use and the\n\
5763type of node to be created, being combined (bitwise OR) with one of\n\
5764S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005765device defines the newly created device special file (probably using\n\
5766os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005767
5768
5769static PyObject *
5770posix_mknod(PyObject *self, PyObject *args)
5771{
5772 char *filename;
5773 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005774 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005775 int res;
Martin v. Löwisd631ebe2002-11-02 17:42:33 +00005776 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005777 return NULL;
5778 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005779 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00005780 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005781 if (res < 0)
5782 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005783 Py_INCREF(Py_None);
5784 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005785}
5786#endif
5787
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005788#ifdef HAVE_DEVICE_MACROS
5789PyDoc_STRVAR(posix_major__doc__,
5790"major(device) -> major number\n\
5791Extracts a device major number from a raw device number.");
5792
5793static PyObject *
5794posix_major(PyObject *self, PyObject *args)
5795{
5796 int device;
5797 if (!PyArg_ParseTuple(args, "i:major", &device))
5798 return NULL;
5799 return PyInt_FromLong((long)major(device));
5800}
5801
5802PyDoc_STRVAR(posix_minor__doc__,
5803"minor(device) -> minor number\n\
5804Extracts a device minor number from a raw device number.");
5805
5806static PyObject *
5807posix_minor(PyObject *self, PyObject *args)
5808{
5809 int device;
5810 if (!PyArg_ParseTuple(args, "i:minor", &device))
5811 return NULL;
5812 return PyInt_FromLong((long)minor(device));
5813}
5814
5815PyDoc_STRVAR(posix_makedev__doc__,
5816"makedev(major, minor) -> device number\n\
5817Composes a raw device number from the major and minor device numbers.");
5818
5819static PyObject *
5820posix_makedev(PyObject *self, PyObject *args)
5821{
5822 int major, minor;
5823 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
5824 return NULL;
5825 return PyInt_FromLong((long)makedev(major, minor));
5826}
5827#endif /* device macros */
5828
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005829
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005830#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005831PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005832"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005833Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005834
Barry Warsaw53699e91996-12-10 23:23:01 +00005835static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005836posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005837{
5838 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005839 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005840 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005841 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005842
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005843 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005844 return NULL;
5845
5846#if !defined(HAVE_LARGEFILE_SUPPORT)
5847 length = PyInt_AsLong(lenobj);
5848#else
5849 length = PyLong_Check(lenobj) ?
5850 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
5851#endif
5852 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005853 return NULL;
5854
Barry Warsaw53699e91996-12-10 23:23:01 +00005855 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005856 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00005857 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005858 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005859 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005860 return NULL;
5861 }
Barry Warsaw53699e91996-12-10 23:23:01 +00005862 Py_INCREF(Py_None);
5863 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005864}
5865#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005866
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005867#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005868PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005869"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005870Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005871
Fred Drake762e2061999-08-26 17:23:54 +00005872/* Save putenv() parameters as values here, so we can collect them when they
5873 * get re-set with another call for the same key. */
5874static PyObject *posix_putenv_garbage;
5875
Tim Peters5aa91602002-01-30 05:46:57 +00005876static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005877posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005878{
5879 char *s1, *s2;
5880 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00005881 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00005882 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005883
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005884 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005885 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00005886
5887#if defined(PYOS_OS2)
5888 if (stricmp(s1, "BEGINLIBPATH") == 0) {
5889 APIRET rc;
5890
Guido van Rossumd48f2521997-12-05 22:19:34 +00005891 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
5892 if (rc != NO_ERROR)
5893 return os2_error(rc);
5894
5895 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
5896 APIRET rc;
5897
Guido van Rossumd48f2521997-12-05 22:19:34 +00005898 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
5899 if (rc != NO_ERROR)
5900 return os2_error(rc);
5901 } else {
5902#endif
5903
Fred Drake762e2061999-08-26 17:23:54 +00005904 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00005905 len = strlen(s1) + strlen(s2) + 2;
5906 /* len includes space for a trailing \0; the size arg to
5907 PyString_FromStringAndSize does not count that */
5908 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00005909 if (newstr == NULL)
5910 return PyErr_NoMemory();
5911 new = PyString_AS_STRING(newstr);
Tim Petersc8996f52001-12-03 20:41:00 +00005912 PyOS_snprintf(new, len, "%s=%s", s1, s2);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005913 if (putenv(new)) {
Neal Norwitz4adc9ab2003-02-10 03:10:43 +00005914 Py_DECREF(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005915 posix_error();
5916 return NULL;
5917 }
Fred Drake762e2061999-08-26 17:23:54 +00005918 /* Install the first arg and newstr in posix_putenv_garbage;
5919 * this will cause previous value to be collected. This has to
5920 * happen after the real putenv() call because the old value
5921 * was still accessible until then. */
5922 if (PyDict_SetItem(posix_putenv_garbage,
5923 PyTuple_GET_ITEM(args, 0), newstr)) {
5924 /* really not much we can do; just leak */
5925 PyErr_Clear();
5926 }
5927 else {
5928 Py_DECREF(newstr);
5929 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00005930
5931#if defined(PYOS_OS2)
5932 }
5933#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005934 Py_INCREF(Py_None);
5935 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005936}
Guido van Rossumb6a47161997-09-15 22:54:34 +00005937#endif /* putenv */
5938
Guido van Rossumc524d952001-10-19 01:31:59 +00005939#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005940PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005941"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005942Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00005943
5944static PyObject *
5945posix_unsetenv(PyObject *self, PyObject *args)
5946{
5947 char *s1;
5948
5949 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
5950 return NULL;
5951
5952 unsetenv(s1);
5953
5954 /* Remove the key from posix_putenv_garbage;
5955 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00005956 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00005957 * old value was still accessible until then.
5958 */
5959 if (PyDict_DelItem(posix_putenv_garbage,
5960 PyTuple_GET_ITEM(args, 0))) {
5961 /* really not much we can do; just leak */
5962 PyErr_Clear();
5963 }
5964
5965 Py_INCREF(Py_None);
5966 return Py_None;
5967}
5968#endif /* unsetenv */
5969
Guido van Rossumb6a47161997-09-15 22:54:34 +00005970#ifdef HAVE_STRERROR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005971PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005972"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005973Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005974
Guido van Rossumf68d8e52001-04-14 17:55:09 +00005975static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005976posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00005977{
5978 int code;
5979 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005980 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00005981 return NULL;
5982 message = strerror(code);
5983 if (message == NULL) {
5984 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00005985 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00005986 return NULL;
5987 }
5988 return PyString_FromString(message);
5989}
5990#endif /* strerror */
5991
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005992
Guido van Rossumc9641791998-08-04 15:26:23 +00005993#ifdef HAVE_SYS_WAIT_H
5994
Fred Drake106c1a02002-04-23 15:58:02 +00005995#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005996PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005997"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005998Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00005999
6000static PyObject *
6001posix_WCOREDUMP(PyObject *self, PyObject *args)
6002{
6003#ifdef UNION_WAIT
6004 union wait status;
6005#define status_i (status.w_status)
6006#else
6007 int status;
6008#define status_i status
6009#endif
6010 status_i = 0;
6011
6012 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &status_i))
6013 {
6014 return NULL;
6015 }
6016
6017 return PyBool_FromLong(WCOREDUMP(status));
6018#undef status_i
6019}
6020#endif /* WCOREDUMP */
6021
6022#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006023PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006024"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006025Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006026job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00006027
6028static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006029posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00006030{
6031#ifdef UNION_WAIT
6032 union wait status;
6033#define status_i (status.w_status)
6034#else
6035 int status;
6036#define status_i status
6037#endif
6038 status_i = 0;
6039
6040 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &status_i))
6041 {
6042 return NULL;
6043 }
6044
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006045 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006046#undef status_i
6047}
6048#endif /* WIFCONTINUED */
6049
Guido van Rossumc9641791998-08-04 15:26:23 +00006050#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006051PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006052"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006053Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006054
6055static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006056posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006057{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006058#ifdef UNION_WAIT
6059 union wait status;
6060#define status_i (status.w_status)
6061#else
6062 int status;
6063#define status_i status
6064#endif
6065 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006066
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006067 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00006068 {
6069 return NULL;
6070 }
Tim Peters5aa91602002-01-30 05:46:57 +00006071
Fred Drake106c1a02002-04-23 15:58:02 +00006072 return PyBool_FromLong(WIFSTOPPED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006073#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00006074}
6075#endif /* WIFSTOPPED */
6076
6077#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006078PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006079"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006080Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006081
6082static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006083posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006084{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006085#ifdef UNION_WAIT
6086 union wait status;
6087#define status_i (status.w_status)
6088#else
6089 int status;
6090#define status_i status
6091#endif
6092 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006093
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006094 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00006095 {
6096 return NULL;
6097 }
Tim Peters5aa91602002-01-30 05:46:57 +00006098
Fred Drake106c1a02002-04-23 15:58:02 +00006099 return PyBool_FromLong(WIFSIGNALED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006100#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00006101}
6102#endif /* WIFSIGNALED */
6103
6104#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006105PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006106"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006107Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006108system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006109
6110static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006111posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006112{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006113#ifdef UNION_WAIT
6114 union wait status;
6115#define status_i (status.w_status)
6116#else
6117 int status;
6118#define status_i status
6119#endif
6120 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006121
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006122 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00006123 {
6124 return NULL;
6125 }
Tim Peters5aa91602002-01-30 05:46:57 +00006126
Fred Drake106c1a02002-04-23 15:58:02 +00006127 return PyBool_FromLong(WIFEXITED(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006128#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00006129}
6130#endif /* WIFEXITED */
6131
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006132#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006133PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006134"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006135Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006136
6137static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006138posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006139{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006140#ifdef UNION_WAIT
6141 union wait status;
6142#define status_i (status.w_status)
6143#else
6144 int status;
6145#define status_i status
6146#endif
6147 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006148
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006149 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00006150 {
6151 return NULL;
6152 }
Tim Peters5aa91602002-01-30 05:46:57 +00006153
Guido van Rossumc9641791998-08-04 15:26:23 +00006154 return Py_BuildValue("i", WEXITSTATUS(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006155#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00006156}
6157#endif /* WEXITSTATUS */
6158
6159#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006160PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006161"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006162Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006163value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006164
6165static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006166posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006167{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006168#ifdef UNION_WAIT
6169 union wait status;
6170#define status_i (status.w_status)
6171#else
6172 int status;
6173#define status_i status
6174#endif
6175 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006176
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006177 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00006178 {
6179 return NULL;
6180 }
Tim Peters5aa91602002-01-30 05:46:57 +00006181
Guido van Rossumc9641791998-08-04 15:26:23 +00006182 return Py_BuildValue("i", WTERMSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006183#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00006184}
6185#endif /* WTERMSIG */
6186
6187#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006188PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006189"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006190Return the signal that stopped the process that provided\n\
6191the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006192
6193static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006194posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006195{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006196#ifdef UNION_WAIT
6197 union wait status;
6198#define status_i (status.w_status)
6199#else
6200 int status;
6201#define status_i status
6202#endif
6203 status_i = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006204
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006205 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
Guido van Rossumc9641791998-08-04 15:26:23 +00006206 {
6207 return NULL;
6208 }
Tim Peters5aa91602002-01-30 05:46:57 +00006209
Guido van Rossumc9641791998-08-04 15:26:23 +00006210 return Py_BuildValue("i", WSTOPSIG(status));
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006211#undef status_i
Guido van Rossumc9641791998-08-04 15:26:23 +00006212}
6213#endif /* WSTOPSIG */
6214
6215#endif /* HAVE_SYS_WAIT_H */
6216
6217
Guido van Rossum94f6f721999-01-06 18:42:14 +00006218#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00006219#ifdef _SCO_DS
6220/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
6221 needed definitions in sys/statvfs.h */
6222#define _SVID3
6223#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006224#include <sys/statvfs.h>
6225
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006226static PyObject*
6227_pystatvfs_fromstructstatvfs(struct statvfs st) {
6228 PyObject *v = PyStructSequence_New(&StatVFSResultType);
6229 if (v == NULL)
6230 return NULL;
6231
6232#if !defined(HAVE_LARGEFILE_SUPPORT)
6233 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6234 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
6235 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
6236 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
6237 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
6238 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
6239 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
6240 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
6241 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6242 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6243#else
6244 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6245 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00006246 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006247 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00006248 PyStructSequence_SET_ITEM(v, 3,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006249 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006250 PyStructSequence_SET_ITEM(v, 4,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006251 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00006252 PyStructSequence_SET_ITEM(v, 5,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006253 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00006254 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006255 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00006256 PyStructSequence_SET_ITEM(v, 7,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006257 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006258 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6259 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6260#endif
6261
6262 return v;
6263}
6264
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006265PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006266"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006267Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006268
6269static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006270posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006271{
6272 int fd, res;
6273 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006274
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006275 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006276 return NULL;
6277 Py_BEGIN_ALLOW_THREADS
6278 res = fstatvfs(fd, &st);
6279 Py_END_ALLOW_THREADS
6280 if (res != 0)
6281 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006282
6283 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006284}
6285#endif /* HAVE_FSTATVFS */
6286
6287
6288#if defined(HAVE_STATVFS)
6289#include <sys/statvfs.h>
6290
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006291PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006292"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006293Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006294
6295static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006296posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006297{
6298 char *path;
6299 int res;
6300 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006301 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006302 return NULL;
6303 Py_BEGIN_ALLOW_THREADS
6304 res = statvfs(path, &st);
6305 Py_END_ALLOW_THREADS
6306 if (res != 0)
6307 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006308
6309 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006310}
6311#endif /* HAVE_STATVFS */
6312
6313
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006314#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006315PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006316"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006317Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00006318The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006319or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006320
6321static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006322posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006323{
6324 PyObject *result = NULL;
6325 char *dir = NULL;
6326 char *pfx = NULL;
6327 char *name;
6328
6329 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
6330 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00006331
6332 if (PyErr_Warn(PyExc_RuntimeWarning,
6333 "tempnam is a potential security risk to your program") < 0)
6334 return NULL;
6335
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006336#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00006337 name = _tempnam(dir, pfx);
6338#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006339 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00006340#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006341 if (name == NULL)
6342 return PyErr_NoMemory();
6343 result = PyString_FromString(name);
6344 free(name);
6345 return result;
6346}
Guido van Rossumd371ff11999-01-25 16:12:23 +00006347#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006348
6349
6350#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006351PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006352"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006353Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006354
6355static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006356posix_tmpfile(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006357{
6358 FILE *fp;
6359
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006360 fp = tmpfile();
6361 if (fp == NULL)
6362 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00006363 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006364}
6365#endif
6366
6367
6368#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006369PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006370"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006371Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006372
6373static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006374posix_tmpnam(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006375{
6376 char buffer[L_tmpnam];
6377 char *name;
6378
Skip Montanaro95618b52001-08-18 18:52:10 +00006379 if (PyErr_Warn(PyExc_RuntimeWarning,
6380 "tmpnam is a potential security risk to your program") < 0)
6381 return NULL;
6382
Greg Wardb48bc172000-03-01 21:51:56 +00006383#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006384 name = tmpnam_r(buffer);
6385#else
6386 name = tmpnam(buffer);
6387#endif
6388 if (name == NULL) {
6389 PyErr_SetObject(PyExc_OSError,
6390 Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00006391#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006392 "unexpected NULL from tmpnam_r"
6393#else
6394 "unexpected NULL from tmpnam"
6395#endif
6396 ));
6397 return NULL;
6398 }
6399 return PyString_FromString(buffer);
6400}
6401#endif
6402
6403
Fred Drakec9680921999-12-13 16:37:25 +00006404/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
6405 * It maps strings representing configuration variable names to
6406 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00006407 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00006408 * rarely-used constants. There are three separate tables that use
6409 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00006410 *
6411 * This code is always included, even if none of the interfaces that
6412 * need it are included. The #if hackery needed to avoid it would be
6413 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00006414 */
6415struct constdef {
6416 char *name;
6417 long value;
6418};
6419
Fred Drake12c6e2d1999-12-14 21:25:03 +00006420static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006421conv_confname(PyObject *arg, int *valuep, struct constdef *table,
6422 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006423{
6424 if (PyInt_Check(arg)) {
6425 *valuep = PyInt_AS_LONG(arg);
6426 return 1;
6427 }
6428 if (PyString_Check(arg)) {
6429 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00006430 size_t lo = 0;
6431 size_t mid;
6432 size_t hi = tablesize;
6433 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006434 char *confname = PyString_AS_STRING(arg);
6435 while (lo < hi) {
6436 mid = (lo + hi) / 2;
6437 cmp = strcmp(confname, table[mid].name);
6438 if (cmp < 0)
6439 hi = mid;
6440 else if (cmp > 0)
6441 lo = mid + 1;
6442 else {
6443 *valuep = table[mid].value;
6444 return 1;
6445 }
6446 }
6447 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
6448 }
6449 else
6450 PyErr_SetString(PyExc_TypeError,
6451 "configuration names must be strings or integers");
6452 return 0;
6453}
6454
6455
6456#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
6457static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006458#ifdef _PC_ABI_AIO_XFER_MAX
6459 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
6460#endif
6461#ifdef _PC_ABI_ASYNC_IO
6462 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
6463#endif
Fred Drakec9680921999-12-13 16:37:25 +00006464#ifdef _PC_ASYNC_IO
6465 {"PC_ASYNC_IO", _PC_ASYNC_IO},
6466#endif
6467#ifdef _PC_CHOWN_RESTRICTED
6468 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
6469#endif
6470#ifdef _PC_FILESIZEBITS
6471 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
6472#endif
6473#ifdef _PC_LAST
6474 {"PC_LAST", _PC_LAST},
6475#endif
6476#ifdef _PC_LINK_MAX
6477 {"PC_LINK_MAX", _PC_LINK_MAX},
6478#endif
6479#ifdef _PC_MAX_CANON
6480 {"PC_MAX_CANON", _PC_MAX_CANON},
6481#endif
6482#ifdef _PC_MAX_INPUT
6483 {"PC_MAX_INPUT", _PC_MAX_INPUT},
6484#endif
6485#ifdef _PC_NAME_MAX
6486 {"PC_NAME_MAX", _PC_NAME_MAX},
6487#endif
6488#ifdef _PC_NO_TRUNC
6489 {"PC_NO_TRUNC", _PC_NO_TRUNC},
6490#endif
6491#ifdef _PC_PATH_MAX
6492 {"PC_PATH_MAX", _PC_PATH_MAX},
6493#endif
6494#ifdef _PC_PIPE_BUF
6495 {"PC_PIPE_BUF", _PC_PIPE_BUF},
6496#endif
6497#ifdef _PC_PRIO_IO
6498 {"PC_PRIO_IO", _PC_PRIO_IO},
6499#endif
6500#ifdef _PC_SOCK_MAXBUF
6501 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
6502#endif
6503#ifdef _PC_SYNC_IO
6504 {"PC_SYNC_IO", _PC_SYNC_IO},
6505#endif
6506#ifdef _PC_VDISABLE
6507 {"PC_VDISABLE", _PC_VDISABLE},
6508#endif
6509};
6510
Fred Drakec9680921999-12-13 16:37:25 +00006511static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006512conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006513{
6514 return conv_confname(arg, valuep, posix_constants_pathconf,
6515 sizeof(posix_constants_pathconf)
6516 / sizeof(struct constdef));
6517}
6518#endif
6519
6520#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006521PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006522"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006523Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006524If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006525
6526static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006527posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006528{
6529 PyObject *result = NULL;
6530 int name, fd;
6531
Fred Drake12c6e2d1999-12-14 21:25:03 +00006532 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
6533 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00006534 long limit;
6535
6536 errno = 0;
6537 limit = fpathconf(fd, name);
6538 if (limit == -1 && errno != 0)
6539 posix_error();
6540 else
6541 result = PyInt_FromLong(limit);
6542 }
6543 return result;
6544}
6545#endif
6546
6547
6548#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006549PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006550"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006551Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006552If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006553
6554static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006555posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006556{
6557 PyObject *result = NULL;
6558 int name;
6559 char *path;
6560
6561 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
6562 conv_path_confname, &name)) {
6563 long limit;
6564
6565 errno = 0;
6566 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006567 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00006568 if (errno == EINVAL)
6569 /* could be a path or name problem */
6570 posix_error();
6571 else
6572 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006573 }
Fred Drakec9680921999-12-13 16:37:25 +00006574 else
6575 result = PyInt_FromLong(limit);
6576 }
6577 return result;
6578}
6579#endif
6580
6581#ifdef HAVE_CONFSTR
6582static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006583#ifdef _CS_ARCHITECTURE
6584 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
6585#endif
6586#ifdef _CS_HOSTNAME
6587 {"CS_HOSTNAME", _CS_HOSTNAME},
6588#endif
6589#ifdef _CS_HW_PROVIDER
6590 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
6591#endif
6592#ifdef _CS_HW_SERIAL
6593 {"CS_HW_SERIAL", _CS_HW_SERIAL},
6594#endif
6595#ifdef _CS_INITTAB_NAME
6596 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
6597#endif
Fred Drakec9680921999-12-13 16:37:25 +00006598#ifdef _CS_LFS64_CFLAGS
6599 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
6600#endif
6601#ifdef _CS_LFS64_LDFLAGS
6602 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
6603#endif
6604#ifdef _CS_LFS64_LIBS
6605 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
6606#endif
6607#ifdef _CS_LFS64_LINTFLAGS
6608 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
6609#endif
6610#ifdef _CS_LFS_CFLAGS
6611 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
6612#endif
6613#ifdef _CS_LFS_LDFLAGS
6614 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
6615#endif
6616#ifdef _CS_LFS_LIBS
6617 {"CS_LFS_LIBS", _CS_LFS_LIBS},
6618#endif
6619#ifdef _CS_LFS_LINTFLAGS
6620 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
6621#endif
Fred Draked86ed291999-12-15 15:34:33 +00006622#ifdef _CS_MACHINE
6623 {"CS_MACHINE", _CS_MACHINE},
6624#endif
Fred Drakec9680921999-12-13 16:37:25 +00006625#ifdef _CS_PATH
6626 {"CS_PATH", _CS_PATH},
6627#endif
Fred Draked86ed291999-12-15 15:34:33 +00006628#ifdef _CS_RELEASE
6629 {"CS_RELEASE", _CS_RELEASE},
6630#endif
6631#ifdef _CS_SRPC_DOMAIN
6632 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
6633#endif
6634#ifdef _CS_SYSNAME
6635 {"CS_SYSNAME", _CS_SYSNAME},
6636#endif
6637#ifdef _CS_VERSION
6638 {"CS_VERSION", _CS_VERSION},
6639#endif
Fred Drakec9680921999-12-13 16:37:25 +00006640#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
6641 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
6642#endif
6643#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
6644 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
6645#endif
6646#ifdef _CS_XBS5_ILP32_OFF32_LIBS
6647 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
6648#endif
6649#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
6650 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
6651#endif
6652#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
6653 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
6654#endif
6655#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
6656 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
6657#endif
6658#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
6659 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
6660#endif
6661#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
6662 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
6663#endif
6664#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
6665 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
6666#endif
6667#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
6668 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
6669#endif
6670#ifdef _CS_XBS5_LP64_OFF64_LIBS
6671 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
6672#endif
6673#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
6674 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
6675#endif
6676#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
6677 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
6678#endif
6679#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
6680 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
6681#endif
6682#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
6683 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
6684#endif
6685#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
6686 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
6687#endif
Fred Draked86ed291999-12-15 15:34:33 +00006688#ifdef _MIPS_CS_AVAIL_PROCESSORS
6689 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
6690#endif
6691#ifdef _MIPS_CS_BASE
6692 {"MIPS_CS_BASE", _MIPS_CS_BASE},
6693#endif
6694#ifdef _MIPS_CS_HOSTID
6695 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
6696#endif
6697#ifdef _MIPS_CS_HW_NAME
6698 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
6699#endif
6700#ifdef _MIPS_CS_NUM_PROCESSORS
6701 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
6702#endif
6703#ifdef _MIPS_CS_OSREL_MAJ
6704 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
6705#endif
6706#ifdef _MIPS_CS_OSREL_MIN
6707 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
6708#endif
6709#ifdef _MIPS_CS_OSREL_PATCH
6710 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
6711#endif
6712#ifdef _MIPS_CS_OS_NAME
6713 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
6714#endif
6715#ifdef _MIPS_CS_OS_PROVIDER
6716 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
6717#endif
6718#ifdef _MIPS_CS_PROCESSORS
6719 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
6720#endif
6721#ifdef _MIPS_CS_SERIAL
6722 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
6723#endif
6724#ifdef _MIPS_CS_VENDOR
6725 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
6726#endif
Fred Drakec9680921999-12-13 16:37:25 +00006727};
6728
6729static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006730conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006731{
6732 return conv_confname(arg, valuep, posix_constants_confstr,
6733 sizeof(posix_constants_confstr)
6734 / sizeof(struct constdef));
6735}
6736
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006737PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006738"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006739Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006740
6741static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006742posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006743{
6744 PyObject *result = NULL;
6745 int name;
6746 char buffer[64];
6747
6748 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
6749 int len = confstr(name, buffer, sizeof(buffer));
6750
Fred Drakec9680921999-12-13 16:37:25 +00006751 errno = 0;
6752 if (len == 0) {
6753 if (errno != 0)
6754 posix_error();
6755 else
6756 result = PyString_FromString("");
6757 }
6758 else {
6759 if (len >= sizeof(buffer)) {
6760 result = PyString_FromStringAndSize(NULL, len);
6761 if (result != NULL)
6762 confstr(name, PyString_AS_STRING(result), len+1);
6763 }
6764 else
6765 result = PyString_FromString(buffer);
6766 }
6767 }
6768 return result;
6769}
6770#endif
6771
6772
6773#ifdef HAVE_SYSCONF
6774static struct constdef posix_constants_sysconf[] = {
6775#ifdef _SC_2_CHAR_TERM
6776 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
6777#endif
6778#ifdef _SC_2_C_BIND
6779 {"SC_2_C_BIND", _SC_2_C_BIND},
6780#endif
6781#ifdef _SC_2_C_DEV
6782 {"SC_2_C_DEV", _SC_2_C_DEV},
6783#endif
6784#ifdef _SC_2_C_VERSION
6785 {"SC_2_C_VERSION", _SC_2_C_VERSION},
6786#endif
6787#ifdef _SC_2_FORT_DEV
6788 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
6789#endif
6790#ifdef _SC_2_FORT_RUN
6791 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
6792#endif
6793#ifdef _SC_2_LOCALEDEF
6794 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
6795#endif
6796#ifdef _SC_2_SW_DEV
6797 {"SC_2_SW_DEV", _SC_2_SW_DEV},
6798#endif
6799#ifdef _SC_2_UPE
6800 {"SC_2_UPE", _SC_2_UPE},
6801#endif
6802#ifdef _SC_2_VERSION
6803 {"SC_2_VERSION", _SC_2_VERSION},
6804#endif
Fred Draked86ed291999-12-15 15:34:33 +00006805#ifdef _SC_ABI_ASYNCHRONOUS_IO
6806 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
6807#endif
6808#ifdef _SC_ACL
6809 {"SC_ACL", _SC_ACL},
6810#endif
Fred Drakec9680921999-12-13 16:37:25 +00006811#ifdef _SC_AIO_LISTIO_MAX
6812 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
6813#endif
Fred Drakec9680921999-12-13 16:37:25 +00006814#ifdef _SC_AIO_MAX
6815 {"SC_AIO_MAX", _SC_AIO_MAX},
6816#endif
6817#ifdef _SC_AIO_PRIO_DELTA_MAX
6818 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
6819#endif
6820#ifdef _SC_ARG_MAX
6821 {"SC_ARG_MAX", _SC_ARG_MAX},
6822#endif
6823#ifdef _SC_ASYNCHRONOUS_IO
6824 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
6825#endif
6826#ifdef _SC_ATEXIT_MAX
6827 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
6828#endif
Fred Draked86ed291999-12-15 15:34:33 +00006829#ifdef _SC_AUDIT
6830 {"SC_AUDIT", _SC_AUDIT},
6831#endif
Fred Drakec9680921999-12-13 16:37:25 +00006832#ifdef _SC_AVPHYS_PAGES
6833 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
6834#endif
6835#ifdef _SC_BC_BASE_MAX
6836 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
6837#endif
6838#ifdef _SC_BC_DIM_MAX
6839 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
6840#endif
6841#ifdef _SC_BC_SCALE_MAX
6842 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
6843#endif
6844#ifdef _SC_BC_STRING_MAX
6845 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
6846#endif
Fred Draked86ed291999-12-15 15:34:33 +00006847#ifdef _SC_CAP
6848 {"SC_CAP", _SC_CAP},
6849#endif
Fred Drakec9680921999-12-13 16:37:25 +00006850#ifdef _SC_CHARCLASS_NAME_MAX
6851 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
6852#endif
6853#ifdef _SC_CHAR_BIT
6854 {"SC_CHAR_BIT", _SC_CHAR_BIT},
6855#endif
6856#ifdef _SC_CHAR_MAX
6857 {"SC_CHAR_MAX", _SC_CHAR_MAX},
6858#endif
6859#ifdef _SC_CHAR_MIN
6860 {"SC_CHAR_MIN", _SC_CHAR_MIN},
6861#endif
6862#ifdef _SC_CHILD_MAX
6863 {"SC_CHILD_MAX", _SC_CHILD_MAX},
6864#endif
6865#ifdef _SC_CLK_TCK
6866 {"SC_CLK_TCK", _SC_CLK_TCK},
6867#endif
6868#ifdef _SC_COHER_BLKSZ
6869 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
6870#endif
6871#ifdef _SC_COLL_WEIGHTS_MAX
6872 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
6873#endif
6874#ifdef _SC_DCACHE_ASSOC
6875 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
6876#endif
6877#ifdef _SC_DCACHE_BLKSZ
6878 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
6879#endif
6880#ifdef _SC_DCACHE_LINESZ
6881 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
6882#endif
6883#ifdef _SC_DCACHE_SZ
6884 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
6885#endif
6886#ifdef _SC_DCACHE_TBLKSZ
6887 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
6888#endif
6889#ifdef _SC_DELAYTIMER_MAX
6890 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
6891#endif
6892#ifdef _SC_EQUIV_CLASS_MAX
6893 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
6894#endif
6895#ifdef _SC_EXPR_NEST_MAX
6896 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
6897#endif
6898#ifdef _SC_FSYNC
6899 {"SC_FSYNC", _SC_FSYNC},
6900#endif
6901#ifdef _SC_GETGR_R_SIZE_MAX
6902 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
6903#endif
6904#ifdef _SC_GETPW_R_SIZE_MAX
6905 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
6906#endif
6907#ifdef _SC_ICACHE_ASSOC
6908 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
6909#endif
6910#ifdef _SC_ICACHE_BLKSZ
6911 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
6912#endif
6913#ifdef _SC_ICACHE_LINESZ
6914 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
6915#endif
6916#ifdef _SC_ICACHE_SZ
6917 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
6918#endif
Fred Draked86ed291999-12-15 15:34:33 +00006919#ifdef _SC_INF
6920 {"SC_INF", _SC_INF},
6921#endif
Fred Drakec9680921999-12-13 16:37:25 +00006922#ifdef _SC_INT_MAX
6923 {"SC_INT_MAX", _SC_INT_MAX},
6924#endif
6925#ifdef _SC_INT_MIN
6926 {"SC_INT_MIN", _SC_INT_MIN},
6927#endif
6928#ifdef _SC_IOV_MAX
6929 {"SC_IOV_MAX", _SC_IOV_MAX},
6930#endif
Fred Draked86ed291999-12-15 15:34:33 +00006931#ifdef _SC_IP_SECOPTS
6932 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
6933#endif
Fred Drakec9680921999-12-13 16:37:25 +00006934#ifdef _SC_JOB_CONTROL
6935 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
6936#endif
Fred Draked86ed291999-12-15 15:34:33 +00006937#ifdef _SC_KERN_POINTERS
6938 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
6939#endif
6940#ifdef _SC_KERN_SIM
6941 {"SC_KERN_SIM", _SC_KERN_SIM},
6942#endif
Fred Drakec9680921999-12-13 16:37:25 +00006943#ifdef _SC_LINE_MAX
6944 {"SC_LINE_MAX", _SC_LINE_MAX},
6945#endif
6946#ifdef _SC_LOGIN_NAME_MAX
6947 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
6948#endif
6949#ifdef _SC_LOGNAME_MAX
6950 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
6951#endif
6952#ifdef _SC_LONG_BIT
6953 {"SC_LONG_BIT", _SC_LONG_BIT},
6954#endif
Fred Draked86ed291999-12-15 15:34:33 +00006955#ifdef _SC_MAC
6956 {"SC_MAC", _SC_MAC},
6957#endif
Fred Drakec9680921999-12-13 16:37:25 +00006958#ifdef _SC_MAPPED_FILES
6959 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
6960#endif
6961#ifdef _SC_MAXPID
6962 {"SC_MAXPID", _SC_MAXPID},
6963#endif
6964#ifdef _SC_MB_LEN_MAX
6965 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
6966#endif
6967#ifdef _SC_MEMLOCK
6968 {"SC_MEMLOCK", _SC_MEMLOCK},
6969#endif
6970#ifdef _SC_MEMLOCK_RANGE
6971 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
6972#endif
6973#ifdef _SC_MEMORY_PROTECTION
6974 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
6975#endif
6976#ifdef _SC_MESSAGE_PASSING
6977 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
6978#endif
Fred Draked86ed291999-12-15 15:34:33 +00006979#ifdef _SC_MMAP_FIXED_ALIGNMENT
6980 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
6981#endif
Fred Drakec9680921999-12-13 16:37:25 +00006982#ifdef _SC_MQ_OPEN_MAX
6983 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
6984#endif
6985#ifdef _SC_MQ_PRIO_MAX
6986 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
6987#endif
Fred Draked86ed291999-12-15 15:34:33 +00006988#ifdef _SC_NACLS_MAX
6989 {"SC_NACLS_MAX", _SC_NACLS_MAX},
6990#endif
Fred Drakec9680921999-12-13 16:37:25 +00006991#ifdef _SC_NGROUPS_MAX
6992 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
6993#endif
6994#ifdef _SC_NL_ARGMAX
6995 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
6996#endif
6997#ifdef _SC_NL_LANGMAX
6998 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
6999#endif
7000#ifdef _SC_NL_MSGMAX
7001 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
7002#endif
7003#ifdef _SC_NL_NMAX
7004 {"SC_NL_NMAX", _SC_NL_NMAX},
7005#endif
7006#ifdef _SC_NL_SETMAX
7007 {"SC_NL_SETMAX", _SC_NL_SETMAX},
7008#endif
7009#ifdef _SC_NL_TEXTMAX
7010 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
7011#endif
7012#ifdef _SC_NPROCESSORS_CONF
7013 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
7014#endif
7015#ifdef _SC_NPROCESSORS_ONLN
7016 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
7017#endif
Fred Draked86ed291999-12-15 15:34:33 +00007018#ifdef _SC_NPROC_CONF
7019 {"SC_NPROC_CONF", _SC_NPROC_CONF},
7020#endif
7021#ifdef _SC_NPROC_ONLN
7022 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
7023#endif
Fred Drakec9680921999-12-13 16:37:25 +00007024#ifdef _SC_NZERO
7025 {"SC_NZERO", _SC_NZERO},
7026#endif
7027#ifdef _SC_OPEN_MAX
7028 {"SC_OPEN_MAX", _SC_OPEN_MAX},
7029#endif
7030#ifdef _SC_PAGESIZE
7031 {"SC_PAGESIZE", _SC_PAGESIZE},
7032#endif
7033#ifdef _SC_PAGE_SIZE
7034 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
7035#endif
7036#ifdef _SC_PASS_MAX
7037 {"SC_PASS_MAX", _SC_PASS_MAX},
7038#endif
7039#ifdef _SC_PHYS_PAGES
7040 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
7041#endif
7042#ifdef _SC_PII
7043 {"SC_PII", _SC_PII},
7044#endif
7045#ifdef _SC_PII_INTERNET
7046 {"SC_PII_INTERNET", _SC_PII_INTERNET},
7047#endif
7048#ifdef _SC_PII_INTERNET_DGRAM
7049 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
7050#endif
7051#ifdef _SC_PII_INTERNET_STREAM
7052 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
7053#endif
7054#ifdef _SC_PII_OSI
7055 {"SC_PII_OSI", _SC_PII_OSI},
7056#endif
7057#ifdef _SC_PII_OSI_CLTS
7058 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
7059#endif
7060#ifdef _SC_PII_OSI_COTS
7061 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
7062#endif
7063#ifdef _SC_PII_OSI_M
7064 {"SC_PII_OSI_M", _SC_PII_OSI_M},
7065#endif
7066#ifdef _SC_PII_SOCKET
7067 {"SC_PII_SOCKET", _SC_PII_SOCKET},
7068#endif
7069#ifdef _SC_PII_XTI
7070 {"SC_PII_XTI", _SC_PII_XTI},
7071#endif
7072#ifdef _SC_POLL
7073 {"SC_POLL", _SC_POLL},
7074#endif
7075#ifdef _SC_PRIORITIZED_IO
7076 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
7077#endif
7078#ifdef _SC_PRIORITY_SCHEDULING
7079 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
7080#endif
7081#ifdef _SC_REALTIME_SIGNALS
7082 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
7083#endif
7084#ifdef _SC_RE_DUP_MAX
7085 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
7086#endif
7087#ifdef _SC_RTSIG_MAX
7088 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
7089#endif
7090#ifdef _SC_SAVED_IDS
7091 {"SC_SAVED_IDS", _SC_SAVED_IDS},
7092#endif
7093#ifdef _SC_SCHAR_MAX
7094 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
7095#endif
7096#ifdef _SC_SCHAR_MIN
7097 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
7098#endif
7099#ifdef _SC_SELECT
7100 {"SC_SELECT", _SC_SELECT},
7101#endif
7102#ifdef _SC_SEMAPHORES
7103 {"SC_SEMAPHORES", _SC_SEMAPHORES},
7104#endif
7105#ifdef _SC_SEM_NSEMS_MAX
7106 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
7107#endif
7108#ifdef _SC_SEM_VALUE_MAX
7109 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
7110#endif
7111#ifdef _SC_SHARED_MEMORY_OBJECTS
7112 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
7113#endif
7114#ifdef _SC_SHRT_MAX
7115 {"SC_SHRT_MAX", _SC_SHRT_MAX},
7116#endif
7117#ifdef _SC_SHRT_MIN
7118 {"SC_SHRT_MIN", _SC_SHRT_MIN},
7119#endif
7120#ifdef _SC_SIGQUEUE_MAX
7121 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
7122#endif
7123#ifdef _SC_SIGRT_MAX
7124 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
7125#endif
7126#ifdef _SC_SIGRT_MIN
7127 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
7128#endif
Fred Draked86ed291999-12-15 15:34:33 +00007129#ifdef _SC_SOFTPOWER
7130 {"SC_SOFTPOWER", _SC_SOFTPOWER},
7131#endif
Fred Drakec9680921999-12-13 16:37:25 +00007132#ifdef _SC_SPLIT_CACHE
7133 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
7134#endif
7135#ifdef _SC_SSIZE_MAX
7136 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
7137#endif
7138#ifdef _SC_STACK_PROT
7139 {"SC_STACK_PROT", _SC_STACK_PROT},
7140#endif
7141#ifdef _SC_STREAM_MAX
7142 {"SC_STREAM_MAX", _SC_STREAM_MAX},
7143#endif
7144#ifdef _SC_SYNCHRONIZED_IO
7145 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
7146#endif
7147#ifdef _SC_THREADS
7148 {"SC_THREADS", _SC_THREADS},
7149#endif
7150#ifdef _SC_THREAD_ATTR_STACKADDR
7151 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
7152#endif
7153#ifdef _SC_THREAD_ATTR_STACKSIZE
7154 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
7155#endif
7156#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
7157 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
7158#endif
7159#ifdef _SC_THREAD_KEYS_MAX
7160 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
7161#endif
7162#ifdef _SC_THREAD_PRIORITY_SCHEDULING
7163 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
7164#endif
7165#ifdef _SC_THREAD_PRIO_INHERIT
7166 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
7167#endif
7168#ifdef _SC_THREAD_PRIO_PROTECT
7169 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
7170#endif
7171#ifdef _SC_THREAD_PROCESS_SHARED
7172 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
7173#endif
7174#ifdef _SC_THREAD_SAFE_FUNCTIONS
7175 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
7176#endif
7177#ifdef _SC_THREAD_STACK_MIN
7178 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
7179#endif
7180#ifdef _SC_THREAD_THREADS_MAX
7181 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
7182#endif
7183#ifdef _SC_TIMERS
7184 {"SC_TIMERS", _SC_TIMERS},
7185#endif
7186#ifdef _SC_TIMER_MAX
7187 {"SC_TIMER_MAX", _SC_TIMER_MAX},
7188#endif
7189#ifdef _SC_TTY_NAME_MAX
7190 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
7191#endif
7192#ifdef _SC_TZNAME_MAX
7193 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
7194#endif
7195#ifdef _SC_T_IOV_MAX
7196 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
7197#endif
7198#ifdef _SC_UCHAR_MAX
7199 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
7200#endif
7201#ifdef _SC_UINT_MAX
7202 {"SC_UINT_MAX", _SC_UINT_MAX},
7203#endif
7204#ifdef _SC_UIO_MAXIOV
7205 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
7206#endif
7207#ifdef _SC_ULONG_MAX
7208 {"SC_ULONG_MAX", _SC_ULONG_MAX},
7209#endif
7210#ifdef _SC_USHRT_MAX
7211 {"SC_USHRT_MAX", _SC_USHRT_MAX},
7212#endif
7213#ifdef _SC_VERSION
7214 {"SC_VERSION", _SC_VERSION},
7215#endif
7216#ifdef _SC_WORD_BIT
7217 {"SC_WORD_BIT", _SC_WORD_BIT},
7218#endif
7219#ifdef _SC_XBS5_ILP32_OFF32
7220 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
7221#endif
7222#ifdef _SC_XBS5_ILP32_OFFBIG
7223 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
7224#endif
7225#ifdef _SC_XBS5_LP64_OFF64
7226 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
7227#endif
7228#ifdef _SC_XBS5_LPBIG_OFFBIG
7229 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
7230#endif
7231#ifdef _SC_XOPEN_CRYPT
7232 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
7233#endif
7234#ifdef _SC_XOPEN_ENH_I18N
7235 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
7236#endif
7237#ifdef _SC_XOPEN_LEGACY
7238 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
7239#endif
7240#ifdef _SC_XOPEN_REALTIME
7241 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
7242#endif
7243#ifdef _SC_XOPEN_REALTIME_THREADS
7244 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
7245#endif
7246#ifdef _SC_XOPEN_SHM
7247 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
7248#endif
7249#ifdef _SC_XOPEN_UNIX
7250 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
7251#endif
7252#ifdef _SC_XOPEN_VERSION
7253 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
7254#endif
7255#ifdef _SC_XOPEN_XCU_VERSION
7256 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
7257#endif
7258#ifdef _SC_XOPEN_XPG2
7259 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
7260#endif
7261#ifdef _SC_XOPEN_XPG3
7262 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
7263#endif
7264#ifdef _SC_XOPEN_XPG4
7265 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
7266#endif
7267};
7268
7269static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007270conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007271{
7272 return conv_confname(arg, valuep, posix_constants_sysconf,
7273 sizeof(posix_constants_sysconf)
7274 / sizeof(struct constdef));
7275}
7276
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007277PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007278"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007279Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007280
7281static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007282posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007283{
7284 PyObject *result = NULL;
7285 int name;
7286
7287 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
7288 int value;
7289
7290 errno = 0;
7291 value = sysconf(name);
7292 if (value == -1 && errno != 0)
7293 posix_error();
7294 else
7295 result = PyInt_FromLong(value);
7296 }
7297 return result;
7298}
7299#endif
7300
7301
Fred Drakebec628d1999-12-15 18:31:10 +00007302/* This code is used to ensure that the tables of configuration value names
7303 * are in sorted order as required by conv_confname(), and also to build the
7304 * the exported dictionaries that are used to publish information about the
7305 * names available on the host platform.
7306 *
7307 * Sorting the table at runtime ensures that the table is properly ordered
7308 * when used, even for platforms we're not able to test on. It also makes
7309 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00007310 */
Fred Drakebec628d1999-12-15 18:31:10 +00007311
7312static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007313cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00007314{
7315 const struct constdef *c1 =
7316 (const struct constdef *) v1;
7317 const struct constdef *c2 =
7318 (const struct constdef *) v2;
7319
7320 return strcmp(c1->name, c2->name);
7321}
7322
7323static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007324setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00007325 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007326{
Fred Drakebec628d1999-12-15 18:31:10 +00007327 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00007328 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00007329
7330 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
7331 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00007332 if (d == NULL)
7333 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007334
Barry Warsaw3155db32000-04-13 15:20:40 +00007335 for (i=0; i < tablesize; ++i) {
7336 PyObject *o = PyInt_FromLong(table[i].value);
7337 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
7338 Py_XDECREF(o);
7339 Py_DECREF(d);
7340 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007341 }
Barry Warsaw3155db32000-04-13 15:20:40 +00007342 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00007343 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00007344 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00007345}
7346
Fred Drakebec628d1999-12-15 18:31:10 +00007347/* Return -1 on failure, 0 on success. */
7348static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007349setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007350{
7351#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00007352 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00007353 sizeof(posix_constants_pathconf)
7354 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007355 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007356 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007357#endif
7358#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00007359 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00007360 sizeof(posix_constants_confstr)
7361 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007362 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007363 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007364#endif
7365#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00007366 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00007367 sizeof(posix_constants_sysconf)
7368 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007369 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007370 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007371#endif
Fred Drakebec628d1999-12-15 18:31:10 +00007372 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00007373}
Fred Draked86ed291999-12-15 15:34:33 +00007374
7375
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007376PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007377"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007378Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007379in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007380
7381static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007382posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007383{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007384 abort();
7385 /*NOTREACHED*/
7386 Py_FatalError("abort() called from Python code didn't abort!");
7387 return NULL;
7388}
Fred Drakebec628d1999-12-15 18:31:10 +00007389
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007390#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007391PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00007392"startfile(filepath [, operation]) - Start a file with its associated\n\
7393application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007394\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00007395When \"operation\" is not specified or \"open\", this acts like\n\
7396double-clicking the file in Explorer, or giving the file name as an\n\
7397argument to the DOS \"start\" command: the file is opened with whatever\n\
7398application (if any) its extension is associated.\n\
7399When another \"operation\" is given, it specifies what should be done with\n\
7400the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007401\n\
7402startfile returns as soon as the associated application is launched.\n\
7403There is no option to wait for the application to close, and no way\n\
7404to retrieve the application's exit status.\n\
7405\n\
7406The filepath is relative to the current directory. If you want to use\n\
7407an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007408the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00007409
7410static PyObject *
7411win32_startfile(PyObject *self, PyObject *args)
7412{
7413 char *filepath;
Georg Brandlf4f44152006-02-18 22:29:33 +00007414 char *operation = NULL;
Tim Petersf58a7aa2000-09-22 10:05:54 +00007415 HINSTANCE rc;
Georg Brandlf4f44152006-02-18 22:29:33 +00007416 if (!PyArg_ParseTuple(args, "et|s:startfile",
7417 Py_FileSystemDefaultEncoding, &filepath,
7418 &operation))
Tim Petersf58a7aa2000-09-22 10:05:54 +00007419 return NULL;
7420 Py_BEGIN_ALLOW_THREADS
Georg Brandlf4f44152006-02-18 22:29:33 +00007421 rc = ShellExecute((HWND)0, operation, filepath,
7422 NULL, NULL, SW_SHOWNORMAL);
Tim Petersf58a7aa2000-09-22 10:05:54 +00007423 Py_END_ALLOW_THREADS
Georg Brandle9f8ec92005-09-25 06:16:40 +00007424 if (rc <= (HINSTANCE)32) {
7425 PyObject *errval = win32_error("startfile", filepath);
7426 PyMem_Free(filepath);
7427 return errval;
7428 }
7429 PyMem_Free(filepath);
Tim Petersf58a7aa2000-09-22 10:05:54 +00007430 Py_INCREF(Py_None);
7431 return Py_None;
7432}
7433#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007434
Martin v. Löwis438b5342002-12-27 10:16:42 +00007435#ifdef HAVE_GETLOADAVG
7436PyDoc_STRVAR(posix_getloadavg__doc__,
7437"getloadavg() -> (float, float, float)\n\n\
7438Return the number of processes in the system run queue averaged over\n\
7439the last 1, 5, and 15 minutes or raises OSError if the load average\n\
7440was unobtainable");
7441
7442static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007443posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00007444{
7445 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00007446 if (getloadavg(loadavg, 3)!=3) {
7447 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
7448 return NULL;
7449 } else
7450 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
7451}
7452#endif
7453
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007454#ifdef MS_WINDOWS
7455
7456PyDoc_STRVAR(win32_urandom__doc__,
7457"urandom(n) -> str\n\n\
7458Return a string of n random bytes suitable for cryptographic use.");
7459
7460typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
7461 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
7462 DWORD dwFlags );
7463typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
7464 BYTE *pbBuffer );
7465
7466static CRYPTGENRANDOM pCryptGenRandom = NULL;
7467static HCRYPTPROV hCryptProv = 0;
7468
Tim Peters4ad82172004-08-30 17:02:04 +00007469static PyObject*
7470win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007471{
Tim Petersd3115382004-08-30 17:36:46 +00007472 int howMany;
7473 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007474
Tim Peters4ad82172004-08-30 17:02:04 +00007475 /* Read arguments */
Tim Peters9b279a82004-08-30 17:10:53 +00007476 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
Tim Peters4ad82172004-08-30 17:02:04 +00007477 return NULL;
Tim Peters51eba612004-08-30 17:08:02 +00007478 if (howMany < 0)
7479 return PyErr_Format(PyExc_ValueError,
7480 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007481
Tim Peters4ad82172004-08-30 17:02:04 +00007482 if (hCryptProv == 0) {
7483 HINSTANCE hAdvAPI32 = NULL;
7484 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007485
Tim Peters4ad82172004-08-30 17:02:04 +00007486 /* Obtain handle to the DLL containing CryptoAPI
7487 This should not fail */
7488 hAdvAPI32 = GetModuleHandle("advapi32.dll");
7489 if(hAdvAPI32 == NULL)
7490 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007491
Tim Peters4ad82172004-08-30 17:02:04 +00007492 /* Obtain pointers to the CryptoAPI functions
7493 This will fail on some early versions of Win95 */
7494 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
7495 hAdvAPI32,
7496 "CryptAcquireContextA");
7497 if (pCryptAcquireContext == NULL)
7498 return PyErr_Format(PyExc_NotImplementedError,
7499 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007500
Tim Peters4ad82172004-08-30 17:02:04 +00007501 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
7502 hAdvAPI32, "CryptGenRandom");
7503 if (pCryptAcquireContext == NULL)
7504 return PyErr_Format(PyExc_NotImplementedError,
7505 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007506
Tim Peters4ad82172004-08-30 17:02:04 +00007507 /* Acquire context */
7508 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
7509 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
7510 return win32_error("CryptAcquireContext", NULL);
7511 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007512
Tim Peters4ad82172004-08-30 17:02:04 +00007513 /* Allocate bytes */
Tim Petersd3115382004-08-30 17:36:46 +00007514 result = PyString_FromStringAndSize(NULL, howMany);
7515 if (result != NULL) {
7516 /* Get random data */
7517 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
7518 PyString_AS_STRING(result))) {
7519 Py_DECREF(result);
7520 return win32_error("CryptGenRandom", NULL);
7521 }
Tim Peters4ad82172004-08-30 17:02:04 +00007522 }
Tim Petersd3115382004-08-30 17:36:46 +00007523 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007524}
7525#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007526
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007527static PyMethodDef posix_methods[] = {
7528 {"access", posix_access, METH_VARARGS, posix_access__doc__},
7529#ifdef HAVE_TTYNAME
7530 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
7531#endif
7532 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
7533 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007534#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007535 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007536#endif /* HAVE_CHOWN */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007537#ifdef HAVE_LCHOWN
7538 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
7539#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00007540#ifdef HAVE_CHROOT
7541 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
7542#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007543#ifdef HAVE_CTERMID
Neal Norwitze241ce82003-02-17 18:17:05 +00007544 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007545#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00007546#ifdef HAVE_GETCWD
Neal Norwitze241ce82003-02-17 18:17:05 +00007547 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Walter Dörwald3b918c32002-11-21 20:18:46 +00007548#ifdef Py_USING_UNICODE
Neal Norwitze241ce82003-02-17 18:17:05 +00007549 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00007550#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00007551#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007552#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007553 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007554#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007555 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
7556 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
7557 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007558#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007559 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007560#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007561#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007562 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007563#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007564 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
7565 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
7566 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007567 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007568#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007569 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007570#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007571#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007572 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007573#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007574 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007575#ifdef HAVE_UNAME
Neal Norwitze241ce82003-02-17 18:17:05 +00007576 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007577#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007578 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
7579 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
7580 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007581#ifdef HAVE_TIMES
Neal Norwitze241ce82003-02-17 18:17:05 +00007582 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007583#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007584 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007585#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007586 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
7587 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007588#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00007589#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007590 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
7591 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00007592#if defined(PYOS_OS2)
7593 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
7594 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
7595#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00007596#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007597#ifdef HAVE_FORK1
Neal Norwitze241ce82003-02-17 18:17:05 +00007598 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007599#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007600#ifdef HAVE_FORK
Neal Norwitze241ce82003-02-17 18:17:05 +00007601 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007602#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007603#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Neal Norwitze241ce82003-02-17 18:17:05 +00007604 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007605#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007606#ifdef HAVE_FORKPTY
Neal Norwitze241ce82003-02-17 18:17:05 +00007607 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00007608#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007609#ifdef HAVE_GETEGID
Neal Norwitze241ce82003-02-17 18:17:05 +00007610 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007611#endif /* HAVE_GETEGID */
7612#ifdef HAVE_GETEUID
Neal Norwitze241ce82003-02-17 18:17:05 +00007613 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007614#endif /* HAVE_GETEUID */
7615#ifdef HAVE_GETGID
Neal Norwitze241ce82003-02-17 18:17:05 +00007616 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007617#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00007618#ifdef HAVE_GETGROUPS
Neal Norwitze241ce82003-02-17 18:17:05 +00007619 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007620#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007621 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007622#ifdef HAVE_GETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00007623 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007624#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007625#ifdef HAVE_GETPPID
Neal Norwitze241ce82003-02-17 18:17:05 +00007626 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007627#endif /* HAVE_GETPPID */
7628#ifdef HAVE_GETUID
Neal Norwitze241ce82003-02-17 18:17:05 +00007629 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007630#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007631#ifdef HAVE_GETLOGIN
Neal Norwitze241ce82003-02-17 18:17:05 +00007632 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00007633#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00007634#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007635 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007636#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007637#ifdef HAVE_KILLPG
7638 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
7639#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00007640#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007641 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00007642#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007643#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007644 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007645#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00007646 {"popen2", win32_popen2, METH_VARARGS},
7647 {"popen3", win32_popen3, METH_VARARGS},
7648 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00007649 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007650#else
7651#if defined(PYOS_OS2) && defined(PYCC_GCC)
7652 {"popen2", os2emx_popen2, METH_VARARGS},
7653 {"popen3", os2emx_popen3, METH_VARARGS},
7654 {"popen4", os2emx_popen4, METH_VARARGS},
7655#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00007656#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007657#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007658#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007659 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007660#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007661#ifdef HAVE_SETEUID
7662 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
7663#endif /* HAVE_SETEUID */
7664#ifdef HAVE_SETEGID
7665 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
7666#endif /* HAVE_SETEGID */
7667#ifdef HAVE_SETREUID
7668 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
7669#endif /* HAVE_SETREUID */
7670#ifdef HAVE_SETREGID
7671 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
7672#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007673#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007674 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007675#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007676#ifdef HAVE_SETGROUPS
7677 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
7678#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00007679#ifdef HAVE_GETPGID
7680 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
7681#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007682#ifdef HAVE_SETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00007683 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007684#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007685#ifdef HAVE_WAIT
Neal Norwitze241ce82003-02-17 18:17:05 +00007686 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007687#endif /* HAVE_WAIT */
Tim Petersab034fa2002-02-01 11:27:43 +00007688#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007689 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007690#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007691#ifdef HAVE_GETSID
7692 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
7693#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007694#ifdef HAVE_SETSID
Neal Norwitze241ce82003-02-17 18:17:05 +00007695 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007696#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007697#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007698 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007699#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007700#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007701 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007702#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007703#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007704 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007705#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007706 {"open", posix_open, METH_VARARGS, posix_open__doc__},
7707 {"close", posix_close, METH_VARARGS, posix_close__doc__},
7708 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
7709 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
7710 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
7711 {"read", posix_read, METH_VARARGS, posix_read__doc__},
7712 {"write", posix_write, METH_VARARGS, posix_write__doc__},
7713 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
7714 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00007715 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007716#ifdef HAVE_PIPE
Neal Norwitze241ce82003-02-17 18:17:05 +00007717 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007718#endif
7719#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007720 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007721#endif
Neal Norwitz11690112002-07-30 01:08:28 +00007722#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007723 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
7724#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007725#ifdef HAVE_DEVICE_MACROS
7726 {"major", posix_major, METH_VARARGS, posix_major__doc__},
7727 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
7728 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
7729#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007730#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007731 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007732#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007733#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007734 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007735#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007736#ifdef HAVE_UNSETENV
7737 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
7738#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00007739#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007740 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00007741#endif
Fred Drake4d1e64b2002-04-15 19:40:07 +00007742#ifdef HAVE_FCHDIR
7743 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
7744#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00007745#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007746 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007747#endif
7748#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007749 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007750#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00007751#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00007752#ifdef WCOREDUMP
7753 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
7754#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007755#ifdef WIFCONTINUED
7756 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
7757#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00007758#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007759 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007760#endif /* WIFSTOPPED */
7761#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007762 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007763#endif /* WIFSIGNALED */
7764#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007765 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007766#endif /* WIFEXITED */
7767#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007768 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007769#endif /* WEXITSTATUS */
7770#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007771 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007772#endif /* WTERMSIG */
7773#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007774 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007775#endif /* WSTOPSIG */
7776#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007777#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007778 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007779#endif
7780#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007781 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007782#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00007783#ifdef HAVE_TMPFILE
Neal Norwitze241ce82003-02-17 18:17:05 +00007784 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007785#endif
7786#ifdef HAVE_TEMPNAM
7787 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
7788#endif
7789#ifdef HAVE_TMPNAM
Neal Norwitze241ce82003-02-17 18:17:05 +00007790 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007791#endif
Fred Drakec9680921999-12-13 16:37:25 +00007792#ifdef HAVE_CONFSTR
7793 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
7794#endif
7795#ifdef HAVE_SYSCONF
7796 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
7797#endif
7798#ifdef HAVE_FPATHCONF
7799 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
7800#endif
7801#ifdef HAVE_PATHCONF
7802 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
7803#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007804 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007805#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00007806 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
7807#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007808#ifdef HAVE_GETLOADAVG
Neal Norwitze241ce82003-02-17 18:17:05 +00007809 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00007810#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007811 #ifdef MS_WINDOWS
7812 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
7813 #endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007814 {NULL, NULL} /* Sentinel */
7815};
7816
7817
Barry Warsaw4a342091996-12-19 23:50:02 +00007818static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007819ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00007820{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007821 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00007822}
7823
Guido van Rossumd48f2521997-12-05 22:19:34 +00007824#if defined(PYOS_OS2)
7825/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007826static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007827{
7828 APIRET rc;
7829 ULONG values[QSV_MAX+1];
7830 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00007831 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00007832
7833 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00007834 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007835 Py_END_ALLOW_THREADS
7836
7837 if (rc != NO_ERROR) {
7838 os2_error(rc);
7839 return -1;
7840 }
7841
Fred Drake4d1e64b2002-04-15 19:40:07 +00007842 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
7843 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
7844 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
7845 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
7846 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
7847 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
7848 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007849
7850 switch (values[QSV_VERSION_MINOR]) {
7851 case 0: ver = "2.00"; break;
7852 case 10: ver = "2.10"; break;
7853 case 11: ver = "2.11"; break;
7854 case 30: ver = "3.00"; break;
7855 case 40: ver = "4.00"; break;
7856 case 50: ver = "5.00"; break;
7857 default:
Tim Peters885d4572001-11-28 20:27:42 +00007858 PyOS_snprintf(tmp, sizeof(tmp),
7859 "%d-%d", values[QSV_VERSION_MAJOR],
7860 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007861 ver = &tmp[0];
7862 }
7863
7864 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007865 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007866 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007867
7868 /* Add Indicator of Which Drive was Used to Boot the System */
7869 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
7870 tmp[1] = ':';
7871 tmp[2] = '\0';
7872
Fred Drake4d1e64b2002-04-15 19:40:07 +00007873 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007874}
7875#endif
7876
Barry Warsaw4a342091996-12-19 23:50:02 +00007877static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007878all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00007879{
Guido van Rossum94f6f721999-01-06 18:42:14 +00007880#ifdef F_OK
7881 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007882#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007883#ifdef R_OK
7884 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007885#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007886#ifdef W_OK
7887 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007888#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007889#ifdef X_OK
7890 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007891#endif
Fred Drakec9680921999-12-13 16:37:25 +00007892#ifdef NGROUPS_MAX
7893 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
7894#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007895#ifdef TMP_MAX
7896 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
7897#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007898#ifdef WCONTINUED
7899 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
7900#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007901#ifdef WNOHANG
7902 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007903#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007904#ifdef WUNTRACED
7905 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
7906#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007907#ifdef O_RDONLY
7908 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
7909#endif
7910#ifdef O_WRONLY
7911 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
7912#endif
7913#ifdef O_RDWR
7914 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
7915#endif
7916#ifdef O_NDELAY
7917 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
7918#endif
7919#ifdef O_NONBLOCK
7920 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
7921#endif
7922#ifdef O_APPEND
7923 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
7924#endif
7925#ifdef O_DSYNC
7926 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
7927#endif
7928#ifdef O_RSYNC
7929 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
7930#endif
7931#ifdef O_SYNC
7932 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
7933#endif
7934#ifdef O_NOCTTY
7935 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
7936#endif
7937#ifdef O_CREAT
7938 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
7939#endif
7940#ifdef O_EXCL
7941 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
7942#endif
7943#ifdef O_TRUNC
7944 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
7945#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00007946#ifdef O_BINARY
7947 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
7948#endif
7949#ifdef O_TEXT
7950 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
7951#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007952#ifdef O_LARGEFILE
7953 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
7954#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00007955#ifdef O_SHLOCK
7956 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
7957#endif
7958#ifdef O_EXLOCK
7959 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
7960#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007961
Tim Peters5aa91602002-01-30 05:46:57 +00007962/* MS Windows */
7963#ifdef O_NOINHERIT
7964 /* Don't inherit in child processes. */
7965 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
7966#endif
7967#ifdef _O_SHORT_LIVED
7968 /* Optimize for short life (keep in memory). */
7969 /* MS forgot to define this one with a non-underscore form too. */
7970 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
7971#endif
7972#ifdef O_TEMPORARY
7973 /* Automatically delete when last handle is closed. */
7974 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
7975#endif
7976#ifdef O_RANDOM
7977 /* Optimize for random access. */
7978 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
7979#endif
7980#ifdef O_SEQUENTIAL
7981 /* Optimize for sequential access. */
7982 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
7983#endif
7984
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007985/* GNU extensions. */
7986#ifdef O_DIRECT
7987 /* Direct disk access. */
7988 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
7989#endif
7990#ifdef O_DIRECTORY
7991 /* Must be a directory. */
7992 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
7993#endif
7994#ifdef O_NOFOLLOW
7995 /* Do not follow links. */
7996 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
7997#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00007998
Barry Warsaw5676bd12003-01-07 20:57:09 +00007999 /* These come from sysexits.h */
8000#ifdef EX_OK
8001 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008002#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008003#ifdef EX_USAGE
8004 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008005#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008006#ifdef EX_DATAERR
8007 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008008#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008009#ifdef EX_NOINPUT
8010 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008011#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008012#ifdef EX_NOUSER
8013 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008014#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008015#ifdef EX_NOHOST
8016 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008017#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008018#ifdef EX_UNAVAILABLE
8019 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008020#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008021#ifdef EX_SOFTWARE
8022 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008023#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008024#ifdef EX_OSERR
8025 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008026#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008027#ifdef EX_OSFILE
8028 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008029#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008030#ifdef EX_CANTCREAT
8031 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008032#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008033#ifdef EX_IOERR
8034 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008035#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008036#ifdef EX_TEMPFAIL
8037 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008038#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008039#ifdef EX_PROTOCOL
8040 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008041#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008042#ifdef EX_NOPERM
8043 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008044#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008045#ifdef EX_CONFIG
8046 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008047#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008048#ifdef EX_NOTFOUND
8049 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008050#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008051
Guido van Rossum246bc171999-02-01 23:54:31 +00008052#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008053#if defined(PYOS_OS2) && defined(PYCC_GCC)
8054 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
8055 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
8056 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
8057 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
8058 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
8059 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
8060 if (ins(d, "P_PM", (long)P_PM)) return -1;
8061 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
8062 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
8063 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
8064 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
8065 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
8066 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
8067 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
8068 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
8069 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
8070 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
8071 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
8072 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
8073 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
8074#else
Guido van Rossum7d385291999-02-16 19:38:04 +00008075 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
8076 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
8077 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
8078 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
8079 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00008080#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008081#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00008082
Guido van Rossumd48f2521997-12-05 22:19:34 +00008083#if defined(PYOS_OS2)
8084 if (insertvalues(d)) return -1;
8085#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008086 return 0;
8087}
8088
8089
Tim Peters5aa91602002-01-30 05:46:57 +00008090#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008091#define INITFUNC initnt
8092#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008093
8094#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008095#define INITFUNC initos2
8096#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008097
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008098#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008099#define INITFUNC initposix
8100#define MODNAME "posix"
8101#endif
8102
Mark Hammondfe51c6d2002-08-02 02:27:13 +00008103PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008104INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00008105{
Fred Drake4d1e64b2002-04-15 19:40:07 +00008106 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00008107
Fred Drake4d1e64b2002-04-15 19:40:07 +00008108 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008109 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00008110 posix__doc__);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00008111 if (m == NULL)
8112 return;
Tim Peters5aa91602002-01-30 05:46:57 +00008113
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008114 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008115 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00008116 Py_XINCREF(v);
8117 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008118 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00008119 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00008120
Fred Drake4d1e64b2002-04-15 19:40:07 +00008121 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00008122 return;
8123
Fred Drake4d1e64b2002-04-15 19:40:07 +00008124 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00008125 return;
8126
Fred Drake4d1e64b2002-04-15 19:40:07 +00008127 Py_INCREF(PyExc_OSError);
8128 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00008129
Guido van Rossumb3d39562000-01-31 18:41:26 +00008130#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00008131 if (posix_putenv_garbage == NULL)
8132 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00008133#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008134
Guido van Rossum14648392001-12-08 18:02:58 +00008135 stat_result_desc.name = MODNAME ".stat_result";
Martin v. Löwisf607bda2002-10-16 18:27:39 +00008136 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
8137 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
8138 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008139 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00008140 structseq_new = StatResultType.tp_new;
8141 StatResultType.tp_new = statresult_new;
Fred Drake4d1e64b2002-04-15 19:40:07 +00008142 Py_INCREF((PyObject*) &StatResultType);
8143 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008144
Guido van Rossum14648392001-12-08 18:02:58 +00008145 statvfs_result_desc.name = MODNAME ".statvfs_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008146 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Fred Drake4d1e64b2002-04-15 19:40:07 +00008147 Py_INCREF((PyObject*) &StatVFSResultType);
8148 PyModule_AddObject(m, "statvfs_result",
8149 (PyObject*) &StatVFSResultType);
Guido van Rossumb6775db1994-08-01 11:34:53 +00008150}