blob: 9e8bf8f5f07b74be81f260bf18b92855af54a9ac [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
Ronald Oussorend06b6f22006-04-23 11:59:25 +000016#ifdef __APPLE__
17 /*
18 * Step 1 of support for weak-linking a number of symbols existing on
19 * OSX 10.4 and later, see the comment in the #ifdef __APPLE__ block
20 * at the end of this file for more information.
21 */
22# pragma weak lchown
23# pragma weak statvfs
24# pragma weak fstatvfs
25
26#endif /* __APPLE__ */
27
Thomas Wouters68bc4f92006-03-01 01:05:10 +000028#define PY_SSIZE_T_CLEAN
29
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000030#include "Python.h"
31#include "structseq.h"
32
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000033#if defined(__VMS)
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000034# include <unixio.h>
Martin v. Löwis79acb9e2002-12-06 12:48:53 +000035#endif /* defined(__VMS) */
36
Anthony Baxterac6bd462006-04-13 02:06:09 +000037#ifdef __cplusplus
38extern "C" {
39#endif
40
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000041PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000042"This module provides access to operating system functionality that is\n\
43standardized by the C Standard and the POSIX standard (a thinly\n\
44disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000045corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000046
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000047#ifndef Py_USING_UNICODE
48/* This is used in signatures of functions. */
49#define Py_UNICODE void
50#endif
51
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000052#if defined(PYOS_OS2)
53#define INCL_DOS
54#define INCL_DOSERRORS
55#define INCL_DOSPROCESS
56#define INCL_NOPMAPI
57#include <os2.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000058#if defined(PYCC_GCC)
59#include <ctype.h>
60#include <io.h>
61#include <stdio.h>
62#include <process.h>
Andrew MacIntyre6c73af22002-03-03 03:07:07 +000063#endif
Andrew MacIntyreda4d6cb2004-03-29 11:53:38 +000064#include "osdefs.h"
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000065#endif
66
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +000067#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000068#include <sys/types.h>
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +000069#endif /* HAVE_SYS_TYPES_H */
70
71#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000072#include <sys/stat.h>
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +000073#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000074
Guido van Rossum36bc6801995-06-14 22:54:23 +000075#ifdef HAVE_SYS_WAIT_H
76#include <sys/wait.h> /* For WNOHANG */
77#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000078
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +000079#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000080#include <signal.h>
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +000081#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000082
Guido van Rossumb6775db1994-08-01 11:34:53 +000083#ifdef HAVE_FCNTL_H
84#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000085#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000086
Guido van Rossuma6535fd2001-10-18 19:44:10 +000087#ifdef HAVE_GRP_H
88#include <grp.h>
89#endif
90
Barry Warsaw5676bd12003-01-07 20:57:09 +000091#ifdef HAVE_SYSEXITS_H
92#include <sysexits.h>
93#endif /* HAVE_SYSEXITS_H */
94
Anthony Baxter8a560de2004-10-13 15:30:56 +000095#ifdef HAVE_SYS_LOADAVG_H
96#include <sys/loadavg.h>
97#endif
98
Guido van Rossuma4916fa1996-05-23 22:58:55 +000099/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000100/* XXX Gosh I wish these were all moved into pyconfig.h */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000101#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000102#include <process.h>
103#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000104#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000105#define HAVE_GETCWD 1
106#define HAVE_OPENDIR 1
107#define HAVE_SYSTEM 1
108#if defined(__OS2__)
109#define HAVE_EXECV 1
110#define HAVE_WAIT 1
Guido van Rossumad0ee831995-03-01 10:34:45 +0000111#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000112#include <process.h>
113#else
114#ifdef __BORLANDC__ /* Borland compiler */
115#define HAVE_EXECV 1
116#define HAVE_GETCWD 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000117#define HAVE_OPENDIR 1
118#define HAVE_PIPE 1
119#define HAVE_POPEN 1
120#define HAVE_SYSTEM 1
121#define HAVE_WAIT 1
122#else
123#ifdef _MSC_VER /* Microsoft compiler */
Guido van Rossum8d665e61996-06-26 18:22:49 +0000124#define HAVE_GETCWD 1
Guido van Rossuma1065681999-01-25 23:20:23 +0000125#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000126#define HAVE_EXECV 1
127#define HAVE_PIPE 1
128#define HAVE_POPEN 1
129#define HAVE_SYSTEM 1
Tim Petersab034fa2002-02-01 11:27:43 +0000130#define HAVE_CWAIT 1
Tim Peters11b23062003-04-23 02:39:17 +0000131#define HAVE_FSYNC 1
132#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000133#else
Martin v. Löwis79acb9e2002-12-06 12:48:53 +0000134#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
135/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000136#else /* all other compilers */
137/* Unix functions that the configure script doesn't check for */
138#define HAVE_EXECV 1
139#define HAVE_FORK 1
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000140#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
141#define HAVE_FORK1 1
142#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000143#define HAVE_GETCWD 1
144#define HAVE_GETEGID 1
145#define HAVE_GETEUID 1
146#define HAVE_GETGID 1
147#define HAVE_GETPPID 1
148#define HAVE_GETUID 1
149#define HAVE_KILL 1
150#define HAVE_OPENDIR 1
151#define HAVE_PIPE 1
Martin v. Löwis212ede62003-09-20 11:20:30 +0000152#ifndef __rtems__
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000153#define HAVE_POPEN 1
Martin v. Löwis212ede62003-09-20 11:20:30 +0000154#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000155#define HAVE_SYSTEM 1
156#define HAVE_WAIT 1
Guido van Rossumd371ff11999-01-25 16:12:23 +0000157#define HAVE_TTYNAME 1
Martin v. Löwis7a924e62003-03-05 14:15:21 +0000158#endif /* PYOS_OS2 && PYCC_GCC && __VMS */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000159#endif /* _MSC_VER */
160#endif /* __BORLANDC__ */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000161#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000162#endif /* ! __IBMC__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000163
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000164#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000165
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000166#if defined(__sgi)&&_COMPILER_VERSION>=700
167/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
168 (default) */
169extern char *ctermid_r(char *);
170#endif
171
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000172#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000173#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000174extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000175#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000176#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000177extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000178#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000179extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000180#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000181#endif
182#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000183extern int chdir(char *);
184extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000185#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000186extern int chdir(const char *);
187extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000188#endif
Tim Peters58e0a8c2001-05-14 22:32:33 +0000189#ifdef __BORLANDC__
190extern int chmod(const char *, int);
191#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000192extern int chmod(const char *, mode_t);
Tim Peters58e0a8c2001-05-14 22:32:33 +0000193#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000194extern int chown(const char *, uid_t, gid_t);
195extern char *getcwd(char *, int);
196extern char *strerror(int);
197extern int link(const char *, const char *);
198extern int rename(const char *, const char *);
199extern int stat(const char *, struct stat *);
200extern int unlink(const char *);
201extern int pclose(FILE *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000202#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000203extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000204#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000205#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000206extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000207#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000208#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000209
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000210#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000211
Guido van Rossumb6775db1994-08-01 11:34:53 +0000212#ifdef HAVE_UTIME_H
213#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000214#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000215
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000216#ifdef HAVE_SYS_UTIME_H
217#include <sys/utime.h>
218#define HAVE_UTIME_H /* pretend we do for the rest of this file */
219#endif /* HAVE_SYS_UTIME_H */
220
Guido van Rossumb6775db1994-08-01 11:34:53 +0000221#ifdef HAVE_SYS_TIMES_H
222#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000223#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000224
225#ifdef HAVE_SYS_PARAM_H
226#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000227#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000228
229#ifdef HAVE_SYS_UTSNAME_H
230#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000231#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000232
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000233#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000234#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000235#define NAMLEN(dirent) strlen((dirent)->d_name)
236#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000237#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000238#include <direct.h>
239#define NAMLEN(dirent) strlen((dirent)->d_name)
240#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000241#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000242#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000243#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000244#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000245#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000246#endif
247#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000248#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000249#endif
250#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000251#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000252#endif
253#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000254
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000255#ifdef _MSC_VER
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +0000256#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000257#include <direct.h>
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +0000258#endif
259#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000260#include <io.h>
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +0000261#endif
262#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000263#include <process.h>
Martin v. Löwis0e8bd7e2006-06-10 12:23:46 +0000264#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000265#include "osdefs.h"
Martin v. Löwisdc3883f2004-08-29 15:46:35 +0000266#define _WIN32_WINNT 0x0400 /* Needed for CryptoAPI on some systems */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000267#include <windows.h>
Tim Petersee66d0c2002-07-15 16:10:55 +0000268#include <shellapi.h> /* for ShellExecute() */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000269#define popen _popen
Guido van Rossum794d8131994-08-23 13:48:48 +0000270#define pclose _pclose
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000271#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000272
Guido van Rossumd48f2521997-12-05 22:19:34 +0000273#if defined(PYCC_VACPP) && defined(PYOS_OS2)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000274#include <io.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000275#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000276
Tim Petersbc2e10e2002-03-03 23:17:02 +0000277#ifndef MAXPATHLEN
Thomas Wouters1ddba602006-04-25 15:29:46 +0000278#if defined(PATH_MAX) && PATH_MAX > 1024
279#define MAXPATHLEN PATH_MAX
280#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000281#define MAXPATHLEN 1024
Thomas Wouters1ddba602006-04-25 15:29:46 +0000282#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000283#endif /* MAXPATHLEN */
284
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000285#ifdef UNION_WAIT
286/* Emulate some macros on systems that have a union instead of macros */
287
288#ifndef WIFEXITED
289#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
290#endif
291
292#ifndef WEXITSTATUS
293#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
294#endif
295
296#ifndef WTERMSIG
297#define WTERMSIG(u_wait) ((u_wait).w_termsig)
298#endif
299
Neal Norwitzd5a37542006-03-20 06:48:34 +0000300#define WAIT_TYPE union wait
301#define WAIT_STATUS_INT(s) (s.w_status)
302
303#else /* !UNION_WAIT */
304#define WAIT_TYPE int
305#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000306#endif /* UNION_WAIT */
307
Greg Wardb48bc172000-03-01 21:51:56 +0000308/* Don't use the "_r" form if we don't need it (also, won't have a
309 prototype for it, at least on Solaris -- maybe others as well?). */
310#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
311#define USE_CTERMID_R
312#endif
313
314#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD)
315#define USE_TMPNAM_R
316#endif
317
Fred Drake699f3522000-06-29 21:12:41 +0000318/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000319#undef STAT
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000320#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwis14694662006-02-03 12:54:16 +0000321# define STAT win32_stat
322# define FSTAT win32_fstat
323# define STRUCT_STAT struct win32_stat
Fred Drake699f3522000-06-29 21:12:41 +0000324#else
325# define STAT stat
326# define FSTAT fstat
327# define STRUCT_STAT struct stat
328#endif
329
Tim Peters11b23062003-04-23 02:39:17 +0000330#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000331#include <sys/mkdev.h>
332#else
333#if defined(MAJOR_IN_SYSMACROS)
334#include <sys/sysmacros.h>
335#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000336#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
337#include <sys/mkdev.h>
338#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000339#endif
Fred Drake699f3522000-06-29 21:12:41 +0000340
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000341/* Return a dictionary corresponding to the POSIX environment table */
Jack Jansenea0c3822002-08-01 21:57:49 +0000342#ifdef WITH_NEXT_FRAMEWORK
343/* On Darwin/MacOSX a shared library or framework has no access to
344** environ directly, we must obtain it with _NSGetEnviron().
345*/
346#include <crt_externs.h>
347static char **environ;
348#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000349extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000350#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000351
Barry Warsaw53699e91996-12-10 23:23:01 +0000352static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000353convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000354{
Barry Warsaw53699e91996-12-10 23:23:01 +0000355 PyObject *d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000356 char **e;
Barry Warsaw53699e91996-12-10 23:23:01 +0000357 d = PyDict_New();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000358 if (d == NULL)
359 return NULL;
Jack Jansenea0c3822002-08-01 21:57:49 +0000360#ifdef WITH_NEXT_FRAMEWORK
361 if (environ == NULL)
362 environ = *_NSGetEnviron();
363#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000364 if (environ == NULL)
365 return d;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000366 /* This part ignores errors */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000367 for (e = environ; *e != NULL; e++) {
Guido van Rossum6a619f41999-08-03 19:41:10 +0000368 PyObject *k;
Barry Warsaw53699e91996-12-10 23:23:01 +0000369 PyObject *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000370 char *p = strchr(*e, '=');
371 if (p == NULL)
372 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000373 k = PyString_FromStringAndSize(*e, (int)(p-*e));
374 if (k == NULL) {
375 PyErr_Clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000376 continue;
Guido van Rossum6a619f41999-08-03 19:41:10 +0000377 }
378 v = PyString_FromString(p+1);
379 if (v == NULL) {
380 PyErr_Clear();
381 Py_DECREF(k);
382 continue;
383 }
384 if (PyDict_GetItem(d, k) == NULL) {
385 if (PyDict_SetItem(d, k, v) != 0)
386 PyErr_Clear();
387 }
388 Py_DECREF(k);
Barry Warsaw53699e91996-12-10 23:23:01 +0000389 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000390 }
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +0000391#if defined(PYOS_OS2)
Guido van Rossumd48f2521997-12-05 22:19:34 +0000392 {
393 APIRET rc;
394 char buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
395
396 rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000397 if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
Guido van Rossumd48f2521997-12-05 22:19:34 +0000398 PyObject *v = PyString_FromString(buffer);
399 PyDict_SetItemString(d, "BEGINLIBPATH", v);
400 Py_DECREF(v);
401 }
402 rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
403 if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
404 PyObject *v = PyString_FromString(buffer);
405 PyDict_SetItemString(d, "ENDLIBPATH", v);
406 Py_DECREF(v);
407 }
408 }
409#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000410 return d;
411}
412
413
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000414/* Set a POSIX-specific error from errno, and return NULL */
415
Barry Warsawd58d7641998-07-23 16:14:40 +0000416static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000417posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +0000418{
Barry Warsawca74da41999-02-09 19:31:45 +0000419 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000420}
Barry Warsawd58d7641998-07-23 16:14:40 +0000421static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000422posix_error_with_filename(char* name)
Barry Warsawd58d7641998-07-23 16:14:40 +0000423{
Barry Warsawca74da41999-02-09 19:31:45 +0000424 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
Barry Warsawd58d7641998-07-23 16:14:40 +0000425}
426
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000427#ifdef Py_WIN_WIDE_FILENAMES
428static PyObject *
429posix_error_with_unicode_filename(Py_UNICODE* name)
430{
431 return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
432}
433#endif /* Py_WIN_WIDE_FILENAMES */
434
435
Mark Hammondef8b6542001-05-13 08:04:26 +0000436static PyObject *
437posix_error_with_allocated_filename(char* name)
438{
439 PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
440 PyMem_Free(name);
441 return rc;
442}
443
Martin v. Löwis6238d2b2002-06-30 15:26:10 +0000444#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000445static PyObject *
446win32_error(char* function, char* filename)
447{
Mark Hammond33a6da92000-08-15 00:46:38 +0000448 /* XXX We should pass the function name along in the future.
449 (_winreg.c also wants to pass the function name.)
Tim Peters5aa91602002-01-30 05:46:57 +0000450 This would however require an additional param to the
Mark Hammond33a6da92000-08-15 00:46:38 +0000451 Windows error object, which is non-trivial.
452 */
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000453 errno = GetLastError();
454 if (filename)
Mark Hammond33a6da92000-08-15 00:46:38 +0000455 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000456 else
Mark Hammond33a6da92000-08-15 00:46:38 +0000457 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000458}
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000459
460#ifdef Py_WIN_WIDE_FILENAMES
461static PyObject *
462win32_error_unicode(char* function, Py_UNICODE* filename)
463{
464 /* XXX - see win32_error for comments on 'function' */
465 errno = GetLastError();
466 if (filename)
467 return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
468 else
469 return PyErr_SetFromWindowsErr(errno);
470}
471
472static PyObject *_PyUnicode_FromFileSystemEncodedObject(register PyObject *obj)
473{
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000474}
475
476/* Function suitable for O& conversion */
477static int
478convert_to_unicode(PyObject *arg, void* _param)
479{
480 PyObject **param = (PyObject**)_param;
481 if (PyUnicode_CheckExact(arg)) {
482 Py_INCREF(arg);
483 *param = arg;
484 }
485 else if (PyUnicode_Check(arg)) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000486 /* For a Unicode subtype that's not a Unicode object,
487 return a true Unicode object with the same data. */
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000488 *param = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(arg),
489 PyUnicode_GET_SIZE(arg));
490 return *param != NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000491 }
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000492 else
493 *param = PyUnicode_FromEncodedObject(arg,
494 Py_FileSystemDefaultEncoding,
495 "strict");
496 return (*param) != NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000497}
498
499#endif /* Py_WIN_WIDE_FILENAMES */
500
Fredrik Lundhffb9c772000-07-09 14:49:51 +0000501#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000502
Guido van Rossumd48f2521997-12-05 22:19:34 +0000503#if defined(PYOS_OS2)
504/**********************************************************************
505 * Helper Function to Trim and Format OS/2 Messages
506 **********************************************************************/
507 static void
508os2_formatmsg(char *msgbuf, int msglen, char *reason)
509{
510 msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
511
512 if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
513 char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
514
Neal Norwitz30b5c5d2005-12-19 06:05:18 +0000515 while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
Guido van Rossumd48f2521997-12-05 22:19:34 +0000516 *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
517 }
518
519 /* Add Optional Reason Text */
520 if (reason) {
521 strcat(msgbuf, " : ");
522 strcat(msgbuf, reason);
523 }
524}
525
526/**********************************************************************
527 * Decode an OS/2 Operating System Error Code
528 *
529 * A convenience function to lookup an OS/2 error code and return a
530 * text message we can use to raise a Python exception.
531 *
532 * Notes:
533 * The messages for errors returned from the OS/2 kernel reside in
534 * the file OSO001.MSG in the \OS2 directory hierarchy.
535 *
536 **********************************************************************/
537 static char *
538os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
539{
540 APIRET rc;
541 ULONG msglen;
542
543 /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
544 Py_BEGIN_ALLOW_THREADS
545 rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
546 errorcode, "oso001.msg", &msglen);
547 Py_END_ALLOW_THREADS
548
549 if (rc == NO_ERROR)
550 os2_formatmsg(msgbuf, msglen, reason);
551 else
Tim Peters1ceb5fb2001-11-28 20:32:57 +0000552 PyOS_snprintf(msgbuf, msgbuflen,
Tim Peters885d4572001-11-28 20:27:42 +0000553 "unknown OS error #%d", errorcode);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000554
555 return msgbuf;
556}
557
558/* Set an OS/2-specific error and return NULL. OS/2 kernel
559 errors are not in a global variable e.g. 'errno' nor are
560 they congruent with posix error numbers. */
561
562static PyObject * os2_error(int code)
563{
564 char text[1024];
565 PyObject *v;
566
567 os2_strerror(text, sizeof(text), code, "");
568
569 v = Py_BuildValue("(is)", code, text);
570 if (v != NULL) {
Barry Warsawca74da41999-02-09 19:31:45 +0000571 PyErr_SetObject(PyExc_OSError, v);
Guido van Rossumd48f2521997-12-05 22:19:34 +0000572 Py_DECREF(v);
573 }
574 return NULL; /* Signal to Python that an Exception is Pending */
575}
576
577#endif /* OS2 */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000578
579/* POSIX generic methods */
580
Barry Warsaw53699e91996-12-10 23:23:01 +0000581static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +0000582posix_fildes(PyObject *fdobj, int (*func)(int))
583{
584 int fd;
585 int res;
586 fd = PyObject_AsFileDescriptor(fdobj);
587 if (fd < 0)
588 return NULL;
589 Py_BEGIN_ALLOW_THREADS
590 res = (*func)(fd);
591 Py_END_ALLOW_THREADS
592 if (res < 0)
593 return posix_error();
594 Py_INCREF(Py_None);
595 return Py_None;
596}
Guido van Rossum21142a01999-01-08 21:05:37 +0000597
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000598#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters11b23062003-04-23 02:39:17 +0000599static int
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000600unicode_file_names(void)
601{
602 static int canusewide = -1;
603 if (canusewide == -1) {
Tim Peters11b23062003-04-23 02:39:17 +0000604 /* As per doc for ::GetVersion(), this is the correct test for
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000605 the Windows NT family. */
606 canusewide = (GetVersion() < 0x80000000) ? 1 : 0;
607 }
608 return canusewide;
609}
610#endif
Tim Peters11b23062003-04-23 02:39:17 +0000611
Guido van Rossum21142a01999-01-08 21:05:37 +0000612static PyObject *
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000613posix_1str(PyObject *args, char *format, int (*func)(const char*))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000614{
Mark Hammondef8b6542001-05-13 08:04:26 +0000615 char *path1 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000616 int res;
Tim Peters5aa91602002-01-30 05:46:57 +0000617 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +0000618 Py_FileSystemDefaultEncoding, &path1))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000619 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000620 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000621 res = (*func)(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000622 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000623 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +0000624 return posix_error_with_allocated_filename(path1);
625 PyMem_Free(path1);
Barry Warsaw53699e91996-12-10 23:23:01 +0000626 Py_INCREF(Py_None);
627 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000628}
629
Barry Warsaw53699e91996-12-10 23:23:01 +0000630static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +0000631posix_2str(PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +0000632 char *format,
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000633 int (*func)(const char *, const char *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000634{
Mark Hammondef8b6542001-05-13 08:04:26 +0000635 char *path1 = NULL, *path2 = NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000636 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +0000637 if (!PyArg_ParseTuple(args, format,
Tim Peters5aa91602002-01-30 05:46:57 +0000638 Py_FileSystemDefaultEncoding, &path1,
Mark Hammondef8b6542001-05-13 08:04:26 +0000639 Py_FileSystemDefaultEncoding, &path2))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000640 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +0000641 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +0000642 res = (*func)(path1, path2);
Barry Warsaw53699e91996-12-10 23:23:01 +0000643 Py_END_ALLOW_THREADS
Mark Hammondef8b6542001-05-13 08:04:26 +0000644 PyMem_Free(path1);
645 PyMem_Free(path2);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000646 if (res != 0)
Barry Warsawd58d7641998-07-23 16:14:40 +0000647 /* XXX how to report both path1 and path2??? */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000648 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +0000649 Py_INCREF(Py_None);
650 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000651}
652
Martin v. Löwis8e0d4942006-05-04 10:08:42 +0000653#ifdef Py_WIN_WIDE_FILENAMES
654static PyObject*
655win32_1str(PyObject* args, char* func,
656 char* format, BOOL (__stdcall *funcA)(LPCSTR),
657 char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
658{
659 PyObject *uni;
660 char *ansi;
661 BOOL result;
662 if (unicode_file_names()) {
663 if (!PyArg_ParseTuple(args, wformat, &uni))
664 PyErr_Clear();
665 else {
666 Py_BEGIN_ALLOW_THREADS
667 result = funcW(PyUnicode_AsUnicode(uni));
668 Py_END_ALLOW_THREADS
669 if (!result)
670 return win32_error_unicode(func, PyUnicode_AsUnicode(uni));
671 Py_INCREF(Py_None);
672 return Py_None;
673 }
674 }
675 if (!PyArg_ParseTuple(args, format, &ansi))
676 return NULL;
677 Py_BEGIN_ALLOW_THREADS
678 result = funcA(ansi);
679 Py_END_ALLOW_THREADS
680 if (!result)
681 return win32_error(func, ansi);
682 Py_INCREF(Py_None);
683 return Py_None;
684
685}
686
687/* This is a reimplementation of the C library's chdir function,
688 but one that produces Win32 errors instead of DOS error codes.
689 chdir is essentially a wrapper around SetCurrentDirectory; however,
690 it also needs to set "magic" environment variables indicating
691 the per-drive current directory, which are of the form =<drive>: */
692BOOL __stdcall
693win32_chdir(LPCSTR path)
694{
695 char new_path[MAX_PATH+1];
696 int result;
697 char env[4] = "=x:";
698
699 if(!SetCurrentDirectoryA(path))
700 return FALSE;
701 result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
702 if (!result)
703 return FALSE;
704 /* In the ANSI API, there should not be any paths longer
705 than MAX_PATH. */
706 assert(result <= MAX_PATH+1);
707 if (strncmp(new_path, "\\\\", 2) == 0 ||
708 strncmp(new_path, "//", 2) == 0)
709 /* UNC path, nothing to do. */
710 return TRUE;
711 env[1] = new_path[0];
712 return SetEnvironmentVariableA(env, new_path);
713}
714
715/* The Unicode version differs from the ANSI version
716 since the current directory might exceed MAX_PATH characters */
717BOOL __stdcall
718win32_wchdir(LPCWSTR path)
719{
720 wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
721 int result;
722 wchar_t env[4] = L"=x:";
723
724 if(!SetCurrentDirectoryW(path))
725 return FALSE;
726 result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
727 if (!result)
728 return FALSE;
729 if (result > MAX_PATH+1) {
730 new_path = malloc(result);
731 if (!new_path) {
732 SetLastError(ERROR_OUTOFMEMORY);
733 return FALSE;
734 }
735 }
736 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
737 wcsncmp(new_path, L"//", 2) == 0)
738 /* UNC path, nothing to do. */
739 return TRUE;
740 env[1] = new_path[0];
741 result = SetEnvironmentVariableW(env, new_path);
742 if (new_path != _new_path)
743 free(new_path);
744 return result;
745}
746#endif
747
Martin v. Löwis14694662006-02-03 12:54:16 +0000748#ifdef MS_WINDOWS
749/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
750 - time stamps are restricted to second resolution
751 - file modification times suffer from forth-and-back conversions between
752 UTC and local time
753 Therefore, we implement our own stat, based on the Win32 API directly.
754*/
755#define HAVE_STAT_NSEC 1
756
757struct win32_stat{
758 int st_dev;
759 __int64 st_ino;
760 unsigned short st_mode;
761 int st_nlink;
762 int st_uid;
763 int st_gid;
764 int st_rdev;
765 __int64 st_size;
766 int st_atime;
767 int st_atime_nsec;
768 int st_mtime;
769 int st_mtime_nsec;
770 int st_ctime;
771 int st_ctime_nsec;
772};
773
774static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
775
776static void
777FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, int *time_out, int* nsec_out)
778{
Martin v. Löwis77c176d2006-05-12 17:22:04 +0000779 /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
780 /* Cannot simply cast and dereference in_ptr,
781 since it might not be aligned properly */
782 __int64 in;
783 memcpy(&in, in_ptr, sizeof(in));
Martin v. Löwis14694662006-02-03 12:54:16 +0000784 *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
785 /* XXX Win32 supports time stamps past 2038; we currently don't */
786 *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, int);
787}
788
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +0000789static void
790time_t_to_FILE_TIME(int time_in, int nsec_in, FILETIME *out_ptr)
791{
792 /* XXX endianness */
793 __int64 out;
794 out = time_in + secs_between_epochs;
Martin v. Löwisf43893a2006-10-09 20:44:25 +0000795 out = out * 10000000 + nsec_in / 100;
Martin v. Löwis77c176d2006-05-12 17:22:04 +0000796 memcpy(out_ptr, &out, sizeof(out));
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +0000797}
798
Martin v. Löwis14694662006-02-03 12:54:16 +0000799/* Below, we *know* that ugo+r is 0444 */
800#if _S_IREAD != 0400
801#error Unsupported C library
802#endif
803static int
804attributes_to_mode(DWORD attr)
805{
806 int m = 0;
807 if (attr & FILE_ATTRIBUTE_DIRECTORY)
808 m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
809 else
810 m |= _S_IFREG;
811 if (attr & FILE_ATTRIBUTE_READONLY)
812 m |= 0444;
813 else
814 m |= 0666;
815 return m;
816}
817
818static int
819attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *result)
820{
821 memset(result, 0, sizeof(*result));
822 result->st_mode = attributes_to_mode(info->dwFileAttributes);
823 result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
824 FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
825 FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
826 FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
827
828 return 0;
829}
830
831static int
832win32_stat(const char* path, struct win32_stat *result)
833{
834 WIN32_FILE_ATTRIBUTE_DATA info;
835 int code;
836 char *dot;
837 /* XXX not supported on Win95 and NT 3.x */
838 if (!GetFileAttributesExA(path, GetFileExInfoStandard, &info)) {
839 /* Protocol violation: we explicitly clear errno, instead of
840 setting it to a POSIX error. Callers should use GetLastError. */
841 errno = 0;
842 return -1;
843 }
844 code = attribute_data_to_stat(&info, result);
845 if (code != 0)
846 return code;
847 /* Set S_IFEXEC if it is an .exe, .bat, ... */
848 dot = strrchr(path, '.');
849 if (dot) {
850 if (stricmp(dot, ".bat") == 0 ||
851 stricmp(dot, ".cmd") == 0 ||
852 stricmp(dot, ".exe") == 0 ||
853 stricmp(dot, ".com") == 0)
854 result->st_mode |= 0111;
855 }
856 return code;
857}
858
859static int
860win32_wstat(const wchar_t* path, struct win32_stat *result)
861{
862 int code;
863 const wchar_t *dot;
864 WIN32_FILE_ATTRIBUTE_DATA info;
865 /* XXX not supported on Win95 and NT 3.x */
866 if (!GetFileAttributesExW(path, GetFileExInfoStandard, &info)) {
867 /* Protocol violation: we explicitly clear errno, instead of
868 setting it to a POSIX error. Callers should use GetLastError. */
869 errno = 0;
870 return -1;
871 }
872 code = attribute_data_to_stat(&info, result);
873 if (code < 0)
874 return code;
875 /* Set IFEXEC if it is an .exe, .bat, ... */
876 dot = wcsrchr(path, '.');
877 if (dot) {
878 if (_wcsicmp(dot, L".bat") == 0 ||
879 _wcsicmp(dot, L".cmd") == 0 ||
880 _wcsicmp(dot, L".exe") == 0 ||
881 _wcsicmp(dot, L".com") == 0)
882 result->st_mode |= 0111;
883 }
884 return code;
885}
886
887static int
888win32_fstat(int file_number, struct win32_stat *result)
889{
890 BY_HANDLE_FILE_INFORMATION info;
891 HANDLE h;
892 int type;
893
894 h = (HANDLE)_get_osfhandle(file_number);
895
896 /* Protocol violation: we explicitly clear errno, instead of
897 setting it to a POSIX error. Callers should use GetLastError. */
898 errno = 0;
899
900 if (h == INVALID_HANDLE_VALUE) {
901 /* This is really a C library error (invalid file handle).
902 We set the Win32 error to the closes one matching. */
903 SetLastError(ERROR_INVALID_HANDLE);
904 return -1;
905 }
906 memset(result, 0, sizeof(*result));
907
908 type = GetFileType(h);
909 if (type == FILE_TYPE_UNKNOWN) {
910 DWORD error = GetLastError();
911 if (error != 0) {
912 return -1;
913 }
914 /* else: valid but unknown file */
915 }
916
917 if (type != FILE_TYPE_DISK) {
918 if (type == FILE_TYPE_CHAR)
919 result->st_mode = _S_IFCHR;
920 else if (type == FILE_TYPE_PIPE)
921 result->st_mode = _S_IFIFO;
922 return 0;
923 }
924
925 if (!GetFileInformationByHandle(h, &info)) {
926 return -1;
927 }
928
929 /* similar to stat() */
930 result->st_mode = attributes_to_mode(info.dwFileAttributes);
931 result->st_size = (((__int64)info.nFileSizeHigh)<<32) + info.nFileSizeLow;
932 FILE_TIME_to_time_t_nsec(&info.ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
933 FILE_TIME_to_time_t_nsec(&info.ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
934 FILE_TIME_to_time_t_nsec(&info.ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
935 /* specific to fstat() */
936 result->st_nlink = info.nNumberOfLinks;
937 result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
938 return 0;
939}
940
941#endif /* MS_WINDOWS */
942
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000943PyDoc_STRVAR(stat_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000944"stat_result: Result from stat or lstat.\n\n\
945This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +0000946 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000947or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
948\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +0000949Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
950or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000951\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000952See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000953
954static PyStructSequence_Field stat_result_fields[] = {
955 {"st_mode", "protection bits"},
956 {"st_ino", "inode"},
957 {"st_dev", "device"},
958 {"st_nlink", "number of hard links"},
959 {"st_uid", "user ID of owner"},
960 {"st_gid", "group ID of owner"},
961 {"st_size", "total size, in bytes"},
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000962 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
963 {NULL, "integer time of last access"},
964 {NULL, "integer time of last modification"},
965 {NULL, "integer time of last change"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000966 {"st_atime", "time of last access"},
967 {"st_mtime", "time of last modification"},
968 {"st_ctime", "time of last change"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000969#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000970 {"st_blksize", "blocksize for filesystem I/O"},
971#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000972#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000973 {"st_blocks", "number of blocks allocated"},
974#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000975#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000976 {"st_rdev", "device type (if inode device)"},
977#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +0000978#ifdef HAVE_STRUCT_STAT_ST_FLAGS
979 {"st_flags", "user defined flags for file"},
980#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +0000981#ifdef HAVE_STRUCT_STAT_ST_GEN
982 {"st_gen", "generation number"},
983#endif
984#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
985 {"st_birthtime", "time of creation"},
986#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000987 {0}
988};
989
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000990#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000991#define ST_BLKSIZE_IDX 13
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000992#else
Martin v. Löwisf607bda2002-10-16 18:27:39 +0000993#define ST_BLKSIZE_IDX 12
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000994#endif
995
Martin v. Löwis60a5d722002-10-16 20:28:25 +0000996#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +0000997#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
998#else
999#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1000#endif
1001
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001002#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001003#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1004#else
1005#define ST_RDEV_IDX ST_BLOCKS_IDX
1006#endif
1007
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001008#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1009#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1010#else
1011#define ST_FLAGS_IDX ST_RDEV_IDX
1012#endif
1013
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001014#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001015#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001016#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001017#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001018#endif
1019
1020#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1021#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1022#else
1023#define ST_BIRTHTIME_IDX ST_GEN_IDX
1024#endif
1025
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001026static PyStructSequence_Desc stat_result_desc = {
1027 "stat_result", /* name */
1028 stat_result__doc__, /* doc */
1029 stat_result_fields,
1030 10
1031};
1032
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001033PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001034"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1035This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001036 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001037or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001038\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001039See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001040
1041static PyStructSequence_Field statvfs_result_fields[] = {
1042 {"f_bsize", },
1043 {"f_frsize", },
1044 {"f_blocks", },
1045 {"f_bfree", },
1046 {"f_bavail", },
1047 {"f_files", },
1048 {"f_ffree", },
1049 {"f_favail", },
1050 {"f_flag", },
1051 {"f_namemax",},
1052 {0}
1053};
1054
1055static PyStructSequence_Desc statvfs_result_desc = {
1056 "statvfs_result", /* name */
1057 statvfs_result__doc__, /* doc */
1058 statvfs_result_fields,
1059 10
1060};
1061
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00001062static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001063static PyTypeObject StatResultType;
1064static PyTypeObject StatVFSResultType;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001065static newfunc structseq_new;
1066
1067static PyObject *
1068statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1069{
1070 PyStructSequence *result;
1071 int i;
1072
1073 result = (PyStructSequence*)structseq_new(type, args, kwds);
1074 if (!result)
1075 return NULL;
1076 /* If we have been initialized from a tuple,
1077 st_?time might be set to None. Initialize it
1078 from the int slots. */
1079 for (i = 7; i <= 9; i++) {
1080 if (result->ob_item[i+3] == Py_None) {
1081 Py_DECREF(Py_None);
1082 Py_INCREF(result->ob_item[i]);
1083 result->ob_item[i+3] = result->ob_item[i];
1084 }
1085 }
1086 return (PyObject*)result;
1087}
1088
1089
1090
1091/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001092static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001093
1094PyDoc_STRVAR(stat_float_times__doc__,
1095"stat_float_times([newval]) -> oldval\n\n\
1096Determine whether os.[lf]stat represents time stamps as float objects.\n\
1097If newval is True, future calls to stat() return floats, if it is False,\n\
1098future calls return ints. \n\
1099If newval is omitted, return the current setting.\n");
1100
1101static PyObject*
1102stat_float_times(PyObject* self, PyObject *args)
1103{
1104 int newval = -1;
1105 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1106 return NULL;
1107 if (newval == -1)
1108 /* Return old value */
1109 return PyBool_FromLong(_stat_float_times);
1110 _stat_float_times = newval;
1111 Py_INCREF(Py_None);
1112 return Py_None;
1113}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001114
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001115static void
1116fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
1117{
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001118 PyObject *fval,*ival;
1119#if SIZEOF_TIME_T > SIZEOF_LONG
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00001120 ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001121#else
1122 ival = PyInt_FromLong((long)sec);
1123#endif
Neal Norwitze0a81af2006-08-12 01:50:38 +00001124 if (!ival)
1125 return;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001126 if (_stat_float_times) {
1127 fval = PyFloat_FromDouble(sec + 1e-9*nsec);
1128 } else {
1129 fval = ival;
1130 Py_INCREF(fval);
1131 }
1132 PyStructSequence_SET_ITEM(v, index, ival);
1133 PyStructSequence_SET_ITEM(v, index+3, fval);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001134}
1135
Tim Peters5aa91602002-01-30 05:46:57 +00001136/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001137 (used by posix_stat() and posix_fstat()) */
1138static PyObject*
Martin v. Löwis14694662006-02-03 12:54:16 +00001139_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001140{
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001141 unsigned long ansec, mnsec, cnsec;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001142 PyObject *v = PyStructSequence_New(&StatResultType);
Fred Drake699f3522000-06-29 21:12:41 +00001143 if (v == NULL)
1144 return NULL;
1145
Martin v. Löwis14694662006-02-03 12:54:16 +00001146 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001147#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001148 PyStructSequence_SET_ITEM(v, 1,
Martin v. Löwis14694662006-02-03 12:54:16 +00001149 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001150#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001151 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001152#endif
1153#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
Tim Peters5aa91602002-01-30 05:46:57 +00001154 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwis14694662006-02-03 12:54:16 +00001155 PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001156#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001157 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001158#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001159 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st->st_nlink));
1160 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st->st_uid));
1161 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st->st_gid));
Fred Drake699f3522000-06-29 21:12:41 +00001162#ifdef HAVE_LARGEFILE_SUPPORT
Tim Peters5aa91602002-01-30 05:46:57 +00001163 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwis14694662006-02-03 12:54:16 +00001164 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001165#else
Martin v. Löwis14694662006-02-03 12:54:16 +00001166 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001167#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001168
Martin v. Löwis14694662006-02-03 12:54:16 +00001169#if defined(HAVE_STAT_TV_NSEC)
1170 ansec = st->st_atim.tv_nsec;
1171 mnsec = st->st_mtim.tv_nsec;
1172 cnsec = st->st_ctim.tv_nsec;
1173#elif defined(HAVE_STAT_TV_NSEC2)
1174 ansec = st->st_atimespec.tv_nsec;
1175 mnsec = st->st_mtimespec.tv_nsec;
1176 cnsec = st->st_ctimespec.tv_nsec;
1177#elif defined(HAVE_STAT_NSEC)
1178 ansec = st->st_atime_nsec;
1179 mnsec = st->st_mtime_nsec;
1180 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001181#else
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001182 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001183#endif
Martin v. Löwis14694662006-02-03 12:54:16 +00001184 fill_time(v, 7, st->st_atime, ansec);
1185 fill_time(v, 8, st->st_mtime, mnsec);
1186 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001187
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001188#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Tim Peters5aa91602002-01-30 05:46:57 +00001189 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001190 PyInt_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001191#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001192#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Tim Peters5aa91602002-01-30 05:46:57 +00001193 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001194 PyInt_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001195#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001196#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001197 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001198 PyInt_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001199#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001200#ifdef HAVE_STRUCT_STAT_ST_GEN
1201 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001202 PyInt_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001203#endif
1204#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1205 {
1206 PyObject *val;
1207 unsigned long bsec,bnsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001208 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001209#ifdef HAVE_STAT_TV_NSEC2
Hye-Shik Changd69e0342006-02-19 16:22:22 +00001210 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001211#else
1212 bnsec = 0;
1213#endif
1214 if (_stat_float_times) {
1215 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1216 } else {
1217 val = PyInt_FromLong((long)bsec);
1218 }
1219 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1220 val);
1221 }
1222#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001223#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1224 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
Martin v. Löwis14694662006-02-03 12:54:16 +00001225 PyInt_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001226#endif
Fred Drake699f3522000-06-29 21:12:41 +00001227
1228 if (PyErr_Occurred()) {
1229 Py_DECREF(v);
1230 return NULL;
1231 }
1232
1233 return v;
1234}
1235
Martin v. Löwisd8948722004-06-02 09:57:56 +00001236#ifdef MS_WINDOWS
1237
1238/* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
1239 where / can be used in place of \ and the trailing slash is optional.
1240 Both SERVER and SHARE must have at least one character.
1241*/
1242
1243#define ISSLASHA(c) ((c) == '\\' || (c) == '/')
1244#define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
Kristján Valur Jónssondbeaa692006-06-09 16:28:01 +00001245#ifndef ARRAYSIZE
Martin v. Löwisd8948722004-06-02 09:57:56 +00001246#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
Kristján Valur Jónssondbeaa692006-06-09 16:28:01 +00001247#endif
Martin v. Löwisd8948722004-06-02 09:57:56 +00001248
Tim Peters4ad82172004-08-30 17:02:04 +00001249static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001250IsUNCRootA(char *path, int pathlen)
1251{
1252 #define ISSLASH ISSLASHA
1253
1254 int i, share;
1255
1256 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1257 /* minimum UNCRoot is \\x\y */
1258 return FALSE;
1259 for (i = 2; i < pathlen ; i++)
1260 if (ISSLASH(path[i])) break;
1261 if (i == 2 || i == pathlen)
1262 /* do not allow \\\SHARE or \\SERVER */
1263 return FALSE;
1264 share = i+1;
1265 for (i = share; i < pathlen; i++)
1266 if (ISSLASH(path[i])) break;
1267 return (i != share && (i == pathlen || i == pathlen-1));
1268
1269 #undef ISSLASH
1270}
1271
1272#ifdef Py_WIN_WIDE_FILENAMES
Tim Peters4ad82172004-08-30 17:02:04 +00001273static BOOL
Martin v. Löwisd8948722004-06-02 09:57:56 +00001274IsUNCRootW(Py_UNICODE *path, int pathlen)
1275{
1276 #define ISSLASH ISSLASHW
1277
1278 int i, share;
1279
1280 if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
1281 /* minimum UNCRoot is \\x\y */
1282 return FALSE;
1283 for (i = 2; i < pathlen ; i++)
1284 if (ISSLASH(path[i])) break;
1285 if (i == 2 || i == pathlen)
1286 /* do not allow \\\SHARE or \\SERVER */
1287 return FALSE;
1288 share = i+1;
1289 for (i = share; i < pathlen; i++)
1290 if (ISSLASH(path[i])) break;
1291 return (i != share && (i == pathlen || i == pathlen-1));
1292
1293 #undef ISSLASH
1294}
1295#endif /* Py_WIN_WIDE_FILENAMES */
1296#endif /* MS_WINDOWS */
1297
Barry Warsaw53699e91996-12-10 23:23:01 +00001298static PyObject *
Tim Peters11b23062003-04-23 02:39:17 +00001299posix_do_stat(PyObject *self, PyObject *args,
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001300 char *format,
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001301#ifdef __VMS
1302 int (*statfunc)(const char *, STRUCT_STAT *, ...),
1303#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001304 int (*statfunc)(const char *, STRUCT_STAT *),
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001305#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001306 char *wformat,
1307 int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001308{
Fred Drake699f3522000-06-29 21:12:41 +00001309 STRUCT_STAT st;
Tim Peters500bd032001-12-19 19:05:01 +00001310 char *path = NULL; /* pass this to stat; do not free() it */
1311 char *pathfree = NULL; /* this memory must be free'd */
Guido van Rossumff4949e1992-08-05 19:58:53 +00001312 int res;
Martin v. Löwis14694662006-02-03 12:54:16 +00001313 PyObject *result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001314
1315#ifdef Py_WIN_WIDE_FILENAMES
1316 /* If on wide-character-capable OS see if argument
1317 is Unicode and if so use wide API. */
1318 if (unicode_file_names()) {
1319 PyUnicodeObject *po;
1320 if (PyArg_ParseTuple(args, wformat, &po)) {
Martin v. Löwis14694662006-02-03 12:54:16 +00001321 Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
1322
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001323 Py_BEGIN_ALLOW_THREADS
1324 /* PyUnicode_AS_UNICODE result OK without
1325 thread lock as it is a simple dereference. */
1326 res = wstatfunc(wpath, &st);
1327 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001328
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001329 if (res != 0)
Martin v. Löwis14694662006-02-03 12:54:16 +00001330 return win32_error_unicode("stat", wpath);
1331 return _pystat_fromstructstat(&st);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001332 }
1333 /* Drop the argument parsing error as narrow strings
1334 are also valid. */
1335 PyErr_Clear();
1336 }
1337#endif
1338
Tim Peters5aa91602002-01-30 05:46:57 +00001339 if (!PyArg_ParseTuple(args, format,
Mark Hammondef8b6542001-05-13 08:04:26 +00001340 Py_FileSystemDefaultEncoding, &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001341 return NULL;
Tim Peters500bd032001-12-19 19:05:01 +00001342 pathfree = path;
Guido van Rossumace88ae2000-04-21 18:54:45 +00001343
Barry Warsaw53699e91996-12-10 23:23:01 +00001344 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001345 res = (*statfunc)(path, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00001346 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00001347
1348 if (res != 0) {
1349#ifdef MS_WINDOWS
1350 result = win32_error("stat", pathfree);
1351#else
1352 result = posix_error_with_filename(pathfree);
1353#endif
1354 }
1355 else
1356 result = _pystat_fromstructstat(&st);
Fred Drake699f3522000-06-29 21:12:41 +00001357
Tim Peters500bd032001-12-19 19:05:01 +00001358 PyMem_Free(pathfree);
Martin v. Löwis14694662006-02-03 12:54:16 +00001359 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001360}
1361
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001362/* POSIX methods */
1363
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001364PyDoc_STRVAR(posix_access__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001365"access(path, mode) -> 1 if granted, 0 otherwise\n\n\
Guido van Rossuma0b90752002-06-18 16:22:43 +00001366Use the real uid/gid to test for access to a path. Note that most\n\
1367operations will use the effective uid/gid, therefore this routine can\n\
1368be used in a suid/sgid environment to test if the invoking user has the\n\
1369specified access to the path. The mode argument can be F_OK to test\n\
1370existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001371
1372static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001373posix_access(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001374{
Guido van Rossum015f22a1999-01-06 22:52:38 +00001375 char *path;
1376 int mode;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001377
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001378#ifdef Py_WIN_WIDE_FILENAMES
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001379 DWORD attr;
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001380 if (unicode_file_names()) {
1381 PyUnicodeObject *po;
1382 if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
1383 Py_BEGIN_ALLOW_THREADS
1384 /* PyUnicode_AS_UNICODE OK without thread lock as
1385 it is a simple dereference. */
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001386 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001387 Py_END_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001388 goto finish;
Martin v. Löwis1b699a52003-09-12 16:25:38 +00001389 }
1390 /* Drop the argument parsing error as narrow strings
1391 are also valid. */
1392 PyErr_Clear();
1393 }
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001394 if (!PyArg_ParseTuple(args, "eti:access",
1395 Py_FileSystemDefaultEncoding, &path, &mode))
1396 return 0;
1397 Py_BEGIN_ALLOW_THREADS
1398 attr = GetFileAttributesA(path);
1399 Py_END_ALLOW_THREADS
1400 PyMem_Free(path);
1401finish:
1402 if (attr == 0xFFFFFFFF)
1403 /* File does not exist, or cannot read attributes */
1404 return PyBool_FromLong(0);
1405 /* Access is possible if either write access wasn't requested, or
1406 the file isn't read-only. */
Martin v. Löwisee1e06d2006-07-02 18:44:00 +00001407 return PyBool_FromLong(!(mode & 2) || !(attr & FILE_ATTRIBUTE_READONLY));
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001408#else
1409 int res;
Martin v. Löwisb60ae992005-03-08 09:10:29 +00001410 if (!PyArg_ParseTuple(args, "eti:access",
1411 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossum015f22a1999-01-06 22:52:38 +00001412 return NULL;
1413 Py_BEGIN_ALLOW_THREADS
1414 res = access(path, mode);
1415 Py_END_ALLOW_THREADS
Neal Norwitz24b3c222005-09-19 06:43:44 +00001416 PyMem_Free(path);
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001417 return PyBool_FromLong(res == 0);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001418#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001419}
1420
Guido van Rossumd371ff11999-01-25 16:12:23 +00001421#ifndef F_OK
1422#define F_OK 0
1423#endif
1424#ifndef R_OK
1425#define R_OK 4
1426#endif
1427#ifndef W_OK
1428#define W_OK 2
1429#endif
1430#ifndef X_OK
1431#define X_OK 1
1432#endif
1433
1434#ifdef HAVE_TTYNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001435PyDoc_STRVAR(posix_ttyname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001436"ttyname(fd) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001437Return the name of the terminal device connected to 'fd'.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00001438
1439static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001440posix_ttyname(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00001441{
Guido van Rossum94f6f721999-01-06 18:42:14 +00001442 int id;
1443 char *ret;
1444
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001445 if (!PyArg_ParseTuple(args, "i:ttyname", &id))
Guido van Rossum94f6f721999-01-06 18:42:14 +00001446 return NULL;
1447
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001448#if defined(__VMS)
Martin v. Löwisc16f3bd2003-05-03 09:14:54 +00001449 /* file descriptor 0 only, the default input device (stdin) */
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001450 if (id == 0) {
1451 ret = ttyname();
1452 }
1453 else {
1454 ret = NULL;
1455 }
1456#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00001457 ret = ttyname(id);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001458#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001459 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001460 return posix_error();
1461 return PyString_FromString(ret);
Guido van Rossum94f6f721999-01-06 18:42:14 +00001462}
Guido van Rossumd371ff11999-01-25 16:12:23 +00001463#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00001464
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001465#ifdef HAVE_CTERMID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001466PyDoc_STRVAR(posix_ctermid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001467"ctermid() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001468Return the name of the controlling terminal for this process.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001469
1470static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001471posix_ctermid(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001472{
1473 char *ret;
1474 char buffer[L_ctermid];
1475
Greg Wardb48bc172000-03-01 21:51:56 +00001476#ifdef USE_CTERMID_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001477 ret = ctermid_r(buffer);
1478#else
1479 ret = ctermid(buffer);
1480#endif
1481 if (ret == NULL)
Neal Norwitz3efd0a12005-09-19 06:45:53 +00001482 return posix_error();
1483 return PyString_FromString(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001484}
1485#endif
1486
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001487PyDoc_STRVAR(posix_chdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001488"chdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001489Change the current working directory to the specified path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001490
Barry Warsaw53699e91996-12-10 23:23:01 +00001491static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001492posix_chdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001493{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001494#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001495 return win32_1str(args, "chdir", "s:chdir", win32_chdir, "U:chdir", win32_wchdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001496#elif defined(PYOS_OS2) && defined(PYCC_GCC)
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001497 return posix_1str(args, "et:chdir", _chdir2);
Martin v. Löwis7a924e62003-03-05 14:15:21 +00001498#elif defined(__VMS)
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001499 return posix_1str(args, "et:chdir", (int (*)(const char *))chdir);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001500#else
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001501 return posix_1str(args, "et:chdir", chdir);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001502#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001503}
1504
Fred Drake4d1e64b2002-04-15 19:40:07 +00001505#ifdef HAVE_FCHDIR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001506PyDoc_STRVAR(posix_fchdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001507"fchdir(fildes)\n\n\
Fred Drake4d1e64b2002-04-15 19:40:07 +00001508Change to the directory of the given file descriptor. fildes must be\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001509opened on a directory, not a file.");
Fred Drake4d1e64b2002-04-15 19:40:07 +00001510
1511static PyObject *
1512posix_fchdir(PyObject *self, PyObject *fdobj)
1513{
1514 return posix_fildes(fdobj, fchdir);
1515}
1516#endif /* HAVE_FCHDIR */
1517
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001518
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001519PyDoc_STRVAR(posix_chmod__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001520"chmod(path, mode)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001521Change the access permissions of a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001522
Barry Warsaw53699e91996-12-10 23:23:01 +00001523static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001524posix_chmod(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001525{
Mark Hammondef8b6542001-05-13 08:04:26 +00001526 char *path = NULL;
Guido van Rossumffd15f52000-03-31 00:47:28 +00001527 int i;
1528 int res;
Mark Hammond817c9292003-12-03 01:22:38 +00001529#ifdef Py_WIN_WIDE_FILENAMES
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001530 DWORD attr;
Mark Hammond817c9292003-12-03 01:22:38 +00001531 if (unicode_file_names()) {
1532 PyUnicodeObject *po;
1533 if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
1534 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001535 attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
1536 if (attr != 0xFFFFFFFF) {
1537 if (i & _S_IWRITE)
1538 attr &= ~FILE_ATTRIBUTE_READONLY;
1539 else
1540 attr |= FILE_ATTRIBUTE_READONLY;
1541 res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
1542 }
1543 else
1544 res = 0;
Mark Hammond817c9292003-12-03 01:22:38 +00001545 Py_END_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001546 if (!res)
1547 return win32_error_unicode("chmod",
Mark Hammond817c9292003-12-03 01:22:38 +00001548 PyUnicode_AS_UNICODE(po));
1549 Py_INCREF(Py_None);
1550 return Py_None;
1551 }
1552 /* Drop the argument parsing error as narrow strings
1553 are also valid. */
1554 PyErr_Clear();
1555 }
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001556 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
1557 &path, &i))
1558 return NULL;
1559 Py_BEGIN_ALLOW_THREADS
1560 attr = GetFileAttributesA(path);
1561 if (attr != 0xFFFFFFFF) {
1562 if (i & _S_IWRITE)
1563 attr &= ~FILE_ATTRIBUTE_READONLY;
1564 else
1565 attr |= FILE_ATTRIBUTE_READONLY;
1566 res = SetFileAttributesA(path, attr);
1567 }
1568 else
1569 res = 0;
1570 Py_END_ALLOW_THREADS
1571 if (!res) {
1572 win32_error("chmod", path);
1573 PyMem_Free(path);
1574 return NULL;
1575 }
Martin v. Löwis9f485bc2006-05-08 05:25:56 +00001576 PyMem_Free(path);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001577 Py_INCREF(Py_None);
1578 return Py_None;
1579#else /* Py_WIN_WIDE_FILENAMES */
Mark Hammond817c9292003-12-03 01:22:38 +00001580 if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
Mark Hammondef8b6542001-05-13 08:04:26 +00001581 &path, &i))
Guido van Rossumffd15f52000-03-31 00:47:28 +00001582 return NULL;
1583 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef40e772000-03-31 01:26:23 +00001584 res = chmod(path, i);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001585 Py_END_ALLOW_THREADS
1586 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001587 return posix_error_with_allocated_filename(path);
1588 PyMem_Free(path);
Guido van Rossumffd15f52000-03-31 00:47:28 +00001589 Py_INCREF(Py_None);
1590 return Py_None;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001591#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001592}
1593
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001594
Martin v. Löwis244edc82001-10-04 22:44:26 +00001595#ifdef HAVE_CHROOT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001596PyDoc_STRVAR(posix_chroot__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001597"chroot(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001598Change root directory to path.");
Martin v. Löwis244edc82001-10-04 22:44:26 +00001599
1600static PyObject *
1601posix_chroot(PyObject *self, PyObject *args)
1602{
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00001603 return posix_1str(args, "et:chroot", chroot);
Martin v. Löwis244edc82001-10-04 22:44:26 +00001604}
1605#endif
1606
Guido van Rossum21142a01999-01-08 21:05:37 +00001607#ifdef HAVE_FSYNC
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001608PyDoc_STRVAR(posix_fsync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001609"fsync(fildes)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001610force write of file with filedescriptor to disk.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001611
1612static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001613posix_fsync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001614{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001615 return posix_fildes(fdobj, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001616}
1617#endif /* HAVE_FSYNC */
1618
1619#ifdef HAVE_FDATASYNC
Guido van Rossumecc23b02000-09-22 16:01:05 +00001620
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00001621#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00001622extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
1623#endif
1624
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001625PyDoc_STRVAR(posix_fdatasync__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001626"fdatasync(fildes)\n\n\
Guido van Rossum21142a01999-01-08 21:05:37 +00001627force write of file with filedescriptor to disk.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001628 does not force update of metadata.");
Guido van Rossum21142a01999-01-08 21:05:37 +00001629
1630static PyObject *
Fred Drake4d1e64b2002-04-15 19:40:07 +00001631posix_fdatasync(PyObject *self, PyObject *fdobj)
Guido van Rossum21142a01999-01-08 21:05:37 +00001632{
Fred Drake4d1e64b2002-04-15 19:40:07 +00001633 return posix_fildes(fdobj, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00001634}
1635#endif /* HAVE_FDATASYNC */
1636
1637
Fredrik Lundh10723342000-07-10 16:38:09 +00001638#ifdef HAVE_CHOWN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001639PyDoc_STRVAR(posix_chown__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001640"chown(path, uid, gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001641Change the owner and group id of path to the numeric uid and gid.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001642
Barry Warsaw53699e91996-12-10 23:23:01 +00001643static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001644posix_chown(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001645{
Mark Hammondef8b6542001-05-13 08:04:26 +00001646 char *path = NULL;
Fredrik Lundh44328e62000-07-10 15:59:30 +00001647 int uid, gid;
1648 int res;
Tim Peters5aa91602002-01-30 05:46:57 +00001649 if (!PyArg_ParseTuple(args, "etii:chown",
1650 Py_FileSystemDefaultEncoding, &path,
Mark Hammondef8b6542001-05-13 08:04:26 +00001651 &uid, &gid))
Fredrik Lundh44328e62000-07-10 15:59:30 +00001652 return NULL;
1653 Py_BEGIN_ALLOW_THREADS
1654 res = chown(path, (uid_t) uid, (gid_t) gid);
1655 Py_END_ALLOW_THREADS
1656 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00001657 return posix_error_with_allocated_filename(path);
1658 PyMem_Free(path);
Fredrik Lundh44328e62000-07-10 15:59:30 +00001659 Py_INCREF(Py_None);
1660 return Py_None;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001661}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001662#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001663
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001664#ifdef HAVE_LCHOWN
1665PyDoc_STRVAR(posix_lchown__doc__,
1666"lchown(path, uid, gid)\n\n\
1667Change the owner and group id of path to the numeric uid and gid.\n\
1668This function will not follow symbolic links.");
1669
1670static PyObject *
1671posix_lchown(PyObject *self, PyObject *args)
1672{
1673 char *path = NULL;
1674 int uid, gid;
1675 int res;
1676 if (!PyArg_ParseTuple(args, "etii:lchown",
1677 Py_FileSystemDefaultEncoding, &path,
1678 &uid, &gid))
1679 return NULL;
1680 Py_BEGIN_ALLOW_THREADS
1681 res = lchown(path, (uid_t) uid, (gid_t) gid);
1682 Py_END_ALLOW_THREADS
Tim Peters11b23062003-04-23 02:39:17 +00001683 if (res < 0)
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00001684 return posix_error_with_allocated_filename(path);
1685 PyMem_Free(path);
1686 Py_INCREF(Py_None);
1687 return Py_None;
1688}
1689#endif /* HAVE_LCHOWN */
1690
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001691
Guido van Rossum36bc6801995-06-14 22:54:23 +00001692#ifdef HAVE_GETCWD
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001693PyDoc_STRVAR(posix_getcwd__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001694"getcwd() -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001695Return a string representing the current working directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001696
Barry Warsaw53699e91996-12-10 23:23:01 +00001697static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001698posix_getcwd(PyObject *self, PyObject *noargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001699{
1700 char buf[1026];
Guido van Rossumff4949e1992-08-05 19:58:53 +00001701 char *res;
Neal Norwitze241ce82003-02-17 18:17:05 +00001702
Barry Warsaw53699e91996-12-10 23:23:01 +00001703 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001704#if defined(PYOS_OS2) && defined(PYCC_GCC)
1705 res = _getcwd2(buf, sizeof buf);
Martin v. Löwis79acb9e2002-12-06 12:48:53 +00001706#else
Guido van Rossumff4949e1992-08-05 19:58:53 +00001707 res = getcwd(buf, sizeof buf);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001708#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00001709 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00001710 if (res == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001711 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00001712 return PyString_FromString(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001713}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001714
Walter Dörwald3b918c32002-11-21 20:18:46 +00001715#ifdef Py_USING_UNICODE
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001716PyDoc_STRVAR(posix_getcwdu__doc__,
1717"getcwdu() -> path\n\n\
1718Return a unicode string representing the current working directory.");
1719
1720static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00001721posix_getcwdu(PyObject *self, PyObject *noargs)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001722{
1723 char buf[1026];
1724 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001725
1726#ifdef Py_WIN_WIDE_FILENAMES
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001727 DWORD len;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001728 if (unicode_file_names()) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001729 wchar_t wbuf[1026];
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001730 wchar_t *wbuf2 = wbuf;
1731 PyObject *resobj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001732 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001733 len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
1734 /* If the buffer is large enough, len does not include the
1735 terminating \0. If the buffer is too small, len includes
1736 the space needed for the terminator. */
1737 if (len >= sizeof wbuf/ sizeof wbuf[0]) {
1738 wbuf2 = malloc(len * sizeof(wchar_t));
1739 if (wbuf2)
1740 len = GetCurrentDirectoryW(len, wbuf2);
1741 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001742 Py_END_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00001743 if (!wbuf2) {
1744 PyErr_NoMemory();
1745 return NULL;
1746 }
1747 if (!len) {
1748 if (wbuf2 != wbuf) free(wbuf2);
1749 return win32_error("getcwdu", NULL);
1750 }
1751 resobj = PyUnicode_FromWideChar(wbuf2, len);
1752 if (wbuf2 != wbuf) free(wbuf2);
1753 return resobj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001754 }
1755#endif
1756
1757 Py_BEGIN_ALLOW_THREADS
1758#if defined(PYOS_OS2) && defined(PYCC_GCC)
1759 res = _getcwd2(buf, sizeof buf);
1760#else
1761 res = getcwd(buf, sizeof buf);
1762#endif
1763 Py_END_ALLOW_THREADS
1764 if (res == NULL)
1765 return posix_error();
1766 return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
1767}
Guido van Rossum36bc6801995-06-14 22:54:23 +00001768#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00001769#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001770
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001771
Guido van Rossumb6775db1994-08-01 11:34:53 +00001772#ifdef HAVE_LINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001773PyDoc_STRVAR(posix_link__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001774"link(src, dst)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001775Create a hard link to a file.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001776
Barry Warsaw53699e91996-12-10 23:23:01 +00001777static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001778posix_link(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001779{
Martin v. Löwis4fc2bda2006-05-04 12:04:27 +00001780 return posix_2str(args, "etet:link", link);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001781}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001782#endif /* HAVE_LINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001783
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001784
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001785PyDoc_STRVAR(posix_listdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00001786"listdir(path) -> list_of_strings\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001787Return a list containing the names of the entries in the directory.\n\
1788\n\
1789 path: path of directory to list\n\
1790\n\
1791The list is in arbitrary order. It does not include the special\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001792entries '.' and '..' even if they are present in the directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00001793
Barry Warsaw53699e91996-12-10 23:23:01 +00001794static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00001795posix_listdir(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001796{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001797 /* XXX Should redo this putting the (now four) versions of opendir
Guido van Rossum6d8841c1997-08-14 19:57:39 +00001798 in separate files instead of having them all here... */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001799#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001800
Barry Warsaw53699e91996-12-10 23:23:01 +00001801 PyObject *d, *v;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001802 HANDLE hFindFile;
Martin v. Löwise920f0d2006-03-07 23:59:33 +00001803 BOOL result;
Guido van Rossumb6775db1994-08-01 11:34:53 +00001804 WIN32_FIND_DATA FileData;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00001805 char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
Mark Hammondef8b6542001-05-13 08:04:26 +00001806 char *bufptr = namebuf;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00001807 Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
Guido van Rossumb6775db1994-08-01 11:34:53 +00001808
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001809#ifdef Py_WIN_WIDE_FILENAMES
1810 /* If on wide-character-capable OS see if argument
1811 is Unicode and if so use wide API. */
1812 if (unicode_file_names()) {
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00001813 PyObject *po;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001814 if (PyArg_ParseTuple(args, "U:listdir", &po)) {
1815 WIN32_FIND_DATAW wFileData;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00001816 Py_UNICODE *wnamebuf;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001817 Py_UNICODE wch;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00001818 /* Overallocate for \\*.*\0 */
1819 len = PyUnicode_GET_SIZE(po);
1820 wnamebuf = malloc((len + 5) * sizeof(wchar_t));
1821 if (!wnamebuf) {
1822 PyErr_NoMemory();
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001823 return NULL;
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00001824 }
1825 wcscpy(wnamebuf, PyUnicode_AS_UNICODE(po));
1826 wch = len > 0 ? wnamebuf[len-1] : '\0';
1827 if (wch != L'/' && wch != L'\\' && wch != L':')
1828 wnamebuf[len++] = L'\\';
1829 wcscpy(wnamebuf + len, L"*.*");
1830 if ((d = PyList_New(0)) == NULL) {
1831 free(wnamebuf);
1832 return NULL;
1833 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001834 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
1835 if (hFindFile == INVALID_HANDLE_VALUE) {
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00001836 int error = GetLastError();
1837 if (error == ERROR_FILE_NOT_FOUND) {
1838 free(wnamebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001839 return d;
1840 }
1841 Py_DECREF(d);
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00001842 win32_error_unicode("FindFirstFileW", wnamebuf);
1843 free(wnamebuf);
1844 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001845 }
1846 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00001847 /* Skip over . and .. */
1848 if (wcscmp(wFileData.cFileName, L".") != 0 &&
1849 wcscmp(wFileData.cFileName, L"..") != 0) {
1850 v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
1851 if (v == NULL) {
1852 Py_DECREF(d);
1853 d = NULL;
1854 break;
1855 }
1856 if (PyList_Append(d, v) != 0) {
1857 Py_DECREF(v);
1858 Py_DECREF(d);
1859 d = NULL;
1860 break;
1861 }
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001862 Py_DECREF(v);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001863 }
Georg Brandl622927b2006-03-07 12:48:03 +00001864 Py_BEGIN_ALLOW_THREADS
1865 result = FindNextFileW(hFindFile, &wFileData);
1866 Py_END_ALLOW_THREADS
Martin v. Löwis982e9fe2006-07-24 12:54:17 +00001867 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
1868 it got to the end of the directory. */
1869 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
1870 Py_DECREF(d);
1871 win32_error_unicode("FindNextFileW", wnamebuf);
1872 FindClose(hFindFile);
1873 free(wnamebuf);
1874 return NULL;
1875 }
Georg Brandl622927b2006-03-07 12:48:03 +00001876 } while (result == TRUE);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001877
1878 if (FindClose(hFindFile) == FALSE) {
1879 Py_DECREF(d);
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00001880 win32_error_unicode("FindClose", wnamebuf);
1881 free(wnamebuf);
1882 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001883 }
Martin v. Löwise3edaea2006-05-15 05:51:36 +00001884 free(wnamebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001885 return d;
1886 }
1887 /* Drop the argument parsing error as narrow strings
1888 are also valid. */
1889 PyErr_Clear();
1890 }
1891#endif
1892
Tim Peters5aa91602002-01-30 05:46:57 +00001893 if (!PyArg_ParseTuple(args, "et#:listdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00001894 Py_FileSystemDefaultEncoding, &bufptr, &len))
Guido van Rossumb6775db1994-08-01 11:34:53 +00001895 return NULL;
Neil Schemenauer94b866a2002-03-22 20:51:58 +00001896 if (len > 0) {
1897 char ch = namebuf[len-1];
1898 if (ch != SEP && ch != ALTSEP && ch != ':')
1899 namebuf[len++] = '/';
1900 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001901 strcpy(namebuf + len, "*.*");
1902
Barry Warsaw53699e91996-12-10 23:23:01 +00001903 if ((d = PyList_New(0)) == NULL)
Guido van Rossumb6775db1994-08-01 11:34:53 +00001904 return NULL;
1905
1906 hFindFile = FindFirstFile(namebuf, &FileData);
1907 if (hFindFile == INVALID_HANDLE_VALUE) {
Martin v. Löwis682b1bb2006-05-12 12:27:28 +00001908 int error = GetLastError();
1909 if (error == ERROR_FILE_NOT_FOUND)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001910 return d;
1911 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00001912 return win32_error("FindFirstFile", namebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001913 }
1914 do {
Martin v. Löwise920f0d2006-03-07 23:59:33 +00001915 /* Skip over . and .. */
1916 if (strcmp(FileData.cFileName, ".") != 0 &&
1917 strcmp(FileData.cFileName, "..") != 0) {
1918 v = PyString_FromString(FileData.cFileName);
1919 if (v == NULL) {
1920 Py_DECREF(d);
1921 d = NULL;
1922 break;
1923 }
1924 if (PyList_Append(d, v) != 0) {
1925 Py_DECREF(v);
1926 Py_DECREF(d);
1927 d = NULL;
1928 break;
1929 }
Barry Warsaw53699e91996-12-10 23:23:01 +00001930 Py_DECREF(v);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001931 }
Georg Brandl622927b2006-03-07 12:48:03 +00001932 Py_BEGIN_ALLOW_THREADS
1933 result = FindNextFile(hFindFile, &FileData);
1934 Py_END_ALLOW_THREADS
Martin v. Löwis982e9fe2006-07-24 12:54:17 +00001935 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
1936 it got to the end of the directory. */
1937 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
1938 Py_DECREF(d);
1939 win32_error("FindNextFile", namebuf);
1940 FindClose(hFindFile);
1941 return NULL;
1942 }
Georg Brandl622927b2006-03-07 12:48:03 +00001943 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00001944
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001945 if (FindClose(hFindFile) == FALSE) {
1946 Py_DECREF(d);
Mark Hammondef8b6542001-05-13 08:04:26 +00001947 return win32_error("FindClose", namebuf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001948 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00001949
1950 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00001951
Tim Peters0bb44a42000-09-15 07:44:49 +00001952#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001953
1954#ifndef MAX_PATH
1955#define MAX_PATH CCHMAXPATH
1956#endif
1957 char *name, *pt;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00001958 Py_ssize_t len;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001959 PyObject *d, *v;
1960 char namebuf[MAX_PATH+5];
1961 HDIR hdir = 1;
1962 ULONG srchcnt = 1;
1963 FILEFINDBUF3 ep;
1964 APIRET rc;
1965
Fred Drake5ab8eaf1999-12-09 21:13:07 +00001966 if (!PyArg_ParseTuple(args, "t#:listdir", &name, &len))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001967 return NULL;
1968 if (len >= MAX_PATH) {
1969 PyErr_SetString(PyExc_ValueError, "path too long");
1970 return NULL;
1971 }
1972 strcpy(namebuf, name);
1973 for (pt = namebuf; *pt; pt++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001974 if (*pt == ALTSEP)
1975 *pt = SEP;
1976 if (namebuf[len-1] != SEP)
1977 namebuf[len++] = SEP;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001978 strcpy(namebuf + len, "*.*");
1979
1980 if ((d = PyList_New(0)) == NULL)
1981 return NULL;
1982
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001983 rc = DosFindFirst(namebuf, /* Wildcard Pattern to Match */
1984 &hdir, /* Handle to Use While Search Directory */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001985 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001986 &ep, sizeof(ep), /* Structure to Receive Directory Entry */
1987 &srchcnt, /* Max and Actual Count of Entries Per Iteration */
1988 FIL_STANDARD); /* Format of Entry (EAs or Not) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001989
1990 if (rc != NO_ERROR) {
1991 errno = ENOENT;
Barry Warsawf63b8cc1999-05-27 23:13:21 +00001992 return posix_error_with_filename(name);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001993 }
1994
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001995 if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00001996 do {
1997 if (ep.achName[0] == '.'
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00001998 && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
Guido van Rossumc5a0f531997-12-02 20:36:02 +00001999 continue; /* Skip Over "." and ".." Names */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002000
2001 strcpy(namebuf, ep.achName);
2002
Guido van Rossumc5a0f531997-12-02 20:36:02 +00002003 /* Leave Case of Name Alone -- In Native Form */
2004 /* (Removed Forced Lowercasing Code) */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00002005
2006 v = PyString_FromString(namebuf);
2007 if (v == NULL) {
2008 Py_DECREF(d);
2009 d = NULL;
2010 break;
2011 }
2012 if (PyList_Append(d, v) != 0) {
2013 Py_DECREF(v);
2014 Py_DECREF(d);
2015 d = NULL;
2016 break;
2017 }
2018 Py_DECREF(v);
2019 } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
2020 }
2021
2022 return d;
2023#else
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002024
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002025 char *name = NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002026 PyObject *d, *v;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002027 DIR *dirp;
Guido van Rossumb6775db1994-08-01 11:34:53 +00002028 struct dirent *ep;
Just van Rossum96b1c902003-03-03 17:32:15 +00002029 int arg_is_unicode = 1;
2030
Georg Brandl05e89b82006-04-11 07:04:06 +00002031 errno = 0;
Just van Rossum96b1c902003-03-03 17:32:15 +00002032 if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
2033 arg_is_unicode = 0;
2034 PyErr_Clear();
2035 }
2036 if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002037 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002038 if ((dirp = opendir(name)) == NULL) {
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002039 return posix_error_with_allocated_filename(name);
Guido van Rossumff4949e1992-08-05 19:58:53 +00002040 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002041 if ((d = PyList_New(0)) == NULL) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002042 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002043 PyMem_Free(name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002044 return NULL;
2045 }
Georg Brandl622927b2006-03-07 12:48:03 +00002046 for (;;) {
2047 Py_BEGIN_ALLOW_THREADS
2048 ep = readdir(dirp);
2049 Py_END_ALLOW_THREADS
2050 if (ep == NULL)
2051 break;
Guido van Rossum24f42ac1995-07-18 18:16:52 +00002052 if (ep->d_name[0] == '.' &&
2053 (NAMLEN(ep) == 1 ||
Guido van Rossuma376cc51996-12-05 23:43:35 +00002054 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
Guido van Rossum24f42ac1995-07-18 18:16:52 +00002055 continue;
Barry Warsaw53699e91996-12-10 23:23:01 +00002056 v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002057 if (v == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002058 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002059 d = NULL;
2060 break;
2061 }
Just van Rossum46c97842003-02-25 21:42:15 +00002062#ifdef Py_USING_UNICODE
Just van Rossum96b1c902003-03-03 17:32:15 +00002063 if (arg_is_unicode) {
Just van Rossum46c97842003-02-25 21:42:15 +00002064 PyObject *w;
2065
2066 w = PyUnicode_FromEncodedObject(v,
Tim Peters11b23062003-04-23 02:39:17 +00002067 Py_FileSystemDefaultEncoding,
Just van Rossum46c97842003-02-25 21:42:15 +00002068 "strict");
Just van Rossum6a421832003-03-04 19:30:44 +00002069 if (w != NULL) {
2070 Py_DECREF(v);
2071 v = w;
2072 }
2073 else {
2074 /* fall back to the original byte string, as
2075 discussed in patch #683592 */
2076 PyErr_Clear();
Just van Rossum46c97842003-02-25 21:42:15 +00002077 }
Just van Rossum46c97842003-02-25 21:42:15 +00002078 }
2079#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002080 if (PyList_Append(d, v) != 0) {
2081 Py_DECREF(v);
2082 Py_DECREF(d);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002083 d = NULL;
2084 break;
2085 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002086 Py_DECREF(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002087 }
Georg Brandlbbfe4fa2006-04-11 06:47:43 +00002088 if (errno != 0 && d != NULL) {
2089 /* readdir() returned NULL and set errno */
2090 closedir(dirp);
2091 Py_DECREF(d);
2092 return posix_error_with_allocated_filename(name);
2093 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002094 closedir(dirp);
Just van Rossum2fe07fd2003-03-03 19:07:13 +00002095 PyMem_Free(name);
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00002096
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002097 return d;
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00002098
Tim Peters0bb44a42000-09-15 07:44:49 +00002099#endif /* which OS */
2100} /* end of posix_listdir */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002101
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002102#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00002103/* A helper function for abspath on win32 */
2104static PyObject *
2105posix__getfullpathname(PyObject *self, PyObject *args)
2106{
2107 /* assume encoded strings wont more than double no of chars */
2108 char inbuf[MAX_PATH*2];
2109 char *inbufp = inbuf;
Tim Peters67d70eb2006-03-01 04:35:45 +00002110 Py_ssize_t insize = sizeof(inbuf);
Mark Hammondef8b6542001-05-13 08:04:26 +00002111 char outbuf[MAX_PATH*2];
2112 char *temp;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002113#ifdef Py_WIN_WIDE_FILENAMES
2114 if (unicode_file_names()) {
2115 PyUnicodeObject *po;
2116 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
2117 Py_UNICODE woutbuf[MAX_PATH*2];
2118 Py_UNICODE *wtemp;
Tim Peters11b23062003-04-23 02:39:17 +00002119 if (!GetFullPathNameW(PyUnicode_AS_UNICODE(po),
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002120 sizeof(woutbuf)/sizeof(woutbuf[0]),
2121 woutbuf, &wtemp))
2122 return win32_error("GetFullPathName", "");
2123 return PyUnicode_FromUnicode(woutbuf, wcslen(woutbuf));
2124 }
2125 /* Drop the argument parsing error as narrow strings
2126 are also valid. */
2127 PyErr_Clear();
2128 }
2129#endif
Tim Peters5aa91602002-01-30 05:46:57 +00002130 if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
2131 Py_FileSystemDefaultEncoding, &inbufp,
Mark Hammondef8b6542001-05-13 08:04:26 +00002132 &insize))
2133 return NULL;
2134 if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
2135 outbuf, &temp))
2136 return win32_error("GetFullPathName", inbuf);
Martin v. Löwis969297f2004-06-15 18:49:58 +00002137 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
2138 return PyUnicode_Decode(outbuf, strlen(outbuf),
2139 Py_FileSystemDefaultEncoding, NULL);
2140 }
Mark Hammondef8b6542001-05-13 08:04:26 +00002141 return PyString_FromString(outbuf);
2142} /* end of posix__getfullpathname */
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00002143#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00002144
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002145PyDoc_STRVAR(posix_mkdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002146"mkdir(path [, mode=0777])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002147Create a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002148
Barry Warsaw53699e91996-12-10 23:23:01 +00002149static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002150posix_mkdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002151{
Guido van Rossumb0824db1996-02-25 04:50:32 +00002152 int res;
Mark Hammondef8b6542001-05-13 08:04:26 +00002153 char *path = NULL;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002154 int mode = 0777;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002155
2156#ifdef Py_WIN_WIDE_FILENAMES
2157 if (unicode_file_names()) {
2158 PyUnicodeObject *po;
Mark Hammond05107b62003-02-19 04:08:27 +00002159 if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002160 Py_BEGIN_ALLOW_THREADS
2161 /* PyUnicode_AS_UNICODE OK without thread lock as
2162 it is a simple dereference. */
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002163 res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002164 Py_END_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002165 if (!res)
2166 return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002167 Py_INCREF(Py_None);
2168 return Py_None;
2169 }
2170 /* Drop the argument parsing error as narrow strings
2171 are also valid. */
2172 PyErr_Clear();
2173 }
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002174 if (!PyArg_ParseTuple(args, "et|i:mkdir",
2175 Py_FileSystemDefaultEncoding, &path, &mode))
2176 return NULL;
2177 Py_BEGIN_ALLOW_THREADS
2178 /* PyUnicode_AS_UNICODE OK without thread lock as
2179 it is a simple dereference. */
2180 res = CreateDirectoryA(path, NULL);
2181 Py_END_ALLOW_THREADS
2182 if (!res) {
2183 win32_error("mkdir", path);
2184 PyMem_Free(path);
2185 return NULL;
2186 }
2187 PyMem_Free(path);
2188 Py_INCREF(Py_None);
2189 return Py_None;
2190#else
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002191
Tim Peters5aa91602002-01-30 05:46:57 +00002192 if (!PyArg_ParseTuple(args, "et|i:mkdir",
Mark Hammondef8b6542001-05-13 08:04:26 +00002193 Py_FileSystemDefaultEncoding, &path, &mode))
Guido van Rossumb0824db1996-02-25 04:50:32 +00002194 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002195 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002196#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002197 res = mkdir(path);
2198#else
Guido van Rossumb0824db1996-02-25 04:50:32 +00002199 res = mkdir(path, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002200#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00002201 Py_END_ALLOW_THREADS
Guido van Rossumb0824db1996-02-25 04:50:32 +00002202 if (res < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00002203 return posix_error_with_allocated_filename(path);
2204 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002205 Py_INCREF(Py_None);
2206 return Py_None;
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002207#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002208}
2209
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002210
Neal Norwitz1818ed72006-03-26 00:29:48 +00002211/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
2212#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002213#include <sys/resource.h>
2214#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002215
Neal Norwitz1818ed72006-03-26 00:29:48 +00002216
2217#ifdef HAVE_NICE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002218PyDoc_STRVAR(posix_nice__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002219"nice(inc) -> new_priority\n\n\
2220Decrease the priority of process by inc and return the new priority.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002221
Barry Warsaw53699e91996-12-10 23:23:01 +00002222static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002223posix_nice(PyObject *self, PyObject *args)
Guido van Rossum775f4da1993-01-09 17:18:52 +00002224{
2225 int increment, value;
2226
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002227 if (!PyArg_ParseTuple(args, "i:nice", &increment))
Guido van Rossum775f4da1993-01-09 17:18:52 +00002228 return NULL;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002229
2230 /* There are two flavours of 'nice': one that returns the new
2231 priority (as required by almost all standards out there) and the
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002232 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
2233 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00002234
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002235 If we are of the nice family that returns the new priority, we
2236 need to clear errno before the call, and check if errno is filled
2237 before calling posix_error() on a returnvalue of -1, because the
2238 -1 may be the actual new priority! */
2239
2240 errno = 0;
Guido van Rossum775f4da1993-01-09 17:18:52 +00002241 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00002242#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00002243 if (value == 0)
2244 value = getpriority(PRIO_PROCESS, 0);
2245#endif
2246 if (value == -1 && errno != 0)
2247 /* either nice() or getpriority() returned an error */
Guido van Rossum775f4da1993-01-09 17:18:52 +00002248 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002249 return PyInt_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00002250}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002251#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002252
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002253PyDoc_STRVAR(posix_rename__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002254"rename(old, new)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002255Rename a file or directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002256
Barry Warsaw53699e91996-12-10 23:23:01 +00002257static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002258posix_rename(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002259{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002260#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002261 PyObject *o1, *o2;
2262 char *p1, *p2;
2263 BOOL result;
2264 if (unicode_file_names()) {
2265 if (!PyArg_ParseTuple(args, "O&O&:rename",
2266 convert_to_unicode, &o1,
2267 convert_to_unicode, &o2))
2268 PyErr_Clear();
2269 else {
2270 Py_BEGIN_ALLOW_THREADS
2271 result = MoveFileW(PyUnicode_AsUnicode(o1),
2272 PyUnicode_AsUnicode(o2));
2273 Py_END_ALLOW_THREADS
2274 Py_DECREF(o1);
2275 Py_DECREF(o2);
2276 if (!result)
2277 return win32_error("rename", NULL);
2278 Py_INCREF(Py_None);
2279 return Py_None;
2280 }
2281 }
2282 if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
2283 return NULL;
2284 Py_BEGIN_ALLOW_THREADS
2285 result = MoveFileA(p1, p2);
2286 Py_END_ALLOW_THREADS
2287 if (!result)
2288 return win32_error("rename", NULL);
2289 Py_INCREF(Py_None);
2290 return Py_None;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002291#else
Martin v. Löwis4fc2bda2006-05-04 12:04:27 +00002292 return posix_2str(args, "etet:rename", rename);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002293#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002294}
2295
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002296
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002297PyDoc_STRVAR(posix_rmdir__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002298"rmdir(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002299Remove a directory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002300
Barry Warsaw53699e91996-12-10 23:23:01 +00002301static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002302posix_rmdir(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002303{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002304#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002305 return win32_1str(args, "rmdir", "s:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002306#else
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002307 return posix_1str(args, "et:rmdir", rmdir);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002308#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002309}
2310
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002311
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002312PyDoc_STRVAR(posix_stat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002313"stat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002314Perform a stat system call on the given path.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002315
Barry Warsaw53699e91996-12-10 23:23:01 +00002316static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002317posix_stat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002318{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002319#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00002320 return posix_do_stat(self, args, "et:stat", STAT, "U:stat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002321#else
2322 return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
2323#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002324}
2325
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002326
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002327#ifdef HAVE_SYSTEM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002328PyDoc_STRVAR(posix_system__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002329"system(command) -> exit_status\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002330Execute the command (a string) in a subshell.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002331
Barry Warsaw53699e91996-12-10 23:23:01 +00002332static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002333posix_system(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002334{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002335 char *command;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002336 long sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002337 if (!PyArg_ParseTuple(args, "s:system", &command))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002338 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002339 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002340 sts = system(command);
Barry Warsaw53699e91996-12-10 23:23:01 +00002341 Py_END_ALLOW_THREADS
2342 return PyInt_FromLong(sts);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002343}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002344#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002345
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002346
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002347PyDoc_STRVAR(posix_umask__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002348"umask(new_mask) -> old_mask\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002349Set the current numeric umask and return the previous umask.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002350
Barry Warsaw53699e91996-12-10 23:23:01 +00002351static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002352posix_umask(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002353{
2354 int i;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002355 if (!PyArg_ParseTuple(args, "i:umask", &i))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002356 return NULL;
Fred Drake0368bc42001-07-19 20:48:32 +00002357 i = (int)umask(i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002358 if (i < 0)
2359 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002360 return PyInt_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002361}
2362
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002363
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002364PyDoc_STRVAR(posix_unlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002365"unlink(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002366Remove a file (same as remove(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002367
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002368PyDoc_STRVAR(posix_remove__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002369"remove(path)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002370Remove a file (same as unlink(path)).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002371
Barry Warsaw53699e91996-12-10 23:23:01 +00002372static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002373posix_unlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002374{
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002375#ifdef MS_WINDOWS
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002376 return win32_1str(args, "remove", "s:remove", DeleteFileA, "U:remove", DeleteFileW);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002377#else
Martin v. Löwis8e0d4942006-05-04 10:08:42 +00002378 return posix_1str(args, "et:remove", unlink);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00002379#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002380}
2381
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002382
Guido van Rossumb6775db1994-08-01 11:34:53 +00002383#ifdef HAVE_UNAME
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002384PyDoc_STRVAR(posix_uname__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002385"uname() -> (sysname, nodename, release, version, machine)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002386Return a tuple identifying the current operating system.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002387
Barry Warsaw53699e91996-12-10 23:23:01 +00002388static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00002389posix_uname(PyObject *self, PyObject *noargs)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002390{
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002391 struct utsname u;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002392 int res;
Neal Norwitze241ce82003-02-17 18:17:05 +00002393
Barry Warsaw53699e91996-12-10 23:23:01 +00002394 Py_BEGIN_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002395 res = uname(&u);
Barry Warsaw53699e91996-12-10 23:23:01 +00002396 Py_END_ALLOW_THREADS
Guido van Rossumff4949e1992-08-05 19:58:53 +00002397 if (res < 0)
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002398 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00002399 return Py_BuildValue("(sssss)",
Barry Warsaw43d68b81996-12-19 22:10:44 +00002400 u.sysname,
2401 u.nodename,
2402 u.release,
2403 u.version,
2404 u.machine);
Guido van Rossumc39de5f1992-02-05 11:15:54 +00002405}
Guido van Rossumb6775db1994-08-01 11:34:53 +00002406#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002407
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002408static int
2409extract_time(PyObject *t, long* sec, long* usec)
2410{
2411 long intval;
2412 if (PyFloat_Check(t)) {
2413 double tval = PyFloat_AsDouble(t);
2414 PyObject *intobj = t->ob_type->tp_as_number->nb_int(t);
2415 if (!intobj)
2416 return -1;
2417 intval = PyInt_AsLong(intobj);
2418 Py_DECREF(intobj);
Michael W. Hudsonb8963812005-07-05 15:21:58 +00002419 if (intval == -1 && PyErr_Occurred())
2420 return -1;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002421 *sec = intval;
Tim Peters96940cf2002-09-10 15:37:28 +00002422 *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002423 if (*usec < 0)
2424 /* If rounding gave us a negative number,
2425 truncate. */
2426 *usec = 0;
2427 return 0;
2428 }
2429 intval = PyInt_AsLong(t);
2430 if (intval == -1 && PyErr_Occurred())
2431 return -1;
2432 *sec = intval;
2433 *usec = 0;
Martin v. Löwis076b2092002-09-10 15:04:41 +00002434 return 0;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002435}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002436
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002437PyDoc_STRVAR(posix_utime__doc__,
Georg Brandl9e5b5e42006-05-17 14:18:20 +00002438"utime(path, (atime, mtime))\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00002439utime(path, None)\n\n\
Barry Warsaw3cef8562000-05-01 16:17:24 +00002440Set the access and modified time of the file to the given values. If the\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002441second form is used, set the access and modified times to the current time.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002442
Barry Warsaw53699e91996-12-10 23:23:01 +00002443static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002444posix_utime(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002445{
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002446#ifdef Py_WIN_WIDE_FILENAMES
2447 PyObject *arg;
2448 PyUnicodeObject *obwpath;
2449 wchar_t *wpath = NULL;
2450 char *apath = NULL;
2451 HANDLE hFile;
2452 long atimesec, mtimesec, ausec, musec;
2453 FILETIME atime, mtime;
2454 PyObject *result = NULL;
2455
2456 if (unicode_file_names()) {
2457 if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
2458 wpath = PyUnicode_AS_UNICODE(obwpath);
2459 Py_BEGIN_ALLOW_THREADS
2460 hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
Martin v. Löwis18aaa562006-10-15 08:43:33 +00002461 NULL, OPEN_EXISTING,
2462 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002463 Py_END_ALLOW_THREADS
2464 if (hFile == INVALID_HANDLE_VALUE)
2465 return win32_error_unicode("utime", wpath);
2466 } else
2467 /* Drop the argument parsing error as narrow strings
2468 are also valid. */
2469 PyErr_Clear();
2470 }
2471 if (!wpath) {
2472 if (!PyArg_ParseTuple(args, "etO:utime",
2473 Py_FileSystemDefaultEncoding, &apath, &arg))
2474 return NULL;
2475 Py_BEGIN_ALLOW_THREADS
2476 hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
Martin v. Löwis18aaa562006-10-15 08:43:33 +00002477 NULL, OPEN_EXISTING,
2478 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002479 Py_END_ALLOW_THREADS
2480 if (hFile == INVALID_HANDLE_VALUE) {
2481 win32_error("utime", apath);
2482 PyMem_Free(apath);
2483 return NULL;
2484 }
2485 PyMem_Free(apath);
2486 }
2487
2488 if (arg == Py_None) {
2489 SYSTEMTIME now;
2490 GetSystemTime(&now);
2491 if (!SystemTimeToFileTime(&now, &mtime) ||
2492 !SystemTimeToFileTime(&now, &atime)) {
2493 win32_error("utime", NULL);
2494 goto done;
2495 }
2496 }
2497 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
2498 PyErr_SetString(PyExc_TypeError,
2499 "utime() arg 2 must be a tuple (atime, mtime)");
2500 goto done;
2501 }
2502 else {
2503 if (extract_time(PyTuple_GET_ITEM(arg, 0),
2504 &atimesec, &ausec) == -1)
2505 goto done;
Martin v. Löwisf43893a2006-10-09 20:44:25 +00002506 time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002507 if (extract_time(PyTuple_GET_ITEM(arg, 1),
2508 &mtimesec, &musec) == -1)
2509 goto done;
Martin v. Löwisf43893a2006-10-09 20:44:25 +00002510 time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002511 }
2512 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
2513 /* Avoid putting the file name into the error here,
2514 as that may confuse the user into believing that
2515 something is wrong with the file, when it also
2516 could be the time stamp that gives a problem. */
2517 win32_error("utime", NULL);
2518 }
2519 Py_INCREF(Py_None);
2520 result = Py_None;
2521done:
2522 CloseHandle(hFile);
2523 return result;
2524#else /* Py_WIN_WIDE_FILENAMES */
2525
Neal Norwitz2adf2102004-06-09 01:46:02 +00002526 char *path = NULL;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002527 long atime, mtime, ausec, musec;
Guido van Rossumff4949e1992-08-05 19:58:53 +00002528 int res;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002529 PyObject* arg;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002530
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002531#if defined(HAVE_UTIMES)
2532 struct timeval buf[2];
2533#define ATIME buf[0].tv_sec
2534#define MTIME buf[1].tv_sec
2535#elif defined(HAVE_UTIME_H)
Guido van Rossum6d8841c1997-08-14 19:57:39 +00002536/* XXX should define struct utimbuf instead, above */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002537 struct utimbuf buf;
2538#define ATIME buf.actime
2539#define MTIME buf.modtime
2540#define UTIME_ARG &buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002541#else /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002542 time_t buf[2];
2543#define ATIME buf[0]
2544#define MTIME buf[1]
2545#define UTIME_ARG buf
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002546#endif /* HAVE_UTIMES */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002547
Mark Hammond817c9292003-12-03 01:22:38 +00002548
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002549 if (!PyArg_ParseTuple(args, "etO:utime",
Hye-Shik Chang2b2c9732004-01-04 13:54:25 +00002550 Py_FileSystemDefaultEncoding, &path, &arg))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002551 return NULL;
Barry Warsaw3cef8562000-05-01 16:17:24 +00002552 if (arg == Py_None) {
2553 /* optional time values not given */
2554 Py_BEGIN_ALLOW_THREADS
2555 res = utime(path, NULL);
2556 Py_END_ALLOW_THREADS
2557 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002558 else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
Barry Warsaw3cef8562000-05-01 16:17:24 +00002559 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002560 "utime() arg 2 must be a tuple (atime, mtime)");
Neal Norwitz96652712004-06-06 20:40:27 +00002561 PyMem_Free(path);
Barry Warsaw3cef8562000-05-01 16:17:24 +00002562 return NULL;
2563 }
2564 else {
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002565 if (extract_time(PyTuple_GET_ITEM(arg, 0),
Neal Norwitz96652712004-06-06 20:40:27 +00002566 &atime, &ausec) == -1) {
2567 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002568 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002569 }
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002570 if (extract_time(PyTuple_GET_ITEM(arg, 1),
Neal Norwitz96652712004-06-06 20:40:27 +00002571 &mtime, &musec) == -1) {
2572 PyMem_Free(path);
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002573 return NULL;
Neal Norwitz96652712004-06-06 20:40:27 +00002574 }
Barry Warsaw3cef8562000-05-01 16:17:24 +00002575 ATIME = atime;
2576 MTIME = mtime;
Martin v. Löwis6aa9fdb2002-09-10 09:16:13 +00002577#ifdef HAVE_UTIMES
2578 buf[0].tv_usec = ausec;
2579 buf[1].tv_usec = musec;
2580 Py_BEGIN_ALLOW_THREADS
2581 res = utimes(path, buf);
2582 Py_END_ALLOW_THREADS
2583#else
Barry Warsaw3cef8562000-05-01 16:17:24 +00002584 Py_BEGIN_ALLOW_THREADS
2585 res = utime(path, UTIME_ARG);
2586 Py_END_ALLOW_THREADS
Mark Hammond817c9292003-12-03 01:22:38 +00002587#endif /* HAVE_UTIMES */
Barry Warsaw3cef8562000-05-01 16:17:24 +00002588 }
Mark Hammond2d5914b2004-05-04 08:10:37 +00002589 if (res < 0) {
Neal Norwitz96652712004-06-06 20:40:27 +00002590 return posix_error_with_allocated_filename(path);
Mark Hammond2d5914b2004-05-04 08:10:37 +00002591 }
Neal Norwitz96652712004-06-06 20:40:27 +00002592 PyMem_Free(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00002593 Py_INCREF(Py_None);
2594 return Py_None;
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00002595#undef UTIME_ARG
2596#undef ATIME
2597#undef MTIME
Martin v. Löwisd4e3bb32006-05-06 16:32:54 +00002598#endif /* Py_WIN_WIDE_FILENAMES */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002599}
2600
Guido van Rossum85e3b011991-06-03 12:42:10 +00002601
Guido van Rossum3b066191991-06-04 19:40:25 +00002602/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002603
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002604PyDoc_STRVAR(posix__exit__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002605"_exit(status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002606Exit to the system with specified status, without normal exit processing.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002607
Barry Warsaw53699e91996-12-10 23:23:01 +00002608static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002609posix__exit(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002610{
2611 int sts;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002612 if (!PyArg_ParseTuple(args, "i:_exit", &sts))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002613 return NULL;
2614 _exit(sts);
Guido van Rossuma376cc51996-12-05 23:43:35 +00002615 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00002616}
2617
Martin v. Löwis114619e2002-10-07 06:44:21 +00002618#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
2619static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00002620free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00002621{
Martin v. Löwis725507b2006-03-07 12:08:51 +00002622 Py_ssize_t i;
Martin v. Löwis114619e2002-10-07 06:44:21 +00002623 for (i = 0; i < count; i++)
2624 PyMem_Free(array[i]);
2625 PyMem_DEL(array);
2626}
2627#endif
2628
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002629
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002630#ifdef HAVE_EXECV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002631PyDoc_STRVAR(posix_execv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002632"execv(path, args)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002633Execute an executable path with arguments, replacing current process.\n\
2634\n\
2635 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002636 args: tuple or list of strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002637
Barry Warsaw53699e91996-12-10 23:23:01 +00002638static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002639posix_execv(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00002640{
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002641 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002642 PyObject *argv;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002643 char **argvlist;
Martin v. Löwis725507b2006-03-07 12:08:51 +00002644 Py_ssize_t i, argc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002645 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002646
Guido van Rossum89b33251993-10-22 14:26:06 +00002647 /* execv has two arguments: (path, argv), where
Guido van Rossum85e3b011991-06-03 12:42:10 +00002648 argv is a list or tuple of strings. */
2649
Martin v. Löwis114619e2002-10-07 06:44:21 +00002650 if (!PyArg_ParseTuple(args, "etO:execv",
2651 Py_FileSystemDefaultEncoding,
2652 &path, &argv))
Guido van Rossum85e3b011991-06-03 12:42:10 +00002653 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002654 if (PyList_Check(argv)) {
2655 argc = PyList_Size(argv);
2656 getitem = PyList_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002657 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002658 else if (PyTuple_Check(argv)) {
2659 argc = PyTuple_Size(argv);
2660 getitem = PyTuple_GetItem;
Guido van Rossum85e3b011991-06-03 12:42:10 +00002661 }
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002662 else {
Fred Drake661ea262000-10-24 19:57:45 +00002663 PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002664 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002665 return NULL;
2666 }
2667
Barry Warsaw53699e91996-12-10 23:23:01 +00002668 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002669 if (argvlist == NULL) {
2670 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002671 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002672 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002673 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002674 if (!PyArg_Parse((*getitem)(argv, i), "et",
2675 Py_FileSystemDefaultEncoding,
2676 &argvlist[i])) {
2677 free_string_array(argvlist, i);
Tim Peters5aa91602002-01-30 05:46:57 +00002678 PyErr_SetString(PyExc_TypeError,
Fred Drake661ea262000-10-24 19:57:45 +00002679 "execv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002680 PyMem_Free(path);
Guido van Rossum50422b42000-04-26 20:34:28 +00002681 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00002682
Guido van Rossum85e3b011991-06-03 12:42:10 +00002683 }
Guido van Rossum85e3b011991-06-03 12:42:10 +00002684 }
2685 argvlist[argc] = NULL;
2686
Guido van Rossumef0a00e1992-01-27 16:51:30 +00002687 execv(path, argvlist);
Guido van Rossumb6775db1994-08-01 11:34:53 +00002688
Guido van Rossum85e3b011991-06-03 12:42:10 +00002689 /* If we get here it's definitely an error */
2690
Martin v. Löwis114619e2002-10-07 06:44:21 +00002691 free_string_array(argvlist, argc);
2692 PyMem_Free(path);
Guido van Rossum85e3b011991-06-03 12:42:10 +00002693 return posix_error();
2694}
2695
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002696
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002697PyDoc_STRVAR(posix_execve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002698"execve(path, args, env)\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002699Execute a path with arguments and environment, replacing current process.\n\
2700\n\
2701 path: path of executable file\n\
2702 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002703 env: dictionary of strings mapping to strings");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002704
Barry Warsaw53699e91996-12-10 23:23:01 +00002705static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002706posix_execve(PyObject *self, PyObject *args)
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002707{
2708 char *path;
Barry Warsaw53699e91996-12-10 23:23:01 +00002709 PyObject *argv, *env;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002710 char **argvlist;
2711 char **envlist;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002712 PyObject *key, *val, *keys=NULL, *vals=NULL;
Martin v. Löwis725507b2006-03-07 12:08:51 +00002713 Py_ssize_t i, pos, argc, envc;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002714 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Martin v. Löwis26fd9602006-04-22 11:15:41 +00002715 Py_ssize_t lastarg = 0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002716
2717 /* execve has three arguments: (path, argv, env), where
2718 argv is a list or tuple of strings and env is a dictionary
2719 like posix.environ. */
2720
Martin v. Löwis114619e2002-10-07 06:44:21 +00002721 if (!PyArg_ParseTuple(args, "etOO:execve",
2722 Py_FileSystemDefaultEncoding,
2723 &path, &argv, &env))
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002724 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00002725 if (PyList_Check(argv)) {
2726 argc = PyList_Size(argv);
2727 getitem = PyList_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002728 }
Barry Warsaw53699e91996-12-10 23:23:01 +00002729 else if (PyTuple_Check(argv)) {
2730 argc = PyTuple_Size(argv);
2731 getitem = PyTuple_GetItem;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002732 }
2733 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002734 PyErr_SetString(PyExc_TypeError,
2735 "execve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002736 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002737 }
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002738 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002739 PyErr_SetString(PyExc_TypeError,
2740 "execve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002741 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002742 }
2743
Barry Warsaw53699e91996-12-10 23:23:01 +00002744 argvlist = PyMem_NEW(char *, argc+1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002745 if (argvlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002746 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002747 goto fail_0;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002748 }
2749 for (i = 0; i < argc; i++) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002750 if (!PyArg_Parse((*getitem)(argv, i),
Martin v. Löwis114619e2002-10-07 06:44:21 +00002751 "et;execve() arg 2 must contain only strings",
Guido van Rossum1e700d22002-10-16 16:52:11 +00002752 Py_FileSystemDefaultEncoding,
Barry Warsaw43d68b81996-12-19 22:10:44 +00002753 &argvlist[i]))
2754 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002755 lastarg = i;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002756 goto fail_1;
2757 }
2758 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002759 lastarg = argc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002760 argvlist[argc] = NULL;
2761
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002762 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002763 if (i < 0)
2764 goto fail_1;
Barry Warsaw53699e91996-12-10 23:23:01 +00002765 envlist = PyMem_NEW(char *, i + 1);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002766 if (envlist == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002767 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002768 goto fail_1;
2769 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002770 envc = 0;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002771 keys = PyMapping_Keys(env);
2772 vals = PyMapping_Values(env);
2773 if (!keys || !vals)
2774 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002775 if (!PyList_Check(keys) || !PyList_Check(vals)) {
2776 PyErr_SetString(PyExc_TypeError,
2777 "execve(): env.keys() or env.values() is not a list");
2778 goto fail_2;
2779 }
Tim Peters5aa91602002-01-30 05:46:57 +00002780
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002781 for (pos = 0; pos < i; pos++) {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002782 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00002783 size_t len;
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002784
2785 key = PyList_GetItem(keys, pos);
2786 val = PyList_GetItem(vals, pos);
2787 if (!key || !val)
2788 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00002789
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002790 if (!PyArg_Parse(
2791 key,
2792 "s;execve() arg 3 contains a non-string key",
2793 &k) ||
2794 !PyArg_Parse(
2795 val,
2796 "s;execve() arg 3 contains a non-string value",
2797 &v))
Barry Warsaw43d68b81996-12-19 22:10:44 +00002798 {
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002799 goto fail_2;
2800 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00002801
2802#if defined(PYOS_OS2)
2803 /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
2804 if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
2805#endif
Tim Petersc8996f52001-12-03 20:41:00 +00002806 len = PyString_Size(key) + PyString_Size(val) + 2;
2807 p = PyMem_NEW(char, len);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002808 if (p == NULL) {
Barry Warsaw53699e91996-12-10 23:23:01 +00002809 PyErr_NoMemory();
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002810 goto fail_2;
2811 }
Tim Petersc8996f52001-12-03 20:41:00 +00002812 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002813 envlist[envc++] = p;
Guido van Rossumd48f2521997-12-05 22:19:34 +00002814#if defined(PYOS_OS2)
2815 }
2816#endif
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002817 }
2818 envlist[envc] = 0;
2819
2820 execve(path, argvlist, envlist);
Tim Peters5aa91602002-01-30 05:46:57 +00002821
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002822 /* If we get here it's definitely an error */
2823
2824 (void) posix_error();
2825
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002826 fail_2:
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002827 while (--envc >= 0)
Barry Warsaw53699e91996-12-10 23:23:01 +00002828 PyMem_DEL(envlist[envc]);
2829 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002830 fail_1:
2831 free_string_array(argvlist, lastarg);
Barry Warsaw5ed19dc1997-01-29 15:08:24 +00002832 Py_XDECREF(vals);
2833 Py_XDECREF(keys);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002834 fail_0:
Martin v. Löwis114619e2002-10-07 06:44:21 +00002835 PyMem_Free(path);
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002836 return NULL;
2837}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00002838#endif /* HAVE_EXECV */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00002839
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002840
Guido van Rossuma1065681999-01-25 23:20:23 +00002841#ifdef HAVE_SPAWNV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002842PyDoc_STRVAR(posix_spawnv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002843"spawnv(mode, path, args)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002844Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002845\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002846 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002847 path: path of executable file\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002848 args: tuple or list of strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002849
2850static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002851posix_spawnv(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002852{
2853 char *path;
2854 PyObject *argv;
2855 char **argvlist;
Martin v. Löwis26fd9602006-04-22 11:15:41 +00002856 int mode, i;
2857 Py_ssize_t argc;
Tim Peters79248aa2001-08-29 21:37:10 +00002858 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002859 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00002860
2861 /* spawnv has three arguments: (mode, path, argv), where
2862 argv is a list or tuple of strings. */
2863
Martin v. Löwis114619e2002-10-07 06:44:21 +00002864 if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
2865 Py_FileSystemDefaultEncoding,
2866 &path, &argv))
Guido van Rossuma1065681999-01-25 23:20:23 +00002867 return NULL;
2868 if (PyList_Check(argv)) {
2869 argc = PyList_Size(argv);
2870 getitem = PyList_GetItem;
2871 }
2872 else if (PyTuple_Check(argv)) {
2873 argc = PyTuple_Size(argv);
2874 getitem = PyTuple_GetItem;
2875 }
2876 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002877 PyErr_SetString(PyExc_TypeError,
2878 "spawnv() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002879 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002880 return NULL;
2881 }
2882
2883 argvlist = PyMem_NEW(char *, argc+1);
Martin v. Löwis114619e2002-10-07 06:44:21 +00002884 if (argvlist == NULL) {
2885 PyMem_Free(path);
Neal Norwitzec74f2f2003-02-11 23:05:40 +00002886 return PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002887 }
Guido van Rossuma1065681999-01-25 23:20:23 +00002888 for (i = 0; i < argc; i++) {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002889 if (!PyArg_Parse((*getitem)(argv, i), "et",
2890 Py_FileSystemDefaultEncoding,
2891 &argvlist[i])) {
2892 free_string_array(argvlist, i);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002893 PyErr_SetString(
2894 PyExc_TypeError,
2895 "spawnv() arg 2 must contain only strings");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002896 PyMem_Free(path);
Fred Drake137507e2000-06-01 02:02:46 +00002897 return NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00002898 }
2899 }
2900 argvlist[argc] = NULL;
2901
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002902#if defined(PYOS_OS2) && defined(PYCC_GCC)
2903 Py_BEGIN_ALLOW_THREADS
2904 spawnval = spawnv(mode, path, argvlist);
2905 Py_END_ALLOW_THREADS
2906#else
Guido van Rossum246bc171999-02-01 23:54:31 +00002907 if (mode == _OLD_P_OVERLAY)
2908 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00002909
Tim Peters25059d32001-12-07 20:35:43 +00002910 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00002911 spawnval = _spawnv(mode, path, argvlist);
Tim Peters25059d32001-12-07 20:35:43 +00002912 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00002913#endif
Tim Peters5aa91602002-01-30 05:46:57 +00002914
Martin v. Löwis114619e2002-10-07 06:44:21 +00002915 free_string_array(argvlist, argc);
2916 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00002917
Fred Drake699f3522000-06-29 21:12:41 +00002918 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00002919 return posix_error();
2920 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00002921#if SIZEOF_LONG == SIZEOF_VOID_P
2922 return Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002923#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00002924 return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00002925#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00002926}
2927
2928
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002929PyDoc_STRVAR(posix_spawnve__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00002930"spawnve(mode, path, args, env)\n\n\
Tim Peters25059d32001-12-07 20:35:43 +00002931Execute the program 'path' in a new process.\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002932\n\
Fred Drakea6dff3e1999-02-01 22:24:40 +00002933 mode: mode of process creation\n\
Guido van Rossuma1065681999-01-25 23:20:23 +00002934 path: path of executable file\n\
2935 args: tuple or list of arguments\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00002936 env: dictionary of strings mapping to strings");
Guido van Rossuma1065681999-01-25 23:20:23 +00002937
2938static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00002939posix_spawnve(PyObject *self, PyObject *args)
Guido van Rossuma1065681999-01-25 23:20:23 +00002940{
2941 char *path;
2942 PyObject *argv, *env;
2943 char **argvlist;
2944 char **envlist;
2945 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
Martin v. Löwis26fd9602006-04-22 11:15:41 +00002946 int mode, pos, envc;
2947 Py_ssize_t argc, i;
Tim Peters79248aa2001-08-29 21:37:10 +00002948 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00002949 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Martin v. Löwis26fd9602006-04-22 11:15:41 +00002950 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002951
2952 /* spawnve has four arguments: (mode, path, argv, env), where
2953 argv is a list or tuple of strings and env is a dictionary
2954 like posix.environ. */
2955
Martin v. Löwis114619e2002-10-07 06:44:21 +00002956 if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
2957 Py_FileSystemDefaultEncoding,
2958 &path, &argv, &env))
Guido van Rossuma1065681999-01-25 23:20:23 +00002959 return NULL;
2960 if (PyList_Check(argv)) {
2961 argc = PyList_Size(argv);
2962 getitem = PyList_GetItem;
2963 }
2964 else if (PyTuple_Check(argv)) {
2965 argc = PyTuple_Size(argv);
2966 getitem = PyTuple_GetItem;
2967 }
2968 else {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002969 PyErr_SetString(PyExc_TypeError,
2970 "spawnve() arg 2 must be a tuple or list");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002971 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002972 }
2973 if (!PyMapping_Check(env)) {
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002974 PyErr_SetString(PyExc_TypeError,
2975 "spawnve() arg 3 must be a mapping object");
Martin v. Löwis114619e2002-10-07 06:44:21 +00002976 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002977 }
2978
2979 argvlist = PyMem_NEW(char *, argc+1);
2980 if (argvlist == NULL) {
2981 PyErr_NoMemory();
Martin v. Löwis114619e2002-10-07 06:44:21 +00002982 goto fail_0;
Guido van Rossuma1065681999-01-25 23:20:23 +00002983 }
2984 for (i = 0; i < argc; i++) {
2985 if (!PyArg_Parse((*getitem)(argv, i),
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002986 "et;spawnve() arg 2 must contain only strings",
Martin v. Löwis114619e2002-10-07 06:44:21 +00002987 Py_FileSystemDefaultEncoding,
Guido van Rossuma1065681999-01-25 23:20:23 +00002988 &argvlist[i]))
2989 {
Martin v. Löwis114619e2002-10-07 06:44:21 +00002990 lastarg = i;
Guido van Rossuma1065681999-01-25 23:20:23 +00002991 goto fail_1;
2992 }
2993 }
Martin v. Löwis114619e2002-10-07 06:44:21 +00002994 lastarg = argc;
Guido van Rossuma1065681999-01-25 23:20:23 +00002995 argvlist[argc] = NULL;
2996
Jeremy Hylton03657cf2000-07-12 13:05:33 +00002997 i = PyMapping_Size(env);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00002998 if (i < 0)
2999 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00003000 envlist = PyMem_NEW(char *, i + 1);
3001 if (envlist == NULL) {
3002 PyErr_NoMemory();
3003 goto fail_1;
3004 }
3005 envc = 0;
3006 keys = PyMapping_Keys(env);
3007 vals = PyMapping_Values(env);
3008 if (!keys || !vals)
3009 goto fail_2;
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003010 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3011 PyErr_SetString(PyExc_TypeError,
3012 "spawnve(): env.keys() or env.values() is not a list");
3013 goto fail_2;
3014 }
Tim Peters5aa91602002-01-30 05:46:57 +00003015
Guido van Rossuma1065681999-01-25 23:20:23 +00003016 for (pos = 0; pos < i; pos++) {
3017 char *p, *k, *v;
Tim Petersc8996f52001-12-03 20:41:00 +00003018 size_t len;
Guido van Rossuma1065681999-01-25 23:20:23 +00003019
3020 key = PyList_GetItem(keys, pos);
3021 val = PyList_GetItem(vals, pos);
3022 if (!key || !val)
3023 goto fail_2;
Tim Peters5aa91602002-01-30 05:46:57 +00003024
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003025 if (!PyArg_Parse(
3026 key,
3027 "s;spawnve() arg 3 contains a non-string key",
3028 &k) ||
3029 !PyArg_Parse(
3030 val,
3031 "s;spawnve() arg 3 contains a non-string value",
3032 &v))
Guido van Rossuma1065681999-01-25 23:20:23 +00003033 {
3034 goto fail_2;
3035 }
Tim Petersc8996f52001-12-03 20:41:00 +00003036 len = PyString_Size(key) + PyString_Size(val) + 2;
3037 p = PyMem_NEW(char, len);
Guido van Rossuma1065681999-01-25 23:20:23 +00003038 if (p == NULL) {
3039 PyErr_NoMemory();
3040 goto fail_2;
3041 }
Tim Petersc8996f52001-12-03 20:41:00 +00003042 PyOS_snprintf(p, len, "%s=%s", k, v);
Guido van Rossuma1065681999-01-25 23:20:23 +00003043 envlist[envc++] = p;
3044 }
3045 envlist[envc] = 0;
3046
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003047#if defined(PYOS_OS2) && defined(PYCC_GCC)
3048 Py_BEGIN_ALLOW_THREADS
3049 spawnval = spawnve(mode, path, argvlist, envlist);
3050 Py_END_ALLOW_THREADS
3051#else
Guido van Rossum246bc171999-02-01 23:54:31 +00003052 if (mode == _OLD_P_OVERLAY)
3053 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00003054
3055 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00003056 spawnval = _spawnve(mode, path, argvlist, envlist);
Tim Peters25059d32001-12-07 20:35:43 +00003057 Py_END_ALLOW_THREADS
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003058#endif
Tim Peters25059d32001-12-07 20:35:43 +00003059
Fred Drake699f3522000-06-29 21:12:41 +00003060 if (spawnval == -1)
Guido van Rossuma1065681999-01-25 23:20:23 +00003061 (void) posix_error();
3062 else
Fredrik Lundhe25cfd82000-07-09 13:10:40 +00003063#if SIZEOF_LONG == SIZEOF_VOID_P
3064 res = Py_BuildValue("l", (long) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003065#else
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00003066 res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
Fred Drake699f3522000-06-29 21:12:41 +00003067#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00003068
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003069 fail_2:
Guido van Rossuma1065681999-01-25 23:20:23 +00003070 while (--envc >= 0)
3071 PyMem_DEL(envlist[envc]);
3072 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00003073 fail_1:
Martin v. Löwis114619e2002-10-07 06:44:21 +00003074 free_string_array(argvlist, lastarg);
Guido van Rossuma1065681999-01-25 23:20:23 +00003075 Py_XDECREF(vals);
3076 Py_XDECREF(keys);
Martin v. Löwis114619e2002-10-07 06:44:21 +00003077 fail_0:
3078 PyMem_Free(path);
Guido van Rossuma1065681999-01-25 23:20:23 +00003079 return res;
3080}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003081
3082/* OS/2 supports spawnvp & spawnvpe natively */
3083#if defined(PYOS_OS2)
3084PyDoc_STRVAR(posix_spawnvp__doc__,
3085"spawnvp(mode, file, args)\n\n\
3086Execute the program 'file' in a new process, using the environment\n\
3087search path to find the file.\n\
3088\n\
3089 mode: mode of process creation\n\
3090 file: executable file name\n\
3091 args: tuple or list of strings");
3092
3093static PyObject *
3094posix_spawnvp(PyObject *self, PyObject *args)
3095{
3096 char *path;
3097 PyObject *argv;
3098 char **argvlist;
3099 int mode, i, argc;
3100 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003101 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003102
3103 /* spawnvp has three arguments: (mode, path, argv), where
3104 argv is a list or tuple of strings. */
3105
3106 if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
3107 Py_FileSystemDefaultEncoding,
3108 &path, &argv))
3109 return NULL;
3110 if (PyList_Check(argv)) {
3111 argc = PyList_Size(argv);
3112 getitem = PyList_GetItem;
3113 }
3114 else if (PyTuple_Check(argv)) {
3115 argc = PyTuple_Size(argv);
3116 getitem = PyTuple_GetItem;
3117 }
3118 else {
3119 PyErr_SetString(PyExc_TypeError,
3120 "spawnvp() arg 2 must be a tuple or list");
3121 PyMem_Free(path);
3122 return NULL;
3123 }
3124
3125 argvlist = PyMem_NEW(char *, argc+1);
3126 if (argvlist == NULL) {
3127 PyMem_Free(path);
3128 return PyErr_NoMemory();
3129 }
3130 for (i = 0; i < argc; i++) {
3131 if (!PyArg_Parse((*getitem)(argv, i), "et",
3132 Py_FileSystemDefaultEncoding,
3133 &argvlist[i])) {
3134 free_string_array(argvlist, i);
3135 PyErr_SetString(
3136 PyExc_TypeError,
3137 "spawnvp() arg 2 must contain only strings");
3138 PyMem_Free(path);
3139 return NULL;
3140 }
3141 }
3142 argvlist[argc] = NULL;
3143
3144 Py_BEGIN_ALLOW_THREADS
3145#if defined(PYCC_GCC)
3146 spawnval = spawnvp(mode, path, argvlist);
3147#else
3148 spawnval = _spawnvp(mode, path, argvlist);
3149#endif
3150 Py_END_ALLOW_THREADS
3151
3152 free_string_array(argvlist, argc);
3153 PyMem_Free(path);
3154
3155 if (spawnval == -1)
3156 return posix_error();
3157 else
3158 return Py_BuildValue("l", (long) spawnval);
3159}
3160
3161
3162PyDoc_STRVAR(posix_spawnvpe__doc__,
3163"spawnvpe(mode, file, args, env)\n\n\
3164Execute the program 'file' in a new process, using the environment\n\
3165search path to find the file.\n\
3166\n\
3167 mode: mode of process creation\n\
3168 file: executable file name\n\
3169 args: tuple or list of arguments\n\
3170 env: dictionary of strings mapping to strings");
3171
3172static PyObject *
3173posix_spawnvpe(PyObject *self, PyObject *args)
3174{
3175 char *path;
3176 PyObject *argv, *env;
3177 char **argvlist;
3178 char **envlist;
3179 PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
3180 int mode, i, pos, argc, envc;
3181 Py_intptr_t spawnval;
Martin v. Löwis18e16552006-02-15 17:27:45 +00003182 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00003183 int lastarg = 0;
3184
3185 /* spawnvpe has four arguments: (mode, path, argv, env), where
3186 argv is a list or tuple of strings and env is a dictionary
3187 like posix.environ. */
3188
3189 if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
3190 Py_FileSystemDefaultEncoding,
3191 &path, &argv, &env))
3192 return NULL;
3193 if (PyList_Check(argv)) {
3194 argc = PyList_Size(argv);
3195 getitem = PyList_GetItem;
3196 }
3197 else if (PyTuple_Check(argv)) {
3198 argc = PyTuple_Size(argv);
3199 getitem = PyTuple_GetItem;
3200 }
3201 else {
3202 PyErr_SetString(PyExc_TypeError,
3203 "spawnvpe() arg 2 must be a tuple or list");
3204 goto fail_0;
3205 }
3206 if (!PyMapping_Check(env)) {
3207 PyErr_SetString(PyExc_TypeError,
3208 "spawnvpe() arg 3 must be a mapping object");
3209 goto fail_0;
3210 }
3211
3212 argvlist = PyMem_NEW(char *, argc+1);
3213 if (argvlist == NULL) {
3214 PyErr_NoMemory();
3215 goto fail_0;
3216 }
3217 for (i = 0; i < argc; i++) {
3218 if (!PyArg_Parse((*getitem)(argv, i),
3219 "et;spawnvpe() arg 2 must contain only strings",
3220 Py_FileSystemDefaultEncoding,
3221 &argvlist[i]))
3222 {
3223 lastarg = i;
3224 goto fail_1;
3225 }
3226 }
3227 lastarg = argc;
3228 argvlist[argc] = NULL;
3229
3230 i = PyMapping_Size(env);
3231 if (i < 0)
3232 goto fail_1;
3233 envlist = PyMem_NEW(char *, i + 1);
3234 if (envlist == NULL) {
3235 PyErr_NoMemory();
3236 goto fail_1;
3237 }
3238 envc = 0;
3239 keys = PyMapping_Keys(env);
3240 vals = PyMapping_Values(env);
3241 if (!keys || !vals)
3242 goto fail_2;
3243 if (!PyList_Check(keys) || !PyList_Check(vals)) {
3244 PyErr_SetString(PyExc_TypeError,
3245 "spawnvpe(): env.keys() or env.values() is not a list");
3246 goto fail_2;
3247 }
3248
3249 for (pos = 0; pos < i; pos++) {
3250 char *p, *k, *v;
3251 size_t len;
3252
3253 key = PyList_GetItem(keys, pos);
3254 val = PyList_GetItem(vals, pos);
3255 if (!key || !val)
3256 goto fail_2;
3257
3258 if (!PyArg_Parse(
3259 key,
3260 "s;spawnvpe() arg 3 contains a non-string key",
3261 &k) ||
3262 !PyArg_Parse(
3263 val,
3264 "s;spawnvpe() arg 3 contains a non-string value",
3265 &v))
3266 {
3267 goto fail_2;
3268 }
3269 len = PyString_Size(key) + PyString_Size(val) + 2;
3270 p = PyMem_NEW(char, len);
3271 if (p == NULL) {
3272 PyErr_NoMemory();
3273 goto fail_2;
3274 }
3275 PyOS_snprintf(p, len, "%s=%s", k, v);
3276 envlist[envc++] = p;
3277 }
3278 envlist[envc] = 0;
3279
3280 Py_BEGIN_ALLOW_THREADS
3281#if defined(PYCC_GCC)
3282 spawnval = spawnve(mode, path, argvlist, envlist);
3283#else
3284 spawnval = _spawnve(mode, path, argvlist, envlist);
3285#endif
3286 Py_END_ALLOW_THREADS
3287
3288 if (spawnval == -1)
3289 (void) posix_error();
3290 else
3291 res = Py_BuildValue("l", (long) spawnval);
3292
3293 fail_2:
3294 while (--envc >= 0)
3295 PyMem_DEL(envlist[envc]);
3296 PyMem_DEL(envlist);
3297 fail_1:
3298 free_string_array(argvlist, lastarg);
3299 Py_XDECREF(vals);
3300 Py_XDECREF(keys);
3301 fail_0:
3302 PyMem_Free(path);
3303 return res;
3304}
3305#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00003306#endif /* HAVE_SPAWNV */
3307
3308
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003309#ifdef HAVE_FORK1
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003310PyDoc_STRVAR(posix_fork1__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003311"fork1() -> pid\n\n\
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003312Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
3313\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003314Return 0 to child process and PID of child to parent process.");
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003315
3316static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003317posix_fork1(PyObject *self, PyObject *noargs)
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003318{
Neal Norwitze241ce82003-02-17 18:17:05 +00003319 int pid = fork1();
Guido van Rossum2242f2f2001-04-11 20:58:20 +00003320 if (pid == -1)
3321 return posix_error();
3322 PyOS_AfterFork();
3323 return PyInt_FromLong((long)pid);
3324}
3325#endif
3326
3327
Guido van Rossumad0ee831995-03-01 10:34:45 +00003328#ifdef HAVE_FORK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003329PyDoc_STRVAR(posix_fork__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003330"fork() -> pid\n\n\
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003331Fork a child process.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003332Return 0 to child process and PID of child to parent process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003333
Barry Warsaw53699e91996-12-10 23:23:01 +00003334static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003335posix_fork(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003336{
Neal Norwitze241ce82003-02-17 18:17:05 +00003337 int pid = fork();
Guido van Rossum85e3b011991-06-03 12:42:10 +00003338 if (pid == -1)
3339 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003340 if (pid == 0)
3341 PyOS_AfterFork();
Barry Warsaw53699e91996-12-10 23:23:01 +00003342 return PyInt_FromLong((long)pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00003343}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003344#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003345
Neal Norwitzb59798b2003-03-21 01:43:31 +00003346/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00003347/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
3348#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00003349#define DEV_PTY_FILE "/dev/ptc"
3350#define HAVE_DEV_PTMX
3351#else
3352#define DEV_PTY_FILE "/dev/ptmx"
3353#endif
3354
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003355#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003356#ifdef HAVE_PTY_H
3357#include <pty.h>
3358#else
3359#ifdef HAVE_LIBUTIL_H
3360#include <libutil.h>
Fred Drake8cef4cf2000-06-28 16:40:38 +00003361#endif /* HAVE_LIBUTIL_H */
3362#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00003363#ifdef HAVE_STROPTS_H
3364#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003365#endif
3366#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003367
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003368#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003369PyDoc_STRVAR(posix_openpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003370"openpty() -> (master_fd, slave_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003371Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003372
3373static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003374posix_openpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003375{
3376 int master_fd, slave_fd;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003377#ifndef HAVE_OPENPTY
3378 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00003379#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003380#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003381 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003382#ifdef sun
Neal Norwitz84a98e02006-04-10 07:44:23 +00003383 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003384#endif
3385#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00003386
Thomas Wouters70c21a12000-07-14 14:28:33 +00003387#ifdef HAVE_OPENPTY
Fred Drake8cef4cf2000-06-28 16:40:38 +00003388 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
3389 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003390#elif defined(HAVE__GETPTY)
Thomas Wouters70c21a12000-07-14 14:28:33 +00003391 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
3392 if (slave_name == NULL)
3393 return posix_error();
3394
3395 slave_fd = open(slave_name, O_RDWR);
3396 if (slave_fd < 0)
3397 return posix_error();
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003398#else
Neal Norwitzb59798b2003-03-21 01:43:31 +00003399 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003400 if (master_fd < 0)
3401 return posix_error();
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003402 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003403 /* change permission of slave */
3404 if (grantpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003405 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003406 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003407 }
3408 /* unlock slave */
3409 if (unlockpt(master_fd) < 0) {
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003410 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003411 return posix_error();
Martin v. Löwisc8b2e772002-12-31 14:30:26 +00003412 }
Anthony Baxter9ceaa722004-10-13 14:48:50 +00003413 PyOS_setsig(SIGCHLD, sig_saved);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003414 slave_name = ptsname(master_fd); /* get name of slave */
3415 if (slave_name == NULL)
3416 return posix_error();
3417 slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
3418 if (slave_fd < 0)
3419 return posix_error();
Neal Norwitzb59798b2003-03-21 01:43:31 +00003420#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003421 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
3422 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00003423#ifndef __hpux
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003424 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00003425#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003426#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00003427#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00003428
Fred Drake8cef4cf2000-06-28 16:40:38 +00003429 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00003430
Fred Drake8cef4cf2000-06-28 16:40:38 +00003431}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00003432#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00003433
3434#ifdef HAVE_FORKPTY
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003435PyDoc_STRVAR(posix_forkpty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003436"forkpty() -> (pid, master_fd)\n\n\
Fred Drake8cef4cf2000-06-28 16:40:38 +00003437Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
3438Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003439To both, return fd of newly opened pseudo-terminal.\n");
Fred Drake8cef4cf2000-06-28 16:40:38 +00003440
3441static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003442posix_forkpty(PyObject *self, PyObject *noargs)
Fred Drake8cef4cf2000-06-28 16:40:38 +00003443{
Neal Norwitz24b3c222005-09-19 06:43:44 +00003444 int master_fd = -1, pid;
Tim Peters5aa91602002-01-30 05:46:57 +00003445
Fred Drake8cef4cf2000-06-28 16:40:38 +00003446 pid = forkpty(&master_fd, NULL, NULL, NULL);
3447 if (pid == -1)
3448 return posix_error();
Fred Drake49b0c3b2000-07-06 19:42:19 +00003449 if (pid == 0)
3450 PyOS_AfterFork();
Fred Drake8cef4cf2000-06-28 16:40:38 +00003451 return Py_BuildValue("(ii)", pid, master_fd);
3452}
3453#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003454
Guido van Rossumad0ee831995-03-01 10:34:45 +00003455#ifdef HAVE_GETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003456PyDoc_STRVAR(posix_getegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003457"getegid() -> egid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003458Return the current process's effective group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003459
Barry Warsaw53699e91996-12-10 23:23:01 +00003460static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003461posix_getegid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003462{
Barry Warsaw53699e91996-12-10 23:23:01 +00003463 return PyInt_FromLong((long)getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003464}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003465#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003466
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003467
Guido van Rossumad0ee831995-03-01 10:34:45 +00003468#ifdef HAVE_GETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003469PyDoc_STRVAR(posix_geteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003470"geteuid() -> euid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003471Return the current process's effective user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003472
Barry Warsaw53699e91996-12-10 23:23:01 +00003473static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003474posix_geteuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003475{
Barry Warsaw53699e91996-12-10 23:23:01 +00003476 return PyInt_FromLong((long)geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003477}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003478#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003479
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003480
Guido van Rossumad0ee831995-03-01 10:34:45 +00003481#ifdef HAVE_GETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003482PyDoc_STRVAR(posix_getgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003483"getgid() -> gid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003484Return the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003485
Barry Warsaw53699e91996-12-10 23:23:01 +00003486static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003487posix_getgid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003488{
Barry Warsaw53699e91996-12-10 23:23:01 +00003489 return PyInt_FromLong((long)getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003490}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003491#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003492
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003493
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003494PyDoc_STRVAR(posix_getpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003495"getpid() -> pid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003496Return the current process id");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003497
Barry Warsaw53699e91996-12-10 23:23:01 +00003498static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003499posix_getpid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003500{
Barry Warsaw53699e91996-12-10 23:23:01 +00003501 return PyInt_FromLong((long)getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003502}
3503
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003504
Fred Drakec9680921999-12-13 16:37:25 +00003505#ifdef HAVE_GETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003506PyDoc_STRVAR(posix_getgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003507"getgroups() -> list of group IDs\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003508Return list of supplemental group IDs for the process.");
Fred Drakec9680921999-12-13 16:37:25 +00003509
3510static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003511posix_getgroups(PyObject *self, PyObject *noargs)
Fred Drakec9680921999-12-13 16:37:25 +00003512{
3513 PyObject *result = NULL;
3514
Fred Drakec9680921999-12-13 16:37:25 +00003515#ifdef NGROUPS_MAX
3516#define MAX_GROUPS NGROUPS_MAX
3517#else
3518 /* defined to be 16 on Solaris7, so this should be a small number */
3519#define MAX_GROUPS 64
3520#endif
3521 gid_t grouplist[MAX_GROUPS];
3522 int n;
3523
3524 n = getgroups(MAX_GROUPS, grouplist);
3525 if (n < 0)
3526 posix_error();
3527 else {
3528 result = PyList_New(n);
3529 if (result != NULL) {
Fred Drakec9680921999-12-13 16:37:25 +00003530 int i;
3531 for (i = 0; i < n; ++i) {
Neal Norwitze241ce82003-02-17 18:17:05 +00003532 PyObject *o = PyInt_FromLong((long)grouplist[i]);
Fred Drakec9680921999-12-13 16:37:25 +00003533 if (o == NULL) {
3534 Py_DECREF(result);
3535 result = NULL;
3536 break;
3537 }
3538 PyList_SET_ITEM(result, i, o);
3539 }
3540 }
3541 }
Neal Norwitze241ce82003-02-17 18:17:05 +00003542
Fred Drakec9680921999-12-13 16:37:25 +00003543 return result;
3544}
3545#endif
3546
Martin v. Löwis606edc12002-06-13 21:09:11 +00003547#ifdef HAVE_GETPGID
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003548PyDoc_STRVAR(posix_getpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003549"getpgid(pid) -> pgid\n\n\
Neal Norwitz0c2c17c2002-06-13 21:22:11 +00003550Call the system call getpgid().");
Martin v. Löwis606edc12002-06-13 21:09:11 +00003551
3552static PyObject *
3553posix_getpgid(PyObject *self, PyObject *args)
3554{
3555 int pid, pgid;
3556 if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
3557 return NULL;
3558 pgid = getpgid(pid);
3559 if (pgid < 0)
3560 return posix_error();
3561 return PyInt_FromLong((long)pgid);
3562}
3563#endif /* HAVE_GETPGID */
3564
3565
Guido van Rossumb6775db1994-08-01 11:34:53 +00003566#ifdef HAVE_GETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003567PyDoc_STRVAR(posix_getpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003568"getpgrp() -> pgrp\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003569Return the current process group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003570
Barry Warsaw53699e91996-12-10 23:23:01 +00003571static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003572posix_getpgrp(PyObject *self, PyObject *noargs)
Guido van Rossum04814471991-06-04 20:23:49 +00003573{
Guido van Rossumb6775db1994-08-01 11:34:53 +00003574#ifdef GETPGRP_HAVE_ARG
Barry Warsaw53699e91996-12-10 23:23:01 +00003575 return PyInt_FromLong((long)getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003576#else /* GETPGRP_HAVE_ARG */
Barry Warsaw53699e91996-12-10 23:23:01 +00003577 return PyInt_FromLong((long)getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003578#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00003579}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003580#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00003581
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003582
Guido van Rossumb6775db1994-08-01 11:34:53 +00003583#ifdef HAVE_SETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003584PyDoc_STRVAR(posix_setpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003585"setpgrp()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003586Make this process a session leader.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003587
Barry Warsaw53699e91996-12-10 23:23:01 +00003588static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003589posix_setpgrp(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00003590{
Guido van Rossum64933891994-10-20 21:56:42 +00003591#ifdef SETPGRP_HAVE_ARG
Guido van Rossumc2670a01992-09-13 20:07:29 +00003592 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003593#else /* SETPGRP_HAVE_ARG */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003594 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00003595#endif /* SETPGRP_HAVE_ARG */
Guido van Rossum687dd131993-05-17 08:34:16 +00003596 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003597 Py_INCREF(Py_None);
3598 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00003599}
3600
Guido van Rossumb6775db1994-08-01 11:34:53 +00003601#endif /* HAVE_SETPGRP */
3602
Guido van Rossumad0ee831995-03-01 10:34:45 +00003603#ifdef HAVE_GETPPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003604PyDoc_STRVAR(posix_getppid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003605"getppid() -> ppid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003606Return the parent's process id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003607
Barry Warsaw53699e91996-12-10 23:23:01 +00003608static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003609posix_getppid(PyObject *self, PyObject *noargs)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003610{
Barry Warsaw53699e91996-12-10 23:23:01 +00003611 return PyInt_FromLong((long)getppid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00003612}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003613#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003614
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003615
Fred Drake12c6e2d1999-12-14 21:25:03 +00003616#ifdef HAVE_GETLOGIN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003617PyDoc_STRVAR(posix_getlogin__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003618"getlogin() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003619Return the actual login name.");
Fred Drake12c6e2d1999-12-14 21:25:03 +00003620
3621static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003622posix_getlogin(PyObject *self, PyObject *noargs)
Fred Drake12c6e2d1999-12-14 21:25:03 +00003623{
Neal Norwitze241ce82003-02-17 18:17:05 +00003624 PyObject *result = NULL;
Fred Drakea30680b2000-12-06 21:24:28 +00003625 char *name;
3626 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00003627
Fred Drakea30680b2000-12-06 21:24:28 +00003628 errno = 0;
3629 name = getlogin();
3630 if (name == NULL) {
3631 if (errno)
3632 posix_error();
3633 else
3634 PyErr_SetString(PyExc_OSError,
Fred Drakee63544f2000-12-06 21:45:33 +00003635 "unable to determine login name");
Fred Drakea30680b2000-12-06 21:24:28 +00003636 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00003637 else
3638 result = PyString_FromString(name);
Fred Drakea30680b2000-12-06 21:24:28 +00003639 errno = old_errno;
Neal Norwitze241ce82003-02-17 18:17:05 +00003640
Fred Drake12c6e2d1999-12-14 21:25:03 +00003641 return result;
3642}
3643#endif
3644
Guido van Rossumad0ee831995-03-01 10:34:45 +00003645#ifdef HAVE_GETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003646PyDoc_STRVAR(posix_getuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003647"getuid() -> uid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003648Return the current process's user id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003649
Barry Warsaw53699e91996-12-10 23:23:01 +00003650static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00003651posix_getuid(PyObject *self, PyObject *noargs)
Guido van Rossum46003ff1992-05-15 11:05:24 +00003652{
Barry Warsaw53699e91996-12-10 23:23:01 +00003653 return PyInt_FromLong((long)getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00003654}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003655#endif
Guido van Rossum46003ff1992-05-15 11:05:24 +00003656
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003657
Guido van Rossumad0ee831995-03-01 10:34:45 +00003658#ifdef HAVE_KILL
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003659PyDoc_STRVAR(posix_kill__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003660"kill(pid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003661Kill a process with a signal.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003662
Barry Warsaw53699e91996-12-10 23:23:01 +00003663static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003664posix_kill(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00003665{
3666 int pid, sig;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003667 if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
Guido van Rossum85e3b011991-06-03 12:42:10 +00003668 return NULL;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003669#if defined(PYOS_OS2) && !defined(PYCC_GCC)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003670 if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
3671 APIRET rc;
3672 if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003673 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003674
3675 } else if (sig == XCPT_SIGNAL_KILLPROC) {
3676 APIRET rc;
3677 if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003678 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003679
3680 } else
Guido van Rossumc5a0f531997-12-02 20:36:02 +00003681 return NULL; /* Unrecognized Signal Requested */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003682#else
Guido van Rossum85e3b011991-06-03 12:42:10 +00003683 if (kill(pid, sig) == -1)
3684 return posix_error();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003685#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00003686 Py_INCREF(Py_None);
3687 return Py_None;
Guido van Rossum85e3b011991-06-03 12:42:10 +00003688}
Guido van Rossumad0ee831995-03-01 10:34:45 +00003689#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00003690
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003691#ifdef HAVE_KILLPG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003692PyDoc_STRVAR(posix_killpg__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003693"killpg(pgid, sig)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003694Kill a process group with a signal.");
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00003695
3696static PyObject *
3697posix_killpg(PyObject *self, PyObject *args)
3698{
3699 int pgid, sig;
3700 if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
3701 return NULL;
3702 if (killpg(pgid, sig) == -1)
3703 return posix_error();
3704 Py_INCREF(Py_None);
3705 return Py_None;
3706}
3707#endif
3708
Guido van Rossumc0125471996-06-28 18:55:32 +00003709#ifdef HAVE_PLOCK
3710
3711#ifdef HAVE_SYS_LOCK_H
3712#include <sys/lock.h>
3713#endif
3714
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003715PyDoc_STRVAR(posix_plock__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003716"plock(op)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003717Lock program segments into memory.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003718
Barry Warsaw53699e91996-12-10 23:23:01 +00003719static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003720posix_plock(PyObject *self, PyObject *args)
Guido van Rossumc0125471996-06-28 18:55:32 +00003721{
3722 int op;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003723 if (!PyArg_ParseTuple(args, "i:plock", &op))
Guido van Rossumc0125471996-06-28 18:55:32 +00003724 return NULL;
3725 if (plock(op) == -1)
3726 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00003727 Py_INCREF(Py_None);
3728 return Py_None;
Guido van Rossumc0125471996-06-28 18:55:32 +00003729}
3730#endif
3731
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003732
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003733#ifdef HAVE_POPEN
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003734PyDoc_STRVAR(posix_popen__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00003735"popen(command [, mode='r' [, bufsize]]) -> pipe\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00003736Open a pipe to/from a command returning a file object.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003737
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003738#if defined(PYOS_OS2)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003739#if defined(PYCC_VACPP)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003740static int
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003741async_system(const char *command)
3742{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003743 char errormsg[256], args[1024];
3744 RESULTCODES rcodes;
3745 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003746
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003747 char *shell = getenv("COMSPEC");
3748 if (!shell)
3749 shell = "cmd";
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003750
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003751 /* avoid overflowing the argument buffer */
3752 if (strlen(shell) + 3 + strlen(command) >= 1024)
3753 return ERROR_NOT_ENOUGH_MEMORY
3754
3755 args[0] = '\0';
3756 strcat(args, shell);
3757 strcat(args, "/c ");
3758 strcat(args, command);
3759
3760 /* execute asynchronously, inheriting the environment */
3761 rc = DosExecPgm(errormsg,
3762 sizeof(errormsg),
3763 EXEC_ASYNC,
3764 args,
3765 NULL,
3766 &rcodes,
3767 shell);
3768 return rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003769}
3770
Guido van Rossumd48f2521997-12-05 22:19:34 +00003771static FILE *
3772popen(const char *command, const char *mode, int pipesize, int *err)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003773{
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003774 int oldfd, tgtfd;
3775 HFILE pipeh[2];
3776 APIRET rc;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003777
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003778 /* mode determines which of stdin or stdout is reconnected to
3779 * the pipe to the child
3780 */
3781 if (strchr(mode, 'r') != NULL) {
3782 tgt_fd = 1; /* stdout */
3783 } else if (strchr(mode, 'w')) {
3784 tgt_fd = 0; /* stdin */
3785 } else {
3786 *err = ERROR_INVALID_ACCESS;
3787 return NULL;
3788 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003789
Andrew MacIntyrea3be2582004-12-18 09:51:05 +00003790 /* setup the pipe */
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003791 if ((rc = DosCreatePipe(&pipeh[0], &pipeh[1], pipesize)) != NO_ERROR) {
3792 *err = rc;
3793 return NULL;
3794 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003795
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003796 /* prevent other threads accessing stdio */
3797 DosEnterCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003798
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003799 /* reconnect stdio and execute child */
3800 oldfd = dup(tgtfd);
3801 close(tgtfd);
3802 if (dup2(pipeh[tgtfd], tgtfd) == 0) {
3803 DosClose(pipeh[tgtfd]);
3804 rc = async_system(command);
3805 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003806
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003807 /* restore stdio */
3808 dup2(oldfd, tgtfd);
3809 close(oldfd);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003810
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003811 /* allow other threads access to stdio */
3812 DosExitCritSec();
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003813
Andrew MacIntyrea4a8afb2004-12-12 08:30:51 +00003814 /* if execution of child was successful return file stream */
3815 if (rc == NO_ERROR)
3816 return fdopen(pipeh[1 - tgtfd], mode);
3817 else {
3818 DosClose(pipeh[1 - tgtfd]);
3819 *err = rc;
3820 return NULL;
3821 }
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003822}
3823
3824static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00003825posix_popen(PyObject *self, PyObject *args)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003826{
3827 char *name;
3828 char *mode = "r";
Guido van Rossumd48f2521997-12-05 22:19:34 +00003829 int err, bufsize = -1;
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003830 FILE *fp;
3831 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00003832 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003833 return NULL;
3834 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd48f2521997-12-05 22:19:34 +00003835 fp = popen(name, mode, (bufsize > 0) ? bufsize : 4096, &err);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003836 Py_END_ALLOW_THREADS
3837 if (fp == NULL)
Guido van Rossumd48f2521997-12-05 22:19:34 +00003838 return os2_error(err);
3839
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00003840 f = PyFile_FromFile(fp, name, mode, fclose);
3841 if (f != NULL)
3842 PyFile_SetBufSize(f, bufsize);
3843 return f;
3844}
3845
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003846#elif defined(PYCC_GCC)
3847
3848/* standard posix version of popen() support */
3849static PyObject *
3850posix_popen(PyObject *self, PyObject *args)
3851{
3852 char *name;
3853 char *mode = "r";
3854 int bufsize = -1;
3855 FILE *fp;
3856 PyObject *f;
3857 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
3858 return NULL;
3859 Py_BEGIN_ALLOW_THREADS
3860 fp = popen(name, mode);
3861 Py_END_ALLOW_THREADS
3862 if (fp == NULL)
3863 return posix_error();
3864 f = PyFile_FromFile(fp, name, mode, pclose);
3865 if (f != NULL)
3866 PyFile_SetBufSize(f, bufsize);
3867 return f;
3868}
3869
3870/* fork() under OS/2 has lots'o'warts
3871 * EMX supports pipe() and spawn*() so we can synthesize popen[234]()
3872 * most of this code is a ripoff of the win32 code, but using the
3873 * capabilities of EMX's C library routines
3874 */
3875
3876/* These tell _PyPopen() whether to return 1, 2, or 3 file objects. */
3877#define POPEN_1 1
3878#define POPEN_2 2
3879#define POPEN_3 3
3880#define POPEN_4 4
3881
3882static PyObject *_PyPopen(char *, int, int, int);
3883static int _PyPclose(FILE *file);
3884
3885/*
3886 * Internal dictionary mapping popen* file pointers to process handles,
3887 * for use when retrieving the process exit code. See _PyPclose() below
3888 * for more information on this dictionary's use.
3889 */
3890static PyObject *_PyPopenProcs = NULL;
3891
3892/* os2emx version of popen2()
3893 *
3894 * The result of this function is a pipe (file) connected to the
3895 * process's stdin, and a pipe connected to the process's stdout.
3896 */
3897
3898static PyObject *
3899os2emx_popen2(PyObject *self, PyObject *args)
3900{
3901 PyObject *f;
3902 int tm=0;
3903
3904 char *cmdstring;
3905 char *mode = "t";
3906 int bufsize = -1;
3907 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
3908 return NULL;
3909
3910 if (*mode == 't')
3911 tm = O_TEXT;
3912 else if (*mode != 'b') {
3913 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3914 return NULL;
3915 } else
3916 tm = O_BINARY;
3917
3918 f = _PyPopen(cmdstring, tm, POPEN_2, bufsize);
3919
3920 return f;
3921}
3922
3923/*
3924 * Variation on os2emx.popen2
3925 *
3926 * The result of this function is 3 pipes - the process's stdin,
3927 * stdout and stderr
3928 */
3929
3930static PyObject *
3931os2emx_popen3(PyObject *self, PyObject *args)
3932{
3933 PyObject *f;
3934 int tm = 0;
3935
3936 char *cmdstring;
3937 char *mode = "t";
3938 int bufsize = -1;
3939 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
3940 return NULL;
3941
3942 if (*mode == 't')
3943 tm = O_TEXT;
3944 else if (*mode != 'b') {
3945 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3946 return NULL;
3947 } else
3948 tm = O_BINARY;
3949
3950 f = _PyPopen(cmdstring, tm, POPEN_3, bufsize);
3951
3952 return f;
3953}
3954
3955/*
3956 * Variation on os2emx.popen2
3957 *
Tim Peters11b23062003-04-23 02:39:17 +00003958 * The result of this function is 2 pipes - the processes stdin,
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00003959 * and stdout+stderr combined as a single pipe.
3960 */
3961
3962static PyObject *
3963os2emx_popen4(PyObject *self, PyObject *args)
3964{
3965 PyObject *f;
3966 int tm = 0;
3967
3968 char *cmdstring;
3969 char *mode = "t";
3970 int bufsize = -1;
3971 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
3972 return NULL;
3973
3974 if (*mode == 't')
3975 tm = O_TEXT;
3976 else if (*mode != 'b') {
3977 PyErr_SetString(PyExc_ValueError, "mode must be 't' or 'b'");
3978 return NULL;
3979 } else
3980 tm = O_BINARY;
3981
3982 f = _PyPopen(cmdstring, tm, POPEN_4, bufsize);
3983
3984 return f;
3985}
3986
3987/* a couple of structures for convenient handling of multiple
3988 * file handles and pipes
3989 */
3990struct file_ref
3991{
3992 int handle;
3993 int flags;
3994};
3995
3996struct pipe_ref
3997{
3998 int rd;
3999 int wr;
4000};
4001
4002/* The following code is derived from the win32 code */
4003
4004static PyObject *
4005_PyPopen(char *cmdstring, int mode, int n, int bufsize)
4006{
4007 struct file_ref stdio[3];
4008 struct pipe_ref p_fd[3];
4009 FILE *p_s[3];
4010 int file_count, i, pipe_err, pipe_pid;
4011 char *shell, *sh_name, *opt, *rd_mode, *wr_mode;
4012 PyObject *f, *p_f[3];
4013
4014 /* file modes for subsequent fdopen's on pipe handles */
4015 if (mode == O_TEXT)
4016 {
4017 rd_mode = "rt";
4018 wr_mode = "wt";
4019 }
4020 else
4021 {
4022 rd_mode = "rb";
4023 wr_mode = "wb";
4024 }
4025
4026 /* prepare shell references */
4027 if ((shell = getenv("EMXSHELL")) == NULL)
4028 if ((shell = getenv("COMSPEC")) == NULL)
4029 {
4030 errno = ENOENT;
4031 return posix_error();
4032 }
4033
4034 sh_name = _getname(shell);
4035 if (stricmp(sh_name, "cmd.exe") == 0 || stricmp(sh_name, "4os2.exe") == 0)
4036 opt = "/c";
4037 else
4038 opt = "-c";
4039
4040 /* save current stdio fds + their flags, and set not inheritable */
4041 i = pipe_err = 0;
4042 while (pipe_err >= 0 && i < 3)
4043 {
4044 pipe_err = stdio[i].handle = dup(i);
4045 stdio[i].flags = fcntl(i, F_GETFD, 0);
4046 fcntl(stdio[i].handle, F_SETFD, stdio[i].flags | FD_CLOEXEC);
4047 i++;
4048 }
4049 if (pipe_err < 0)
4050 {
4051 /* didn't get them all saved - clean up and bail out */
4052 int saved_err = errno;
4053 while (i-- > 0)
4054 {
4055 close(stdio[i].handle);
4056 }
4057 errno = saved_err;
4058 return posix_error();
4059 }
4060
4061 /* create pipe ends */
4062 file_count = 2;
4063 if (n == POPEN_3)
4064 file_count = 3;
4065 i = pipe_err = 0;
4066 while ((pipe_err == 0) && (i < file_count))
4067 pipe_err = pipe((int *)&p_fd[i++]);
4068 if (pipe_err < 0)
4069 {
4070 /* didn't get them all made - clean up and bail out */
4071 while (i-- > 0)
4072 {
4073 close(p_fd[i].wr);
4074 close(p_fd[i].rd);
4075 }
4076 errno = EPIPE;
4077 return posix_error();
4078 }
4079
4080 /* change the actual standard IO streams over temporarily,
4081 * making the retained pipe ends non-inheritable
4082 */
4083 pipe_err = 0;
4084
4085 /* - stdin */
4086 if (dup2(p_fd[0].rd, 0) == 0)
4087 {
4088 close(p_fd[0].rd);
4089 i = fcntl(p_fd[0].wr, F_GETFD, 0);
4090 fcntl(p_fd[0].wr, F_SETFD, i | FD_CLOEXEC);
4091 if ((p_s[0] = fdopen(p_fd[0].wr, wr_mode)) == NULL)
4092 {
4093 close(p_fd[0].wr);
4094 pipe_err = -1;
4095 }
4096 }
4097 else
4098 {
4099 pipe_err = -1;
4100 }
4101
4102 /* - stdout */
4103 if (pipe_err == 0)
4104 {
4105 if (dup2(p_fd[1].wr, 1) == 1)
4106 {
4107 close(p_fd[1].wr);
4108 i = fcntl(p_fd[1].rd, F_GETFD, 0);
4109 fcntl(p_fd[1].rd, F_SETFD, i | FD_CLOEXEC);
4110 if ((p_s[1] = fdopen(p_fd[1].rd, rd_mode)) == NULL)
4111 {
4112 close(p_fd[1].rd);
4113 pipe_err = -1;
4114 }
4115 }
4116 else
4117 {
4118 pipe_err = -1;
4119 }
4120 }
4121
4122 /* - stderr, as required */
4123 if (pipe_err == 0)
4124 switch (n)
4125 {
4126 case POPEN_3:
4127 {
4128 if (dup2(p_fd[2].wr, 2) == 2)
4129 {
4130 close(p_fd[2].wr);
4131 i = fcntl(p_fd[2].rd, F_GETFD, 0);
4132 fcntl(p_fd[2].rd, F_SETFD, i | FD_CLOEXEC);
4133 if ((p_s[2] = fdopen(p_fd[2].rd, rd_mode)) == NULL)
4134 {
4135 close(p_fd[2].rd);
4136 pipe_err = -1;
4137 }
4138 }
4139 else
4140 {
4141 pipe_err = -1;
4142 }
4143 break;
4144 }
4145
4146 case POPEN_4:
4147 {
4148 if (dup2(1, 2) != 2)
4149 {
4150 pipe_err = -1;
4151 }
4152 break;
4153 }
4154 }
4155
4156 /* spawn the child process */
4157 if (pipe_err == 0)
4158 {
4159 pipe_pid = spawnlp(P_NOWAIT, shell, shell, opt, cmdstring, (char *)0);
4160 if (pipe_pid == -1)
4161 {
4162 pipe_err = -1;
4163 }
4164 else
4165 {
4166 /* save the PID into the FILE structure
4167 * NOTE: this implementation doesn't actually
4168 * take advantage of this, but do it for
4169 * completeness - AIM Apr01
4170 */
4171 for (i = 0; i < file_count; i++)
4172 p_s[i]->_pid = pipe_pid;
4173 }
4174 }
4175
4176 /* reset standard IO to normal */
4177 for (i = 0; i < 3; i++)
4178 {
4179 dup2(stdio[i].handle, i);
4180 fcntl(i, F_SETFD, stdio[i].flags);
4181 close(stdio[i].handle);
4182 }
4183
4184 /* if any remnant problems, clean up and bail out */
4185 if (pipe_err < 0)
4186 {
4187 for (i = 0; i < 3; i++)
4188 {
4189 close(p_fd[i].rd);
4190 close(p_fd[i].wr);
4191 }
4192 errno = EPIPE;
4193 return posix_error_with_filename(cmdstring);
4194 }
4195
4196 /* build tuple of file objects to return */
4197 if ((p_f[0] = PyFile_FromFile(p_s[0], cmdstring, wr_mode, _PyPclose)) != NULL)
4198 PyFile_SetBufSize(p_f[0], bufsize);
4199 if ((p_f[1] = PyFile_FromFile(p_s[1], cmdstring, rd_mode, _PyPclose)) != NULL)
4200 PyFile_SetBufSize(p_f[1], bufsize);
4201 if (n == POPEN_3)
4202 {
4203 if ((p_f[2] = PyFile_FromFile(p_s[2], cmdstring, rd_mode, _PyPclose)) != NULL)
4204 PyFile_SetBufSize(p_f[0], bufsize);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004205 f = PyTuple_Pack(3, p_f[0], p_f[1], p_f[2]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004206 }
4207 else
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004208 f = PyTuple_Pack(2, p_f[0], p_f[1]);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004209
4210 /*
4211 * Insert the files we've created into the process dictionary
4212 * all referencing the list with the process handle and the
4213 * initial number of files (see description below in _PyPclose).
4214 * Since if _PyPclose later tried to wait on a process when all
4215 * handles weren't closed, it could create a deadlock with the
4216 * child, we spend some energy here to try to ensure that we
4217 * either insert all file handles into the dictionary or none
4218 * at all. It's a little clumsy with the various popen modes
4219 * and variable number of files involved.
4220 */
4221 if (!_PyPopenProcs)
4222 {
4223 _PyPopenProcs = PyDict_New();
4224 }
4225
4226 if (_PyPopenProcs)
4227 {
4228 PyObject *procObj, *pidObj, *intObj, *fileObj[3];
4229 int ins_rc[3];
4230
4231 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4232 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4233
4234 procObj = PyList_New(2);
4235 pidObj = PyInt_FromLong((long) pipe_pid);
4236 intObj = PyInt_FromLong((long) file_count);
4237
4238 if (procObj && pidObj && intObj)
4239 {
4240 PyList_SetItem(procObj, 0, pidObj);
4241 PyList_SetItem(procObj, 1, intObj);
4242
4243 fileObj[0] = PyLong_FromVoidPtr(p_s[0]);
4244 if (fileObj[0])
4245 {
4246 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4247 fileObj[0],
4248 procObj);
4249 }
4250 fileObj[1] = PyLong_FromVoidPtr(p_s[1]);
4251 if (fileObj[1])
4252 {
4253 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4254 fileObj[1],
4255 procObj);
4256 }
4257 if (file_count >= 3)
4258 {
4259 fileObj[2] = PyLong_FromVoidPtr(p_s[2]);
4260 if (fileObj[2])
4261 {
4262 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
4263 fileObj[2],
4264 procObj);
4265 }
4266 }
4267
4268 if (ins_rc[0] < 0 || !fileObj[0] ||
4269 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
4270 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2]))
4271 {
4272 /* Something failed - remove any dictionary
4273 * entries that did make it.
4274 */
4275 if (!ins_rc[0] && fileObj[0])
4276 {
4277 PyDict_DelItem(_PyPopenProcs,
4278 fileObj[0]);
4279 }
4280 if (!ins_rc[1] && fileObj[1])
4281 {
4282 PyDict_DelItem(_PyPopenProcs,
4283 fileObj[1]);
4284 }
4285 if (!ins_rc[2] && fileObj[2])
4286 {
4287 PyDict_DelItem(_PyPopenProcs,
4288 fileObj[2]);
4289 }
4290 }
4291 }
Tim Peters11b23062003-04-23 02:39:17 +00004292
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004293 /*
4294 * Clean up our localized references for the dictionary keys
4295 * and value since PyDict_SetItem will Py_INCREF any copies
4296 * that got placed in the dictionary.
4297 */
4298 Py_XDECREF(procObj);
4299 Py_XDECREF(fileObj[0]);
4300 Py_XDECREF(fileObj[1]);
4301 Py_XDECREF(fileObj[2]);
4302 }
4303
4304 /* Child is launched. */
4305 return f;
4306}
4307
4308/*
4309 * Wrapper for fclose() to use for popen* files, so we can retrieve the
4310 * exit code for the child process and return as a result of the close.
4311 *
4312 * This function uses the _PyPopenProcs dictionary in order to map the
4313 * input file pointer to information about the process that was
4314 * originally created by the popen* call that created the file pointer.
4315 * The dictionary uses the file pointer as a key (with one entry
4316 * inserted for each file returned by the original popen* call) and a
4317 * single list object as the value for all files from a single call.
4318 * The list object contains the Win32 process handle at [0], and a file
4319 * count at [1], which is initialized to the total number of file
4320 * handles using that list.
4321 *
4322 * This function closes whichever handle it is passed, and decrements
4323 * the file count in the dictionary for the process handle pointed to
4324 * by this file. On the last close (when the file count reaches zero),
4325 * this function will wait for the child process and then return its
4326 * exit code as the result of the close() operation. This permits the
4327 * files to be closed in any order - it is always the close() of the
4328 * final handle that will return the exit code.
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004329 *
4330 * NOTE: This function is currently called with the GIL released.
4331 * hence we use the GILState API to manage our state.
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004332 */
4333
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004334static int _PyPclose(FILE *file)
4335{
4336 int result;
4337 int exit_code;
4338 int pipe_pid;
4339 PyObject *procObj, *pidObj, *intObj, *fileObj;
4340 int file_count;
4341#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004342 PyGILState_STATE state;
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004343#endif
4344
4345 /* Close the file handle first, to ensure it can't block the
4346 * child from exiting if it's the last handle.
4347 */
4348 result = fclose(file);
4349
4350#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004351 state = PyGILState_Ensure();
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004352#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004353 if (_PyPopenProcs)
4354 {
4355 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
4356 (procObj = PyDict_GetItem(_PyPopenProcs,
4357 fileObj)) != NULL &&
4358 (pidObj = PyList_GetItem(procObj,0)) != NULL &&
4359 (intObj = PyList_GetItem(procObj,1)) != NULL)
4360 {
4361 pipe_pid = (int) PyInt_AsLong(pidObj);
4362 file_count = (int) PyInt_AsLong(intObj);
4363
4364 if (file_count > 1)
4365 {
4366 /* Still other files referencing process */
4367 file_count--;
4368 PyList_SetItem(procObj,1,
4369 PyInt_FromLong((long) file_count));
4370 }
4371 else
4372 {
4373 /* Last file for this process */
4374 if (result != EOF &&
4375 waitpid(pipe_pid, &exit_code, 0) == pipe_pid)
4376 {
4377 /* extract exit status */
4378 if (WIFEXITED(exit_code))
4379 {
4380 result = WEXITSTATUS(exit_code);
4381 }
4382 else
4383 {
4384 errno = EPIPE;
4385 result = -1;
4386 }
4387 }
4388 else
4389 {
4390 /* Indicate failure - this will cause the file object
4391 * to raise an I/O error and translate the last
4392 * error code from errno. We do have a problem with
4393 * last errors that overlap the normal errno table,
4394 * but that's a consistent problem with the file object.
4395 */
4396 result = -1;
4397 }
4398 }
4399
4400 /* Remove this file pointer from dictionary */
4401 PyDict_DelItem(_PyPopenProcs, fileObj);
4402
4403 if (PyDict_Size(_PyPopenProcs) == 0)
4404 {
4405 Py_DECREF(_PyPopenProcs);
4406 _PyPopenProcs = NULL;
4407 }
4408
4409 } /* if object retrieval ok */
4410
4411 Py_XDECREF(fileObj);
4412 } /* if _PyPopenProcs */
4413
4414#ifdef WITH_THREAD
Andrew MacIntyrebaf25b02003-04-21 14:22:36 +00004415 PyGILState_Release(state);
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004416#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004417 return result;
4418}
4419
4420#endif /* PYCC_??? */
4421
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004422#elif defined(MS_WINDOWS)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004423
4424/*
4425 * Portable 'popen' replacement for Win32.
4426 *
4427 * Written by Bill Tutt <billtut@microsoft.com>. Minor tweaks
4428 * and 2.0 integration by Fredrik Lundh <fredrik@pythonware.com>
Mark Hammondb37a3732000-08-14 04:47:33 +00004429 * Return code handling by David Bolen <db3l@fitlinxx.com>.
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004430 */
4431
4432#include <malloc.h>
4433#include <io.h>
4434#include <fcntl.h>
4435
4436/* These tell _PyPopen() wether to return 1, 2, or 3 file objects. */
4437#define POPEN_1 1
4438#define POPEN_2 2
4439#define POPEN_3 3
4440#define POPEN_4 4
4441
4442static PyObject *_PyPopen(char *, int, int);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004443static int _PyPclose(FILE *file);
4444
4445/*
4446 * Internal dictionary mapping popen* file pointers to process handles,
Mark Hammondb37a3732000-08-14 04:47:33 +00004447 * for use when retrieving the process exit code. See _PyPclose() below
4448 * for more information on this dictionary's use.
Fredrik Lundh56055a42000-07-23 19:47:12 +00004449 */
4450static PyObject *_PyPopenProcs = NULL;
4451
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004452
4453/* popen that works from a GUI.
4454 *
4455 * The result of this function is a pipe (file) connected to the
4456 * processes stdin or stdout, depending on the requested mode.
4457 */
4458
4459static PyObject *
4460posix_popen(PyObject *self, PyObject *args)
4461{
Raymond Hettingerb5cb6652003-09-01 22:25:41 +00004462 PyObject *f;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004463 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004464
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004465 char *cmdstring;
4466 char *mode = "r";
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004467 int bufsize = -1;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004468 if (!PyArg_ParseTuple(args, "s|si:popen", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004469 return NULL;
4470
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004471 if (*mode == 'r')
4472 tm = _O_RDONLY;
4473 else if (*mode != 'w') {
Fred Drake661ea262000-10-24 19:57:45 +00004474 PyErr_SetString(PyExc_ValueError, "popen() arg 2 must be 'r' or 'w'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004475 return NULL;
4476 } else
4477 tm = _O_WRONLY;
Tim Peters5aa91602002-01-30 05:46:57 +00004478
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004479 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004480 PyErr_SetString(PyExc_ValueError, "popen() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004481 return NULL;
4482 }
4483
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004484 if (*(mode+1) == 't')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004485 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004486 else if (*(mode+1) == 'b')
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004487 f = _PyPopen(cmdstring, tm | _O_BINARY, POPEN_1);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004488 else
4489 f = _PyPopen(cmdstring, tm | _O_TEXT, POPEN_1);
4490
4491 return f;
4492}
4493
4494/* Variation on win32pipe.popen
4495 *
4496 * The result of this function is a pipe (file) connected to the
4497 * process's stdin, and a pipe connected to the process's stdout.
4498 */
4499
4500static PyObject *
4501win32_popen2(PyObject *self, PyObject *args)
4502{
4503 PyObject *f;
4504 int tm=0;
Tim Peters5aa91602002-01-30 05:46:57 +00004505
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004506 char *cmdstring;
4507 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004508 int bufsize = -1;
4509 if (!PyArg_ParseTuple(args, "s|si:popen2", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004510 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004511
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004512 if (*mode == 't')
4513 tm = _O_TEXT;
4514 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004515 PyErr_SetString(PyExc_ValueError, "popen2() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004516 return NULL;
4517 } else
4518 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004519
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004520 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004521 PyErr_SetString(PyExc_ValueError, "popen2() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004522 return NULL;
4523 }
4524
4525 f = _PyPopen(cmdstring, tm, POPEN_2);
Tim Peters5aa91602002-01-30 05:46:57 +00004526
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004527 return f;
4528}
4529
4530/*
4531 * Variation on <om win32pipe.popen>
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004532 *
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004533 * The result of this function is 3 pipes - the process's stdin,
4534 * stdout and stderr
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004535 */
4536
4537static PyObject *
4538win32_popen3(PyObject *self, PyObject *args)
4539{
4540 PyObject *f;
4541 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004542
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004543 char *cmdstring;
4544 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004545 int bufsize = -1;
4546 if (!PyArg_ParseTuple(args, "s|si:popen3", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004547 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004548
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004549 if (*mode == 't')
4550 tm = _O_TEXT;
4551 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004552 PyErr_SetString(PyExc_ValueError, "popen3() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004553 return NULL;
4554 } else
4555 tm = _O_BINARY;
Tim Peters5aa91602002-01-30 05:46:57 +00004556
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004557 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004558 PyErr_SetString(PyExc_ValueError, "popen3() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004559 return NULL;
4560 }
4561
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004562 f = _PyPopen(cmdstring, tm, POPEN_3);
Tim Peters5aa91602002-01-30 05:46:57 +00004563
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004564 return f;
4565}
4566
4567/*
4568 * Variation on win32pipe.popen
4569 *
Tim Peters5aa91602002-01-30 05:46:57 +00004570 * The result of this function is 2 pipes - the processes stdin,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004571 * and stdout+stderr combined as a single pipe.
4572 */
4573
4574static PyObject *
4575win32_popen4(PyObject *self, PyObject *args)
4576{
4577 PyObject *f;
4578 int tm = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00004579
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004580 char *cmdstring;
4581 char *mode = "t";
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004582 int bufsize = -1;
4583 if (!PyArg_ParseTuple(args, "s|si:popen4", &cmdstring, &mode, &bufsize))
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004584 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00004585
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004586 if (*mode == 't')
4587 tm = _O_TEXT;
4588 else if (*mode != 'b') {
Fred Drake661ea262000-10-24 19:57:45 +00004589 PyErr_SetString(PyExc_ValueError, "popen4() arg 2 must be 't' or 'b'");
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004590 return NULL;
4591 } else
4592 tm = _O_BINARY;
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004593
4594 if (bufsize != -1) {
Fred Drake661ea262000-10-24 19:57:45 +00004595 PyErr_SetString(PyExc_ValueError, "popen4() arg 3 must be -1");
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004596 return NULL;
4597 }
4598
Fredrik Lundhbb7eeff2000-07-09 17:59:32 +00004599 f = _PyPopen(cmdstring, tm, POPEN_4);
Fredrik Lundh766ccdc2000-07-09 17:41:01 +00004600
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004601 return f;
4602}
4603
Mark Hammond08501372001-01-31 07:30:29 +00004604static BOOL
Mark Hammondb37a3732000-08-14 04:47:33 +00004605_PyPopenCreateProcess(char *cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004606 HANDLE hStdin,
4607 HANDLE hStdout,
Mark Hammondb37a3732000-08-14 04:47:33 +00004608 HANDLE hStderr,
4609 HANDLE *hProcess)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004610{
4611 PROCESS_INFORMATION piProcInfo;
4612 STARTUPINFO siStartInfo;
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004613 DWORD dwProcessFlags = 0; /* no NEW_CONSOLE by default for Ctrl+C handling */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004614 char *s1,*s2, *s3 = " /c ";
Mark Hammond08501372001-01-31 07:30:29 +00004615 const char *szConsoleSpawn = "w9xpopen.exe";
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004616 int i;
Martin v. Löwis18e16552006-02-15 17:27:45 +00004617 Py_ssize_t x;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004618
4619 if (i = GetEnvironmentVariable("COMSPEC",NULL,0)) {
Tim Peters402d5982001-08-27 06:37:48 +00004620 char *comshell;
4621
Tim Peters92e4dd82002-10-05 01:47:34 +00004622 s1 = (char *)alloca(i);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004623 if (!(x = GetEnvironmentVariable("COMSPEC", s1, i)))
Martin v. Löwis18e16552006-02-15 17:27:45 +00004624 /* x < i, so x fits into an integer */
4625 return (int)x;
Tim Peters402d5982001-08-27 06:37:48 +00004626
4627 /* Explicitly check if we are using COMMAND.COM. If we are
4628 * then use the w9xpopen hack.
4629 */
4630 comshell = s1 + x;
4631 while (comshell >= s1 && *comshell != '\\')
4632 --comshell;
4633 ++comshell;
4634
4635 if (GetVersion() < 0x80000000 &&
4636 _stricmp(comshell, "command.com") != 0) {
4637 /* NT/2000 and not using command.com. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004638 x = i + strlen(s3) + strlen(cmdstring) + 1;
Tim Peters92e4dd82002-10-05 01:47:34 +00004639 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004640 ZeroMemory(s2, x);
Tim Peters75cdad52001-11-28 22:07:30 +00004641 PyOS_snprintf(s2, x, "%s%s%s", s1, s3, cmdstring);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004642 }
4643 else {
4644 /*
Tim Peters402d5982001-08-27 06:37:48 +00004645 * Oh gag, we're on Win9x or using COMMAND.COM. Use
4646 * the workaround listed in KB: Q150956
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004647 */
Mark Hammond08501372001-01-31 07:30:29 +00004648 char modulepath[_MAX_PATH];
4649 struct stat statinfo;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004650 GetModuleFileName(NULL, modulepath, sizeof(modulepath));
Martin v. Löwis26fd9602006-04-22 11:15:41 +00004651 for (x = i = 0; modulepath[i]; i++)
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00004652 if (modulepath[i] == SEP)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004653 x = i+1;
4654 modulepath[x] = '\0';
Mark Hammond08501372001-01-31 07:30:29 +00004655 /* Create the full-name to w9xpopen, so we can test it exists */
Tim Peters5aa91602002-01-30 05:46:57 +00004656 strncat(modulepath,
4657 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00004658 (sizeof(modulepath)/sizeof(modulepath[0]))
4659 -strlen(modulepath));
4660 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00004661 /* Eeek - file-not-found - possibly an embedding
4662 situation - see if we can locate it in sys.prefix
Mark Hammond08501372001-01-31 07:30:29 +00004663 */
Tim Peters5aa91602002-01-30 05:46:57 +00004664 strncpy(modulepath,
4665 Py_GetExecPrefix(),
Mark Hammond08501372001-01-31 07:30:29 +00004666 sizeof(modulepath)/sizeof(modulepath[0]));
4667 if (modulepath[strlen(modulepath)-1] != '\\')
4668 strcat(modulepath, "\\");
Tim Peters5aa91602002-01-30 05:46:57 +00004669 strncat(modulepath,
4670 szConsoleSpawn,
Mark Hammond08501372001-01-31 07:30:29 +00004671 (sizeof(modulepath)/sizeof(modulepath[0]))
4672 -strlen(modulepath));
4673 /* No where else to look - raise an easily identifiable
4674 error, rather than leaving Windows to report
4675 "file not found" - as the user is probably blissfully
4676 unaware this shim EXE is used, and it will confuse them.
4677 (well, it confused me for a while ;-)
4678 */
4679 if (stat(modulepath, &statinfo) != 0) {
Tim Peters5aa91602002-01-30 05:46:57 +00004680 PyErr_Format(PyExc_RuntimeError,
Mark Hammond08501372001-01-31 07:30:29 +00004681 "Can not locate '%s' which is needed "
Tim Peters402d5982001-08-27 06:37:48 +00004682 "for popen to work with your shell "
4683 "or platform.",
Mark Hammond08501372001-01-31 07:30:29 +00004684 szConsoleSpawn);
4685 return FALSE;
4686 }
4687 }
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004688 x = i + strlen(s3) + strlen(cmdstring) + 1 +
Tim Peters5aa91602002-01-30 05:46:57 +00004689 strlen(modulepath) +
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004690 strlen(szConsoleSpawn) + 1;
Mark Hammond08501372001-01-31 07:30:29 +00004691
Tim Peters92e4dd82002-10-05 01:47:34 +00004692 s2 = (char *)alloca(x);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004693 ZeroMemory(s2, x);
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004694 /* To maintain correct argument passing semantics,
4695 we pass the command-line as it stands, and allow
4696 quoting to be applied. w9xpopen.exe will then
4697 use its argv vector, and re-quote the necessary
4698 args for the ultimate child process.
4699 */
Tim Peters75cdad52001-11-28 22:07:30 +00004700 PyOS_snprintf(
4701 s2, x,
Mark Hammonde7fefbf2002-04-03 01:47:00 +00004702 "\"%s\" %s%s%s",
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004703 modulepath,
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004704 s1,
4705 s3,
4706 cmdstring);
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004707 /* Not passing CREATE_NEW_CONSOLE has been known to
Tim Peters11b23062003-04-23 02:39:17 +00004708 cause random failures on win9x. Specifically a
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004709 dialog:
4710 "Your program accessed mem currently in use at xxx"
4711 and a hopeful warning about the stability of your
4712 system.
4713 Cost is Ctrl+C wont kill children, but anyone
4714 who cares can have a go!
4715 */
4716 dwProcessFlags |= CREATE_NEW_CONSOLE;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004717 }
4718 }
4719
4720 /* Could be an else here to try cmd.exe / command.com in the path
4721 Now we'll just error out.. */
Mark Hammond08501372001-01-31 07:30:29 +00004722 else {
Tim Peters402d5982001-08-27 06:37:48 +00004723 PyErr_SetString(PyExc_RuntimeError,
4724 "Cannot locate a COMSPEC environment variable to "
4725 "use as the shell");
Mark Hammond08501372001-01-31 07:30:29 +00004726 return FALSE;
4727 }
Tim Peters5aa91602002-01-30 05:46:57 +00004728
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004729 ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
4730 siStartInfo.cb = sizeof(STARTUPINFO);
4731 siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
4732 siStartInfo.hStdInput = hStdin;
4733 siStartInfo.hStdOutput = hStdout;
4734 siStartInfo.hStdError = hStderr;
4735 siStartInfo.wShowWindow = SW_HIDE;
4736
4737 if (CreateProcess(NULL,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004738 s2,
4739 NULL,
4740 NULL,
4741 TRUE,
Mark Hammondfe51c6d2002-08-02 02:27:13 +00004742 dwProcessFlags,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004743 NULL,
4744 NULL,
4745 &siStartInfo,
4746 &piProcInfo) ) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004747 /* Close the handles now so anyone waiting is woken. */
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004748 CloseHandle(piProcInfo.hThread);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004749
Mark Hammondb37a3732000-08-14 04:47:33 +00004750 /* Return process handle */
4751 *hProcess = piProcInfo.hProcess;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004752 return TRUE;
4753 }
Tim Peters402d5982001-08-27 06:37:48 +00004754 win32_error("CreateProcess", s2);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004755 return FALSE;
4756}
4757
4758/* The following code is based off of KB: Q190351 */
4759
4760static PyObject *
4761_PyPopen(char *cmdstring, int mode, int n)
4762{
4763 HANDLE hChildStdinRd, hChildStdinWr, hChildStdoutRd, hChildStdoutWr,
4764 hChildStderrRd, hChildStderrWr, hChildStdinWrDup, hChildStdoutRdDup,
Mark Hammondb37a3732000-08-14 04:47:33 +00004765 hChildStderrRdDup, hProcess; /* hChildStdoutWrDup; */
Tim Peters5aa91602002-01-30 05:46:57 +00004766
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004767 SECURITY_ATTRIBUTES saAttr;
4768 BOOL fSuccess;
4769 int fd1, fd2, fd3;
4770 FILE *f1, *f2, *f3;
Mark Hammondb37a3732000-08-14 04:47:33 +00004771 long file_count;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004772 PyObject *f;
4773
4774 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
4775 saAttr.bInheritHandle = TRUE;
4776 saAttr.lpSecurityDescriptor = NULL;
4777
4778 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
4779 return win32_error("CreatePipe", NULL);
4780
4781 /* Create new output read handle and the input write handle. Set
4782 * the inheritance properties to FALSE. Otherwise, the child inherits
Walter Dörwaldf0dfc7a2003-10-20 14:01:56 +00004783 * these handles; resulting in non-closeable handles to the pipes
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004784 * being created. */
4785 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004786 GetCurrentProcess(), &hChildStdinWrDup, 0,
4787 FALSE,
4788 DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004789 if (!fSuccess)
4790 return win32_error("DuplicateHandle", NULL);
4791
4792 /* Close the inheritable version of ChildStdin
4793 that we're using. */
4794 CloseHandle(hChildStdinWr);
4795
4796 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
4797 return win32_error("CreatePipe", NULL);
4798
4799 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004800 GetCurrentProcess(), &hChildStdoutRdDup, 0,
4801 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004802 if (!fSuccess)
4803 return win32_error("DuplicateHandle", NULL);
4804
4805 /* Close the inheritable version of ChildStdout
4806 that we're using. */
4807 CloseHandle(hChildStdoutRd);
4808
4809 if (n != POPEN_4) {
4810 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
4811 return win32_error("CreatePipe", NULL);
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004812 fSuccess = DuplicateHandle(GetCurrentProcess(),
4813 hChildStderrRd,
4814 GetCurrentProcess(),
4815 &hChildStderrRdDup, 0,
4816 FALSE, DUPLICATE_SAME_ACCESS);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004817 if (!fSuccess)
4818 return win32_error("DuplicateHandle", NULL);
4819 /* Close the inheritable version of ChildStdErr that we're using. */
4820 CloseHandle(hChildStderrRd);
4821 }
Tim Peters5aa91602002-01-30 05:46:57 +00004822
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004823 switch (n) {
4824 case POPEN_1:
4825 switch (mode & (_O_RDONLY | _O_TEXT | _O_BINARY | _O_WRONLY)) {
4826 case _O_WRONLY | _O_TEXT:
4827 /* Case for writing to child Stdin in text mode. */
Martin v. Löwisa43190b2006-05-22 09:15:18 +00004828 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004829 f1 = _fdopen(fd1, "w");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004830 f = PyFile_FromFile(f1, cmdstring, "w", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004831 PyFile_SetBufSize(f, 0);
4832 /* We don't care about these pipes anymore, so close them. */
4833 CloseHandle(hChildStdoutRdDup);
4834 CloseHandle(hChildStderrRdDup);
4835 break;
4836
4837 case _O_RDONLY | _O_TEXT:
4838 /* Case for reading from child Stdout in text mode. */
Martin v. Löwisa43190b2006-05-22 09:15:18 +00004839 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004840 f1 = _fdopen(fd1, "r");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004841 f = PyFile_FromFile(f1, cmdstring, "r", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004842 PyFile_SetBufSize(f, 0);
4843 /* We don't care about these pipes anymore, so close them. */
4844 CloseHandle(hChildStdinWrDup);
4845 CloseHandle(hChildStderrRdDup);
4846 break;
4847
4848 case _O_RDONLY | _O_BINARY:
4849 /* Case for readinig from child Stdout in binary mode. */
Martin v. Löwisa43190b2006-05-22 09:15:18 +00004850 fd1 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004851 f1 = _fdopen(fd1, "rb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004852 f = PyFile_FromFile(f1, cmdstring, "rb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004853 PyFile_SetBufSize(f, 0);
4854 /* We don't care about these pipes anymore, so close them. */
4855 CloseHandle(hChildStdinWrDup);
4856 CloseHandle(hChildStderrRdDup);
4857 break;
4858
4859 case _O_WRONLY | _O_BINARY:
4860 /* Case for writing to child Stdin in binary mode. */
Martin v. Löwisa43190b2006-05-22 09:15:18 +00004861 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004862 f1 = _fdopen(fd1, "wb");
Fredrik Lundh56055a42000-07-23 19:47:12 +00004863 f = PyFile_FromFile(f1, cmdstring, "wb", _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004864 PyFile_SetBufSize(f, 0);
4865 /* We don't care about these pipes anymore, so close them. */
4866 CloseHandle(hChildStdoutRdDup);
4867 CloseHandle(hChildStderrRdDup);
4868 break;
4869 }
Mark Hammondb37a3732000-08-14 04:47:33 +00004870 file_count = 1;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004871 break;
Tim Peters5aa91602002-01-30 05:46:57 +00004872
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004873 case POPEN_2:
4874 case POPEN_4:
4875 {
4876 char *m1, *m2;
4877 PyObject *p1, *p2;
Tim Peters5aa91602002-01-30 05:46:57 +00004878
Tim Peters7dca21e2002-08-19 00:42:29 +00004879 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004880 m1 = "r";
4881 m2 = "w";
4882 } else {
4883 m1 = "rb";
4884 m2 = "wb";
4885 }
4886
Martin v. Löwisa43190b2006-05-22 09:15:18 +00004887 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004888 f1 = _fdopen(fd1, m2);
Martin v. Löwisa43190b2006-05-22 09:15:18 +00004889 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004890 f2 = _fdopen(fd2, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004891 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004892 PyFile_SetBufSize(p1, 0);
Mark Hammondb37a3732000-08-14 04:47:33 +00004893 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004894 PyFile_SetBufSize(p2, 0);
4895
4896 if (n != 4)
4897 CloseHandle(hChildStderrRdDup);
4898
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004899 f = PyTuple_Pack(2,p1,p2);
Mark Hammond64aae662001-01-31 05:38:47 +00004900 Py_XDECREF(p1);
4901 Py_XDECREF(p2);
Mark Hammondb37a3732000-08-14 04:47:33 +00004902 file_count = 2;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004903 break;
4904 }
Tim Peters5aa91602002-01-30 05:46:57 +00004905
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004906 case POPEN_3:
4907 {
4908 char *m1, *m2;
4909 PyObject *p1, *p2, *p3;
Tim Peters5aa91602002-01-30 05:46:57 +00004910
Tim Peters7dca21e2002-08-19 00:42:29 +00004911 if (mode & _O_TEXT) {
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004912 m1 = "r";
4913 m2 = "w";
4914 } else {
4915 m1 = "rb";
4916 m2 = "wb";
4917 }
4918
Martin v. Löwisa43190b2006-05-22 09:15:18 +00004919 fd1 = _open_osfhandle((Py_intptr_t)hChildStdinWrDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004920 f1 = _fdopen(fd1, m2);
Martin v. Löwisa43190b2006-05-22 09:15:18 +00004921 fd2 = _open_osfhandle((Py_intptr_t)hChildStdoutRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004922 f2 = _fdopen(fd2, m1);
Martin v. Löwisa43190b2006-05-22 09:15:18 +00004923 fd3 = _open_osfhandle((Py_intptr_t)hChildStderrRdDup, mode);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004924 f3 = _fdopen(fd3, m1);
Fredrik Lundh56055a42000-07-23 19:47:12 +00004925 p1 = PyFile_FromFile(f1, cmdstring, m2, _PyPclose);
Mark Hammondb37a3732000-08-14 04:47:33 +00004926 p2 = PyFile_FromFile(f2, cmdstring, m1, _PyPclose);
4927 p3 = PyFile_FromFile(f3, cmdstring, m1, _PyPclose);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004928 PyFile_SetBufSize(p1, 0);
4929 PyFile_SetBufSize(p2, 0);
4930 PyFile_SetBufSize(p3, 0);
Raymond Hettinger8ae46892003-10-12 19:09:37 +00004931 f = PyTuple_Pack(3,p1,p2,p3);
Mark Hammond64aae662001-01-31 05:38:47 +00004932 Py_XDECREF(p1);
4933 Py_XDECREF(p2);
4934 Py_XDECREF(p3);
Mark Hammondb37a3732000-08-14 04:47:33 +00004935 file_count = 3;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004936 break;
4937 }
4938 }
4939
4940 if (n == POPEN_4) {
4941 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004942 hChildStdinRd,
4943 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004944 hChildStdoutWr,
4945 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004946 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004947 }
4948 else {
4949 if (!_PyPopenCreateProcess(cmdstring,
Fredrik Lundh9ac81f62000-07-09 23:35:24 +00004950 hChildStdinRd,
4951 hChildStdoutWr,
Mark Hammondb37a3732000-08-14 04:47:33 +00004952 hChildStderrWr,
4953 &hProcess))
Mark Hammond08501372001-01-31 07:30:29 +00004954 return NULL;
Fredrik Lundhffb9c772000-07-09 14:49:51 +00004955 }
4956
Mark Hammondb37a3732000-08-14 04:47:33 +00004957 /*
4958 * Insert the files we've created into the process dictionary
4959 * all referencing the list with the process handle and the
4960 * initial number of files (see description below in _PyPclose).
4961 * Since if _PyPclose later tried to wait on a process when all
4962 * handles weren't closed, it could create a deadlock with the
4963 * child, we spend some energy here to try to ensure that we
4964 * either insert all file handles into the dictionary or none
4965 * at all. It's a little clumsy with the various popen modes
4966 * and variable number of files involved.
4967 */
4968 if (!_PyPopenProcs) {
4969 _PyPopenProcs = PyDict_New();
4970 }
4971
4972 if (_PyPopenProcs) {
4973 PyObject *procObj, *hProcessObj, *intObj, *fileObj[3];
4974 int ins_rc[3];
4975
4976 fileObj[0] = fileObj[1] = fileObj[2] = NULL;
4977 ins_rc[0] = ins_rc[1] = ins_rc[2] = 0;
4978
4979 procObj = PyList_New(2);
4980 hProcessObj = PyLong_FromVoidPtr(hProcess);
4981 intObj = PyInt_FromLong(file_count);
4982
4983 if (procObj && hProcessObj && intObj) {
4984 PyList_SetItem(procObj,0,hProcessObj);
4985 PyList_SetItem(procObj,1,intObj);
4986
4987 fileObj[0] = PyLong_FromVoidPtr(f1);
4988 if (fileObj[0]) {
4989 ins_rc[0] = PyDict_SetItem(_PyPopenProcs,
4990 fileObj[0],
4991 procObj);
4992 }
4993 if (file_count >= 2) {
4994 fileObj[1] = PyLong_FromVoidPtr(f2);
4995 if (fileObj[1]) {
4996 ins_rc[1] = PyDict_SetItem(_PyPopenProcs,
4997 fileObj[1],
4998 procObj);
4999 }
5000 }
5001 if (file_count >= 3) {
5002 fileObj[2] = PyLong_FromVoidPtr(f3);
5003 if (fileObj[2]) {
5004 ins_rc[2] = PyDict_SetItem(_PyPopenProcs,
5005 fileObj[2],
5006 procObj);
5007 }
5008 }
5009
5010 if (ins_rc[0] < 0 || !fileObj[0] ||
5011 ins_rc[1] < 0 || (file_count > 1 && !fileObj[1]) ||
5012 ins_rc[2] < 0 || (file_count > 2 && !fileObj[2])) {
5013 /* Something failed - remove any dictionary
5014 * entries that did make it.
5015 */
5016 if (!ins_rc[0] && fileObj[0]) {
5017 PyDict_DelItem(_PyPopenProcs,
5018 fileObj[0]);
5019 }
5020 if (!ins_rc[1] && fileObj[1]) {
5021 PyDict_DelItem(_PyPopenProcs,
5022 fileObj[1]);
5023 }
5024 if (!ins_rc[2] && fileObj[2]) {
5025 PyDict_DelItem(_PyPopenProcs,
5026 fileObj[2]);
5027 }
5028 }
5029 }
Tim Peters5aa91602002-01-30 05:46:57 +00005030
Mark Hammondb37a3732000-08-14 04:47:33 +00005031 /*
5032 * Clean up our localized references for the dictionary keys
5033 * and value since PyDict_SetItem will Py_INCREF any copies
5034 * that got placed in the dictionary.
5035 */
5036 Py_XDECREF(procObj);
5037 Py_XDECREF(fileObj[0]);
5038 Py_XDECREF(fileObj[1]);
5039 Py_XDECREF(fileObj[2]);
5040 }
5041
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005042 /* Child is launched. Close the parents copy of those pipe
5043 * handles that only the child should have open. You need to
5044 * make sure that no handles to the write end of the output pipe
5045 * are maintained in this process or else the pipe will not close
5046 * when the child process exits and the ReadFile will hang. */
5047
5048 if (!CloseHandle(hChildStdinRd))
5049 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005050
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005051 if (!CloseHandle(hChildStdoutWr))
5052 return win32_error("CloseHandle", NULL);
Tim Peters5aa91602002-01-30 05:46:57 +00005053
Fredrik Lundhffb9c772000-07-09 14:49:51 +00005054 if ((n != 4) && (!CloseHandle(hChildStderrWr)))
5055 return win32_error("CloseHandle", NULL);
5056
5057 return f;
5058}
Fredrik Lundh56055a42000-07-23 19:47:12 +00005059
5060/*
5061 * Wrapper for fclose() to use for popen* files, so we can retrieve the
5062 * exit code for the child process and return as a result of the close.
Mark Hammondb37a3732000-08-14 04:47:33 +00005063 *
5064 * This function uses the _PyPopenProcs dictionary in order to map the
5065 * input file pointer to information about the process that was
5066 * originally created by the popen* call that created the file pointer.
5067 * The dictionary uses the file pointer as a key (with one entry
5068 * inserted for each file returned by the original popen* call) and a
5069 * single list object as the value for all files from a single call.
5070 * The list object contains the Win32 process handle at [0], and a file
5071 * count at [1], which is initialized to the total number of file
5072 * handles using that list.
5073 *
5074 * This function closes whichever handle it is passed, and decrements
5075 * the file count in the dictionary for the process handle pointed to
5076 * by this file. On the last close (when the file count reaches zero),
5077 * this function will wait for the child process and then return its
5078 * exit code as the result of the close() operation. This permits the
5079 * files to be closed in any order - it is always the close() of the
5080 * final handle that will return the exit code.
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005081 *
5082 * NOTE: This function is currently called with the GIL released.
5083 * hence we use the GILState API to manage our state.
Fredrik Lundh56055a42000-07-23 19:47:12 +00005084 */
Tim Peters736aa322000-09-01 06:51:24 +00005085
Fredrik Lundh56055a42000-07-23 19:47:12 +00005086static int _PyPclose(FILE *file)
5087{
Fredrik Lundh20318932000-07-26 17:29:12 +00005088 int result;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005089 DWORD exit_code;
5090 HANDLE hProcess;
Mark Hammondb37a3732000-08-14 04:47:33 +00005091 PyObject *procObj, *hProcessObj, *intObj, *fileObj;
5092 long file_count;
Tim Peters736aa322000-09-01 06:51:24 +00005093#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005094 PyGILState_STATE state;
Tim Peters736aa322000-09-01 06:51:24 +00005095#endif
5096
Fredrik Lundh20318932000-07-26 17:29:12 +00005097 /* Close the file handle first, to ensure it can't block the
Mark Hammondb37a3732000-08-14 04:47:33 +00005098 * child from exiting if it's the last handle.
Fredrik Lundh20318932000-07-26 17:29:12 +00005099 */
5100 result = fclose(file);
Tim Peters736aa322000-09-01 06:51:24 +00005101#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005102 state = PyGILState_Ensure();
Tim Peters736aa322000-09-01 06:51:24 +00005103#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00005104 if (_PyPopenProcs) {
Mark Hammondb37a3732000-08-14 04:47:33 +00005105 if ((fileObj = PyLong_FromVoidPtr(file)) != NULL &&
5106 (procObj = PyDict_GetItem(_PyPopenProcs,
5107 fileObj)) != NULL &&
5108 (hProcessObj = PyList_GetItem(procObj,0)) != NULL &&
5109 (intObj = PyList_GetItem(procObj,1)) != NULL) {
5110
5111 hProcess = PyLong_AsVoidPtr(hProcessObj);
5112 file_count = PyInt_AsLong(intObj);
5113
5114 if (file_count > 1) {
5115 /* Still other files referencing process */
5116 file_count--;
5117 PyList_SetItem(procObj,1,
5118 PyInt_FromLong(file_count));
5119 } else {
5120 /* Last file for this process */
Fredrik Lundh20318932000-07-26 17:29:12 +00005121 if (result != EOF &&
5122 WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED &&
5123 GetExitCodeProcess(hProcess, &exit_code)) {
Fredrik Lundh56055a42000-07-23 19:47:12 +00005124 /* Possible truncation here in 16-bit environments, but
5125 * real exit codes are just the lower byte in any event.
5126 */
5127 result = exit_code;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005128 } else {
Fredrik Lundh20318932000-07-26 17:29:12 +00005129 /* Indicate failure - this will cause the file object
5130 * to raise an I/O error and translate the last Win32
5131 * error code from errno. We do have a problem with
5132 * last errors that overlap the normal errno table,
5133 * but that's a consistent problem with the file object.
Fredrik Lundh56055a42000-07-23 19:47:12 +00005134 */
Fredrik Lundh20318932000-07-26 17:29:12 +00005135 if (result != EOF) {
5136 /* If the error wasn't from the fclose(), then
5137 * set errno for the file object error handling.
5138 */
5139 errno = GetLastError();
5140 }
5141 result = -1;
Fredrik Lundh56055a42000-07-23 19:47:12 +00005142 }
5143
5144 /* Free up the native handle at this point */
5145 CloseHandle(hProcess);
Mark Hammondb37a3732000-08-14 04:47:33 +00005146 }
Fredrik Lundh56055a42000-07-23 19:47:12 +00005147
Mark Hammondb37a3732000-08-14 04:47:33 +00005148 /* Remove this file pointer from dictionary */
5149 PyDict_DelItem(_PyPopenProcs, fileObj);
5150
5151 if (PyDict_Size(_PyPopenProcs) == 0) {
5152 Py_DECREF(_PyPopenProcs);
5153 _PyPopenProcs = NULL;
5154 }
5155
5156 } /* if object retrieval ok */
5157
5158 Py_XDECREF(fileObj);
Fredrik Lundh56055a42000-07-23 19:47:12 +00005159 } /* if _PyPopenProcs */
5160
Tim Peters736aa322000-09-01 06:51:24 +00005161#ifdef WITH_THREAD
Mark Hammond8d98d2c2003-04-19 15:41:53 +00005162 PyGILState_Release(state);
Tim Peters736aa322000-09-01 06:51:24 +00005163#endif
Fredrik Lundh56055a42000-07-23 19:47:12 +00005164 return result;
5165}
Tim Peters9acdd3a2000-09-01 19:26:36 +00005166
5167#else /* which OS? */
Barry Warsaw53699e91996-12-10 23:23:01 +00005168static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005169posix_popen(PyObject *self, PyObject *args)
Guido van Rossum3b066191991-06-04 19:40:25 +00005170{
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005171 char *name;
5172 char *mode = "r";
5173 int bufsize = -1;
Guido van Rossum3b066191991-06-04 19:40:25 +00005174 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00005175 PyObject *f;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005176 if (!PyArg_ParseTuple(args, "s|si:popen", &name, &mode, &bufsize))
Guido van Rossum3b066191991-06-04 19:40:25 +00005177 return NULL;
Martin v. Löwis9ad853b2003-10-31 10:01:53 +00005178 /* Strip mode of binary or text modifiers */
5179 if (strcmp(mode, "rb") == 0 || strcmp(mode, "rt") == 0)
5180 mode = "r";
5181 else if (strcmp(mode, "wb") == 0 || strcmp(mode, "wt") == 0)
5182 mode = "w";
Barry Warsaw53699e91996-12-10 23:23:01 +00005183 Py_BEGIN_ALLOW_THREADS
Guido van Rossumef0a00e1992-01-27 16:51:30 +00005184 fp = popen(name, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005185 Py_END_ALLOW_THREADS
Guido van Rossum3b066191991-06-04 19:40:25 +00005186 if (fp == NULL)
5187 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005188 f = PyFile_FromFile(fp, name, mode, pclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005189 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00005190 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00005191 return f;
Guido van Rossum3b066191991-06-04 19:40:25 +00005192}
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00005193
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00005194#endif /* PYOS_??? */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00005195#endif /* HAVE_POPEN */
Guido van Rossum3b066191991-06-04 19:40:25 +00005196
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005197
Guido van Rossumb6775db1994-08-01 11:34:53 +00005198#ifdef HAVE_SETUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005199PyDoc_STRVAR(posix_setuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005200"setuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005201Set the current process's user id.");
5202
Barry Warsaw53699e91996-12-10 23:23:01 +00005203static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005204posix_setuid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005205{
5206 int uid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005207 if (!PyArg_ParseTuple(args, "i:setuid", &uid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005208 return NULL;
5209 if (setuid(uid) < 0)
5210 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005211 Py_INCREF(Py_None);
5212 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005213}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005214#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005215
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005216
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005217#ifdef HAVE_SETEUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005218PyDoc_STRVAR(posix_seteuid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005219"seteuid(uid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005220Set the current process's effective user id.");
5221
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005222static PyObject *
5223posix_seteuid (PyObject *self, PyObject *args)
5224{
5225 int euid;
5226 if (!PyArg_ParseTuple(args, "i", &euid)) {
5227 return NULL;
5228 } else if (seteuid(euid) < 0) {
5229 return posix_error();
5230 } else {
5231 Py_INCREF(Py_None);
5232 return Py_None;
5233 }
5234}
5235#endif /* HAVE_SETEUID */
5236
5237#ifdef HAVE_SETEGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005238PyDoc_STRVAR(posix_setegid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005239"setegid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005240Set the current process's effective group id.");
5241
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005242static PyObject *
5243posix_setegid (PyObject *self, PyObject *args)
5244{
5245 int egid;
5246 if (!PyArg_ParseTuple(args, "i", &egid)) {
5247 return NULL;
5248 } else if (setegid(egid) < 0) {
5249 return posix_error();
5250 } else {
5251 Py_INCREF(Py_None);
5252 return Py_None;
5253 }
5254}
5255#endif /* HAVE_SETEGID */
5256
5257#ifdef HAVE_SETREUID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005258PyDoc_STRVAR(posix_setreuid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005259"setreuid(ruid, euid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005260Set the current process's real and effective user ids.");
5261
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005262static PyObject *
5263posix_setreuid (PyObject *self, PyObject *args)
5264{
5265 int ruid, euid;
5266 if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
5267 return NULL;
5268 } else if (setreuid(ruid, euid) < 0) {
5269 return posix_error();
5270 } else {
5271 Py_INCREF(Py_None);
5272 return Py_None;
5273 }
5274}
5275#endif /* HAVE_SETREUID */
5276
5277#ifdef HAVE_SETREGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005278PyDoc_STRVAR(posix_setregid__doc__,
Neal Norwitz94f1d712004-02-16 01:26:34 +00005279"setregid(rgid, egid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005280Set the current process's real and effective group ids.");
5281
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00005282static PyObject *
5283posix_setregid (PyObject *self, PyObject *args)
5284{
5285 int rgid, egid;
5286 if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
5287 return NULL;
5288 } else if (setregid(rgid, egid) < 0) {
5289 return posix_error();
5290 } else {
5291 Py_INCREF(Py_None);
5292 return Py_None;
5293 }
5294}
5295#endif /* HAVE_SETREGID */
5296
Guido van Rossumb6775db1994-08-01 11:34:53 +00005297#ifdef HAVE_SETGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005298PyDoc_STRVAR(posix_setgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005299"setgid(gid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005300Set the current process's group id.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005301
Barry Warsaw53699e91996-12-10 23:23:01 +00005302static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005303posix_setgid(PyObject *self, PyObject *args)
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005304{
5305 int gid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005306 if (!PyArg_ParseTuple(args, "i:setgid", &gid))
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005307 return NULL;
5308 if (setgid(gid) < 0)
5309 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005310 Py_INCREF(Py_None);
5311 return Py_None;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005312}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005313#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00005314
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005315#ifdef HAVE_SETGROUPS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005316PyDoc_STRVAR(posix_setgroups__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005317"setgroups(list)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005318Set the groups of the current process to list.");
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005319
5320static PyObject *
Georg Brandl96a8c392006-05-29 21:04:52 +00005321posix_setgroups(PyObject *self, PyObject *groups)
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005322{
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005323 int i, len;
5324 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00005325
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005326 if (!PySequence_Check(groups)) {
5327 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
5328 return NULL;
5329 }
5330 len = PySequence_Size(groups);
5331 if (len > MAX_GROUPS) {
5332 PyErr_SetString(PyExc_ValueError, "too many groups");
5333 return NULL;
5334 }
5335 for(i = 0; i < len; i++) {
5336 PyObject *elem;
5337 elem = PySequence_GetItem(groups, i);
5338 if (!elem)
5339 return NULL;
5340 if (!PyInt_Check(elem)) {
Georg Brandla13c2442005-11-22 19:30:31 +00005341 if (!PyLong_Check(elem)) {
5342 PyErr_SetString(PyExc_TypeError,
5343 "groups must be integers");
5344 Py_DECREF(elem);
5345 return NULL;
5346 } else {
5347 unsigned long x = PyLong_AsUnsignedLong(elem);
5348 if (PyErr_Occurred()) {
5349 PyErr_SetString(PyExc_TypeError,
5350 "group id too big");
5351 Py_DECREF(elem);
5352 return NULL;
5353 }
5354 grouplist[i] = x;
5355 /* read back the value to see if it fitted in gid_t */
5356 if (grouplist[i] != x) {
5357 PyErr_SetString(PyExc_TypeError,
5358 "group id too big");
5359 Py_DECREF(elem);
5360 return NULL;
5361 }
5362 }
5363 } else {
5364 long x = PyInt_AsLong(elem);
5365 grouplist[i] = x;
5366 if (grouplist[i] != x) {
5367 PyErr_SetString(PyExc_TypeError,
5368 "group id too big");
5369 Py_DECREF(elem);
5370 return NULL;
5371 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005372 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00005373 Py_DECREF(elem);
5374 }
5375
5376 if (setgroups(len, grouplist) < 0)
5377 return posix_error();
5378 Py_INCREF(Py_None);
5379 return Py_None;
5380}
5381#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005382
Neal Norwitz6c2f9132006-03-20 07:25:26 +00005383#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
Neal Norwitz05a45592006-03-20 06:30:08 +00005384static PyObject *
5385wait_helper(int pid, int status, struct rusage *ru)
5386{
5387 PyObject *result;
5388 static PyObject *struct_rusage;
5389
5390 if (pid == -1)
5391 return posix_error();
5392
5393 if (struct_rusage == NULL) {
5394 PyObject *m = PyImport_ImportModule("resource");
5395 if (m == NULL)
5396 return NULL;
5397 struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
5398 Py_DECREF(m);
5399 if (struct_rusage == NULL)
5400 return NULL;
5401 }
5402
5403 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
5404 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
5405 if (!result)
5406 return NULL;
5407
5408#ifndef doubletime
5409#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
5410#endif
5411
5412 PyStructSequence_SET_ITEM(result, 0,
5413 PyFloat_FromDouble(doubletime(ru->ru_utime)));
5414 PyStructSequence_SET_ITEM(result, 1,
5415 PyFloat_FromDouble(doubletime(ru->ru_stime)));
5416#define SET_INT(result, index, value)\
5417 PyStructSequence_SET_ITEM(result, index, PyInt_FromLong(value))
5418 SET_INT(result, 2, ru->ru_maxrss);
5419 SET_INT(result, 3, ru->ru_ixrss);
5420 SET_INT(result, 4, ru->ru_idrss);
5421 SET_INT(result, 5, ru->ru_isrss);
5422 SET_INT(result, 6, ru->ru_minflt);
5423 SET_INT(result, 7, ru->ru_majflt);
5424 SET_INT(result, 8, ru->ru_nswap);
5425 SET_INT(result, 9, ru->ru_inblock);
5426 SET_INT(result, 10, ru->ru_oublock);
5427 SET_INT(result, 11, ru->ru_msgsnd);
5428 SET_INT(result, 12, ru->ru_msgrcv);
5429 SET_INT(result, 13, ru->ru_nsignals);
5430 SET_INT(result, 14, ru->ru_nvcsw);
5431 SET_INT(result, 15, ru->ru_nivcsw);
5432#undef SET_INT
5433
5434 if (PyErr_Occurred()) {
5435 Py_DECREF(result);
5436 return NULL;
5437 }
5438
Neal Norwitz9b00a562006-03-20 08:47:12 +00005439 return Py_BuildValue("iiN", pid, status, result);
Neal Norwitz05a45592006-03-20 06:30:08 +00005440}
Neal Norwitz6c2f9132006-03-20 07:25:26 +00005441#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
Neal Norwitz05a45592006-03-20 06:30:08 +00005442
5443#ifdef HAVE_WAIT3
5444PyDoc_STRVAR(posix_wait3__doc__,
5445"wait3(options) -> (pid, status, rusage)\n\n\
5446Wait for completion of a child process.");
5447
5448static PyObject *
5449posix_wait3(PyObject *self, PyObject *args)
5450{
5451 int pid, options;
5452 struct rusage ru;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005453 WAIT_TYPE status;
5454 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00005455
5456 if (!PyArg_ParseTuple(args, "i:wait3", &options))
5457 return NULL;
5458
5459 Py_BEGIN_ALLOW_THREADS
5460 pid = wait3(&status, options, &ru);
5461 Py_END_ALLOW_THREADS
5462
Neal Norwitzd5a37542006-03-20 06:48:34 +00005463 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00005464}
5465#endif /* HAVE_WAIT3 */
5466
5467#ifdef HAVE_WAIT4
5468PyDoc_STRVAR(posix_wait4__doc__,
5469"wait4(pid, options) -> (pid, status, rusage)\n\n\
5470Wait for completion of a given child process.");
5471
5472static PyObject *
5473posix_wait4(PyObject *self, PyObject *args)
5474{
5475 int pid, options;
5476 struct rusage ru;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005477 WAIT_TYPE status;
5478 WAIT_STATUS_INT(status) = 0;
Neal Norwitz05a45592006-03-20 06:30:08 +00005479
5480 if (!PyArg_ParseTuple(args, "ii:wait4", &pid, &options))
5481 return NULL;
5482
5483 Py_BEGIN_ALLOW_THREADS
5484 pid = wait4(pid, &status, options, &ru);
5485 Py_END_ALLOW_THREADS
5486
Neal Norwitzd5a37542006-03-20 06:48:34 +00005487 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Neal Norwitz05a45592006-03-20 06:30:08 +00005488}
5489#endif /* HAVE_WAIT4 */
5490
Guido van Rossumb6775db1994-08-01 11:34:53 +00005491#ifdef HAVE_WAITPID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005492PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005493"waitpid(pid, options) -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005494Wait for completion of a given child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005495
Barry Warsaw53699e91996-12-10 23:23:01 +00005496static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005497posix_waitpid(PyObject *self, PyObject *args)
Guido van Rossum85e3b011991-06-03 12:42:10 +00005498{
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005499 int pid, options;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005500 WAIT_TYPE status;
5501 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005502
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005503 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
Guido van Rossum21803b81992-08-09 12:55:27 +00005504 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005505 Py_BEGIN_ALLOW_THREADS
Guido van Rossume6a3aa61999-02-01 16:15:30 +00005506 pid = waitpid(pid, &status, options);
Barry Warsaw53699e91996-12-10 23:23:01 +00005507 Py_END_ALLOW_THREADS
Guido van Rossum85e3b011991-06-03 12:42:10 +00005508 if (pid == -1)
5509 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00005510
5511 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00005512}
5513
Tim Petersab034fa2002-02-01 11:27:43 +00005514#elif defined(HAVE_CWAIT)
5515
5516/* MS C has a variant of waitpid() that's usable for most purposes. */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005517PyDoc_STRVAR(posix_waitpid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005518"waitpid(pid, options) -> (pid, status << 8)\n\n"
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005519"Wait for completion of a given process. options is ignored on Windows.");
Tim Petersab034fa2002-02-01 11:27:43 +00005520
5521static PyObject *
5522posix_waitpid(PyObject *self, PyObject *args)
5523{
Martin v. Löwisa43190b2006-05-22 09:15:18 +00005524 Py_intptr_t pid;
Martin v. Löwis18e16552006-02-15 17:27:45 +00005525 int status, options;
Tim Petersab034fa2002-02-01 11:27:43 +00005526
5527 if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
5528 return NULL;
5529 Py_BEGIN_ALLOW_THREADS
5530 pid = _cwait(&status, pid, options);
5531 Py_END_ALLOW_THREADS
5532 if (pid == -1)
5533 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00005534
5535 /* shift the status left a byte so this is more like the POSIX waitpid */
5536 return Py_BuildValue("ii", pid, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00005537}
5538#endif /* HAVE_WAITPID || HAVE_CWAIT */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005539
Guido van Rossumad0ee831995-03-01 10:34:45 +00005540#ifdef HAVE_WAIT
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005541PyDoc_STRVAR(posix_wait__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005542"wait() -> (pid, status)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005543Wait for completion of a child process.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005544
Barry Warsaw53699e91996-12-10 23:23:01 +00005545static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005546posix_wait(PyObject *self, PyObject *noargs)
Guido van Rossum21803b81992-08-09 12:55:27 +00005547{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005548 int pid;
Neal Norwitzd5a37542006-03-20 06:48:34 +00005549 WAIT_TYPE status;
5550 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00005551
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00005552 Py_BEGIN_ALLOW_THREADS
5553 pid = wait(&status);
Barry Warsaw53699e91996-12-10 23:23:01 +00005554 Py_END_ALLOW_THREADS
Guido van Rossum21803b81992-08-09 12:55:27 +00005555 if (pid == -1)
5556 return posix_error();
Neal Norwitzd5a37542006-03-20 06:48:34 +00005557
5558 return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00005559}
Guido van Rossumad0ee831995-03-01 10:34:45 +00005560#endif
Guido van Rossum85e3b011991-06-03 12:42:10 +00005561
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005562
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005563PyDoc_STRVAR(posix_lstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005564"lstat(path) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005565Like stat(path), but do not follow symbolic links.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005566
Barry Warsaw53699e91996-12-10 23:23:01 +00005567static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005568posix_lstat(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005569{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005570#ifdef HAVE_LSTAT
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005571 return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
Guido van Rossumb6775db1994-08-01 11:34:53 +00005572#else /* !HAVE_LSTAT */
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005573#ifdef MS_WINDOWS
Martin v. Löwis14694662006-02-03 12:54:16 +00005574 return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", win32_wstat);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005575#else
5576 return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
5577#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00005578#endif /* !HAVE_LSTAT */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005579}
5580
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005581
Guido van Rossumb6775db1994-08-01 11:34:53 +00005582#ifdef HAVE_READLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005583PyDoc_STRVAR(posix_readlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005584"readlink(path) -> path\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005585Return a string representing the path to which the symbolic link points.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005586
Barry Warsaw53699e91996-12-10 23:23:01 +00005587static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005588posix_readlink(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005589{
Guido van Rossumb6775db1994-08-01 11:34:53 +00005590 char buf[MAXPATHLEN];
Guido van Rossumef0a00e1992-01-27 16:51:30 +00005591 char *path;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005592 int n;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005593 if (!PyArg_ParseTuple(args, "s:readlink", &path))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005594 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005595 Py_BEGIN_ALLOW_THREADS
Guido van Rossum50e61dc1992-03-27 17:22:31 +00005596 n = readlink(path, buf, (int) sizeof buf);
Barry Warsaw53699e91996-12-10 23:23:01 +00005597 Py_END_ALLOW_THREADS
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005598 if (n < 0)
Barry Warsawd58d7641998-07-23 16:14:40 +00005599 return posix_error_with_filename(path);
Barry Warsaw53699e91996-12-10 23:23:01 +00005600 return PyString_FromStringAndSize(buf, n);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005601}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005602#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00005603
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005604
Guido van Rossumb6775db1994-08-01 11:34:53 +00005605#ifdef HAVE_SYMLINK
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005606PyDoc_STRVAR(posix_symlink__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005607"symlink(src, dst)\n\n\
Brett Cannon807413d2003-06-11 00:18:09 +00005608Create a symbolic link pointing to src named dst.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005609
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005610static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005611posix_symlink(PyObject *self, PyObject *args)
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005612{
Martin v. Löwis4fc2bda2006-05-04 12:04:27 +00005613 return posix_2str(args, "etet:symlink", symlink);
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005614}
5615#endif /* HAVE_SYMLINK */
5616
5617
5618#ifdef HAVE_TIMES
5619#ifndef HZ
5620#define HZ 60 /* Universal constant :-) */
5621#endif /* HZ */
Tim Peters5aa91602002-01-30 05:46:57 +00005622
Guido van Rossumd48f2521997-12-05 22:19:34 +00005623#if defined(PYCC_VACPP) && defined(PYOS_OS2)
5624static long
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00005625system_uptime(void)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005626{
5627 ULONG value = 0;
5628
5629 Py_BEGIN_ALLOW_THREADS
5630 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
5631 Py_END_ALLOW_THREADS
5632
5633 return value;
5634}
5635
5636static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005637posix_times(PyObject *self, PyObject *noargs)
Guido van Rossumd48f2521997-12-05 22:19:34 +00005638{
Guido van Rossumd48f2521997-12-05 22:19:34 +00005639 /* Currently Only Uptime is Provided -- Others Later */
5640 return Py_BuildValue("ddddd",
5641 (double)0 /* t.tms_utime / HZ */,
5642 (double)0 /* t.tms_stime / HZ */,
5643 (double)0 /* t.tms_cutime / HZ */,
5644 (double)0 /* t.tms_cstime / HZ */,
5645 (double)system_uptime() / 1000);
5646}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005647#else /* not OS2 */
Barry Warsaw53699e91996-12-10 23:23:01 +00005648static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005649posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum22db57e1992-04-05 14:25:30 +00005650{
5651 struct tms t;
5652 clock_t c;
Guido van Rossum22db57e1992-04-05 14:25:30 +00005653 errno = 0;
5654 c = times(&t);
Guido van Rossum687dd131993-05-17 08:34:16 +00005655 if (c == (clock_t) -1)
5656 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005657 return Py_BuildValue("ddddd",
Barry Warsaw43d68b81996-12-19 22:10:44 +00005658 (double)t.tms_utime / HZ,
5659 (double)t.tms_stime / HZ,
5660 (double)t.tms_cutime / HZ,
5661 (double)t.tms_cstime / HZ,
5662 (double)c / HZ);
Guido van Rossum22db57e1992-04-05 14:25:30 +00005663}
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005664#endif /* not OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +00005665#endif /* HAVE_TIMES */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005666
5667
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005668#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005669#define HAVE_TIMES /* so the method table will pick it up */
Barry Warsaw53699e91996-12-10 23:23:01 +00005670static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005671posix_times(PyObject *self, PyObject *noargs)
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005672{
5673 FILETIME create, exit, kernel, user;
5674 HANDLE hProc;
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005675 hProc = GetCurrentProcess();
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00005676 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
5677 /* The fields of a FILETIME structure are the hi and lo part
5678 of a 64-bit value expressed in 100 nanosecond units.
5679 1e7 is one second in such units; 1e-7 the inverse.
5680 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
5681 */
Barry Warsaw53699e91996-12-10 23:23:01 +00005682 return Py_BuildValue(
5683 "ddddd",
Guido van Rossumb8c3cbd1999-02-16 14:37:28 +00005684 (double)(kernel.dwHighDateTime*429.4967296 +
5685 kernel.dwLowDateTime*1e-7),
5686 (double)(user.dwHighDateTime*429.4967296 +
5687 user.dwLowDateTime*1e-7),
Barry Warsaw53699e91996-12-10 23:23:01 +00005688 (double)0,
5689 (double)0,
5690 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00005691}
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005692#endif /* MS_WINDOWS */
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005693
5694#ifdef HAVE_TIMES
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005695PyDoc_STRVAR(posix_times__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005696"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005697Return a tuple of floating point numbers indicating process times.");
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00005698#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00005699
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005700
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00005701#ifdef HAVE_GETSID
5702PyDoc_STRVAR(posix_getsid__doc__,
5703"getsid(pid) -> sid\n\n\
5704Call the system call getsid().");
5705
5706static PyObject *
5707posix_getsid(PyObject *self, PyObject *args)
5708{
5709 int pid, sid;
5710 if (!PyArg_ParseTuple(args, "i:getsid", &pid))
5711 return NULL;
5712 sid = getsid(pid);
5713 if (sid < 0)
5714 return posix_error();
5715 return PyInt_FromLong((long)sid);
5716}
5717#endif /* HAVE_GETSID */
5718
5719
Guido van Rossumb6775db1994-08-01 11:34:53 +00005720#ifdef HAVE_SETSID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005721PyDoc_STRVAR(posix_setsid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005722"setsid()\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005723Call the system call setsid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005724
Barry Warsaw53699e91996-12-10 23:23:01 +00005725static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00005726posix_setsid(PyObject *self, PyObject *noargs)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005727{
Guido van Rossum687dd131993-05-17 08:34:16 +00005728 if (setsid() < 0)
5729 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005730 Py_INCREF(Py_None);
5731 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005732}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005733#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005734
Guido van Rossumb6775db1994-08-01 11:34:53 +00005735#ifdef HAVE_SETPGID
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005736PyDoc_STRVAR(posix_setpgid__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005737"setpgid(pid, pgrp)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005738Call the system call setpgid().");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005739
Barry Warsaw53699e91996-12-10 23:23:01 +00005740static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005741posix_setpgid(PyObject *self, PyObject *args)
Guido van Rossumc2670a01992-09-13 20:07:29 +00005742{
5743 int pid, pgrp;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005744 if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
Guido van Rossumc2670a01992-09-13 20:07:29 +00005745 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005746 if (setpgid(pid, pgrp) < 0)
5747 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005748 Py_INCREF(Py_None);
5749 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00005750}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005751#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00005752
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005753
Guido van Rossumb6775db1994-08-01 11:34:53 +00005754#ifdef HAVE_TCGETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005755PyDoc_STRVAR(posix_tcgetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005756"tcgetpgrp(fd) -> pgid\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005757Return the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005758
Barry Warsaw53699e91996-12-10 23:23:01 +00005759static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005760posix_tcgetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005761{
5762 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005763 if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
Guido van Rossum7066dd71992-09-17 17:54:56 +00005764 return NULL;
5765 pgid = tcgetpgrp(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005766 if (pgid < 0)
5767 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005768 return PyInt_FromLong((long)pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00005769}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005770#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00005771
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005772
Guido van Rossumb6775db1994-08-01 11:34:53 +00005773#ifdef HAVE_TCSETPGRP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005774PyDoc_STRVAR(posix_tcsetpgrp__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005775"tcsetpgrp(fd, pgid)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005776Set the process group associated with the terminal given by a fd.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005777
Barry Warsaw53699e91996-12-10 23:23:01 +00005778static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005779posix_tcsetpgrp(PyObject *self, PyObject *args)
Guido van Rossum7066dd71992-09-17 17:54:56 +00005780{
5781 int fd, pgid;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005782 if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
Guido van Rossum7066dd71992-09-17 17:54:56 +00005783 return NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005784 if (tcsetpgrp(fd, pgid) < 0)
5785 return posix_error();
Barry Warsaw43d68b81996-12-19 22:10:44 +00005786 Py_INCREF(Py_None);
Barry Warsaw53699e91996-12-10 23:23:01 +00005787 return Py_None;
Guido van Rossum7066dd71992-09-17 17:54:56 +00005788}
Guido van Rossumb6775db1994-08-01 11:34:53 +00005789#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00005790
Guido van Rossum687dd131993-05-17 08:34:16 +00005791/* Functions acting on file descriptors */
5792
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005793PyDoc_STRVAR(posix_open__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005794"open(filename, flag [, mode=0777]) -> fd\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005795Open a file (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005796
Barry Warsaw53699e91996-12-10 23:23:01 +00005797static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005798posix_open(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005799{
Mark Hammondef8b6542001-05-13 08:04:26 +00005800 char *file = NULL;
Guido van Rossum687dd131993-05-17 08:34:16 +00005801 int flag;
5802 int mode = 0777;
5803 int fd;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00005804
5805#ifdef MS_WINDOWS
5806 if (unicode_file_names()) {
5807 PyUnicodeObject *po;
5808 if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
5809 Py_BEGIN_ALLOW_THREADS
5810 /* PyUnicode_AS_UNICODE OK without thread
5811 lock as it is a simple dereference. */
5812 fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
5813 Py_END_ALLOW_THREADS
5814 if (fd < 0)
5815 return posix_error();
5816 return PyInt_FromLong((long)fd);
5817 }
5818 /* Drop the argument parsing error as narrow strings
5819 are also valid. */
5820 PyErr_Clear();
5821 }
5822#endif
5823
Tim Peters5aa91602002-01-30 05:46:57 +00005824 if (!PyArg_ParseTuple(args, "eti|i",
Mark Hammondef8b6542001-05-13 08:04:26 +00005825 Py_FileSystemDefaultEncoding, &file,
5826 &flag, &mode))
Barry Warsaw43d68b81996-12-19 22:10:44 +00005827 return NULL;
5828
Barry Warsaw53699e91996-12-10 23:23:01 +00005829 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005830 fd = open(file, flag, mode);
Barry Warsaw53699e91996-12-10 23:23:01 +00005831 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005832 if (fd < 0)
Mark Hammondef8b6542001-05-13 08:04:26 +00005833 return posix_error_with_allocated_filename(file);
5834 PyMem_Free(file);
Barry Warsaw53699e91996-12-10 23:23:01 +00005835 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005836}
5837
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005838
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005839PyDoc_STRVAR(posix_close__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005840"close(fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005841Close a file descriptor (for low level IO).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005842
Barry Warsaw53699e91996-12-10 23:23:01 +00005843static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005844posix_close(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005845{
5846 int fd, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005847 if (!PyArg_ParseTuple(args, "i:close", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005848 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005849 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005850 res = close(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00005851 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005852 if (res < 0)
5853 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005854 Py_INCREF(Py_None);
5855 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005856}
5857
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005858
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005859PyDoc_STRVAR(posix_dup__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005860"dup(fd) -> fd2\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005861Return a duplicate of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005862
Barry Warsaw53699e91996-12-10 23:23:01 +00005863static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005864posix_dup(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005865{
5866 int fd;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005867 if (!PyArg_ParseTuple(args, "i:dup", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00005868 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005869 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005870 fd = dup(fd);
Barry Warsaw53699e91996-12-10 23:23:01 +00005871 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005872 if (fd < 0)
5873 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005874 return PyInt_FromLong((long)fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00005875}
5876
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005877
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005878PyDoc_STRVAR(posix_dup2__doc__,
Andrew M. Kuchling8135fd52004-01-16 13:18:42 +00005879"dup2(old_fd, new_fd)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005880Duplicate file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005881
Barry Warsaw53699e91996-12-10 23:23:01 +00005882static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005883posix_dup2(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005884{
5885 int fd, fd2, res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005886 if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
Guido van Rossum687dd131993-05-17 08:34:16 +00005887 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005888 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005889 res = dup2(fd, fd2);
Barry Warsaw53699e91996-12-10 23:23:01 +00005890 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005891 if (res < 0)
5892 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00005893 Py_INCREF(Py_None);
5894 return Py_None;
Guido van Rossum687dd131993-05-17 08:34:16 +00005895}
5896
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005897
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005898PyDoc_STRVAR(posix_lseek__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005899"lseek(fd, pos, how) -> newpos\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005900Set the current position of a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005901
Barry Warsaw53699e91996-12-10 23:23:01 +00005902static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005903posix_lseek(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005904{
5905 int fd, how;
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005906#if defined(MS_WIN64) || defined(MS_WINDOWS)
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00005907 PY_LONG_LONG pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005908#else
Guido van Rossum94f6f721999-01-06 18:42:14 +00005909 off_t pos, res;
Fred Drake699f3522000-06-29 21:12:41 +00005910#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00005911 PyObject *posobj;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005912 if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
Guido van Rossum687dd131993-05-17 08:34:16 +00005913 return NULL;
5914#ifdef SEEK_SET
5915 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
5916 switch (how) {
5917 case 0: how = SEEK_SET; break;
5918 case 1: how = SEEK_CUR; break;
5919 case 2: how = SEEK_END; break;
5920 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00005921#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00005922
5923#if !defined(HAVE_LARGEFILE_SUPPORT)
5924 pos = PyInt_AsLong(posobj);
5925#else
5926 pos = PyLong_Check(posobj) ?
5927 PyLong_AsLongLong(posobj) : PyInt_AsLong(posobj);
5928#endif
5929 if (PyErr_Occurred())
5930 return NULL;
5931
Barry Warsaw53699e91996-12-10 23:23:01 +00005932 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00005933#if defined(MS_WIN64) || defined(MS_WINDOWS)
Fred Drake699f3522000-06-29 21:12:41 +00005934 res = _lseeki64(fd, pos, how);
5935#else
Guido van Rossum687dd131993-05-17 08:34:16 +00005936 res = lseek(fd, pos, how);
Fred Drake699f3522000-06-29 21:12:41 +00005937#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00005938 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005939 if (res < 0)
5940 return posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00005941
5942#if !defined(HAVE_LARGEFILE_SUPPORT)
Barry Warsaw53699e91996-12-10 23:23:01 +00005943 return PyInt_FromLong(res);
Guido van Rossum94f6f721999-01-06 18:42:14 +00005944#else
5945 return PyLong_FromLongLong(res);
5946#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00005947}
5948
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005949
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005950PyDoc_STRVAR(posix_read__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005951"read(fd, buffersize) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005952Read a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005953
Barry Warsaw53699e91996-12-10 23:23:01 +00005954static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005955posix_read(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005956{
Guido van Rossum8bac5461996-06-11 18:38:48 +00005957 int fd, size, n;
Barry Warsaw53699e91996-12-10 23:23:01 +00005958 PyObject *buffer;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005959 if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005960 return NULL;
Michael W. Hudson9867ced2005-01-31 17:01:59 +00005961 if (size < 0) {
5962 errno = EINVAL;
5963 return posix_error();
5964 }
Barry Warsaw53699e91996-12-10 23:23:01 +00005965 buffer = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum687dd131993-05-17 08:34:16 +00005966 if (buffer == NULL)
5967 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005968 Py_BEGIN_ALLOW_THREADS
5969 n = read(fd, PyString_AsString(buffer), size);
5970 Py_END_ALLOW_THREADS
Guido van Rossum8bac5461996-06-11 18:38:48 +00005971 if (n < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00005972 Py_DECREF(buffer);
Guido van Rossum687dd131993-05-17 08:34:16 +00005973 return posix_error();
5974 }
Guido van Rossum8bac5461996-06-11 18:38:48 +00005975 if (n != size)
Barry Warsaw53699e91996-12-10 23:23:01 +00005976 _PyString_Resize(&buffer, n);
Guido van Rossum687dd131993-05-17 08:34:16 +00005977 return buffer;
5978}
5979
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005980
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005981PyDoc_STRVAR(posix_write__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00005982"write(fd, string) -> byteswritten\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00005983Write a string to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005984
Barry Warsaw53699e91996-12-10 23:23:01 +00005985static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00005986posix_write(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00005987{
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005988 int fd;
5989 Py_ssize_t size;
Guido van Rossum687dd131993-05-17 08:34:16 +00005990 char *buffer;
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005991
Fred Drake5ab8eaf1999-12-09 21:13:07 +00005992 if (!PyArg_ParseTuple(args, "is#:write", &fd, &buffer, &size))
Guido van Rossum687dd131993-05-17 08:34:16 +00005993 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00005994 Py_BEGIN_ALLOW_THREADS
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005995 size = write(fd, buffer, (size_t)size);
Barry Warsaw53699e91996-12-10 23:23:01 +00005996 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00005997 if (size < 0)
5998 return posix_error();
Thomas Wouters68bc4f92006-03-01 01:05:10 +00005999 return PyInt_FromSsize_t(size);
Guido van Rossum687dd131993-05-17 08:34:16 +00006000}
6001
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006002
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006003PyDoc_STRVAR(posix_fstat__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006004"fstat(fd) -> stat result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006005Like stat(), but for an open file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006006
Barry Warsaw53699e91996-12-10 23:23:01 +00006007static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006008posix_fstat(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006009{
6010 int fd;
Fred Drake699f3522000-06-29 21:12:41 +00006011 STRUCT_STAT st;
Guido van Rossum687dd131993-05-17 08:34:16 +00006012 int res;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006013 if (!PyArg_ParseTuple(args, "i:fstat", &fd))
Guido van Rossum687dd131993-05-17 08:34:16 +00006014 return NULL;
Martin v. Löwis7a924e62003-03-05 14:15:21 +00006015#ifdef __VMS
6016 /* on OpenVMS we must ensure that all bytes are written to the file */
6017 fsync(fd);
6018#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006019 Py_BEGIN_ALLOW_THREADS
Fred Drake699f3522000-06-29 21:12:41 +00006020 res = FSTAT(fd, &st);
Barry Warsaw53699e91996-12-10 23:23:01 +00006021 Py_END_ALLOW_THREADS
Martin v. Löwis14694662006-02-03 12:54:16 +00006022 if (res != 0) {
6023#ifdef MS_WINDOWS
6024 return win32_error("fstat", NULL);
6025#else
Guido van Rossum687dd131993-05-17 08:34:16 +00006026 return posix_error();
Martin v. Löwis14694662006-02-03 12:54:16 +00006027#endif
6028 }
Tim Peters5aa91602002-01-30 05:46:57 +00006029
Martin v. Löwis14694662006-02-03 12:54:16 +00006030 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00006031}
6032
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006033
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006034PyDoc_STRVAR(posix_fdopen__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006035"fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006036Return an open file object connected to a file descriptor.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006037
Barry Warsaw53699e91996-12-10 23:23:01 +00006038static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006039posix_fdopen(PyObject *self, PyObject *args)
Guido van Rossum687dd131993-05-17 08:34:16 +00006040{
Guido van Rossum687dd131993-05-17 08:34:16 +00006041 int fd;
Guido van Rossuma6a1e531995-01-10 15:36:38 +00006042 char *mode = "r";
6043 int bufsize = -1;
Guido van Rossum687dd131993-05-17 08:34:16 +00006044 FILE *fp;
Barry Warsaw53699e91996-12-10 23:23:01 +00006045 PyObject *f;
6046 if (!PyArg_ParseTuple(args, "i|si", &fd, &mode, &bufsize))
Guido van Rossum687dd131993-05-17 08:34:16 +00006047 return NULL;
Barry Warsaw43d68b81996-12-19 22:10:44 +00006048
Thomas Heller1f043e22002-11-07 16:00:59 +00006049 if (mode[0] != 'r' && mode[0] != 'w' && mode[0] != 'a') {
6050 PyErr_Format(PyExc_ValueError,
6051 "invalid file mode '%s'", mode);
6052 return NULL;
6053 }
Barry Warsaw53699e91996-12-10 23:23:01 +00006054 Py_BEGIN_ALLOW_THREADS
Georg Brandl644b1e72006-03-31 20:27:22 +00006055#if !defined(MS_WINDOWS) && defined(HAVE_FCNTL_H)
Georg Brandl54a188a2006-03-31 20:00:11 +00006056 if (mode[0] == 'a') {
6057 /* try to make sure the O_APPEND flag is set */
6058 int flags;
6059 flags = fcntl(fd, F_GETFL);
6060 if (flags != -1)
6061 fcntl(fd, F_SETFL, flags | O_APPEND);
6062 fp = fdopen(fd, mode);
Thomas Wouters2a9a6b02006-03-31 22:38:19 +00006063 if (fp == NULL && flags != -1)
Georg Brandl54a188a2006-03-31 20:00:11 +00006064 /* restore old mode if fdopen failed */
6065 fcntl(fd, F_SETFL, flags);
6066 } else {
6067 fp = fdopen(fd, mode);
6068 }
Georg Brandl644b1e72006-03-31 20:27:22 +00006069#else
6070 fp = fdopen(fd, mode);
6071#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006072 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006073 if (fp == NULL)
6074 return posix_error();
Guido van Rossumbd6be7a2002-09-15 18:45:46 +00006075 f = PyFile_FromFile(fp, "<fdopen>", mode, fclose);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00006076 if (f != NULL)
Barry Warsaw53699e91996-12-10 23:23:01 +00006077 PyFile_SetBufSize(f, bufsize);
Guido van Rossuma6a1e531995-01-10 15:36:38 +00006078 return f;
Guido van Rossum687dd131993-05-17 08:34:16 +00006079}
6080
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006081PyDoc_STRVAR(posix_isatty__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006082"isatty(fd) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006083Return True if the file descriptor 'fd' is an open file descriptor\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006084connected to the slave end of a terminal.");
Skip Montanaro1517d842000-07-19 14:34:14 +00006085
6086static PyObject *
Thomas Wouters616607a2000-07-19 14:45:40 +00006087posix_isatty(PyObject *self, PyObject *args)
Skip Montanaro1517d842000-07-19 14:34:14 +00006088{
6089 int fd;
6090 if (!PyArg_ParseTuple(args, "i:isatty", &fd))
6091 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006092 return PyBool_FromLong(isatty(fd));
Skip Montanaro1517d842000-07-19 14:34:14 +00006093}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006094
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006095#ifdef HAVE_PIPE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006096PyDoc_STRVAR(posix_pipe__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006097"pipe() -> (read_end, write_end)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006098Create a pipe.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006099
Barry Warsaw53699e91996-12-10 23:23:01 +00006100static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006101posix_pipe(PyObject *self, PyObject *noargs)
Guido van Rossum687dd131993-05-17 08:34:16 +00006102{
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006103#if defined(PYOS_OS2)
6104 HFILE read, write;
6105 APIRET rc;
6106
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006107 Py_BEGIN_ALLOW_THREADS
6108 rc = DosCreatePipe( &read, &write, 4096);
6109 Py_END_ALLOW_THREADS
6110 if (rc != NO_ERROR)
Guido van Rossumd48f2521997-12-05 22:19:34 +00006111 return os2_error(rc);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006112
6113 return Py_BuildValue("(ii)", read, write);
6114#else
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006115#if !defined(MS_WINDOWS)
Guido van Rossum687dd131993-05-17 08:34:16 +00006116 int fds[2];
6117 int res;
Barry Warsaw53699e91996-12-10 23:23:01 +00006118 Py_BEGIN_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006119 res = pipe(fds);
Barry Warsaw53699e91996-12-10 23:23:01 +00006120 Py_END_ALLOW_THREADS
Guido van Rossum687dd131993-05-17 08:34:16 +00006121 if (res != 0)
6122 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006123 return Py_BuildValue("(ii)", fds[0], fds[1]);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006124#else /* MS_WINDOWS */
Guido van Rossum794d8131994-08-23 13:48:48 +00006125 HANDLE read, write;
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00006126 int read_fd, write_fd;
Guido van Rossum794d8131994-08-23 13:48:48 +00006127 BOOL ok;
Barry Warsaw53699e91996-12-10 23:23:01 +00006128 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00006129 ok = CreatePipe(&read, &write, NULL, 0);
Barry Warsaw53699e91996-12-10 23:23:01 +00006130 Py_END_ALLOW_THREADS
Guido van Rossum794d8131994-08-23 13:48:48 +00006131 if (!ok)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00006132 return win32_error("CreatePipe", NULL);
Tim Peters79248aa2001-08-29 21:37:10 +00006133 read_fd = _open_osfhandle((Py_intptr_t)read, 0);
6134 write_fd = _open_osfhandle((Py_intptr_t)write, 1);
Guido van Rossumb3f9f4b1998-06-12 15:05:15 +00006135 return Py_BuildValue("(ii)", read_fd, write_fd);
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006136#endif /* MS_WINDOWS */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00006137#endif
Guido van Rossum687dd131993-05-17 08:34:16 +00006138}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006139#endif /* HAVE_PIPE */
6140
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006141
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006142#ifdef HAVE_MKFIFO
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006143PyDoc_STRVAR(posix_mkfifo__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006144"mkfifo(filename [, mode=0666])\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006145Create a FIFO (a POSIX named pipe).");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006146
Barry Warsaw53699e91996-12-10 23:23:01 +00006147static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006148posix_mkfifo(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006149{
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006150 char *filename;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006151 int mode = 0666;
6152 int res;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006153 if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006154 return NULL;
Barry Warsaw53699e91996-12-10 23:23:01 +00006155 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006156 res = mkfifo(filename, mode);
6157 Py_END_ALLOW_THREADS
6158 if (res < 0)
6159 return posix_error();
6160 Py_INCREF(Py_None);
6161 return Py_None;
6162}
6163#endif
6164
6165
Neal Norwitz11690112002-07-30 01:08:28 +00006166#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006167PyDoc_STRVAR(posix_mknod__doc__,
Neal Norwitzc18b3082002-10-11 22:19:42 +00006168"mknod(filename [, mode=0600, device])\n\n\
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006169Create a filesystem node (file, device special file or named pipe)\n\
6170named filename. mode specifies both the permissions to use and the\n\
6171type of node to be created, being combined (bitwise OR) with one of\n\
6172S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006173device defines the newly created device special file (probably using\n\
6174os.makedev()), otherwise it is ignored.");
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006175
6176
6177static PyObject *
6178posix_mknod(PyObject *self, PyObject *args)
6179{
6180 char *filename;
6181 int mode = 0600;
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006182 int device = 0;
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006183 int res;
Martin v. Löwisd631ebe2002-11-02 17:42:33 +00006184 if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
Martin v. Löwis06a83e92002-04-14 10:19:44 +00006185 return NULL;
6186 Py_BEGIN_ALLOW_THREADS
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006187 res = mknod(filename, mode, device);
Barry Warsaw53699e91996-12-10 23:23:01 +00006188 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006189 if (res < 0)
6190 return posix_error();
Barry Warsaw53699e91996-12-10 23:23:01 +00006191 Py_INCREF(Py_None);
6192 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006193}
6194#endif
6195
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00006196#ifdef HAVE_DEVICE_MACROS
6197PyDoc_STRVAR(posix_major__doc__,
6198"major(device) -> major number\n\
6199Extracts a device major number from a raw device number.");
6200
6201static PyObject *
6202posix_major(PyObject *self, PyObject *args)
6203{
6204 int device;
6205 if (!PyArg_ParseTuple(args, "i:major", &device))
6206 return NULL;
6207 return PyInt_FromLong((long)major(device));
6208}
6209
6210PyDoc_STRVAR(posix_minor__doc__,
6211"minor(device) -> minor number\n\
6212Extracts a device minor number from a raw device number.");
6213
6214static PyObject *
6215posix_minor(PyObject *self, PyObject *args)
6216{
6217 int device;
6218 if (!PyArg_ParseTuple(args, "i:minor", &device))
6219 return NULL;
6220 return PyInt_FromLong((long)minor(device));
6221}
6222
6223PyDoc_STRVAR(posix_makedev__doc__,
6224"makedev(major, minor) -> device number\n\
6225Composes a raw device number from the major and minor device numbers.");
6226
6227static PyObject *
6228posix_makedev(PyObject *self, PyObject *args)
6229{
6230 int major, minor;
6231 if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
6232 return NULL;
6233 return PyInt_FromLong((long)makedev(major, minor));
6234}
6235#endif /* device macros */
6236
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006237
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006238#ifdef HAVE_FTRUNCATE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006239PyDoc_STRVAR(posix_ftruncate__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006240"ftruncate(fd, length)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006241Truncate a file to a specified length.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006242
Barry Warsaw53699e91996-12-10 23:23:01 +00006243static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006244posix_ftruncate(PyObject *self, PyObject *args)
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006245{
6246 int fd;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006247 off_t length;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006248 int res;
Guido van Rossum94f6f721999-01-06 18:42:14 +00006249 PyObject *lenobj;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006250
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006251 if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006252 return NULL;
6253
6254#if !defined(HAVE_LARGEFILE_SUPPORT)
6255 length = PyInt_AsLong(lenobj);
6256#else
6257 length = PyLong_Check(lenobj) ?
6258 PyLong_AsLongLong(lenobj) : PyInt_AsLong(lenobj);
6259#endif
6260 if (PyErr_Occurred())
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006261 return NULL;
6262
Barry Warsaw53699e91996-12-10 23:23:01 +00006263 Py_BEGIN_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006264 res = ftruncate(fd, length);
Barry Warsaw53699e91996-12-10 23:23:01 +00006265 Py_END_ALLOW_THREADS
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006266 if (res < 0) {
Barry Warsaw53699e91996-12-10 23:23:01 +00006267 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006268 return NULL;
6269 }
Barry Warsaw53699e91996-12-10 23:23:01 +00006270 Py_INCREF(Py_None);
6271 return Py_None;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00006272}
6273#endif
Guido van Rossum22db57e1992-04-05 14:25:30 +00006274
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006275#ifdef HAVE_PUTENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006276PyDoc_STRVAR(posix_putenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006277"putenv(key, value)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006278Change or add an environment variable.");
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006279
Fred Drake762e2061999-08-26 17:23:54 +00006280/* Save putenv() parameters as values here, so we can collect them when they
6281 * get re-set with another call for the same key. */
6282static PyObject *posix_putenv_garbage;
6283
Tim Peters5aa91602002-01-30 05:46:57 +00006284static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006285posix_putenv(PyObject *self, PyObject *args)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006286{
6287 char *s1, *s2;
Anthony Baxter64182fe2006-04-11 12:14:09 +00006288 char *newenv;
Fred Drake762e2061999-08-26 17:23:54 +00006289 PyObject *newstr;
Tim Petersc8996f52001-12-03 20:41:00 +00006290 size_t len;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006291
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006292 if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2))
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006293 return NULL;
Guido van Rossumd48f2521997-12-05 22:19:34 +00006294
6295#if defined(PYOS_OS2)
6296 if (stricmp(s1, "BEGINLIBPATH") == 0) {
6297 APIRET rc;
6298
Guido van Rossumd48f2521997-12-05 22:19:34 +00006299 rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
6300 if (rc != NO_ERROR)
6301 return os2_error(rc);
6302
6303 } else if (stricmp(s1, "ENDLIBPATH") == 0) {
6304 APIRET rc;
6305
Guido van Rossumd48f2521997-12-05 22:19:34 +00006306 rc = DosSetExtLIBPATH(s2, END_LIBPATH);
6307 if (rc != NO_ERROR)
6308 return os2_error(rc);
6309 } else {
6310#endif
6311
Fred Drake762e2061999-08-26 17:23:54 +00006312 /* XXX This can leak memory -- not easy to fix :-( */
Tim Petersc8996f52001-12-03 20:41:00 +00006313 len = strlen(s1) + strlen(s2) + 2;
6314 /* len includes space for a trailing \0; the size arg to
6315 PyString_FromStringAndSize does not count that */
6316 newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
Fred Drake762e2061999-08-26 17:23:54 +00006317 if (newstr == NULL)
6318 return PyErr_NoMemory();
Anthony Baxter64182fe2006-04-11 12:14:09 +00006319 newenv = PyString_AS_STRING(newstr);
6320 PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
6321 if (putenv(newenv)) {
Neal Norwitz4adc9ab2003-02-10 03:10:43 +00006322 Py_DECREF(newstr);
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006323 posix_error();
6324 return NULL;
6325 }
Fred Drake762e2061999-08-26 17:23:54 +00006326 /* Install the first arg and newstr in posix_putenv_garbage;
6327 * this will cause previous value to be collected. This has to
6328 * happen after the real putenv() call because the old value
6329 * was still accessible until then. */
6330 if (PyDict_SetItem(posix_putenv_garbage,
6331 PyTuple_GET_ITEM(args, 0), newstr)) {
6332 /* really not much we can do; just leak */
6333 PyErr_Clear();
6334 }
6335 else {
6336 Py_DECREF(newstr);
6337 }
Guido van Rossumd48f2521997-12-05 22:19:34 +00006338
6339#if defined(PYOS_OS2)
6340 }
6341#endif
Barry Warsaw53699e91996-12-10 23:23:01 +00006342 Py_INCREF(Py_None);
6343 return Py_None;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006344}
Guido van Rossumb6a47161997-09-15 22:54:34 +00006345#endif /* putenv */
6346
Guido van Rossumc524d952001-10-19 01:31:59 +00006347#ifdef HAVE_UNSETENV
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006348PyDoc_STRVAR(posix_unsetenv__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006349"unsetenv(key)\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006350Delete an environment variable.");
Guido van Rossumc524d952001-10-19 01:31:59 +00006351
6352static PyObject *
6353posix_unsetenv(PyObject *self, PyObject *args)
6354{
6355 char *s1;
6356
6357 if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
6358 return NULL;
6359
6360 unsetenv(s1);
6361
6362 /* Remove the key from posix_putenv_garbage;
6363 * this will cause it to be collected. This has to
Tim Peters5aa91602002-01-30 05:46:57 +00006364 * happen after the real unsetenv() call because the
Guido van Rossumc524d952001-10-19 01:31:59 +00006365 * old value was still accessible until then.
6366 */
6367 if (PyDict_DelItem(posix_putenv_garbage,
6368 PyTuple_GET_ITEM(args, 0))) {
6369 /* really not much we can do; just leak */
6370 PyErr_Clear();
6371 }
6372
6373 Py_INCREF(Py_None);
6374 return Py_None;
6375}
6376#endif /* unsetenv */
6377
Guido van Rossumb6a47161997-09-15 22:54:34 +00006378#ifdef HAVE_STRERROR
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006379PyDoc_STRVAR(posix_strerror__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006380"strerror(code) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006381Translate an error code to a message string.");
Guido van Rossumb6a47161997-09-15 22:54:34 +00006382
Guido van Rossumf68d8e52001-04-14 17:55:09 +00006383static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006384posix_strerror(PyObject *self, PyObject *args)
Guido van Rossumb6a47161997-09-15 22:54:34 +00006385{
6386 int code;
6387 char *message;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006388 if (!PyArg_ParseTuple(args, "i:strerror", &code))
Guido van Rossumb6a47161997-09-15 22:54:34 +00006389 return NULL;
6390 message = strerror(code);
6391 if (message == NULL) {
6392 PyErr_SetString(PyExc_ValueError,
Fred Drake661ea262000-10-24 19:57:45 +00006393 "strerror() argument out of range");
Guido van Rossumb6a47161997-09-15 22:54:34 +00006394 return NULL;
6395 }
6396 return PyString_FromString(message);
6397}
6398#endif /* strerror */
6399
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00006400
Guido van Rossumc9641791998-08-04 15:26:23 +00006401#ifdef HAVE_SYS_WAIT_H
6402
Fred Drake106c1a02002-04-23 15:58:02 +00006403#ifdef WCOREDUMP
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006404PyDoc_STRVAR(posix_WCOREDUMP__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006405"WCOREDUMP(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006406Return True if the process returning 'status' was dumped to a core file.");
Fred Drake106c1a02002-04-23 15:58:02 +00006407
6408static PyObject *
6409posix_WCOREDUMP(PyObject *self, PyObject *args)
6410{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006411 WAIT_TYPE status;
6412 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006413
Neal Norwitzd5a37542006-03-20 06:48:34 +00006414 if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00006415 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006416
6417 return PyBool_FromLong(WCOREDUMP(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006418}
6419#endif /* WCOREDUMP */
6420
6421#ifdef WIFCONTINUED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006422PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006423"WIFCONTINUED(status) -> bool\n\n\
Fred Drake106c1a02002-04-23 15:58:02 +00006424Return True if the process returning 'status' was continued from a\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006425job control stop.");
Fred Drake106c1a02002-04-23 15:58:02 +00006426
6427static PyObject *
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006428posix_WIFCONTINUED(PyObject *self, PyObject *args)
Fred Drake106c1a02002-04-23 15:58:02 +00006429{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006430 WAIT_TYPE status;
6431 WAIT_STATUS_INT(status) = 0;
Fred Drake106c1a02002-04-23 15:58:02 +00006432
Neal Norwitzd5a37542006-03-20 06:48:34 +00006433 if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
Fred Drake106c1a02002-04-23 15:58:02 +00006434 return NULL;
Fred Drake106c1a02002-04-23 15:58:02 +00006435
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00006436 return PyBool_FromLong(WIFCONTINUED(status));
Fred Drake106c1a02002-04-23 15:58:02 +00006437}
6438#endif /* WIFCONTINUED */
6439
Guido van Rossumc9641791998-08-04 15:26:23 +00006440#ifdef WIFSTOPPED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006441PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006442"WIFSTOPPED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006443Return True if the process returning 'status' was stopped.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006444
6445static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006446posix_WIFSTOPPED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006447{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006448 WAIT_TYPE status;
6449 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006450
Neal Norwitzd5a37542006-03-20 06:48:34 +00006451 if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006452 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006453
Fred Drake106c1a02002-04-23 15:58:02 +00006454 return PyBool_FromLong(WIFSTOPPED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006455}
6456#endif /* WIFSTOPPED */
6457
6458#ifdef WIFSIGNALED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006459PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006460"WIFSIGNALED(status) -> bool\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006461Return True if the process returning 'status' was terminated by a signal.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006462
6463static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006464posix_WIFSIGNALED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006465{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006466 WAIT_TYPE status;
6467 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006468
Neal Norwitzd5a37542006-03-20 06:48:34 +00006469 if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006470 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006471
Fred Drake106c1a02002-04-23 15:58:02 +00006472 return PyBool_FromLong(WIFSIGNALED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006473}
6474#endif /* WIFSIGNALED */
6475
6476#ifdef WIFEXITED
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006477PyDoc_STRVAR(posix_WIFEXITED__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006478"WIFEXITED(status) -> bool\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006479Return true if the process returning 'status' exited using the exit()\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006480system call.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006481
6482static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006483posix_WIFEXITED(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006484{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006485 WAIT_TYPE status;
6486 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006487
Neal Norwitzd5a37542006-03-20 06:48:34 +00006488 if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006489 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006490
Fred Drake106c1a02002-04-23 15:58:02 +00006491 return PyBool_FromLong(WIFEXITED(status));
Guido van Rossumc9641791998-08-04 15:26:23 +00006492}
6493#endif /* WIFEXITED */
6494
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006495#ifdef WEXITSTATUS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006496PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006497"WEXITSTATUS(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006498Return the process return code from 'status'.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006499
6500static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006501posix_WEXITSTATUS(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006502{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006503 WAIT_TYPE status;
6504 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006505
Neal Norwitzd5a37542006-03-20 06:48:34 +00006506 if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006507 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006508
Guido van Rossumc9641791998-08-04 15:26:23 +00006509 return Py_BuildValue("i", WEXITSTATUS(status));
6510}
6511#endif /* WEXITSTATUS */
6512
6513#ifdef WTERMSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006514PyDoc_STRVAR(posix_WTERMSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006515"WTERMSIG(status) -> integer\n\n\
Fred Drake7e3535c1999-02-02 16:37:11 +00006516Return the signal that terminated the process that provided the 'status'\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006517value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006518
6519static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006520posix_WTERMSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006521{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006522 WAIT_TYPE status;
6523 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006524
Neal Norwitzd5a37542006-03-20 06:48:34 +00006525 if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006526 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006527
Guido van Rossumc9641791998-08-04 15:26:23 +00006528 return Py_BuildValue("i", WTERMSIG(status));
6529}
6530#endif /* WTERMSIG */
6531
6532#ifdef WSTOPSIG
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006533PyDoc_STRVAR(posix_WSTOPSIG__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006534"WSTOPSIG(status) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006535Return the signal that stopped the process that provided\n\
6536the 'status' value.");
Guido van Rossumc9641791998-08-04 15:26:23 +00006537
6538static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006539posix_WSTOPSIG(PyObject *self, PyObject *args)
Guido van Rossumc9641791998-08-04 15:26:23 +00006540{
Neal Norwitzd5a37542006-03-20 06:48:34 +00006541 WAIT_TYPE status;
6542 WAIT_STATUS_INT(status) = 0;
Tim Peters5aa91602002-01-30 05:46:57 +00006543
Neal Norwitzd5a37542006-03-20 06:48:34 +00006544 if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
Guido van Rossumc9641791998-08-04 15:26:23 +00006545 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +00006546
Guido van Rossumc9641791998-08-04 15:26:23 +00006547 return Py_BuildValue("i", WSTOPSIG(status));
6548}
6549#endif /* WSTOPSIG */
6550
6551#endif /* HAVE_SYS_WAIT_H */
6552
6553
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00006554#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00006555#ifdef _SCO_DS
6556/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
6557 needed definitions in sys/statvfs.h */
6558#define _SVID3
6559#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00006560#include <sys/statvfs.h>
6561
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006562static PyObject*
6563_pystatvfs_fromstructstatvfs(struct statvfs st) {
6564 PyObject *v = PyStructSequence_New(&StatVFSResultType);
6565 if (v == NULL)
6566 return NULL;
6567
6568#if !defined(HAVE_LARGEFILE_SUPPORT)
6569 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6570 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
6571 PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
6572 PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
6573 PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
6574 PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
6575 PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
6576 PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
6577 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6578 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6579#else
6580 PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
6581 PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
Tim Peters5aa91602002-01-30 05:46:57 +00006582 PyStructSequence_SET_ITEM(v, 2,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006583 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
Tim Peters5aa91602002-01-30 05:46:57 +00006584 PyStructSequence_SET_ITEM(v, 3,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006585 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006586 PyStructSequence_SET_ITEM(v, 4,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006587 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
Tim Peters5aa91602002-01-30 05:46:57 +00006588 PyStructSequence_SET_ITEM(v, 5,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006589 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
Tim Peters5aa91602002-01-30 05:46:57 +00006590 PyStructSequence_SET_ITEM(v, 6,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006591 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
Tim Peters5aa91602002-01-30 05:46:57 +00006592 PyStructSequence_SET_ITEM(v, 7,
Martin v. Löwisb9a0f912003-03-29 10:06:18 +00006593 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006594 PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
6595 PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
6596#endif
6597
6598 return v;
6599}
6600
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006601PyDoc_STRVAR(posix_fstatvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006602"fstatvfs(fd) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006603Perform an fstatvfs system call on the given fd.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006604
6605static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006606posix_fstatvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006607{
6608 int fd, res;
6609 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006610
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006611 if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006612 return NULL;
6613 Py_BEGIN_ALLOW_THREADS
6614 res = fstatvfs(fd, &st);
6615 Py_END_ALLOW_THREADS
6616 if (res != 0)
6617 return posix_error();
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006618
6619 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006620}
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00006621#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
Guido van Rossum94f6f721999-01-06 18:42:14 +00006622
6623
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00006624#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006625#include <sys/statvfs.h>
6626
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006627PyDoc_STRVAR(posix_statvfs__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006628"statvfs(path) -> statvfs result\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006629Perform a statvfs system call on the given path.");
Guido van Rossum94f6f721999-01-06 18:42:14 +00006630
6631static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006632posix_statvfs(PyObject *self, PyObject *args)
Guido van Rossum94f6f721999-01-06 18:42:14 +00006633{
6634 char *path;
6635 int res;
6636 struct statvfs st;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006637 if (!PyArg_ParseTuple(args, "s:statvfs", &path))
Guido van Rossum94f6f721999-01-06 18:42:14 +00006638 return NULL;
6639 Py_BEGIN_ALLOW_THREADS
6640 res = statvfs(path, &st);
6641 Py_END_ALLOW_THREADS
6642 if (res != 0)
6643 return posix_error_with_filename(path);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00006644
6645 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00006646}
6647#endif /* HAVE_STATVFS */
6648
6649
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006650#ifdef HAVE_TEMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006651PyDoc_STRVAR(posix_tempnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006652"tempnam([dir[, prefix]]) -> string\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006653Return a unique name for a temporary file.\n\
Neal Norwitz50d5d4f2002-07-30 01:17:43 +00006654The directory and a prefix may be specified as strings; they may be omitted\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006655or None if not needed.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006656
6657static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006658posix_tempnam(PyObject *self, PyObject *args)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006659{
6660 PyObject *result = NULL;
6661 char *dir = NULL;
6662 char *pfx = NULL;
6663 char *name;
6664
6665 if (!PyArg_ParseTuple(args, "|zz:tempnam", &dir, &pfx))
6666 return NULL;
Skip Montanaro95618b52001-08-18 18:52:10 +00006667
6668 if (PyErr_Warn(PyExc_RuntimeWarning,
6669 "tempnam is a potential security risk to your program") < 0)
6670 return NULL;
6671
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00006672#ifdef MS_WINDOWS
Fred Drake78b71c22001-07-17 20:37:36 +00006673 name = _tempnam(dir, pfx);
6674#else
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006675 name = tempnam(dir, pfx);
Fred Drake78b71c22001-07-17 20:37:36 +00006676#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006677 if (name == NULL)
6678 return PyErr_NoMemory();
6679 result = PyString_FromString(name);
6680 free(name);
6681 return result;
6682}
Guido van Rossumd371ff11999-01-25 16:12:23 +00006683#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006684
6685
6686#ifdef HAVE_TMPFILE
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006687PyDoc_STRVAR(posix_tmpfile__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006688"tmpfile() -> file object\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006689Create a temporary file with no directory entries.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006690
6691static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006692posix_tmpfile(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006693{
6694 FILE *fp;
6695
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006696 fp = tmpfile();
6697 if (fp == NULL)
6698 return posix_error();
Guido van Rossumdb9198a2002-06-10 19:23:22 +00006699 return PyFile_FromFile(fp, "<tmpfile>", "w+b", fclose);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006700}
6701#endif
6702
6703
6704#ifdef HAVE_TMPNAM
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006705PyDoc_STRVAR(posix_tmpnam__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006706"tmpnam() -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006707Return a unique name for a temporary file.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006708
6709static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00006710posix_tmpnam(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006711{
6712 char buffer[L_tmpnam];
6713 char *name;
6714
Skip Montanaro95618b52001-08-18 18:52:10 +00006715 if (PyErr_Warn(PyExc_RuntimeWarning,
6716 "tmpnam is a potential security risk to your program") < 0)
6717 return NULL;
6718
Greg Wardb48bc172000-03-01 21:51:56 +00006719#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006720 name = tmpnam_r(buffer);
6721#else
6722 name = tmpnam(buffer);
6723#endif
6724 if (name == NULL) {
Neal Norwitzd1e0ef62006-03-20 04:08:12 +00006725 PyObject *err = Py_BuildValue("is", 0,
Greg Wardb48bc172000-03-01 21:51:56 +00006726#ifdef USE_TMPNAM_R
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006727 "unexpected NULL from tmpnam_r"
6728#else
6729 "unexpected NULL from tmpnam"
6730#endif
Neal Norwitzd1e0ef62006-03-20 04:08:12 +00006731 );
6732 PyErr_SetObject(PyExc_OSError, err);
6733 Py_XDECREF(err);
6734 return NULL;
Fred Drake5ab8eaf1999-12-09 21:13:07 +00006735 }
6736 return PyString_FromString(buffer);
6737}
6738#endif
6739
6740
Fred Drakec9680921999-12-13 16:37:25 +00006741/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
6742 * It maps strings representing configuration variable names to
6743 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00006744 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00006745 * rarely-used constants. There are three separate tables that use
6746 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00006747 *
6748 * This code is always included, even if none of the interfaces that
6749 * need it are included. The #if hackery needed to avoid it would be
6750 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00006751 */
6752struct constdef {
6753 char *name;
6754 long value;
6755};
6756
Fred Drake12c6e2d1999-12-14 21:25:03 +00006757static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006758conv_confname(PyObject *arg, int *valuep, struct constdef *table,
6759 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00006760{
6761 if (PyInt_Check(arg)) {
6762 *valuep = PyInt_AS_LONG(arg);
6763 return 1;
6764 }
6765 if (PyString_Check(arg)) {
6766 /* look up the value in the table using a binary search */
Fred Drake699f3522000-06-29 21:12:41 +00006767 size_t lo = 0;
6768 size_t mid;
6769 size_t hi = tablesize;
6770 int cmp;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006771 char *confname = PyString_AS_STRING(arg);
6772 while (lo < hi) {
6773 mid = (lo + hi) / 2;
6774 cmp = strcmp(confname, table[mid].name);
6775 if (cmp < 0)
6776 hi = mid;
6777 else if (cmp > 0)
6778 lo = mid + 1;
6779 else {
6780 *valuep = table[mid].value;
6781 return 1;
6782 }
6783 }
6784 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
6785 }
6786 else
6787 PyErr_SetString(PyExc_TypeError,
6788 "configuration names must be strings or integers");
6789 return 0;
6790}
6791
6792
6793#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
6794static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006795#ifdef _PC_ABI_AIO_XFER_MAX
6796 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
6797#endif
6798#ifdef _PC_ABI_ASYNC_IO
6799 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
6800#endif
Fred Drakec9680921999-12-13 16:37:25 +00006801#ifdef _PC_ASYNC_IO
6802 {"PC_ASYNC_IO", _PC_ASYNC_IO},
6803#endif
6804#ifdef _PC_CHOWN_RESTRICTED
6805 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
6806#endif
6807#ifdef _PC_FILESIZEBITS
6808 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
6809#endif
6810#ifdef _PC_LAST
6811 {"PC_LAST", _PC_LAST},
6812#endif
6813#ifdef _PC_LINK_MAX
6814 {"PC_LINK_MAX", _PC_LINK_MAX},
6815#endif
6816#ifdef _PC_MAX_CANON
6817 {"PC_MAX_CANON", _PC_MAX_CANON},
6818#endif
6819#ifdef _PC_MAX_INPUT
6820 {"PC_MAX_INPUT", _PC_MAX_INPUT},
6821#endif
6822#ifdef _PC_NAME_MAX
6823 {"PC_NAME_MAX", _PC_NAME_MAX},
6824#endif
6825#ifdef _PC_NO_TRUNC
6826 {"PC_NO_TRUNC", _PC_NO_TRUNC},
6827#endif
6828#ifdef _PC_PATH_MAX
6829 {"PC_PATH_MAX", _PC_PATH_MAX},
6830#endif
6831#ifdef _PC_PIPE_BUF
6832 {"PC_PIPE_BUF", _PC_PIPE_BUF},
6833#endif
6834#ifdef _PC_PRIO_IO
6835 {"PC_PRIO_IO", _PC_PRIO_IO},
6836#endif
6837#ifdef _PC_SOCK_MAXBUF
6838 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
6839#endif
6840#ifdef _PC_SYNC_IO
6841 {"PC_SYNC_IO", _PC_SYNC_IO},
6842#endif
6843#ifdef _PC_VDISABLE
6844 {"PC_VDISABLE", _PC_VDISABLE},
6845#endif
6846};
6847
Fred Drakec9680921999-12-13 16:37:25 +00006848static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006849conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00006850{
6851 return conv_confname(arg, valuep, posix_constants_pathconf,
6852 sizeof(posix_constants_pathconf)
6853 / sizeof(struct constdef));
6854}
6855#endif
6856
6857#ifdef HAVE_FPATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006858PyDoc_STRVAR(posix_fpathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006859"fpathconf(fd, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006860Return the configuration limit name for the file descriptor fd.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006861If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006862
6863static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006864posix_fpathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006865{
6866 PyObject *result = NULL;
6867 int name, fd;
6868
Fred Drake12c6e2d1999-12-14 21:25:03 +00006869 if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
6870 conv_path_confname, &name)) {
Fred Drakec9680921999-12-13 16:37:25 +00006871 long limit;
6872
6873 errno = 0;
6874 limit = fpathconf(fd, name);
6875 if (limit == -1 && errno != 0)
6876 posix_error();
6877 else
6878 result = PyInt_FromLong(limit);
6879 }
6880 return result;
6881}
6882#endif
6883
6884
6885#ifdef HAVE_PATHCONF
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006886PyDoc_STRVAR(posix_pathconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00006887"pathconf(path, name) -> integer\n\n\
Fred Drakec9680921999-12-13 16:37:25 +00006888Return the configuration limit name for the file or directory path.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006889If there is no limit, return -1.");
Fred Drakec9680921999-12-13 16:37:25 +00006890
6891static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00006892posix_pathconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00006893{
6894 PyObject *result = NULL;
6895 int name;
6896 char *path;
6897
6898 if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
6899 conv_path_confname, &name)) {
6900 long limit;
6901
6902 errno = 0;
6903 limit = pathconf(path, name);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006904 if (limit == -1 && errno != 0) {
Fred Drakec9680921999-12-13 16:37:25 +00006905 if (errno == EINVAL)
6906 /* could be a path or name problem */
6907 posix_error();
6908 else
6909 posix_error_with_filename(path);
Fred Drake12c6e2d1999-12-14 21:25:03 +00006910 }
Fred Drakec9680921999-12-13 16:37:25 +00006911 else
6912 result = PyInt_FromLong(limit);
6913 }
6914 return result;
6915}
6916#endif
6917
6918#ifdef HAVE_CONFSTR
6919static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00006920#ifdef _CS_ARCHITECTURE
6921 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
6922#endif
6923#ifdef _CS_HOSTNAME
6924 {"CS_HOSTNAME", _CS_HOSTNAME},
6925#endif
6926#ifdef _CS_HW_PROVIDER
6927 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
6928#endif
6929#ifdef _CS_HW_SERIAL
6930 {"CS_HW_SERIAL", _CS_HW_SERIAL},
6931#endif
6932#ifdef _CS_INITTAB_NAME
6933 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
6934#endif
Fred Drakec9680921999-12-13 16:37:25 +00006935#ifdef _CS_LFS64_CFLAGS
6936 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
6937#endif
6938#ifdef _CS_LFS64_LDFLAGS
6939 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
6940#endif
6941#ifdef _CS_LFS64_LIBS
6942 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
6943#endif
6944#ifdef _CS_LFS64_LINTFLAGS
6945 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
6946#endif
6947#ifdef _CS_LFS_CFLAGS
6948 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
6949#endif
6950#ifdef _CS_LFS_LDFLAGS
6951 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
6952#endif
6953#ifdef _CS_LFS_LIBS
6954 {"CS_LFS_LIBS", _CS_LFS_LIBS},
6955#endif
6956#ifdef _CS_LFS_LINTFLAGS
6957 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
6958#endif
Fred Draked86ed291999-12-15 15:34:33 +00006959#ifdef _CS_MACHINE
6960 {"CS_MACHINE", _CS_MACHINE},
6961#endif
Fred Drakec9680921999-12-13 16:37:25 +00006962#ifdef _CS_PATH
6963 {"CS_PATH", _CS_PATH},
6964#endif
Fred Draked86ed291999-12-15 15:34:33 +00006965#ifdef _CS_RELEASE
6966 {"CS_RELEASE", _CS_RELEASE},
6967#endif
6968#ifdef _CS_SRPC_DOMAIN
6969 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
6970#endif
6971#ifdef _CS_SYSNAME
6972 {"CS_SYSNAME", _CS_SYSNAME},
6973#endif
6974#ifdef _CS_VERSION
6975 {"CS_VERSION", _CS_VERSION},
6976#endif
Fred Drakec9680921999-12-13 16:37:25 +00006977#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
6978 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
6979#endif
6980#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
6981 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
6982#endif
6983#ifdef _CS_XBS5_ILP32_OFF32_LIBS
6984 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
6985#endif
6986#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
6987 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
6988#endif
6989#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
6990 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
6991#endif
6992#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
6993 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
6994#endif
6995#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
6996 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
6997#endif
6998#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
6999 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
7000#endif
7001#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
7002 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
7003#endif
7004#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
7005 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
7006#endif
7007#ifdef _CS_XBS5_LP64_OFF64_LIBS
7008 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
7009#endif
7010#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
7011 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
7012#endif
7013#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
7014 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
7015#endif
7016#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
7017 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
7018#endif
7019#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
7020 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
7021#endif
7022#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
7023 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
7024#endif
Fred Draked86ed291999-12-15 15:34:33 +00007025#ifdef _MIPS_CS_AVAIL_PROCESSORS
7026 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
7027#endif
7028#ifdef _MIPS_CS_BASE
7029 {"MIPS_CS_BASE", _MIPS_CS_BASE},
7030#endif
7031#ifdef _MIPS_CS_HOSTID
7032 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
7033#endif
7034#ifdef _MIPS_CS_HW_NAME
7035 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
7036#endif
7037#ifdef _MIPS_CS_NUM_PROCESSORS
7038 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
7039#endif
7040#ifdef _MIPS_CS_OSREL_MAJ
7041 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
7042#endif
7043#ifdef _MIPS_CS_OSREL_MIN
7044 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
7045#endif
7046#ifdef _MIPS_CS_OSREL_PATCH
7047 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
7048#endif
7049#ifdef _MIPS_CS_OS_NAME
7050 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
7051#endif
7052#ifdef _MIPS_CS_OS_PROVIDER
7053 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
7054#endif
7055#ifdef _MIPS_CS_PROCESSORS
7056 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
7057#endif
7058#ifdef _MIPS_CS_SERIAL
7059 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
7060#endif
7061#ifdef _MIPS_CS_VENDOR
7062 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
7063#endif
Fred Drakec9680921999-12-13 16:37:25 +00007064};
7065
7066static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007067conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007068{
7069 return conv_confname(arg, valuep, posix_constants_confstr,
7070 sizeof(posix_constants_confstr)
7071 / sizeof(struct constdef));
7072}
7073
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007074PyDoc_STRVAR(posix_confstr__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007075"confstr(name) -> string\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007076Return a string-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007077
7078static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007079posix_confstr(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007080{
7081 PyObject *result = NULL;
7082 int name;
Neal Norwitz449b24e2006-04-20 06:56:05 +00007083 char buffer[256];
Fred Drakec9680921999-12-13 16:37:25 +00007084
7085 if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
Skip Montanarodd527fc2006-04-18 00:49:49 +00007086 int len;
Fred Drakec9680921999-12-13 16:37:25 +00007087
Fred Drakec9680921999-12-13 16:37:25 +00007088 errno = 0;
Skip Montanarodd527fc2006-04-18 00:49:49 +00007089 len = confstr(name, buffer, sizeof(buffer));
Skip Montanaro94785ef2006-04-20 01:29:48 +00007090 if (len == 0) {
7091 if (errno) {
7092 posix_error();
7093 }
7094 else {
7095 result = Py_None;
7096 Py_INCREF(Py_None);
7097 }
Fred Drakec9680921999-12-13 16:37:25 +00007098 }
7099 else {
Neal Norwitz0d21b1e2006-04-20 06:44:42 +00007100 if ((unsigned int)len >= sizeof(buffer)) {
Neal Norwitz449b24e2006-04-20 06:56:05 +00007101 result = PyString_FromStringAndSize(NULL, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00007102 if (result != NULL)
Neal Norwitz449b24e2006-04-20 06:56:05 +00007103 confstr(name, PyString_AS_STRING(result), len);
Fred Drakec9680921999-12-13 16:37:25 +00007104 }
7105 else
Neal Norwitz449b24e2006-04-20 06:56:05 +00007106 result = PyString_FromStringAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00007107 }
7108 }
7109 return result;
7110}
7111#endif
7112
7113
7114#ifdef HAVE_SYSCONF
7115static struct constdef posix_constants_sysconf[] = {
7116#ifdef _SC_2_CHAR_TERM
7117 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
7118#endif
7119#ifdef _SC_2_C_BIND
7120 {"SC_2_C_BIND", _SC_2_C_BIND},
7121#endif
7122#ifdef _SC_2_C_DEV
7123 {"SC_2_C_DEV", _SC_2_C_DEV},
7124#endif
7125#ifdef _SC_2_C_VERSION
7126 {"SC_2_C_VERSION", _SC_2_C_VERSION},
7127#endif
7128#ifdef _SC_2_FORT_DEV
7129 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
7130#endif
7131#ifdef _SC_2_FORT_RUN
7132 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
7133#endif
7134#ifdef _SC_2_LOCALEDEF
7135 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
7136#endif
7137#ifdef _SC_2_SW_DEV
7138 {"SC_2_SW_DEV", _SC_2_SW_DEV},
7139#endif
7140#ifdef _SC_2_UPE
7141 {"SC_2_UPE", _SC_2_UPE},
7142#endif
7143#ifdef _SC_2_VERSION
7144 {"SC_2_VERSION", _SC_2_VERSION},
7145#endif
Fred Draked86ed291999-12-15 15:34:33 +00007146#ifdef _SC_ABI_ASYNCHRONOUS_IO
7147 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
7148#endif
7149#ifdef _SC_ACL
7150 {"SC_ACL", _SC_ACL},
7151#endif
Fred Drakec9680921999-12-13 16:37:25 +00007152#ifdef _SC_AIO_LISTIO_MAX
7153 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
7154#endif
Fred Drakec9680921999-12-13 16:37:25 +00007155#ifdef _SC_AIO_MAX
7156 {"SC_AIO_MAX", _SC_AIO_MAX},
7157#endif
7158#ifdef _SC_AIO_PRIO_DELTA_MAX
7159 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
7160#endif
7161#ifdef _SC_ARG_MAX
7162 {"SC_ARG_MAX", _SC_ARG_MAX},
7163#endif
7164#ifdef _SC_ASYNCHRONOUS_IO
7165 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
7166#endif
7167#ifdef _SC_ATEXIT_MAX
7168 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
7169#endif
Fred Draked86ed291999-12-15 15:34:33 +00007170#ifdef _SC_AUDIT
7171 {"SC_AUDIT", _SC_AUDIT},
7172#endif
Fred Drakec9680921999-12-13 16:37:25 +00007173#ifdef _SC_AVPHYS_PAGES
7174 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
7175#endif
7176#ifdef _SC_BC_BASE_MAX
7177 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
7178#endif
7179#ifdef _SC_BC_DIM_MAX
7180 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
7181#endif
7182#ifdef _SC_BC_SCALE_MAX
7183 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
7184#endif
7185#ifdef _SC_BC_STRING_MAX
7186 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
7187#endif
Fred Draked86ed291999-12-15 15:34:33 +00007188#ifdef _SC_CAP
7189 {"SC_CAP", _SC_CAP},
7190#endif
Fred Drakec9680921999-12-13 16:37:25 +00007191#ifdef _SC_CHARCLASS_NAME_MAX
7192 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
7193#endif
7194#ifdef _SC_CHAR_BIT
7195 {"SC_CHAR_BIT", _SC_CHAR_BIT},
7196#endif
7197#ifdef _SC_CHAR_MAX
7198 {"SC_CHAR_MAX", _SC_CHAR_MAX},
7199#endif
7200#ifdef _SC_CHAR_MIN
7201 {"SC_CHAR_MIN", _SC_CHAR_MIN},
7202#endif
7203#ifdef _SC_CHILD_MAX
7204 {"SC_CHILD_MAX", _SC_CHILD_MAX},
7205#endif
7206#ifdef _SC_CLK_TCK
7207 {"SC_CLK_TCK", _SC_CLK_TCK},
7208#endif
7209#ifdef _SC_COHER_BLKSZ
7210 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
7211#endif
7212#ifdef _SC_COLL_WEIGHTS_MAX
7213 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
7214#endif
7215#ifdef _SC_DCACHE_ASSOC
7216 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
7217#endif
7218#ifdef _SC_DCACHE_BLKSZ
7219 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
7220#endif
7221#ifdef _SC_DCACHE_LINESZ
7222 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
7223#endif
7224#ifdef _SC_DCACHE_SZ
7225 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
7226#endif
7227#ifdef _SC_DCACHE_TBLKSZ
7228 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
7229#endif
7230#ifdef _SC_DELAYTIMER_MAX
7231 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
7232#endif
7233#ifdef _SC_EQUIV_CLASS_MAX
7234 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
7235#endif
7236#ifdef _SC_EXPR_NEST_MAX
7237 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
7238#endif
7239#ifdef _SC_FSYNC
7240 {"SC_FSYNC", _SC_FSYNC},
7241#endif
7242#ifdef _SC_GETGR_R_SIZE_MAX
7243 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
7244#endif
7245#ifdef _SC_GETPW_R_SIZE_MAX
7246 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
7247#endif
7248#ifdef _SC_ICACHE_ASSOC
7249 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
7250#endif
7251#ifdef _SC_ICACHE_BLKSZ
7252 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
7253#endif
7254#ifdef _SC_ICACHE_LINESZ
7255 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
7256#endif
7257#ifdef _SC_ICACHE_SZ
7258 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
7259#endif
Fred Draked86ed291999-12-15 15:34:33 +00007260#ifdef _SC_INF
7261 {"SC_INF", _SC_INF},
7262#endif
Fred Drakec9680921999-12-13 16:37:25 +00007263#ifdef _SC_INT_MAX
7264 {"SC_INT_MAX", _SC_INT_MAX},
7265#endif
7266#ifdef _SC_INT_MIN
7267 {"SC_INT_MIN", _SC_INT_MIN},
7268#endif
7269#ifdef _SC_IOV_MAX
7270 {"SC_IOV_MAX", _SC_IOV_MAX},
7271#endif
Fred Draked86ed291999-12-15 15:34:33 +00007272#ifdef _SC_IP_SECOPTS
7273 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
7274#endif
Fred Drakec9680921999-12-13 16:37:25 +00007275#ifdef _SC_JOB_CONTROL
7276 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
7277#endif
Fred Draked86ed291999-12-15 15:34:33 +00007278#ifdef _SC_KERN_POINTERS
7279 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
7280#endif
7281#ifdef _SC_KERN_SIM
7282 {"SC_KERN_SIM", _SC_KERN_SIM},
7283#endif
Fred Drakec9680921999-12-13 16:37:25 +00007284#ifdef _SC_LINE_MAX
7285 {"SC_LINE_MAX", _SC_LINE_MAX},
7286#endif
7287#ifdef _SC_LOGIN_NAME_MAX
7288 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
7289#endif
7290#ifdef _SC_LOGNAME_MAX
7291 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
7292#endif
7293#ifdef _SC_LONG_BIT
7294 {"SC_LONG_BIT", _SC_LONG_BIT},
7295#endif
Fred Draked86ed291999-12-15 15:34:33 +00007296#ifdef _SC_MAC
7297 {"SC_MAC", _SC_MAC},
7298#endif
Fred Drakec9680921999-12-13 16:37:25 +00007299#ifdef _SC_MAPPED_FILES
7300 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
7301#endif
7302#ifdef _SC_MAXPID
7303 {"SC_MAXPID", _SC_MAXPID},
7304#endif
7305#ifdef _SC_MB_LEN_MAX
7306 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
7307#endif
7308#ifdef _SC_MEMLOCK
7309 {"SC_MEMLOCK", _SC_MEMLOCK},
7310#endif
7311#ifdef _SC_MEMLOCK_RANGE
7312 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
7313#endif
7314#ifdef _SC_MEMORY_PROTECTION
7315 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
7316#endif
7317#ifdef _SC_MESSAGE_PASSING
7318 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
7319#endif
Fred Draked86ed291999-12-15 15:34:33 +00007320#ifdef _SC_MMAP_FIXED_ALIGNMENT
7321 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
7322#endif
Fred Drakec9680921999-12-13 16:37:25 +00007323#ifdef _SC_MQ_OPEN_MAX
7324 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
7325#endif
7326#ifdef _SC_MQ_PRIO_MAX
7327 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
7328#endif
Fred Draked86ed291999-12-15 15:34:33 +00007329#ifdef _SC_NACLS_MAX
7330 {"SC_NACLS_MAX", _SC_NACLS_MAX},
7331#endif
Fred Drakec9680921999-12-13 16:37:25 +00007332#ifdef _SC_NGROUPS_MAX
7333 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
7334#endif
7335#ifdef _SC_NL_ARGMAX
7336 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
7337#endif
7338#ifdef _SC_NL_LANGMAX
7339 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
7340#endif
7341#ifdef _SC_NL_MSGMAX
7342 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
7343#endif
7344#ifdef _SC_NL_NMAX
7345 {"SC_NL_NMAX", _SC_NL_NMAX},
7346#endif
7347#ifdef _SC_NL_SETMAX
7348 {"SC_NL_SETMAX", _SC_NL_SETMAX},
7349#endif
7350#ifdef _SC_NL_TEXTMAX
7351 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
7352#endif
7353#ifdef _SC_NPROCESSORS_CONF
7354 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
7355#endif
7356#ifdef _SC_NPROCESSORS_ONLN
7357 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
7358#endif
Fred Draked86ed291999-12-15 15:34:33 +00007359#ifdef _SC_NPROC_CONF
7360 {"SC_NPROC_CONF", _SC_NPROC_CONF},
7361#endif
7362#ifdef _SC_NPROC_ONLN
7363 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
7364#endif
Fred Drakec9680921999-12-13 16:37:25 +00007365#ifdef _SC_NZERO
7366 {"SC_NZERO", _SC_NZERO},
7367#endif
7368#ifdef _SC_OPEN_MAX
7369 {"SC_OPEN_MAX", _SC_OPEN_MAX},
7370#endif
7371#ifdef _SC_PAGESIZE
7372 {"SC_PAGESIZE", _SC_PAGESIZE},
7373#endif
7374#ifdef _SC_PAGE_SIZE
7375 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
7376#endif
7377#ifdef _SC_PASS_MAX
7378 {"SC_PASS_MAX", _SC_PASS_MAX},
7379#endif
7380#ifdef _SC_PHYS_PAGES
7381 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
7382#endif
7383#ifdef _SC_PII
7384 {"SC_PII", _SC_PII},
7385#endif
7386#ifdef _SC_PII_INTERNET
7387 {"SC_PII_INTERNET", _SC_PII_INTERNET},
7388#endif
7389#ifdef _SC_PII_INTERNET_DGRAM
7390 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
7391#endif
7392#ifdef _SC_PII_INTERNET_STREAM
7393 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
7394#endif
7395#ifdef _SC_PII_OSI
7396 {"SC_PII_OSI", _SC_PII_OSI},
7397#endif
7398#ifdef _SC_PII_OSI_CLTS
7399 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
7400#endif
7401#ifdef _SC_PII_OSI_COTS
7402 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
7403#endif
7404#ifdef _SC_PII_OSI_M
7405 {"SC_PII_OSI_M", _SC_PII_OSI_M},
7406#endif
7407#ifdef _SC_PII_SOCKET
7408 {"SC_PII_SOCKET", _SC_PII_SOCKET},
7409#endif
7410#ifdef _SC_PII_XTI
7411 {"SC_PII_XTI", _SC_PII_XTI},
7412#endif
7413#ifdef _SC_POLL
7414 {"SC_POLL", _SC_POLL},
7415#endif
7416#ifdef _SC_PRIORITIZED_IO
7417 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
7418#endif
7419#ifdef _SC_PRIORITY_SCHEDULING
7420 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
7421#endif
7422#ifdef _SC_REALTIME_SIGNALS
7423 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
7424#endif
7425#ifdef _SC_RE_DUP_MAX
7426 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
7427#endif
7428#ifdef _SC_RTSIG_MAX
7429 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
7430#endif
7431#ifdef _SC_SAVED_IDS
7432 {"SC_SAVED_IDS", _SC_SAVED_IDS},
7433#endif
7434#ifdef _SC_SCHAR_MAX
7435 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
7436#endif
7437#ifdef _SC_SCHAR_MIN
7438 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
7439#endif
7440#ifdef _SC_SELECT
7441 {"SC_SELECT", _SC_SELECT},
7442#endif
7443#ifdef _SC_SEMAPHORES
7444 {"SC_SEMAPHORES", _SC_SEMAPHORES},
7445#endif
7446#ifdef _SC_SEM_NSEMS_MAX
7447 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
7448#endif
7449#ifdef _SC_SEM_VALUE_MAX
7450 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
7451#endif
7452#ifdef _SC_SHARED_MEMORY_OBJECTS
7453 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
7454#endif
7455#ifdef _SC_SHRT_MAX
7456 {"SC_SHRT_MAX", _SC_SHRT_MAX},
7457#endif
7458#ifdef _SC_SHRT_MIN
7459 {"SC_SHRT_MIN", _SC_SHRT_MIN},
7460#endif
7461#ifdef _SC_SIGQUEUE_MAX
7462 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
7463#endif
7464#ifdef _SC_SIGRT_MAX
7465 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
7466#endif
7467#ifdef _SC_SIGRT_MIN
7468 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
7469#endif
Fred Draked86ed291999-12-15 15:34:33 +00007470#ifdef _SC_SOFTPOWER
7471 {"SC_SOFTPOWER", _SC_SOFTPOWER},
7472#endif
Fred Drakec9680921999-12-13 16:37:25 +00007473#ifdef _SC_SPLIT_CACHE
7474 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
7475#endif
7476#ifdef _SC_SSIZE_MAX
7477 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
7478#endif
7479#ifdef _SC_STACK_PROT
7480 {"SC_STACK_PROT", _SC_STACK_PROT},
7481#endif
7482#ifdef _SC_STREAM_MAX
7483 {"SC_STREAM_MAX", _SC_STREAM_MAX},
7484#endif
7485#ifdef _SC_SYNCHRONIZED_IO
7486 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
7487#endif
7488#ifdef _SC_THREADS
7489 {"SC_THREADS", _SC_THREADS},
7490#endif
7491#ifdef _SC_THREAD_ATTR_STACKADDR
7492 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
7493#endif
7494#ifdef _SC_THREAD_ATTR_STACKSIZE
7495 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
7496#endif
7497#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
7498 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
7499#endif
7500#ifdef _SC_THREAD_KEYS_MAX
7501 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
7502#endif
7503#ifdef _SC_THREAD_PRIORITY_SCHEDULING
7504 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
7505#endif
7506#ifdef _SC_THREAD_PRIO_INHERIT
7507 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
7508#endif
7509#ifdef _SC_THREAD_PRIO_PROTECT
7510 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
7511#endif
7512#ifdef _SC_THREAD_PROCESS_SHARED
7513 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
7514#endif
7515#ifdef _SC_THREAD_SAFE_FUNCTIONS
7516 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
7517#endif
7518#ifdef _SC_THREAD_STACK_MIN
7519 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
7520#endif
7521#ifdef _SC_THREAD_THREADS_MAX
7522 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
7523#endif
7524#ifdef _SC_TIMERS
7525 {"SC_TIMERS", _SC_TIMERS},
7526#endif
7527#ifdef _SC_TIMER_MAX
7528 {"SC_TIMER_MAX", _SC_TIMER_MAX},
7529#endif
7530#ifdef _SC_TTY_NAME_MAX
7531 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
7532#endif
7533#ifdef _SC_TZNAME_MAX
7534 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
7535#endif
7536#ifdef _SC_T_IOV_MAX
7537 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
7538#endif
7539#ifdef _SC_UCHAR_MAX
7540 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
7541#endif
7542#ifdef _SC_UINT_MAX
7543 {"SC_UINT_MAX", _SC_UINT_MAX},
7544#endif
7545#ifdef _SC_UIO_MAXIOV
7546 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
7547#endif
7548#ifdef _SC_ULONG_MAX
7549 {"SC_ULONG_MAX", _SC_ULONG_MAX},
7550#endif
7551#ifdef _SC_USHRT_MAX
7552 {"SC_USHRT_MAX", _SC_USHRT_MAX},
7553#endif
7554#ifdef _SC_VERSION
7555 {"SC_VERSION", _SC_VERSION},
7556#endif
7557#ifdef _SC_WORD_BIT
7558 {"SC_WORD_BIT", _SC_WORD_BIT},
7559#endif
7560#ifdef _SC_XBS5_ILP32_OFF32
7561 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
7562#endif
7563#ifdef _SC_XBS5_ILP32_OFFBIG
7564 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
7565#endif
7566#ifdef _SC_XBS5_LP64_OFF64
7567 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
7568#endif
7569#ifdef _SC_XBS5_LPBIG_OFFBIG
7570 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
7571#endif
7572#ifdef _SC_XOPEN_CRYPT
7573 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
7574#endif
7575#ifdef _SC_XOPEN_ENH_I18N
7576 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
7577#endif
7578#ifdef _SC_XOPEN_LEGACY
7579 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
7580#endif
7581#ifdef _SC_XOPEN_REALTIME
7582 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
7583#endif
7584#ifdef _SC_XOPEN_REALTIME_THREADS
7585 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
7586#endif
7587#ifdef _SC_XOPEN_SHM
7588 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
7589#endif
7590#ifdef _SC_XOPEN_UNIX
7591 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
7592#endif
7593#ifdef _SC_XOPEN_VERSION
7594 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
7595#endif
7596#ifdef _SC_XOPEN_XCU_VERSION
7597 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
7598#endif
7599#ifdef _SC_XOPEN_XPG2
7600 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
7601#endif
7602#ifdef _SC_XOPEN_XPG3
7603 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
7604#endif
7605#ifdef _SC_XOPEN_XPG4
7606 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
7607#endif
7608};
7609
7610static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007611conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00007612{
7613 return conv_confname(arg, valuep, posix_constants_sysconf,
7614 sizeof(posix_constants_sysconf)
7615 / sizeof(struct constdef));
7616}
7617
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007618PyDoc_STRVAR(posix_sysconf__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007619"sysconf(name) -> integer\n\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007620Return an integer-valued system configuration variable.");
Fred Drakec9680921999-12-13 16:37:25 +00007621
7622static PyObject *
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007623posix_sysconf(PyObject *self, PyObject *args)
Fred Drakec9680921999-12-13 16:37:25 +00007624{
7625 PyObject *result = NULL;
7626 int name;
7627
7628 if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
7629 int value;
7630
7631 errno = 0;
7632 value = sysconf(name);
7633 if (value == -1 && errno != 0)
7634 posix_error();
7635 else
7636 result = PyInt_FromLong(value);
7637 }
7638 return result;
7639}
7640#endif
7641
7642
Fred Drakebec628d1999-12-15 18:31:10 +00007643/* This code is used to ensure that the tables of configuration value names
7644 * are in sorted order as required by conv_confname(), and also to build the
7645 * the exported dictionaries that are used to publish information about the
7646 * names available on the host platform.
7647 *
7648 * Sorting the table at runtime ensures that the table is properly ordered
7649 * when used, even for platforms we're not able to test on. It also makes
7650 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +00007651 */
Fred Drakebec628d1999-12-15 18:31:10 +00007652
7653static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007654cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +00007655{
7656 const struct constdef *c1 =
7657 (const struct constdef *) v1;
7658 const struct constdef *c2 =
7659 (const struct constdef *) v2;
7660
7661 return strcmp(c1->name, c2->name);
7662}
7663
7664static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00007665setup_confname_table(struct constdef *table, size_t tablesize,
Fred Drake4d1e64b2002-04-15 19:40:07 +00007666 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007667{
Fred Drakebec628d1999-12-15 18:31:10 +00007668 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +00007669 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +00007670
7671 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
7672 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +00007673 if (d == NULL)
7674 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007675
Barry Warsaw3155db32000-04-13 15:20:40 +00007676 for (i=0; i < tablesize; ++i) {
7677 PyObject *o = PyInt_FromLong(table[i].value);
7678 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
7679 Py_XDECREF(o);
7680 Py_DECREF(d);
7681 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007682 }
Barry Warsaw3155db32000-04-13 15:20:40 +00007683 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +00007684 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00007685 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +00007686}
7687
Fred Drakebec628d1999-12-15 18:31:10 +00007688/* Return -1 on failure, 0 on success. */
7689static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00007690setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +00007691{
7692#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +00007693 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +00007694 sizeof(posix_constants_pathconf)
7695 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007696 "pathconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007697 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007698#endif
7699#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +00007700 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +00007701 sizeof(posix_constants_confstr)
7702 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007703 "confstr_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007704 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007705#endif
7706#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +00007707 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +00007708 sizeof(posix_constants_sysconf)
7709 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +00007710 "sysconf_names", module))
Fred Drakebec628d1999-12-15 18:31:10 +00007711 return -1;
Fred Draked86ed291999-12-15 15:34:33 +00007712#endif
Fred Drakebec628d1999-12-15 18:31:10 +00007713 return 0;
Fred Draked86ed291999-12-15 15:34:33 +00007714}
Fred Draked86ed291999-12-15 15:34:33 +00007715
7716
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007717PyDoc_STRVAR(posix_abort__doc__,
Fred Drakef7ce04d2002-06-20 18:31:21 +00007718"abort() -> does not return!\n\n\
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007719Abort the interpreter immediately. This 'dumps core' or otherwise fails\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007720in the hardest way possible on the hosting operating system.");
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007721
7722static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007723posix_abort(PyObject *self, PyObject *noargs)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007724{
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007725 abort();
7726 /*NOTREACHED*/
7727 Py_FatalError("abort() called from Python code didn't abort!");
7728 return NULL;
7729}
Fred Drakebec628d1999-12-15 18:31:10 +00007730
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007731#ifdef MS_WINDOWS
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007732PyDoc_STRVAR(win32_startfile__doc__,
Georg Brandlf4f44152006-02-18 22:29:33 +00007733"startfile(filepath [, operation]) - Start a file with its associated\n\
7734application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007735\n\
Georg Brandlf4f44152006-02-18 22:29:33 +00007736When \"operation\" is not specified or \"open\", this acts like\n\
7737double-clicking the file in Explorer, or giving the file name as an\n\
7738argument to the DOS \"start\" command: the file is opened with whatever\n\
7739application (if any) its extension is associated.\n\
7740When another \"operation\" is given, it specifies what should be done with\n\
7741the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +00007742\n\
7743startfile returns as soon as the associated application is launched.\n\
7744There is no option to wait for the application to close, and no way\n\
7745to retrieve the application's exit status.\n\
7746\n\
7747The filepath is relative to the current directory. If you want to use\n\
7748an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00007749the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +00007750
7751static PyObject *
7752win32_startfile(PyObject *self, PyObject *args)
7753{
7754 char *filepath;
Georg Brandlf4f44152006-02-18 22:29:33 +00007755 char *operation = NULL;
Tim Petersf58a7aa2000-09-22 10:05:54 +00007756 HINSTANCE rc;
Georg Brandlad89dc82006-04-03 12:26:26 +00007757#ifdef Py_WIN_WIDE_FILENAMES
7758 if (unicode_file_names()) {
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00007759 PyObject *unipath, *woperation = NULL;
Georg Brandlad89dc82006-04-03 12:26:26 +00007760 if (!PyArg_ParseTuple(args, "U|s:startfile",
7761 &unipath, &operation)) {
7762 PyErr_Clear();
7763 goto normal;
7764 }
7765
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00007766
7767 if (operation) {
7768 woperation = PyUnicode_DecodeASCII(operation,
7769 strlen(operation), NULL);
7770 if (!woperation) {
7771 PyErr_Clear();
7772 operation = NULL;
7773 goto normal;
7774 }
Georg Brandlad89dc82006-04-03 12:26:26 +00007775 }
7776
7777 Py_BEGIN_ALLOW_THREADS
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00007778 rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
Georg Brandlad89dc82006-04-03 12:26:26 +00007779 PyUnicode_AS_UNICODE(unipath),
Georg Brandlad89dc82006-04-03 12:26:26 +00007780 NULL, NULL, SW_SHOWNORMAL);
7781 Py_END_ALLOW_THREADS
7782
Martin v. Löwis5fe715f2006-04-03 23:01:24 +00007783 Py_XDECREF(woperation);
Georg Brandlad89dc82006-04-03 12:26:26 +00007784 if (rc <= (HINSTANCE)32) {
7785 PyObject *errval = win32_error_unicode("startfile",
7786 PyUnicode_AS_UNICODE(unipath));
7787 return errval;
7788 }
7789 Py_INCREF(Py_None);
7790 return Py_None;
7791 }
7792#endif
7793
7794normal:
Georg Brandlf4f44152006-02-18 22:29:33 +00007795 if (!PyArg_ParseTuple(args, "et|s:startfile",
7796 Py_FileSystemDefaultEncoding, &filepath,
7797 &operation))
Tim Petersf58a7aa2000-09-22 10:05:54 +00007798 return NULL;
7799 Py_BEGIN_ALLOW_THREADS
Georg Brandlf4f44152006-02-18 22:29:33 +00007800 rc = ShellExecute((HWND)0, operation, filepath,
7801 NULL, NULL, SW_SHOWNORMAL);
Tim Petersf58a7aa2000-09-22 10:05:54 +00007802 Py_END_ALLOW_THREADS
Georg Brandle9f8ec92005-09-25 06:16:40 +00007803 if (rc <= (HINSTANCE)32) {
7804 PyObject *errval = win32_error("startfile", filepath);
7805 PyMem_Free(filepath);
7806 return errval;
7807 }
7808 PyMem_Free(filepath);
Tim Petersf58a7aa2000-09-22 10:05:54 +00007809 Py_INCREF(Py_None);
7810 return Py_None;
7811}
7812#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007813
Martin v. Löwis438b5342002-12-27 10:16:42 +00007814#ifdef HAVE_GETLOADAVG
7815PyDoc_STRVAR(posix_getloadavg__doc__,
7816"getloadavg() -> (float, float, float)\n\n\
7817Return the number of processes in the system run queue averaged over\n\
7818the last 1, 5, and 15 minutes or raises OSError if the load average\n\
7819was unobtainable");
7820
7821static PyObject *
Neal Norwitze241ce82003-02-17 18:17:05 +00007822posix_getloadavg(PyObject *self, PyObject *noargs)
Martin v. Löwis438b5342002-12-27 10:16:42 +00007823{
7824 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +00007825 if (getloadavg(loadavg, 3)!=3) {
7826 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
7827 return NULL;
7828 } else
7829 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
7830}
7831#endif
7832
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007833#ifdef MS_WINDOWS
7834
7835PyDoc_STRVAR(win32_urandom__doc__,
7836"urandom(n) -> str\n\n\
7837Return a string of n random bytes suitable for cryptographic use.");
7838
7839typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
7840 LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
7841 DWORD dwFlags );
7842typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
7843 BYTE *pbBuffer );
7844
7845static CRYPTGENRANDOM pCryptGenRandom = NULL;
7846static HCRYPTPROV hCryptProv = 0;
7847
Tim Peters4ad82172004-08-30 17:02:04 +00007848static PyObject*
7849win32_urandom(PyObject *self, PyObject *args)
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007850{
Tim Petersd3115382004-08-30 17:36:46 +00007851 int howMany;
7852 PyObject* result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007853
Tim Peters4ad82172004-08-30 17:02:04 +00007854 /* Read arguments */
Tim Peters9b279a82004-08-30 17:10:53 +00007855 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
Tim Peters4ad82172004-08-30 17:02:04 +00007856 return NULL;
Tim Peters51eba612004-08-30 17:08:02 +00007857 if (howMany < 0)
7858 return PyErr_Format(PyExc_ValueError,
7859 "negative argument not allowed");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007860
Tim Peters4ad82172004-08-30 17:02:04 +00007861 if (hCryptProv == 0) {
7862 HINSTANCE hAdvAPI32 = NULL;
7863 CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007864
Tim Peters4ad82172004-08-30 17:02:04 +00007865 /* Obtain handle to the DLL containing CryptoAPI
7866 This should not fail */
7867 hAdvAPI32 = GetModuleHandle("advapi32.dll");
7868 if(hAdvAPI32 == NULL)
7869 return win32_error("GetModuleHandle", NULL);
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007870
Tim Peters4ad82172004-08-30 17:02:04 +00007871 /* Obtain pointers to the CryptoAPI functions
7872 This will fail on some early versions of Win95 */
7873 pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
7874 hAdvAPI32,
7875 "CryptAcquireContextA");
7876 if (pCryptAcquireContext == NULL)
7877 return PyErr_Format(PyExc_NotImplementedError,
7878 "CryptAcquireContextA not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007879
Tim Peters4ad82172004-08-30 17:02:04 +00007880 pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
7881 hAdvAPI32, "CryptGenRandom");
Georg Brandl74bb7832006-09-06 06:03:59 +00007882 if (pCryptGenRandom == NULL)
Tim Peters4ad82172004-08-30 17:02:04 +00007883 return PyErr_Format(PyExc_NotImplementedError,
7884 "CryptGenRandom not found");
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007885
Tim Peters4ad82172004-08-30 17:02:04 +00007886 /* Acquire context */
7887 if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
7888 PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
7889 return win32_error("CryptAcquireContext", NULL);
7890 }
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007891
Tim Peters4ad82172004-08-30 17:02:04 +00007892 /* Allocate bytes */
Tim Petersd3115382004-08-30 17:36:46 +00007893 result = PyString_FromStringAndSize(NULL, howMany);
7894 if (result != NULL) {
7895 /* Get random data */
7896 if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
7897 PyString_AS_STRING(result))) {
7898 Py_DECREF(result);
7899 return win32_error("CryptGenRandom", NULL);
7900 }
Tim Peters4ad82172004-08-30 17:02:04 +00007901 }
Tim Petersd3115382004-08-30 17:36:46 +00007902 return result;
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00007903}
7904#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00007905
Neal Norwitz2a30cd02006-07-10 01:18:57 +00007906#ifdef __VMS
7907/* Use openssl random routine */
7908#include <openssl/rand.h>
7909PyDoc_STRVAR(vms_urandom__doc__,
7910"urandom(n) -> str\n\n\
7911Return a string of n random bytes suitable for cryptographic use.");
7912
7913static PyObject*
7914vms_urandom(PyObject *self, PyObject *args)
7915{
7916 int howMany;
7917 PyObject* result;
7918
7919 /* Read arguments */
7920 if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
7921 return NULL;
7922 if (howMany < 0)
7923 return PyErr_Format(PyExc_ValueError,
7924 "negative argument not allowed");
7925
7926 /* Allocate bytes */
7927 result = PyString_FromStringAndSize(NULL, howMany);
7928 if (result != NULL) {
7929 /* Get random data */
7930 if (RAND_pseudo_bytes((unsigned char*)
7931 PyString_AS_STRING(result),
7932 howMany) < 0) {
7933 Py_DECREF(result);
7934 return PyErr_Format(PyExc_ValueError,
7935 "RAND_pseudo_bytes");
7936 }
7937 }
7938 return result;
7939}
7940#endif
7941
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007942static PyMethodDef posix_methods[] = {
7943 {"access", posix_access, METH_VARARGS, posix_access__doc__},
7944#ifdef HAVE_TTYNAME
7945 {"ttyname", posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
7946#endif
7947 {"chdir", posix_chdir, METH_VARARGS, posix_chdir__doc__},
7948 {"chmod", posix_chmod, METH_VARARGS, posix_chmod__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007949#ifdef HAVE_CHOWN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007950 {"chown", posix_chown, METH_VARARGS, posix_chown__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007951#endif /* HAVE_CHOWN */
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00007952#ifdef HAVE_LCHOWN
7953 {"lchown", posix_lchown, METH_VARARGS, posix_lchown__doc__},
7954#endif /* HAVE_LCHOWN */
Martin v. Löwis244edc82001-10-04 22:44:26 +00007955#ifdef HAVE_CHROOT
7956 {"chroot", posix_chroot, METH_VARARGS, posix_chroot__doc__},
7957#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007958#ifdef HAVE_CTERMID
Neal Norwitze241ce82003-02-17 18:17:05 +00007959 {"ctermid", posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007960#endif
Guido van Rossum36bc6801995-06-14 22:54:23 +00007961#ifdef HAVE_GETCWD
Neal Norwitze241ce82003-02-17 18:17:05 +00007962 {"getcwd", posix_getcwd, METH_NOARGS, posix_getcwd__doc__},
Walter Dörwald3b918c32002-11-21 20:18:46 +00007963#ifdef Py_USING_UNICODE
Neal Norwitze241ce82003-02-17 18:17:05 +00007964 {"getcwdu", posix_getcwdu, METH_NOARGS, posix_getcwdu__doc__},
Guido van Rossum36bc6801995-06-14 22:54:23 +00007965#endif
Walter Dörwald3b918c32002-11-21 20:18:46 +00007966#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +00007967#ifdef HAVE_LINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007968 {"link", posix_link, METH_VARARGS, posix_link__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007969#endif /* HAVE_LINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007970 {"listdir", posix_listdir, METH_VARARGS, posix_listdir__doc__},
7971 {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__},
7972 {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007973#ifdef HAVE_NICE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007974 {"nice", posix_nice, METH_VARARGS, posix_nice__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007975#endif /* HAVE_NICE */
Guido van Rossumb6775db1994-08-01 11:34:53 +00007976#ifdef HAVE_READLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007977 {"readlink", posix_readlink, METH_VARARGS, posix_readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007978#endif /* HAVE_READLINK */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007979 {"rename", posix_rename, METH_VARARGS, posix_rename__doc__},
7980 {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
7981 {"stat", posix_stat, METH_VARARGS, posix_stat__doc__},
Martin v. Löwisf607bda2002-10-16 18:27:39 +00007982 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007983#ifdef HAVE_SYMLINK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007984 {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007985#endif /* HAVE_SYMLINK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007986#ifdef HAVE_SYSTEM
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007987 {"system", posix_system, METH_VARARGS, posix_system__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00007988#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007989 {"umask", posix_umask, METH_VARARGS, posix_umask__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007990#ifdef HAVE_UNAME
Neal Norwitze241ce82003-02-17 18:17:05 +00007991 {"uname", posix_uname, METH_NOARGS, posix_uname__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007992#endif /* HAVE_UNAME */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007993 {"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
7994 {"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
7995 {"utime", posix_utime, METH_VARARGS, posix_utime__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00007996#ifdef HAVE_TIMES
Neal Norwitze241ce82003-02-17 18:17:05 +00007997 {"times", posix_times, METH_NOARGS, posix_times__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007998#endif /* HAVE_TIMES */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00007999 {"_exit", posix__exit, METH_VARARGS, posix__exit__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008000#ifdef HAVE_EXECV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008001 {"execv", posix_execv, METH_VARARGS, posix_execv__doc__},
8002 {"execve", posix_execve, METH_VARARGS, posix_execve__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008003#endif /* HAVE_EXECV */
Guido van Rossuma1065681999-01-25 23:20:23 +00008004#ifdef HAVE_SPAWNV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008005 {"spawnv", posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
8006 {"spawnve", posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00008007#if defined(PYOS_OS2)
8008 {"spawnvp", posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
8009 {"spawnvpe", posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
8010#endif /* PYOS_OS2 */
Guido van Rossuma1065681999-01-25 23:20:23 +00008011#endif /* HAVE_SPAWNV */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00008012#ifdef HAVE_FORK1
Neal Norwitze241ce82003-02-17 18:17:05 +00008013 {"fork1", posix_fork1, METH_NOARGS, posix_fork1__doc__},
Guido van Rossum2242f2f2001-04-11 20:58:20 +00008014#endif /* HAVE_FORK1 */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008015#ifdef HAVE_FORK
Neal Norwitze241ce82003-02-17 18:17:05 +00008016 {"fork", posix_fork, METH_NOARGS, posix_fork__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008017#endif /* HAVE_FORK */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008018#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Neal Norwitze241ce82003-02-17 18:17:05 +00008019 {"openpty", posix_openpty, METH_NOARGS, posix_openpty__doc__},
Martin v. Löwis24a880b2002-12-31 12:55:15 +00008020#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00008021#ifdef HAVE_FORKPTY
Neal Norwitze241ce82003-02-17 18:17:05 +00008022 {"forkpty", posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
Fred Drake8cef4cf2000-06-28 16:40:38 +00008023#endif /* HAVE_FORKPTY */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008024#ifdef HAVE_GETEGID
Neal Norwitze241ce82003-02-17 18:17:05 +00008025 {"getegid", posix_getegid, METH_NOARGS, posix_getegid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008026#endif /* HAVE_GETEGID */
8027#ifdef HAVE_GETEUID
Neal Norwitze241ce82003-02-17 18:17:05 +00008028 {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008029#endif /* HAVE_GETEUID */
8030#ifdef HAVE_GETGID
Neal Norwitze241ce82003-02-17 18:17:05 +00008031 {"getgid", posix_getgid, METH_NOARGS, posix_getgid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008032#endif /* HAVE_GETGID */
Fred Drakec9680921999-12-13 16:37:25 +00008033#ifdef HAVE_GETGROUPS
Neal Norwitze241ce82003-02-17 18:17:05 +00008034 {"getgroups", posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
Fred Drakec9680921999-12-13 16:37:25 +00008035#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00008036 {"getpid", posix_getpid, METH_NOARGS, posix_getpid__doc__},
Guido van Rossumb6775db1994-08-01 11:34:53 +00008037#ifdef HAVE_GETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00008038 {"getpgrp", posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008039#endif /* HAVE_GETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008040#ifdef HAVE_GETPPID
Neal Norwitze241ce82003-02-17 18:17:05 +00008041 {"getppid", posix_getppid, METH_NOARGS, posix_getppid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008042#endif /* HAVE_GETPPID */
8043#ifdef HAVE_GETUID
Neal Norwitze241ce82003-02-17 18:17:05 +00008044 {"getuid", posix_getuid, METH_NOARGS, posix_getuid__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008045#endif /* HAVE_GETUID */
Fred Drake12c6e2d1999-12-14 21:25:03 +00008046#ifdef HAVE_GETLOGIN
Neal Norwitze241ce82003-02-17 18:17:05 +00008047 {"getlogin", posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
Fred Drake12c6e2d1999-12-14 21:25:03 +00008048#endif
Guido van Rossumad0ee831995-03-01 10:34:45 +00008049#ifdef HAVE_KILL
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008050 {"kill", posix_kill, METH_VARARGS, posix_kill__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008051#endif /* HAVE_KILL */
Martin v. Löwisb2c92f42002-02-16 23:35:41 +00008052#ifdef HAVE_KILLPG
8053 {"killpg", posix_killpg, METH_VARARGS, posix_killpg__doc__},
8054#endif /* HAVE_KILLPG */
Guido van Rossumc0125471996-06-28 18:55:32 +00008055#ifdef HAVE_PLOCK
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008056 {"plock", posix_plock, METH_VARARGS, posix_plock__doc__},
Guido van Rossumc0125471996-06-28 18:55:32 +00008057#endif /* HAVE_PLOCK */
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008058#ifdef HAVE_POPEN
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008059 {"popen", posix_popen, METH_VARARGS, posix_popen__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008060#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00008061 {"popen2", win32_popen2, METH_VARARGS},
8062 {"popen3", win32_popen3, METH_VARARGS},
8063 {"popen4", win32_popen4, METH_VARARGS},
Tim Petersf58a7aa2000-09-22 10:05:54 +00008064 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008065#else
8066#if defined(PYOS_OS2) && defined(PYCC_GCC)
8067 {"popen2", os2emx_popen2, METH_VARARGS},
8068 {"popen3", os2emx_popen3, METH_VARARGS},
8069 {"popen4", os2emx_popen4, METH_VARARGS},
8070#endif
Fredrik Lundhffb9c772000-07-09 14:49:51 +00008071#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008072#endif /* HAVE_POPEN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008073#ifdef HAVE_SETUID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008074 {"setuid", posix_setuid, METH_VARARGS, posix_setuid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008075#endif /* HAVE_SETUID */
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00008076#ifdef HAVE_SETEUID
8077 {"seteuid", posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
8078#endif /* HAVE_SETEUID */
8079#ifdef HAVE_SETEGID
8080 {"setegid", posix_setegid, METH_VARARGS, posix_setegid__doc__},
8081#endif /* HAVE_SETEGID */
8082#ifdef HAVE_SETREUID
8083 {"setreuid", posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
8084#endif /* HAVE_SETREUID */
8085#ifdef HAVE_SETREGID
8086 {"setregid", posix_setregid, METH_VARARGS, posix_setregid__doc__},
8087#endif /* HAVE_SETREGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008088#ifdef HAVE_SETGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008089 {"setgid", posix_setgid, METH_VARARGS, posix_setgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008090#endif /* HAVE_SETGID */
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008091#ifdef HAVE_SETGROUPS
Georg Brandl96a8c392006-05-29 21:04:52 +00008092 {"setgroups", posix_setgroups, METH_O, posix_setgroups__doc__},
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00008093#endif /* HAVE_SETGROUPS */
Martin v. Löwis606edc12002-06-13 21:09:11 +00008094#ifdef HAVE_GETPGID
8095 {"getpgid", posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
8096#endif /* HAVE_GETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008097#ifdef HAVE_SETPGRP
Neal Norwitze241ce82003-02-17 18:17:05 +00008098 {"setpgrp", posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008099#endif /* HAVE_SETPGRP */
Guido van Rossumad0ee831995-03-01 10:34:45 +00008100#ifdef HAVE_WAIT
Neal Norwitze241ce82003-02-17 18:17:05 +00008101 {"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
Guido van Rossumad0ee831995-03-01 10:34:45 +00008102#endif /* HAVE_WAIT */
Neal Norwitz05a45592006-03-20 06:30:08 +00008103#ifdef HAVE_WAIT3
8104 {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
8105#endif /* HAVE_WAIT3 */
8106#ifdef HAVE_WAIT4
8107 {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
8108#endif /* HAVE_WAIT4 */
Tim Petersab034fa2002-02-01 11:27:43 +00008109#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008110 {"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008111#endif /* HAVE_WAITPID */
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00008112#ifdef HAVE_GETSID
8113 {"getsid", posix_getsid, METH_VARARGS, posix_getsid__doc__},
8114#endif /* HAVE_GETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008115#ifdef HAVE_SETSID
Neal Norwitze241ce82003-02-17 18:17:05 +00008116 {"setsid", posix_setsid, METH_NOARGS, posix_setsid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008117#endif /* HAVE_SETSID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008118#ifdef HAVE_SETPGID
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008119 {"setpgid", posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008120#endif /* HAVE_SETPGID */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008121#ifdef HAVE_TCGETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008122 {"tcgetpgrp", posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008123#endif /* HAVE_TCGETPGRP */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008124#ifdef HAVE_TCSETPGRP
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008125 {"tcsetpgrp", posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008126#endif /* HAVE_TCSETPGRP */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008127 {"open", posix_open, METH_VARARGS, posix_open__doc__},
8128 {"close", posix_close, METH_VARARGS, posix_close__doc__},
8129 {"dup", posix_dup, METH_VARARGS, posix_dup__doc__},
8130 {"dup2", posix_dup2, METH_VARARGS, posix_dup2__doc__},
8131 {"lseek", posix_lseek, METH_VARARGS, posix_lseek__doc__},
8132 {"read", posix_read, METH_VARARGS, posix_read__doc__},
8133 {"write", posix_write, METH_VARARGS, posix_write__doc__},
8134 {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__},
8135 {"fdopen", posix_fdopen, METH_VARARGS, posix_fdopen__doc__},
Skip Montanaro1517d842000-07-19 14:34:14 +00008136 {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008137#ifdef HAVE_PIPE
Neal Norwitze241ce82003-02-17 18:17:05 +00008138 {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008139#endif
8140#ifdef HAVE_MKFIFO
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008141 {"mkfifo", posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008142#endif
Neal Norwitz11690112002-07-30 01:08:28 +00008143#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
Martin v. Löwis06a83e92002-04-14 10:19:44 +00008144 {"mknod", posix_mknod, METH_VARARGS, posix_mknod__doc__},
8145#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +00008146#ifdef HAVE_DEVICE_MACROS
8147 {"major", posix_major, METH_VARARGS, posix_major__doc__},
8148 {"minor", posix_minor, METH_VARARGS, posix_minor__doc__},
8149 {"makedev", posix_makedev, METH_VARARGS, posix_makedev__doc__},
8150#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008151#ifdef HAVE_FTRUNCATE
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008152 {"ftruncate", posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008153#endif
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008154#ifdef HAVE_PUTENV
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008155 {"putenv", posix_putenv, METH_VARARGS, posix_putenv__doc__},
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008156#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008157#ifdef HAVE_UNSETENV
8158 {"unsetenv", posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
8159#endif
Guido van Rossumb6a47161997-09-15 22:54:34 +00008160#ifdef HAVE_STRERROR
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008161 {"strerror", posix_strerror, METH_VARARGS, posix_strerror__doc__},
Guido van Rossumb6a47161997-09-15 22:54:34 +00008162#endif
Fred Drake4d1e64b2002-04-15 19:40:07 +00008163#ifdef HAVE_FCHDIR
8164 {"fchdir", posix_fchdir, METH_O, posix_fchdir__doc__},
8165#endif
Guido van Rossum21142a01999-01-08 21:05:37 +00008166#ifdef HAVE_FSYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00008167 {"fsync", posix_fsync, METH_O, posix_fsync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00008168#endif
8169#ifdef HAVE_FDATASYNC
Fred Drake4d1e64b2002-04-15 19:40:07 +00008170 {"fdatasync", posix_fdatasync, METH_O, posix_fdatasync__doc__},
Guido van Rossum21142a01999-01-08 21:05:37 +00008171#endif
Guido van Rossumc9641791998-08-04 15:26:23 +00008172#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00008173#ifdef WCOREDUMP
8174 {"WCOREDUMP", posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
8175#endif /* WCOREDUMP */
Martin v. Löwis2b41b0d2002-05-04 13:13:41 +00008176#ifdef WIFCONTINUED
8177 {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
8178#endif /* WIFCONTINUED */
Guido van Rossumc9641791998-08-04 15:26:23 +00008179#ifdef WIFSTOPPED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008180 {"WIFSTOPPED", posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008181#endif /* WIFSTOPPED */
8182#ifdef WIFSIGNALED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008183 {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008184#endif /* WIFSIGNALED */
8185#ifdef WIFEXITED
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008186 {"WIFEXITED", posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008187#endif /* WIFEXITED */
8188#ifdef WEXITSTATUS
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008189 {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008190#endif /* WEXITSTATUS */
8191#ifdef WTERMSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008192 {"WTERMSIG", posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008193#endif /* WTERMSIG */
8194#ifdef WSTOPSIG
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008195 {"WSTOPSIG", posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
Guido van Rossumc9641791998-08-04 15:26:23 +00008196#endif /* WSTOPSIG */
8197#endif /* HAVE_SYS_WAIT_H */
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00008198#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008199 {"fstatvfs", posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00008200#endif
Martin v. Löwis5f5d99c2006-05-16 07:05:37 +00008201#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008202 {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
Guido van Rossum94f6f721999-01-06 18:42:14 +00008203#endif
Guido van Rossume2ad6332001-01-08 17:51:55 +00008204#ifdef HAVE_TMPFILE
Neal Norwitze241ce82003-02-17 18:17:05 +00008205 {"tmpfile", posix_tmpfile, METH_NOARGS, posix_tmpfile__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008206#endif
8207#ifdef HAVE_TEMPNAM
8208 {"tempnam", posix_tempnam, METH_VARARGS, posix_tempnam__doc__},
8209#endif
8210#ifdef HAVE_TMPNAM
Neal Norwitze241ce82003-02-17 18:17:05 +00008211 {"tmpnam", posix_tmpnam, METH_NOARGS, posix_tmpnam__doc__},
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008212#endif
Fred Drakec9680921999-12-13 16:37:25 +00008213#ifdef HAVE_CONFSTR
8214 {"confstr", posix_confstr, METH_VARARGS, posix_confstr__doc__},
8215#endif
8216#ifdef HAVE_SYSCONF
8217 {"sysconf", posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
8218#endif
8219#ifdef HAVE_FPATHCONF
8220 {"fpathconf", posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
8221#endif
8222#ifdef HAVE_PATHCONF
8223 {"pathconf", posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
8224#endif
Neal Norwitze241ce82003-02-17 18:17:05 +00008225 {"abort", posix_abort, METH_NOARGS, posix_abort__doc__},
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00008226#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00008227 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
8228#endif
Martin v. Löwis438b5342002-12-27 10:16:42 +00008229#ifdef HAVE_GETLOADAVG
Neal Norwitze241ce82003-02-17 18:17:05 +00008230 {"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
Martin v. Löwis438b5342002-12-27 10:16:42 +00008231#endif
Martin v. Löwisdc3883f2004-08-29 15:46:35 +00008232 #ifdef MS_WINDOWS
8233 {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
8234 #endif
Neal Norwitz2a30cd02006-07-10 01:18:57 +00008235 #ifdef __VMS
8236 {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
8237 #endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008238 {NULL, NULL} /* Sentinel */
8239};
8240
8241
Barry Warsaw4a342091996-12-19 23:50:02 +00008242static int
Fred Drake4d1e64b2002-04-15 19:40:07 +00008243ins(PyObject *module, char *symbol, long value)
Barry Warsaw4a342091996-12-19 23:50:02 +00008244{
Fred Drake4d1e64b2002-04-15 19:40:07 +00008245 return PyModule_AddIntConstant(module, symbol, value);
Barry Warsaw4a342091996-12-19 23:50:02 +00008246}
8247
Guido van Rossumd48f2521997-12-05 22:19:34 +00008248#if defined(PYOS_OS2)
8249/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008250static int insertvalues(PyObject *module)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008251{
8252 APIRET rc;
8253 ULONG values[QSV_MAX+1];
8254 PyObject *v;
Marc-André Lemburgd4c0a9c2001-11-28 11:47:00 +00008255 char *ver, tmp[50];
Guido van Rossumd48f2521997-12-05 22:19:34 +00008256
8257 Py_BEGIN_ALLOW_THREADS
Andrew MacIntyre75e01452003-04-21 14:19:51 +00008258 rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008259 Py_END_ALLOW_THREADS
8260
8261 if (rc != NO_ERROR) {
8262 os2_error(rc);
8263 return -1;
8264 }
8265
Fred Drake4d1e64b2002-04-15 19:40:07 +00008266 if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
8267 if (ins(module, "memkernel", values[QSV_TOTRESMEM])) return -1;
8268 if (ins(module, "memvirtual", values[QSV_TOTAVAILMEM])) return -1;
8269 if (ins(module, "maxpathlen", values[QSV_MAX_PATH_LENGTH])) return -1;
8270 if (ins(module, "maxnamelen", values[QSV_MAX_COMP_LENGTH])) return -1;
8271 if (ins(module, "revision", values[QSV_VERSION_REVISION])) return -1;
8272 if (ins(module, "timeslice", values[QSV_MIN_SLICE])) return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008273
8274 switch (values[QSV_VERSION_MINOR]) {
8275 case 0: ver = "2.00"; break;
8276 case 10: ver = "2.10"; break;
8277 case 11: ver = "2.11"; break;
8278 case 30: ver = "3.00"; break;
8279 case 40: ver = "4.00"; break;
8280 case 50: ver = "5.00"; break;
8281 default:
Tim Peters885d4572001-11-28 20:27:42 +00008282 PyOS_snprintf(tmp, sizeof(tmp),
8283 "%d-%d", values[QSV_VERSION_MAJOR],
8284 values[QSV_VERSION_MINOR]);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008285 ver = &tmp[0];
8286 }
8287
8288 /* Add Indicator of the Version of the Operating System */
Fred Drake4d1e64b2002-04-15 19:40:07 +00008289 if (PyModule_AddStringConstant(module, "version", tmp) < 0)
Guido van Rossumd48f2521997-12-05 22:19:34 +00008290 return -1;
Guido van Rossumd48f2521997-12-05 22:19:34 +00008291
8292 /* Add Indicator of Which Drive was Used to Boot the System */
8293 tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
8294 tmp[1] = ':';
8295 tmp[2] = '\0';
8296
Fred Drake4d1e64b2002-04-15 19:40:07 +00008297 return PyModule_AddStringConstant(module, "bootdrive", tmp);
Guido van Rossumd48f2521997-12-05 22:19:34 +00008298}
8299#endif
8300
Barry Warsaw4a342091996-12-19 23:50:02 +00008301static int
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008302all_ins(PyObject *d)
Barry Warsaw4a342091996-12-19 23:50:02 +00008303{
Guido van Rossum94f6f721999-01-06 18:42:14 +00008304#ifdef F_OK
8305 if (ins(d, "F_OK", (long)F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008306#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008307#ifdef R_OK
8308 if (ins(d, "R_OK", (long)R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008309#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008310#ifdef W_OK
8311 if (ins(d, "W_OK", (long)W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008312#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00008313#ifdef X_OK
8314 if (ins(d, "X_OK", (long)X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008315#endif
Fred Drakec9680921999-12-13 16:37:25 +00008316#ifdef NGROUPS_MAX
8317 if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
8318#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +00008319#ifdef TMP_MAX
8320 if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
8321#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008322#ifdef WCONTINUED
8323 if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
8324#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008325#ifdef WNOHANG
8326 if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +00008327#endif
Fred Drake106c1a02002-04-23 15:58:02 +00008328#ifdef WUNTRACED
8329 if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
8330#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008331#ifdef O_RDONLY
8332 if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
8333#endif
8334#ifdef O_WRONLY
8335 if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
8336#endif
8337#ifdef O_RDWR
8338 if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
8339#endif
8340#ifdef O_NDELAY
8341 if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
8342#endif
8343#ifdef O_NONBLOCK
8344 if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
8345#endif
8346#ifdef O_APPEND
8347 if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
8348#endif
8349#ifdef O_DSYNC
8350 if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
8351#endif
8352#ifdef O_RSYNC
8353 if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
8354#endif
8355#ifdef O_SYNC
8356 if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
8357#endif
8358#ifdef O_NOCTTY
8359 if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
8360#endif
8361#ifdef O_CREAT
8362 if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
8363#endif
8364#ifdef O_EXCL
8365 if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
8366#endif
8367#ifdef O_TRUNC
8368 if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
8369#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +00008370#ifdef O_BINARY
8371 if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
8372#endif
8373#ifdef O_TEXT
8374 if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
8375#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008376#ifdef O_LARGEFILE
8377 if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
8378#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +00008379#ifdef O_SHLOCK
8380 if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
8381#endif
8382#ifdef O_EXLOCK
8383 if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
8384#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008385
Tim Peters5aa91602002-01-30 05:46:57 +00008386/* MS Windows */
8387#ifdef O_NOINHERIT
8388 /* Don't inherit in child processes. */
8389 if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
8390#endif
8391#ifdef _O_SHORT_LIVED
8392 /* Optimize for short life (keep in memory). */
8393 /* MS forgot to define this one with a non-underscore form too. */
8394 if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
8395#endif
8396#ifdef O_TEMPORARY
8397 /* Automatically delete when last handle is closed. */
8398 if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
8399#endif
8400#ifdef O_RANDOM
8401 /* Optimize for random access. */
8402 if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
8403#endif
8404#ifdef O_SEQUENTIAL
8405 /* Optimize for sequential access. */
8406 if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
8407#endif
8408
Martin v. Löwis4fe3c272001-10-18 22:05:36 +00008409/* GNU extensions. */
8410#ifdef O_DIRECT
8411 /* Direct disk access. */
8412 if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
8413#endif
8414#ifdef O_DIRECTORY
8415 /* Must be a directory. */
8416 if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
8417#endif
8418#ifdef O_NOFOLLOW
8419 /* Do not follow links. */
8420 if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
8421#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00008422
Barry Warsaw5676bd12003-01-07 20:57:09 +00008423 /* These come from sysexits.h */
8424#ifdef EX_OK
8425 if (ins(d, "EX_OK", (long)EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008426#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008427#ifdef EX_USAGE
8428 if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008429#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008430#ifdef EX_DATAERR
8431 if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008432#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008433#ifdef EX_NOINPUT
8434 if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008435#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008436#ifdef EX_NOUSER
8437 if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008438#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008439#ifdef EX_NOHOST
8440 if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008441#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008442#ifdef EX_UNAVAILABLE
8443 if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008444#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008445#ifdef EX_SOFTWARE
8446 if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008447#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008448#ifdef EX_OSERR
8449 if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008450#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008451#ifdef EX_OSFILE
8452 if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008453#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008454#ifdef EX_CANTCREAT
8455 if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008456#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008457#ifdef EX_IOERR
8458 if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008459#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008460#ifdef EX_TEMPFAIL
8461 if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008462#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008463#ifdef EX_PROTOCOL
8464 if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008465#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008466#ifdef EX_NOPERM
8467 if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008468#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008469#ifdef EX_CONFIG
8470 if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008471#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008472#ifdef EX_NOTFOUND
8473 if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +00008474#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +00008475
Guido van Rossum246bc171999-02-01 23:54:31 +00008476#ifdef HAVE_SPAWNV
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008477#if defined(PYOS_OS2) && defined(PYCC_GCC)
8478 if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
8479 if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
8480 if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
8481 if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
8482 if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
8483 if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
8484 if (ins(d, "P_PM", (long)P_PM)) return -1;
8485 if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
8486 if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
8487 if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
8488 if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
8489 if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
8490 if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
8491 if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
8492 if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
8493 if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
8494 if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
8495 if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
8496 if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
8497 if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
8498#else
Guido van Rossum7d385291999-02-16 19:38:04 +00008499 if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
8500 if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
8501 if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
8502 if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
8503 if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +00008504#endif
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00008505#endif
Guido van Rossum246bc171999-02-01 23:54:31 +00008506
Guido van Rossumd48f2521997-12-05 22:19:34 +00008507#if defined(PYOS_OS2)
8508 if (insertvalues(d)) return -1;
8509#endif
Barry Warsaw4a342091996-12-19 23:50:02 +00008510 return 0;
8511}
8512
8513
Tim Peters5aa91602002-01-30 05:46:57 +00008514#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008515#define INITFUNC initnt
8516#define MODNAME "nt"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008517
8518#elif defined(PYOS_OS2)
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008519#define INITFUNC initos2
8520#define MODNAME "os2"
Tim Peters58e0a8c2001-05-14 22:32:33 +00008521
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +00008522#else
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008523#define INITFUNC initposix
8524#define MODNAME "posix"
8525#endif
8526
Mark Hammondfe51c6d2002-08-02 02:27:13 +00008527PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00008528INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +00008529{
Fred Drake4d1e64b2002-04-15 19:40:07 +00008530 PyObject *m, *v;
Tim Peters5aa91602002-01-30 05:46:57 +00008531
Fred Drake4d1e64b2002-04-15 19:40:07 +00008532 m = Py_InitModule3(MODNAME,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008533 posix_methods,
Fred Drake4d1e64b2002-04-15 19:40:07 +00008534 posix__doc__);
Neal Norwitz1ac754f2006-01-19 06:09:39 +00008535 if (m == NULL)
8536 return;
Tim Peters5aa91602002-01-30 05:46:57 +00008537
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008538 /* Initialize environ dictionary */
Guido van Rossumb6775db1994-08-01 11:34:53 +00008539 v = convertenviron();
Fred Drake4d1e64b2002-04-15 19:40:07 +00008540 Py_XINCREF(v);
8541 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
Guido van Rossum0cb96de1997-10-01 04:29:29 +00008542 return;
Barry Warsaw53699e91996-12-10 23:23:01 +00008543 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +00008544
Fred Drake4d1e64b2002-04-15 19:40:07 +00008545 if (all_ins(m))
Barry Warsaw4a342091996-12-19 23:50:02 +00008546 return;
8547
Fred Drake4d1e64b2002-04-15 19:40:07 +00008548 if (setup_confname_tables(m))
Fred Drakebec628d1999-12-15 18:31:10 +00008549 return;
8550
Fred Drake4d1e64b2002-04-15 19:40:07 +00008551 Py_INCREF(PyExc_OSError);
8552 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +00008553
Guido van Rossumb3d39562000-01-31 18:41:26 +00008554#ifdef HAVE_PUTENV
Neil Schemenauer19030a02001-01-16 04:27:47 +00008555 if (posix_putenv_garbage == NULL)
8556 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +00008557#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +00008558
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00008559 if (!initialized) {
8560 stat_result_desc.name = MODNAME ".stat_result";
8561 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
8562 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
8563 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
8564 PyStructSequence_InitType(&StatResultType, &stat_result_desc);
8565 structseq_new = StatResultType.tp_new;
8566 StatResultType.tp_new = statresult_new;
8567
8568 statvfs_result_desc.name = MODNAME ".statvfs_result";
8569 PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
8570 }
Fred Drake4d1e64b2002-04-15 19:40:07 +00008571 Py_INCREF((PyObject*) &StatResultType);
8572 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
Fred Drake4d1e64b2002-04-15 19:40:07 +00008573 Py_INCREF((PyObject*) &StatVFSResultType);
8574 PyModule_AddObject(m, "statvfs_result",
8575 (PyObject*) &StatVFSResultType);
Martin v. Löwis19ab6c92006-04-16 18:55:50 +00008576 initialized = 1;
Ronald Oussorend06b6f22006-04-23 11:59:25 +00008577
8578#ifdef __APPLE__
8579 /*
8580 * Step 2 of weak-linking support on Mac OS X.
8581 *
8582 * The code below removes functions that are not available on the
8583 * currently active platform.
8584 *
8585 * This block allow one to use a python binary that was build on
8586 * OSX 10.4 on OSX 10.3, without loosing access to new APIs on
8587 * OSX 10.4.
8588 */
8589#ifdef HAVE_FSTATVFS
8590 if (fstatvfs == NULL) {
8591 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
8592 return;
8593 }
8594 }
8595#endif /* HAVE_FSTATVFS */
8596
8597#ifdef HAVE_STATVFS
8598 if (statvfs == NULL) {
8599 if (PyObject_DelAttrString(m, "statvfs") == -1) {
8600 return;
8601 }
8602 }
8603#endif /* HAVE_STATVFS */
8604
8605# ifdef HAVE_LCHOWN
8606 if (lchown == NULL) {
8607 if (PyObject_DelAttrString(m, "lchown") == -1) {
8608 return;
8609 }
8610 }
8611#endif /* HAVE_LCHOWN */
8612
8613
8614#endif /* __APPLE__ */
8615
Guido van Rossumb6775db1994-08-01 11:34:53 +00008616}
Anthony Baxterac6bd462006-04-13 02:06:09 +00008617
8618#ifdef __cplusplus
8619}
8620#endif
8621
Martin v. Löwis18aaa562006-10-15 08:43:33 +00008622