blob: 84e46375f081358fc8313c6db149ec8f80a0237f [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
Neal Norwitz1818ed72006-03-26 00:29:48 +00002004/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2005#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002006#include <sys/resource.h>
2007#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002008
Neal Norwitz1818ed72006-03-26 00:29:48 +00002009
2010#ifdef HAVE_NICE
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 }
Barry Warsaw53699e91996-12-10 23:23:01 +00005771 Py_BEGIN_ALLOW_THREADS
Georg Brandl644b1e72006-03-31 20:27:22 +00005772#if !defined(MS_WINDOWS) && defined(HAVE_FCNTL_H)
Georg Brandl54a188a2006-03-31 20:00:11 +00005773 if (mode[0] == 'a') {
5774 /* try to make sure the O_APPEND flag is set */
5775 int flags;
5776 flags = fcntl(fd, F_GETFL);
5777 if (flags != -1)
5778 fcntl(fd, F_SETFL, flags | O_APPEND);
5779 fp = fdopen(fd, mode);
Thomas Wouters2a9a6b02006-03-31 22:38:19 +00005780 if (fp == NULL && flags != -1)
Georg Brandl54a188a2006-03-31 20:00:11 +00005781 /* restore old mode if fdopen failed */
5782 fcntl(fd, F_SETFL, flags);
5783 } else {
5784 fp = fdopen(fd, mode);
5785 }
Georg Brandl644b1e72006-03-31 20:27:22 +00005786#else
5787 fp = fdopen(fd, mode);
5788#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005789 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005790 if (fp == NULL)
5791 return posix_error();
Guido van Rossumbd6be7a2002-09-15 18:45:46 +00005792 f = PyFile_FromFile(fp, "<fdopen>", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005793 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00005794 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005795 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00005796}
5797
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005798PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005799"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00005800Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005801connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00005802
5803static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00005804posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00005805{
5806 int fd;
5807 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
5808 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00005809 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00005810}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005811
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005812#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005813PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005814"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005815Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005816
Barry Warsaw53699e91996-12-10 23:23:01 +00005817static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005818posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00005819{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005820#if defined(PYOS_OS2)
5821 HFILE read, write;
5822 APIRET rc;
5823
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005824 Py_BEGIN_ALLOW_THREADS
5825 rc = DosCreatePipe( &read, &write, 4096);
5826 Py_END_ALLOW_THREADS
5827 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005828 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005829
5830 return Py_BuildValue("(ii)", read, write);
5831#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005832#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00005833 int fds[2];
5834 int res;
Barry Warsaw53699e91996-12-10 23:23:01 +00005835 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005836 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00005837 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005838 if (res != 0)
5839 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005840 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005841#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00005842 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005843 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00005844 BOOL ok;
Barry Warsaw53699e91996-12-10 23:23:01 +00005845 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005846 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00005847 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00005848 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005849 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00005850 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
5851 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00005852 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005853#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005854#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005855}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005856#endif /* HAVE_PIPE */
5857
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005858
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005859#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005860PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005861"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005862Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005863
Barry Warsaw53699e91996-12-10 23:23:01 +00005864static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005865posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005866{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005867 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005868 int mode = 0666;
5869 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005870 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005871 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005872 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005873 res = mkfifo(filename, mode);
5874 Py_END_ALLOW_THREADS
5875 if (res < 0)
5876 return posix_error();
5877 Py_INCREF(Py_None);
5878 return Py_None;
5879}
5880#endif
5881
5882
Neal Norwitz11690112002-07-30 01:08:28 +00005883#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005884PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00005885"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005886Create a filesystem node (file, device special file or named pipe)\n\
5887named filename. mode specifies both the permissions to use and the\n\
5888type of node to be created, being combined (bitwise OR) with one of\n\
5889S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005890device defines the newly created device special file (probably using\n\
5891os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005892
5893
5894static PyObject *
5895posix_mknod(PyObject *self, PyObject *args)
5896{
5897 char *filename;
5898 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005899 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005900 int res;
Martin v. Löwisd631ebe2002-11-02 17:42:33 +00005901 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00005902 return NULL;
5903 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005904 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00005905 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005906 if (res < 0)
5907 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005908 Py_INCREF(Py_None);
5909 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005910}
5911#endif
5912
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00005913#ifdef HAVE_DEVICE_MACROS
5914PyDoc_STRVAR(posix_major__doc__,
5915"major(device) -> major number\n\
5916Extracts a device major number from a raw device number.");
5917
5918static PyObject *
5919posix_major(PyObject *self, PyObject *args)
5920{
5921 int device;
5922 if (!PyArg_ParseTuple(args, "i:major", &device))
5923 return NULL;
5924 return PyInt_FromLong((long)major(device));
5925}
5926
5927PyDoc_STRVAR(posix_minor__doc__,
5928"minor(device) -> minor number\n\
5929Extracts a device minor number from a raw device number.");
5930
5931static PyObject *
5932posix_minor(PyObject *self, PyObject *args)
5933{
5934 int device;
5935 if (!PyArg_ParseTuple(args, "i:minor", &device))
5936 return NULL;
5937 return PyInt_FromLong((long)minor(device));
5938}
5939
5940PyDoc_STRVAR(posix_makedev__doc__,
5941"makedev(major, minor) -> device number\n\
5942Composes a raw device number from the major and minor device numbers.");
5943
5944static PyObject *
5945posix_makedev(PyObject *self, PyObject *args)
5946{
5947 int major, minor;
5948 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
5949 return NULL;
5950 return PyInt_FromLong((long)makedev(major, minor));
5951}
5952#endif /* device macros */
5953
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005954
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005955#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005956PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005957"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005958Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005959
Barry Warsaw53699e91996-12-10 23:23:01 +00005960static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005961posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005962{
5963 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005964 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005965 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00005966 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005967
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005968 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00005969 return NULL;
5970
5971#if !defined(HAVE_LARGEFILE_SUPPORT)
5972 length = PyInt_AsLong(lenobj);
5973#else
5974 length = PyLong_Check(lenobj) ?
5975 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
5976#endif
5977 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005978 return NULL;
5979
Barry Warsaw53699e91996-12-10 23:23:01 +00005980 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005981 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00005982 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005983 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005984 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005985 return NULL;
5986 }
Barry Warsaw53699e91996-12-10 23:23:01 +00005987 Py_INCREF(Py_None);
5988 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005989}
5990#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005991
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00005992#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005993PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005994"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005995Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005996
Fred Drake762e2061999-08-26 17:23:54 +00005997/* Save putenv() parameters as values here, so we can collect them when they
5998 * get re-set with another call for the same key. */
5999static PyObject *posix_putenv_garbage;
6000
Tim Peters5aa91602002-01-30 05:46:57 +00006001static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006002posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006003{
6004 char *s1, *s2;
6005 char *new;
Fred Drake762e2061999-08-26 17:23:54 +00006006 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00006007 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006008
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006009 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006010 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00006011
6012#if defined(PYOS_OS2)
6013 if (stricmp(s1, "BEGINLIBPATH") == 0) {
6014 APIRET rc;
6015
Guido van Rossumd48f2521997-12-05 22:19:34 +00006016 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
6017 if (rc != NO_ERROR)
6018 return os2_error(rc);
6019
6020 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
6021 APIRET rc;
6022
Guido van Rossumd48f2521997-12-05 22:19:34 +00006023 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
6024 if (rc != NO_ERROR)
6025 return os2_error(rc);
6026 } else {
6027#endif
6028
Fred Drake762e2061999-08-26 17:23:54 +00006029 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00006030 len = strlen(s1) + strlen(s2) + 2;
6031 /* len includes space for a trailing \0; the size arg to
6032 PyString_FromStringAndSize does not count that */
6033 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00006034 if (newstr == NULL)
6035 return PyErr_NoMemory();
6036 new = PyString_AS_STRING(newstr);
Tim Petersc8996f52001-12-03 20:41:00 +00006037 PyOS_snprintf(new, len, "%s=%s", s1, s2);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006038 if (putenv(new)) {
Neal Norwitz4adc9ab2003-02-10 03:10:43 +00006039 Py_DECREF(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006040 posix_error();
6041 return NULL;
6042 }
Fred Drake762e2061999-08-26 17:23:54 +00006043 /* Install the first arg and newstr in posix_putenv_garbage;
6044 * this will cause previous value to be collected. This has to
6045 * happen after the real putenv() call because the old value
6046 * was still accessible until then. */
6047 if (PyDict_SetItem(posix_putenv_garbage,
6048 PyTuple_GET_ITEM(args, 0), newstr)) {
6049 /* really not much we can do; just leak */
6050 PyErr_Clear();
6051 }
6052 else {
6053 Py_DECREF(newstr);
6054 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00006055
6056#if defined(PYOS_OS2)
6057 }
6058#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006059 Py_INCREF(Py_None);
6060 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006061}
Guido van Rossumb6a47161997-09-15 22:54:34 +00006062#endif /* putenv */
6063
Guido van Rossumc524d952001-10-19 01:31:59 +00006064#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006065PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006066"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006067Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00006068
6069static PyObject *
6070posix_unsetenv(PyObject *self, PyObject *args)
6071{
6072 char *s1;
6073
6074 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
6075 return NULL;
6076
6077 unsetenv(s1);
6078
6079 /* Remove the key from posix_putenv_garbage;
6080 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00006081 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00006082 * old value was still accessible until then.
6083 */
6084 if (PyDict_DelItem(posix_putenv_garbage,
6085 PyTuple_GET_ITEM(args, 0))) {
6086 /* really not much we can do; just leak */
6087 PyErr_Clear();
6088 }
6089
6090 Py_INCREF(Py_None);
6091 return Py_None;
6092}
6093#endif /* unsetenv */
6094
Guido van Rossumb6a47161997-09-15 22:54:34 +00006095#ifdef HAVE_STRERROR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006096PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006097"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006098Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00006099
Guido van Rossumf68d8e52001-04-14 17:55:09 +00006100static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006101posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00006102{
6103 int code;
6104 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006105 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00006106 return NULL;
6107 message = strerror(code);
6108 if (message == NULL) {
6109 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00006110 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00006111 return NULL;
6112 }
6113 return PyString_FromString(message);
6114}
6115#endif /* strerror */
6116
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006117
Guido van Rossumc9641791998-08-04 15:26:23 +00006118#ifdef HAVE_SYS_WAIT_H
6119
Fred Drake106c1a02002-04-23 15:58:02 +00006120#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006121PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006122"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006123Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00006124
6125static PyObject *
6126posix_WCOREDUMP(PyObject *self, PyObject *args)
6127{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006128 WAIT_TYPE status;
6129 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006130
Neal Norwitzd5a37542006-03-20 06:48:34 +00006131 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00006132 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006133
6134 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006135}
6136#endif /* WCOREDUMP */
6137
6138#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006139PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006140"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006141Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006142job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00006143
6144static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006145posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00006146{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006147 WAIT_TYPE status;
6148 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006149
Neal Norwitzd5a37542006-03-20 06:48:34 +00006150 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00006151 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006152
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006153 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006154}
6155#endif /* WIFCONTINUED */
6156
Guido van Rossumc9641791998-08-04 15:26:23 +00006157#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006158PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006159"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006160Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006161
6162static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006163posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006164{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006165 WAIT_TYPE status;
6166 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006167
Neal Norwitzd5a37542006-03-20 06:48:34 +00006168 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006169 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006170
Fred Drake106c1a02002-04-23 15:58:02 +00006171 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006172}
6173#endif /* WIFSTOPPED */
6174
6175#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006176PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006177"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006178Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006179
6180static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006181posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006182{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006183 WAIT_TYPE status;
6184 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006185
Neal Norwitzd5a37542006-03-20 06:48:34 +00006186 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006187 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006188
Fred Drake106c1a02002-04-23 15:58:02 +00006189 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006190}
6191#endif /* WIFSIGNALED */
6192
6193#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006194PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006195"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006196Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006197system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006198
6199static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006200posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006201{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006202 WAIT_TYPE status;
6203 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006204
Neal Norwitzd5a37542006-03-20 06:48:34 +00006205 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006206 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006207
Fred Drake106c1a02002-04-23 15:58:02 +00006208 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006209}
6210#endif /* WIFEXITED */
6211
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006212#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006213PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006214"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006215Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006216
6217static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006218posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006219{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006220 WAIT_TYPE status;
6221 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006222
Neal Norwitzd5a37542006-03-20 06:48:34 +00006223 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006224 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006225
Guido van Rossumc9641791998-08-04 15:26:23 +00006226 return Py_BuildValue("i", WEXITSTATUS(status));
6227}
6228#endif /* WEXITSTATUS */
6229
6230#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006231PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006232"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006233Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006234value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006235
6236static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006237posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006238{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006239 WAIT_TYPE status;
6240 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006241
Neal Norwitzd5a37542006-03-20 06:48:34 +00006242 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006243 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006244
Guido van Rossumc9641791998-08-04 15:26:23 +00006245 return Py_BuildValue("i", WTERMSIG(status));
6246}
6247#endif /* WTERMSIG */
6248
6249#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006250PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006251"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006252Return the signal that stopped the process that provided\n\
6253the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006254
6255static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006256posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006257{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006258 WAIT_TYPE status;
6259 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006260
Neal Norwitzd5a37542006-03-20 06:48:34 +00006261 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006262 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006263
Guido van Rossumc9641791998-08-04 15:26:23 +00006264 return Py_BuildValue("i", WSTOPSIG(status));
6265}
6266#endif /* WSTOPSIG */
6267
6268#endif /* HAVE_SYS_WAIT_H */
6269
6270
Guido van Rossum94f6f721999-01-06 18:42:14 +00006271#if defined(HAVE_FSTATVFS)
Guido van Rossumd5753e11999-10-19 13:29:23 +00006272#ifdef _SCO_DS
6273/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
6274 needed definitions in sys/statvfs.h */
6275#define _SVID3
6276#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006277#include <sys/statvfs.h>
6278
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006279static PyObject*
6280_pystatvfs_fromstructstatvfs(struct statvfs st) {
6281 PyObject *v = PyStructSequence_New(&StatVFSResultType);
6282 if (v == NULL)
6283 return NULL;
6284
6285#if !defined(HAVE_LARGEFILE_SUPPORT)
6286 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6287 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
6288 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
6289 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
6290 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
6291 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
6292 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
6293 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
6294 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6295 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6296#else
6297 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6298 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00006299 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006300 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00006301 PyStructSequence_SET_ITEM(v, 3,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006302 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006303 PyStructSequence_SET_ITEM(v, 4,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006304 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00006305 PyStructSequence_SET_ITEM(v, 5,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006306 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00006307 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006308 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00006309 PyStructSequence_SET_ITEM(v, 7,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006310 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006311 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6312 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6313#endif
6314
6315 return v;
6316}
6317
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006318PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006319"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006320Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006321
6322static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006323posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006324{
6325 int fd, res;
6326 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006327
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006328 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006329 return NULL;
6330 Py_BEGIN_ALLOW_THREADS
6331 res = fstatvfs(fd, &st);
6332 Py_END_ALLOW_THREADS
6333 if (res != 0)
6334 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006335
6336 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006337}
6338#endif /* HAVE_FSTATVFS */
6339
6340
6341#if defined(HAVE_STATVFS)
6342#include <sys/statvfs.h>
6343
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006344PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006345"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006346Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006347
6348static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006349posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006350{
6351 char *path;
6352 int res;
6353 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006354 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006355 return NULL;
6356 Py_BEGIN_ALLOW_THREADS
6357 res = statvfs(path, &st);
6358 Py_END_ALLOW_THREADS
6359 if (res != 0)
6360 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006361
6362 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006363}
6364#endif /* HAVE_STATVFS */
6365
6366
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006367#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006368PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006369"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006370Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00006371The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006372or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006373
6374static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006375posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006376{
6377 PyObject *result = NULL;
6378 char *dir = NULL;
6379 char *pfx = NULL;
6380 char *name;
6381
6382 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
6383 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00006384
6385 if (PyErr_Warn(PyExc_RuntimeWarning,
6386 "tempnam is a potential security risk to your program") < 0)
6387 return NULL;
6388
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006389#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00006390 name = _tempnam(dir, pfx);
6391#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006392 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00006393#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006394 if (name == NULL)
6395 return PyErr_NoMemory();
6396 result = PyString_FromString(name);
6397 free(name);
6398 return result;
6399}
Guido van Rossumd371ff11999-01-25 16:12:23 +00006400#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006401
6402
6403#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006404PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006405"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006406Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006407
6408static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006409posix_tmpfile(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006410{
6411 FILE *fp;
6412
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006413 fp = tmpfile();
6414 if (fp == NULL)
6415 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00006416 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006417}
6418#endif
6419
6420
6421#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006422PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006423"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006424Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006425
6426static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006427posix_tmpnam(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006428{
6429 char buffer[L_tmpnam];
6430 char *name;
6431
Skip Montanaro95618b52001-08-18 18:52:10 +00006432 if (PyErr_Warn(PyExc_RuntimeWarning,
6433 "tmpnam is a potential security risk to your program") < 0)
6434 return NULL;
6435
Greg Wardb48bc172000-03-01 21:51:56 +00006436#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006437 name = tmpnam_r(buffer);
6438#else
6439 name = tmpnam(buffer);
6440#endif
6441 if (name == NULL) {
Neal Norwitzd1e0ef62006-03-20 04:08:12 +00006442 PyObject *err = Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00006443#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006444 "unexpected NULL from tmpnam_r"
6445#else
6446 "unexpected NULL from tmpnam"
6447#endif
Neal Norwitzd1e0ef62006-03-20 04:08:12 +00006448 );
6449 PyErr_SetObject(PyExc_OSError, err);
6450 Py_XDECREF(err);
6451 return NULL;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006452 }
6453 return PyString_FromString(buffer);
6454}
6455#endif
6456
6457
Fred Drakec9680921999-12-13 16:37:25 +00006458/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
6459 * It maps strings representing configuration variable names to
6460 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00006461 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00006462 * rarely-used constants. There are three separate tables that use
6463 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00006464 *
6465 * This code is always included, even if none of the interfaces that
6466 * need it are included. The #if hackery needed to avoid it would be
6467 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00006468 */
6469struct constdef {
6470 char *name;
6471 long value;
6472};
6473
Fred Drake12c6e2d1999-12-14 21:25:03 +00006474static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006475conv_confname(PyObject *arg, int *valuep, struct constdef *table,
6476 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006477{
6478 if (PyInt_Check(arg)) {
6479 *valuep = PyInt_AS_LONG(arg);
6480 return 1;
6481 }
6482 if (PyString_Check(arg)) {
6483 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00006484 size_t lo = 0;
6485 size_t mid;
6486 size_t hi = tablesize;
6487 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006488 char *confname = PyString_AS_STRING(arg);
6489 while (lo < hi) {
6490 mid = (lo + hi) / 2;
6491 cmp = strcmp(confname, table[mid].name);
6492 if (cmp < 0)
6493 hi = mid;
6494 else if (cmp > 0)
6495 lo = mid + 1;
6496 else {
6497 *valuep = table[mid].value;
6498 return 1;
6499 }
6500 }
6501 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
6502 }
6503 else
6504 PyErr_SetString(PyExc_TypeError,
6505 "configuration names must be strings or integers");
6506 return 0;
6507}
6508
6509
6510#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
6511static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006512#ifdef _PC_ABI_AIO_XFER_MAX
6513 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
6514#endif
6515#ifdef _PC_ABI_ASYNC_IO
6516 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
6517#endif
Fred Drakec9680921999-12-13 16:37:25 +00006518#ifdef _PC_ASYNC_IO
6519 {"PC_ASYNC_IO", _PC_ASYNC_IO},
6520#endif
6521#ifdef _PC_CHOWN_RESTRICTED
6522 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
6523#endif
6524#ifdef _PC_FILESIZEBITS
6525 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
6526#endif
6527#ifdef _PC_LAST
6528 {"PC_LAST", _PC_LAST},
6529#endif
6530#ifdef _PC_LINK_MAX
6531 {"PC_LINK_MAX", _PC_LINK_MAX},
6532#endif
6533#ifdef _PC_MAX_CANON
6534 {"PC_MAX_CANON", _PC_MAX_CANON},
6535#endif
6536#ifdef _PC_MAX_INPUT
6537 {"PC_MAX_INPUT", _PC_MAX_INPUT},
6538#endif
6539#ifdef _PC_NAME_MAX
6540 {"PC_NAME_MAX", _PC_NAME_MAX},
6541#endif
6542#ifdef _PC_NO_TRUNC
6543 {"PC_NO_TRUNC", _PC_NO_TRUNC},
6544#endif
6545#ifdef _PC_PATH_MAX
6546 {"PC_PATH_MAX", _PC_PATH_MAX},
6547#endif
6548#ifdef _PC_PIPE_BUF
6549 {"PC_PIPE_BUF", _PC_PIPE_BUF},
6550#endif
6551#ifdef _PC_PRIO_IO
6552 {"PC_PRIO_IO", _PC_PRIO_IO},
6553#endif
6554#ifdef _PC_SOCK_MAXBUF
6555 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
6556#endif
6557#ifdef _PC_SYNC_IO
6558 {"PC_SYNC_IO", _PC_SYNC_IO},
6559#endif
6560#ifdef _PC_VDISABLE
6561 {"PC_VDISABLE", _PC_VDISABLE},
6562#endif
6563};
6564
Fred Drakec9680921999-12-13 16:37:25 +00006565static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006566conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006567{
6568 return conv_confname(arg, valuep, posix_constants_pathconf,
6569 sizeof(posix_constants_pathconf)
6570 / sizeof(struct constdef));
6571}
6572#endif
6573
6574#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006575PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006576"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006577Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006578If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006579
6580static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006581posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006582{
6583 PyObject *result = NULL;
6584 int name, fd;
6585
Fred Drake12c6e2d1999-12-14 21:25:03 +00006586 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
6587 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00006588 long limit;
6589
6590 errno = 0;
6591 limit = fpathconf(fd, name);
6592 if (limit == -1 && errno != 0)
6593 posix_error();
6594 else
6595 result = PyInt_FromLong(limit);
6596 }
6597 return result;
6598}
6599#endif
6600
6601
6602#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006603PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006604"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006605Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006606If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006607
6608static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006609posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006610{
6611 PyObject *result = NULL;
6612 int name;
6613 char *path;
6614
6615 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
6616 conv_path_confname, &name)) {
6617 long limit;
6618
6619 errno = 0;
6620 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006621 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00006622 if (errno == EINVAL)
6623 /* could be a path or name problem */
6624 posix_error();
6625 else
6626 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006627 }
Fred Drakec9680921999-12-13 16:37:25 +00006628 else
6629 result = PyInt_FromLong(limit);
6630 }
6631 return result;
6632}
6633#endif
6634
6635#ifdef HAVE_CONFSTR
6636static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006637#ifdef _CS_ARCHITECTURE
6638 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
6639#endif
6640#ifdef _CS_HOSTNAME
6641 {"CS_HOSTNAME", _CS_HOSTNAME},
6642#endif
6643#ifdef _CS_HW_PROVIDER
6644 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
6645#endif
6646#ifdef _CS_HW_SERIAL
6647 {"CS_HW_SERIAL", _CS_HW_SERIAL},
6648#endif
6649#ifdef _CS_INITTAB_NAME
6650 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
6651#endif
Fred Drakec9680921999-12-13 16:37:25 +00006652#ifdef _CS_LFS64_CFLAGS
6653 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
6654#endif
6655#ifdef _CS_LFS64_LDFLAGS
6656 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
6657#endif
6658#ifdef _CS_LFS64_LIBS
6659 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
6660#endif
6661#ifdef _CS_LFS64_LINTFLAGS
6662 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
6663#endif
6664#ifdef _CS_LFS_CFLAGS
6665 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
6666#endif
6667#ifdef _CS_LFS_LDFLAGS
6668 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
6669#endif
6670#ifdef _CS_LFS_LIBS
6671 {"CS_LFS_LIBS", _CS_LFS_LIBS},
6672#endif
6673#ifdef _CS_LFS_LINTFLAGS
6674 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
6675#endif
Fred Draked86ed291999-12-15 15:34:33 +00006676#ifdef _CS_MACHINE
6677 {"CS_MACHINE", _CS_MACHINE},
6678#endif
Fred Drakec9680921999-12-13 16:37:25 +00006679#ifdef _CS_PATH
6680 {"CS_PATH", _CS_PATH},
6681#endif
Fred Draked86ed291999-12-15 15:34:33 +00006682#ifdef _CS_RELEASE
6683 {"CS_RELEASE", _CS_RELEASE},
6684#endif
6685#ifdef _CS_SRPC_DOMAIN
6686 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
6687#endif
6688#ifdef _CS_SYSNAME
6689 {"CS_SYSNAME", _CS_SYSNAME},
6690#endif
6691#ifdef _CS_VERSION
6692 {"CS_VERSION", _CS_VERSION},
6693#endif
Fred Drakec9680921999-12-13 16:37:25 +00006694#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
6695 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
6696#endif
6697#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
6698 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
6699#endif
6700#ifdef _CS_XBS5_ILP32_OFF32_LIBS
6701 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
6702#endif
6703#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
6704 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
6705#endif
6706#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
6707 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
6708#endif
6709#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
6710 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
6711#endif
6712#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
6713 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
6714#endif
6715#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
6716 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
6717#endif
6718#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
6719 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
6720#endif
6721#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
6722 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
6723#endif
6724#ifdef _CS_XBS5_LP64_OFF64_LIBS
6725 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
6726#endif
6727#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
6728 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
6729#endif
6730#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
6731 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
6732#endif
6733#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
6734 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
6735#endif
6736#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
6737 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
6738#endif
6739#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
6740 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
6741#endif
Fred Draked86ed291999-12-15 15:34:33 +00006742#ifdef _MIPS_CS_AVAIL_PROCESSORS
6743 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
6744#endif
6745#ifdef _MIPS_CS_BASE
6746 {"MIPS_CS_BASE", _MIPS_CS_BASE},
6747#endif
6748#ifdef _MIPS_CS_HOSTID
6749 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
6750#endif
6751#ifdef _MIPS_CS_HW_NAME
6752 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
6753#endif
6754#ifdef _MIPS_CS_NUM_PROCESSORS
6755 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
6756#endif
6757#ifdef _MIPS_CS_OSREL_MAJ
6758 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
6759#endif
6760#ifdef _MIPS_CS_OSREL_MIN
6761 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
6762#endif
6763#ifdef _MIPS_CS_OSREL_PATCH
6764 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
6765#endif
6766#ifdef _MIPS_CS_OS_NAME
6767 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
6768#endif
6769#ifdef _MIPS_CS_OS_PROVIDER
6770 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
6771#endif
6772#ifdef _MIPS_CS_PROCESSORS
6773 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
6774#endif
6775#ifdef _MIPS_CS_SERIAL
6776 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
6777#endif
6778#ifdef _MIPS_CS_VENDOR
6779 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
6780#endif
Fred Drakec9680921999-12-13 16:37:25 +00006781};
6782
6783static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006784conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006785{
6786 return conv_confname(arg, valuep, posix_constants_confstr,
6787 sizeof(posix_constants_confstr)
6788 / sizeof(struct constdef));
6789}
6790
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006791PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006792"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006793Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00006794
6795static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006796posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006797{
6798 PyObject *result = NULL;
6799 int name;
6800 char buffer[64];
6801
6802 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
6803 int len = confstr(name, buffer, sizeof(buffer));
6804
Fred Drakec9680921999-12-13 16:37:25 +00006805 errno = 0;
6806 if (len == 0) {
6807 if (errno != 0)
6808 posix_error();
6809 else
6810 result = PyString_FromString("");
6811 }
6812 else {
6813 if (len >= sizeof(buffer)) {
6814 result = PyString_FromStringAndSize(NULL, len);
6815 if (result != NULL)
6816 confstr(name, PyString_AS_STRING(result), len+1);
6817 }
6818 else
6819 result = PyString_FromString(buffer);
6820 }
6821 }
6822 return result;
6823}
6824#endif
6825
6826
6827#ifdef HAVE_SYSCONF
6828static struct constdef posix_constants_sysconf[] = {
6829#ifdef _SC_2_CHAR_TERM
6830 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
6831#endif
6832#ifdef _SC_2_C_BIND
6833 {"SC_2_C_BIND", _SC_2_C_BIND},
6834#endif
6835#ifdef _SC_2_C_DEV
6836 {"SC_2_C_DEV", _SC_2_C_DEV},
6837#endif
6838#ifdef _SC_2_C_VERSION
6839 {"SC_2_C_VERSION", _SC_2_C_VERSION},
6840#endif
6841#ifdef _SC_2_FORT_DEV
6842 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
6843#endif
6844#ifdef _SC_2_FORT_RUN
6845 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
6846#endif
6847#ifdef _SC_2_LOCALEDEF
6848 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
6849#endif
6850#ifdef _SC_2_SW_DEV
6851 {"SC_2_SW_DEV", _SC_2_SW_DEV},
6852#endif
6853#ifdef _SC_2_UPE
6854 {"SC_2_UPE", _SC_2_UPE},
6855#endif
6856#ifdef _SC_2_VERSION
6857 {"SC_2_VERSION", _SC_2_VERSION},
6858#endif
Fred Draked86ed291999-12-15 15:34:33 +00006859#ifdef _SC_ABI_ASYNCHRONOUS_IO
6860 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
6861#endif
6862#ifdef _SC_ACL
6863 {"SC_ACL", _SC_ACL},
6864#endif
Fred Drakec9680921999-12-13 16:37:25 +00006865#ifdef _SC_AIO_LISTIO_MAX
6866 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
6867#endif
Fred Drakec9680921999-12-13 16:37:25 +00006868#ifdef _SC_AIO_MAX
6869 {"SC_AIO_MAX", _SC_AIO_MAX},
6870#endif
6871#ifdef _SC_AIO_PRIO_DELTA_MAX
6872 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
6873#endif
6874#ifdef _SC_ARG_MAX
6875 {"SC_ARG_MAX", _SC_ARG_MAX},
6876#endif
6877#ifdef _SC_ASYNCHRONOUS_IO
6878 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
6879#endif
6880#ifdef _SC_ATEXIT_MAX
6881 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
6882#endif
Fred Draked86ed291999-12-15 15:34:33 +00006883#ifdef _SC_AUDIT
6884 {"SC_AUDIT", _SC_AUDIT},
6885#endif
Fred Drakec9680921999-12-13 16:37:25 +00006886#ifdef _SC_AVPHYS_PAGES
6887 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
6888#endif
6889#ifdef _SC_BC_BASE_MAX
6890 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
6891#endif
6892#ifdef _SC_BC_DIM_MAX
6893 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
6894#endif
6895#ifdef _SC_BC_SCALE_MAX
6896 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
6897#endif
6898#ifdef _SC_BC_STRING_MAX
6899 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
6900#endif
Fred Draked86ed291999-12-15 15:34:33 +00006901#ifdef _SC_CAP
6902 {"SC_CAP", _SC_CAP},
6903#endif
Fred Drakec9680921999-12-13 16:37:25 +00006904#ifdef _SC_CHARCLASS_NAME_MAX
6905 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
6906#endif
6907#ifdef _SC_CHAR_BIT
6908 {"SC_CHAR_BIT", _SC_CHAR_BIT},
6909#endif
6910#ifdef _SC_CHAR_MAX
6911 {"SC_CHAR_MAX", _SC_CHAR_MAX},
6912#endif
6913#ifdef _SC_CHAR_MIN
6914 {"SC_CHAR_MIN", _SC_CHAR_MIN},
6915#endif
6916#ifdef _SC_CHILD_MAX
6917 {"SC_CHILD_MAX", _SC_CHILD_MAX},
6918#endif
6919#ifdef _SC_CLK_TCK
6920 {"SC_CLK_TCK", _SC_CLK_TCK},
6921#endif
6922#ifdef _SC_COHER_BLKSZ
6923 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
6924#endif
6925#ifdef _SC_COLL_WEIGHTS_MAX
6926 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
6927#endif
6928#ifdef _SC_DCACHE_ASSOC
6929 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
6930#endif
6931#ifdef _SC_DCACHE_BLKSZ
6932 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
6933#endif
6934#ifdef _SC_DCACHE_LINESZ
6935 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
6936#endif
6937#ifdef _SC_DCACHE_SZ
6938 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
6939#endif
6940#ifdef _SC_DCACHE_TBLKSZ
6941 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
6942#endif
6943#ifdef _SC_DELAYTIMER_MAX
6944 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
6945#endif
6946#ifdef _SC_EQUIV_CLASS_MAX
6947 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
6948#endif
6949#ifdef _SC_EXPR_NEST_MAX
6950 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
6951#endif
6952#ifdef _SC_FSYNC
6953 {"SC_FSYNC", _SC_FSYNC},
6954#endif
6955#ifdef _SC_GETGR_R_SIZE_MAX
6956 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
6957#endif
6958#ifdef _SC_GETPW_R_SIZE_MAX
6959 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
6960#endif
6961#ifdef _SC_ICACHE_ASSOC
6962 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
6963#endif
6964#ifdef _SC_ICACHE_BLKSZ
6965 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
6966#endif
6967#ifdef _SC_ICACHE_LINESZ
6968 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
6969#endif
6970#ifdef _SC_ICACHE_SZ
6971 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
6972#endif
Fred Draked86ed291999-12-15 15:34:33 +00006973#ifdef _SC_INF
6974 {"SC_INF", _SC_INF},
6975#endif
Fred Drakec9680921999-12-13 16:37:25 +00006976#ifdef _SC_INT_MAX
6977 {"SC_INT_MAX", _SC_INT_MAX},
6978#endif
6979#ifdef _SC_INT_MIN
6980 {"SC_INT_MIN", _SC_INT_MIN},
6981#endif
6982#ifdef _SC_IOV_MAX
6983 {"SC_IOV_MAX", _SC_IOV_MAX},
6984#endif
Fred Draked86ed291999-12-15 15:34:33 +00006985#ifdef _SC_IP_SECOPTS
6986 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
6987#endif
Fred Drakec9680921999-12-13 16:37:25 +00006988#ifdef _SC_JOB_CONTROL
6989 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
6990#endif
Fred Draked86ed291999-12-15 15:34:33 +00006991#ifdef _SC_KERN_POINTERS
6992 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
6993#endif
6994#ifdef _SC_KERN_SIM
6995 {"SC_KERN_SIM", _SC_KERN_SIM},
6996#endif
Fred Drakec9680921999-12-13 16:37:25 +00006997#ifdef _SC_LINE_MAX
6998 {"SC_LINE_MAX", _SC_LINE_MAX},
6999#endif
7000#ifdef _SC_LOGIN_NAME_MAX
7001 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
7002#endif
7003#ifdef _SC_LOGNAME_MAX
7004 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
7005#endif
7006#ifdef _SC_LONG_BIT
7007 {"SC_LONG_BIT", _SC_LONG_BIT},
7008#endif
Fred Draked86ed291999-12-15 15:34:33 +00007009#ifdef _SC_MAC
7010 {"SC_MAC", _SC_MAC},
7011#endif
Fred Drakec9680921999-12-13 16:37:25 +00007012#ifdef _SC_MAPPED_FILES
7013 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
7014#endif
7015#ifdef _SC_MAXPID
7016 {"SC_MAXPID", _SC_MAXPID},
7017#endif
7018#ifdef _SC_MB_LEN_MAX
7019 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
7020#endif
7021#ifdef _SC_MEMLOCK
7022 {"SC_MEMLOCK", _SC_MEMLOCK},
7023#endif
7024#ifdef _SC_MEMLOCK_RANGE
7025 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
7026#endif
7027#ifdef _SC_MEMORY_PROTECTION
7028 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
7029#endif
7030#ifdef _SC_MESSAGE_PASSING
7031 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
7032#endif
Fred Draked86ed291999-12-15 15:34:33 +00007033#ifdef _SC_MMAP_FIXED_ALIGNMENT
7034 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
7035#endif
Fred Drakec9680921999-12-13 16:37:25 +00007036#ifdef _SC_MQ_OPEN_MAX
7037 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
7038#endif
7039#ifdef _SC_MQ_PRIO_MAX
7040 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
7041#endif
Fred Draked86ed291999-12-15 15:34:33 +00007042#ifdef _SC_NACLS_MAX
7043 {"SC_NACLS_MAX", _SC_NACLS_MAX},
7044#endif
Fred Drakec9680921999-12-13 16:37:25 +00007045#ifdef _SC_NGROUPS_MAX
7046 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
7047#endif
7048#ifdef _SC_NL_ARGMAX
7049 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
7050#endif
7051#ifdef _SC_NL_LANGMAX
7052 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
7053#endif
7054#ifdef _SC_NL_MSGMAX
7055 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
7056#endif
7057#ifdef _SC_NL_NMAX
7058 {"SC_NL_NMAX", _SC_NL_NMAX},
7059#endif
7060#ifdef _SC_NL_SETMAX
7061 {"SC_NL_SETMAX", _SC_NL_SETMAX},
7062#endif
7063#ifdef _SC_NL_TEXTMAX
7064 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
7065#endif
7066#ifdef _SC_NPROCESSORS_CONF
7067 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
7068#endif
7069#ifdef _SC_NPROCESSORS_ONLN
7070 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
7071#endif
Fred Draked86ed291999-12-15 15:34:33 +00007072#ifdef _SC_NPROC_CONF
7073 {"SC_NPROC_CONF", _SC_NPROC_CONF},
7074#endif
7075#ifdef _SC_NPROC_ONLN
7076 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
7077#endif
Fred Drakec9680921999-12-13 16:37:25 +00007078#ifdef _SC_NZERO
7079 {"SC_NZERO", _SC_NZERO},
7080#endif
7081#ifdef _SC_OPEN_MAX
7082 {"SC_OPEN_MAX", _SC_OPEN_MAX},
7083#endif
7084#ifdef _SC_PAGESIZE
7085 {"SC_PAGESIZE", _SC_PAGESIZE},
7086#endif
7087#ifdef _SC_PAGE_SIZE
7088 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
7089#endif
7090#ifdef _SC_PASS_MAX
7091 {"SC_PASS_MAX", _SC_PASS_MAX},
7092#endif
7093#ifdef _SC_PHYS_PAGES
7094 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
7095#endif
7096#ifdef _SC_PII
7097 {"SC_PII", _SC_PII},
7098#endif
7099#ifdef _SC_PII_INTERNET
7100 {"SC_PII_INTERNET", _SC_PII_INTERNET},
7101#endif
7102#ifdef _SC_PII_INTERNET_DGRAM
7103 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
7104#endif
7105#ifdef _SC_PII_INTERNET_STREAM
7106 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
7107#endif
7108#ifdef _SC_PII_OSI
7109 {"SC_PII_OSI", _SC_PII_OSI},
7110#endif
7111#ifdef _SC_PII_OSI_CLTS
7112 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
7113#endif
7114#ifdef _SC_PII_OSI_COTS
7115 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
7116#endif
7117#ifdef _SC_PII_OSI_M
7118 {"SC_PII_OSI_M", _SC_PII_OSI_M},
7119#endif
7120#ifdef _SC_PII_SOCKET
7121 {"SC_PII_SOCKET", _SC_PII_SOCKET},
7122#endif
7123#ifdef _SC_PII_XTI
7124 {"SC_PII_XTI", _SC_PII_XTI},
7125#endif
7126#ifdef _SC_POLL
7127 {"SC_POLL", _SC_POLL},
7128#endif
7129#ifdef _SC_PRIORITIZED_IO
7130 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
7131#endif
7132#ifdef _SC_PRIORITY_SCHEDULING
7133 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
7134#endif
7135#ifdef _SC_REALTIME_SIGNALS
7136 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
7137#endif
7138#ifdef _SC_RE_DUP_MAX
7139 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
7140#endif
7141#ifdef _SC_RTSIG_MAX
7142 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
7143#endif
7144#ifdef _SC_SAVED_IDS
7145 {"SC_SAVED_IDS", _SC_SAVED_IDS},
7146#endif
7147#ifdef _SC_SCHAR_MAX
7148 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
7149#endif
7150#ifdef _SC_SCHAR_MIN
7151 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
7152#endif
7153#ifdef _SC_SELECT
7154 {"SC_SELECT", _SC_SELECT},
7155#endif
7156#ifdef _SC_SEMAPHORES
7157 {"SC_SEMAPHORES", _SC_SEMAPHORES},
7158#endif
7159#ifdef _SC_SEM_NSEMS_MAX
7160 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
7161#endif
7162#ifdef _SC_SEM_VALUE_MAX
7163 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
7164#endif
7165#ifdef _SC_SHARED_MEMORY_OBJECTS
7166 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
7167#endif
7168#ifdef _SC_SHRT_MAX
7169 {"SC_SHRT_MAX", _SC_SHRT_MAX},
7170#endif
7171#ifdef _SC_SHRT_MIN
7172 {"SC_SHRT_MIN", _SC_SHRT_MIN},
7173#endif
7174#ifdef _SC_SIGQUEUE_MAX
7175 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
7176#endif
7177#ifdef _SC_SIGRT_MAX
7178 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
7179#endif
7180#ifdef _SC_SIGRT_MIN
7181 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
7182#endif
Fred Draked86ed291999-12-15 15:34:33 +00007183#ifdef _SC_SOFTPOWER
7184 {"SC_SOFTPOWER", _SC_SOFTPOWER},
7185#endif
Fred Drakec9680921999-12-13 16:37:25 +00007186#ifdef _SC_SPLIT_CACHE
7187 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
7188#endif
7189#ifdef _SC_SSIZE_MAX
7190 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
7191#endif
7192#ifdef _SC_STACK_PROT
7193 {"SC_STACK_PROT", _SC_STACK_PROT},
7194#endif
7195#ifdef _SC_STREAM_MAX
7196 {"SC_STREAM_MAX", _SC_STREAM_MAX},
7197#endif
7198#ifdef _SC_SYNCHRONIZED_IO
7199 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
7200#endif
7201#ifdef _SC_THREADS
7202 {"SC_THREADS", _SC_THREADS},
7203#endif
7204#ifdef _SC_THREAD_ATTR_STACKADDR
7205 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
7206#endif
7207#ifdef _SC_THREAD_ATTR_STACKSIZE
7208 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
7209#endif
7210#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
7211 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
7212#endif
7213#ifdef _SC_THREAD_KEYS_MAX
7214 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
7215#endif
7216#ifdef _SC_THREAD_PRIORITY_SCHEDULING
7217 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
7218#endif
7219#ifdef _SC_THREAD_PRIO_INHERIT
7220 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
7221#endif
7222#ifdef _SC_THREAD_PRIO_PROTECT
7223 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
7224#endif
7225#ifdef _SC_THREAD_PROCESS_SHARED
7226 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
7227#endif
7228#ifdef _SC_THREAD_SAFE_FUNCTIONS
7229 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
7230#endif
7231#ifdef _SC_THREAD_STACK_MIN
7232 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
7233#endif
7234#ifdef _SC_THREAD_THREADS_MAX
7235 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
7236#endif
7237#ifdef _SC_TIMERS
7238 {"SC_TIMERS", _SC_TIMERS},
7239#endif
7240#ifdef _SC_TIMER_MAX
7241 {"SC_TIMER_MAX", _SC_TIMER_MAX},
7242#endif
7243#ifdef _SC_TTY_NAME_MAX
7244 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
7245#endif
7246#ifdef _SC_TZNAME_MAX
7247 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
7248#endif
7249#ifdef _SC_T_IOV_MAX
7250 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
7251#endif
7252#ifdef _SC_UCHAR_MAX
7253 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
7254#endif
7255#ifdef _SC_UINT_MAX
7256 {"SC_UINT_MAX", _SC_UINT_MAX},
7257#endif
7258#ifdef _SC_UIO_MAXIOV
7259 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
7260#endif
7261#ifdef _SC_ULONG_MAX
7262 {"SC_ULONG_MAX", _SC_ULONG_MAX},
7263#endif
7264#ifdef _SC_USHRT_MAX
7265 {"SC_USHRT_MAX", _SC_USHRT_MAX},
7266#endif
7267#ifdef _SC_VERSION
7268 {"SC_VERSION", _SC_VERSION},
7269#endif
7270#ifdef _SC_WORD_BIT
7271 {"SC_WORD_BIT", _SC_WORD_BIT},
7272#endif
7273#ifdef _SC_XBS5_ILP32_OFF32
7274 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
7275#endif
7276#ifdef _SC_XBS5_ILP32_OFFBIG
7277 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
7278#endif
7279#ifdef _SC_XBS5_LP64_OFF64
7280 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
7281#endif
7282#ifdef _SC_XBS5_LPBIG_OFFBIG
7283 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
7284#endif
7285#ifdef _SC_XOPEN_CRYPT
7286 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
7287#endif
7288#ifdef _SC_XOPEN_ENH_I18N
7289 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
7290#endif
7291#ifdef _SC_XOPEN_LEGACY
7292 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
7293#endif
7294#ifdef _SC_XOPEN_REALTIME
7295 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
7296#endif
7297#ifdef _SC_XOPEN_REALTIME_THREADS
7298 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
7299#endif
7300#ifdef _SC_XOPEN_SHM
7301 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
7302#endif
7303#ifdef _SC_XOPEN_UNIX
7304 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
7305#endif
7306#ifdef _SC_XOPEN_VERSION
7307 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
7308#endif
7309#ifdef _SC_XOPEN_XCU_VERSION
7310 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
7311#endif
7312#ifdef _SC_XOPEN_XPG2
7313 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
7314#endif
7315#ifdef _SC_XOPEN_XPG3
7316 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
7317#endif
7318#ifdef _SC_XOPEN_XPG4
7319 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
7320#endif
7321};
7322
7323static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007324conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007325{
7326 return conv_confname(arg, valuep, posix_constants_sysconf,
7327 sizeof(posix_constants_sysconf)
7328 / sizeof(struct constdef));
7329}
7330
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007331PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007332"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007333Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007334
7335static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007336posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007337{
7338 PyObject *result = NULL;
7339 int name;
7340
7341 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
7342 int value;
7343
7344 errno = 0;
7345 value = sysconf(name);
7346 if (value == -1 && errno != 0)
7347 posix_error();
7348 else
7349 result = PyInt_FromLong(value);
7350 }
7351 return result;
7352}
7353#endif
7354
7355
Fred Drakebec628d1999-12-15 18:31:10 +00007356/* This code is used to ensure that the tables of configuration value names
7357 * are in sorted order as required by conv_confname(), and also to build the
7358 * the exported dictionaries that are used to publish information about the
7359 * names available on the host platform.
7360 *
7361 * Sorting the table at runtime ensures that the table is properly ordered
7362 * when used, even for platforms we're not able to test on. It also makes
7363 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00007364 */
Fred Drakebec628d1999-12-15 18:31:10 +00007365
7366static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007367cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00007368{
7369 const struct constdef *c1 =
7370 (const struct constdef *) v1;
7371 const struct constdef *c2 =
7372 (const struct constdef *) v2;
7373
7374 return strcmp(c1->name, c2->name);
7375}
7376
7377static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007378setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00007379 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007380{
Fred Drakebec628d1999-12-15 18:31:10 +00007381 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00007382 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00007383
7384 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
7385 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00007386 if (d == NULL)
7387 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007388
Barry Warsaw3155db32000-04-13 15:20:40 +00007389 for (i=0; i < tablesize; ++i) {
7390 PyObject *o = PyInt_FromLong(table[i].value);
7391 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
7392 Py_XDECREF(o);
7393 Py_DECREF(d);
7394 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007395 }
Barry Warsaw3155db32000-04-13 15:20:40 +00007396 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00007397 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00007398 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00007399}
7400
Fred Drakebec628d1999-12-15 18:31:10 +00007401/* Return -1 on failure, 0 on success. */
7402static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007403setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007404{
7405#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00007406 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00007407 sizeof(posix_constants_pathconf)
7408 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007409 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007410 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007411#endif
7412#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00007413 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00007414 sizeof(posix_constants_confstr)
7415 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007416 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007417 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007418#endif
7419#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00007420 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00007421 sizeof(posix_constants_sysconf)
7422 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007423 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007424 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007425#endif
Fred Drakebec628d1999-12-15 18:31:10 +00007426 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00007427}
Fred Draked86ed291999-12-15 15:34:33 +00007428
7429
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007430PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007431"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007432Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007433in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007434
7435static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007436posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007437{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007438 abort();
7439 /*NOTREACHED*/
7440 Py_FatalError("abort() called from Python code didn't abort!");
7441 return NULL;
7442}
Fred Drakebec628d1999-12-15 18:31:10 +00007443
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007444#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007445PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00007446"startfile(filepath [, operation]) - Start a file with its associated\n\
7447application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007448\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00007449When \"operation\" is not specified or \"open\", this acts like\n\
7450double-clicking the file in Explorer, or giving the file name as an\n\
7451argument to the DOS \"start\" command: the file is opened with whatever\n\
7452application (if any) its extension is associated.\n\
7453When another \"operation\" is given, it specifies what should be done with\n\
7454the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007455\n\
7456startfile returns as soon as the associated application is launched.\n\
7457There is no option to wait for the application to close, and no way\n\
7458to retrieve the application's exit status.\n\
7459\n\
7460The filepath is relative to the current directory. If you want to use\n\
7461an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007462the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00007463
7464static PyObject *
7465win32_startfile(PyObject *self, PyObject *args)
7466{
7467 char *filepath;
Georg Brandlf4f44152006-02-18 22:29:33 +00007468 char *operation = NULL;
Tim Petersf58a7aa2000-09-22 10:05:54 +00007469 HINSTANCE rc;
Georg Brandlad89dc82006-04-03 12:26:26 +00007470#ifdef Py_WIN_WIDE_FILENAMES
7471 if (unicode_file_names()) {
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00007472 PyObject *unipath, *woperation = NULL;
Georg Brandlad89dc82006-04-03 12:26:26 +00007473 if (!PyArg_ParseTuple(args, "U|s:startfile",
7474 &unipath, &operation)) {
7475 PyErr_Clear();
7476 goto normal;
7477 }
7478
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00007479
7480 if (operation) {
7481 woperation = PyUnicode_DecodeASCII(operation,
7482 strlen(operation), NULL);
7483 if (!woperation) {
7484 PyErr_Clear();
7485 operation = NULL;
7486 goto normal;
7487 }
Georg Brandlad89dc82006-04-03 12:26:26 +00007488 }
7489
7490 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00007491 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
Georg Brandlad89dc82006-04-03 12:26:26 +00007492 PyUnicode_AS_UNICODE(unipath),
Georg Brandlad89dc82006-04-03 12:26:26 +00007493 NULL, NULL, SW_SHOWNORMAL);
7494 Py_END_ALLOW_THREADS
7495
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00007496 Py_XDECREF(woperation);
Georg Brandlad89dc82006-04-03 12:26:26 +00007497 if (rc <= (HINSTANCE)32) {
7498 PyObject *errval = win32_error_unicode("startfile",
7499 PyUnicode_AS_UNICODE(unipath));
7500 return errval;
7501 }
7502 Py_INCREF(Py_None);
7503 return Py_None;
7504 }
7505#endif
7506
7507normal:
Georg Brandlf4f44152006-02-18 22:29:33 +00007508 if (!PyArg_ParseTuple(args, "et|s:startfile",
7509 Py_FileSystemDefaultEncoding, &filepath,
7510 &operation))
Tim Petersf58a7aa2000-09-22 10:05:54 +00007511 return NULL;
7512 Py_BEGIN_ALLOW_THREADS
Georg Brandlf4f44152006-02-18 22:29:33 +00007513 rc = ShellExecute((HWND)0, operation, filepath,
7514 NULL, NULL, SW_SHOWNORMAL);
Tim Petersf58a7aa2000-09-22 10:05:54 +00007515 Py_END_ALLOW_THREADS
Georg Brandle9f8ec92005-09-25 06:16:40 +00007516 if (rc <= (HINSTANCE)32) {
7517 PyObject *errval = win32_error("startfile", filepath);
7518 PyMem_Free(filepath);
7519 return errval;
7520 }
7521 PyMem_Free(filepath);
Tim Petersf58a7aa2000-09-22 10:05:54 +00007522 Py_INCREF(Py_None);
7523 return Py_None;
7524}
7525#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007526
Martin v. Löwis438b5342002-12-27 10:16:42 +00007527#ifdef HAVE_GETLOADAVG
7528PyDoc_STRVAR(posix_getloadavg__doc__,
7529"getloadavg() -> (float, float, float)\n\n\
7530Return the number of processes in the system run queue averaged over\n\
7531the last 1, 5, and 15 minutes or raises OSError if the load average\n\
7532was unobtainable");
7533
7534static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007535posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00007536{
7537 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00007538 if (getloadavg(loadavg, 3)!=3) {
7539 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
7540 return NULL;
7541 } else
7542 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
7543}
7544#endif
7545
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007546#ifdef MS_WINDOWS
7547
7548PyDoc_STRVAR(win32_urandom__doc__,
7549"urandom(n) -> str\n\n\
7550Return a string of n random bytes suitable for cryptographic use.");
7551
7552typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
7553 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
7554 DWORD dwFlags );
7555typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
7556 BYTE *pbBuffer );
7557
7558static CRYPTGENRANDOM pCryptGenRandom = NULL;
7559static HCRYPTPROV hCryptProv = 0;
7560
Tim Peters4ad82172004-08-30 17:02:04 +00007561static PyObject*
7562win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007563{
Tim Petersd3115382004-08-30 17:36:46 +00007564 int howMany;
7565 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007566
Tim Peters4ad82172004-08-30 17:02:04 +00007567 /* Read arguments */
Tim Peters9b279a82004-08-30 17:10:53 +00007568 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
Tim Peters4ad82172004-08-30 17:02:04 +00007569 return NULL;
Tim Peters51eba612004-08-30 17:08:02 +00007570 if (howMany < 0)
7571 return PyErr_Format(PyExc_ValueError,
7572 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007573
Tim Peters4ad82172004-08-30 17:02:04 +00007574 if (hCryptProv == 0) {
7575 HINSTANCE hAdvAPI32 = NULL;
7576 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007577
Tim Peters4ad82172004-08-30 17:02:04 +00007578 /* Obtain handle to the DLL containing CryptoAPI
7579 This should not fail */
7580 hAdvAPI32 = GetModuleHandle("advapi32.dll");
7581 if(hAdvAPI32 == NULL)
7582 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007583
Tim Peters4ad82172004-08-30 17:02:04 +00007584 /* Obtain pointers to the CryptoAPI functions
7585 This will fail on some early versions of Win95 */
7586 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
7587 hAdvAPI32,
7588 "CryptAcquireContextA");
7589 if (pCryptAcquireContext == NULL)
7590 return PyErr_Format(PyExc_NotImplementedError,
7591 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007592
Tim Peters4ad82172004-08-30 17:02:04 +00007593 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
7594 hAdvAPI32, "CryptGenRandom");
7595 if (pCryptAcquireContext == NULL)
7596 return PyErr_Format(PyExc_NotImplementedError,
7597 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007598
Tim Peters4ad82172004-08-30 17:02:04 +00007599 /* Acquire context */
7600 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
7601 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
7602 return win32_error("CryptAcquireContext", NULL);
7603 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007604
Tim Peters4ad82172004-08-30 17:02:04 +00007605 /* Allocate bytes */
Tim Petersd3115382004-08-30 17:36:46 +00007606 result = PyString_FromStringAndSize(NULL, howMany);
7607 if (result != NULL) {
7608 /* Get random data */
7609 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
7610 PyString_AS_STRING(result))) {
7611 Py_DECREF(result);
7612 return win32_error("CryptGenRandom", NULL);
7613 }
Tim Peters4ad82172004-08-30 17:02:04 +00007614 }
Tim Petersd3115382004-08-30 17:36:46 +00007615 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007616}
7617#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007618
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007619static PyMethodDef posix_methods[] = {
7620 {"access", posix_access, METH_VARARGS, posix_access__doc__},
7621#ifdef HAVE_TTYNAME
7622 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
7623#endif
7624 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
7625 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007626#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007627 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007628#endif /* HAVE_CHOWN */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007629#ifdef HAVE_LCHOWN
7630 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
7631#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00007632#ifdef HAVE_CHROOT
7633 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
7634#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007635#ifdef HAVE_CTERMID
Neal Norwitze241ce82003-02-17 18:17:05 +00007636 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007637#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00007638#ifdef HAVE_GETCWD
Neal Norwitze241ce82003-02-17 18:17:05 +00007639 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Walter Dörwald3b918c32002-11-21 20:18:46 +00007640#ifdef Py_USING_UNICODE
Neal Norwitze241ce82003-02-17 18:17:05 +00007641 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00007642#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00007643#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007644#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007645 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007646#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007647 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
7648 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
7649 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007650#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007651 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007652#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007653#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007654 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007655#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007656 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
7657 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
7658 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007659 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007660#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007661 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007662#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007663#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007664 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007665#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007666 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007667#ifdef HAVE_UNAME
Neal Norwitze241ce82003-02-17 18:17:05 +00007668 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007669#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007670 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
7671 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
7672 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007673#ifdef HAVE_TIMES
Neal Norwitze241ce82003-02-17 18:17:05 +00007674 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007675#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007676 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007677#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007678 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
7679 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007680#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00007681#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007682 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
7683 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00007684#if defined(PYOS_OS2)
7685 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
7686 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
7687#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00007688#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007689#ifdef HAVE_FORK1
Neal Norwitze241ce82003-02-17 18:17:05 +00007690 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00007691#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007692#ifdef HAVE_FORK
Neal Norwitze241ce82003-02-17 18:17:05 +00007693 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007694#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007695#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Neal Norwitze241ce82003-02-17 18:17:05 +00007696 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00007697#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00007698#ifdef HAVE_FORKPTY
Neal Norwitze241ce82003-02-17 18:17:05 +00007699 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00007700#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007701#ifdef HAVE_GETEGID
Neal Norwitze241ce82003-02-17 18:17:05 +00007702 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007703#endif /* HAVE_GETEGID */
7704#ifdef HAVE_GETEUID
Neal Norwitze241ce82003-02-17 18:17:05 +00007705 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007706#endif /* HAVE_GETEUID */
7707#ifdef HAVE_GETGID
Neal Norwitze241ce82003-02-17 18:17:05 +00007708 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007709#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00007710#ifdef HAVE_GETGROUPS
Neal Norwitze241ce82003-02-17 18:17:05 +00007711 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00007712#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007713 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007714#ifdef HAVE_GETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00007715 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007716#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007717#ifdef HAVE_GETPPID
Neal Norwitze241ce82003-02-17 18:17:05 +00007718 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007719#endif /* HAVE_GETPPID */
7720#ifdef HAVE_GETUID
Neal Norwitze241ce82003-02-17 18:17:05 +00007721 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007722#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00007723#ifdef HAVE_GETLOGIN
Neal Norwitze241ce82003-02-17 18:17:05 +00007724 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00007725#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00007726#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007727 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007728#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00007729#ifdef HAVE_KILLPG
7730 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
7731#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00007732#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007733 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00007734#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007735#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007736 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007737#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00007738 {"popen2", win32_popen2, METH_VARARGS},
7739 {"popen3", win32_popen3, METH_VARARGS},
7740 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00007741 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00007742#else
7743#if defined(PYOS_OS2) && defined(PYCC_GCC)
7744 {"popen2", os2emx_popen2, METH_VARARGS},
7745 {"popen3", os2emx_popen3, METH_VARARGS},
7746 {"popen4", os2emx_popen4, METH_VARARGS},
7747#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00007748#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007749#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007750#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007751 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007752#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00007753#ifdef HAVE_SETEUID
7754 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
7755#endif /* HAVE_SETEUID */
7756#ifdef HAVE_SETEGID
7757 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
7758#endif /* HAVE_SETEGID */
7759#ifdef HAVE_SETREUID
7760 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
7761#endif /* HAVE_SETREUID */
7762#ifdef HAVE_SETREGID
7763 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
7764#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007765#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007766 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007767#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00007768#ifdef HAVE_SETGROUPS
7769 {"setgroups", posix_setgroups, METH_VARARGS, posix_setgroups__doc__},
7770#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00007771#ifdef HAVE_GETPGID
7772 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
7773#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007774#ifdef HAVE_SETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00007775 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007776#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00007777#ifdef HAVE_WAIT
Neal Norwitze241ce82003-02-17 18:17:05 +00007778 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00007779#endif /* HAVE_WAIT */
Neal Norwitz05a45592006-03-20 06:30:08 +00007780#ifdef HAVE_WAIT3
7781 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
7782#endif /* HAVE_WAIT3 */
7783#ifdef HAVE_WAIT4
7784 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
7785#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00007786#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007787 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007788#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007789#ifdef HAVE_GETSID
7790 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
7791#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007792#ifdef HAVE_SETSID
Neal Norwitze241ce82003-02-17 18:17:05 +00007793 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007794#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007795#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007796 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007797#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007798#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007799 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007800#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007801#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007802 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007803#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007804 {"open", posix_open, METH_VARARGS, posix_open__doc__},
7805 {"close", posix_close, METH_VARARGS, posix_close__doc__},
7806 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
7807 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
7808 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
7809 {"read", posix_read, METH_VARARGS, posix_read__doc__},
7810 {"write", posix_write, METH_VARARGS, posix_write__doc__},
7811 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
7812 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00007813 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007814#ifdef HAVE_PIPE
Neal Norwitze241ce82003-02-17 18:17:05 +00007815 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007816#endif
7817#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007818 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007819#endif
Neal Norwitz11690112002-07-30 01:08:28 +00007820#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00007821 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
7822#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00007823#ifdef HAVE_DEVICE_MACROS
7824 {"major", posix_major, METH_VARARGS, posix_major__doc__},
7825 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
7826 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
7827#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007828#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007829 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007830#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007831#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007832 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00007833#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00007834#ifdef HAVE_UNSETENV
7835 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
7836#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00007837#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007838 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00007839#endif
Fred Drake4d1e64b2002-04-15 19:40:07 +00007840#ifdef HAVE_FCHDIR
7841 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
7842#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00007843#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007844 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007845#endif
7846#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00007847 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00007848#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00007849#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00007850#ifdef WCOREDUMP
7851 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
7852#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00007853#ifdef WIFCONTINUED
7854 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
7855#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00007856#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007857 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007858#endif /* WIFSTOPPED */
7859#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007860 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007861#endif /* WIFSIGNALED */
7862#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007863 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007864#endif /* WIFEXITED */
7865#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007866 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007867#endif /* WEXITSTATUS */
7868#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007869 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007870#endif /* WTERMSIG */
7871#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007872 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00007873#endif /* WSTOPSIG */
7874#endif /* HAVE_SYS_WAIT_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007875#ifdef HAVE_FSTATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007876 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007877#endif
7878#ifdef HAVE_STATVFS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007879 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00007880#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00007881#ifdef HAVE_TMPFILE
Neal Norwitze241ce82003-02-17 18:17:05 +00007882 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007883#endif
7884#ifdef HAVE_TEMPNAM
7885 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
7886#endif
7887#ifdef HAVE_TMPNAM
Neal Norwitze241ce82003-02-17 18:17:05 +00007888 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007889#endif
Fred Drakec9680921999-12-13 16:37:25 +00007890#ifdef HAVE_CONFSTR
7891 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
7892#endif
7893#ifdef HAVE_SYSCONF
7894 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
7895#endif
7896#ifdef HAVE_FPATHCONF
7897 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
7898#endif
7899#ifdef HAVE_PATHCONF
7900 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
7901#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00007902 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007903#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00007904 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
7905#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007906#ifdef HAVE_GETLOADAVG
Neal Norwitze241ce82003-02-17 18:17:05 +00007907 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00007908#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007909 #ifdef MS_WINDOWS
7910 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
7911 #endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007912 {NULL, NULL} /* Sentinel */
7913};
7914
7915
Barry Warsaw4a342091996-12-19 23:50:02 +00007916static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007917ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00007918{
Fred Drake4d1e64b2002-04-15 19:40:07 +00007919 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00007920}
7921
Guido van Rossumd48f2521997-12-05 22:19:34 +00007922#if defined(PYOS_OS2)
7923/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007924static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007925{
7926 APIRET rc;
7927 ULONG values[QSV_MAX+1];
7928 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00007929 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00007930
7931 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00007932 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007933 Py_END_ALLOW_THREADS
7934
7935 if (rc != NO_ERROR) {
7936 os2_error(rc);
7937 return -1;
7938 }
7939
Fred Drake4d1e64b2002-04-15 19:40:07 +00007940 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
7941 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
7942 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
7943 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
7944 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
7945 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
7946 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007947
7948 switch (values[QSV_VERSION_MINOR]) {
7949 case 0: ver = "2.00"; break;
7950 case 10: ver = "2.10"; break;
7951 case 11: ver = "2.11"; break;
7952 case 30: ver = "3.00"; break;
7953 case 40: ver = "4.00"; break;
7954 case 50: ver = "5.00"; break;
7955 default:
Tim Peters885d4572001-11-28 20:27:42 +00007956 PyOS_snprintf(tmp, sizeof(tmp),
7957 "%d-%d", values[QSV_VERSION_MAJOR],
7958 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007959 ver = &tmp[0];
7960 }
7961
7962 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00007963 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00007964 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00007965
7966 /* Add Indicator of Which Drive was Used to Boot the System */
7967 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
7968 tmp[1] = ':';
7969 tmp[2] = '\0';
7970
Fred Drake4d1e64b2002-04-15 19:40:07 +00007971 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00007972}
7973#endif
7974
Barry Warsaw4a342091996-12-19 23:50:02 +00007975static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00007976all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00007977{
Guido van Rossum94f6f721999-01-06 18:42:14 +00007978#ifdef F_OK
7979 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007980#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007981#ifdef R_OK
7982 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007983#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007984#ifdef W_OK
7985 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007986#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00007987#ifdef X_OK
7988 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00007989#endif
Fred Drakec9680921999-12-13 16:37:25 +00007990#ifdef NGROUPS_MAX
7991 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
7992#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007993#ifdef TMP_MAX
7994 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
7995#endif
Fred Drake106c1a02002-04-23 15:58:02 +00007996#ifdef WCONTINUED
7997 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
7998#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00007999#ifdef WNOHANG
8000 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008001#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008002#ifdef WUNTRACED
8003 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
8004#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008005#ifdef O_RDONLY
8006 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
8007#endif
8008#ifdef O_WRONLY
8009 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
8010#endif
8011#ifdef O_RDWR
8012 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
8013#endif
8014#ifdef O_NDELAY
8015 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
8016#endif
8017#ifdef O_NONBLOCK
8018 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
8019#endif
8020#ifdef O_APPEND
8021 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
8022#endif
8023#ifdef O_DSYNC
8024 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
8025#endif
8026#ifdef O_RSYNC
8027 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
8028#endif
8029#ifdef O_SYNC
8030 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
8031#endif
8032#ifdef O_NOCTTY
8033 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
8034#endif
8035#ifdef O_CREAT
8036 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
8037#endif
8038#ifdef O_EXCL
8039 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
8040#endif
8041#ifdef O_TRUNC
8042 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
8043#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00008044#ifdef O_BINARY
8045 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
8046#endif
8047#ifdef O_TEXT
8048 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
8049#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008050#ifdef O_LARGEFILE
8051 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
8052#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00008053#ifdef O_SHLOCK
8054 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
8055#endif
8056#ifdef O_EXLOCK
8057 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
8058#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008059
Tim Peters5aa91602002-01-30 05:46:57 +00008060/* MS Windows */
8061#ifdef O_NOINHERIT
8062 /* Don't inherit in child processes. */
8063 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
8064#endif
8065#ifdef _O_SHORT_LIVED
8066 /* Optimize for short life (keep in memory). */
8067 /* MS forgot to define this one with a non-underscore form too. */
8068 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
8069#endif
8070#ifdef O_TEMPORARY
8071 /* Automatically delete when last handle is closed. */
8072 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
8073#endif
8074#ifdef O_RANDOM
8075 /* Optimize for random access. */
8076 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
8077#endif
8078#ifdef O_SEQUENTIAL
8079 /* Optimize for sequential access. */
8080 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
8081#endif
8082
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008083/* GNU extensions. */
8084#ifdef O_DIRECT
8085 /* Direct disk access. */
8086 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
8087#endif
8088#ifdef O_DIRECTORY
8089 /* Must be a directory. */
8090 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
8091#endif
8092#ifdef O_NOFOLLOW
8093 /* Do not follow links. */
8094 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
8095#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00008096
Barry Warsaw5676bd12003-01-07 20:57:09 +00008097 /* These come from sysexits.h */
8098#ifdef EX_OK
8099 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008100#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008101#ifdef EX_USAGE
8102 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008103#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008104#ifdef EX_DATAERR
8105 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008106#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008107#ifdef EX_NOINPUT
8108 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008109#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008110#ifdef EX_NOUSER
8111 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008112#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008113#ifdef EX_NOHOST
8114 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008115#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008116#ifdef EX_UNAVAILABLE
8117 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008118#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008119#ifdef EX_SOFTWARE
8120 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008121#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008122#ifdef EX_OSERR
8123 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008124#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008125#ifdef EX_OSFILE
8126 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008127#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008128#ifdef EX_CANTCREAT
8129 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008130#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008131#ifdef EX_IOERR
8132 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008133#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008134#ifdef EX_TEMPFAIL
8135 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008136#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008137#ifdef EX_PROTOCOL
8138 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008139#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008140#ifdef EX_NOPERM
8141 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008142#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008143#ifdef EX_CONFIG
8144 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008145#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008146#ifdef EX_NOTFOUND
8147 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008148#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008149
Guido van Rossum246bc171999-02-01 23:54:31 +00008150#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008151#if defined(PYOS_OS2) && defined(PYCC_GCC)
8152 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
8153 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
8154 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
8155 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
8156 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
8157 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
8158 if (ins(d, "P_PM", (long)P_PM)) return -1;
8159 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
8160 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
8161 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
8162 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
8163 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
8164 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
8165 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
8166 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
8167 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
8168 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
8169 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
8170 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
8171 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
8172#else
Guido van Rossum7d385291999-02-16 19:38:04 +00008173 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
8174 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
8175 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
8176 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
8177 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00008178#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008179#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00008180
Guido van Rossumd48f2521997-12-05 22:19:34 +00008181#if defined(PYOS_OS2)
8182 if (insertvalues(d)) return -1;
8183#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008184 return 0;
8185}
8186
8187
Tim Peters5aa91602002-01-30 05:46:57 +00008188#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008189#define INITFUNC initnt
8190#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008191
8192#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008193#define INITFUNC initos2
8194#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008195
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008196#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008197#define INITFUNC initposix
8198#define MODNAME "posix"
8199#endif
8200
Mark Hammondfe51c6d2002-08-02 02:27:13 +00008201PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008202INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00008203{
Fred Drake4d1e64b2002-04-15 19:40:07 +00008204 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00008205
Fred Drake4d1e64b2002-04-15 19:40:07 +00008206 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008207 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00008208 posix__doc__);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00008209 if (m == NULL)
8210 return;
Tim Peters5aa91602002-01-30 05:46:57 +00008211
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008212 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008213 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00008214 Py_XINCREF(v);
8215 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008216 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00008217 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00008218
Fred Drake4d1e64b2002-04-15 19:40:07 +00008219 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00008220 return;
8221
Fred Drake4d1e64b2002-04-15 19:40:07 +00008222 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00008223 return;
8224
Fred Drake4d1e64b2002-04-15 19:40:07 +00008225 Py_INCREF(PyExc_OSError);
8226 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00008227
Guido van Rossumb3d39562000-01-31 18:41:26 +00008228#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00008229 if (posix_putenv_garbage == NULL)
8230 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00008231#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008232
Guido van Rossum14648392001-12-08 18:02:58 +00008233 stat_result_desc.name = MODNAME ".stat_result";
Martin v. Löwisf607bda2002-10-16 18:27:39 +00008234 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
8235 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
8236 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008237 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00008238 structseq_new = StatResultType.tp_new;
8239 StatResultType.tp_new = statresult_new;
Fred Drake4d1e64b2002-04-15 19:40:07 +00008240 Py_INCREF((PyObject*) &StatResultType);
8241 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008242
Guido van Rossum14648392001-12-08 18:02:58 +00008243 statvfs_result_desc.name = MODNAME ".statvfs_result";
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008244 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Fred Drake4d1e64b2002-04-15 19:40:07 +00008245 Py_INCREF((PyObject*) &StatVFSResultType);
8246 PyModule_AddObject(m, "statvfs_result",
8247 (PyObject*) &StatVFSResultType);
Guido van Rossumb6775db1994-08-01 11:34:53 +00008248}