blob: 8f730c7dc45ee17cb8582eb9d388941ff0a65396 [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
Neal Norwitzd5a37542006-03-20 06:48:34 +0000267#define WAIT_TYPE union wait
268#define WAIT_STATUS_INT(s) (s.w_status)
269
270#else /* !UNION_WAIT */
271#define WAIT_TYPE int
272#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000273#endif /* UNION_WAIT */
274
Greg Wardb48bc172000-03-01 21:51:56 +0000275/* Don't use the "_r" form if we don't need it (also, won't have a
276 prototype for it, at least on Solaris -- maybe others as well?). */
277#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
278#define USE_CTERMID_R
279#endif
280
281#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
282#define USE_TMPNAM_R
283#endif
284
Fred Drake699f3522000-06-29 21:12:41 +0000285/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000286#undef STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000287#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwis14694662006-02-03 12:54:16 +0000288# define STAT win32_stat
289# define FSTAT win32_fstat
290# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000291#else
292# define STAT stat
293# define FSTAT fstat
294# define STRUCT_STAT struct stat
295#endif
296
Tim Peters11b23062003-04-23 02:39:17 +0000297#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000298#include <sys/mkdev.h>
299#else
300#if defined(MAJOR_IN_SYSMACROS)
301#include <sys/sysmacros.h>
302#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000303#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
304#include <sys/mkdev.h>
305#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000306#endif
Fred Drake699f3522000-06-29 21:12:41 +0000307
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000308/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000309#ifdef WITH_NEXT_FRAMEWORK
310/* On Darwin/MacOSX a shared library or framework has no access to
311** environ directly, we must obtain it with _NSGetEnviron().
312*/
313#include <crt_externs.h>
314static char **environ;
315#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000316extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000317#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000318
Barry Warsaw53699e91996-12-10 23:23:01 +0000319static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000320convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000321{
Barry Warsaw53699e91996-12-10 23:23:01 +0000322 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000323 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000324 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000325 if (d == NULL)
326 return NULL;
Jack Jansenea0c3822002-08-01 21:57:49 +0000327#ifdef WITH_NEXT_FRAMEWORK
328 if (environ == NULL)
329 environ = *_NSGetEnviron();
330#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000331 if (environ == NULL)
332 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000333 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000334 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000335 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000336 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000337 char *p = strchr(*e, '=');
338 if (p == NULL)
339 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000340 k = PyString_FromStringAndSize(*e, (int)(p-*e));
341 if (k == NULL) {
342 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000343 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000344 }
345 v = PyString_FromString(p+1);
346 if (v == NULL) {
347 PyErr_Clear();
348 Py_DECREF(k);
349 continue;
350 }
351 if (PyDict_GetItem(d, k) == NULL) {
352 if (PyDict_SetItem(d, k, v) != 0)
353 PyErr_Clear();
354 }
355 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000356 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000357 }
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000358#if defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000359 {
360 APIRET rc;
361 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
362
363 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000364 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000365 PyObject *v = PyString_FromString(buffer);
366 PyDict_SetItemString(d, "BEGINLIBPATH", v);
367 Py_DECREF(v);
368 }
369 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
370 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
371 PyObject *v = PyString_FromString(buffer);
372 PyDict_SetItemString(d, "ENDLIBPATH", v);
373 Py_DECREF(v);
374 }
375 }
376#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000377 return d;
378}
379
380
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000381/* Set a POSIX-specific error from errno, and return NULL */
382
Barry Warsawd58d7641998-07-23 16:14:40 +0000383static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000384posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000385{
Barry Warsawca74da41999-02-09 19:31:45 +0000386 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000387}
Barry Warsawd58d7641998-07-23 16:14:40 +0000388static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000389posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000390{
Barry Warsawca74da41999-02-09 19:31:45 +0000391 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000392}
393
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000394#ifdef Py_WIN_WIDE_FILENAMES
395static PyObject *
396posix_error_with_unicode_filename(Py_UNICODE* name)
397{
398 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
399}
400#endif /* Py_WIN_WIDE_FILENAMES */
401
402
Mark Hammondef8b6542001-05-13 08:04:26 +0000403static PyObject *
404posix_error_with_allocated_filename(char* name)
405{
406 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
407 PyMem_Free(name);
408 return rc;
409}
410
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000411#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000412static PyObject *
413win32_error(char* function, char* filename)
414{
Mark Hammond33a6da92000-08-15 00:46:38 +0000415 /* XXX We should pass the function name along in the future.
416 (_winreg.c also wants to pass the function name.)
Tim Peters5aa91602002-01-30 05:46:57 +0000417 This would however require an additional param to the
Mark Hammond33a6da92000-08-15 00:46:38 +0000418 Windows error object, which is non-trivial.
419 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000420 errno = GetLastError();
421 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000422 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000423 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000424 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000425}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000426
427#ifdef Py_WIN_WIDE_FILENAMES
428static PyObject *
429win32_error_unicode(char* function, Py_UNICODE* filename)
430{
431 /* XXX - see win32_error for comments on 'function' */
432 errno = GetLastError();
433 if (filename)
434 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
435 else
436 return PyErr_SetFromWindowsErr(errno);
437}
438
439static PyObject *_PyUnicode_FromFileSystemEncodedObject(register PyObject *obj)
440{
441 /* XXX Perhaps we should make this API an alias of
442 PyObject_Unicode() instead ?! */
443 if (PyUnicode_CheckExact(obj)) {
444 Py_INCREF(obj);
445 return obj;
446 }
447 if (PyUnicode_Check(obj)) {
448 /* For a Unicode subtype that's not a Unicode object,
449 return a true Unicode object with the same data. */
450 return PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(obj),
451 PyUnicode_GET_SIZE(obj));
452 }
Tim Peters11b23062003-04-23 02:39:17 +0000453 return PyUnicode_FromEncodedObject(obj,
454 Py_FileSystemDefaultEncoding,
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000455 "strict");
456}
457
458#endif /* Py_WIN_WIDE_FILENAMES */
459
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000460#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000461
Guido van Rossumd48f2521997-12-05 22:19:34 +0000462#if defined(PYOS_OS2)
463/**********************************************************************
464 * Helper Function to Trim and Format OS/2 Messages
465 **********************************************************************/
466 static void
467os2_formatmsg(char *msgbuf, int msglen, char *reason)
468{
469 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
470
471 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
472 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
473
Neal Norwitz30b5c5d2005-12-19 06:05:18 +0000474 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
Guido van Rossumd48f2521997-12-05 22:19:34 +0000475 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
476 }
477
478 /* Add Optional Reason Text */
479 if (reason) {
480 strcat(msgbuf, " : ");
481 strcat(msgbuf, reason);
482 }
483}
484
485/**********************************************************************
486 * Decode an OS/2 Operating System Error Code
487 *
488 * A convenience function to lookup an OS/2 error code and return a
489 * text message we can use to raise a Python exception.
490 *
491 * Notes:
492 * The messages for errors returned from the OS/2 kernel reside in
493 * the file OSO001.MSG in the \OS2 directory hierarchy.
494 *
495 **********************************************************************/
496 static char *
497os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
498{
499 APIRET rc;
500 ULONG msglen;
501
502 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
503 Py_BEGIN_ALLOW_THREADS
504 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
505 errorcode, "oso001.msg", &msglen);
506 Py_END_ALLOW_THREADS
507
508 if (rc == NO_ERROR)
509 os2_formatmsg(msgbuf, msglen, reason);
510 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000511 PyOS_snprintf(msgbuf, msgbuflen,
Tim Peters885d4572001-11-28 20:27:42 +0000512 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000513
514 return msgbuf;
515}
516
517/* Set an OS/2-specific error and return NULL. OS/2 kernel
518 errors are not in a global variable e.g. 'errno' nor are
519 they congruent with posix error numbers. */
520
521static PyObject * os2_error(int code)
522{
523 char text[1024];
524 PyObject *v;
525
526 os2_strerror(text, sizeof(text), code, "");
527
528 v = Py_BuildValue("(is)", code, text);
529 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000530 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000531 Py_DECREF(v);
532 }
533 return NULL; /* Signal to Python that an Exception is Pending */
534}
535
536#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000537
538/* POSIX generic methods */
539
Barry Warsaw53699e91996-12-10 23:23:01 +0000540static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000541posix_fildes(PyObject *fdobj, int (*func)(int))
542{
543 int fd;
544 int res;
545 fd = PyObject_AsFileDescriptor(fdobj);
546 if (fd < 0)
547 return NULL;
548 Py_BEGIN_ALLOW_THREADS
549 res = (*func)(fd);
550 Py_END_ALLOW_THREADS
551 if (res < 0)
552 return posix_error();
553 Py_INCREF(Py_None);
554 return Py_None;
555}
Guido van Rossum21142a01999-01-08 21:05:37 +0000556
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000557#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters11b23062003-04-23 02:39:17 +0000558static int
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000559unicode_file_names(void)
560{
561 static int canusewide = -1;
562 if (canusewide == -1) {
Tim Peters11b23062003-04-23 02:39:17 +0000563 /* As per doc for ::GetVersion(), this is the correct test for
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000564 the Windows NT family. */
565 canusewide = (GetVersion() < 0x80000000) ? 1 : 0;
566 }
567 return canusewide;
568}
569#endif
Tim Peters11b23062003-04-23 02:39:17 +0000570
Guido van Rossum21142a01999-01-08 21:05:37 +0000571static PyObject *
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000572posix_1str(PyObject *args, char *format, int (*func)(const char*),
573 char *wformat, int (*wfunc)(const Py_UNICODE*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000574{
Mark Hammondef8b6542001-05-13 08:04:26 +0000575 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000576 int res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000577#ifdef Py_WIN_WIDE_FILENAMES
578 if (unicode_file_names()) {
579 PyUnicodeObject *po;
580 if (PyArg_ParseTuple(args, wformat, &po)) {
581 Py_BEGIN_ALLOW_THREADS
582 /* PyUnicode_AS_UNICODE OK without thread
583 lock as it is a simple dereference. */
584 res = (*wfunc)(PyUnicode_AS_UNICODE(po));
585 Py_END_ALLOW_THREADS
586 if (res < 0)
Mark Hammondd3890362002-10-03 07:24:48 +0000587 return posix_error_with_unicode_filename(PyUnicode_AS_UNICODE(po));
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000588 Py_INCREF(Py_None);
589 return Py_None;
590 }
591 /* Drop the argument parsing error as narrow
592 strings are also valid. */
593 PyErr_Clear();
594 }
595#else
596 /* Platforms that don't support Unicode filenames
597 shouldn't be passing these extra params */
598 assert(wformat==NULL && wfunc == NULL);
599#endif
600
Tim Peters5aa91602002-01-30 05:46:57 +0000601 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000602 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000603 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000604 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000605 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000606 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000607 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000608 return posix_error_with_allocated_filename(path1);
609 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000610 Py_INCREF(Py_None);
611 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000612}
613
Barry Warsaw53699e91996-12-10 23:23:01 +0000614static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000615posix_2str(PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000616 char *format,
617 int (*func)(const char *, const char *),
618 char *wformat,
619 int (*wfunc)(const Py_UNICODE *, const Py_UNICODE *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000620{
Mark Hammondef8b6542001-05-13 08:04:26 +0000621 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000622 int res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000623#ifdef Py_WIN_WIDE_FILENAMES
624 if (unicode_file_names()) {
625 PyObject *po1;
626 PyObject *po2;
627 if (PyArg_ParseTuple(args, wformat, &po1, &po2)) {
628 if (PyUnicode_Check(po1) || PyUnicode_Check(po2)) {
629 PyObject *wpath1;
630 PyObject *wpath2;
631 wpath1 = _PyUnicode_FromFileSystemEncodedObject(po1);
632 wpath2 = _PyUnicode_FromFileSystemEncodedObject(po2);
633 if (!wpath1 || !wpath2) {
634 Py_XDECREF(wpath1);
635 Py_XDECREF(wpath2);
636 return NULL;
637 }
638 Py_BEGIN_ALLOW_THREADS
639 /* PyUnicode_AS_UNICODE OK without thread
640 lock as it is a simple dereference. */
641 res = (*wfunc)(PyUnicode_AS_UNICODE(wpath1),
642 PyUnicode_AS_UNICODE(wpath2));
643 Py_END_ALLOW_THREADS
644 Py_XDECREF(wpath1);
645 Py_XDECREF(wpath2);
646 if (res != 0)
647 return posix_error();
648 Py_INCREF(Py_None);
649 return Py_None;
650 }
651 /* Else flow through as neither is Unicode. */
652 }
653 /* Drop the argument parsing error as narrow
654 strings are also valid. */
655 PyErr_Clear();
656 }
657#else
658 /* Platforms that don't support Unicode filenames
659 shouldn't be passing these extra params */
660 assert(wformat==NULL && wfunc == NULL);
661#endif
662
Mark Hammondef8b6542001-05-13 08:04:26 +0000663 if (!PyArg_ParseTuple(args, format,
Tim Peters5aa91602002-01-30 05:46:57 +0000664 Py_FileSystemDefaultEncoding, &path1,
Mark Hammondef8b6542001-05-13 08:04:26 +0000665 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000666 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000667 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000668 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000669 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000670 PyMem_Free(path1);
671 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000672 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000673 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000674 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000675 Py_INCREF(Py_None);
676 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000677}
678
Martin v. Löwis14694662006-02-03 12:54:16 +0000679#ifdef MS_WINDOWS
680/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
681 - time stamps are restricted to second resolution
682 - file modification times suffer from forth-and-back conversions between
683 UTC and local time
684 Therefore, we implement our own stat, based on the Win32 API directly.
685*/
686#define HAVE_STAT_NSEC 1
687
688struct win32_stat{
689 int st_dev;
690 __int64 st_ino;
691 unsigned short st_mode;
692 int st_nlink;
693 int st_uid;
694 int st_gid;
695 int st_rdev;
696 __int64 st_size;
697 int st_atime;
698 int st_atime_nsec;
699 int st_mtime;
700 int st_mtime_nsec;
701 int st_ctime;
702 int st_ctime_nsec;
703};
704
705static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
706
707static void
708FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, int *time_out, int* nsec_out)
709{
710 /* XXX endianness */
711 __int64 in = *(__int64*)in_ptr;
712 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
713 /* XXX Win32 supports time stamps past 2038; we currently don't */
714 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, int);
715}
716
717/* Below, we *know* that ugo+r is 0444 */
718#if _S_IREAD != 0400
719#error Unsupported C library
720#endif
721static int
722attributes_to_mode(DWORD attr)
723{
724 int m = 0;
725 if (attr & FILE_ATTRIBUTE_DIRECTORY)
726 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
727 else
728 m |= _S_IFREG;
729 if (attr & FILE_ATTRIBUTE_READONLY)
730 m |= 0444;
731 else
732 m |= 0666;
733 return m;
734}
735
736static int
737attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *result)
738{
739 memset(result, 0, sizeof(*result));
740 result->st_mode = attributes_to_mode(info->dwFileAttributes);
741 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
742 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
743 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
744 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
745
746 return 0;
747}
748
749static int
750win32_stat(const char* path, struct win32_stat *result)
751{
752 WIN32_FILE_ATTRIBUTE_DATA info;
753 int code;
754 char *dot;
755 /* XXX not supported on Win95 and NT 3.x */
756 if (!GetFileAttributesExA(path, GetFileExInfoStandard, &info)) {
757 /* Protocol violation: we explicitly clear errno, instead of
758 setting it to a POSIX error. Callers should use GetLastError. */
759 errno = 0;
760 return -1;
761 }
762 code = attribute_data_to_stat(&info, result);
763 if (code != 0)
764 return code;
765 /* Set S_IFEXEC if it is an .exe, .bat, ... */
766 dot = strrchr(path, '.');
767 if (dot) {
768 if (stricmp(dot, ".bat") == 0 ||
769 stricmp(dot, ".cmd") == 0 ||
770 stricmp(dot, ".exe") == 0 ||
771 stricmp(dot, ".com") == 0)
772 result->st_mode |= 0111;
773 }
774 return code;
775}
776
777static int
778win32_wstat(const wchar_t* path, struct win32_stat *result)
779{
780 int code;
781 const wchar_t *dot;
782 WIN32_FILE_ATTRIBUTE_DATA info;
783 /* XXX not supported on Win95 and NT 3.x */
784 if (!GetFileAttributesExW(path, GetFileExInfoStandard, &info)) {
785 /* Protocol violation: we explicitly clear errno, instead of
786 setting it to a POSIX error. Callers should use GetLastError. */
787 errno = 0;
788 return -1;
789 }
790 code = attribute_data_to_stat(&info, result);
791 if (code < 0)
792 return code;
793 /* Set IFEXEC if it is an .exe, .bat, ... */
794 dot = wcsrchr(path, '.');
795 if (dot) {
796 if (_wcsicmp(dot, L".bat") == 0 ||
797 _wcsicmp(dot, L".cmd") == 0 ||
798 _wcsicmp(dot, L".exe") == 0 ||
799 _wcsicmp(dot, L".com") == 0)
800 result->st_mode |= 0111;
801 }
802 return code;
803}
804
805static int
806win32_fstat(int file_number, struct win32_stat *result)
807{
808 BY_HANDLE_FILE_INFORMATION info;
809 HANDLE h;
810 int type;
811
812 h = (HANDLE)_get_osfhandle(file_number);
813
814 /* Protocol violation: we explicitly clear errno, instead of
815 setting it to a POSIX error. Callers should use GetLastError. */
816 errno = 0;
817
818 if (h == INVALID_HANDLE_VALUE) {
819 /* This is really a C library error (invalid file handle).
820 We set the Win32 error to the closes one matching. */
821 SetLastError(ERROR_INVALID_HANDLE);
822 return -1;
823 }
824 memset(result, 0, sizeof(*result));
825
826 type = GetFileType(h);
827 if (type == FILE_TYPE_UNKNOWN) {
828 DWORD error = GetLastError();
829 if (error != 0) {
830 return -1;
831 }
832 /* else: valid but unknown file */
833 }
834
835 if (type != FILE_TYPE_DISK) {
836 if (type == FILE_TYPE_CHAR)
837 result->st_mode = _S_IFCHR;
838 else if (type == FILE_TYPE_PIPE)
839 result->st_mode = _S_IFIFO;
840 return 0;
841 }
842
843 if (!GetFileInformationByHandle(h, &info)) {
844 return -1;
845 }
846
847 /* similar to stat() */
848 result->st_mode = attributes_to_mode(info.dwFileAttributes);
849 result->st_size = (((__int64)info.nFileSizeHigh)<<32) + info.nFileSizeLow;
850 FILE_TIME_to_time_t_nsec(&info.ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
851 FILE_TIME_to_time_t_nsec(&info.ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
852 FILE_TIME_to_time_t_nsec(&info.ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
853 /* specific to fstat() */
854 result->st_nlink = info.nNumberOfLinks;
855 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
856 return 0;
857}
858
859#endif /* MS_WINDOWS */
860
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000861PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000862"stat_result: Result from stat or lstat.\n\n\
863This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +0000864 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000865or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
866\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +0000867Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
868or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000869\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000870See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000871
872static PyStructSequence_Field stat_result_fields[] = {
873 {"st_mode", "protection bits"},
874 {"st_ino", "inode"},
875 {"st_dev", "device"},
876 {"st_nlink", "number of hard links"},
877 {"st_uid", "user ID of owner"},
878 {"st_gid", "group ID of owner"},
879 {"st_size", "total size, in bytes"},
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000880 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
881 {NULL, "integer time of last access"},
882 {NULL, "integer time of last modification"},
883 {NULL, "integer time of last change"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000884 {"st_atime", "time of last access"},
885 {"st_mtime", "time of last modification"},
886 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000887#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000888 {"st_blksize", "blocksize for filesystem I/O"},
889#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000890#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000891 {"st_blocks", "number of blocks allocated"},
892#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000893#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000894 {"st_rdev", "device type (if inode device)"},
895#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +0000896#ifdef HAVE_STRUCT_STAT_ST_FLAGS
897 {"st_flags", "user defined flags for file"},
898#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +0000899#ifdef HAVE_STRUCT_STAT_ST_GEN
900 {"st_gen", "generation number"},
901#endif
902#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
903 {"st_birthtime", "time of creation"},
904#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000905 {0}
906};
907
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000908#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000909#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000910#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000911#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000912#endif
913
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000914#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000915#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
916#else
917#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
918#endif
919
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000920#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000921#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
922#else
923#define ST_RDEV_IDX ST_BLOCKS_IDX
924#endif
925
Hye-Shik Chang5f937a72005-06-02 13:09:30 +0000926#ifdef HAVE_STRUCT_STAT_ST_FLAGS
927#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
928#else
929#define ST_FLAGS_IDX ST_RDEV_IDX
930#endif
931
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +0000932#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +0000933#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +0000934#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +0000935#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +0000936#endif
937
938#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
939#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
940#else
941#define ST_BIRTHTIME_IDX ST_GEN_IDX
942#endif
943
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000944static PyStructSequence_Desc stat_result_desc = {
945 "stat_result", /* name */
946 stat_result__doc__, /* doc */
947 stat_result_fields,
948 10
949};
950
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000951PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000952"statvfs_result: Result from statvfs or fstatvfs.\n\n\
953This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +0000954 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +0000955or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000956\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000957See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000958
959static PyStructSequence_Field statvfs_result_fields[] = {
960 {"f_bsize", },
961 {"f_frsize", },
962 {"f_blocks", },
963 {"f_bfree", },
964 {"f_bavail", },
965 {"f_files", },
966 {"f_ffree", },
967 {"f_favail", },
968 {"f_flag", },
969 {"f_namemax",},
970 {0}
971};
972
973static PyStructSequence_Desc statvfs_result_desc = {
974 "statvfs_result", /* name */
975 statvfs_result__doc__, /* doc */
976 statvfs_result_fields,
977 10
978};
979
980static PyTypeObject StatResultType;
981static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000982static newfunc structseq_new;
983
984static PyObject *
985statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
986{
987 PyStructSequence *result;
988 int i;
989
990 result = (PyStructSequence*)structseq_new(type, args, kwds);
991 if (!result)
992 return NULL;
993 /* If we have been initialized from a tuple,
994 st_?time might be set to None. Initialize it
995 from the int slots. */
996 for (i = 7; i <= 9; i++) {
997 if (result->ob_item[i+3] == Py_None) {
998 Py_DECREF(Py_None);
999 Py_INCREF(result->ob_item[i]);
1000 result->ob_item[i+3] = result->ob_item[i];
1001 }
1002 }
1003 return (PyObject*)result;
1004}
1005
1006
1007
1008/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001009static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001010
1011PyDoc_STRVAR(stat_float_times__doc__,
1012"stat_float_times([newval]) -> oldval\n\n\
1013Determine whether os.[lf]stat represents time stamps as float objects.\n\
1014If newval is True, future calls to stat() return floats, if it is False,\n\
1015future calls return ints. \n\
1016If newval is omitted, return the current setting.\n");
1017
1018static PyObject*
1019stat_float_times(PyObject* self, PyObject *args)
1020{
1021 int newval = -1;
1022 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1023 return NULL;
1024 if (newval == -1)
1025 /* Return old value */
1026 return PyBool_FromLong(_stat_float_times);
1027 _stat_float_times = newval;
1028 Py_INCREF(Py_None);
1029 return Py_None;
1030}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001031
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001032static void
1033fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1034{
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001035 PyObject *fval,*ival;
1036#if SIZEOF_TIME_T > SIZEOF_LONG
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00001037 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001038#else
1039 ival = PyInt_FromLong((long)sec);
1040#endif
1041 if (_stat_float_times) {
1042 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1043 } else {
1044 fval = ival;
1045 Py_INCREF(fval);
1046 }
1047 PyStructSequence_SET_ITEM(v, index, ival);
1048 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001049}
1050
Tim Peters5aa91602002-01-30 05:46:57 +00001051/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001052 (used by posix_stat() and posix_fstat()) */
1053static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001054_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001055{
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001056 unsigned long ansec, mnsec, cnsec;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001057 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +00001058 if (v == NULL)
1059 return NULL;
1060
Martin v. Löwis14694662006-02-03 12:54:16 +00001061 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001062#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001063 PyStructSequence_SET_ITEM(v, 1,
Martin v. Löwis14694662006-02-03 12:54:16 +00001064 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001065#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001066 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001067#endif
1068#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +00001069 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwis14694662006-02-03 12:54:16 +00001070 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001071#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001072 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001073#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001074 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st->st_nlink));
1075 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st->st_uid));
1076 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001077#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001078 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwis14694662006-02-03 12:54:16 +00001079 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001080#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001081 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001082#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001083
Martin v. Löwis14694662006-02-03 12:54:16 +00001084#if defined(HAVE_STAT_TV_NSEC)
1085 ansec = st->st_atim.tv_nsec;
1086 mnsec = st->st_mtim.tv_nsec;
1087 cnsec = st->st_ctim.tv_nsec;
1088#elif defined(HAVE_STAT_TV_NSEC2)
1089 ansec = st->st_atimespec.tv_nsec;
1090 mnsec = st->st_mtimespec.tv_nsec;
1091 cnsec = st->st_ctimespec.tv_nsec;
1092#elif defined(HAVE_STAT_NSEC)
1093 ansec = st->st_atime_nsec;
1094 mnsec = st->st_mtime_nsec;
1095 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001096#else
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001097 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001098#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001099 fill_time(v, 7, st->st_atime, ansec);
1100 fill_time(v, 8, st->st_mtime, mnsec);
1101 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001102
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001103#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +00001104 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001105 PyInt_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001106#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001107#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +00001108 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001109 PyInt_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001110#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001111#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001112 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001113 PyInt_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001114#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001115#ifdef HAVE_STRUCT_STAT_ST_GEN
1116 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001117 PyInt_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001118#endif
1119#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1120 {
1121 PyObject *val;
1122 unsigned long bsec,bnsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001123 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001124#ifdef HAVE_STAT_TV_NSEC2
Hye-Shik Changd69e0342006-02-19 16:22:22 +00001125 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001126#else
1127 bnsec = 0;
1128#endif
1129 if (_stat_float_times) {
1130 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1131 } else {
1132 val = PyInt_FromLong((long)bsec);
1133 }
1134 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1135 val);
1136 }
1137#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001138#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1139 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001140 PyInt_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001141#endif
Fred Drake699f3522000-06-29 21:12:41 +00001142
1143 if (PyErr_Occurred()) {
1144 Py_DECREF(v);
1145 return NULL;
1146 }
1147
1148 return v;
1149}
1150
Martin v. Löwisd8948722004-06-02 09:57:56 +00001151#ifdef MS_WINDOWS
1152
1153/* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
1154 where / can be used in place of \ and the trailing slash is optional.
1155 Both SERVER and SHARE must have at least one character.
1156*/
1157
1158#define ISSLASHA(c) ((c) == '\\' || (c) == '/')
1159#define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
1160#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
1161
Tim Peters4ad82172004-08-30 17:02:04 +00001162static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001163IsUNCRootA(char *path, int pathlen)
1164{
1165 #define ISSLASH ISSLASHA
1166
1167 int i, share;
1168
1169 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1170 /* minimum UNCRoot is \\x\y */
1171 return FALSE;
1172 for (i = 2; i < pathlen ; i++)
1173 if (ISSLASH(path[i])) break;
1174 if (i == 2 || i == pathlen)
1175 /* do not allow \\\SHARE or \\SERVER */
1176 return FALSE;
1177 share = i+1;
1178 for (i = share; i < pathlen; i++)
1179 if (ISSLASH(path[i])) break;
1180 return (i != share && (i == pathlen || i == pathlen-1));
1181
1182 #undef ISSLASH
1183}
1184
1185#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters4ad82172004-08-30 17:02:04 +00001186static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001187IsUNCRootW(Py_UNICODE *path, int pathlen)
1188{
1189 #define ISSLASH ISSLASHW
1190
1191 int i, share;
1192
1193 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1194 /* minimum UNCRoot is \\x\y */
1195 return FALSE;
1196 for (i = 2; i < pathlen ; i++)
1197 if (ISSLASH(path[i])) break;
1198 if (i == 2 || i == pathlen)
1199 /* do not allow \\\SHARE or \\SERVER */
1200 return FALSE;
1201 share = i+1;
1202 for (i = share; i < pathlen; i++)
1203 if (ISSLASH(path[i])) break;
1204 return (i != share && (i == pathlen || i == pathlen-1));
1205
1206 #undef ISSLASH
1207}
1208#endif /* Py_WIN_WIDE_FILENAMES */
1209#endif /* MS_WINDOWS */
1210
Barry Warsaw53699e91996-12-10 23:23:01 +00001211static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001212posix_do_stat(PyObject *self, PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001213 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001214#ifdef __VMS
1215 int (*statfunc)(const char *, STRUCT_STAT *, ...),
1216#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001217 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001218#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001219 char *wformat,
1220 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001221{
Fred Drake699f3522000-06-29 21:12:41 +00001222 STRUCT_STAT st;
Tim Peters500bd032001-12-19 19:05:01 +00001223 char *path = NULL; /* pass this to stat; do not free() it */
1224 char *pathfree = NULL; /* this memory must be free'd */
Guido van Rossumff4949e1992-08-05 19:58:53 +00001225 int res;
Martin v. Löwis14694662006-02-03 12:54:16 +00001226 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001227
1228#ifdef Py_WIN_WIDE_FILENAMES
1229 /* If on wide-character-capable OS see if argument
1230 is Unicode and if so use wide API. */
1231 if (unicode_file_names()) {
1232 PyUnicodeObject *po;
1233 if (PyArg_ParseTuple(args, wformat, &po)) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001234 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
1235
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001236 Py_BEGIN_ALLOW_THREADS
1237 /* PyUnicode_AS_UNICODE result OK without
1238 thread lock as it is a simple dereference. */
1239 res = wstatfunc(wpath, &st);
1240 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001241
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001242 if (res != 0)
Martin v. Löwis14694662006-02-03 12:54:16 +00001243 return win32_error_unicode("stat", wpath);
1244 return _pystat_fromstructstat(&st);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001245 }
1246 /* Drop the argument parsing error as narrow strings
1247 are also valid. */
1248 PyErr_Clear();
1249 }
1250#endif
1251
Tim Peters5aa91602002-01-30 05:46:57 +00001252 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +00001253 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001254 return NULL;
Tim Peters500bd032001-12-19 19:05:01 +00001255 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +00001256
Barry Warsaw53699e91996-12-10 23:23:01 +00001257 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001258 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00001259 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001260
1261 if (res != 0) {
1262#ifdef MS_WINDOWS
1263 result = win32_error("stat", pathfree);
1264#else
1265 result = posix_error_with_filename(pathfree);
1266#endif
1267 }
1268 else
1269 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001270
Tim Peters500bd032001-12-19 19:05:01 +00001271 PyMem_Free(pathfree);
Martin v. Löwis14694662006-02-03 12:54:16 +00001272 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001273}
1274
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001275/* POSIX methods */
1276
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001277PyDoc_STRVAR(posix_access__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001278"access(path, mode) -> 1 if granted, 0 otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001279Use the real uid/gid to test for access to a path. Note that most\n\
1280operations will use the effective uid/gid, therefore this routine can\n\
1281be used in a suid/sgid environment to test if the invoking user has the\n\
1282specified access to the path. The mode argument can be F_OK to test\n\
1283existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001284
1285static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001286posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001287{
Guido van Rossum015f22a1999-01-06 22:52:38 +00001288 char *path;
1289 int mode;
1290 int res;
1291
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001292#ifdef Py_WIN_WIDE_FILENAMES
1293 if (unicode_file_names()) {
1294 PyUnicodeObject *po;
1295 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1296 Py_BEGIN_ALLOW_THREADS
1297 /* PyUnicode_AS_UNICODE OK without thread lock as
1298 it is a simple dereference. */
1299 res = _waccess(PyUnicode_AS_UNICODE(po), mode);
1300 Py_END_ALLOW_THREADS
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001301 return PyBool_FromLong(res == 0);
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001302 }
1303 /* Drop the argument parsing error as narrow strings
1304 are also valid. */
1305 PyErr_Clear();
1306 }
1307#endif
Martin v. Löwisb60ae992005-03-08 09:10:29 +00001308 if (!PyArg_ParseTuple(args, "eti:access",
1309 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +00001310 return NULL;
1311 Py_BEGIN_ALLOW_THREADS
1312 res = access(path, mode);
1313 Py_END_ALLOW_THREADS
Neal Norwitz24b3c222005-09-19 06:43:44 +00001314 PyMem_Free(path);
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001315 return PyBool_FromLong(res == 0);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001316}
1317
Guido van Rossumd371ff11999-01-25 16:12:23 +00001318#ifndef F_OK
1319#define F_OK 0
1320#endif
1321#ifndef R_OK
1322#define R_OK 4
1323#endif
1324#ifndef W_OK
1325#define W_OK 2
1326#endif
1327#ifndef X_OK
1328#define X_OK 1
1329#endif
1330
1331#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001332PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001333"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001334Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001335
1336static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001337posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001338{
Guido van Rossum94f6f721999-01-06 18:42:14 +00001339 int id;
1340 char *ret;
1341
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001342 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +00001343 return NULL;
1344
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001345#if defined(__VMS)
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +00001346 /* file descriptor 0 only, the default input device (stdin) */
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001347 if (id == 0) {
1348 ret = ttyname();
1349 }
1350 else {
1351 ret = NULL;
1352 }
1353#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00001354 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001355#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001356 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001357 return posix_error();
1358 return PyString_FromString(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001359}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001360#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001361
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001362#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001363PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001364"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001365Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001366
1367static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001368posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001369{
1370 char *ret;
1371 char buffer[L_ctermid];
1372
Greg Wardb48bc172000-03-01 21:51:56 +00001373#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001374 ret = ctermid_r(buffer);
1375#else
1376 ret = ctermid(buffer);
1377#endif
1378 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001379 return posix_error();
1380 return PyString_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001381}
1382#endif
1383
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001384PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001385"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001386Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001387
Barry Warsaw53699e91996-12-10 23:23:01 +00001388static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001389posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001390{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001391#ifdef MS_WINDOWS
1392 return posix_1str(args, "et:chdir", chdir, "U:chdir", _wchdir);
1393#elif defined(PYOS_OS2) && defined(PYCC_GCC)
1394 return posix_1str(args, "et:chdir", _chdir2, NULL, NULL);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001395#elif defined(__VMS)
Tim Peters11b23062003-04-23 02:39:17 +00001396 return posix_1str(args, "et:chdir", (int (*)(const char *))chdir,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001397 NULL, NULL);
1398#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001399 return posix_1str(args, "et:chdir", chdir, NULL, NULL);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001400#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001401}
1402
Fred Drake4d1e64b2002-04-15 19:40:07 +00001403#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001404PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001405"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001406Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001407opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001408
1409static PyObject *
1410posix_fchdir(PyObject *self, PyObject *fdobj)
1411{
1412 return posix_fildes(fdobj, fchdir);
1413}
1414#endif /* HAVE_FCHDIR */
1415
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001416
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001417PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001418"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001419Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001420
Barry Warsaw53699e91996-12-10 23:23:01 +00001421static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001422posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001423{
Mark Hammondef8b6542001-05-13 08:04:26 +00001424 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +00001425 int i;
1426 int res;
Mark Hammond817c9292003-12-03 01:22:38 +00001427#ifdef Py_WIN_WIDE_FILENAMES
1428 if (unicode_file_names()) {
1429 PyUnicodeObject *po;
1430 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1431 Py_BEGIN_ALLOW_THREADS
1432 res = _wchmod(PyUnicode_AS_UNICODE(po), i);
1433 Py_END_ALLOW_THREADS
1434 if (res < 0)
1435 return posix_error_with_unicode_filename(
1436 PyUnicode_AS_UNICODE(po));
1437 Py_INCREF(Py_None);
1438 return Py_None;
1439 }
1440 /* Drop the argument parsing error as narrow strings
1441 are also valid. */
1442 PyErr_Clear();
1443 }
1444#endif /* Py_WIN_WIDE_FILENAMES */
1445 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
Mark Hammondef8b6542001-05-13 08:04:26 +00001446 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +00001447 return NULL;
1448 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +00001449 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001450 Py_END_ALLOW_THREADS
1451 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001452 return posix_error_with_allocated_filename(path);
1453 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001454 Py_INCREF(Py_None);
1455 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001456}
1457
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001458
Martin v. Löwis244edc82001-10-04 22:44:26 +00001459#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001460PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001461"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001462Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00001463
1464static PyObject *
1465posix_chroot(PyObject *self, PyObject *args)
1466{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001467 return posix_1str(args, "et:chroot", chroot, NULL, NULL);
Martin v. Löwis244edc82001-10-04 22:44:26 +00001468}
1469#endif
1470
Guido van Rossum21142a01999-01-08 21:05:37 +00001471#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001472PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001473"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001474force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001475
1476static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001477posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001478{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001479 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001480}
1481#endif /* HAVE_FSYNC */
1482
1483#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00001484
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00001485#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00001486extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1487#endif
1488
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001489PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001490"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00001491force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001492 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001493
1494static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001495posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001496{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001497 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001498}
1499#endif /* HAVE_FDATASYNC */
1500
1501
Fredrik Lundh10723342000-07-10 16:38:09 +00001502#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001503PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001504"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001505Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001506
Barry Warsaw53699e91996-12-10 23:23:01 +00001507static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001508posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001509{
Mark Hammondef8b6542001-05-13 08:04:26 +00001510 char *path = NULL;
Fredrik Lundh44328e62000-07-10 15:59:30 +00001511 int uid, gid;
1512 int res;
Tim Peters5aa91602002-01-30 05:46:57 +00001513 if (!PyArg_ParseTuple(args, "etii:chown",
1514 Py_FileSystemDefaultEncoding, &path,
Mark Hammondef8b6542001-05-13 08:04:26 +00001515 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +00001516 return NULL;
1517 Py_BEGIN_ALLOW_THREADS
1518 res = chown(path, (uid_t) uid, (gid_t) gid);
1519 Py_END_ALLOW_THREADS
1520 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001521 return posix_error_with_allocated_filename(path);
1522 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +00001523 Py_INCREF(Py_None);
1524 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001525}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001526#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001527
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001528#ifdef HAVE_LCHOWN
1529PyDoc_STRVAR(posix_lchown__doc__,
1530"lchown(path, uid, gid)\n\n\
1531Change the owner and group id of path to the numeric uid and gid.\n\
1532This function will not follow symbolic links.");
1533
1534static PyObject *
1535posix_lchown(PyObject *self, PyObject *args)
1536{
1537 char *path = NULL;
1538 int uid, gid;
1539 int res;
1540 if (!PyArg_ParseTuple(args, "etii:lchown",
1541 Py_FileSystemDefaultEncoding, &path,
1542 &uid, &gid))
1543 return NULL;
1544 Py_BEGIN_ALLOW_THREADS
1545 res = lchown(path, (uid_t) uid, (gid_t) gid);
1546 Py_END_ALLOW_THREADS
Tim Peters11b23062003-04-23 02:39:17 +00001547 if (res < 0)
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001548 return posix_error_with_allocated_filename(path);
1549 PyMem_Free(path);
1550 Py_INCREF(Py_None);
1551 return Py_None;
1552}
1553#endif /* HAVE_LCHOWN */
1554
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001555
Guido van Rossum36bc6801995-06-14 22:54:23 +00001556#ifdef HAVE_GETCWD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001557PyDoc_STRVAR(posix_getcwd__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001558"getcwd() -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001559Return a string representing the current working directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001560
Barry Warsaw53699e91996-12-10 23:23:01 +00001561static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001562posix_getcwd(PyObject *self, PyObject *noargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001563{
1564 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +00001565 char *res;
Neal Norwitze241ce82003-02-17 18:17:05 +00001566
Barry Warsaw53699e91996-12-10 23:23:01 +00001567 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001568#if defined(PYOS_OS2) && defined(PYCC_GCC)
1569 res = _getcwd2(buf, sizeof buf);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001570#else
Guido van Rossumff4949e1992-08-05 19:58:53 +00001571 res = getcwd(buf, sizeof buf);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001572#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001573 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001574 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001575 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001576 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001577}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001578
Walter Dörwald3b918c32002-11-21 20:18:46 +00001579#ifdef Py_USING_UNICODE
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001580PyDoc_STRVAR(posix_getcwdu__doc__,
1581"getcwdu() -> path\n\n\
1582Return a unicode string representing the current working directory.");
1583
1584static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001585posix_getcwdu(PyObject *self, PyObject *noargs)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001586{
1587 char buf[1026];
1588 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001589
1590#ifdef Py_WIN_WIDE_FILENAMES
1591 if (unicode_file_names()) {
1592 wchar_t *wres;
1593 wchar_t wbuf[1026];
1594 Py_BEGIN_ALLOW_THREADS
1595 wres = _wgetcwd(wbuf, sizeof wbuf/ sizeof wbuf[0]);
1596 Py_END_ALLOW_THREADS
1597 if (wres == NULL)
1598 return posix_error();
1599 return PyUnicode_FromWideChar(wbuf, wcslen(wbuf));
1600 }
1601#endif
1602
1603 Py_BEGIN_ALLOW_THREADS
1604#if defined(PYOS_OS2) && defined(PYCC_GCC)
1605 res = _getcwd2(buf, sizeof buf);
1606#else
1607 res = getcwd(buf, sizeof buf);
1608#endif
1609 Py_END_ALLOW_THREADS
1610 if (res == NULL)
1611 return posix_error();
1612 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
1613}
Guido van Rossum36bc6801995-06-14 22:54:23 +00001614#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00001615#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001616
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001617
Guido van Rossumb6775db1994-08-01 11:34:53 +00001618#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001619PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001620"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001621Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001622
Barry Warsaw53699e91996-12-10 23:23:01 +00001623static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001624posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001625{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001626 return posix_2str(args, "etet:link", link, NULL, NULL);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001627}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001628#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001629
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001630
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001631PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001632"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001633Return a list containing the names of the entries in the directory.\n\
1634\n\
1635 path: path of directory to list\n\
1636\n\
1637The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001638entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001639
Barry Warsaw53699e91996-12-10 23:23:01 +00001640static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001641posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001642{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001643 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001644 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001645#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001646
Barry Warsaw53699e91996-12-10 23:23:01 +00001647 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001648 HANDLE hFindFile;
Martin v. Löwise920f0d2006-03-07 23:59:33 +00001649 BOOL result;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001650 WIN32_FIND_DATA FileData;
Mark Hammondef8b6542001-05-13 08:04:26 +00001651 /* MAX_PATH characters could mean a bigger encoded string */
1652 char namebuf[MAX_PATH*2+5];
1653 char *bufptr = namebuf;
Martin v. Löwis18e16552006-02-15 17:27:45 +00001654 Py_ssize_t len = sizeof(namebuf)/sizeof(namebuf[0]);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001655
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001656#ifdef Py_WIN_WIDE_FILENAMES
1657 /* If on wide-character-capable OS see if argument
1658 is Unicode and if so use wide API. */
1659 if (unicode_file_names()) {
1660 PyUnicodeObject *po;
1661 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
1662 WIN32_FIND_DATAW wFileData;
1663 Py_UNICODE wnamebuf[MAX_PATH*2+5];
1664 Py_UNICODE wch;
1665 wcsncpy(wnamebuf, PyUnicode_AS_UNICODE(po), MAX_PATH);
1666 wnamebuf[MAX_PATH] = L'\0';
1667 len = wcslen(wnamebuf);
1668 wch = (len > 0) ? wnamebuf[len-1] : L'\0';
1669 if (wch != L'/' && wch != L'\\' && wch != L':')
1670 wnamebuf[len++] = L'/';
1671 wcscpy(wnamebuf + len, L"*.*");
1672 if ((d = PyList_New(0)) == NULL)
1673 return NULL;
1674 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
1675 if (hFindFile == INVALID_HANDLE_VALUE) {
1676 errno = GetLastError();
1677 if (errno == ERROR_FILE_NOT_FOUND) {
1678 return d;
1679 }
1680 Py_DECREF(d);
1681 return win32_error_unicode("FindFirstFileW", wnamebuf);
1682 }
1683 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00001684 /* Skip over . and .. */
1685 if (wcscmp(wFileData.cFileName, L".") != 0 &&
1686 wcscmp(wFileData.cFileName, L"..") != 0) {
1687 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
1688 if (v == NULL) {
1689 Py_DECREF(d);
1690 d = NULL;
1691 break;
1692 }
1693 if (PyList_Append(d, v) != 0) {
1694 Py_DECREF(v);
1695 Py_DECREF(d);
1696 d = NULL;
1697 break;
1698 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001699 Py_DECREF(v);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001700 }
Georg Brandl622927b2006-03-07 12:48:03 +00001701 Py_BEGIN_ALLOW_THREADS
1702 result = FindNextFileW(hFindFile, &wFileData);
1703 Py_END_ALLOW_THREADS
1704 } while (result == TRUE);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001705
1706 if (FindClose(hFindFile) == FALSE) {
1707 Py_DECREF(d);
1708 return win32_error_unicode("FindClose", wnamebuf);
1709 }
1710 return d;
1711 }
1712 /* Drop the argument parsing error as narrow strings
1713 are also valid. */
1714 PyErr_Clear();
1715 }
1716#endif
1717
Tim Peters5aa91602002-01-30 05:46:57 +00001718 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001719 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +00001720 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +00001721 if (len > 0) {
1722 char ch = namebuf[len-1];
1723 if (ch != SEP && ch != ALTSEP && ch != ':')
1724 namebuf[len++] = '/';
1725 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001726 strcpy(namebuf + len, "*.*");
1727
Barry Warsaw53699e91996-12-10 23:23:01 +00001728 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001729 return NULL;
1730
1731 hFindFile = FindFirstFile(namebuf, &FileData);
1732 if (hFindFile == INVALID_HANDLE_VALUE) {
1733 errno = GetLastError();
Guido van Rossum617bc191998-08-06 03:23:32 +00001734 if (errno == ERROR_FILE_NOT_FOUND)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001735 return d;
1736 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00001737 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001738 }
1739 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00001740 /* Skip over . and .. */
1741 if (strcmp(FileData.cFileName, ".") != 0 &&
1742 strcmp(FileData.cFileName, "..") != 0) {
1743 v = PyString_FromString(FileData.cFileName);
1744 if (v == NULL) {
1745 Py_DECREF(d);
1746 d = NULL;
1747 break;
1748 }
1749 if (PyList_Append(d, v) != 0) {
1750 Py_DECREF(v);
1751 Py_DECREF(d);
1752 d = NULL;
1753 break;
1754 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001755 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001756 }
Georg Brandl622927b2006-03-07 12:48:03 +00001757 Py_BEGIN_ALLOW_THREADS
1758 result = FindNextFile(hFindFile, &FileData);
1759 Py_END_ALLOW_THREADS
1760 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001761
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001762 if (FindClose(hFindFile) == FALSE) {
1763 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00001764 return win32_error("FindClose", namebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001765 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001766
1767 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001768
Tim Peters0bb44a42000-09-15 07:44:49 +00001769#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001770
1771#ifndef MAX_PATH
1772#define MAX_PATH CCHMAXPATH
1773#endif
1774 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00001775 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001776 PyObject *d, *v;
1777 char namebuf[MAX_PATH+5];
1778 HDIR hdir = 1;
1779 ULONG srchcnt = 1;
1780 FILEFINDBUF3 ep;
1781 APIRET rc;
1782
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001783 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001784 return NULL;
1785 if (len >= MAX_PATH) {
1786 PyErr_SetString(PyExc_ValueError, "path too long");
1787 return NULL;
1788 }
1789 strcpy(namebuf, name);
1790 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001791 if (*pt == ALTSEP)
1792 *pt = SEP;
1793 if (namebuf[len-1] != SEP)
1794 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001795 strcpy(namebuf + len, "*.*");
1796
1797 if ((d = PyList_New(0)) == NULL)
1798 return NULL;
1799
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001800 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
1801 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001802 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001803 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
1804 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
1805 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001806
1807 if (rc != NO_ERROR) {
1808 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001809 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001810 }
1811
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001812 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001813 do {
1814 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001815 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001816 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001817
1818 strcpy(namebuf, ep.achName);
1819
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001820 /* Leave Case of Name Alone -- In Native Form */
1821 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001822
1823 v = PyString_FromString(namebuf);
1824 if (v == NULL) {
1825 Py_DECREF(d);
1826 d = NULL;
1827 break;
1828 }
1829 if (PyList_Append(d, v) != 0) {
1830 Py_DECREF(v);
1831 Py_DECREF(d);
1832 d = NULL;
1833 break;
1834 }
1835 Py_DECREF(v);
1836 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
1837 }
1838
1839 return d;
1840#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001841
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001842 char *name = NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001843 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001844 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001845 struct dirent *ep;
Just van Rossum96b1c902003-03-03 17:32:15 +00001846 int arg_is_unicode = 1;
1847
1848 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
1849 arg_is_unicode = 0;
1850 PyErr_Clear();
1851 }
1852 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001853 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00001854 if ((dirp = opendir(name)) == NULL) {
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001855 return posix_error_with_allocated_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00001856 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001857 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001858 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001859 PyMem_Free(name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001860 return NULL;
1861 }
Georg Brandl622927b2006-03-07 12:48:03 +00001862 for (;;) {
1863 Py_BEGIN_ALLOW_THREADS
1864 ep = readdir(dirp);
1865 Py_END_ALLOW_THREADS
1866 if (ep == NULL)
1867 break;
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001868 if (ep->d_name[0] == '.' &&
1869 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00001870 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00001871 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00001872 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001873 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00001874 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001875 d = NULL;
1876 break;
1877 }
Just van Rossum46c97842003-02-25 21:42:15 +00001878#ifdef Py_USING_UNICODE
Just van Rossum96b1c902003-03-03 17:32:15 +00001879 if (arg_is_unicode) {
Just van Rossum46c97842003-02-25 21:42:15 +00001880 PyObject *w;
1881
1882 w = PyUnicode_FromEncodedObject(v,
Tim Peters11b23062003-04-23 02:39:17 +00001883 Py_FileSystemDefaultEncoding,
Just van Rossum46c97842003-02-25 21:42:15 +00001884 "strict");
Just van Rossum6a421832003-03-04 19:30:44 +00001885 if (w != NULL) {
1886 Py_DECREF(v);
1887 v = w;
1888 }
1889 else {
1890 /* fall back to the original byte string, as
1891 discussed in patch #683592 */
1892 PyErr_Clear();
Just van Rossum46c97842003-02-25 21:42:15 +00001893 }
Just van Rossum46c97842003-02-25 21:42:15 +00001894 }
1895#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001896 if (PyList_Append(d, v) != 0) {
1897 Py_DECREF(v);
1898 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001899 d = NULL;
1900 break;
1901 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001902 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001903 }
1904 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00001905 PyMem_Free(name);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00001906
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001907 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001908
Tim Peters0bb44a42000-09-15 07:44:49 +00001909#endif /* which OS */
1910} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001911
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001912#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00001913/* A helper function for abspath on win32 */
1914static PyObject *
1915posix__getfullpathname(PyObject *self, PyObject *args)
1916{
1917 /* assume encoded strings wont more than double no of chars */
1918 char inbuf[MAX_PATH*2];
1919 char *inbufp = inbuf;
Tim Peters67d70eb2006-03-01 04:35:45 +00001920 Py_ssize_t insize = sizeof(inbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00001921 char outbuf[MAX_PATH*2];
1922 char *temp;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001923#ifdef Py_WIN_WIDE_FILENAMES
1924 if (unicode_file_names()) {
1925 PyUnicodeObject *po;
1926 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
1927 Py_UNICODE woutbuf[MAX_PATH*2];
1928 Py_UNICODE *wtemp;
Tim Peters11b23062003-04-23 02:39:17 +00001929 if (!GetFullPathNameW(PyUnicode_AS_UNICODE(po),
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001930 sizeof(woutbuf)/sizeof(woutbuf[0]),
1931 woutbuf, &wtemp))
1932 return win32_error("GetFullPathName", "");
1933 return PyUnicode_FromUnicode(woutbuf, wcslen(woutbuf));
1934 }
1935 /* Drop the argument parsing error as narrow strings
1936 are also valid. */
1937 PyErr_Clear();
1938 }
1939#endif
Tim Peters5aa91602002-01-30 05:46:57 +00001940 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
1941 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00001942 &insize))
1943 return NULL;
1944 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
1945 outbuf, &temp))
1946 return win32_error("GetFullPathName", inbuf);
Martin v. Löwis969297f2004-06-15 18:49:58 +00001947 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
1948 return PyUnicode_Decode(outbuf, strlen(outbuf),
1949 Py_FileSystemDefaultEncoding, NULL);
1950 }
Mark Hammondef8b6542001-05-13 08:04:26 +00001951 return PyString_FromString(outbuf);
1952} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001953#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00001954
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001955PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001956"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001957Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001958
Barry Warsaw53699e91996-12-10 23:23:01 +00001959static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001960posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001961{
Guido van Rossumb0824db1996-02-25 04:50:32 +00001962 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00001963 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001964 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001965
1966#ifdef Py_WIN_WIDE_FILENAMES
1967 if (unicode_file_names()) {
1968 PyUnicodeObject *po;
Mark Hammond05107b62003-02-19 04:08:27 +00001969 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001970 Py_BEGIN_ALLOW_THREADS
1971 /* PyUnicode_AS_UNICODE OK without thread lock as
1972 it is a simple dereference. */
1973 res = _wmkdir(PyUnicode_AS_UNICODE(po));
1974 Py_END_ALLOW_THREADS
1975 if (res < 0)
1976 return posix_error();
1977 Py_INCREF(Py_None);
1978 return Py_None;
1979 }
1980 /* Drop the argument parsing error as narrow strings
1981 are also valid. */
1982 PyErr_Clear();
1983 }
1984#endif
1985
Tim Peters5aa91602002-01-30 05:46:57 +00001986 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001987 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00001988 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00001989 Py_BEGIN_ALLOW_THREADS
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001990#if ( defined(__WATCOMC__) || defined(_MSC_VER) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001991 res = mkdir(path);
1992#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00001993 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001994#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001995 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00001996 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001997 return posix_error_with_allocated_filename(path);
1998 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00001999 Py_INCREF(Py_None);
2000 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002001}
2002
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002003
Guido van Rossumb6775db1994-08-01 11:34:53 +00002004#ifdef HAVE_NICE
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002005#if defined(HAVE_BROKEN_NICE) && defined(HAVE_SYS_RESOURCE_H)
2006#if defined(HAVE_GETPRIORITY) && !defined(PRIO_PROCESS)
2007#include <sys/resource.h>
2008#endif
2009#endif
2010
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002011PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002012"nice(inc) -> new_priority\n\n\
2013Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002014
Barry Warsaw53699e91996-12-10 23:23:01 +00002015static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002016posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002017{
2018 int increment, value;
2019
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002020 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00002021 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002022
2023 /* There are two flavours of 'nice': one that returns the new
2024 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002025 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2026 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002027
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002028 If we are of the nice family that returns the new priority, we
2029 need to clear errno before the call, and check if errno is filled
2030 before calling posix_error() on a returnvalue of -1, because the
2031 -1 may be the actual new priority! */
2032
2033 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002034 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002035#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002036 if (value == 0)
2037 value = getpriority(PRIO_PROCESS, 0);
2038#endif
2039 if (value == -1 && errno != 0)
2040 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00002041 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002042 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002043}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002044#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002045
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002046
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002047PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002048"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002049Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002050
Barry Warsaw53699e91996-12-10 23:23:01 +00002051static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002052posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002053{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002054#ifdef MS_WINDOWS
2055 return posix_2str(args, "etet:rename", rename, "OO:rename", _wrename);
2056#else
2057 return posix_2str(args, "etet:rename", rename, NULL, NULL);
2058#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002059}
2060
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002061
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002062PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002063"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002064Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002065
Barry Warsaw53699e91996-12-10 23:23:01 +00002066static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002067posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002068{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002069#ifdef MS_WINDOWS
2070 return posix_1str(args, "et:rmdir", rmdir, "U:rmdir", _wrmdir);
2071#else
2072 return posix_1str(args, "et:rmdir", rmdir, NULL, NULL);
2073#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002074}
2075
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002076
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002077PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002078"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002079Perform a stat system call on the given path.");
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_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002083{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002084#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00002085 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002086#else
2087 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
2088#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002089}
2090
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002091
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002092#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002093PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002094"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002095Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002096
Barry Warsaw53699e91996-12-10 23:23:01 +00002097static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002098posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002099{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002100 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002101 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002102 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002103 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002104 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002105 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00002106 Py_END_ALLOW_THREADS
2107 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002108}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002109#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002110
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002111
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002112PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002113"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002114Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002115
Barry Warsaw53699e91996-12-10 23:23:01 +00002116static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002117posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002118{
2119 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002120 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002121 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00002122 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002123 if (i < 0)
2124 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002125 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002126}
2127
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002128
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002129PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002130"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002131Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002132
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002133PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002134"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002135Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002136
Barry Warsaw53699e91996-12-10 23:23:01 +00002137static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002138posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002139{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002140#ifdef MS_WINDOWS
2141 return posix_1str(args, "et:remove", unlink, "U:remove", _wunlink);
2142#else
2143 return posix_1str(args, "et:remove", unlink, NULL, NULL);
2144#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002145}
2146
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002147
Guido van Rossumb6775db1994-08-01 11:34:53 +00002148#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002149PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002150"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002151Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002152
Barry Warsaw53699e91996-12-10 23:23:01 +00002153static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002154posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002155{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002156 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002157 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00002158
Barry Warsaw53699e91996-12-10 23:23:01 +00002159 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002160 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00002161 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002162 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002163 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002164 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00002165 u.sysname,
2166 u.nodename,
2167 u.release,
2168 u.version,
2169 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002170}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002171#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002172
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002173static int
2174extract_time(PyObject *t, long* sec, long* usec)
2175{
2176 long intval;
2177 if (PyFloat_Check(t)) {
2178 double tval = PyFloat_AsDouble(t);
2179 PyObject *intobj = t->ob_type->tp_as_number->nb_int(t);
2180 if (!intobj)
2181 return -1;
2182 intval = PyInt_AsLong(intobj);
2183 Py_DECREF(intobj);
Michael W. Hudsonb8963812005-07-05 15:21:58 +00002184 if (intval == -1 && PyErr_Occurred())
2185 return -1;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002186 *sec = intval;
Tim Peters96940cf2002-09-10 15:37:28 +00002187 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002188 if (*usec < 0)
2189 /* If rounding gave us a negative number,
2190 truncate. */
2191 *usec = 0;
2192 return 0;
2193 }
2194 intval = PyInt_AsLong(t);
2195 if (intval == -1 && PyErr_Occurred())
2196 return -1;
2197 *sec = intval;
2198 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00002199 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002200}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002201
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002202PyDoc_STRVAR(posix_utime__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002203"utime(path, (atime, utime))\n\
2204utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00002205Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002206second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002207
Barry Warsaw53699e91996-12-10 23:23:01 +00002208static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002209posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002210{
Neal Norwitz2adf2102004-06-09 01:46:02 +00002211 char *path = NULL;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002212 long atime, mtime, ausec, musec;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002213 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002214 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002215
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002216#if defined(HAVE_UTIMES)
2217 struct timeval buf[2];
2218#define ATIME buf[0].tv_sec
2219#define MTIME buf[1].tv_sec
2220#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002221/* XXX should define struct utimbuf instead, above */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002222 struct utimbuf buf;
2223#define ATIME buf.actime
2224#define MTIME buf.modtime
2225#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002226#else /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002227 time_t buf[2];
2228#define ATIME buf[0]
2229#define MTIME buf[1]
2230#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002231#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002232
Mark Hammond817c9292003-12-03 01:22:38 +00002233 int have_unicode_filename = 0;
2234#ifdef Py_WIN_WIDE_FILENAMES
2235 PyUnicodeObject *obwpath;
2236 wchar_t *wpath;
2237 if (unicode_file_names()) {
2238 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
2239 wpath = PyUnicode_AS_UNICODE(obwpath);
2240 have_unicode_filename = 1;
2241 } else
2242 /* Drop the argument parsing error as narrow strings
2243 are also valid. */
2244 PyErr_Clear();
2245 }
2246#endif /* Py_WIN_WIDE_FILENAMES */
2247
2248 if (!have_unicode_filename && \
Hye-Shik Chang2b2c9732004-01-04 13:54:25 +00002249 !PyArg_ParseTuple(args, "etO:utime",
2250 Py_FileSystemDefaultEncoding, &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002251 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002252 if (arg == Py_None) {
2253 /* optional time values not given */
2254 Py_BEGIN_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002255#ifdef Py_WIN_WIDE_FILENAMES
2256 if (have_unicode_filename)
2257 res = _wutime(wpath, NULL);
2258 else
2259#endif /* Py_WIN_WIDE_FILENAMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002260 res = utime(path, NULL);
2261 Py_END_ALLOW_THREADS
2262 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002263 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00002264 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002265 "utime() arg 2 must be a tuple (atime, mtime)");
Neal Norwitz96652712004-06-06 20:40:27 +00002266 PyMem_Free(path);
Barry Warsaw3cef8562000-05-01 16:17:24 +00002267 return NULL;
2268 }
2269 else {
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002270 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Neal Norwitz96652712004-06-06 20:40:27 +00002271 &atime, &ausec) == -1) {
2272 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002273 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002274 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002275 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Neal Norwitz96652712004-06-06 20:40:27 +00002276 &mtime, &musec) == -1) {
2277 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002278 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002279 }
Barry Warsaw3cef8562000-05-01 16:17:24 +00002280 ATIME = atime;
2281 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002282#ifdef HAVE_UTIMES
2283 buf[0].tv_usec = ausec;
2284 buf[1].tv_usec = musec;
2285 Py_BEGIN_ALLOW_THREADS
2286 res = utimes(path, buf);
2287 Py_END_ALLOW_THREADS
2288#else
Barry Warsaw3cef8562000-05-01 16:17:24 +00002289 Py_BEGIN_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002290#ifdef Py_WIN_WIDE_FILENAMES
2291 if (have_unicode_filename)
Tim Peters4ad82172004-08-30 17:02:04 +00002292 /* utime is OK with utimbuf, but _wutime insists
2293 on _utimbuf (the msvc headers assert the
Mark Hammond817c9292003-12-03 01:22:38 +00002294 underscore version is ansi) */
2295 res = _wutime(wpath, (struct _utimbuf *)UTIME_ARG);
2296 else
2297#endif /* Py_WIN_WIDE_FILENAMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002298 res = utime(path, UTIME_ARG);
2299 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002300#endif /* HAVE_UTIMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002301 }
Mark Hammond2d5914b2004-05-04 08:10:37 +00002302 if (res < 0) {
2303#ifdef Py_WIN_WIDE_FILENAMES
Neal Norwitz2adf2102004-06-09 01:46:02 +00002304 if (have_unicode_filename)
Mark Hammond2d5914b2004-05-04 08:10:37 +00002305 return posix_error_with_unicode_filename(wpath);
2306#endif /* Py_WIN_WIDE_FILENAMES */
Neal Norwitz96652712004-06-06 20:40:27 +00002307 return posix_error_with_allocated_filename(path);
Mark Hammond2d5914b2004-05-04 08:10:37 +00002308 }
Neal Norwitz96652712004-06-06 20:40:27 +00002309 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002310 Py_INCREF(Py_None);
2311 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002312#undef UTIME_ARG
2313#undef ATIME
2314#undef MTIME
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002315}
2316
Guido van Rossum85e3b011991-06-03 12:42:10 +00002317
Guido van Rossum3b066191991-06-04 19:40:25 +00002318/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002319
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002320PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002321"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002322Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002323
Barry Warsaw53699e91996-12-10 23:23:01 +00002324static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002325posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002326{
2327 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002328 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002329 return NULL;
2330 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00002331 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002332}
2333
Martin v. Löwis114619e2002-10-07 06:44:21 +00002334#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
2335static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00002336free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00002337{
Martin v. Löwis725507b2006-03-07 12:08:51 +00002338 Py_ssize_t i;
Martin v. Löwis114619e2002-10-07 06:44:21 +00002339 for (i = 0; i < count; i++)
2340 PyMem_Free(array[i]);
2341 PyMem_DEL(array);
2342}
2343#endif
2344
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002345
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002346#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002347PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002348"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002349Execute an executable path with arguments, replacing current process.\n\
2350\n\
2351 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002352 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002353
Barry Warsaw53699e91996-12-10 23:23:01 +00002354static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002355posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002356{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002357 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002358 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002359 char **argvlist;
Martin v. Löwis725507b2006-03-07 12:08:51 +00002360 Py_ssize_t i, argc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002361 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002362
Guido van Rossum89b33251993-10-22 14:26:06 +00002363 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00002364 argv is a list or tuple of strings. */
2365
Martin v. Löwis114619e2002-10-07 06:44:21 +00002366 if (!PyArg_ParseTuple(args, "etO:execv",
2367 Py_FileSystemDefaultEncoding,
2368 &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002369 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002370 if (PyList_Check(argv)) {
2371 argc = PyList_Size(argv);
2372 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002373 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002374 else if (PyTuple_Check(argv)) {
2375 argc = PyTuple_Size(argv);
2376 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002377 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002378 else {
Fred Drake661ea262000-10-24 19:57:45 +00002379 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002380 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002381 return NULL;
2382 }
2383
Barry Warsaw53699e91996-12-10 23:23:01 +00002384 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002385 if (argvlist == NULL) {
2386 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002387 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002388 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002389 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002390 if (!PyArg_Parse((*getitem)(argv, i), "et",
2391 Py_FileSystemDefaultEncoding,
2392 &argvlist[i])) {
2393 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00002394 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002395 "execv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002396 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002397 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00002398
Guido van Rossum85e3b011991-06-03 12:42:10 +00002399 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002400 }
2401 argvlist[argc] = NULL;
2402
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002403 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002404
Guido van Rossum85e3b011991-06-03 12:42:10 +00002405 /* If we get here it's definitely an error */
2406
Martin v. Löwis114619e2002-10-07 06:44:21 +00002407 free_string_array(argvlist, argc);
2408 PyMem_Free(path);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002409 return posix_error();
2410}
2411
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002412
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002413PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002414"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002415Execute a path with arguments and environment, replacing current process.\n\
2416\n\
2417 path: path of executable file\n\
2418 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002419 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002420
Barry Warsaw53699e91996-12-10 23:23:01 +00002421static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002422posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002423{
2424 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002425 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002426 char **argvlist;
2427 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002428 PyObject *key, *val, *keys=NULL, *vals=NULL;
Martin v. Löwis725507b2006-03-07 12:08:51 +00002429 Py_ssize_t i, pos, argc, envc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002430 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002431 int lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002432
2433 /* execve has three arguments: (path, argv, env), where
2434 argv is a list or tuple of strings and env is a dictionary
2435 like posix.environ. */
2436
Martin v. Löwis114619e2002-10-07 06:44:21 +00002437 if (!PyArg_ParseTuple(args, "etOO:execve",
2438 Py_FileSystemDefaultEncoding,
2439 &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002440 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002441 if (PyList_Check(argv)) {
2442 argc = PyList_Size(argv);
2443 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002444 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002445 else if (PyTuple_Check(argv)) {
2446 argc = PyTuple_Size(argv);
2447 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002448 }
2449 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002450 PyErr_SetString(PyExc_TypeError,
2451 "execve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002452 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002453 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002454 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002455 PyErr_SetString(PyExc_TypeError,
2456 "execve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002457 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002458 }
2459
Barry Warsaw53699e91996-12-10 23:23:01 +00002460 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002461 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002462 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002463 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002464 }
2465 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002466 if (!PyArg_Parse((*getitem)(argv, i),
Martin v. Löwis114619e2002-10-07 06:44:21 +00002467 "et;execve() arg 2 must contain only strings",
Guido van Rossum1e700d22002-10-16 16:52:11 +00002468 Py_FileSystemDefaultEncoding,
Barry Warsaw43d68b81996-12-19 22:10:44 +00002469 &argvlist[i]))
2470 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002471 lastarg = i;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002472 goto fail_1;
2473 }
2474 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002475 lastarg = argc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002476 argvlist[argc] = NULL;
2477
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002478 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002479 if (i < 0)
2480 goto fail_1;
Barry Warsaw53699e91996-12-10 23:23:01 +00002481 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002482 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002483 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002484 goto fail_1;
2485 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002486 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002487 keys = PyMapping_Keys(env);
2488 vals = PyMapping_Values(env);
2489 if (!keys || !vals)
2490 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002491 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2492 PyErr_SetString(PyExc_TypeError,
2493 "execve(): env.keys() or env.values() is not a list");
2494 goto fail_2;
2495 }
Tim Peters5aa91602002-01-30 05:46:57 +00002496
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002497 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002498 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002499 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002500
2501 key = PyList_GetItem(keys, pos);
2502 val = PyList_GetItem(vals, pos);
2503 if (!key || !val)
2504 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002505
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002506 if (!PyArg_Parse(
2507 key,
2508 "s;execve() arg 3 contains a non-string key",
2509 &k) ||
2510 !PyArg_Parse(
2511 val,
2512 "s;execve() arg 3 contains a non-string value",
2513 &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00002514 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002515 goto fail_2;
2516 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00002517
2518#if defined(PYOS_OS2)
2519 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
2520 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
2521#endif
Tim Petersc8996f52001-12-03 20:41:00 +00002522 len = PyString_Size(key) + PyString_Size(val) + 2;
2523 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002524 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002525 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002526 goto fail_2;
2527 }
Tim Petersc8996f52001-12-03 20:41:00 +00002528 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002529 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00002530#if defined(PYOS_OS2)
2531 }
2532#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002533 }
2534 envlist[envc] = 0;
2535
2536 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00002537
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002538 /* If we get here it's definitely an error */
2539
2540 (void) posix_error();
2541
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002542 fail_2:
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002543 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00002544 PyMem_DEL(envlist[envc]);
2545 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002546 fail_1:
2547 free_string_array(argvlist, lastarg);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002548 Py_XDECREF(vals);
2549 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002550 fail_0:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002551 PyMem_Free(path);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002552 return NULL;
2553}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002554#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002555
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002556
Guido van Rossuma1065681999-01-25 23:20:23 +00002557#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002558PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002559"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002560Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002561\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002562 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002563 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002564 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002565
2566static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002567posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002568{
2569 char *path;
2570 PyObject *argv;
2571 char **argvlist;
2572 int mode, i, argc;
Tim Peters79248aa2001-08-29 21:37:10 +00002573 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002574 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00002575
2576 /* spawnv has three arguments: (mode, path, argv), where
2577 argv is a list or tuple of strings. */
2578
Martin v. Löwis114619e2002-10-07 06:44:21 +00002579 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
2580 Py_FileSystemDefaultEncoding,
2581 &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00002582 return NULL;
2583 if (PyList_Check(argv)) {
2584 argc = PyList_Size(argv);
2585 getitem = PyList_GetItem;
2586 }
2587 else if (PyTuple_Check(argv)) {
2588 argc = PyTuple_Size(argv);
2589 getitem = PyTuple_GetItem;
2590 }
2591 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002592 PyErr_SetString(PyExc_TypeError,
2593 "spawnv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002594 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002595 return NULL;
2596 }
2597
2598 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002599 if (argvlist == NULL) {
2600 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002601 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002602 }
Guido van Rossuma1065681999-01-25 23:20:23 +00002603 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002604 if (!PyArg_Parse((*getitem)(argv, i), "et",
2605 Py_FileSystemDefaultEncoding,
2606 &argvlist[i])) {
2607 free_string_array(argvlist, i);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002608 PyErr_SetString(
2609 PyExc_TypeError,
2610 "spawnv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002611 PyMem_Free(path);
Fred Drake137507e2000-06-01 02:02:46 +00002612 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00002613 }
2614 }
2615 argvlist[argc] = NULL;
2616
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002617#if defined(PYOS_OS2) && defined(PYCC_GCC)
2618 Py_BEGIN_ALLOW_THREADS
2619 spawnval = spawnv(mode, path, argvlist);
2620 Py_END_ALLOW_THREADS
2621#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002622 if (mode == _OLD_P_OVERLAY)
2623 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00002624
Tim Peters25059d32001-12-07 20:35:43 +00002625 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002626 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00002627 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002628#endif
Tim Peters5aa91602002-01-30 05:46:57 +00002629
Martin v. Löwis114619e2002-10-07 06:44:21 +00002630 free_string_array(argvlist, argc);
2631 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002632
Fred Drake699f3522000-06-29 21:12:41 +00002633 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002634 return posix_error();
2635 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002636#if SIZEOF_LONG == SIZEOF_VOID_P
2637 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002638#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00002639 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002640#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002641}
2642
2643
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002644PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002645"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002646Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002647\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002648 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002649 path: path of executable file\n\
2650 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002651 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002652
2653static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002654posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002655{
2656 char *path;
2657 PyObject *argv, *env;
2658 char **argvlist;
2659 char **envlist;
2660 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
2661 int mode, i, pos, argc, envc;
Tim Peters79248aa2001-08-29 21:37:10 +00002662 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002663 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002664 int lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002665
2666 /* spawnve has four arguments: (mode, path, argv, env), where
2667 argv is a list or tuple of strings and env is a dictionary
2668 like posix.environ. */
2669
Martin v. Löwis114619e2002-10-07 06:44:21 +00002670 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
2671 Py_FileSystemDefaultEncoding,
2672 &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00002673 return NULL;
2674 if (PyList_Check(argv)) {
2675 argc = PyList_Size(argv);
2676 getitem = PyList_GetItem;
2677 }
2678 else if (PyTuple_Check(argv)) {
2679 argc = PyTuple_Size(argv);
2680 getitem = PyTuple_GetItem;
2681 }
2682 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002683 PyErr_SetString(PyExc_TypeError,
2684 "spawnve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002685 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002686 }
2687 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002688 PyErr_SetString(PyExc_TypeError,
2689 "spawnve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002690 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002691 }
2692
2693 argvlist = PyMem_NEW(char *, argc+1);
2694 if (argvlist == NULL) {
2695 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002696 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002697 }
2698 for (i = 0; i < argc; i++) {
2699 if (!PyArg_Parse((*getitem)(argv, i),
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002700 "et;spawnve() arg 2 must contain only strings",
Martin v. Löwis114619e2002-10-07 06:44:21 +00002701 Py_FileSystemDefaultEncoding,
Guido van Rossuma1065681999-01-25 23:20:23 +00002702 &argvlist[i]))
2703 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002704 lastarg = i;
Guido van Rossuma1065681999-01-25 23:20:23 +00002705 goto fail_1;
2706 }
2707 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002708 lastarg = argc;
Guido van Rossuma1065681999-01-25 23:20:23 +00002709 argvlist[argc] = NULL;
2710
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002711 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002712 if (i < 0)
2713 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00002714 envlist = PyMem_NEW(char *, i + 1);
2715 if (envlist == NULL) {
2716 PyErr_NoMemory();
2717 goto fail_1;
2718 }
2719 envc = 0;
2720 keys = PyMapping_Keys(env);
2721 vals = PyMapping_Values(env);
2722 if (!keys || !vals)
2723 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002724 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2725 PyErr_SetString(PyExc_TypeError,
2726 "spawnve(): env.keys() or env.values() is not a list");
2727 goto fail_2;
2728 }
Tim Peters5aa91602002-01-30 05:46:57 +00002729
Guido van Rossuma1065681999-01-25 23:20:23 +00002730 for (pos = 0; pos < i; pos++) {
2731 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002732 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00002733
2734 key = PyList_GetItem(keys, pos);
2735 val = PyList_GetItem(vals, pos);
2736 if (!key || !val)
2737 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002738
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002739 if (!PyArg_Parse(
2740 key,
2741 "s;spawnve() arg 3 contains a non-string key",
2742 &k) ||
2743 !PyArg_Parse(
2744 val,
2745 "s;spawnve() arg 3 contains a non-string value",
2746 &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00002747 {
2748 goto fail_2;
2749 }
Tim Petersc8996f52001-12-03 20:41:00 +00002750 len = PyString_Size(key) + PyString_Size(val) + 2;
2751 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00002752 if (p == NULL) {
2753 PyErr_NoMemory();
2754 goto fail_2;
2755 }
Tim Petersc8996f52001-12-03 20:41:00 +00002756 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00002757 envlist[envc++] = p;
2758 }
2759 envlist[envc] = 0;
2760
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002761#if defined(PYOS_OS2) && defined(PYCC_GCC)
2762 Py_BEGIN_ALLOW_THREADS
2763 spawnval = spawnve(mode, path, argvlist, envlist);
2764 Py_END_ALLOW_THREADS
2765#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002766 if (mode == _OLD_P_OVERLAY)
2767 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00002768
2769 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002770 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00002771 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002772#endif
Tim Peters25059d32001-12-07 20:35:43 +00002773
Fred Drake699f3522000-06-29 21:12:41 +00002774 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002775 (void) posix_error();
2776 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002777#if SIZEOF_LONG == SIZEOF_VOID_P
2778 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002779#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00002780 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002781#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002782
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002783 fail_2:
Guido van Rossuma1065681999-01-25 23:20:23 +00002784 while (--envc >= 0)
2785 PyMem_DEL(envlist[envc]);
2786 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002787 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002788 free_string_array(argvlist, lastarg);
Guido van Rossuma1065681999-01-25 23:20:23 +00002789 Py_XDECREF(vals);
2790 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002791 fail_0:
2792 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002793 return res;
2794}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00002795
2796/* OS/2 supports spawnvp & spawnvpe natively */
2797#if defined(PYOS_OS2)
2798PyDoc_STRVAR(posix_spawnvp__doc__,
2799"spawnvp(mode, file, args)\n\n\
2800Execute the program 'file' in a new process, using the environment\n\
2801search path to find the file.\n\
2802\n\
2803 mode: mode of process creation\n\
2804 file: executable file name\n\
2805 args: tuple or list of strings");
2806
2807static PyObject *
2808posix_spawnvp(PyObject *self, PyObject *args)
2809{
2810 char *path;
2811 PyObject *argv;
2812 char **argvlist;
2813 int mode, i, argc;
2814 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002815 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00002816
2817 /* spawnvp has three arguments: (mode, path, argv), where
2818 argv is a list or tuple of strings. */
2819
2820 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
2821 Py_FileSystemDefaultEncoding,
2822 &path, &argv))
2823 return NULL;
2824 if (PyList_Check(argv)) {
2825 argc = PyList_Size(argv);
2826 getitem = PyList_GetItem;
2827 }
2828 else if (PyTuple_Check(argv)) {
2829 argc = PyTuple_Size(argv);
2830 getitem = PyTuple_GetItem;
2831 }
2832 else {
2833 PyErr_SetString(PyExc_TypeError,
2834 "spawnvp() arg 2 must be a tuple or list");
2835 PyMem_Free(path);
2836 return NULL;
2837 }
2838
2839 argvlist = PyMem_NEW(char *, argc+1);
2840 if (argvlist == NULL) {
2841 PyMem_Free(path);
2842 return PyErr_NoMemory();
2843 }
2844 for (i = 0; i < argc; i++) {
2845 if (!PyArg_Parse((*getitem)(argv, i), "et",
2846 Py_FileSystemDefaultEncoding,
2847 &argvlist[i])) {
2848 free_string_array(argvlist, i);
2849 PyErr_SetString(
2850 PyExc_TypeError,
2851 "spawnvp() arg 2 must contain only strings");
2852 PyMem_Free(path);
2853 return NULL;
2854 }
2855 }
2856 argvlist[argc] = NULL;
2857
2858 Py_BEGIN_ALLOW_THREADS
2859#if defined(PYCC_GCC)
2860 spawnval = spawnvp(mode, path, argvlist);
2861#else
2862 spawnval = _spawnvp(mode, path, argvlist);
2863#endif
2864 Py_END_ALLOW_THREADS
2865
2866 free_string_array(argvlist, argc);
2867 PyMem_Free(path);
2868
2869 if (spawnval == -1)
2870 return posix_error();
2871 else
2872 return Py_BuildValue("l", (long) spawnval);
2873}
2874
2875
2876PyDoc_STRVAR(posix_spawnvpe__doc__,
2877"spawnvpe(mode, file, args, env)\n\n\
2878Execute the program 'file' in a new process, using the environment\n\
2879search path to find the file.\n\
2880\n\
2881 mode: mode of process creation\n\
2882 file: executable file name\n\
2883 args: tuple or list of arguments\n\
2884 env: dictionary of strings mapping to strings");
2885
2886static PyObject *
2887posix_spawnvpe(PyObject *self, PyObject *args)
2888{
2889 char *path;
2890 PyObject *argv, *env;
2891 char **argvlist;
2892 char **envlist;
2893 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
2894 int mode, i, pos, argc, envc;
2895 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002896 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00002897 int lastarg = 0;
2898
2899 /* spawnvpe has four arguments: (mode, path, argv, env), where
2900 argv is a list or tuple of strings and env is a dictionary
2901 like posix.environ. */
2902
2903 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
2904 Py_FileSystemDefaultEncoding,
2905 &path, &argv, &env))
2906 return NULL;
2907 if (PyList_Check(argv)) {
2908 argc = PyList_Size(argv);
2909 getitem = PyList_GetItem;
2910 }
2911 else if (PyTuple_Check(argv)) {
2912 argc = PyTuple_Size(argv);
2913 getitem = PyTuple_GetItem;
2914 }
2915 else {
2916 PyErr_SetString(PyExc_TypeError,
2917 "spawnvpe() arg 2 must be a tuple or list");
2918 goto fail_0;
2919 }
2920 if (!PyMapping_Check(env)) {
2921 PyErr_SetString(PyExc_TypeError,
2922 "spawnvpe() arg 3 must be a mapping object");
2923 goto fail_0;
2924 }
2925
2926 argvlist = PyMem_NEW(char *, argc+1);
2927 if (argvlist == NULL) {
2928 PyErr_NoMemory();
2929 goto fail_0;
2930 }
2931 for (i = 0; i < argc; i++) {
2932 if (!PyArg_Parse((*getitem)(argv, i),
2933 "et;spawnvpe() arg 2 must contain only strings",
2934 Py_FileSystemDefaultEncoding,
2935 &argvlist[i]))
2936 {
2937 lastarg = i;
2938 goto fail_1;
2939 }
2940 }
2941 lastarg = argc;
2942 argvlist[argc] = NULL;
2943
2944 i = PyMapping_Size(env);
2945 if (i < 0)
2946 goto fail_1;
2947 envlist = PyMem_NEW(char *, i + 1);
2948 if (envlist == NULL) {
2949 PyErr_NoMemory();
2950 goto fail_1;
2951 }
2952 envc = 0;
2953 keys = PyMapping_Keys(env);
2954 vals = PyMapping_Values(env);
2955 if (!keys || !vals)
2956 goto fail_2;
2957 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2958 PyErr_SetString(PyExc_TypeError,
2959 "spawnvpe(): env.keys() or env.values() is not a list");
2960 goto fail_2;
2961 }
2962
2963 for (pos = 0; pos < i; pos++) {
2964 char *p, *k, *v;
2965 size_t len;
2966
2967 key = PyList_GetItem(keys, pos);
2968 val = PyList_GetItem(vals, pos);
2969 if (!key || !val)
2970 goto fail_2;
2971
2972 if (!PyArg_Parse(
2973 key,
2974 "s;spawnvpe() arg 3 contains a non-string key",
2975 &k) ||
2976 !PyArg_Parse(
2977 val,
2978 "s;spawnvpe() arg 3 contains a non-string value",
2979 &v))
2980 {
2981 goto fail_2;
2982 }
2983 len = PyString_Size(key) + PyString_Size(val) + 2;
2984 p = PyMem_NEW(char, len);
2985 if (p == NULL) {
2986 PyErr_NoMemory();
2987 goto fail_2;
2988 }
2989 PyOS_snprintf(p, len, "%s=%s", k, v);
2990 envlist[envc++] = p;
2991 }
2992 envlist[envc] = 0;
2993
2994 Py_BEGIN_ALLOW_THREADS
2995#if defined(PYCC_GCC)
2996 spawnval = spawnve(mode, path, argvlist, envlist);
2997#else
2998 spawnval = _spawnve(mode, path, argvlist, envlist);
2999#endif
3000 Py_END_ALLOW_THREADS
3001
3002 if (spawnval == -1)
3003 (void) posix_error();
3004 else
3005 res = Py_BuildValue("l", (long) spawnval);
3006
3007 fail_2:
3008 while (--envc >= 0)
3009 PyMem_DEL(envlist[envc]);
3010 PyMem_DEL(envlist);
3011 fail_1:
3012 free_string_array(argvlist, lastarg);
3013 Py_XDECREF(vals);
3014 Py_XDECREF(keys);
3015 fail_0:
3016 PyMem_Free(path);
3017 return res;
3018}
3019#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003020#endif /* HAVE_SPAWNV */
3021
3022
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003023#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003024PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003025"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003026Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3027\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003028Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003029
3030static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003031posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003032{
Neal Norwitze241ce82003-02-17 18:17:05 +00003033 int pid = fork1();
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003034 if (pid == -1)
3035 return posix_error();
3036 PyOS_AfterFork();
3037 return PyInt_FromLong((long)pid);
3038}
3039#endif
3040
3041
Guido van Rossumad0ee831995-03-01 10:34:45 +00003042#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003043PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003044"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003045Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003046Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003047
Barry Warsaw53699e91996-12-10 23:23:01 +00003048static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003049posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003050{
Neal Norwitze241ce82003-02-17 18:17:05 +00003051 int pid = fork();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003052 if (pid == -1)
3053 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003054 if (pid == 0)
3055 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00003056 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003057}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003058#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003059
Neal Norwitzb59798b2003-03-21 01:43:31 +00003060/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00003061/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3062#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00003063#define DEV_PTY_FILE "/dev/ptc"
3064#define HAVE_DEV_PTMX
3065#else
3066#define DEV_PTY_FILE "/dev/ptmx"
3067#endif
3068
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003069#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003070#ifdef HAVE_PTY_H
3071#include <pty.h>
3072#else
3073#ifdef HAVE_LIBUTIL_H
3074#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00003075#endif /* HAVE_LIBUTIL_H */
3076#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00003077#ifdef HAVE_STROPTS_H
3078#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003079#endif
3080#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003081
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003082#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003083PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003084"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003085Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003086
3087static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003088posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003089{
3090 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003091#ifndef HAVE_OPENPTY
3092 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003093#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003094#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003095 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003096#ifdef sun
3097 extern char *ptsname();
3098#endif
3099#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00003100
Thomas Wouters70c21a12000-07-14 14:28:33 +00003101#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00003102 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
3103 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003104#elif defined(HAVE__GETPTY)
Thomas Wouters70c21a12000-07-14 14:28:33 +00003105 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
3106 if (slave_name == NULL)
3107 return posix_error();
3108
3109 slave_fd = open(slave_name, O_RDWR);
3110 if (slave_fd < 0)
3111 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003112#else
Neal Norwitzb59798b2003-03-21 01:43:31 +00003113 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003114 if (master_fd < 0)
3115 return posix_error();
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003116 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003117 /* change permission of slave */
3118 if (grantpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003119 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003120 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003121 }
3122 /* unlock slave */
3123 if (unlockpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003124 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003125 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003126 }
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003127 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003128 slave_name = ptsname(master_fd); /* get name of slave */
3129 if (slave_name == NULL)
3130 return posix_error();
3131 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
3132 if (slave_fd < 0)
3133 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003134#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003135 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
3136 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00003137#ifndef __hpux
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003138 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00003139#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003140#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00003141#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00003142
Fred Drake8cef4cf2000-06-28 16:40:38 +00003143 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00003144
Fred Drake8cef4cf2000-06-28 16:40:38 +00003145}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003146#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003147
3148#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003149PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003150"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00003151Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
3152Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003153To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003154
3155static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003156posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003157{
Neal Norwitz24b3c222005-09-19 06:43:44 +00003158 int master_fd = -1, pid;
Tim Peters5aa91602002-01-30 05:46:57 +00003159
Fred Drake8cef4cf2000-06-28 16:40:38 +00003160 pid = forkpty(&master_fd, NULL, NULL, NULL);
3161 if (pid == -1)
3162 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003163 if (pid == 0)
3164 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00003165 return Py_BuildValue("(ii)", pid, master_fd);
3166}
3167#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003168
Guido van Rossumad0ee831995-03-01 10:34:45 +00003169#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003170PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003171"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003172Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003173
Barry Warsaw53699e91996-12-10 23:23:01 +00003174static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003175posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003176{
Barry Warsaw53699e91996-12-10 23:23:01 +00003177 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003178}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003179#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003180
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003181
Guido van Rossumad0ee831995-03-01 10:34:45 +00003182#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003183PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003184"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003185Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003186
Barry Warsaw53699e91996-12-10 23:23:01 +00003187static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003188posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003189{
Barry Warsaw53699e91996-12-10 23:23:01 +00003190 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003191}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003192#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003193
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003194
Guido van Rossumad0ee831995-03-01 10:34:45 +00003195#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003196PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003197"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003198Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003199
Barry Warsaw53699e91996-12-10 23:23:01 +00003200static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003201posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003202{
Barry Warsaw53699e91996-12-10 23:23:01 +00003203 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003204}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003205#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003206
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003207
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003208PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003209"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003210Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003211
Barry Warsaw53699e91996-12-10 23:23:01 +00003212static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003213posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003214{
Barry Warsaw53699e91996-12-10 23:23:01 +00003215 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003216}
3217
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003218
Fred Drakec9680921999-12-13 16:37:25 +00003219#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003220PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003221"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003222Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00003223
3224static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003225posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00003226{
3227 PyObject *result = NULL;
3228
Fred Drakec9680921999-12-13 16:37:25 +00003229#ifdef NGROUPS_MAX
3230#define MAX_GROUPS NGROUPS_MAX
3231#else
3232 /* defined to be 16 on Solaris7, so this should be a small number */
3233#define MAX_GROUPS 64
3234#endif
3235 gid_t grouplist[MAX_GROUPS];
3236 int n;
3237
3238 n = getgroups(MAX_GROUPS, grouplist);
3239 if (n < 0)
3240 posix_error();
3241 else {
3242 result = PyList_New(n);
3243 if (result != NULL) {
Fred Drakec9680921999-12-13 16:37:25 +00003244 int i;
3245 for (i = 0; i < n; ++i) {
Neal Norwitze241ce82003-02-17 18:17:05 +00003246 PyObject *o = PyInt_FromLong((long)grouplist[i]);
Fred Drakec9680921999-12-13 16:37:25 +00003247 if (o == NULL) {
3248 Py_DECREF(result);
3249 result = NULL;
3250 break;
3251 }
3252 PyList_SET_ITEM(result, i, o);
3253 }
3254 }
3255 }
Neal Norwitze241ce82003-02-17 18:17:05 +00003256
Fred Drakec9680921999-12-13 16:37:25 +00003257 return result;
3258}
3259#endif
3260
Martin v. Löwis606edc12002-06-13 21:09:11 +00003261#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003262PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003263"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003264Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00003265
3266static PyObject *
3267posix_getpgid(PyObject *self, PyObject *args)
3268{
3269 int pid, pgid;
3270 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
3271 return NULL;
3272 pgid = getpgid(pid);
3273 if (pgid < 0)
3274 return posix_error();
3275 return PyInt_FromLong((long)pgid);
3276}
3277#endif /* HAVE_GETPGID */
3278
3279
Guido van Rossumb6775db1994-08-01 11:34:53 +00003280#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003281PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003282"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003283Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003284
Barry Warsaw53699e91996-12-10 23:23:01 +00003285static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003286posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00003287{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003288#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00003289 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003290#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00003291 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003292#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00003293}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003294#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00003295
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003296
Guido van Rossumb6775db1994-08-01 11:34:53 +00003297#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003298PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003299"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003300Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003301
Barry Warsaw53699e91996-12-10 23:23:01 +00003302static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003303posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003304{
Guido van Rossum64933891994-10-20 21:56:42 +00003305#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00003306 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003307#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003308 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003309#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00003310 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003311 Py_INCREF(Py_None);
3312 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003313}
3314
Guido van Rossumb6775db1994-08-01 11:34:53 +00003315#endif /* HAVE_SETPGRP */
3316
Guido van Rossumad0ee831995-03-01 10:34:45 +00003317#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003318PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003319"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003320Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003321
Barry Warsaw53699e91996-12-10 23:23:01 +00003322static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003323posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003324{
Barry Warsaw53699e91996-12-10 23:23:01 +00003325 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003326}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003327#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003328
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003329
Fred Drake12c6e2d1999-12-14 21:25:03 +00003330#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003331PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003332"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003333Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00003334
3335static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003336posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00003337{
Neal Norwitze241ce82003-02-17 18:17:05 +00003338 PyObject *result = NULL;
Fred Drakea30680b2000-12-06 21:24:28 +00003339 char *name;
3340 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00003341
Fred Drakea30680b2000-12-06 21:24:28 +00003342 errno = 0;
3343 name = getlogin();
3344 if (name == NULL) {
3345 if (errno)
3346 posix_error();
3347 else
3348 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00003349 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00003350 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00003351 else
3352 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00003353 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00003354
Fred Drake12c6e2d1999-12-14 21:25:03 +00003355 return result;
3356}
3357#endif
3358
Guido van Rossumad0ee831995-03-01 10:34:45 +00003359#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003360PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003361"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003362Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003363
Barry Warsaw53699e91996-12-10 23:23:01 +00003364static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003365posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003366{
Barry Warsaw53699e91996-12-10 23:23:01 +00003367 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003368}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003369#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003370
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003371
Guido van Rossumad0ee831995-03-01 10:34:45 +00003372#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003373PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003374"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003375Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003376
Barry Warsaw53699e91996-12-10 23:23:01 +00003377static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003378posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003379{
3380 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003381 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00003382 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003383#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003384 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
3385 APIRET rc;
3386 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003387 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003388
3389 } else if (sig == XCPT_SIGNAL_KILLPROC) {
3390 APIRET rc;
3391 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003392 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003393
3394 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003395 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003396#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00003397 if (kill(pid, sig) == -1)
3398 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003399#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003400 Py_INCREF(Py_None);
3401 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003402}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003403#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003404
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003405#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003406PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003407"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003408Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003409
3410static PyObject *
3411posix_killpg(PyObject *self, PyObject *args)
3412{
3413 int pgid, sig;
3414 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
3415 return NULL;
3416 if (killpg(pgid, sig) == -1)
3417 return posix_error();
3418 Py_INCREF(Py_None);
3419 return Py_None;
3420}
3421#endif
3422
Guido van Rossumc0125471996-06-28 18:55:32 +00003423#ifdef HAVE_PLOCK
3424
3425#ifdef HAVE_SYS_LOCK_H
3426#include <sys/lock.h>
3427#endif
3428
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003429PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003430"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003431Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003432
Barry Warsaw53699e91996-12-10 23:23:01 +00003433static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003434posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00003435{
3436 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003437 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00003438 return NULL;
3439 if (plock(op) == -1)
3440 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003441 Py_INCREF(Py_None);
3442 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00003443}
3444#endif
3445
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003446
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003447#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003448PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003449"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003450Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003451
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003452#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003453#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003454static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003455async_system(const char *command)
3456{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003457 char errormsg[256], args[1024];
3458 RESULTCODES rcodes;
3459 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003460
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003461 char *shell = getenv("COMSPEC");
3462 if (!shell)
3463 shell = "cmd";
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003464
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003465 /* avoid overflowing the argument buffer */
3466 if (strlen(shell) + 3 + strlen(command) >= 1024)
3467 return ERROR_NOT_ENOUGH_MEMORY
3468
3469 args[0] = '\0';
3470 strcat(args, shell);
3471 strcat(args, "/c ");
3472 strcat(args, command);
3473
3474 /* execute asynchronously, inheriting the environment */
3475 rc = DosExecPgm(errormsg,
3476 sizeof(errormsg),
3477 EXEC_ASYNC,
3478 args,
3479 NULL,
3480 &rcodes,
3481 shell);
3482 return rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003483}
3484
Guido van Rossumd48f2521997-12-05 22:19:34 +00003485static FILE *
3486popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003487{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003488 int oldfd, tgtfd;
3489 HFILE pipeh[2];
3490 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003491
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003492 /* mode determines which of stdin or stdout is reconnected to
3493 * the pipe to the child
3494 */
3495 if (strchr(mode, 'r') != NULL) {
3496 tgt_fd = 1; /* stdout */
3497 } else if (strchr(mode, 'w')) {
3498 tgt_fd = 0; /* stdin */
3499 } else {
3500 *err = ERROR_INVALID_ACCESS;
3501 return NULL;
3502 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003503
Andrew MacIntyrea3be2582004-12-18 09:51:05 +00003504 /* setup the pipe */
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003505 if ((rc = DosCreatePipe(&pipeh[0], &pipeh[1], pipesize)) != NO_ERROR) {
3506 *err = rc;
3507 return NULL;
3508 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003509
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003510 /* prevent other threads accessing stdio */
3511 DosEnterCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003512
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003513 /* reconnect stdio and execute child */
3514 oldfd = dup(tgtfd);
3515 close(tgtfd);
3516 if (dup2(pipeh[tgtfd], tgtfd) == 0) {
3517 DosClose(pipeh[tgtfd]);
3518 rc = async_system(command);
3519 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003520
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003521 /* restore stdio */
3522 dup2(oldfd, tgtfd);
3523 close(oldfd);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003524
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003525 /* allow other threads access to stdio */
3526 DosExitCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003527
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003528 /* if execution of child was successful return file stream */
3529 if (rc == NO_ERROR)
3530 return fdopen(pipeh[1 - tgtfd], mode);
3531 else {
3532 DosClose(pipeh[1 - tgtfd]);
3533 *err = rc;
3534 return NULL;
3535 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003536}
3537
3538static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003539posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003540{
3541 char *name;
3542 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00003543 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003544 FILE *fp;
3545 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003546 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003547 return NULL;
3548 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00003549 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003550 Py_END_ALLOW_THREADS
3551 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003552 return os2_error(err);
3553
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003554 f = PyFile_FromFile(fp, name, mode, fclose);
3555 if (f != NULL)
3556 PyFile_SetBufSize(f, bufsize);
3557 return f;
3558}
3559
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003560#elif defined(PYCC_GCC)
3561
3562/* standard posix version of popen() support */
3563static PyObject *
3564posix_popen(PyObject *self, PyObject *args)
3565{
3566 char *name;
3567 char *mode = "r";
3568 int bufsize = -1;
3569 FILE *fp;
3570 PyObject *f;
3571 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
3572 return NULL;
3573 Py_BEGIN_ALLOW_THREADS
3574 fp = popen(name, mode);
3575 Py_END_ALLOW_THREADS
3576 if (fp == NULL)
3577 return posix_error();
3578 f = PyFile_FromFile(fp, name, mode, pclose);
3579 if (f != NULL)
3580 PyFile_SetBufSize(f, bufsize);
3581 return f;
3582}
3583
3584/* fork() under OS/2 has lots'o'warts
3585 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
3586 * most of this code is a ripoff of the win32 code, but using the
3587 * capabilities of EMX's C library routines
3588 */
3589
3590/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
3591#define POPEN_1 1
3592#define POPEN_2 2
3593#define POPEN_3 3
3594#define POPEN_4 4
3595
3596static PyObject *_PyPopen(char *, int, int, int);
3597static int _PyPclose(FILE *file);
3598
3599/*
3600 * Internal dictionary mapping popen* file pointers to process handles,
3601 * for use when retrieving the process exit code. See _PyPclose() below
3602 * for more information on this dictionary's use.
3603 */
3604static PyObject *_PyPopenProcs = NULL;
3605
3606/* os2emx version of popen2()
3607 *
3608 * The result of this function is a pipe (file) connected to the
3609 * process's stdin, and a pipe connected to the process's stdout.
3610 */
3611
3612static PyObject *
3613os2emx_popen2(PyObject *self, PyObject *args)
3614{
3615 PyObject *f;
3616 int tm=0;
3617
3618 char *cmdstring;
3619 char *mode = "t";
3620 int bufsize = -1;
3621 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
3622 return NULL;
3623
3624 if (*mode == 't')
3625 tm = O_TEXT;
3626 else if (*mode != 'b') {
3627 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3628 return NULL;
3629 } else
3630 tm = O_BINARY;
3631
3632 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
3633
3634 return f;
3635}
3636
3637/*
3638 * Variation on os2emx.popen2
3639 *
3640 * The result of this function is 3 pipes - the process's stdin,
3641 * stdout and stderr
3642 */
3643
3644static PyObject *
3645os2emx_popen3(PyObject *self, PyObject *args)
3646{
3647 PyObject *f;
3648 int tm = 0;
3649
3650 char *cmdstring;
3651 char *mode = "t";
3652 int bufsize = -1;
3653 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
3654 return NULL;
3655
3656 if (*mode == 't')
3657 tm = O_TEXT;
3658 else if (*mode != 'b') {
3659 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3660 return NULL;
3661 } else
3662 tm = O_BINARY;
3663
3664 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
3665
3666 return f;
3667}
3668
3669/*
3670 * Variation on os2emx.popen2
3671 *
Tim Peters11b23062003-04-23 02:39:17 +00003672 * The result of this function is 2 pipes - the processes stdin,
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003673 * and stdout+stderr combined as a single pipe.
3674 */
3675
3676static PyObject *
3677os2emx_popen4(PyObject *self, PyObject *args)
3678{
3679 PyObject *f;
3680 int tm = 0;
3681
3682 char *cmdstring;
3683 char *mode = "t";
3684 int bufsize = -1;
3685 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
3686 return NULL;
3687
3688 if (*mode == 't')
3689 tm = O_TEXT;
3690 else if (*mode != 'b') {
3691 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3692 return NULL;
3693 } else
3694 tm = O_BINARY;
3695
3696 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
3697
3698 return f;
3699}
3700
3701/* a couple of structures for convenient handling of multiple
3702 * file handles and pipes
3703 */
3704struct file_ref
3705{
3706 int handle;
3707 int flags;
3708};
3709
3710struct pipe_ref
3711{
3712 int rd;
3713 int wr;
3714};
3715
3716/* The following code is derived from the win32 code */
3717
3718static PyObject *
3719_PyPopen(char *cmdstring, int mode, int n, int bufsize)
3720{
3721 struct file_ref stdio[3];
3722 struct pipe_ref p_fd[3];
3723 FILE *p_s[3];
3724 int file_count, i, pipe_err, pipe_pid;
3725 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
3726 PyObject *f, *p_f[3];
3727
3728 /* file modes for subsequent fdopen's on pipe handles */
3729 if (mode == O_TEXT)
3730 {
3731 rd_mode = "rt";
3732 wr_mode = "wt";
3733 }
3734 else
3735 {
3736 rd_mode = "rb";
3737 wr_mode = "wb";
3738 }
3739
3740 /* prepare shell references */
3741 if ((shell = getenv("EMXSHELL")) == NULL)
3742 if ((shell = getenv("COMSPEC")) == NULL)
3743 {
3744 errno = ENOENT;
3745 return posix_error();
3746 }
3747
3748 sh_name = _getname(shell);
3749 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
3750 opt = "/c";
3751 else
3752 opt = "-c";
3753
3754 /* save current stdio fds + their flags, and set not inheritable */
3755 i = pipe_err = 0;
3756 while (pipe_err >= 0 && i < 3)
3757 {
3758 pipe_err = stdio[i].handle = dup(i);
3759 stdio[i].flags = fcntl(i, F_GETFD, 0);
3760 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
3761 i++;
3762 }
3763 if (pipe_err < 0)
3764 {
3765 /* didn't get them all saved - clean up and bail out */
3766 int saved_err = errno;
3767 while (i-- > 0)
3768 {
3769 close(stdio[i].handle);
3770 }
3771 errno = saved_err;
3772 return posix_error();
3773 }
3774
3775 /* create pipe ends */
3776 file_count = 2;
3777 if (n == POPEN_3)
3778 file_count = 3;
3779 i = pipe_err = 0;
3780 while ((pipe_err == 0) && (i < file_count))
3781 pipe_err = pipe((int *)&p_fd[i++]);
3782 if (pipe_err < 0)
3783 {
3784 /* didn't get them all made - clean up and bail out */
3785 while (i-- > 0)
3786 {
3787 close(p_fd[i].wr);
3788 close(p_fd[i].rd);
3789 }
3790 errno = EPIPE;
3791 return posix_error();
3792 }
3793
3794 /* change the actual standard IO streams over temporarily,
3795 * making the retained pipe ends non-inheritable
3796 */
3797 pipe_err = 0;
3798
3799 /* - stdin */
3800 if (dup2(p_fd[0].rd, 0) == 0)
3801 {
3802 close(p_fd[0].rd);
3803 i = fcntl(p_fd[0].wr, F_GETFD, 0);
3804 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
3805 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
3806 {
3807 close(p_fd[0].wr);
3808 pipe_err = -1;
3809 }
3810 }
3811 else
3812 {
3813 pipe_err = -1;
3814 }
3815
3816 /* - stdout */
3817 if (pipe_err == 0)
3818 {
3819 if (dup2(p_fd[1].wr, 1) == 1)
3820 {
3821 close(p_fd[1].wr);
3822 i = fcntl(p_fd[1].rd, F_GETFD, 0);
3823 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
3824 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
3825 {
3826 close(p_fd[1].rd);
3827 pipe_err = -1;
3828 }
3829 }
3830 else
3831 {
3832 pipe_err = -1;
3833 }
3834 }
3835
3836 /* - stderr, as required */
3837 if (pipe_err == 0)
3838 switch (n)
3839 {
3840 case POPEN_3:
3841 {
3842 if (dup2(p_fd[2].wr, 2) == 2)
3843 {
3844 close(p_fd[2].wr);
3845 i = fcntl(p_fd[2].rd, F_GETFD, 0);
3846 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
3847 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
3848 {
3849 close(p_fd[2].rd);
3850 pipe_err = -1;
3851 }
3852 }
3853 else
3854 {
3855 pipe_err = -1;
3856 }
3857 break;
3858 }
3859
3860 case POPEN_4:
3861 {
3862 if (dup2(1, 2) != 2)
3863 {
3864 pipe_err = -1;
3865 }
3866 break;
3867 }
3868 }
3869
3870 /* spawn the child process */
3871 if (pipe_err == 0)
3872 {
3873 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
3874 if (pipe_pid == -1)
3875 {
3876 pipe_err = -1;
3877 }
3878 else
3879 {
3880 /* save the PID into the FILE structure
3881 * NOTE: this implementation doesn't actually
3882 * take advantage of this, but do it for
3883 * completeness - AIM Apr01
3884 */
3885 for (i = 0; i < file_count; i++)
3886 p_s[i]->_pid = pipe_pid;
3887 }
3888 }
3889
3890 /* reset standard IO to normal */
3891 for (i = 0; i < 3; i++)
3892 {
3893 dup2(stdio[i].handle, i);
3894 fcntl(i, F_SETFD, stdio[i].flags);
3895 close(stdio[i].handle);
3896 }
3897
3898 /* if any remnant problems, clean up and bail out */
3899 if (pipe_err < 0)
3900 {
3901 for (i = 0; i < 3; i++)
3902 {
3903 close(p_fd[i].rd);
3904 close(p_fd[i].wr);
3905 }
3906 errno = EPIPE;
3907 return posix_error_with_filename(cmdstring);
3908 }
3909
3910 /* build tuple of file objects to return */
3911 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
3912 PyFile_SetBufSize(p_f[0], bufsize);
3913 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
3914 PyFile_SetBufSize(p_f[1], bufsize);
3915 if (n == POPEN_3)
3916 {
3917 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
3918 PyFile_SetBufSize(p_f[0], bufsize);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00003919 f = PyTuple_Pack(3, p_f[0], p_f[1], p_f[2]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003920 }
3921 else
Raymond Hettinger8ae46892003-10-12 19:09:37 +00003922 f = PyTuple_Pack(2, p_f[0], p_f[1]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003923
3924 /*
3925 * Insert the files we've created into the process dictionary
3926 * all referencing the list with the process handle and the
3927 * initial number of files (see description below in _PyPclose).
3928 * Since if _PyPclose later tried to wait on a process when all
3929 * handles weren't closed, it could create a deadlock with the
3930 * child, we spend some energy here to try to ensure that we
3931 * either insert all file handles into the dictionary or none
3932 * at all. It's a little clumsy with the various popen modes
3933 * and variable number of files involved.
3934 */
3935 if (!_PyPopenProcs)
3936 {
3937 _PyPopenProcs = PyDict_New();
3938 }
3939
3940 if (_PyPopenProcs)
3941 {
3942 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
3943 int ins_rc[3];
3944
3945 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
3946 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
3947
3948 procObj = PyList_New(2);
3949 pidObj = PyInt_FromLong((long) pipe_pid);
3950 intObj = PyInt_FromLong((long) file_count);
3951
3952 if (procObj && pidObj && intObj)
3953 {
3954 PyList_SetItem(procObj, 0, pidObj);
3955 PyList_SetItem(procObj, 1, intObj);
3956
3957 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
3958 if (fileObj[0])
3959 {
3960 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
3961 fileObj[0],
3962 procObj);
3963 }
3964 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
3965 if (fileObj[1])
3966 {
3967 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
3968 fileObj[1],
3969 procObj);
3970 }
3971 if (file_count >= 3)
3972 {
3973 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
3974 if (fileObj[2])
3975 {
3976 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
3977 fileObj[2],
3978 procObj);
3979 }
3980 }
3981
3982 if (ins_rc[0] < 0 || !fileObj[0] ||
3983 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
3984 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
3985 {
3986 /* Something failed - remove any dictionary
3987 * entries that did make it.
3988 */
3989 if (!ins_rc[0] && fileObj[0])
3990 {
3991 PyDict_DelItem(_PyPopenProcs,
3992 fileObj[0]);
3993 }
3994 if (!ins_rc[1] && fileObj[1])
3995 {
3996 PyDict_DelItem(_PyPopenProcs,
3997 fileObj[1]);
3998 }
3999 if (!ins_rc[2] && fileObj[2])
4000 {
4001 PyDict_DelItem(_PyPopenProcs,
4002 fileObj[2]);
4003 }
4004 }
4005 }
Tim Peters11b23062003-04-23 02:39:17 +00004006
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004007 /*
4008 * Clean up our localized references for the dictionary keys
4009 * and value since PyDict_SetItem will Py_INCREF any copies
4010 * that got placed in the dictionary.
4011 */
4012 Py_XDECREF(procObj);
4013 Py_XDECREF(fileObj[0]);
4014 Py_XDECREF(fileObj[1]);
4015 Py_XDECREF(fileObj[2]);
4016 }
4017
4018 /* Child is launched. */
4019 return f;
4020}
4021
4022/*
4023 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4024 * exit code for the child process and return as a result of the close.
4025 *
4026 * This function uses the _PyPopenProcs dictionary in order to map the
4027 * input file pointer to information about the process that was
4028 * originally created by the popen* call that created the file pointer.
4029 * The dictionary uses the file pointer as a key (with one entry
4030 * inserted for each file returned by the original popen* call) and a
4031 * single list object as the value for all files from a single call.
4032 * The list object contains the Win32 process handle at [0], and a file
4033 * count at [1], which is initialized to the total number of file
4034 * handles using that list.
4035 *
4036 * This function closes whichever handle it is passed, and decrements
4037 * the file count in the dictionary for the process handle pointed to
4038 * by this file. On the last close (when the file count reaches zero),
4039 * this function will wait for the child process and then return its
4040 * exit code as the result of the close() operation. This permits the
4041 * files to be closed in any order - it is always the close() of the
4042 * final handle that will return the exit code.
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004043 *
4044 * NOTE: This function is currently called with the GIL released.
4045 * hence we use the GILState API to manage our state.
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004046 */
4047
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004048static int _PyPclose(FILE *file)
4049{
4050 int result;
4051 int exit_code;
4052 int pipe_pid;
4053 PyObject *procObj, *pidObj, *intObj, *fileObj;
4054 int file_count;
4055#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004056 PyGILState_STATE state;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004057#endif
4058
4059 /* Close the file handle first, to ensure it can't block the
4060 * child from exiting if it's the last handle.
4061 */
4062 result = fclose(file);
4063
4064#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004065 state = PyGILState_Ensure();
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004066#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004067 if (_PyPopenProcs)
4068 {
4069 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4070 (procObj = PyDict_GetItem(_PyPopenProcs,
4071 fileObj)) != NULL &&
4072 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
4073 (intObj = PyList_GetItem(procObj,1)) != NULL)
4074 {
4075 pipe_pid = (int) PyInt_AsLong(pidObj);
4076 file_count = (int) PyInt_AsLong(intObj);
4077
4078 if (file_count > 1)
4079 {
4080 /* Still other files referencing process */
4081 file_count--;
4082 PyList_SetItem(procObj,1,
4083 PyInt_FromLong((long) file_count));
4084 }
4085 else
4086 {
4087 /* Last file for this process */
4088 if (result != EOF &&
4089 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
4090 {
4091 /* extract exit status */
4092 if (WIFEXITED(exit_code))
4093 {
4094 result = WEXITSTATUS(exit_code);
4095 }
4096 else
4097 {
4098 errno = EPIPE;
4099 result = -1;
4100 }
4101 }
4102 else
4103 {
4104 /* Indicate failure - this will cause the file object
4105 * to raise an I/O error and translate the last
4106 * error code from errno. We do have a problem with
4107 * last errors that overlap the normal errno table,
4108 * but that's a consistent problem with the file object.
4109 */
4110 result = -1;
4111 }
4112 }
4113
4114 /* Remove this file pointer from dictionary */
4115 PyDict_DelItem(_PyPopenProcs, fileObj);
4116
4117 if (PyDict_Size(_PyPopenProcs) == 0)
4118 {
4119 Py_DECREF(_PyPopenProcs);
4120 _PyPopenProcs = NULL;
4121 }
4122
4123 } /* if object retrieval ok */
4124
4125 Py_XDECREF(fileObj);
4126 } /* if _PyPopenProcs */
4127
4128#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004129 PyGILState_Release(state);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004130#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004131 return result;
4132}
4133
4134#endif /* PYCC_??? */
4135
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004136#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004137
4138/*
4139 * Portable 'popen' replacement for Win32.
4140 *
4141 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
4142 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00004143 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004144 */
4145
4146#include <malloc.h>
4147#include <io.h>
4148#include <fcntl.h>
4149
4150/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
4151#define POPEN_1 1
4152#define POPEN_2 2
4153#define POPEN_3 3
4154#define POPEN_4 4
4155
4156static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004157static int _PyPclose(FILE *file);
4158
4159/*
4160 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00004161 * for use when retrieving the process exit code. See _PyPclose() below
4162 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004163 */
4164static PyObject *_PyPopenProcs = NULL;
4165
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004166
4167/* popen that works from a GUI.
4168 *
4169 * The result of this function is a pipe (file) connected to the
4170 * processes stdin or stdout, depending on the requested mode.
4171 */
4172
4173static PyObject *
4174posix_popen(PyObject *self, PyObject *args)
4175{
Raymond Hettingerb5cb6652003-09-01 22:25:41 +00004176 PyObject *f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004177 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004178
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004179 char *cmdstring;
4180 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004181 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004182 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004183 return NULL;
4184
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004185 if (*mode == 'r')
4186 tm = _O_RDONLY;
4187 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00004188 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004189 return NULL;
4190 } else
4191 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00004192
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004193 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004194 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004195 return NULL;
4196 }
4197
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004198 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004199 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004200 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004201 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004202 else
4203 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
4204
4205 return f;
4206}
4207
4208/* Variation on win32pipe.popen
4209 *
4210 * The result of this function is a pipe (file) connected to the
4211 * process's stdin, and a pipe connected to the process's stdout.
4212 */
4213
4214static PyObject *
4215win32_popen2(PyObject *self, PyObject *args)
4216{
4217 PyObject *f;
4218 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00004219
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004220 char *cmdstring;
4221 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004222 int bufsize = -1;
4223 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004224 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004225
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004226 if (*mode == 't')
4227 tm = _O_TEXT;
4228 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004229 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004230 return NULL;
4231 } else
4232 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004233
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004234 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004235 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004236 return NULL;
4237 }
4238
4239 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00004240
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004241 return f;
4242}
4243
4244/*
4245 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004246 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004247 * The result of this function is 3 pipes - the process's stdin,
4248 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004249 */
4250
4251static PyObject *
4252win32_popen3(PyObject *self, PyObject *args)
4253{
4254 PyObject *f;
4255 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004256
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004257 char *cmdstring;
4258 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004259 int bufsize = -1;
4260 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004261 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004262
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004263 if (*mode == 't')
4264 tm = _O_TEXT;
4265 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004266 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004267 return NULL;
4268 } else
4269 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004270
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004271 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004272 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004273 return NULL;
4274 }
4275
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004276 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00004277
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004278 return f;
4279}
4280
4281/*
4282 * Variation on win32pipe.popen
4283 *
Tim Peters5aa91602002-01-30 05:46:57 +00004284 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004285 * and stdout+stderr combined as a single pipe.
4286 */
4287
4288static PyObject *
4289win32_popen4(PyObject *self, PyObject *args)
4290{
4291 PyObject *f;
4292 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004293
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004294 char *cmdstring;
4295 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004296 int bufsize = -1;
4297 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004298 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004299
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004300 if (*mode == 't')
4301 tm = _O_TEXT;
4302 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004303 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004304 return NULL;
4305 } else
4306 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004307
4308 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004309 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004310 return NULL;
4311 }
4312
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004313 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004314
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004315 return f;
4316}
4317
Mark Hammond08501372001-01-31 07:30:29 +00004318static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00004319_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004320 HANDLE hStdin,
4321 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00004322 HANDLE hStderr,
4323 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004324{
4325 PROCESS_INFORMATION piProcInfo;
4326 STARTUPINFO siStartInfo;
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004327 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004328 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00004329 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004330 int i;
Martin v. Löwis18e16552006-02-15 17:27:45 +00004331 Py_ssize_t x;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004332
4333 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00004334 char *comshell;
4335
Tim Peters92e4dd82002-10-05 01:47:34 +00004336 s1 = (char *)alloca(i);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004337 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
Martin v. Löwis18e16552006-02-15 17:27:45 +00004338 /* x < i, so x fits into an integer */
4339 return (int)x;
Tim Peters402d5982001-08-27 06:37:48 +00004340
4341 /* Explicitly check if we are using COMMAND.COM. If we are
4342 * then use the w9xpopen hack.
4343 */
4344 comshell = s1 + x;
4345 while (comshell >= s1 && *comshell != '\\')
4346 --comshell;
4347 ++comshell;
4348
4349 if (GetVersion() < 0x80000000 &&
4350 _stricmp(comshell, "command.com") != 0) {
4351 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004352 x = i + strlen(s3) + strlen(cmdstring) + 1;
Tim Peters92e4dd82002-10-05 01:47:34 +00004353 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004354 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00004355 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004356 }
4357 else {
4358 /*
Tim Peters402d5982001-08-27 06:37:48 +00004359 * Oh gag, we're on Win9x or using COMMAND.COM. Use
4360 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004361 */
Mark Hammond08501372001-01-31 07:30:29 +00004362 char modulepath[_MAX_PATH];
4363 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004364 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
4365 for (i = x = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004366 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004367 x = i+1;
4368 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00004369 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00004370 strncat(modulepath,
4371 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00004372 (sizeof(modulepath)/sizeof(modulepath[0]))
4373 -strlen(modulepath));
4374 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00004375 /* Eeek - file-not-found - possibly an embedding
4376 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00004377 */
Tim Peters5aa91602002-01-30 05:46:57 +00004378 strncpy(modulepath,
4379 Py_GetExecPrefix(),
Mark Hammond08501372001-01-31 07:30:29 +00004380 sizeof(modulepath)/sizeof(modulepath[0]));
4381 if (modulepath[strlen(modulepath)-1] != '\\')
4382 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00004383 strncat(modulepath,
4384 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00004385 (sizeof(modulepath)/sizeof(modulepath[0]))
4386 -strlen(modulepath));
4387 /* No where else to look - raise an easily identifiable
4388 error, rather than leaving Windows to report
4389 "file not found" - as the user is probably blissfully
4390 unaware this shim EXE is used, and it will confuse them.
4391 (well, it confused me for a while ;-)
4392 */
4393 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00004394 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00004395 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00004396 "for popen to work with your shell "
4397 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00004398 szConsoleSpawn);
4399 return FALSE;
4400 }
4401 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004402 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00004403 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004404 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00004405
Tim Peters92e4dd82002-10-05 01:47:34 +00004406 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004407 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004408 /* To maintain correct argument passing semantics,
4409 we pass the command-line as it stands, and allow
4410 quoting to be applied. w9xpopen.exe will then
4411 use its argv vector, and re-quote the necessary
4412 args for the ultimate child process.
4413 */
Tim Peters75cdad52001-11-28 22:07:30 +00004414 PyOS_snprintf(
4415 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004416 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004417 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004418 s1,
4419 s3,
4420 cmdstring);
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004421 /* Not passing CREATE_NEW_CONSOLE has been known to
Tim Peters11b23062003-04-23 02:39:17 +00004422 cause random failures on win9x. Specifically a
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004423 dialog:
4424 "Your program accessed mem currently in use at xxx"
4425 and a hopeful warning about the stability of your
4426 system.
4427 Cost is Ctrl+C wont kill children, but anyone
4428 who cares can have a go!
4429 */
4430 dwProcessFlags |= CREATE_NEW_CONSOLE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004431 }
4432 }
4433
4434 /* Could be an else here to try cmd.exe / command.com in the path
4435 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00004436 else {
Tim Peters402d5982001-08-27 06:37:48 +00004437 PyErr_SetString(PyExc_RuntimeError,
4438 "Cannot locate a COMSPEC environment variable to "
4439 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00004440 return FALSE;
4441 }
Tim Peters5aa91602002-01-30 05:46:57 +00004442
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004443 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
4444 siStartInfo.cb = sizeof(STARTUPINFO);
4445 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
4446 siStartInfo.hStdInput = hStdin;
4447 siStartInfo.hStdOutput = hStdout;
4448 siStartInfo.hStdError = hStderr;
4449 siStartInfo.wShowWindow = SW_HIDE;
4450
4451 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004452 s2,
4453 NULL,
4454 NULL,
4455 TRUE,
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004456 dwProcessFlags,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004457 NULL,
4458 NULL,
4459 &siStartInfo,
4460 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004461 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004462 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004463
Mark Hammondb37a3732000-08-14 04:47:33 +00004464 /* Return process handle */
4465 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004466 return TRUE;
4467 }
Tim Peters402d5982001-08-27 06:37:48 +00004468 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004469 return FALSE;
4470}
4471
4472/* The following code is based off of KB: Q190351 */
4473
4474static PyObject *
4475_PyPopen(char *cmdstring, int mode, int n)
4476{
4477 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
4478 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00004479 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00004480
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004481 SECURITY_ATTRIBUTES saAttr;
4482 BOOL fSuccess;
4483 int fd1, fd2, fd3;
4484 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00004485 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004486 PyObject *f;
4487
4488 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
4489 saAttr.bInheritHandle = TRUE;
4490 saAttr.lpSecurityDescriptor = NULL;
4491
4492 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
4493 return win32_error("CreatePipe", NULL);
4494
4495 /* Create new output read handle and the input write handle. Set
4496 * the inheritance properties to FALSE. Otherwise, the child inherits
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00004497 * these handles; resulting in non-closeable handles to the pipes
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004498 * being created. */
4499 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004500 GetCurrentProcess(), &hChildStdinWrDup, 0,
4501 FALSE,
4502 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004503 if (!fSuccess)
4504 return win32_error("DuplicateHandle", NULL);
4505
4506 /* Close the inheritable version of ChildStdin
4507 that we're using. */
4508 CloseHandle(hChildStdinWr);
4509
4510 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
4511 return win32_error("CreatePipe", NULL);
4512
4513 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004514 GetCurrentProcess(), &hChildStdoutRdDup, 0,
4515 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004516 if (!fSuccess)
4517 return win32_error("DuplicateHandle", NULL);
4518
4519 /* Close the inheritable version of ChildStdout
4520 that we're using. */
4521 CloseHandle(hChildStdoutRd);
4522
4523 if (n != POPEN_4) {
4524 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
4525 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004526 fSuccess = DuplicateHandle(GetCurrentProcess(),
4527 hChildStderrRd,
4528 GetCurrentProcess(),
4529 &hChildStderrRdDup, 0,
4530 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004531 if (!fSuccess)
4532 return win32_error("DuplicateHandle", NULL);
4533 /* Close the inheritable version of ChildStdErr that we're using. */
4534 CloseHandle(hChildStderrRd);
4535 }
Tim Peters5aa91602002-01-30 05:46:57 +00004536
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004537 switch (n) {
4538 case POPEN_1:
4539 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
4540 case _O_WRONLY | _O_TEXT:
4541 /* Case for writing to child Stdin in text mode. */
Martin v. Löwis18e16552006-02-15 17:27:45 +00004542 fd1 = _open_osfhandle((intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004543 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004544 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004545 PyFile_SetBufSize(f, 0);
4546 /* We don't care about these pipes anymore, so close them. */
4547 CloseHandle(hChildStdoutRdDup);
4548 CloseHandle(hChildStderrRdDup);
4549 break;
4550
4551 case _O_RDONLY | _O_TEXT:
4552 /* Case for reading from child Stdout in text mode. */
Martin v. Löwis18e16552006-02-15 17:27:45 +00004553 fd1 = _open_osfhandle((intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004554 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004555 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004556 PyFile_SetBufSize(f, 0);
4557 /* We don't care about these pipes anymore, so close them. */
4558 CloseHandle(hChildStdinWrDup);
4559 CloseHandle(hChildStderrRdDup);
4560 break;
4561
4562 case _O_RDONLY | _O_BINARY:
4563 /* Case for readinig from child Stdout in binary mode. */
Martin v. Löwis18e16552006-02-15 17:27:45 +00004564 fd1 = _open_osfhandle((intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004565 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004566 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004567 PyFile_SetBufSize(f, 0);
4568 /* We don't care about these pipes anymore, so close them. */
4569 CloseHandle(hChildStdinWrDup);
4570 CloseHandle(hChildStderrRdDup);
4571 break;
4572
4573 case _O_WRONLY | _O_BINARY:
4574 /* Case for writing to child Stdin in binary mode. */
Martin v. Löwis18e16552006-02-15 17:27:45 +00004575 fd1 = _open_osfhandle((intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004576 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004577 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004578 PyFile_SetBufSize(f, 0);
4579 /* We don't care about these pipes anymore, so close them. */
4580 CloseHandle(hChildStdoutRdDup);
4581 CloseHandle(hChildStderrRdDup);
4582 break;
4583 }
Mark Hammondb37a3732000-08-14 04:47:33 +00004584 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004585 break;
Tim Peters5aa91602002-01-30 05:46:57 +00004586
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004587 case POPEN_2:
4588 case POPEN_4:
4589 {
4590 char *m1, *m2;
4591 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00004592
Tim Peters7dca21e2002-08-19 00:42:29 +00004593 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004594 m1 = "r";
4595 m2 = "w";
4596 } else {
4597 m1 = "rb";
4598 m2 = "wb";
4599 }
4600
Martin v. Löwis18e16552006-02-15 17:27:45 +00004601 fd1 = _open_osfhandle((intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004602 f1 = _fdopen(fd1, m2);
Martin v. Löwis18e16552006-02-15 17:27:45 +00004603 fd2 = _open_osfhandle((intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004604 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004605 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004606 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00004607 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004608 PyFile_SetBufSize(p2, 0);
4609
4610 if (n != 4)
4611 CloseHandle(hChildStderrRdDup);
4612
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004613 f = PyTuple_Pack(2,p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00004614 Py_XDECREF(p1);
4615 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00004616 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004617 break;
4618 }
Tim Peters5aa91602002-01-30 05:46:57 +00004619
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004620 case POPEN_3:
4621 {
4622 char *m1, *m2;
4623 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00004624
Tim Peters7dca21e2002-08-19 00:42:29 +00004625 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004626 m1 = "r";
4627 m2 = "w";
4628 } else {
4629 m1 = "rb";
4630 m2 = "wb";
4631 }
4632
Martin v. Löwis18e16552006-02-15 17:27:45 +00004633 fd1 = _open_osfhandle((intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004634 f1 = _fdopen(fd1, m2);
Martin v. Löwis18e16552006-02-15 17:27:45 +00004635 fd2 = _open_osfhandle((intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004636 f2 = _fdopen(fd2, m1);
Martin v. Löwis18e16552006-02-15 17:27:45 +00004637 fd3 = _open_osfhandle((intptr_t)hChildStderrRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004638 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004639 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00004640 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
4641 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004642 PyFile_SetBufSize(p1, 0);
4643 PyFile_SetBufSize(p2, 0);
4644 PyFile_SetBufSize(p3, 0);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004645 f = PyTuple_Pack(3,p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00004646 Py_XDECREF(p1);
4647 Py_XDECREF(p2);
4648 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00004649 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004650 break;
4651 }
4652 }
4653
4654 if (n == POPEN_4) {
4655 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004656 hChildStdinRd,
4657 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004658 hChildStdoutWr,
4659 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004660 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004661 }
4662 else {
4663 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004664 hChildStdinRd,
4665 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004666 hChildStderrWr,
4667 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004668 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004669 }
4670
Mark Hammondb37a3732000-08-14 04:47:33 +00004671 /*
4672 * Insert the files we've created into the process dictionary
4673 * all referencing the list with the process handle and the
4674 * initial number of files (see description below in _PyPclose).
4675 * Since if _PyPclose later tried to wait on a process when all
4676 * handles weren't closed, it could create a deadlock with the
4677 * child, we spend some energy here to try to ensure that we
4678 * either insert all file handles into the dictionary or none
4679 * at all. It's a little clumsy with the various popen modes
4680 * and variable number of files involved.
4681 */
4682 if (!_PyPopenProcs) {
4683 _PyPopenProcs = PyDict_New();
4684 }
4685
4686 if (_PyPopenProcs) {
4687 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
4688 int ins_rc[3];
4689
4690 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4691 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4692
4693 procObj = PyList_New(2);
4694 hProcessObj = PyLong_FromVoidPtr(hProcess);
4695 intObj = PyInt_FromLong(file_count);
4696
4697 if (procObj && hProcessObj && intObj) {
4698 PyList_SetItem(procObj,0,hProcessObj);
4699 PyList_SetItem(procObj,1,intObj);
4700
4701 fileObj[0] = PyLong_FromVoidPtr(f1);
4702 if (fileObj[0]) {
4703 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4704 fileObj[0],
4705 procObj);
4706 }
4707 if (file_count >= 2) {
4708 fileObj[1] = PyLong_FromVoidPtr(f2);
4709 if (fileObj[1]) {
4710 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4711 fileObj[1],
4712 procObj);
4713 }
4714 }
4715 if (file_count >= 3) {
4716 fileObj[2] = PyLong_FromVoidPtr(f3);
4717 if (fileObj[2]) {
4718 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4719 fileObj[2],
4720 procObj);
4721 }
4722 }
4723
4724 if (ins_rc[0] < 0 || !fileObj[0] ||
4725 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4726 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
4727 /* Something failed - remove any dictionary
4728 * entries that did make it.
4729 */
4730 if (!ins_rc[0] && fileObj[0]) {
4731 PyDict_DelItem(_PyPopenProcs,
4732 fileObj[0]);
4733 }
4734 if (!ins_rc[1] && fileObj[1]) {
4735 PyDict_DelItem(_PyPopenProcs,
4736 fileObj[1]);
4737 }
4738 if (!ins_rc[2] && fileObj[2]) {
4739 PyDict_DelItem(_PyPopenProcs,
4740 fileObj[2]);
4741 }
4742 }
4743 }
Tim Peters5aa91602002-01-30 05:46:57 +00004744
Mark Hammondb37a3732000-08-14 04:47:33 +00004745 /*
4746 * Clean up our localized references for the dictionary keys
4747 * and value since PyDict_SetItem will Py_INCREF any copies
4748 * that got placed in the dictionary.
4749 */
4750 Py_XDECREF(procObj);
4751 Py_XDECREF(fileObj[0]);
4752 Py_XDECREF(fileObj[1]);
4753 Py_XDECREF(fileObj[2]);
4754 }
4755
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004756 /* Child is launched. Close the parents copy of those pipe
4757 * handles that only the child should have open. You need to
4758 * make sure that no handles to the write end of the output pipe
4759 * are maintained in this process or else the pipe will not close
4760 * when the child process exits and the ReadFile will hang. */
4761
4762 if (!CloseHandle(hChildStdinRd))
4763 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004764
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004765 if (!CloseHandle(hChildStdoutWr))
4766 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00004767
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004768 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
4769 return win32_error("CloseHandle", NULL);
4770
4771 return f;
4772}
Fredrik Lundh56055a42000-07-23 19:47:12 +00004773
4774/*
4775 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4776 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00004777 *
4778 * This function uses the _PyPopenProcs dictionary in order to map the
4779 * input file pointer to information about the process that was
4780 * originally created by the popen* call that created the file pointer.
4781 * The dictionary uses the file pointer as a key (with one entry
4782 * inserted for each file returned by the original popen* call) and a
4783 * single list object as the value for all files from a single call.
4784 * The list object contains the Win32 process handle at [0], and a file
4785 * count at [1], which is initialized to the total number of file
4786 * handles using that list.
4787 *
4788 * This function closes whichever handle it is passed, and decrements
4789 * the file count in the dictionary for the process handle pointed to
4790 * by this file. On the last close (when the file count reaches zero),
4791 * this function will wait for the child process and then return its
4792 * exit code as the result of the close() operation. This permits the
4793 * files to be closed in any order - it is always the close() of the
4794 * final handle that will return the exit code.
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004795 *
4796 * NOTE: This function is currently called with the GIL released.
4797 * hence we use the GILState API to manage our state.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004798 */
Tim Peters736aa322000-09-01 06:51:24 +00004799
Fredrik Lundh56055a42000-07-23 19:47:12 +00004800static int _PyPclose(FILE *file)
4801{
Fredrik Lundh20318932000-07-26 17:29:12 +00004802 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004803 DWORD exit_code;
4804 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00004805 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
4806 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00004807#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004808 PyGILState_STATE state;
Tim Peters736aa322000-09-01 06:51:24 +00004809#endif
4810
Fredrik Lundh20318932000-07-26 17:29:12 +00004811 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00004812 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00004813 */
4814 result = fclose(file);
Tim Peters736aa322000-09-01 06:51:24 +00004815#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004816 state = PyGILState_Ensure();
Tim Peters736aa322000-09-01 06:51:24 +00004817#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00004818 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00004819 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4820 (procObj = PyDict_GetItem(_PyPopenProcs,
4821 fileObj)) != NULL &&
4822 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
4823 (intObj = PyList_GetItem(procObj,1)) != NULL) {
4824
4825 hProcess = PyLong_AsVoidPtr(hProcessObj);
4826 file_count = PyInt_AsLong(intObj);
4827
4828 if (file_count > 1) {
4829 /* Still other files referencing process */
4830 file_count--;
4831 PyList_SetItem(procObj,1,
4832 PyInt_FromLong(file_count));
4833 } else {
4834 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00004835 if (result != EOF &&
4836 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
4837 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00004838 /* Possible truncation here in 16-bit environments, but
4839 * real exit codes are just the lower byte in any event.
4840 */
4841 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004842 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00004843 /* Indicate failure - this will cause the file object
4844 * to raise an I/O error and translate the last Win32
4845 * error code from errno. We do have a problem with
4846 * last errors that overlap the normal errno table,
4847 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004848 */
Fredrik Lundh20318932000-07-26 17:29:12 +00004849 if (result != EOF) {
4850 /* If the error wasn't from the fclose(), then
4851 * set errno for the file object error handling.
4852 */
4853 errno = GetLastError();
4854 }
4855 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00004856 }
4857
4858 /* Free up the native handle at this point */
4859 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00004860 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00004861
Mark Hammondb37a3732000-08-14 04:47:33 +00004862 /* Remove this file pointer from dictionary */
4863 PyDict_DelItem(_PyPopenProcs, fileObj);
4864
4865 if (PyDict_Size(_PyPopenProcs) == 0) {
4866 Py_DECREF(_PyPopenProcs);
4867 _PyPopenProcs = NULL;
4868 }
4869
4870 } /* if object retrieval ok */
4871
4872 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004873 } /* if _PyPopenProcs */
4874
Tim Peters736aa322000-09-01 06:51:24 +00004875#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00004876 PyGILState_Release(state);
Tim Peters736aa322000-09-01 06:51:24 +00004877#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00004878 return result;
4879}
Tim Peters9acdd3a2000-09-01 19:26:36 +00004880
4881#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00004882static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004883posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00004884{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004885 char *name;
4886 char *mode = "r";
4887 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00004888 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00004889 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004890 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00004891 return NULL;
Martin v. Löwis9ad853b2003-10-31 10:01:53 +00004892 /* Strip mode of binary or text modifiers */
4893 if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
4894 mode = "r";
4895 else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
4896 mode = "w";
Barry Warsaw53699e91996-12-10 23:23:01 +00004897 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00004898 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00004899 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00004900 if (fp == NULL)
4901 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004902 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004903 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00004904 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00004905 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00004906}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00004907
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004908#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004909#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00004910
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004911
Guido van Rossumb6775db1994-08-01 11:34:53 +00004912#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004913PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004914"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004915Set the current process's user id.");
4916
Barry Warsaw53699e91996-12-10 23:23:01 +00004917static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00004918posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004919{
4920 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00004921 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004922 return NULL;
4923 if (setuid(uid) < 0)
4924 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00004925 Py_INCREF(Py_None);
4926 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004927}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00004928#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00004929
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004930
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004931#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004932PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004933"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004934Set the current process's effective user id.");
4935
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004936static PyObject *
4937posix_seteuid (PyObject *self, PyObject *args)
4938{
4939 int euid;
4940 if (!PyArg_ParseTuple(args, "i", &euid)) {
4941 return NULL;
4942 } else if (seteuid(euid) < 0) {
4943 return posix_error();
4944 } else {
4945 Py_INCREF(Py_None);
4946 return Py_None;
4947 }
4948}
4949#endif /* HAVE_SETEUID */
4950
4951#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004952PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00004953"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004954Set the current process's effective group id.");
4955
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004956static PyObject *
4957posix_setegid (PyObject *self, PyObject *args)
4958{
4959 int egid;
4960 if (!PyArg_ParseTuple(args, "i", &egid)) {
4961 return NULL;
4962 } else if (setegid(egid) < 0) {
4963 return posix_error();
4964 } else {
4965 Py_INCREF(Py_None);
4966 return Py_None;
4967 }
4968}
4969#endif /* HAVE_SETEGID */
4970
4971#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004972PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004973"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004974Set the current process's real and effective user ids.");
4975
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004976static PyObject *
4977posix_setreuid (PyObject *self, PyObject *args)
4978{
4979 int ruid, euid;
4980 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
4981 return NULL;
4982 } else if (setreuid(ruid, euid) < 0) {
4983 return posix_error();
4984 } else {
4985 Py_INCREF(Py_None);
4986 return Py_None;
4987 }
4988}
4989#endif /* HAVE_SETREUID */
4990
4991#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004992PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00004993"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00004994Set the current process's real and effective group ids.");
4995
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00004996static PyObject *
4997posix_setregid (PyObject *self, PyObject *args)
4998{
4999 int rgid, egid;
5000 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
5001 return NULL;
5002 } else if (setregid(rgid, egid) < 0) {
5003 return posix_error();
5004 } else {
5005 Py_INCREF(Py_None);
5006 return Py_None;
5007 }
5008}
5009#endif /* HAVE_SETREGID */
5010
Guido van Rossumb6775db1994-08-01 11:34:53 +00005011#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005012PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005013"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005014Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005015
Barry Warsaw53699e91996-12-10 23:23:01 +00005016static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005017posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005018{
5019 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005020 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005021 return NULL;
5022 if (setgid(gid) < 0)
5023 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005024 Py_INCREF(Py_None);
5025 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005026}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005027#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005028
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005029#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005030PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005031"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005032Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005033
5034static PyObject *
5035posix_setgroups(PyObject *self, PyObject *args)
5036{
5037 PyObject *groups;
5038 int i, len;
5039 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00005040
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005041 if (!PyArg_ParseTuple(args, "O:setgid", &groups))
5042 return NULL;
5043 if (!PySequence_Check(groups)) {
5044 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
5045 return NULL;
5046 }
5047 len = PySequence_Size(groups);
5048 if (len > MAX_GROUPS) {
5049 PyErr_SetString(PyExc_ValueError, "too many groups");
5050 return NULL;
5051 }
5052 for(i = 0; i < len; i++) {
5053 PyObject *elem;
5054 elem = PySequence_GetItem(groups, i);
5055 if (!elem)
5056 return NULL;
5057 if (!PyInt_Check(elem)) {
Georg Brandla13c2442005-11-22 19:30:31 +00005058 if (!PyLong_Check(elem)) {
5059 PyErr_SetString(PyExc_TypeError,
5060 "groups must be integers");
5061 Py_DECREF(elem);
5062 return NULL;
5063 } else {
5064 unsigned long x = PyLong_AsUnsignedLong(elem);
5065 if (PyErr_Occurred()) {
5066 PyErr_SetString(PyExc_TypeError,
5067 "group id too big");
5068 Py_DECREF(elem);
5069 return NULL;
5070 }
5071 grouplist[i] = x;
5072 /* read back the value to see if it fitted in gid_t */
5073 if (grouplist[i] != x) {
5074 PyErr_SetString(PyExc_TypeError,
5075 "group id too big");
5076 Py_DECREF(elem);
5077 return NULL;
5078 }
5079 }
5080 } else {
5081 long x = PyInt_AsLong(elem);
5082 grouplist[i] = x;
5083 if (grouplist[i] != x) {
5084 PyErr_SetString(PyExc_TypeError,
5085 "group id too big");
5086 Py_DECREF(elem);
5087 return NULL;
5088 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005089 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005090 Py_DECREF(elem);
5091 }
5092
5093 if (setgroups(len, grouplist) < 0)
5094 return posix_error();
5095 Py_INCREF(Py_None);
5096 return Py_None;
5097}
5098#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005099
Neal Norwitz6c2f9132006-03-20 07:25:26 +00005100#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Neal Norwitz05a45592006-03-20 06:30:08 +00005101static PyObject *
5102wait_helper(int pid, int status, struct rusage *ru)
5103{
5104 PyObject *result;
5105 static PyObject *struct_rusage;
5106
5107 if (pid == -1)
5108 return posix_error();
5109
5110 if (struct_rusage == NULL) {
5111 PyObject *m = PyImport_ImportModule("resource");
5112 if (m == NULL)
5113 return NULL;
5114 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
5115 Py_DECREF(m);
5116 if (struct_rusage == NULL)
5117 return NULL;
5118 }
5119
5120 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
5121 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
5122 if (!result)
5123 return NULL;
5124
5125#ifndef doubletime
5126#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
5127#endif
5128
5129 PyStructSequence_SET_ITEM(result, 0,
5130 PyFloat_FromDouble(doubletime(ru->ru_utime)));
5131 PyStructSequence_SET_ITEM(result, 1,
5132 PyFloat_FromDouble(doubletime(ru->ru_stime)));
5133#define SET_INT(result, index, value)\
5134 PyStructSequence_SET_ITEM(result, index, PyInt_FromLong(value))
5135 SET_INT(result, 2, ru->ru_maxrss);
5136 SET_INT(result, 3, ru->ru_ixrss);
5137 SET_INT(result, 4, ru->ru_idrss);
5138 SET_INT(result, 5, ru->ru_isrss);
5139 SET_INT(result, 6, ru->ru_minflt);
5140 SET_INT(result, 7, ru->ru_majflt);
5141 SET_INT(result, 8, ru->ru_nswap);
5142 SET_INT(result, 9, ru->ru_inblock);
5143 SET_INT(result, 10, ru->ru_oublock);
5144 SET_INT(result, 11, ru->ru_msgsnd);
5145 SET_INT(result, 12, ru->ru_msgrcv);
5146 SET_INT(result, 13, ru->ru_nsignals);
5147 SET_INT(result, 14, ru->ru_nvcsw);
5148 SET_INT(result, 15, ru->ru_nivcsw);
5149#undef SET_INT
5150
5151 if (PyErr_Occurred()) {
5152 Py_DECREF(result);
5153 return NULL;
5154 }
5155
Neal Norwitz9b00a562006-03-20 08:47:12 +00005156 return Py_BuildValue("iiN", pid, status, result);
Neal Norwitz05a45592006-03-20 06:30:08 +00005157}
Neal Norwitz6c2f9132006-03-20 07:25:26 +00005158#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
Neal Norwitz05a45592006-03-20 06:30:08 +00005159
5160#ifdef HAVE_WAIT3
5161PyDoc_STRVAR(posix_wait3__doc__,
5162"wait3(options) -> (pid, status, rusage)\n\n\
5163Wait for completion of a child process.");
5164
5165static PyObject *
5166posix_wait3(PyObject *self, PyObject *args)
5167{
5168 int pid, options;
5169 struct rusage ru;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005170 WAIT_TYPE status;
5171 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00005172
5173 if (!PyArg_ParseTuple(args, "i:wait3", &options))
5174 return NULL;
5175
5176 Py_BEGIN_ALLOW_THREADS
5177 pid = wait3(&status, options, &ru);
5178 Py_END_ALLOW_THREADS
5179
Neal Norwitzd5a37542006-03-20 06:48:34 +00005180 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00005181}
5182#endif /* HAVE_WAIT3 */
5183
5184#ifdef HAVE_WAIT4
5185PyDoc_STRVAR(posix_wait4__doc__,
5186"wait4(pid, options) -> (pid, status, rusage)\n\n\
5187Wait for completion of a given child process.");
5188
5189static PyObject *
5190posix_wait4(PyObject *self, PyObject *args)
5191{
5192 int pid, options;
5193 struct rusage ru;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005194 WAIT_TYPE status;
5195 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00005196
5197 if (!PyArg_ParseTuple(args, "ii:wait4", &pid, &options))
5198 return NULL;
5199
5200 Py_BEGIN_ALLOW_THREADS
5201 pid = wait4(pid, &status, options, &ru);
5202 Py_END_ALLOW_THREADS
5203
Neal Norwitzd5a37542006-03-20 06:48:34 +00005204 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00005205}
5206#endif /* HAVE_WAIT4 */
5207
Guido van Rossumb6775db1994-08-01 11:34:53 +00005208#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005209PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005210"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005211Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005212
Barry Warsaw53699e91996-12-10 23:23:01 +00005213static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005214posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005215{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005216 int pid, options;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005217 WAIT_TYPE status;
5218 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005219
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005220 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00005221 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005222 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00005223 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00005224 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00005225 if (pid == -1)
5226 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00005227
5228 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00005229}
5230
Tim Petersab034fa2002-02-01 11:27:43 +00005231#elif defined(HAVE_CWAIT)
5232
5233/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005234PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005235"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005236"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00005237
5238static PyObject *
5239posix_waitpid(PyObject *self, PyObject *args)
5240{
Martin v. Löwis18e16552006-02-15 17:27:45 +00005241 intptr_t pid;
5242 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00005243
5244 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
5245 return NULL;
5246 Py_BEGIN_ALLOW_THREADS
5247 pid = _cwait(&status, pid, options);
5248 Py_END_ALLOW_THREADS
5249 if (pid == -1)
5250 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00005251
5252 /* shift the status left a byte so this is more like the POSIX waitpid */
5253 return Py_BuildValue("ii", pid, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00005254}
5255#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005256
Guido van Rossumad0ee831995-03-01 10:34:45 +00005257#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005258PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005259"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005260Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005261
Barry Warsaw53699e91996-12-10 23:23:01 +00005262static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005263posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00005264{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005265 int pid;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005266 WAIT_TYPE status;
5267 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00005268
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005269 Py_BEGIN_ALLOW_THREADS
5270 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00005271 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00005272 if (pid == -1)
5273 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00005274
5275 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00005276}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005277#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005278
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005279
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005280PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005281"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005282Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005283
Barry Warsaw53699e91996-12-10 23:23:01 +00005284static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005285posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005286{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005287#ifdef HAVE_LSTAT
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005288 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005289#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005290#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00005291 return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005292#else
5293 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
5294#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005295#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005296}
5297
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005298
Guido van Rossumb6775db1994-08-01 11:34:53 +00005299#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005300PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005301"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005302Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005303
Barry Warsaw53699e91996-12-10 23:23:01 +00005304static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005305posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005306{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005307 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00005308 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005309 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005310 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005311 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005312 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00005313 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00005314 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005315 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00005316 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00005317 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005318}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005319#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005320
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005321
Guido van Rossumb6775db1994-08-01 11:34:53 +00005322#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005323PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005324"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00005325Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005326
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005327static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005328posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005329{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005330 return posix_2str(args, "etet:symlink", symlink, NULL, NULL);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005331}
5332#endif /* HAVE_SYMLINK */
5333
5334
5335#ifdef HAVE_TIMES
5336#ifndef HZ
5337#define HZ 60 /* Universal constant :-) */
5338#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00005339
Guido van Rossumd48f2521997-12-05 22:19:34 +00005340#if defined(PYCC_VACPP) && defined(PYOS_OS2)
5341static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005342system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005343{
5344 ULONG value = 0;
5345
5346 Py_BEGIN_ALLOW_THREADS
5347 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
5348 Py_END_ALLOW_THREADS
5349
5350 return value;
5351}
5352
5353static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005354posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005355{
Guido van Rossumd48f2521997-12-05 22:19:34 +00005356 /* Currently Only Uptime is Provided -- Others Later */
5357 return Py_BuildValue("ddddd",
5358 (double)0 /* t.tms_utime / HZ */,
5359 (double)0 /* t.tms_stime / HZ */,
5360 (double)0 /* t.tms_cutime / HZ */,
5361 (double)0 /* t.tms_cstime / HZ */,
5362 (double)system_uptime() / 1000);
5363}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005364#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00005365static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005366posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00005367{
5368 struct tms t;
5369 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +00005370 errno = 0;
5371 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00005372 if (c == (clock_t) -1)
5373 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005374 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00005375 (double)t.tms_utime / HZ,
5376 (double)t.tms_stime / HZ,
5377 (double)t.tms_cutime / HZ,
5378 (double)t.tms_cstime / HZ,
5379 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00005380}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005381#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005382#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005383
5384
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005385#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005386#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00005387static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005388posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005389{
5390 FILETIME create, exit, kernel, user;
5391 HANDLE hProc;
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005392 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00005393 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
5394 /* The fields of a FILETIME structure are the hi and lo part
5395 of a 64-bit value expressed in 100 nanosecond units.
5396 1e7 is one second in such units; 1e-7 the inverse.
5397 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
5398 */
Barry Warsaw53699e91996-12-10 23:23:01 +00005399 return Py_BuildValue(
5400 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00005401 (double)(kernel.dwHighDateTime*429.4967296 +
5402 kernel.dwLowDateTime*1e-7),
5403 (double)(user.dwHighDateTime*429.4967296 +
5404 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00005405 (double)0,
5406 (double)0,
5407 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005408}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005409#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005410
5411#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005412PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005413"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005414Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005415#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005416
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005417
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00005418#ifdef HAVE_GETSID
5419PyDoc_STRVAR(posix_getsid__doc__,
5420"getsid(pid) -> sid\n\n\
5421Call the system call getsid().");
5422
5423static PyObject *
5424posix_getsid(PyObject *self, PyObject *args)
5425{
5426 int pid, sid;
5427 if (!PyArg_ParseTuple(args, "i:getsid", &pid))
5428 return NULL;
5429 sid = getsid(pid);
5430 if (sid < 0)
5431 return posix_error();
5432 return PyInt_FromLong((long)sid);
5433}
5434#endif /* HAVE_GETSID */
5435
5436
Guido van Rossumb6775db1994-08-01 11:34:53 +00005437#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005438PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005439"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005440Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005441
Barry Warsaw53699e91996-12-10 23:23:01 +00005442static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005443posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005444{
Guido van Rossum687dd131993-05-17 08:34:16 +00005445 if (setsid() < 0)
5446 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005447 Py_INCREF(Py_None);
5448 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005449}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005450#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005451
Guido van Rossumb6775db1994-08-01 11:34:53 +00005452#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005453PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005454"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005455Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005456
Barry Warsaw53699e91996-12-10 23:23:01 +00005457static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005458posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005459{
5460 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005461 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00005462 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005463 if (setpgid(pid, pgrp) < 0)
5464 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005465 Py_INCREF(Py_None);
5466 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005467}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005468#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005469
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005470
Guido van Rossumb6775db1994-08-01 11:34:53 +00005471#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005472PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005473"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005474Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005475
Barry Warsaw53699e91996-12-10 23:23:01 +00005476static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005477posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005478{
5479 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005480 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00005481 return NULL;
5482 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005483 if (pgid < 0)
5484 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005485 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00005486}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005487#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00005488
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005489
Guido van Rossumb6775db1994-08-01 11:34:53 +00005490#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005491PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005492"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005493Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005494
Barry Warsaw53699e91996-12-10 23:23:01 +00005495static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005496posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005497{
5498 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005499 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00005500 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005501 if (tcsetpgrp(fd, pgid) < 0)
5502 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00005503 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00005504 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00005505}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005506#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00005507
Guido van Rossum687dd131993-05-17 08:34:16 +00005508/* Functions acting on file descriptors */
5509
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005510PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005511"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005512Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005513
Barry Warsaw53699e91996-12-10 23:23:01 +00005514static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005515posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005516{
Mark Hammondef8b6542001-05-13 08:04:26 +00005517 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005518 int flag;
5519 int mode = 0777;
5520 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005521
5522#ifdef MS_WINDOWS
5523 if (unicode_file_names()) {
5524 PyUnicodeObject *po;
5525 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
5526 Py_BEGIN_ALLOW_THREADS
5527 /* PyUnicode_AS_UNICODE OK without thread
5528 lock as it is a simple dereference. */
5529 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
5530 Py_END_ALLOW_THREADS
5531 if (fd < 0)
5532 return posix_error();
5533 return PyInt_FromLong((long)fd);
5534 }
5535 /* Drop the argument parsing error as narrow strings
5536 are also valid. */
5537 PyErr_Clear();
5538 }
5539#endif
5540
Tim Peters5aa91602002-01-30 05:46:57 +00005541 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00005542 Py_FileSystemDefaultEncoding, &file,
5543 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00005544 return NULL;
5545
Barry Warsaw53699e91996-12-10 23:23:01 +00005546 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005547 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005548 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005549 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00005550 return posix_error_with_allocated_filename(file);
5551 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00005552 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005553}
5554
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005555
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005556PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005557"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005558Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005559
Barry Warsaw53699e91996-12-10 23:23:01 +00005560static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005561posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005562{
5563 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005564 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005565 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005566 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005567 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00005568 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005569 if (res < 0)
5570 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005571 Py_INCREF(Py_None);
5572 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005573}
5574
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005575
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005576PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005577"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005578Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005579
Barry Warsaw53699e91996-12-10 23:23:01 +00005580static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005581posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005582{
5583 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005584 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005585 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005586 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005587 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00005588 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005589 if (fd < 0)
5590 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005591 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005592}
5593
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005594
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005595PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00005596"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005597Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005598
Barry Warsaw53699e91996-12-10 23:23:01 +00005599static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005600posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005601{
5602 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005603 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00005604 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005605 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005606 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00005607 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005608 if (res < 0)
5609 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005610 Py_INCREF(Py_None);
5611 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005612}
5613
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005614
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005615PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005616"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005617Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005618
Barry Warsaw53699e91996-12-10 23:23:01 +00005619static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005620posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005621{
5622 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005623#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005624 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005625#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00005626 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005627#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005628 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005629 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00005630 return NULL;
5631#ifdef SEEK_SET
5632 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
5633 switch (how) {
5634 case 0: how = SEEK_SET; break;
5635 case 1: how = SEEK_CUR; break;
5636 case 2: how = SEEK_END; break;
5637 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005638#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005639
5640#if !defined(HAVE_LARGEFILE_SUPPORT)
5641 pos = PyInt_AsLong(posobj);
5642#else
5643 pos = PyLong_Check(posobj) ?
5644 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
5645#endif
5646 if (PyErr_Occurred())
5647 return NULL;
5648
Barry Warsaw53699e91996-12-10 23:23:01 +00005649 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005650#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00005651 res = _lseeki64(fd, pos, how);
5652#else
Guido van Rossum687dd131993-05-17 08:34:16 +00005653 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005654#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005655 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005656 if (res < 0)
5657 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00005658
5659#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00005660 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005661#else
5662 return PyLong_FromLongLong(res);
5663#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005664}
5665
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005666
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005667PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005668"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005669Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005670
Barry Warsaw53699e91996-12-10 23:23:01 +00005671static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005672posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005673{
Guido van Rossum8bac5461996-06-11 18:38:48 +00005674 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00005675 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005676 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005677 return NULL;
Michael W. Hudson9867ced2005-01-31 17:01:59 +00005678 if (size < 0) {
5679 errno = EINVAL;
5680 return posix_error();
5681 }
Barry Warsaw53699e91996-12-10 23:23:01 +00005682 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005683 if (buffer == NULL)
5684 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005685 Py_BEGIN_ALLOW_THREADS
5686 n = read(fd, PyString_AsString(buffer), size);
5687 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00005688 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005689 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00005690 return posix_error();
5691 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00005692 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00005693 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00005694 return buffer;
5695}
5696
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005697
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005698PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005699"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005700Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005701
Barry Warsaw53699e91996-12-10 23:23:01 +00005702static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005703posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005704{
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005705 int fd;
5706 Py_ssize_t size;
Guido van Rossum687dd131993-05-17 08:34:16 +00005707 char *buffer;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005708
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005709 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005710 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005711 Py_BEGIN_ALLOW_THREADS
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005712 size = write(fd, buffer, (size_t)size);
Barry Warsaw53699e91996-12-10 23:23:01 +00005713 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005714 if (size < 0)
5715 return posix_error();
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005716 return PyInt_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005717}
5718
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005719
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005720PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005721"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005722Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005723
Barry Warsaw53699e91996-12-10 23:23:01 +00005724static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005725posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005726{
5727 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00005728 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00005729 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005730 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005731 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00005732#ifdef __VMS
5733 /* on OpenVMS we must ensure that all bytes are written to the file */
5734 fsync(fd);
5735#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005736 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00005737 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00005738 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00005739 if (res != 0) {
5740#ifdef MS_WINDOWS
5741 return win32_error("fstat", NULL);
5742#else
Guido van Rossum687dd131993-05-17 08:34:16 +00005743 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00005744#endif
5745 }
Tim Peters5aa91602002-01-30 05:46:57 +00005746
Martin v. Löwis14694662006-02-03 12:54:16 +00005747 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00005748}
5749
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005750
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005751PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005752"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005753Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005754
Barry Warsaw53699e91996-12-10 23:23:01 +00005755static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005756posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005757{
Guido van Rossum687dd131993-05-17 08:34:16 +00005758 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005759 char *mode = "r";
5760 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00005761 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00005762 PyObject *f;
5763 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00005764 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00005765
Thomas Heller1f043e22002-11-07 16:00:59 +00005766 if (mode[0] != 'r' && mode[0] != 'w' && mode[0] != 'a') {
5767 PyErr_Format(PyExc_ValueError,
5768 "invalid file mode '%s'", mode);
5769 return NULL;
5770 }
5771
Barry Warsaw53699e91996-12-10 23:23:01 +00005772 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005773 fp = fdopen(fd, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005774 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005775 if (fp == NULL)
5776 return posix_error();
Guido van Rossumbd6be7a2002-09-15 18:45:46 +00005777 f = PyFile_FromFile(fp, "<fdopen>", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005778 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00005779 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005780 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00005781}
5782
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005783PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005784"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005785Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005786connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00005787
5788static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00005789posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00005790{
5791 int fd;
5792 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
5793 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005794 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00005795}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005796
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005797#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005798PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005799"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005800Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005801
Barry Warsaw53699e91996-12-10 23:23:01 +00005802static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005803posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00005804{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005805#if defined(PYOS_OS2)
5806 HFILE read, write;
5807 APIRET rc;
5808
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005809 Py_BEGIN_ALLOW_THREADS
5810 rc = DosCreatePipe( &read, &write, 4096);
5811 Py_END_ALLOW_THREADS
5812 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005813 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005814
5815 return Py_BuildValue("(ii)", read, write);
5816#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005817#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00005818 int fds[2];
5819 int res;
Barry Warsaw53699e91996-12-10 23:23:01 +00005820 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005821 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00005822 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005823 if (res != 0)
5824 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005825 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005826#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00005827 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005828 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00005829 BOOL ok;
Barry Warsaw53699e91996-12-10 23:23:01 +00005830 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005831 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00005832 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00005833 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005834 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00005835 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
5836 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005837 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005838#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005839#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005840}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005841#endif /* HAVE_PIPE */
5842
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005843
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005844#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005845PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005846"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005847Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005848
Barry Warsaw53699e91996-12-10 23:23:01 +00005849static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005850posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005851{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005852 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005853 int mode = 0666;
5854 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005855 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005856 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005857 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005858 res = mkfifo(filename, mode);
5859 Py_END_ALLOW_THREADS
5860 if (res < 0)
5861 return posix_error();
5862 Py_INCREF(Py_None);
5863 return Py_None;
5864}
5865#endif
5866
5867
Neal Norwitz11690112002-07-30 01:08:28 +00005868#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005869PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005870"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005871Create a filesystem node (file, device special file or named pipe)\n\
5872named filename. mode specifies both the permissions to use and the\n\
5873type of node to be created, being combined (bitwise OR) with one of\n\
5874S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005875device defines the newly created device special file (probably using\n\
5876os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005877
5878
5879static PyObject *
5880posix_mknod(PyObject *self, PyObject *args)
5881{
5882 char *filename;
5883 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005884 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005885 int res;
Martin v. Löwisd631ebe2002-11-02 17:42:33 +00005886 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005887 return NULL;
5888 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005889 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00005890 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005891 if (res < 0)
5892 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005893 Py_INCREF(Py_None);
5894 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005895}
5896#endif
5897
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005898#ifdef HAVE_DEVICE_MACROS
5899PyDoc_STRVAR(posix_major__doc__,
5900"major(device) -> major number\n\
5901Extracts a device major number from a raw device number.");
5902
5903static PyObject *
5904posix_major(PyObject *self, PyObject *args)
5905{
5906 int device;
5907 if (!PyArg_ParseTuple(args, "i:major", &device))
5908 return NULL;
5909 return PyInt_FromLong((long)major(device));
5910}
5911
5912PyDoc_STRVAR(posix_minor__doc__,
5913"minor(device) -> minor number\n\
5914Extracts a device minor number from a raw device number.");
5915
5916static PyObject *
5917posix_minor(PyObject *self, PyObject *args)
5918{
5919 int device;
5920 if (!PyArg_ParseTuple(args, "i:minor", &device))
5921 return NULL;
5922 return PyInt_FromLong((long)minor(device));
5923}
5924
5925PyDoc_STRVAR(posix_makedev__doc__,
5926"makedev(major, minor) -> device number\n\
5927Composes a raw device number from the major and minor device numbers.");
5928
5929static PyObject *
5930posix_makedev(PyObject *self, PyObject *args)
5931{
5932 int major, minor;
5933 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
5934 return NULL;
5935 return PyInt_FromLong((long)makedev(major, minor));
5936}
5937#endif /* device macros */
5938
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005939
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005940#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005941PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005942"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005943Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005944
Barry Warsaw53699e91996-12-10 23:23:01 +00005945static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005946posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005947{
5948 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005949 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005950 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005951 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005952
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005953 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005954 return NULL;
5955
5956#if !defined(HAVE_LARGEFILE_SUPPORT)
5957 length = PyInt_AsLong(lenobj);
5958#else
5959 length = PyLong_Check(lenobj) ?
5960 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
5961#endif
5962 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005963 return NULL;
5964
Barry Warsaw53699e91996-12-10 23:23:01 +00005965 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005966 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00005967 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005968 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005969 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005970 return NULL;
5971 }
Barry Warsaw53699e91996-12-10 23:23:01 +00005972 Py_INCREF(Py_None);
5973 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005974}
5975#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005976
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005977#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005978PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005979"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005980Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005981
Fred Drake762e2061999-08-26 17:23:54 +00005982/* Save putenv() parameters as values here, so we can collect them when they
5983 * get re-set with another call for the same key. */
5984static PyObject *posix_putenv_garbage;
5985
Tim Peters5aa91602002-01-30 05:46:57 +00005986static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005987posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005988{
5989 char *s1, *s2;
5990 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00005991 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00005992 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005993
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005994 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005995 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00005996
5997#if defined(PYOS_OS2)
5998 if (stricmp(s1, "BEGINLIBPATH") == 0) {
5999 APIRET rc;
6000
Guido van Rossumd48f2521997-12-05 22:19:34 +00006001 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
6002 if (rc != NO_ERROR)
6003 return os2_error(rc);
6004
6005 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
6006 APIRET rc;
6007
Guido van Rossumd48f2521997-12-05 22:19:34 +00006008 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
6009 if (rc != NO_ERROR)
6010 return os2_error(rc);
6011 } else {
6012#endif
6013
Fred Drake762e2061999-08-26 17:23:54 +00006014 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00006015 len = strlen(s1) + strlen(s2) + 2;
6016 /* len includes space for a trailing \0; the size arg to
6017 PyString_FromStringAndSize does not count that */
6018 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00006019 if (newstr == NULL)
6020 return PyErr_NoMemory();
6021 new = PyString_AS_STRING(newstr);
Tim Petersc8996f52001-12-03 20:41:00 +00006022 PyOS_snprintf(new, len, "%s=%s", s1, s2);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006023 if (putenv(new)) {
Neal Norwitz4adc9ab2003-02-10 03:10:43 +00006024 Py_DECREF(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006025 posix_error();
6026 return NULL;
6027 }
Fred Drake762e2061999-08-26 17:23:54 +00006028 /* Install the first arg and newstr in posix_putenv_garbage;
6029 * this will cause previous value to be collected. This has to
6030 * happen after the real putenv() call because the old value
6031 * was still accessible until then. */
6032 if (PyDict_SetItem(posix_putenv_garbage,
6033 PyTuple_GET_ITEM(args, 0), newstr)) {
6034 /* really not much we can do; just leak */
6035 PyErr_Clear();
6036 }
6037 else {
6038 Py_DECREF(newstr);
6039 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00006040
6041#if defined(PYOS_OS2)
6042 }
6043#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006044 Py_INCREF(Py_None);
6045 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006046}
Guido van Rossumb6a47161997-09-15 22:54:34 +00006047#endif /* putenv */
6048
Guido van Rossumc524d952001-10-19 01:31:59 +00006049#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006050PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006051"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006052Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00006053
6054static PyObject *
6055posix_unsetenv(PyObject *self, PyObject *args)
6056{
6057 char *s1;
6058
6059 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
6060 return NULL;
6061
6062 unsetenv(s1);
6063
6064 /* Remove the key from posix_putenv_garbage;
6065 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00006066 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00006067 * old value was still accessible until then.
6068 */
6069 if (PyDict_DelItem(posix_putenv_garbage,
6070 PyTuple_GET_ITEM(args, 0))) {
6071 /* really not much we can do; just leak */
6072 PyErr_Clear();
6073 }
6074
6075 Py_INCREF(Py_None);
6076 return Py_None;
6077}
6078#endif /* unsetenv */
6079
Guido van Rossumb6a47161997-09-15 22:54:34 +00006080#ifdef HAVE_STRERROR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006081PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006082"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006083Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00006084
Guido van Rossumf68d8e52001-04-14 17:55:09 +00006085static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006086posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00006087{
6088 int code;
6089 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006090 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00006091 return NULL;
6092 message = strerror(code);
6093 if (message == NULL) {
6094 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00006095 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00006096 return NULL;
6097 }
6098 return PyString_FromString(message);
6099}
6100#endif /* strerror */
6101
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006102
Guido van Rossumc9641791998-08-04 15:26:23 +00006103#ifdef HAVE_SYS_WAIT_H
6104
Fred Drake106c1a02002-04-23 15:58:02 +00006105#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006106PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006107"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006108Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00006109
6110static PyObject *
6111posix_WCOREDUMP(PyObject *self, PyObject *args)
6112{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006113 WAIT_TYPE status;
6114 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006115
Neal Norwitzd5a37542006-03-20 06:48:34 +00006116 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00006117 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006118
6119 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006120}
6121#endif /* WCOREDUMP */
6122
6123#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006124PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006125"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006126Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006127job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00006128
6129static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006130posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00006131{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006132 WAIT_TYPE status;
6133 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006134
Neal Norwitzd5a37542006-03-20 06:48:34 +00006135 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00006136 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006137
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006138 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006139}
6140#endif /* WIFCONTINUED */
6141
Guido van Rossumc9641791998-08-04 15:26:23 +00006142#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006143PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006144"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006145Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006146
6147static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006148posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006149{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006150 WAIT_TYPE status;
6151 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006152
Neal Norwitzd5a37542006-03-20 06:48:34 +00006153 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006154 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006155
Fred Drake106c1a02002-04-23 15:58:02 +00006156 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006157}
6158#endif /* WIFSTOPPED */
6159
6160#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006161PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006162"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006163Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006164
6165static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006166posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006167{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006168 WAIT_TYPE status;
6169 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006170
Neal Norwitzd5a37542006-03-20 06:48:34 +00006171 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006172 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006173
Fred Drake106c1a02002-04-23 15:58:02 +00006174 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006175}
6176#endif /* WIFSIGNALED */
6177
6178#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006179PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006180"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006181Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006182system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006183
6184static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006185posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006186{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006187 WAIT_TYPE status;
6188 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006189
Neal Norwitzd5a37542006-03-20 06:48:34 +00006190 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006191 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006192
Fred Drake106c1a02002-04-23 15:58:02 +00006193 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006194}
6195#endif /* WIFEXITED */
6196
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006197#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006198PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006199"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006200Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006201
6202static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006203posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006204{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006205 WAIT_TYPE status;
6206 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006207
Neal Norwitzd5a37542006-03-20 06:48:34 +00006208 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006209 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006210
Guido van Rossumc9641791998-08-04 15:26:23 +00006211 return Py_BuildValue("i", WEXITSTATUS(status));
6212}
6213#endif /* WEXITSTATUS */
6214
6215#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006216PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006217"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006218Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006219value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006220
6221static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006222posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006223{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006224 WAIT_TYPE status;
6225 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006226
Neal Norwitzd5a37542006-03-20 06:48:34 +00006227 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006228 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006229
Guido van Rossumc9641791998-08-04 15:26:23 +00006230 return Py_BuildValue("i", WTERMSIG(status));
6231}
6232#endif /* WTERMSIG */
6233
6234#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006235PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006236"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006237Return the signal that stopped the process that provided\n\
6238the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006239
6240static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006241posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006242{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006243 WAIT_TYPE status;
6244 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006245
Neal Norwitzd5a37542006-03-20 06:48:34 +00006246 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006247 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006248
Guido van Rossumc9641791998-08-04 15:26:23 +00006249 return Py_BuildValue("i", WSTOPSIG(status));
6250}
6251#endif /* WSTOPSIG */
6252
6253#endif /* HAVE_SYS_WAIT_H */
6254
6255
Guido van Rossum94f6f721999-01-06 18:42:14 +00006256#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00006257#ifdef _SCO_DS
6258/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
6259 needed definitions in sys/statvfs.h */
6260#define _SVID3
6261#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006262#include <sys/statvfs.h>
6263
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006264static PyObject*
6265_pystatvfs_fromstructstatvfs(struct statvfs st) {
6266 PyObject *v = PyStructSequence_New(&StatVFSResultType);
6267 if (v == NULL)
6268 return NULL;
6269
6270#if !defined(HAVE_LARGEFILE_SUPPORT)
6271 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6272 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
6273 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
6274 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
6275 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
6276 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
6277 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
6278 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
6279 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6280 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6281#else
6282 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6283 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00006284 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006285 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00006286 PyStructSequence_SET_ITEM(v, 3,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006287 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006288 PyStructSequence_SET_ITEM(v, 4,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006289 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00006290 PyStructSequence_SET_ITEM(v, 5,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006291 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00006292 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006293 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00006294 PyStructSequence_SET_ITEM(v, 7,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006295 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006296 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6297 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6298#endif
6299
6300 return v;
6301}
6302
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006303PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006304"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006305Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006306
6307static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006308posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006309{
6310 int fd, res;
6311 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006312
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006313 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006314 return NULL;
6315 Py_BEGIN_ALLOW_THREADS
6316 res = fstatvfs(fd, &st);
6317 Py_END_ALLOW_THREADS
6318 if (res != 0)
6319 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006320
6321 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006322}
6323#endif /* HAVE_FSTATVFS */
6324
6325
6326#if defined(HAVE_STATVFS)
6327#include <sys/statvfs.h>
6328
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006329PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006330"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006331Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006332
6333static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006334posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006335{
6336 char *path;
6337 int res;
6338 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006339 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006340 return NULL;
6341 Py_BEGIN_ALLOW_THREADS
6342 res = statvfs(path, &st);
6343 Py_END_ALLOW_THREADS
6344 if (res != 0)
6345 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006346
6347 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006348}
6349#endif /* HAVE_STATVFS */
6350
6351
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006352#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006353PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006354"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006355Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00006356The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006357or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006358
6359static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006360posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006361{
6362 PyObject *result = NULL;
6363 char *dir = NULL;
6364 char *pfx = NULL;
6365 char *name;
6366
6367 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
6368 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00006369
6370 if (PyErr_Warn(PyExc_RuntimeWarning,
6371 "tempnam is a potential security risk to your program") < 0)
6372 return NULL;
6373
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006374#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00006375 name = _tempnam(dir, pfx);
6376#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006377 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00006378#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006379 if (name == NULL)
6380 return PyErr_NoMemory();
6381 result = PyString_FromString(name);
6382 free(name);
6383 return result;
6384}
Guido van Rossumd371ff11999-01-25 16:12:23 +00006385#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006386
6387
6388#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006389PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006390"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006391Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006392
6393static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006394posix_tmpfile(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006395{
6396 FILE *fp;
6397
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006398 fp = tmpfile();
6399 if (fp == NULL)
6400 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00006401 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006402}
6403#endif
6404
6405
6406#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006407PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006408"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006409Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006410
6411static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006412posix_tmpnam(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006413{
6414 char buffer[L_tmpnam];
6415 char *name;
6416
Skip Montanaro95618b52001-08-18 18:52:10 +00006417 if (PyErr_Warn(PyExc_RuntimeWarning,
6418 "tmpnam is a potential security risk to your program") < 0)
6419 return NULL;
6420
Greg Wardb48bc172000-03-01 21:51:56 +00006421#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006422 name = tmpnam_r(buffer);
6423#else
6424 name = tmpnam(buffer);
6425#endif
6426 if (name == NULL) {
Neal Norwitzd1e0ef62006-03-20 04:08:12 +00006427 PyObject *err = Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00006428#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006429 "unexpected NULL from tmpnam_r"
6430#else
6431 "unexpected NULL from tmpnam"
6432#endif
Neal Norwitzd1e0ef62006-03-20 04:08:12 +00006433 );
6434 PyErr_SetObject(PyExc_OSError, err);
6435 Py_XDECREF(err);
6436 return NULL;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006437 }
6438 return PyString_FromString(buffer);
6439}
6440#endif
6441
6442
Fred Drakec9680921999-12-13 16:37:25 +00006443/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
6444 * It maps strings representing configuration variable names to
6445 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00006446 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00006447 * rarely-used constants. There are three separate tables that use
6448 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00006449 *
6450 * This code is always included, even if none of the interfaces that
6451 * need it are included. The #if hackery needed to avoid it would be
6452 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00006453 */
6454struct constdef {
6455 char *name;
6456 long value;
6457};
6458
Fred Drake12c6e2d1999-12-14 21:25:03 +00006459static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006460conv_confname(PyObject *arg, int *valuep, struct constdef *table,
6461 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006462{
6463 if (PyInt_Check(arg)) {
6464 *valuep = PyInt_AS_LONG(arg);
6465 return 1;
6466 }
6467 if (PyString_Check(arg)) {
6468 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00006469 size_t lo = 0;
6470 size_t mid;
6471 size_t hi = tablesize;
6472 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006473 char *confname = PyString_AS_STRING(arg);
6474 while (lo < hi) {
6475 mid = (lo + hi) / 2;
6476 cmp = strcmp(confname, table[mid].name);
6477 if (cmp < 0)
6478 hi = mid;
6479 else if (cmp > 0)
6480 lo = mid + 1;
6481 else {
6482 *valuep = table[mid].value;
6483 return 1;
6484 }
6485 }
6486 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
6487 }
6488 else
6489 PyErr_SetString(PyExc_TypeError,
6490 "configuration names must be strings or integers");
6491 return 0;
6492}
6493
6494
6495#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
6496static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006497#ifdef _PC_ABI_AIO_XFER_MAX
6498 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
6499#endif
6500#ifdef _PC_ABI_ASYNC_IO
6501 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
6502#endif
Fred Drakec9680921999-12-13 16:37:25 +00006503#ifdef _PC_ASYNC_IO
6504 {"PC_ASYNC_IO", _PC_ASYNC_IO},
6505#endif
6506#ifdef _PC_CHOWN_RESTRICTED
6507 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
6508#endif
6509#ifdef _PC_FILESIZEBITS
6510 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
6511#endif
6512#ifdef _PC_LAST
6513 {"PC_LAST", _PC_LAST},
6514#endif
6515#ifdef _PC_LINK_MAX
6516 {"PC_LINK_MAX", _PC_LINK_MAX},
6517#endif
6518#ifdef _PC_MAX_CANON
6519 {"PC_MAX_CANON", _PC_MAX_CANON},
6520#endif
6521#ifdef _PC_MAX_INPUT
6522 {"PC_MAX_INPUT", _PC_MAX_INPUT},
6523#endif
6524#ifdef _PC_NAME_MAX
6525 {"PC_NAME_MAX", _PC_NAME_MAX},
6526#endif
6527#ifdef _PC_NO_TRUNC
6528 {"PC_NO_TRUNC", _PC_NO_TRUNC},
6529#endif
6530#ifdef _PC_PATH_MAX
6531 {"PC_PATH_MAX", _PC_PATH_MAX},
6532#endif
6533#ifdef _PC_PIPE_BUF
6534 {"PC_PIPE_BUF", _PC_PIPE_BUF},
6535#endif
6536#ifdef _PC_PRIO_IO
6537 {"PC_PRIO_IO", _PC_PRIO_IO},
6538#endif
6539#ifdef _PC_SOCK_MAXBUF
6540 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
6541#endif
6542#ifdef _PC_SYNC_IO
6543 {"PC_SYNC_IO", _PC_SYNC_IO},
6544#endif
6545#ifdef _PC_VDISABLE
6546 {"PC_VDISABLE", _PC_VDISABLE},
6547#endif
6548};
6549
Fred Drakec9680921999-12-13 16:37:25 +00006550static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006551conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006552{
6553 return conv_confname(arg, valuep, posix_constants_pathconf,
6554 sizeof(posix_constants_pathconf)
6555 / sizeof(struct constdef));
6556}
6557#endif
6558
6559#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006560PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006561"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006562Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006563If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006564
6565static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006566posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006567{
6568 PyObject *result = NULL;
6569 int name, fd;
6570
Fred Drake12c6e2d1999-12-14 21:25:03 +00006571 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
6572 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00006573 long limit;
6574
6575 errno = 0;
6576 limit = fpathconf(fd, name);
6577 if (limit == -1 && errno != 0)
6578 posix_error();
6579 else
6580 result = PyInt_FromLong(limit);
6581 }
6582 return result;
6583}
6584#endif
6585
6586
6587#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006588PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006589"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006590Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006591If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006592
6593static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006594posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006595{
6596 PyObject *result = NULL;
6597 int name;
6598 char *path;
6599
6600 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
6601 conv_path_confname, &name)) {
6602 long limit;
6603
6604 errno = 0;
6605 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006606 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00006607 if (errno == EINVAL)
6608 /* could be a path or name problem */
6609 posix_error();
6610 else
6611 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006612 }
Fred Drakec9680921999-12-13 16:37:25 +00006613 else
6614 result = PyInt_FromLong(limit);
6615 }
6616 return result;
6617}
6618#endif
6619
6620#ifdef HAVE_CONFSTR
6621static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006622#ifdef _CS_ARCHITECTURE
6623 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
6624#endif
6625#ifdef _CS_HOSTNAME
6626 {"CS_HOSTNAME", _CS_HOSTNAME},
6627#endif
6628#ifdef _CS_HW_PROVIDER
6629 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
6630#endif
6631#ifdef _CS_HW_SERIAL
6632 {"CS_HW_SERIAL", _CS_HW_SERIAL},
6633#endif
6634#ifdef _CS_INITTAB_NAME
6635 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
6636#endif
Fred Drakec9680921999-12-13 16:37:25 +00006637#ifdef _CS_LFS64_CFLAGS
6638 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
6639#endif
6640#ifdef _CS_LFS64_LDFLAGS
6641 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
6642#endif
6643#ifdef _CS_LFS64_LIBS
6644 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
6645#endif
6646#ifdef _CS_LFS64_LINTFLAGS
6647 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
6648#endif
6649#ifdef _CS_LFS_CFLAGS
6650 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
6651#endif
6652#ifdef _CS_LFS_LDFLAGS
6653 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
6654#endif
6655#ifdef _CS_LFS_LIBS
6656 {"CS_LFS_LIBS", _CS_LFS_LIBS},
6657#endif
6658#ifdef _CS_LFS_LINTFLAGS
6659 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
6660#endif
Fred Draked86ed291999-12-15 15:34:33 +00006661#ifdef _CS_MACHINE
6662 {"CS_MACHINE", _CS_MACHINE},
6663#endif
Fred Drakec9680921999-12-13 16:37:25 +00006664#ifdef _CS_PATH
6665 {"CS_PATH", _CS_PATH},
6666#endif
Fred Draked86ed291999-12-15 15:34:33 +00006667#ifdef _CS_RELEASE
6668 {"CS_RELEASE", _CS_RELEASE},
6669#endif
6670#ifdef _CS_SRPC_DOMAIN
6671 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
6672#endif
6673#ifdef _CS_SYSNAME
6674 {"CS_SYSNAME", _CS_SYSNAME},
6675#endif
6676#ifdef _CS_VERSION
6677 {"CS_VERSION", _CS_VERSION},
6678#endif
Fred Drakec9680921999-12-13 16:37:25 +00006679#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
6680 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
6681#endif
6682#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
6683 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
6684#endif
6685#ifdef _CS_XBS5_ILP32_OFF32_LIBS
6686 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
6687#endif
6688#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
6689 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
6690#endif
6691#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
6692 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
6693#endif
6694#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
6695 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
6696#endif
6697#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
6698 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
6699#endif
6700#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
6701 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
6702#endif
6703#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
6704 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
6705#endif
6706#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
6707 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
6708#endif
6709#ifdef _CS_XBS5_LP64_OFF64_LIBS
6710 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
6711#endif
6712#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
6713 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
6714#endif
6715#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
6716 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
6717#endif
6718#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
6719 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
6720#endif
6721#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
6722 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
6723#endif
6724#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
6725 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
6726#endif
Fred Draked86ed291999-12-15 15:34:33 +00006727#ifdef _MIPS_CS_AVAIL_PROCESSORS
6728 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
6729#endif
6730#ifdef _MIPS_CS_BASE
6731 {"MIPS_CS_BASE", _MIPS_CS_BASE},
6732#endif
6733#ifdef _MIPS_CS_HOSTID
6734 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
6735#endif
6736#ifdef _MIPS_CS_HW_NAME
6737 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
6738#endif
6739#ifdef _MIPS_CS_NUM_PROCESSORS
6740 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
6741#endif
6742#ifdef _MIPS_CS_OSREL_MAJ
6743 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
6744#endif
6745#ifdef _MIPS_CS_OSREL_MIN
6746 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
6747#endif
6748#ifdef _MIPS_CS_OSREL_PATCH
6749 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
6750#endif
6751#ifdef _MIPS_CS_OS_NAME
6752 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
6753#endif
6754#ifdef _MIPS_CS_OS_PROVIDER
6755 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
6756#endif
6757#ifdef _MIPS_CS_PROCESSORS
6758 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
6759#endif
6760#ifdef _MIPS_CS_SERIAL
6761 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
6762#endif
6763#ifdef _MIPS_CS_VENDOR
6764 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
6765#endif
Fred Drakec9680921999-12-13 16:37:25 +00006766};
6767
6768static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006769conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006770{
6771 return conv_confname(arg, valuep, posix_constants_confstr,
6772 sizeof(posix_constants_confstr)
6773 / sizeof(struct constdef));
6774}
6775
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006776PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006777"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006778Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006779
6780static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006781posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006782{
6783 PyObject *result = NULL;
6784 int name;
6785 char buffer[64];
6786
6787 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
6788 int len = confstr(name, buffer, sizeof(buffer));
6789
Fred Drakec9680921999-12-13 16:37:25 +00006790 errno = 0;
6791 if (len == 0) {
6792 if (errno != 0)
6793 posix_error();
6794 else
6795 result = PyString_FromString("");
6796 }
6797 else {
6798 if (len >= sizeof(buffer)) {
6799 result = PyString_FromStringAndSize(NULL, len);
6800 if (result != NULL)
6801 confstr(name, PyString_AS_STRING(result), len+1);
6802 }
6803 else
6804 result = PyString_FromString(buffer);
6805 }
6806 }
6807 return result;
6808}
6809#endif
6810
6811
6812#ifdef HAVE_SYSCONF
6813static struct constdef posix_constants_sysconf[] = {
6814#ifdef _SC_2_CHAR_TERM
6815 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
6816#endif
6817#ifdef _SC_2_C_BIND
6818 {"SC_2_C_BIND", _SC_2_C_BIND},
6819#endif
6820#ifdef _SC_2_C_DEV
6821 {"SC_2_C_DEV", _SC_2_C_DEV},
6822#endif
6823#ifdef _SC_2_C_VERSION
6824 {"SC_2_C_VERSION", _SC_2_C_VERSION},
6825#endif
6826#ifdef _SC_2_FORT_DEV
6827 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
6828#endif
6829#ifdef _SC_2_FORT_RUN
6830 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
6831#endif
6832#ifdef _SC_2_LOCALEDEF
6833 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
6834#endif
6835#ifdef _SC_2_SW_DEV
6836 {"SC_2_SW_DEV", _SC_2_SW_DEV},
6837#endif
6838#ifdef _SC_2_UPE
6839 {"SC_2_UPE", _SC_2_UPE},
6840#endif
6841#ifdef _SC_2_VERSION
6842 {"SC_2_VERSION", _SC_2_VERSION},
6843#endif
Fred Draked86ed291999-12-15 15:34:33 +00006844#ifdef _SC_ABI_ASYNCHRONOUS_IO
6845 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
6846#endif
6847#ifdef _SC_ACL
6848 {"SC_ACL", _SC_ACL},
6849#endif
Fred Drakec9680921999-12-13 16:37:25 +00006850#ifdef _SC_AIO_LISTIO_MAX
6851 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
6852#endif
Fred Drakec9680921999-12-13 16:37:25 +00006853#ifdef _SC_AIO_MAX
6854 {"SC_AIO_MAX", _SC_AIO_MAX},
6855#endif
6856#ifdef _SC_AIO_PRIO_DELTA_MAX
6857 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
6858#endif
6859#ifdef _SC_ARG_MAX
6860 {"SC_ARG_MAX", _SC_ARG_MAX},
6861#endif
6862#ifdef _SC_ASYNCHRONOUS_IO
6863 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
6864#endif
6865#ifdef _SC_ATEXIT_MAX
6866 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
6867#endif
Fred Draked86ed291999-12-15 15:34:33 +00006868#ifdef _SC_AUDIT
6869 {"SC_AUDIT", _SC_AUDIT},
6870#endif
Fred Drakec9680921999-12-13 16:37:25 +00006871#ifdef _SC_AVPHYS_PAGES
6872 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
6873#endif
6874#ifdef _SC_BC_BASE_MAX
6875 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
6876#endif
6877#ifdef _SC_BC_DIM_MAX
6878 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
6879#endif
6880#ifdef _SC_BC_SCALE_MAX
6881 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
6882#endif
6883#ifdef _SC_BC_STRING_MAX
6884 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
6885#endif
Fred Draked86ed291999-12-15 15:34:33 +00006886#ifdef _SC_CAP
6887 {"SC_CAP", _SC_CAP},
6888#endif
Fred Drakec9680921999-12-13 16:37:25 +00006889#ifdef _SC_CHARCLASS_NAME_MAX
6890 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
6891#endif
6892#ifdef _SC_CHAR_BIT
6893 {"SC_CHAR_BIT", _SC_CHAR_BIT},
6894#endif
6895#ifdef _SC_CHAR_MAX
6896 {"SC_CHAR_MAX", _SC_CHAR_MAX},
6897#endif
6898#ifdef _SC_CHAR_MIN
6899 {"SC_CHAR_MIN", _SC_CHAR_MIN},
6900#endif
6901#ifdef _SC_CHILD_MAX
6902 {"SC_CHILD_MAX", _SC_CHILD_MAX},
6903#endif
6904#ifdef _SC_CLK_TCK
6905 {"SC_CLK_TCK", _SC_CLK_TCK},
6906#endif
6907#ifdef _SC_COHER_BLKSZ
6908 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
6909#endif
6910#ifdef _SC_COLL_WEIGHTS_MAX
6911 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
6912#endif
6913#ifdef _SC_DCACHE_ASSOC
6914 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
6915#endif
6916#ifdef _SC_DCACHE_BLKSZ
6917 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
6918#endif
6919#ifdef _SC_DCACHE_LINESZ
6920 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
6921#endif
6922#ifdef _SC_DCACHE_SZ
6923 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
6924#endif
6925#ifdef _SC_DCACHE_TBLKSZ
6926 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
6927#endif
6928#ifdef _SC_DELAYTIMER_MAX
6929 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
6930#endif
6931#ifdef _SC_EQUIV_CLASS_MAX
6932 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
6933#endif
6934#ifdef _SC_EXPR_NEST_MAX
6935 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
6936#endif
6937#ifdef _SC_FSYNC
6938 {"SC_FSYNC", _SC_FSYNC},
6939#endif
6940#ifdef _SC_GETGR_R_SIZE_MAX
6941 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
6942#endif
6943#ifdef _SC_GETPW_R_SIZE_MAX
6944 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
6945#endif
6946#ifdef _SC_ICACHE_ASSOC
6947 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
6948#endif
6949#ifdef _SC_ICACHE_BLKSZ
6950 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
6951#endif
6952#ifdef _SC_ICACHE_LINESZ
6953 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
6954#endif
6955#ifdef _SC_ICACHE_SZ
6956 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
6957#endif
Fred Draked86ed291999-12-15 15:34:33 +00006958#ifdef _SC_INF
6959 {"SC_INF", _SC_INF},
6960#endif
Fred Drakec9680921999-12-13 16:37:25 +00006961#ifdef _SC_INT_MAX
6962 {"SC_INT_MAX", _SC_INT_MAX},
6963#endif
6964#ifdef _SC_INT_MIN
6965 {"SC_INT_MIN", _SC_INT_MIN},
6966#endif
6967#ifdef _SC_IOV_MAX
6968 {"SC_IOV_MAX", _SC_IOV_MAX},
6969#endif
Fred Draked86ed291999-12-15 15:34:33 +00006970#ifdef _SC_IP_SECOPTS
6971 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
6972#endif
Fred Drakec9680921999-12-13 16:37:25 +00006973#ifdef _SC_JOB_CONTROL
6974 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
6975#endif
Fred Draked86ed291999-12-15 15:34:33 +00006976#ifdef _SC_KERN_POINTERS
6977 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
6978#endif
6979#ifdef _SC_KERN_SIM
6980 {"SC_KERN_SIM", _SC_KERN_SIM},
6981#endif
Fred Drakec9680921999-12-13 16:37:25 +00006982#ifdef _SC_LINE_MAX
6983 {"SC_LINE_MAX", _SC_LINE_MAX},
6984#endif
6985#ifdef _SC_LOGIN_NAME_MAX
6986 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
6987#endif
6988#ifdef _SC_LOGNAME_MAX
6989 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
6990#endif
6991#ifdef _SC_LONG_BIT
6992 {"SC_LONG_BIT", _SC_LONG_BIT},
6993#endif
Fred Draked86ed291999-12-15 15:34:33 +00006994#ifdef _SC_MAC
6995 {"SC_MAC", _SC_MAC},
6996#endif
Fred Drakec9680921999-12-13 16:37:25 +00006997#ifdef _SC_MAPPED_FILES
6998 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
6999#endif
7000#ifdef _SC_MAXPID
7001 {"SC_MAXPID", _SC_MAXPID},
7002#endif
7003#ifdef _SC_MB_LEN_MAX
7004 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
7005#endif
7006#ifdef _SC_MEMLOCK
7007 {"SC_MEMLOCK", _SC_MEMLOCK},
7008#endif
7009#ifdef _SC_MEMLOCK_RANGE
7010 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
7011#endif
7012#ifdef _SC_MEMORY_PROTECTION
7013 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
7014#endif
7015#ifdef _SC_MESSAGE_PASSING
7016 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
7017#endif
Fred Draked86ed291999-12-15 15:34:33 +00007018#ifdef _SC_MMAP_FIXED_ALIGNMENT
7019 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
7020#endif
Fred Drakec9680921999-12-13 16:37:25 +00007021#ifdef _SC_MQ_OPEN_MAX
7022 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
7023#endif
7024#ifdef _SC_MQ_PRIO_MAX
7025 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
7026#endif
Fred Draked86ed291999-12-15 15:34:33 +00007027#ifdef _SC_NACLS_MAX
7028 {"SC_NACLS_MAX", _SC_NACLS_MAX},
7029#endif
Fred Drakec9680921999-12-13 16:37:25 +00007030#ifdef _SC_NGROUPS_MAX
7031 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
7032#endif
7033#ifdef _SC_NL_ARGMAX
7034 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
7035#endif
7036#ifdef _SC_NL_LANGMAX
7037 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
7038#endif
7039#ifdef _SC_NL_MSGMAX
7040 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
7041#endif
7042#ifdef _SC_NL_NMAX
7043 {"SC_NL_NMAX", _SC_NL_NMAX},
7044#endif
7045#ifdef _SC_NL_SETMAX
7046 {"SC_NL_SETMAX", _SC_NL_SETMAX},
7047#endif
7048#ifdef _SC_NL_TEXTMAX
7049 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
7050#endif
7051#ifdef _SC_NPROCESSORS_CONF
7052 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
7053#endif
7054#ifdef _SC_NPROCESSORS_ONLN
7055 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
7056#endif
Fred Draked86ed291999-12-15 15:34:33 +00007057#ifdef _SC_NPROC_CONF
7058 {"SC_NPROC_CONF", _SC_NPROC_CONF},
7059#endif
7060#ifdef _SC_NPROC_ONLN
7061 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
7062#endif
Fred Drakec9680921999-12-13 16:37:25 +00007063#ifdef _SC_NZERO
7064 {"SC_NZERO", _SC_NZERO},
7065#endif
7066#ifdef _SC_OPEN_MAX
7067 {"SC_OPEN_MAX", _SC_OPEN_MAX},
7068#endif
7069#ifdef _SC_PAGESIZE
7070 {"SC_PAGESIZE", _SC_PAGESIZE},
7071#endif
7072#ifdef _SC_PAGE_SIZE
7073 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
7074#endif
7075#ifdef _SC_PASS_MAX
7076 {"SC_PASS_MAX", _SC_PASS_MAX},
7077#endif
7078#ifdef _SC_PHYS_PAGES
7079 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
7080#endif
7081#ifdef _SC_PII
7082 {"SC_PII", _SC_PII},
7083#endif
7084#ifdef _SC_PII_INTERNET
7085 {"SC_PII_INTERNET", _SC_PII_INTERNET},
7086#endif
7087#ifdef _SC_PII_INTERNET_DGRAM
7088 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
7089#endif
7090#ifdef _SC_PII_INTERNET_STREAM
7091 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
7092#endif
7093#ifdef _SC_PII_OSI
7094 {"SC_PII_OSI", _SC_PII_OSI},
7095#endif
7096#ifdef _SC_PII_OSI_CLTS
7097 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
7098#endif
7099#ifdef _SC_PII_OSI_COTS
7100 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
7101#endif
7102#ifdef _SC_PII_OSI_M
7103 {"SC_PII_OSI_M", _SC_PII_OSI_M},
7104#endif
7105#ifdef _SC_PII_SOCKET
7106 {"SC_PII_SOCKET", _SC_PII_SOCKET},
7107#endif
7108#ifdef _SC_PII_XTI
7109 {"SC_PII_XTI", _SC_PII_XTI},
7110#endif
7111#ifdef _SC_POLL
7112 {"SC_POLL", _SC_POLL},
7113#endif
7114#ifdef _SC_PRIORITIZED_IO
7115 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
7116#endif
7117#ifdef _SC_PRIORITY_SCHEDULING
7118 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
7119#endif
7120#ifdef _SC_REALTIME_SIGNALS
7121 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
7122#endif
7123#ifdef _SC_RE_DUP_MAX
7124 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
7125#endif
7126#ifdef _SC_RTSIG_MAX
7127 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
7128#endif
7129#ifdef _SC_SAVED_IDS
7130 {"SC_SAVED_IDS", _SC_SAVED_IDS},
7131#endif
7132#ifdef _SC_SCHAR_MAX
7133 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
7134#endif
7135#ifdef _SC_SCHAR_MIN
7136 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
7137#endif
7138#ifdef _SC_SELECT
7139 {"SC_SELECT", _SC_SELECT},
7140#endif
7141#ifdef _SC_SEMAPHORES
7142 {"SC_SEMAPHORES", _SC_SEMAPHORES},
7143#endif
7144#ifdef _SC_SEM_NSEMS_MAX
7145 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
7146#endif
7147#ifdef _SC_SEM_VALUE_MAX
7148 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
7149#endif
7150#ifdef _SC_SHARED_MEMORY_OBJECTS
7151 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
7152#endif
7153#ifdef _SC_SHRT_MAX
7154 {"SC_SHRT_MAX", _SC_SHRT_MAX},
7155#endif
7156#ifdef _SC_SHRT_MIN
7157 {"SC_SHRT_MIN", _SC_SHRT_MIN},
7158#endif
7159#ifdef _SC_SIGQUEUE_MAX
7160 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
7161#endif
7162#ifdef _SC_SIGRT_MAX
7163 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
7164#endif
7165#ifdef _SC_SIGRT_MIN
7166 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
7167#endif
Fred Draked86ed291999-12-15 15:34:33 +00007168#ifdef _SC_SOFTPOWER
7169 {"SC_SOFTPOWER", _SC_SOFTPOWER},
7170#endif
Fred Drakec9680921999-12-13 16:37:25 +00007171#ifdef _SC_SPLIT_CACHE
7172 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
7173#endif
7174#ifdef _SC_SSIZE_MAX
7175 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
7176#endif
7177#ifdef _SC_STACK_PROT
7178 {"SC_STACK_PROT", _SC_STACK_PROT},
7179#endif
7180#ifdef _SC_STREAM_MAX
7181 {"SC_STREAM_MAX", _SC_STREAM_MAX},
7182#endif
7183#ifdef _SC_SYNCHRONIZED_IO
7184 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
7185#endif
7186#ifdef _SC_THREADS
7187 {"SC_THREADS", _SC_THREADS},
7188#endif
7189#ifdef _SC_THREAD_ATTR_STACKADDR
7190 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
7191#endif
7192#ifdef _SC_THREAD_ATTR_STACKSIZE
7193 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
7194#endif
7195#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
7196 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
7197#endif
7198#ifdef _SC_THREAD_KEYS_MAX
7199 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
7200#endif
7201#ifdef _SC_THREAD_PRIORITY_SCHEDULING
7202 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
7203#endif
7204#ifdef _SC_THREAD_PRIO_INHERIT
7205 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
7206#endif
7207#ifdef _SC_THREAD_PRIO_PROTECT
7208 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
7209#endif
7210#ifdef _SC_THREAD_PROCESS_SHARED
7211 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
7212#endif
7213#ifdef _SC_THREAD_SAFE_FUNCTIONS
7214 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
7215#endif
7216#ifdef _SC_THREAD_STACK_MIN
7217 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
7218#endif
7219#ifdef _SC_THREAD_THREADS_MAX
7220 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
7221#endif
7222#ifdef _SC_TIMERS
7223 {"SC_TIMERS", _SC_TIMERS},
7224#endif
7225#ifdef _SC_TIMER_MAX
7226 {"SC_TIMER_MAX", _SC_TIMER_MAX},
7227#endif
7228#ifdef _SC_TTY_NAME_MAX
7229 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
7230#endif
7231#ifdef _SC_TZNAME_MAX
7232 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
7233#endif
7234#ifdef _SC_T_IOV_MAX
7235 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
7236#endif
7237#ifdef _SC_UCHAR_MAX
7238 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
7239#endif
7240#ifdef _SC_UINT_MAX
7241 {"SC_UINT_MAX", _SC_UINT_MAX},
7242#endif
7243#ifdef _SC_UIO_MAXIOV
7244 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
7245#endif
7246#ifdef _SC_ULONG_MAX
7247 {"SC_ULONG_MAX", _SC_ULONG_MAX},
7248#endif
7249#ifdef _SC_USHRT_MAX
7250 {"SC_USHRT_MAX", _SC_USHRT_MAX},
7251#endif
7252#ifdef _SC_VERSION
7253 {"SC_VERSION", _SC_VERSION},
7254#endif
7255#ifdef _SC_WORD_BIT
7256 {"SC_WORD_BIT", _SC_WORD_BIT},
7257#endif
7258#ifdef _SC_XBS5_ILP32_OFF32
7259 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
7260#endif
7261#ifdef _SC_XBS5_ILP32_OFFBIG
7262 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
7263#endif
7264#ifdef _SC_XBS5_LP64_OFF64
7265 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
7266#endif
7267#ifdef _SC_XBS5_LPBIG_OFFBIG
7268 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
7269#endif
7270#ifdef _SC_XOPEN_CRYPT
7271 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
7272#endif
7273#ifdef _SC_XOPEN_ENH_I18N
7274 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
7275#endif
7276#ifdef _SC_XOPEN_LEGACY
7277 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
7278#endif
7279#ifdef _SC_XOPEN_REALTIME
7280 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
7281#endif
7282#ifdef _SC_XOPEN_REALTIME_THREADS
7283 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
7284#endif
7285#ifdef _SC_XOPEN_SHM
7286 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
7287#endif
7288#ifdef _SC_XOPEN_UNIX
7289 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
7290#endif
7291#ifdef _SC_XOPEN_VERSION
7292 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
7293#endif
7294#ifdef _SC_XOPEN_XCU_VERSION
7295 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
7296#endif
7297#ifdef _SC_XOPEN_XPG2
7298 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
7299#endif
7300#ifdef _SC_XOPEN_XPG3
7301 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
7302#endif
7303#ifdef _SC_XOPEN_XPG4
7304 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
7305#endif
7306};
7307
7308static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007309conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007310{
7311 return conv_confname(arg, valuep, posix_constants_sysconf,
7312 sizeof(posix_constants_sysconf)
7313 / sizeof(struct constdef));
7314}
7315
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007316PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007317"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007318Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007319
7320static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007321posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007322{
7323 PyObject *result = NULL;
7324 int name;
7325
7326 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
7327 int value;
7328
7329 errno = 0;
7330 value = sysconf(name);
7331 if (value == -1 && errno != 0)
7332 posix_error();
7333 else
7334 result = PyInt_FromLong(value);
7335 }
7336 return result;
7337}
7338#endif
7339
7340
Fred Drakebec628d1999-12-15 18:31:10 +00007341/* This code is used to ensure that the tables of configuration value names
7342 * are in sorted order as required by conv_confname(), and also to build the
7343 * the exported dictionaries that are used to publish information about the
7344 * names available on the host platform.
7345 *
7346 * Sorting the table at runtime ensures that the table is properly ordered
7347 * when used, even for platforms we're not able to test on. It also makes
7348 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00007349 */
Fred Drakebec628d1999-12-15 18:31:10 +00007350
7351static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007352cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00007353{
7354 const struct constdef *c1 =
7355 (const struct constdef *) v1;
7356 const struct constdef *c2 =
7357 (const struct constdef *) v2;
7358
7359 return strcmp(c1->name, c2->name);
7360}
7361
7362static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007363setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00007364 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007365{
Fred Drakebec628d1999-12-15 18:31:10 +00007366 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00007367 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00007368
7369 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
7370 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00007371 if (d == NULL)
7372 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007373
Barry Warsaw3155db32000-04-13 15:20:40 +00007374 for (i=0; i < tablesize; ++i) {
7375 PyObject *o = PyInt_FromLong(table[i].value);
7376 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
7377 Py_XDECREF(o);
7378 Py_DECREF(d);
7379 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007380 }
Barry Warsaw3155db32000-04-13 15:20:40 +00007381 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00007382 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00007383 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00007384}
7385
Fred Drakebec628d1999-12-15 18:31:10 +00007386/* Return -1 on failure, 0 on success. */
7387static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007388setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007389{
7390#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00007391 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00007392 sizeof(posix_constants_pathconf)
7393 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007394 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007395 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007396#endif
7397#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00007398 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00007399 sizeof(posix_constants_confstr)
7400 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007401 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007402 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007403#endif
7404#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00007405 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00007406 sizeof(posix_constants_sysconf)
7407 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007408 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007409 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007410#endif
Fred Drakebec628d1999-12-15 18:31:10 +00007411 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00007412}
Fred Draked86ed291999-12-15 15:34:33 +00007413
7414
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007415PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007416"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007417Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007418in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007419
7420static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007421posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007422{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007423 abort();
7424 /*NOTREACHED*/
7425 Py_FatalError("abort() called from Python code didn't abort!");
7426 return NULL;
7427}
Fred Drakebec628d1999-12-15 18:31:10 +00007428
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007429#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007430PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00007431"startfile(filepath [, operation]) - Start a file with its associated\n\
7432application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007433\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00007434When \"operation\" is not specified or \"open\", this acts like\n\
7435double-clicking the file in Explorer, or giving the file name as an\n\
7436argument to the DOS \"start\" command: the file is opened with whatever\n\
7437application (if any) its extension is associated.\n\
7438When another \"operation\" is given, it specifies what should be done with\n\
7439the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007440\n\
7441startfile returns as soon as the associated application is launched.\n\
7442There is no option to wait for the application to close, and no way\n\
7443to retrieve the application's exit status.\n\
7444\n\
7445The filepath is relative to the current directory. If you want to use\n\
7446an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007447the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00007448
7449static PyObject *
7450win32_startfile(PyObject *self, PyObject *args)
7451{
7452 char *filepath;
Georg Brandlf4f44152006-02-18 22:29:33 +00007453 char *operation = NULL;
Tim Petersf58a7aa2000-09-22 10:05:54 +00007454 HINSTANCE rc;
Georg Brandlf4f44152006-02-18 22:29:33 +00007455 if (!PyArg_ParseTuple(args, "et|s:startfile",
7456 Py_FileSystemDefaultEncoding, &filepath,
7457 &operation))
Tim Petersf58a7aa2000-09-22 10:05:54 +00007458 return NULL;
7459 Py_BEGIN_ALLOW_THREADS
Georg Brandlf4f44152006-02-18 22:29:33 +00007460 rc = ShellExecute((HWND)0, operation, filepath,
7461 NULL, NULL, SW_SHOWNORMAL);
Tim Petersf58a7aa2000-09-22 10:05:54 +00007462 Py_END_ALLOW_THREADS
Georg Brandle9f8ec92005-09-25 06:16:40 +00007463 if (rc <= (HINSTANCE)32) {
7464 PyObject *errval = win32_error("startfile", filepath);
7465 PyMem_Free(filepath);
7466 return errval;
7467 }
7468 PyMem_Free(filepath);
Tim Petersf58a7aa2000-09-22 10:05:54 +00007469 Py_INCREF(Py_None);
7470 return Py_None;
7471}
7472#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007473
Martin v. Löwis438b5342002-12-27 10:16:42 +00007474#ifdef HAVE_GETLOADAVG
7475PyDoc_STRVAR(posix_getloadavg__doc__,
7476"getloadavg() -> (float, float, float)\n\n\
7477Return the number of processes in the system run queue averaged over\n\
7478the last 1, 5, and 15 minutes or raises OSError if the load average\n\
7479was unobtainable");
7480
7481static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007482posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00007483{
7484 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00007485 if (getloadavg(loadavg, 3)!=3) {
7486 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
7487 return NULL;
7488 } else
7489 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
7490}
7491#endif
7492
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007493#ifdef MS_WINDOWS
7494
7495PyDoc_STRVAR(win32_urandom__doc__,
7496"urandom(n) -> str\n\n\
7497Return a string of n random bytes suitable for cryptographic use.");
7498
7499typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
7500 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
7501 DWORD dwFlags );
7502typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
7503 BYTE *pbBuffer );
7504
7505static CRYPTGENRANDOM pCryptGenRandom = NULL;
7506static HCRYPTPROV hCryptProv = 0;
7507
Tim Peters4ad82172004-08-30 17:02:04 +00007508static PyObject*
7509win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007510{
Tim Petersd3115382004-08-30 17:36:46 +00007511 int howMany;
7512 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007513
Tim Peters4ad82172004-08-30 17:02:04 +00007514 /* Read arguments */
Tim Peters9b279a82004-08-30 17:10:53 +00007515 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
Tim Peters4ad82172004-08-30 17:02:04 +00007516 return NULL;
Tim Peters51eba612004-08-30 17:08:02 +00007517 if (howMany < 0)
7518 return PyErr_Format(PyExc_ValueError,
7519 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007520
Tim Peters4ad82172004-08-30 17:02:04 +00007521 if (hCryptProv == 0) {
7522 HINSTANCE hAdvAPI32 = NULL;
7523 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007524
Tim Peters4ad82172004-08-30 17:02:04 +00007525 /* Obtain handle to the DLL containing CryptoAPI
7526 This should not fail */
7527 hAdvAPI32 = GetModuleHandle("advapi32.dll");
7528 if(hAdvAPI32 == NULL)
7529 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007530
Tim Peters4ad82172004-08-30 17:02:04 +00007531 /* Obtain pointers to the CryptoAPI functions
7532 This will fail on some early versions of Win95 */
7533 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
7534 hAdvAPI32,
7535 "CryptAcquireContextA");
7536 if (pCryptAcquireContext == NULL)
7537 return PyErr_Format(PyExc_NotImplementedError,
7538 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007539
Tim Peters4ad82172004-08-30 17:02:04 +00007540 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
7541 hAdvAPI32, "CryptGenRandom");
7542 if (pCryptAcquireContext == NULL)
7543 return PyErr_Format(PyExc_NotImplementedError,
7544 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007545
Tim Peters4ad82172004-08-30 17:02:04 +00007546 /* Acquire context */
7547 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
7548 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
7549 return win32_error("CryptAcquireContext", NULL);
7550 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007551
Tim Peters4ad82172004-08-30 17:02:04 +00007552 /* Allocate bytes */
Tim Petersd3115382004-08-30 17:36:46 +00007553 result = PyString_FromStringAndSize(NULL, howMany);
7554 if (result != NULL) {
7555 /* Get random data */
7556 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
7557 PyString_AS_STRING(result))) {
7558 Py_DECREF(result);
7559 return win32_error("CryptGenRandom", NULL);
7560 }
Tim Peters4ad82172004-08-30 17:02:04 +00007561 }
Tim Petersd3115382004-08-30 17:36:46 +00007562 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007563}
7564#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007565
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007566static PyMethodDef posix_methods[] = {
7567 {"access", posix_access, METH_VARARGS, posix_access__doc__},
7568#ifdef HAVE_TTYNAME
7569 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
7570#endif
7571 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
7572 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007573#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007574 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007575#endif /* HAVE_CHOWN */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007576#ifdef HAVE_LCHOWN
7577 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
7578#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00007579#ifdef HAVE_CHROOT
7580 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
7581#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007582#ifdef HAVE_CTERMID
Neal Norwitze241ce82003-02-17 18:17:05 +00007583 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007584#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00007585#ifdef HAVE_GETCWD
Neal Norwitze241ce82003-02-17 18:17:05 +00007586 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Walter Dörwald3b918c32002-11-21 20:18:46 +00007587#ifdef Py_USING_UNICODE
Neal Norwitze241ce82003-02-17 18:17:05 +00007588 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00007589#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00007590#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007591#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007592 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007593#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007594 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
7595 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
7596 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007597#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007598 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007599#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007600#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007601 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007602#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007603 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
7604 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
7605 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007606 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007607#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007608 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007609#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007610#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007611 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007612#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007613 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007614#ifdef HAVE_UNAME
Neal Norwitze241ce82003-02-17 18:17:05 +00007615 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007616#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007617 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
7618 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
7619 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007620#ifdef HAVE_TIMES
Neal Norwitze241ce82003-02-17 18:17:05 +00007621 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007622#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007623 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007624#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007625 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
7626 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007627#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00007628#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007629 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
7630 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00007631#if defined(PYOS_OS2)
7632 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
7633 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
7634#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00007635#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007636#ifdef HAVE_FORK1
Neal Norwitze241ce82003-02-17 18:17:05 +00007637 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007638#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007639#ifdef HAVE_FORK
Neal Norwitze241ce82003-02-17 18:17:05 +00007640 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007641#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007642#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Neal Norwitze241ce82003-02-17 18:17:05 +00007643 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007644#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007645#ifdef HAVE_FORKPTY
Neal Norwitze241ce82003-02-17 18:17:05 +00007646 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00007647#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007648#ifdef HAVE_GETEGID
Neal Norwitze241ce82003-02-17 18:17:05 +00007649 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007650#endif /* HAVE_GETEGID */
7651#ifdef HAVE_GETEUID
Neal Norwitze241ce82003-02-17 18:17:05 +00007652 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007653#endif /* HAVE_GETEUID */
7654#ifdef HAVE_GETGID
Neal Norwitze241ce82003-02-17 18:17:05 +00007655 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007656#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00007657#ifdef HAVE_GETGROUPS
Neal Norwitze241ce82003-02-17 18:17:05 +00007658 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007659#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007660 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007661#ifdef HAVE_GETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00007662 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007663#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007664#ifdef HAVE_GETPPID
Neal Norwitze241ce82003-02-17 18:17:05 +00007665 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007666#endif /* HAVE_GETPPID */
7667#ifdef HAVE_GETUID
Neal Norwitze241ce82003-02-17 18:17:05 +00007668 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007669#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007670#ifdef HAVE_GETLOGIN
Neal Norwitze241ce82003-02-17 18:17:05 +00007671 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00007672#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00007673#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007674 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007675#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007676#ifdef HAVE_KILLPG
7677 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
7678#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00007679#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007680 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00007681#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007682#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007683 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007684#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00007685 {"popen2", win32_popen2, METH_VARARGS},
7686 {"popen3", win32_popen3, METH_VARARGS},
7687 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00007688 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007689#else
7690#if defined(PYOS_OS2) && defined(PYCC_GCC)
7691 {"popen2", os2emx_popen2, METH_VARARGS},
7692 {"popen3", os2emx_popen3, METH_VARARGS},
7693 {"popen4", os2emx_popen4, METH_VARARGS},
7694#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00007695#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007696#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007697#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007698 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007699#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007700#ifdef HAVE_SETEUID
7701 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
7702#endif /* HAVE_SETEUID */
7703#ifdef HAVE_SETEGID
7704 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
7705#endif /* HAVE_SETEGID */
7706#ifdef HAVE_SETREUID
7707 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
7708#endif /* HAVE_SETREUID */
7709#ifdef HAVE_SETREGID
7710 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
7711#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007712#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007713 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007714#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007715#ifdef HAVE_SETGROUPS
7716 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
7717#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00007718#ifdef HAVE_GETPGID
7719 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
7720#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007721#ifdef HAVE_SETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00007722 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007723#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007724#ifdef HAVE_WAIT
Neal Norwitze241ce82003-02-17 18:17:05 +00007725 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007726#endif /* HAVE_WAIT */
Neal Norwitz05a45592006-03-20 06:30:08 +00007727#ifdef HAVE_WAIT3
7728 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
7729#endif /* HAVE_WAIT3 */
7730#ifdef HAVE_WAIT4
7731 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
7732#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00007733#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007734 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007735#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007736#ifdef HAVE_GETSID
7737 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
7738#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007739#ifdef HAVE_SETSID
Neal Norwitze241ce82003-02-17 18:17:05 +00007740 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007741#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007742#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007743 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007744#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007745#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007746 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007747#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007748#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007749 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007750#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007751 {"open", posix_open, METH_VARARGS, posix_open__doc__},
7752 {"close", posix_close, METH_VARARGS, posix_close__doc__},
7753 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
7754 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
7755 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
7756 {"read", posix_read, METH_VARARGS, posix_read__doc__},
7757 {"write", posix_write, METH_VARARGS, posix_write__doc__},
7758 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
7759 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00007760 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007761#ifdef HAVE_PIPE
Neal Norwitze241ce82003-02-17 18:17:05 +00007762 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007763#endif
7764#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007765 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007766#endif
Neal Norwitz11690112002-07-30 01:08:28 +00007767#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007768 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
7769#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007770#ifdef HAVE_DEVICE_MACROS
7771 {"major", posix_major, METH_VARARGS, posix_major__doc__},
7772 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
7773 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
7774#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007775#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007776 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007777#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007778#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007779 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007780#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007781#ifdef HAVE_UNSETENV
7782 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
7783#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00007784#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007785 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00007786#endif
Fred Drake4d1e64b2002-04-15 19:40:07 +00007787#ifdef HAVE_FCHDIR
7788 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
7789#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00007790#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007791 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007792#endif
7793#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007794 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007795#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00007796#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00007797#ifdef WCOREDUMP
7798 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
7799#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007800#ifdef WIFCONTINUED
7801 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
7802#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00007803#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007804 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007805#endif /* WIFSTOPPED */
7806#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007807 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007808#endif /* WIFSIGNALED */
7809#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007810 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007811#endif /* WIFEXITED */
7812#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007813 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007814#endif /* WEXITSTATUS */
7815#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007816 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007817#endif /* WTERMSIG */
7818#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007819 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007820#endif /* WSTOPSIG */
7821#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007822#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007823 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007824#endif
7825#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007826 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007827#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00007828#ifdef HAVE_TMPFILE
Neal Norwitze241ce82003-02-17 18:17:05 +00007829 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007830#endif
7831#ifdef HAVE_TEMPNAM
7832 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
7833#endif
7834#ifdef HAVE_TMPNAM
Neal Norwitze241ce82003-02-17 18:17:05 +00007835 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007836#endif
Fred Drakec9680921999-12-13 16:37:25 +00007837#ifdef HAVE_CONFSTR
7838 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
7839#endif
7840#ifdef HAVE_SYSCONF
7841 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
7842#endif
7843#ifdef HAVE_FPATHCONF
7844 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
7845#endif
7846#ifdef HAVE_PATHCONF
7847 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
7848#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007849 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007850#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00007851 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
7852#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007853#ifdef HAVE_GETLOADAVG
Neal Norwitze241ce82003-02-17 18:17:05 +00007854 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00007855#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007856 #ifdef MS_WINDOWS
7857 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
7858 #endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007859 {NULL, NULL} /* Sentinel */
7860};
7861
7862
Barry Warsaw4a342091996-12-19 23:50:02 +00007863static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007864ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00007865{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007866 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00007867}
7868
Guido van Rossumd48f2521997-12-05 22:19:34 +00007869#if defined(PYOS_OS2)
7870/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007871static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007872{
7873 APIRET rc;
7874 ULONG values[QSV_MAX+1];
7875 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00007876 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00007877
7878 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00007879 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007880 Py_END_ALLOW_THREADS
7881
7882 if (rc != NO_ERROR) {
7883 os2_error(rc);
7884 return -1;
7885 }
7886
Fred Drake4d1e64b2002-04-15 19:40:07 +00007887 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
7888 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
7889 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
7890 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
7891 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
7892 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
7893 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007894
7895 switch (values[QSV_VERSION_MINOR]) {
7896 case 0: ver = "2.00"; break;
7897 case 10: ver = "2.10"; break;
7898 case 11: ver = "2.11"; break;
7899 case 30: ver = "3.00"; break;
7900 case 40: ver = "4.00"; break;
7901 case 50: ver = "5.00"; break;
7902 default:
Tim Peters885d4572001-11-28 20:27:42 +00007903 PyOS_snprintf(tmp, sizeof(tmp),
7904 "%d-%d", values[QSV_VERSION_MAJOR],
7905 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007906 ver = &tmp[0];
7907 }
7908
7909 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007910 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007911 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007912
7913 /* Add Indicator of Which Drive was Used to Boot the System */
7914 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
7915 tmp[1] = ':';
7916 tmp[2] = '\0';
7917
Fred Drake4d1e64b2002-04-15 19:40:07 +00007918 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007919}
7920#endif
7921
Barry Warsaw4a342091996-12-19 23:50:02 +00007922static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007923all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00007924{
Guido van Rossum94f6f721999-01-06 18:42:14 +00007925#ifdef F_OK
7926 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007927#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007928#ifdef R_OK
7929 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007930#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007931#ifdef W_OK
7932 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007933#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007934#ifdef X_OK
7935 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007936#endif
Fred Drakec9680921999-12-13 16:37:25 +00007937#ifdef NGROUPS_MAX
7938 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
7939#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007940#ifdef TMP_MAX
7941 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
7942#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007943#ifdef WCONTINUED
7944 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
7945#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007946#ifdef WNOHANG
7947 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007948#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007949#ifdef WUNTRACED
7950 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
7951#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007952#ifdef O_RDONLY
7953 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
7954#endif
7955#ifdef O_WRONLY
7956 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
7957#endif
7958#ifdef O_RDWR
7959 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
7960#endif
7961#ifdef O_NDELAY
7962 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
7963#endif
7964#ifdef O_NONBLOCK
7965 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
7966#endif
7967#ifdef O_APPEND
7968 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
7969#endif
7970#ifdef O_DSYNC
7971 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
7972#endif
7973#ifdef O_RSYNC
7974 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
7975#endif
7976#ifdef O_SYNC
7977 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
7978#endif
7979#ifdef O_NOCTTY
7980 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
7981#endif
7982#ifdef O_CREAT
7983 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
7984#endif
7985#ifdef O_EXCL
7986 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
7987#endif
7988#ifdef O_TRUNC
7989 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
7990#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00007991#ifdef O_BINARY
7992 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
7993#endif
7994#ifdef O_TEXT
7995 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
7996#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00007997#ifdef O_LARGEFILE
7998 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
7999#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00008000#ifdef O_SHLOCK
8001 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
8002#endif
8003#ifdef O_EXLOCK
8004 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
8005#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008006
Tim Peters5aa91602002-01-30 05:46:57 +00008007/* MS Windows */
8008#ifdef O_NOINHERIT
8009 /* Don't inherit in child processes. */
8010 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
8011#endif
8012#ifdef _O_SHORT_LIVED
8013 /* Optimize for short life (keep in memory). */
8014 /* MS forgot to define this one with a non-underscore form too. */
8015 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
8016#endif
8017#ifdef O_TEMPORARY
8018 /* Automatically delete when last handle is closed. */
8019 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
8020#endif
8021#ifdef O_RANDOM
8022 /* Optimize for random access. */
8023 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
8024#endif
8025#ifdef O_SEQUENTIAL
8026 /* Optimize for sequential access. */
8027 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
8028#endif
8029
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008030/* GNU extensions. */
8031#ifdef O_DIRECT
8032 /* Direct disk access. */
8033 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
8034#endif
8035#ifdef O_DIRECTORY
8036 /* Must be a directory. */
8037 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
8038#endif
8039#ifdef O_NOFOLLOW
8040 /* Do not follow links. */
8041 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
8042#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00008043
Barry Warsaw5676bd12003-01-07 20:57:09 +00008044 /* These come from sysexits.h */
8045#ifdef EX_OK
8046 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008047#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008048#ifdef EX_USAGE
8049 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008050#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008051#ifdef EX_DATAERR
8052 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008053#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008054#ifdef EX_NOINPUT
8055 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008056#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008057#ifdef EX_NOUSER
8058 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008059#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008060#ifdef EX_NOHOST
8061 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008062#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008063#ifdef EX_UNAVAILABLE
8064 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008065#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008066#ifdef EX_SOFTWARE
8067 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008068#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008069#ifdef EX_OSERR
8070 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008071#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008072#ifdef EX_OSFILE
8073 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008074#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008075#ifdef EX_CANTCREAT
8076 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008077#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008078#ifdef EX_IOERR
8079 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008080#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008081#ifdef EX_TEMPFAIL
8082 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008083#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008084#ifdef EX_PROTOCOL
8085 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008086#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008087#ifdef EX_NOPERM
8088 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008089#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008090#ifdef EX_CONFIG
8091 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008092#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008093#ifdef EX_NOTFOUND
8094 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008095#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008096
Guido van Rossum246bc171999-02-01 23:54:31 +00008097#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008098#if defined(PYOS_OS2) && defined(PYCC_GCC)
8099 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
8100 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
8101 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
8102 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
8103 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
8104 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
8105 if (ins(d, "P_PM", (long)P_PM)) return -1;
8106 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
8107 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
8108 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
8109 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
8110 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
8111 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
8112 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
8113 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
8114 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
8115 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
8116 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
8117 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
8118 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
8119#else
Guido van Rossum7d385291999-02-16 19:38:04 +00008120 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
8121 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
8122 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
8123 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
8124 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00008125#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008126#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00008127
Guido van Rossumd48f2521997-12-05 22:19:34 +00008128#if defined(PYOS_OS2)
8129 if (insertvalues(d)) return -1;
8130#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008131 return 0;
8132}
8133
8134
Tim Peters5aa91602002-01-30 05:46:57 +00008135#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008136#define INITFUNC initnt
8137#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008138
8139#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008140#define INITFUNC initos2
8141#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008142
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008143#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008144#define INITFUNC initposix
8145#define MODNAME "posix"
8146#endif
8147
Mark Hammondfe51c6d2002-08-02 02:27:13 +00008148PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008149INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00008150{
Fred Drake4d1e64b2002-04-15 19:40:07 +00008151 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00008152
Fred Drake4d1e64b2002-04-15 19:40:07 +00008153 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008154 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00008155 posix__doc__);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00008156 if (m == NULL)
8157 return;
Tim Peters5aa91602002-01-30 05:46:57 +00008158
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008159 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008160 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00008161 Py_XINCREF(v);
8162 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008163 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00008164 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00008165
Fred Drake4d1e64b2002-04-15 19:40:07 +00008166 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00008167 return;
8168
Fred Drake4d1e64b2002-04-15 19:40:07 +00008169 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00008170 return;
8171
Fred Drake4d1e64b2002-04-15 19:40:07 +00008172 Py_INCREF(PyExc_OSError);
8173 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00008174
Guido van Rossumb3d39562000-01-31 18:41:26 +00008175#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00008176 if (posix_putenv_garbage == NULL)
8177 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00008178#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008179
Guido van Rossum14648392001-12-08 18:02:58 +00008180 stat_result_desc.name = MODNAME ".stat_result";
Martin v. Löwisf607bda2002-10-16 18:27:39 +00008181 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
8182 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
8183 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008184 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00008185 structseq_new = StatResultType.tp_new;
8186 StatResultType.tp_new = statresult_new;
Fred Drake4d1e64b2002-04-15 19:40:07 +00008187 Py_INCREF((PyObject*) &StatResultType);
8188 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008189
Guido van Rossum14648392001-12-08 18:02:58 +00008190 statvfs_result_desc.name = MODNAME ".statvfs_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008191 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Fred Drake4d1e64b2002-04-15 19:40:07 +00008192 Py_INCREF((PyObject*) &StatVFSResultType);
8193 PyModule_AddObject(m, "statvfs_result",
8194 (PyObject*) &StatVFSResultType);
Guido van Rossumb6775db1994-08-01 11:34:53 +00008195}